diff --git a/config/boards/bananapir2.csc b/config/boards/bananapir2.csc index 58c1dbe15b90..e5ad7bc05d4b 100644 --- a/config/boards/bananapir2.csc +++ b/config/boards/bananapir2.csc @@ -2,6 +2,7 @@ BOARD_NAME="Banana Pi R2" BOARDFAMILY="mt7623" BOARD_MAINTAINER="" +KERNEL_TARGET="current" BOOTCONFIG="mt7623n_bpir2_defconfig" -HAS_VIDEO_OUTPUT="no" -KERNEL_TARGET="legacy" +BOOT_FDT_FILE="mediatek/mt7623n-bananapi-bpi-r2" +HAS_VIDEO_OUTPUT="yes" diff --git a/config/kernel/linux-mt7623-edge.config b/config/kernel/linux-mt7623-current.config similarity index 79% rename from config/kernel/linux-mt7623-edge.config rename to config/kernel/linux-mt7623-current.config index 98b5b7a0a703..3a63a47fbca4 100644 --- a/config/kernel/linux-mt7623-edge.config +++ b/config/kernel/linux-mt7623-current.config @@ -1,26 +1,32 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 5.7.6 Kernel Configuration -# - -# -# Compiler: arm-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36)) 8.3.0 +# Linux/arm 6.6.37 Kernel Configuration # +CONFIG_CC_VERSION_TEXT="arm-linux-gnueabihf-gcc (Ubuntu 13.2.0-23ubuntu4) 13.2.0" CONFIG_CC_IS_GCC=y -CONFIG_GCC_VERSION=80300 -CONFIG_LD_VERSION=232000000 +CONFIG_GCC_VERSION=130200 CONFIG_CLANG_VERSION=0 -CONFIG_CC_CAN_LINK=y -CONFIG_CC_HAS_ASM_GOTO=y +CONFIG_AS_IS_GNU=y +CONFIG_AS_VERSION=24200 +CONFIG_LD_IS_BFD=y +CONFIG_LD_VERSION=24200 +CONFIG_LLD_VERSION=0 +CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y +CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y +CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y CONFIG_CC_HAS_ASM_INLINE=y +CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y +CONFIG_PAHOLE_VERSION=125 CONFIG_IRQ_WORK=y CONFIG_BUILDTIME_TABLE_SORT=y +CONFIG_THREAD_INFO_IN_TASK=y # # General setup # CONFIG_INIT_ENV_ARG_LIMIT=32 # CONFIG_COMPILE_TEST is not set +# CONFIG_WERROR is not set CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_BUILD_SALT="" @@ -34,12 +40,13 @@ CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_XZ is not set # CONFIG_KERNEL_LZO is not set # CONFIG_KERNEL_LZ4 is not set +CONFIG_DEFAULT_INIT="" CONFIG_DEFAULT_HOSTNAME="(none)" -CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_WATCH_QUEUE is not set CONFIG_CROSS_MEMORY_ATTACH=y # CONFIG_USELIB is not set # CONFIG_AUDIT is not set @@ -56,10 +63,8 @@ CONFIG_GENERIC_IRQ_MIGRATION=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_GENERIC_IRQ_IPI=y CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_IRQ_MSI_IOMMU=y -CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_IRQ_FORCED_THREADING=y CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_IRQ_DEBUGFS is not set @@ -70,6 +75,8 @@ CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_ARCH_HAS_TICK_BROADCAST=y CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_CONTEXT_TRACKING=y +CONFIG_CONTEXT_TRACKING_IDLE=y # # Timers subsystem @@ -83,6 +90,20 @@ CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y # end of Timers subsystem +CONFIG_BPF=y +CONFIG_HAVE_EBPF_JIT=y + +# +# BPF subsystem +# +CONFIG_BPF_SYSCALL=y +CONFIG_BPF_JIT=y +# CONFIG_BPF_JIT_ALWAYS_ON is not set +CONFIG_BPF_UNPRIV_DEFAULT_OFF=y +# CONFIG_BPF_PRELOAD is not set +# end of BPF subsystem + +CONFIG_PREEMPT_NONE_BUILD=y CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -107,8 +128,10 @@ CONFIG_CPU_ISOLATION=y # CONFIG_TREE_RCU=y # CONFIG_RCU_EXPERT is not set -CONFIG_SRCU=y CONFIG_TREE_SRCU=y +CONFIG_NEED_SRCU_NMI_SAFE=y +CONFIG_TASKS_RCU_GENERIC=y +CONFIG_TASKS_TRACE_RCU=y CONFIG_RCU_STALL_COMMON=y CONFIG_RCU_NEED_SEGCBLIST=y # end of RCU Subsystem @@ -118,7 +141,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_IKHEADERS=m CONFIG_LOG_BUF_SHIFT=17 CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 -CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 +# CONFIG_PRINTK_INDEX is not set CONFIG_GENERIC_SCHED_CLOCK=y # @@ -127,11 +150,13 @@ CONFIG_GENERIC_SCHED_CLOCK=y # CONFIG_UCLAMP_TASK is not set # end of Scheduler features +CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" +CONFIG_GCC10_NO_ARRAY_BOUNDS=y +CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_CGROUPS=y CONFIG_PAGE_COUNTER=y +# CONFIG_CGROUP_FAVOR_DYNMODS is not set CONFIG_MEMCG=y -CONFIG_MEMCG_SWAP=y -CONFIG_MEMCG_SWAP_ENABLED=y CONFIG_MEMCG_KMEM=y CONFIG_BLK_CGROUP=y CONFIG_CGROUP_WRITEBACK=y @@ -139,6 +164,7 @@ CONFIG_CGROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y CONFIG_CFS_BANDWIDTH=y CONFIG_RT_GROUP_SCHED=y +CONFIG_SCHED_MM_CID=y CONFIG_CGROUP_PIDS=y CONFIG_CGROUP_RDMA=y CONFIG_CGROUP_FREEZER=y @@ -148,6 +174,7 @@ CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_PERF=y CONFIG_CGROUP_BPF=y +# CONFIG_CGROUP_MISC is not set # CONFIG_CGROUP_DEBUG is not set CONFIG_SOCK_CGROUP_DATA=y CONFIG_NAMESPACES=y @@ -158,7 +185,6 @@ CONFIG_PID_NS=y CONFIG_NET_NS=y # CONFIG_CHECKPOINT_RESTORE is not set # CONFIG_SCHED_AUTOGROUP is not set -# CONFIG_SYSFS_DEPRECATED is not set # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" @@ -168,12 +194,15 @@ CONFIG_RD_LZMA=y CONFIG_RD_XZ=y CONFIG_RD_LZO=y CONFIG_RD_LZ4=y +CONFIG_RD_ZSTD=y # CONFIG_BOOT_CONFIG is not set +CONFIG_INITRAMFS_PRESERVE_MTIME=y CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_LD_ORPHAN_WARN=y +CONFIG_LD_ORPHAN_WARN_LEVEL="warn" CONFIG_SYSCTL=y CONFIG_HAVE_UID16=y -CONFIG_BPF=y CONFIG_EXPERT=y CONFIG_UID16=y CONFIG_MULTIUSER=y @@ -182,7 +211,6 @@ CONFIG_SYSFS_SYSCALL=y CONFIG_FHANDLE=y CONFIG_POSIX_TIMERS=y CONFIG_PRINTK=y -CONFIG_PRINTK_NMI=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y @@ -198,15 +226,14 @@ CONFIG_IO_URING=y CONFIG_ADVISE_SYSCALLS=y CONFIG_MEMBARRIER=y CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_SELFTEST is not set CONFIG_KALLSYMS_ALL=y CONFIG_KALLSYMS_BASE_RELATIVE=y -CONFIG_BPF_SYSCALL=y -# CONFIG_BPF_JIT_ALWAYS_ON is not set -# CONFIG_USERFAULTFD is not set CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y +CONFIG_KCMP=y CONFIG_RSEQ=y +CONFIG_CACHESTAT_SYSCALL=y # CONFIG_DEBUG_RSEQ is not set -CONFIG_EMBEDDED=y CONFIG_HAVE_PERF_EVENTS=y CONFIG_PERF_USE_VMALLOC=y # CONFIG_PC104 is not set @@ -218,32 +245,28 @@ CONFIG_PERF_EVENTS=y # CONFIG_DEBUG_PERF_USE_VMALLOC is not set # end of Kernel Performance Events And Counters -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLUB_DEBUG=y -# CONFIG_SLUB_MEMCG_SYSFS_ON is not set -CONFIG_COMPAT_BRK=y -# CONFIG_SLAB is not set -CONFIG_SLUB=y -# CONFIG_SLOB is not set -CONFIG_SLAB_MERGE_DEFAULT=y -# CONFIG_SLAB_FREELIST_RANDOM is not set -# CONFIG_SLAB_FREELIST_HARDENED is not set -# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set -CONFIG_SLUB_CPU_PARTIAL=y CONFIG_SYSTEM_DATA_VERIFICATION=y # CONFIG_PROFILING is not set CONFIG_TRACEPOINTS=y + +# +# Kexec and crash features +# +CONFIG_CRASH_CORE=y +CONFIG_KEXEC_CORE=y +CONFIG_KEXEC=y +# CONFIG_CRASH_DUMP is not set +# end of Kexec and crash features # end of General setup CONFIG_ARM=y -CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_HAS_GROUP_RELOCS=y CONFIG_ARM_DMA_USE_IOMMU=y CONFIG_ARM_DMA_IOMMU_ALIGNMENT=8 CONFIG_SYS_SUPPORTS_APM_EMULATION=y CONFIG_HAVE_PROC_CPU=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_FIX_EARLYCON_MEM=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y @@ -259,20 +282,9 @@ CONFIG_MMU=y CONFIG_ARCH_MMAP_RND_BITS_MIN=8 CONFIG_ARCH_MMAP_RND_BITS_MAX=16 CONFIG_ARCH_MULTIPLATFORM=y -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_DOVE is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C24XX is not set -# CONFIG_ARCH_OMAP1 is not set # -# Multiple platform selection +# Platform selection # # @@ -281,9 +293,10 @@ CONFIG_ARCH_MULTIPLATFORM=y # CONFIG_ARCH_MULTI_V6 is not set CONFIG_ARCH_MULTI_V7=y CONFIG_ARCH_MULTI_V6_V7=y -# end of Multiple platform selection +# end of Platform selection # CONFIG_ARCH_VIRT is not set +# CONFIG_ARCH_AIROHA is not set # CONFIG_ARCH_ACTIONS is not set # CONFIG_ARCH_ALPINE is not set # CONFIG_ARCH_ARTPEC is not set @@ -292,9 +305,11 @@ CONFIG_ARCH_MULTI_V6_V7=y # CONFIG_ARCH_BCM is not set # CONFIG_ARCH_BERLIN is not set # CONFIG_ARCH_DIGICOLOR is not set +# CONFIG_ARCH_DOVE is not set # CONFIG_ARCH_EXYNOS is not set # CONFIG_ARCH_HIGHBANK is not set # CONFIG_ARCH_HISI is not set +# CONFIG_ARCH_HPE is not set # CONFIG_ARCH_MXC is not set # CONFIG_ARCH_KEYSTONE is not set CONFIG_ARCH_MEDIATEK=y @@ -308,6 +323,7 @@ CONFIG_MACH_MT8135=y # CONFIG_ARCH_MESON is not set # CONFIG_ARCH_MILBEAUT is not set # CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_MSTARV7 is not set # CONFIG_ARCH_MVEBU is not set # CONFIG_ARCH_NPCM is not set @@ -322,25 +338,24 @@ CONFIG_MACH_MT8135=y # CONFIG_SOC_DRA7XX is not set # end of TI OMAP/AM/DM/DRA Family -# CONFIG_ARCH_SIRF is not set # CONFIG_ARCH_QCOM is not set # CONFIG_ARCH_RDA is not set -# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_REALTEK is not set # CONFIG_ARCH_ROCKCHIP is not set # CONFIG_ARCH_S5PV210 is not set # CONFIG_ARCH_RENESAS is not set -# CONFIG_ARCH_SOCFPGA is not set +# CONFIG_ARCH_INTEL_SOCFPGA is not set # CONFIG_PLAT_SPEAR is not set # CONFIG_ARCH_STI is not set # CONFIG_ARCH_STM32 is not set +# CONFIG_ARCH_SUNPLUS is not set # CONFIG_ARCH_SUNXI is not set -# CONFIG_ARCH_TANGO is not set # CONFIG_ARCH_TEGRA is not set # CONFIG_ARCH_UNIPHIER is not set # CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_VEXPRESS is not set # CONFIG_ARCH_WM8850 is not set -# CONFIG_ARCH_ZX is not set # CONFIG_ARCH_ZYNQ is not set # @@ -368,11 +383,14 @@ CONFIG_ARM_THUMB=y CONFIG_ARM_THUMBEE=y CONFIG_ARM_VIRT_EXT=y CONFIG_SWP_EMULATE=y +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set # CONFIG_CPU_ICACHE_DISABLE is not set # CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND is not set # CONFIG_CPU_BPREDICT_DISABLE is not set CONFIG_CPU_SPECTRE=y CONFIG_HARDEN_BRANCH_PREDICTOR=y +CONFIG_HARDEN_BRANCH_HISTORY=y CONFIG_KUSER_HELPERS=y CONFIG_VDSO=y CONFIG_OUTER_CACHE=y @@ -395,6 +413,7 @@ CONFIG_ARM_ERRATA_720789=y CONFIG_ARM_ERRATA_754322=y CONFIG_ARM_ERRATA_754327=y CONFIG_ARM_ERRATA_764369=y +# CONFIG_ARM_ERRATA_764319 is not set CONFIG_ARM_ERRATA_775420=y CONFIG_ARM_ERRATA_798181=y # CONFIG_ARM_ERRATA_773022 is not set @@ -419,6 +438,8 @@ CONFIG_ARM_ERRATA_814220=y CONFIG_HAVE_SMP=y CONFIG_SMP=y CONFIG_SMP_ON_UP=y +CONFIG_CURRENT_POINTER_IN_TPIDRURO=y +CONFIG_IRQSTACKS=y CONFIG_ARM_CPU_TOPOLOGY=y # CONFIG_SCHED_MC is not set # CONFIG_SCHED_SMT is not set @@ -433,7 +454,6 @@ CONFIG_PAGE_OFFSET=0xC0000000 CONFIG_NR_CPUS=16 CONFIG_HOTPLUG_CPU=y CONFIG_ARM_PSCI=y -CONFIG_ARCH_NR_GPIO=0 CONFIG_HZ_FIXED=0 # CONFIG_HZ_100 is not set # CONFIG_HZ_200 is not set @@ -447,35 +467,38 @@ CONFIG_SCHED_HRTICK=y CONFIG_ARM_PATCH_IDIV=y CONFIG_AEABI=y # CONFIG_OABI_COMPAT is not set -CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_HIGHMEM=y CONFIG_HIGHPTE=y CONFIG_CPU_SW_DOMAIN_PAN=y CONFIG_HW_PERF_EVENTS=y -CONFIG_ARCH_WANT_GENERAL_HUGETLB=y # CONFIG_ARM_MODULE_PLTS is not set -CONFIG_FORCE_MAX_ZONEORDER=12 +CONFIG_ARCH_FORCE_MAX_ORDER=10 CONFIG_ALIGNMENT_TRAP=y # CONFIG_UACCESS_WITH_MEMCPY is not set -CONFIG_SECCOMP=y # CONFIG_PARAVIRT is not set # CONFIG_PARAVIRT_TIME_ACCOUNTING is not set # CONFIG_XEN is not set +CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y +CONFIG_STACKPROTECTOR_PER_TASK=y # end of Kernel Features # # Boot options # CONFIG_USE_OF=y +CONFIG_ARCH_WANT_FLAT_DTB_INSTALL=y CONFIG_ATAGS=y # CONFIG_DEPRECATED_PARAM_STRUCT is not set CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZBOOT_ROM_BSS=0 # CONFIG_ARM_APPENDED_DTB is not set CONFIG_CMDLINE="" -CONFIG_KEXEC=y +CONFIG_ARCH_SUPPORTS_KEXEC=y CONFIG_ATAGS_PROC=y -# CONFIG_CRASH_DUMP is not set +CONFIG_ARCH_SUPPORTS_CRASH_DUMP=y CONFIG_AUTO_ZRELADDR=y CONFIG_EFI_STUB=y CONFIG_EFI=y @@ -512,7 +535,7 @@ CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y CONFIG_CPUFREQ_DT=y CONFIG_CPUFREQ_DT_PLATDEV=y CONFIG_ARM_MEDIATEK_CPUFREQ=y -# CONFIG_QORIQ_CPUFREQ is not set +CONFIG_ARM_MEDIATEK_CPUFREQ_HW=m # end of CPU Frequency scaling # @@ -558,6 +581,7 @@ CONFIG_SUSPEND_FREEZER=y CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y CONFIG_PM_AUTOSLEEP=y +# CONFIG_PM_USERSPACE_AUTOSLEEP is not set # CONFIG_PM_WAKELOCKS is not set CONFIG_PM=y # CONFIG_PM_DEBUG is not set @@ -574,79 +598,27 @@ CONFIG_ARM_CPU_SUSPEND=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y # end of Power management options -# -# Firmware Drivers -# -# CONFIG_ARM_SCMI_PROTOCOL is not set -# CONFIG_ARM_SCPI_PROTOCOL is not set -# CONFIG_FIRMWARE_MEMMAP is not set -CONFIG_DMIID=y -# CONFIG_DMI_SYSFS is not set -CONFIG_FW_CFG_SYSFS=m -# CONFIG_FW_CFG_SYSFS_CMDLINE is not set -# CONFIG_TRUSTED_FOUNDATIONS is not set -CONFIG_HAVE_ARM_SMCCC=y -CONFIG_ARM_PSCI_FW=y -# CONFIG_ARM_PSCI_CHECKER is not set -# CONFIG_GOOGLE_FIRMWARE is not set - -# -# EFI (Extensible Firmware Interface) Support -# -CONFIG_EFI_VARS=m -CONFIG_EFI_ESRT=y -CONFIG_EFI_VARS_PSTORE=m -# CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE is not set -CONFIG_EFI_PARAMS_FROM_FDT=y -CONFIG_EFI_RUNTIME_WRAPPERS=y -CONFIG_EFI_ARMSTUB=y -# CONFIG_EFI_ARMSTUB_DTB_LOADER is not set -# CONFIG_EFI_BOOTLOADER_CONTROL is not set -CONFIG_EFI_CAPSULE_LOADER=m -# CONFIG_EFI_TEST is not set -# CONFIG_RESET_ATTACK_MITIGATION is not set -# CONFIG_EFI_DISABLE_PCI_DMA is not set -# end of EFI (Extensible Firmware Interface) Support - -# -# Tegra firmware driver -# -# end of Tegra firmware driver -# end of Firmware Drivers - -CONFIG_ARM_CRYPTO=y -CONFIG_CRYPTO_SHA1_ARM=m -CONFIG_CRYPTO_SHA1_ARM_NEON=m -CONFIG_CRYPTO_SHA1_ARM_CE=m -CONFIG_CRYPTO_SHA2_ARM_CE=m -CONFIG_CRYPTO_SHA256_ARM=m -CONFIG_CRYPTO_SHA512_ARM=m -CONFIG_CRYPTO_AES_ARM=m -CONFIG_CRYPTO_AES_ARM_BS=m -CONFIG_CRYPTO_AES_ARM_CE=m -CONFIG_CRYPTO_GHASH_ARM_CE=m -CONFIG_CRYPTO_CRCT10DIF_ARM_CE=m -CONFIG_CRYPTO_CRC32_ARM_CE=m -CONFIG_CRYPTO_CHACHA20_NEON=m -CONFIG_CRYPTO_POLY1305_ARM=m -CONFIG_CRYPTO_NHPOLY1305_NEON=m -CONFIG_CRYPTO_CURVE25519_NEON=m +CONFIG_AS_VFP_VMRS_FPINST=y +CONFIG_CPU_MITIGATIONS=y # # General architecture-dependent options # -CONFIG_CRASH_CORE=y -CONFIG_KEXEC_CORE=y -CONFIG_HAVE_OPROFILE=y +CONFIG_HOTPLUG_CORE_SYNC=y +CONFIG_HOTPLUG_CORE_SYNC_DEAD=y CONFIG_KPROBES=y # CONFIG_JUMP_LABEL is not set +CONFIG_OPTPROBES=y CONFIG_UPROBES=y CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_KRETPROBES=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y CONFIG_HAVE_NMI=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_CONTIGUOUS=y CONFIG_GENERIC_SMP_IDLE_THREAD=y @@ -654,45 +626,57 @@ CONFIG_GENERIC_IDLE_POLL_SETUP=y CONFIG_ARCH_HAS_FORTIFY_SOURCE=y CONFIG_ARCH_HAS_KEEPINITRD=y CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_ARCH_HAS_CPU_FINALIZE_INIT=y CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y CONFIG_ARCH_32BIT_OFF_T=y CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y CONFIG_HAVE_RSEQ=y -CONFIG_HAVE_CLK=y CONFIG_HAVE_HW_BREAKPOINT=y CONFIG_HAVE_PERF_REGS=y CONFIG_HAVE_PERF_USER_STACK_DUMP=y CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_MMU_LAZY_TLB_REFCOUNT=y +CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP=y CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP=y CONFIG_SECCOMP_FILTER=y +# CONFIG_SECCOMP_CACHE_DEBUG is not set CONFIG_HAVE_STACKPROTECTOR=y -CONFIG_CC_HAS_STACKPROTECTOR_NONE=y CONFIG_STACKPROTECTOR=y CONFIG_STACKPROTECTOR_STRONG=y -CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_LTO_NONE=y +CONFIG_HAVE_CONTEXT_TRACKING_USER=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y CONFIG_HAVE_MOD_ARCH_SPECIFIC=y CONFIG_MODULES_USE_ELF_REL=y +CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y +CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK=y +CONFIG_SOFTIRQ_ON_OWN_STACK=y CONFIG_ARCH_HAS_ELF_RANDOMIZE=y CONFIG_HAVE_ARCH_MMAP_RND_BITS=y CONFIG_HAVE_EXIT_THREAD=y CONFIG_ARCH_MMAP_RND_BITS=8 +CONFIG_PAGE_SIZE_LESS_THAN_64KB=y +CONFIG_PAGE_SIZE_LESS_THAN_256KB=y CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y -CONFIG_HAVE_COPY_THREAD_TLS=y CONFIG_CLONE_BACKWARDS=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_OLD_SIGACTION=y CONFIG_COMPAT_32BIT_TIME=y +CONFIG_HAVE_ARCH_VMAP_STACK=y +CONFIG_VMAP_STACK=y CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y CONFIG_STRICT_KERNEL_RWX=y CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y CONFIG_STRICT_MODULE_RWX=y -CONFIG_ARCH_HAS_PHYS_TO_DMA=y # CONFIG_LOCK_EVENT_COUNTS is not set +CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y +CONFIG_HAVE_ARCH_PFN_VALID=y # # GCOV-based kernel profiling @@ -702,37 +686,47 @@ CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y # end of GCOV-based kernel profiling CONFIG_HAVE_GCC_PLUGINS=y +CONFIG_FUNCTION_ALIGNMENT=0 # end of General architecture-dependent options CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y +# CONFIG_MODULE_DEBUG is not set CONFIG_MODULE_FORCE_LOAD=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODULE_UNLOAD_TAINT_TRACKING is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set # CONFIG_MODULE_SIG is not set -# CONFIG_MODULE_COMPRESS is not set +CONFIG_MODULE_COMPRESS_NONE=y +# CONFIG_MODULE_COMPRESS_GZIP is not set +# CONFIG_MODULE_COMPRESS_XZ is not set +# CONFIG_MODULE_COMPRESS_ZSTD is not set # CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set -# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_MODPROBE_PATH="/sbin/modprobe" # CONFIG_TRIM_UNUSED_KSYMS is not set CONFIG_MODULES_TREE_LOOKUP=y CONFIG_BLOCK=y -CONFIG_BLK_SCSI_REQUEST=y +CONFIG_BLOCK_LEGACY_AUTOLOAD=y CONFIG_BLK_CGROUP_RWSTAT=y -CONFIG_BLK_DEV_BSG=y +CONFIG_BLK_CGROUP_PUNT_BIO=y +CONFIG_BLK_DEV_BSG_COMMON=y +CONFIG_BLK_ICQ=y CONFIG_BLK_DEV_BSGLIB=y -# CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_INTEGRITY_T10=y # CONFIG_BLK_DEV_ZONED is not set CONFIG_BLK_DEV_THROTTLING=y # CONFIG_BLK_DEV_THROTTLING_LOW is not set -CONFIG_BLK_CMDLINE_PARSER=y # CONFIG_BLK_WBT is not set # CONFIG_BLK_CGROUP_IOLATENCY is not set # CONFIG_BLK_CGROUP_IOCOST is not set +# CONFIG_BLK_CGROUP_IOPRIO is not set CONFIG_BLK_DEBUG_FS=y # CONFIG_BLK_SED_OPAL is not set +# CONFIG_BLK_INLINE_ENCRYPTION is not set # # Partition Types @@ -762,6 +756,8 @@ CONFIG_CMDLINE_PARTITION=y CONFIG_BLK_MQ_PCI=y CONFIG_BLK_MQ_VIRTIO=y CONFIG_BLK_PM=y +CONFIG_BLOCK_HOLDER_DEPRECATED=y +CONFIG_BLK_MQ_STACKING=y # # IO Schedulers @@ -804,25 +800,11 @@ CONFIG_COREDUMP=y # # Memory Management options # -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_MEMORY_ISOLATION=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_COMPACTION=y -# CONFIG_PAGE_REPORTING is not set -CONFIG_MIGRATION=y -CONFIG_CONTIG_ALLOC=y -CONFIG_BOUNCE=y -CONFIG_KSM=y -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -CONFIG_CLEANCACHE=y -CONFIG_FRONTSWAP=y -CONFIG_CMA=y -# CONFIG_CMA_DEBUG is not set -# CONFIG_CMA_DEBUGFS is not set -CONFIG_CMA_AREAS=7 +CONFIG_ZPOOL=y +CONFIG_SWAP=y CONFIG_ZSWAP=y +CONFIG_ZSWAP_DEFAULT_ON=y +# CONFIG_ZSWAP_EXCLUSIVE_LOADS_DEFAULT_ON is not set # CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set # CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO is not set # CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842 is not set @@ -834,23 +816,75 @@ CONFIG_ZSWAP_COMPRESSOR_DEFAULT="zstd" CONFIG_ZSWAP_ZPOOL_DEFAULT_Z3FOLD=y # CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set CONFIG_ZSWAP_ZPOOL_DEFAULT="z3fold" -CONFIG_ZSWAP_DEFAULT_ON=y -CONFIG_ZPOOL=y CONFIG_ZBUD=y CONFIG_Z3FOLD=y CONFIG_ZSMALLOC=y -# CONFIG_PGTABLE_MAPPING is not set # CONFIG_ZSMALLOC_STAT is not set +CONFIG_ZSMALLOC_CHAIN_SIZE=8 + +# +# SLAB allocator options +# +# CONFIG_SLAB_DEPRECATED is not set +CONFIG_SLUB=y +# CONFIG_SLUB_TINY is not set +CONFIG_SLAB_MERGE_DEFAULT=y +# CONFIG_SLAB_FREELIST_RANDOM is not set +# CONFIG_SLAB_FREELIST_HARDENED is not set +# CONFIG_SLUB_STATS is not set +CONFIG_SLUB_CPU_PARTIAL=y +# CONFIG_RANDOM_KMALLOC_CACHES is not set +# end of SLAB allocator options + +# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set +CONFIG_COMPAT_BRK=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_COMPACTION=y +CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 +# CONFIG_PAGE_REPORTING is not set +CONFIG_MIGRATION=y +CONFIG_CONTIG_ALLOC=y +CONFIG_BOUNCE=y +CONFIG_KSM=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set +# CONFIG_CMA_DEBUGFS is not set +# CONFIG_CMA_SYSFS is not set +CONFIG_CMA_AREAS=7 CONFIG_GENERIC_EARLY_IOREMAP=y # CONFIG_IDLE_PAGE_TRACKING is not set -CONFIG_FRAME_VECTOR=y +CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y +CONFIG_VM_EVENT_COUNTERS=y # CONFIG_PERCPU_STATS is not set -# CONFIG_GUP_BENCHMARK is not set +# CONFIG_GUP_TEST is not set +# CONFIG_DMAPOOL_TEST is not set +CONFIG_KMAP_LOCAL=y +CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y +CONFIG_MEMFD_CREATE=y +# CONFIG_ANON_VMA_NAME is not set +# CONFIG_USERFAULTFD is not set +# CONFIG_LRU_GEN is not set +CONFIG_LOCK_MM_AND_FIND_VMA=y + +# +# Data Access Monitoring +# +# CONFIG_DAMON is not set +# end of Data Access Monitoring # end of Memory Management options CONFIG_NET=y CONFIG_NET_INGRESS=y CONFIG_NET_EGRESS=y +CONFIG_NET_XGRESS=y CONFIG_NET_REDIRECT=y CONFIG_SKB_EXTENSIONS=y @@ -861,6 +895,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_SCM=y +CONFIG_AF_UNIX_OOB=y CONFIG_UNIX_DIAG=m # CONFIG_TLS is not set CONFIG_XFRM=y @@ -871,10 +906,13 @@ CONFIG_XFRM_INTERFACE=m # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set # CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_AH=m +CONFIG_XFRM_ESP=m CONFIG_XFRM_IPCOMP=m CONFIG_NET_KEY=y # CONFIG_NET_KEY_MIGRATE is not set # CONFIG_XDP_SOCKETS is not set +CONFIG_NET_HANDSHAKE=y CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y @@ -907,6 +945,7 @@ CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m # CONFIG_INET_ESPINTCP is not set CONFIG_INET_IPCOMP=m +CONFIG_INET_TABLE_PERTURB_ORDER=16 CONFIG_INET_XFRM_TUNNEL=m CONFIG_INET_TUNNEL=m CONFIG_INET_DIAG=m @@ -948,6 +987,7 @@ CONFIG_IPV6_OPTIMISTIC_DAD=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_ESP_OFFLOAD=m +# CONFIG_INET6_ESPINTCP is not set CONFIG_INET6_IPCOMP=m CONFIG_IPV6_MIP6=m CONFIG_IPV6_ILA=m @@ -968,6 +1008,7 @@ CONFIG_IPV6_SEG6_LWTUNNEL=y CONFIG_IPV6_SEG6_HMAC=y CONFIG_IPV6_SEG6_BPF=y # CONFIG_IPV6_RPL_LWTUNNEL is not set +# CONFIG_IPV6_IOAM6_LWTUNNEL is not set # CONFIG_MPTCP is not set CONFIG_NETWORK_SECMARK=y CONFIG_NET_PTP_CLASSIFY=y @@ -980,16 +1021,19 @@ CONFIG_BRIDGE_NETFILTER=m # Core Netfilter Configuration # CONFIG_NETFILTER_INGRESS=y +CONFIG_NETFILTER_EGRESS=y +CONFIG_NETFILTER_SKIP_EGRESS=y CONFIG_NETFILTER_NETLINK=m CONFIG_NETFILTER_FAMILY_BRIDGE=y CONFIG_NETFILTER_FAMILY_ARP=y +CONFIG_NETFILTER_BPF_LINK=y +# CONFIG_NETFILTER_NETLINK_HOOK is not set CONFIG_NETFILTER_NETLINK_ACCT=m CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NETFILTER_NETLINK_LOG=m CONFIG_NETFILTER_NETLINK_OSF=m CONFIG_NF_CONNTRACK=m -CONFIG_NF_LOG_COMMON=m -CONFIG_NF_LOG_NETDEV=m +CONFIG_NF_LOG_SYSLOG=m CONFIG_NETFILTER_CONNCOUNT=m CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_SECMARK=y @@ -999,6 +1043,7 @@ CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_TIMEOUT=y CONFIG_NF_CONNTRACK_TIMESTAMP=y CONFIG_NF_CONNTRACK_LABELS=y +CONFIG_NF_CONNTRACK_OVS=y CONFIG_NF_CT_PROTO_DCCP=y CONFIG_NF_CT_PROTO_GRE=y CONFIG_NF_CT_PROTO_SCTP=y @@ -1026,6 +1071,7 @@ CONFIG_NF_NAT_SIP=m CONFIG_NF_NAT_TFTP=m CONFIG_NF_NAT_REDIRECT=y CONFIG_NF_NAT_MASQUERADE=y +CONFIG_NF_NAT_OVS=y CONFIG_NETFILTER_SYNPROXY=m CONFIG_NF_TABLES=m CONFIG_NF_TABLES_INET=y @@ -1033,7 +1079,6 @@ CONFIG_NF_TABLES_NETDEV=y CONFIG_NFT_NUMGEN=m CONFIG_NFT_CT=m CONFIG_NFT_FLOW_OFFLOAD=m -CONFIG_NFT_COUNTER=m CONFIG_NFT_CONNLIMIT=m CONFIG_NFT_LOG=m CONFIG_NFT_LIMIT=m @@ -1041,7 +1086,6 @@ CONFIG_NFT_MASQ=m CONFIG_NFT_REDIR=m CONFIG_NFT_NAT=m CONFIG_NFT_TUNNEL=m -CONFIG_NFT_OBJREF=m CONFIG_NFT_QUEUE=m CONFIG_NFT_QUOTA=m CONFIG_NFT_REJECT=m @@ -1059,8 +1103,10 @@ CONFIG_NF_DUP_NETDEV=m CONFIG_NFT_DUP_NETDEV=m CONFIG_NFT_FWD_NETDEV=m CONFIG_NFT_FIB_NETDEV=m +# CONFIG_NFT_REJECT_NETDEV is not set CONFIG_NF_FLOW_TABLE_INET=m CONFIG_NF_FLOW_TABLE=m +# CONFIG_NF_FLOW_TABLE_PROCFS is not set CONFIG_NETFILTER_XTABLES=m # @@ -1200,6 +1246,7 @@ CONFIG_IP_VS_SH=m CONFIG_IP_VS_MH=m CONFIG_IP_VS_SED=m CONFIG_IP_VS_NQ=m +# CONFIG_IP_VS_TWOS is not set # # IPVS SH scheduler @@ -1229,7 +1276,6 @@ CONFIG_NFT_REJECT_IPV4=m CONFIG_NFT_DUP_IPV4=m CONFIG_NFT_FIB_IPV4=m CONFIG_NF_TABLES_ARP=y -CONFIG_NF_FLOW_TABLE_IPV4=m CONFIG_NF_DUP_IPV4=m CONFIG_NF_LOG_ARP=m CONFIG_NF_LOG_IPV4=m @@ -1250,7 +1296,6 @@ CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_RAW=m @@ -1268,7 +1313,6 @@ CONFIG_NF_TABLES_IPV6=y CONFIG_NFT_REJECT_IPV6=m CONFIG_NFT_DUP_IPV6=m CONFIG_NFT_FIB_IPV6=m -CONFIG_NF_FLOW_TABLE_IPV6=m CONFIG_NF_DUP_IPV6=m CONFIG_NF_REJECT_IPV6=m CONFIG_NF_LOG_IPV6=m @@ -1298,7 +1342,6 @@ CONFIG_NF_DEFRAG_IPV6=m CONFIG_NF_TABLES_BRIDGE=m CONFIG_NFT_BRIDGE_META=m CONFIG_NFT_BRIDGE_REJECT=m -CONFIG_NF_LOG_BRIDGE=m CONFIG_NF_CONNTRACK_BRIDGE=m CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m @@ -1372,26 +1415,34 @@ CONFIG_MRP=y CONFIG_BRIDGE=y CONFIG_BRIDGE_IGMP_SNOOPING=y CONFIG_BRIDGE_VLAN_FILTERING=y -CONFIG_HAVE_NET_DSA=y +# CONFIG_BRIDGE_MRP is not set +# CONFIG_BRIDGE_CFM is not set CONFIG_NET_DSA=m -CONFIG_NET_DSA_TAG_8021Q=m +CONFIG_NET_DSA_TAG_NONE=m CONFIG_NET_DSA_TAG_AR9331=m # CONFIG_NET_DSA_TAG_BRCM is not set +# CONFIG_NET_DSA_TAG_BRCM_LEGACY is not set # CONFIG_NET_DSA_TAG_BRCM_PREPEND is not set +# CONFIG_NET_DSA_TAG_HELLCREEK is not set CONFIG_NET_DSA_TAG_GSWIP=m +CONFIG_NET_DSA_TAG_DSA_COMMON=m CONFIG_NET_DSA_TAG_DSA=m CONFIG_NET_DSA_TAG_EDSA=m CONFIG_NET_DSA_TAG_MTK=m CONFIG_NET_DSA_TAG_KSZ=m CONFIG_NET_DSA_TAG_OCELOT=m +# CONFIG_NET_DSA_TAG_OCELOT_8021Q is not set CONFIG_NET_DSA_TAG_QCA=m +# CONFIG_NET_DSA_TAG_RTL4_A is not set +# CONFIG_NET_DSA_TAG_RTL8_4 is not set +# CONFIG_NET_DSA_TAG_RZN1_A5PSW is not set CONFIG_NET_DSA_TAG_LAN9303=m CONFIG_NET_DSA_TAG_SJA1105=m CONFIG_NET_DSA_TAG_TRAILER=m +# CONFIG_NET_DSA_TAG_XRS700X is not set CONFIG_VLAN_8021Q=y CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y -# CONFIG_DECNET is not set CONFIG_LLC=y # CONFIG_LLC2 is not set CONFIG_ATALK=m @@ -1427,10 +1478,8 @@ 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=m CONFIG_NET_SCH_RED=m @@ -1440,9 +1489,9 @@ CONFIG_NET_SCH_TEQL=m CONFIG_NET_SCH_TBF=m CONFIG_NET_SCH_CBS=m CONFIG_NET_SCH_ETF=m +CONFIG_NET_SCH_MQPRIO_LIB=m CONFIG_NET_SCH_TAPRIO=m CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m CONFIG_NET_SCH_NETEM=m CONFIG_NET_SCH_DRR=m CONFIG_NET_SCH_MQPRIO=m @@ -1466,14 +1515,11 @@ CONFIG_NET_SCH_ETS=m # CONFIG_NET_CLS=y CONFIG_NET_CLS_BASIC=m -CONFIG_NET_CLS_TCINDEX=m CONFIG_NET_CLS_ROUTE4=m 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=m CONFIG_NET_CLS_CGROUP=m CONFIG_NET_CLS_BPF=m @@ -1510,6 +1556,7 @@ CONFIG_NET_ACT_CTINFO=m # CONFIG_NET_ACT_IFE is not set # CONFIG_NET_ACT_TUNNEL_KEY is not set CONFIG_NET_ACT_CT=m +# CONFIG_NET_ACT_GATE is not set # CONFIG_NET_TC_SKB_EXT is not set CONFIG_NET_SCH_FIFO=y CONFIG_DCB=y @@ -1520,9 +1567,7 @@ CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=y CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=y -# CONFIG_BATMAN_ADV_DEBUGFS is not set # CONFIG_BATMAN_ADV_DEBUG is not set -# CONFIG_BATMAN_ADV_SYSFS is not set # CONFIG_BATMAN_ADV_TRACING is not set CONFIG_OPENVSWITCH=m CONFIG_OPENVSWITCH_GRE=m @@ -1541,15 +1586,18 @@ CONFIG_NET_NSH=m CONFIG_HSR=m CONFIG_NET_SWITCHDEV=y CONFIG_NET_L3_MASTER_DEV=y +# CONFIG_QRTR is not set # CONFIG_NET_NCSI is not set +CONFIG_PCPU_DEV_REFCNT=y +CONFIG_MAX_SKB_FRAGS=17 CONFIG_RPS=y CONFIG_RFS_ACCEL=y +CONFIG_SOCK_RX_QUEUE_MAPPING=y CONFIG_XPS=y CONFIG_CGROUP_NET_PRIO=y CONFIG_CGROUP_NET_CLASSID=y CONFIG_NET_RX_BUSY_POLL=y CONFIG_BQL=y -CONFIG_BPF_JIT=y # CONFIG_BPF_STREAM_PARSER is not set CONFIG_NET_FLOW_LIMIT=y @@ -1589,66 +1637,7 @@ CONFIG_CAN_RAW=m CONFIG_CAN_BCM=m CONFIG_CAN_GW=m CONFIG_CAN_J1939=m - -# -# CAN Device Drivers -# -CONFIG_CAN_VCAN=m -CONFIG_CAN_VXCAN=m -CONFIG_CAN_SLCAN=m -CONFIG_CAN_DEV=m -CONFIG_CAN_CALC_BITTIMING=y -CONFIG_CAN_FLEXCAN=m -CONFIG_CAN_GRCAN=m -CONFIG_CAN_KVASER_PCIEFD=m -CONFIG_CAN_TI_HECC=m -CONFIG_CAN_C_CAN=m -CONFIG_CAN_C_CAN_PLATFORM=m -CONFIG_CAN_C_CAN_PCI=m -CONFIG_CAN_CC770=m -CONFIG_CAN_CC770_ISA=m -CONFIG_CAN_CC770_PLATFORM=m -# CONFIG_CAN_IFI_CANFD is not set -CONFIG_CAN_M_CAN=m -CONFIG_CAN_M_CAN_PLATFORM=m -CONFIG_CAN_M_CAN_TCAN4X5X=m -CONFIG_CAN_PEAK_PCIEFD=m -CONFIG_CAN_RCAR=m -CONFIG_CAN_RCAR_CANFD=m -CONFIG_CAN_SJA1000=m -CONFIG_CAN_EMS_PCI=m -CONFIG_CAN_F81601=m -CONFIG_CAN_KVASER_PCI=m -CONFIG_CAN_PEAK_PCI=m -CONFIG_CAN_PEAK_PCIEC=y -CONFIG_CAN_PLX_PCI=m -CONFIG_CAN_SJA1000_ISA=m -CONFIG_CAN_SJA1000_PLATFORM=m -CONFIG_CAN_SOFTING=m - -# -# CAN SPI interfaces -# -CONFIG_CAN_HI311X=m -CONFIG_CAN_MCP251X=m -# end of CAN SPI interfaces - -# -# CAN USB interfaces -# -CONFIG_CAN_8DEV_USB=m -CONFIG_CAN_EMS_USB=m -CONFIG_CAN_ESD_USB2=m -CONFIG_CAN_GS_USB=m -CONFIG_CAN_KVASER_USB=m -# CONFIG_CAN_MCBA_USB is not set -CONFIG_CAN_PEAK_USB=m -CONFIG_CAN_UCAN=m -# end of CAN USB interfaces - -# CONFIG_CAN_DEBUG_DEVICES is not set -# end of CAN Device Drivers - +# CONFIG_CAN_ISOTP is not set CONFIG_BT=y CONFIG_BT_BREDR=y CONFIG_BT_RFCOMM=m @@ -1657,12 +1646,15 @@ CONFIG_BT_BNEP=m CONFIG_BT_BNEP_MC_FILTER=y CONFIG_BT_BNEP_PROTO_FILTER=y CONFIG_BT_HIDP=m -CONFIG_BT_HS=y CONFIG_BT_LE=y +CONFIG_BT_LE_L2CAP_ECRED=y CONFIG_BT_6LOWPAN=m CONFIG_BT_LEDS=y -# CONFIG_BT_SELFTEST is not set +# CONFIG_BT_MSFTEXT is not set +# CONFIG_BT_AOSPEXT is not set CONFIG_BT_DEBUGFS=y +# CONFIG_BT_SELFTEST is not set +# CONFIG_BT_FEATURE_DEBUG is not set # # Bluetooth device drivers @@ -1670,10 +1662,12 @@ CONFIG_BT_DEBUGFS=y CONFIG_BT_INTEL=m CONFIG_BT_BCM=m CONFIG_BT_RTL=m +CONFIG_BT_MTK=m CONFIG_BT_HCIBTUSB=m # CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set +CONFIG_BT_HCIBTUSB_POLL_SYNC=y CONFIG_BT_HCIBTUSB_BCM=y -# CONFIG_BT_HCIBTUSB_MTK is not set +CONFIG_BT_HCIBTUSB_MTK=y CONFIG_BT_HCIBTUSB_RTL=y CONFIG_BT_HCIBTSDIO=m CONFIG_BT_HCIUART=m @@ -1683,6 +1677,7 @@ CONFIG_BT_HCIUART_ATH3K=y CONFIG_BT_HCIUART_INTEL=y # CONFIG_BT_HCIUART_AG6XX is not set CONFIG_BT_HCIBCM203X=m +# CONFIG_BT_HCIBCM4377 is not set CONFIG_BT_HCIBPA10X=m CONFIG_BT_HCIBFUSB=m CONFIG_BT_HCIVHCI=m @@ -1691,15 +1686,19 @@ CONFIG_BT_MRVL_SDIO=m CONFIG_BT_ATH3K=m CONFIG_BT_MTKSDIO=m CONFIG_BT_HCIRSI=m +# CONFIG_BT_VIRTIO is not set # end of Bluetooth device drivers CONFIG_AF_RXRPC=m # CONFIG_AF_RXRPC_IPV6 is not set # CONFIG_AF_RXRPC_INJECT_LOSS is not set +# CONFIG_AF_RXRPC_INJECT_RX_DELAY is not set # CONFIG_AF_RXRPC_DEBUG is not set # CONFIG_RXKAD is not set +# CONFIG_RXPERF is not set CONFIG_AF_KCM=m CONFIG_STREAM_PARSER=y +# CONFIG_MCTP is not set CONFIG_FIB_RULES=y CONFIG_WIRELESS=y CONFIG_WIRELESS_EXT=y @@ -1737,13 +1736,12 @@ CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_MESSAGE_TRACING is not set # CONFIG_MAC80211_DEBUG_MENU is not set CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -CONFIG_WIMAX=y -CONFIG_WIMAX_DEBUG_LEVEL=8 CONFIG_RFKILL=y CONFIG_RFKILL_LEDS=y CONFIG_RFKILL_INPUT=y CONFIG_RFKILL_GPIO=y CONFIG_NET_9P=m +CONFIG_NET_9P_FD=m CONFIG_NET_9P_VIRTIO=m # CONFIG_NET_9P_DEBUG is not set # CONFIG_CAIF is not set @@ -1764,6 +1762,7 @@ CONFIG_NFC_SHDLC=y CONFIG_NFC_TRF7970A=m CONFIG_NFC_SIM=m CONFIG_NFC_PORT100=m +# CONFIG_NFC_VIRTUAL_NCI is not set CONFIG_NFC_FDP=m CONFIG_NFC_FDP_I2C=m CONFIG_NFC_PN544=m @@ -1795,10 +1794,13 @@ CONFIG_LWTUNNEL=y CONFIG_LWTUNNEL_BPF=y CONFIG_DST_CACHE=y CONFIG_GRO_CELLS=y +CONFIG_NET_SELFTESTS=y +CONFIG_NET_SOCK_MSG=y CONFIG_NET_DEVLINK=y +CONFIG_PAGE_POOL=y +CONFIG_PAGE_POOL_STATS=y CONFIG_FAILOVER=y CONFIG_ETHTOOL_NETLINK=y -CONFIG_HAVE_EBPF_JIT=y # # Device Drivers @@ -1820,9 +1822,7 @@ CONFIG_PCIEASPM_DEFAULT=y CONFIG_PCIE_PME=y # CONFIG_PCIE_DPC is not set # CONFIG_PCIE_PTM is not set -# CONFIG_PCIE_BW is not set CONFIG_PCI_MSI=y -CONFIG_PCI_MSI_IRQ_DOMAIN=y CONFIG_PCI_QUIRKS=y # CONFIG_PCI_DEBUG is not set # CONFIG_PCI_STUB is not set @@ -1831,40 +1831,52 @@ CONFIG_PCI_ECAM=y # CONFIG_PCI_PRI is not set # CONFIG_PCI_PASID is not set CONFIG_PCI_LABEL=y +# CONFIG_PCI_DYNAMIC_OF_NODES is not set +# CONFIG_PCIE_BUS_TUNE_OFF is not set +CONFIG_PCIE_BUS_DEFAULT=y +# CONFIG_PCIE_BUS_SAFE is not set +# CONFIG_PCIE_BUS_PERFORMANCE is not set +# CONFIG_PCIE_BUS_PEER2PEER is not set +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_HOTPLUG_PCI is not set # # PCI controller drivers # +# CONFIG_PCIE_ALTERA is not set # CONFIG_PCI_FTPCI100 is not set CONFIG_PCI_HOST_COMMON=y CONFIG_PCI_HOST_GENERIC=y -# CONFIG_PCIE_XILINX is not set -# CONFIG_PCI_V3_SEMI is not set -# CONFIG_PCIE_ALTERA is not set CONFIG_PCIE_MEDIATEK=y +# CONFIG_PCIE_MEDIATEK_GEN3 is not set +# CONFIG_PCIE_MICROCHIP_HOST is not set +# CONFIG_PCI_V3_SEMI is not set +# CONFIG_PCIE_XILINX is not set # -# DesignWare PCI Core Support +# Cadence-based PCIe controllers # -# CONFIG_PCIE_DW_PLAT_HOST is not set -# CONFIG_PCIE_DW_PLAT_EP is not set -# CONFIG_PCI_LAYERSCAPE is not set -# CONFIG_PCI_LAYERSCAPE_EP is not set -# CONFIG_PCI_MESON is not set -# end of DesignWare PCI Core Support +# CONFIG_PCIE_CADENCE_PLAT_HOST is not set +# CONFIG_PCIE_CADENCE_PLAT_EP is not set +# CONFIG_PCI_J721E_HOST is not set +# CONFIG_PCI_J721E_EP is not set +# end of Cadence-based PCIe controllers # -# Mobiveil PCIe Core Support +# DesignWare-based PCIe controllers # -# end of Mobiveil PCIe Core Support +# CONFIG_PCI_MESON is not set +# CONFIG_PCI_LAYERSCAPE is not set +# CONFIG_PCI_LAYERSCAPE_EP is not set +# CONFIG_PCIE_DW_PLAT_HOST is not set +# CONFIG_PCIE_DW_PLAT_EP is not set +# end of DesignWare-based PCIe controllers # -# Cadence PCIe controllers support +# Mobiveil-based PCIe controllers # -# CONFIG_PCIE_CADENCE_PLAT_HOST is not set -# CONFIG_PCIE_CADENCE_PLAT_EP is not set -# end of Cadence PCIe controllers support +# end of Mobiveil-based PCIe controllers # end of PCI controller drivers # @@ -1873,6 +1885,7 @@ CONFIG_PCIE_MEDIATEK=y CONFIG_PCI_ENDPOINT=y CONFIG_PCI_ENDPOINT_CONFIGFS=y CONFIG_PCI_EPF_TEST=m +# CONFIG_PCI_EPF_NTB is not set # end of PCI Endpoint # @@ -1881,6 +1894,7 @@ CONFIG_PCI_EPF_TEST=m # CONFIG_PCI_SW_SWITCHTEC is not set # end of PCI switch controller drivers +# CONFIG_CXL_BUS is not set # CONFIG_PCCARD is not set CONFIG_RAPIDIO=m CONFIG_RAPIDIO_TSI721=m @@ -1895,9 +1909,7 @@ CONFIG_RAPIDIO_MPORT_CDEV=m # # RapidIO Switch drivers # -CONFIG_RAPIDIO_TSI57X=m CONFIG_RAPIDIO_CPS_XX=m -CONFIG_RAPIDIO_TSI568=m CONFIG_RAPIDIO_CPS_GEN2=m CONFIG_RAPIDIO_RXS_GEN3=m # end of RapidIO Switch drivers @@ -1905,10 +1917,12 @@ CONFIG_RAPIDIO_RXS_GEN3=m # # Generic Driver Options # +CONFIG_AUXILIARY_BUS=y CONFIG_UEVENT_HELPER=y CONFIG_UEVENT_HELPER_PATH="" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_DEVTMPFS_SAFE is not set CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y @@ -1920,6 +1934,7 @@ CONFIG_EXTRA_FIRMWARE="" # CONFIG_FW_LOADER_USER_HELPER is not set # CONFIG_FW_LOADER_COMPRESS is not set CONFIG_FW_CACHE=y +# CONFIG_FW_UPLOAD is not set # end of Firmware loader CONFIG_WANT_DEV_COREDUMP=y @@ -1930,6 +1945,7 @@ CONFIG_DEV_COREDUMP=y # CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set # CONFIG_TEST_ASYNC_DRIVER_PROBE is not set CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y CONFIG_SOC_BUS=y CONFIG_REGMAP=y CONFIG_REGMAP_I2C=y @@ -1941,6 +1957,7 @@ CONFIG_REGMAP_SOUNDWIRE=m CONFIG_DMA_SHARED_BUFFER=y # CONFIG_DMA_FENCE_TRACE is not set CONFIG_GENERIC_ARCH_TOPOLOGY=y +# CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT is not set # end of Generic Driver Options # @@ -1948,31 +1965,98 @@ CONFIG_GENERIC_ARCH_TOPOLOGY=y # # CONFIG_BRCMSTB_GISB_ARB is not set CONFIG_MOXTET=m -# CONFIG_SIMPLE_PM_BUS is not set CONFIG_VEXPRESS_CONFIG=y CONFIG_MHI_BUS=m +# CONFIG_MHI_BUS_DEBUG is not set +# CONFIG_MHI_BUS_PCI_GENERIC is not set +# CONFIG_MHI_BUS_EP is not set # end of Bus devices +# +# Cache Drivers +# +# end of Cache Drivers + # CONFIG_CONNECTOR is not set -CONFIG_GNSS=m -CONFIG_MTD=y -# CONFIG_MTD_TESTS is not set # -# Partition parsers +# Firmware Drivers # -# CONFIG_MTD_AR7_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_OF_PARTS=y -# CONFIG_MTD_AFS_PARTS is not set -# CONFIG_MTD_REDBOOT_PARTS is not set -# end of Partition parsers # -# User Modules And Translation Layers +# ARM System Control and Management Interface Protocol +# +# CONFIG_ARM_SCMI_PROTOCOL is not set +# end of ARM System Control and Management Interface Protocol + +# CONFIG_ARM_SCPI_PROTOCOL is not set +# CONFIG_FIRMWARE_MEMMAP is not set +CONFIG_DMIID=y +# CONFIG_DMI_SYSFS is not set +CONFIG_FW_CFG_SYSFS=m +# CONFIG_FW_CFG_SYSFS_CMDLINE is not set +# CONFIG_MTK_ADSP_IPC is not set +CONFIG_SYSFB=y +# CONFIG_SYSFB_SIMPLEFB is not set +# CONFIG_TRUSTED_FOUNDATIONS is not set +# CONFIG_GOOGLE_FIRMWARE is not set + +# +# EFI (Extensible Firmware Interface) Support +# +CONFIG_EFI_ESRT=y +CONFIG_EFI_VARS_PSTORE=m +# CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE is not set +CONFIG_EFI_PARAMS_FROM_FDT=y +CONFIG_EFI_RUNTIME_WRAPPERS=y +CONFIG_EFI_GENERIC_STUB=y +# CONFIG_EFI_ARMSTUB_DTB_LOADER is not set +# CONFIG_EFI_BOOTLOADER_CONTROL is not set +CONFIG_EFI_CAPSULE_LOADER=m +# CONFIG_EFI_TEST is not set +# CONFIG_RESET_ATTACK_MITIGATION is not set +# CONFIG_EFI_DISABLE_PCI_DMA is not set +# CONFIG_EFI_DISABLE_RUNTIME is not set +# CONFIG_EFI_COCO_SECRET is not set +# end of EFI (Extensible Firmware Interface) Support + +CONFIG_ARM_PSCI_FW=y +# CONFIG_ARM_PSCI_CHECKER is not set +CONFIG_HAVE_ARM_SMCCC=y +CONFIG_HAVE_ARM_SMCCC_DISCOVERY=y +CONFIG_ARM_SMCCC_SOC_ID=y + +# +# Tegra firmware driver +# +# end of Tegra firmware driver +# end of Firmware Drivers + +CONFIG_GNSS=m +# CONFIG_GNSS_USB is not set +CONFIG_MTD=y +# CONFIG_MTD_TESTS is not set + +# +# Partition parsers +# +# CONFIG_MTD_AR7_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_PARSER_TRX is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# end of Partition parsers + +# +# User Modules And Translation Layers +# +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y + +# +# Note that in some cases UBI block is preferred. See MTD_UBI_BLOCK. # -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set @@ -2023,6 +2107,7 @@ CONFIG_MTD_PCI=m # CONFIG_MTD_PMC551 is not set # CONFIG_MTD_DATAFLASH is not set # CONFIG_MTD_MCHP23K256 is not set +# CONFIG_MTD_MCHP48L640 is not set # CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set @@ -2035,12 +2120,12 @@ CONFIG_MTD_PCI=m # CONFIG_MTD_DOCG3 is not set # end of Self-contained MTD device drivers -CONFIG_MTD_NAND_CORE=m +# +# NAND +# +CONFIG_MTD_NAND_CORE=y # CONFIG_MTD_ONENAND is not set -CONFIG_MTD_NAND_ECC_SW_HAMMING=m -# CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC is not set CONFIG_MTD_RAW_NAND=m -# CONFIG_MTD_NAND_ECC_SW_BCH is not set # # Raw/parallel NAND flash controllers @@ -2050,11 +2135,16 @@ CONFIG_MTD_NAND_DENALI=m CONFIG_MTD_NAND_DENALI_DT=m # CONFIG_MTD_NAND_CAFE is not set CONFIG_MTD_NAND_BRCMNAND=m -# CONFIG_MTD_NAND_MTK is not set +# CONFIG_MTD_NAND_BRCMNAND_BCM63XX is not set +# CONFIG_MTD_NAND_BRCMNAND_BCMBCA is not set +# CONFIG_MTD_NAND_BRCMNAND_BRCMSTB is not set +# CONFIG_MTD_NAND_BRCMNAND_IPROC is not set CONFIG_MTD_NAND_MXIC=m # CONFIG_MTD_NAND_GPIO is not set # CONFIG_MTD_NAND_PLATFORM is not set CONFIG_MTD_NAND_CADENCE=m +# CONFIG_MTD_NAND_ARASAN is not set +# CONFIG_MTD_NAND_INTEL_LGM is not set # # Misc @@ -2064,6 +2154,18 @@ CONFIG_MTD_NAND_CADENCE=m # CONFIG_MTD_NAND_DISKONCHIP is not set # CONFIG_MTD_SPI_NAND is not set +# +# ECC engine support +# +CONFIG_MTD_NAND_ECC=y +CONFIG_MTD_NAND_ECC_SW_HAMMING=y +# CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC is not set +# CONFIG_MTD_NAND_ECC_SW_BCH is not set +CONFIG_MTD_NAND_ECC_MXIC=y +# CONFIG_MTD_NAND_ECC_MEDIATEK is not set +# end of ECC engine support +# end of NAND + # # LPDDR & LPDDR2 PCM memory drivers # @@ -2073,7 +2175,9 @@ CONFIG_MTD_NAND_CADENCE=m CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y -# CONFIG_SPI_CADENCE_QUADSPI is not set +# CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set +CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y +# CONFIG_MTD_SPI_NOR_SWP_KEEP is not set CONFIG_MTD_UBI=y CONFIG_MTD_UBI_WL_THRESHOLD=4096 CONFIG_MTD_UBI_BEB_LIMIT=20 @@ -2090,15 +2194,12 @@ CONFIG_OF_KOBJ=y CONFIG_OF_DYNAMIC=y CONFIG_OF_ADDRESS=y CONFIG_OF_IRQ=y -CONFIG_OF_NET=y -CONFIG_OF_MDIO=y CONFIG_OF_RESERVED_MEM=y CONFIG_OF_RESOLVE=y CONFIG_OF_OVERLAY=y CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y CONFIG_PARPORT=m # CONFIG_PARPORT_PC is not set -CONFIG_PARPORT_AX88796=m # CONFIG_PARPORT_1284 is not set CONFIG_PARPORT_NOT_PC=y CONFIG_BLK_DEV=y @@ -2106,15 +2207,17 @@ CONFIG_BLK_DEV=y CONFIG_CDROM=y # CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set CONFIG_ZRAM=m +CONFIG_ZRAM_DEF_COMP_LZORLE=y +# CONFIG_ZRAM_DEF_COMP_ZSTD is not set +# CONFIG_ZRAM_DEF_COMP_LZO is not set +CONFIG_ZRAM_DEF_COMP="lzo-rle" CONFIG_ZRAM_WRITEBACK=y # CONFIG_ZRAM_MEMORY_TRACKING is not set -# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_ZRAM_MULTI_COMP is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 -CONFIG_BLK_DEV_CRYPTOLOOP=m # CONFIG_BLK_DEV_DRBD is not set CONFIG_BLK_DEV_NBD=m -# CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=4 CONFIG_BLK_DEV_RAM_SIZE=4096 @@ -2122,7 +2225,7 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_ATA_OVER_ETH=m CONFIG_VIRTIO_BLK=m CONFIG_BLK_DEV_RBD=m -# CONFIG_BLK_DEV_RSXX is not set +# CONFIG_BLK_DEV_UBLK is not set # # NVME Support @@ -2130,10 +2233,12 @@ CONFIG_BLK_DEV_RBD=m CONFIG_NVME_CORE=y CONFIG_BLK_DEV_NVME=y # CONFIG_NVME_MULTIPATH is not set +# CONFIG_NVME_VERBOSE_ERRORS is not set # CONFIG_NVME_HWMON is not set CONFIG_NVME_FABRICS=m # CONFIG_NVME_FC is not set CONFIG_NVME_TCP=m +# CONFIG_NVME_AUTH is not set # CONFIG_NVME_TARGET is not set # end of NVME Support @@ -2148,6 +2253,7 @@ CONFIG_AD525X_DPOT_I2C=y # CONFIG_TIFM_CORE is not set CONFIG_ICS932S401=y # CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HI6421V600_IRQ is not set # CONFIG_HP_ILO is not set CONFIG_APDS9802ALS=y CONFIG_ISL29003=y @@ -2160,10 +2266,12 @@ CONFIG_ISL29003=y # CONFIG_LATTICE_ECP3_CONFIG is not set CONFIG_SRAM=y CONFIG_SRAM_EXEC=y -CONFIG_VEXPRESS_SYSCFG=y +# CONFIG_DW_XDATA_PCIE is not set CONFIG_PCI_ENDPOINT_TEST=m CONFIG_XILINX_SDFEC=m -CONFIG_PVPANIC=m +# CONFIG_HISI_HIKEY_USB is not set +# CONFIG_OPEN_DICE is not set +# CONFIG_VCPU_STALL_DETECTOR is not set # CONFIG_C2PORT is not set # @@ -2190,115 +2298,22 @@ CONFIG_EEPROM_EE1004=m # CONFIG_SENSORS_LIS3_SPI is not set # CONFIG_SENSORS_LIS3_I2C is not set # CONFIG_ALTERA_STAPL is not set - -# -# Intel MIC & related support -# -CONFIG_VOP_BUS=m -CONFIG_VOP=m -# end of Intel MIC & related support - # CONFIG_ECHO is not set +# CONFIG_BCM_VK is not set CONFIG_MISC_ALCOR_PCI=m # CONFIG_MISC_RTSX_PCI is not set # CONFIG_MISC_RTSX_USB is not set -CONFIG_HABANA_AI=m CONFIG_UACCE=m - -# -# Mediatek Peripherals -# -CONFIG_MTK_PLATFORM="mt7623" -CONFIG_MTK_BTIF=y - -# -# Modem & Connectivity related configs -# -CONFIG_MTK_COMBO=y -# CONFIG_MTK_COMBO_CHIP_MT6620 is not set -# CONFIG_MTK_COMBO_CHIP_MT6628 is not set -# CONFIG_MTK_COMBO_CHIP_MT6630 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6572 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6582 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_8127 is not set -CONFIG_MTK_COMBO_CHIP_CONSYS_7623=y -# CONFIG_MTK_COMBO_CHIP_CONSYS_6752 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6592 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_8163 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6735 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6755 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6580 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6797 is not set -CONFIG_MTK_COMBO_CHIP="CONSYS_7623" -CONFIG_MTK_COMBO_PLAT_PATH="" -# CONFIG_MTK_COMBO_COMM is not set -# CONFIG_MTK_COMBO_BT is not set -# CONFIG_MTK_COMBO_BT_HCI is not set -CONFIG_MTK_COMBO_WIFI=y -# CONFIG_MTK_WAPI_SUPPORT is not set -# CONFIG_MTK_PASSPOINT_R1_SUPPORT is not set -# CONFIG_MTK_PASSPOINT_R2_SUPPORT is not set -# CONFIG_MTK_WIFI_MCC_SUPPORT is not set -# CONFIG_MTK_DHCPV6C_WIFI is not set -# CONFIG_MTK_CONN_LTE_IDC_SUPPORT is not set -CONFIG_GPS=m -CONFIG_MTK_GPS=m -CONFIG_MTK_GPS_SUPPORT=m -# end of Modem & Connectivity related configs -# end of Mediatek Peripherals +# CONFIG_PVPANIC is not set +# CONFIG_GP_PCI1XXXX is not set # end of Misc devices -CONFIG_HAVE_IDE=y -CONFIG_IDE=y - -# -# Please see Documentation/ide/ide.rst for help/info on IDE drives -# -# 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 is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_IDE_TASK_IOCTL is not set -CONFIG_IDE_PROC_FS=y - -# -# IDE chipset support/bugfixes -# -# CONFIG_BLK_DEV_PLATFORM is not set - -# -# PCI IDE chipsets support -# -# CONFIG_BLK_DEV_GENERIC is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON 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_SL82C105 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 - # # SCSI device support # CONFIG_SCSI_MOD=y CONFIG_RAID_ATTRS=m +CONFIG_SCSI_COMMON=y CONFIG_SCSI=y CONFIG_SCSI_DMA=y CONFIG_SCSI_PROC_FS=y @@ -2310,6 +2325,7 @@ CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set CONFIG_BLK_DEV_SR=y # CONFIG_CHR_DEV_SG is not set +CONFIG_BLK_DEV_BSG=y # CONFIG_CHR_DEV_SCH is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set @@ -2356,16 +2372,16 @@ CONFIG_SCSI_MVUMI=m # CONFIG_MEGARAID_SAS is not set # CONFIG_SCSI_MPT3SAS is not set # CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_MPI3MR is not set # CONFIG_SCSI_SMARTPQI is not set -# CONFIG_SCSI_UFSHCD is not set # CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_BUSLOGIC is not set CONFIG_SCSI_MYRB=m CONFIG_SCSI_MYRS=m # CONFIG_SCSI_SNIC is not set # CONFIG_SCSI_DMX3191D is not set CONFIG_SCSI_FDOMAIN=m CONFIG_SCSI_FDOMAIN_PCI=m -CONFIG_SCSI_GDTH=m # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set @@ -2397,9 +2413,9 @@ CONFIG_SATA_PMP=y CONFIG_SATA_AHCI=y CONFIG_SATA_MOBILE_LPM_POLICY=0 CONFIG_SATA_AHCI_PLATFORM=y +# CONFIG_AHCI_DWC is not set # CONFIG_AHCI_CEVA is not set CONFIG_AHCI_MTK=m -# CONFIG_AHCI_QORIQ is not set # CONFIG_SATA_INIC162X is not set # CONFIG_SATA_ACARD_AHCI is not set # CONFIG_SATA_SIL24 is not set @@ -2472,7 +2488,7 @@ CONFIG_ATA_BMDMA=y # CONFIG_PATA_MPIIX is not set # CONFIG_PATA_NS87410 is not set # CONFIG_PATA_OPTI is not set -# CONFIG_PATA_PLATFORM is not set +# CONFIG_PATA_OF_PLATFORM is not set # CONFIG_PATA_RZ1000 is not set # @@ -2483,6 +2499,7 @@ CONFIG_ATA_BMDMA=y CONFIG_MD=y CONFIG_BLK_DEV_MD=y CONFIG_MD_AUTODETECT=y +CONFIG_MD_BITMAP_FILE=y # CONFIG_MD_LINEAR is not set CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y @@ -2513,6 +2530,8 @@ CONFIG_DM_RAID=y CONFIG_DM_MULTIPATH=y CONFIG_DM_MULTIPATH_QL=y CONFIG_DM_MULTIPATH_ST=y +# CONFIG_DM_MULTIPATH_HST is not set +# CONFIG_DM_MULTIPATH_IOA is not set # CONFIG_DM_DELAY is not set CONFIG_DM_DUST=m # CONFIG_DM_INIT is not set @@ -2522,6 +2541,13 @@ CONFIG_DM_DUST=m # CONFIG_DM_SWITCH is not set # CONFIG_DM_LOG_WRITES is not set # CONFIG_DM_INTEGRITY is not set +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m +# CONFIG_LOOPBACK_TARGET is not set +CONFIG_ISCSI_TARGET=m +# CONFIG_REMOTE_TARGET is not set # CONFIG_FUSION is not set # @@ -2556,6 +2582,7 @@ CONFIG_VXLAN=m # CONFIG_GENEVE is not set CONFIG_BAREUDP=m # CONFIG_GTP is not set +# CONFIG_AMT is not set # CONFIG_MACSEC is not set # CONFIG_NETCONSOLE is not set CONFIG_RIONET=m @@ -2568,6 +2595,7 @@ CONFIG_VETH=y CONFIG_VIRTIO_NET=y # CONFIG_NLMON is not set CONFIG_NET_VRF=m +# CONFIG_MHI_NET is not set # CONFIG_ARCNET is not set CONFIG_ATM_DRIVERS=y # CONFIG_ATM_DUMMY is not set @@ -2587,21 +2615,27 @@ CONFIG_ATM_DRIVERS=y # CONFIG_B53 is not set # CONFIG_NET_DSA_BCM_SF2 is not set # CONFIG_NET_DSA_LOOP is not set +# CONFIG_NET_DSA_HIRSCHMANN_HELLCREEK is not set CONFIG_NET_DSA_LANTIQ_GSWIP=m CONFIG_NET_DSA_MT7530=m +CONFIG_NET_DSA_MT7530_MDIO=m +CONFIG_NET_DSA_MT7530_MMIO=m # CONFIG_NET_DSA_MV88E6060 is not set CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m -CONFIG_NET_DSA_MICROCHIP_KSZ9477=m CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C=m -CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI=m -CONFIG_NET_DSA_MICROCHIP_KSZ8795=m -CONFIG_NET_DSA_MICROCHIP_KSZ8795_SPI=m +# CONFIG_NET_DSA_MICROCHIP_KSZ_SPI is not set +# CONFIG_NET_DSA_MICROCHIP_KSZ_PTP is not set +# CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI is not set # CONFIG_NET_DSA_MV88E6XXX is not set +# CONFIG_NET_DSA_MSCC_OCELOT_EXT is not set +# CONFIG_NET_DSA_MSCC_SEVILLE is not set CONFIG_NET_DSA_AR9331=m +# CONFIG_NET_DSA_QCA8K is not set CONFIG_NET_DSA_SJA1105=m # CONFIG_NET_DSA_SJA1105_PTP is not set -# CONFIG_NET_DSA_QCA8K is not set -# CONFIG_NET_DSA_REALTEK_SMI is not set +# CONFIG_NET_DSA_XRS700X_I2C is not set +# CONFIG_NET_DSA_XRS700X_MDIO is not set +# CONFIG_NET_DSA_REALTEK is not set # CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set # CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set CONFIG_NET_DSA_VITESSE_VSC73XX=m @@ -2620,10 +2654,10 @@ CONFIG_ETHERNET=y # CONFIG_NET_VENDOR_AMD is not set # CONFIG_NET_VENDOR_AQUANTIA is not set # CONFIG_NET_VENDOR_ARC is not set +CONFIG_NET_VENDOR_ASIX=y +# CONFIG_SPI_AX88796C is not set # CONFIG_NET_VENDOR_ATHEROS is not set -# CONFIG_NET_VENDOR_AURORA is not set # CONFIG_NET_VENDOR_BROADCOM is not set -# CONFIG_NET_VENDOR_BROCADE is not set CONFIG_NET_VENDOR_CADENCE=y # CONFIG_MACB is not set # CONFIG_NET_VENDOR_CAVIUM is not set @@ -2632,37 +2666,49 @@ CONFIG_NET_VENDOR_CADENCE=y # CONFIG_NET_VENDOR_CISCO is not set CONFIG_NET_VENDOR_CORTINA=y CONFIG_GEMINI_ETHERNET=m +CONFIG_NET_VENDOR_DAVICOM=y # CONFIG_DM9000 is not set +# CONFIG_DM9051 is not set # CONFIG_DNET is not set # CONFIG_NET_VENDOR_DEC is not set # CONFIG_NET_VENDOR_DLINK is not set # CONFIG_NET_VENDOR_EMULEX is not set +CONFIG_NET_VENDOR_ENGLEDER=y +# CONFIG_TSNEP is not set # CONFIG_NET_VENDOR_EZCHIP is not set # CONFIG_NET_VENDOR_FARADAY is not set +CONFIG_NET_VENDOR_FUNGIBLE=y +# CONFIG_FUN_ETH is not set CONFIG_NET_VENDOR_GOOGLE=y CONFIG_GVE=m # CONFIG_NET_VENDOR_HISILICON is not set # CONFIG_NET_VENDOR_HUAWEI is not set # CONFIG_NET_VENDOR_INTEL is not set # CONFIG_JME is not set +CONFIG_NET_VENDOR_ADI=y +# CONFIG_ADIN1110 is not set +CONFIG_NET_VENDOR_LITEX=y +# CONFIG_LITEX_LITEETH is not set # CONFIG_NET_VENDOR_MARVELL is not set CONFIG_NET_VENDOR_MEDIATEK=y -CONFIG_NET_MEDIATEK_SOC=y +CONFIG_NET_MEDIATEK_SOC_WED=y +CONFIG_NET_MEDIATEK_SOC=m +# CONFIG_NET_MEDIATEK_STAR_EMAC is not set # CONFIG_NET_VENDOR_MELLANOX is not set # CONFIG_NET_VENDOR_MICREL is not set # CONFIG_NET_VENDOR_MICROCHIP is not set CONFIG_NET_VENDOR_MICROSEMI=y +CONFIG_MSCC_OCELOT_SWITCH_LIB=m CONFIG_MSCC_OCELOT_SWITCH=m -# CONFIG_MSCC_OCELOT_SWITCH_OCELOT is not set +CONFIG_NET_VENDOR_MICROSOFT=y # CONFIG_NET_VENDOR_MYRI is not set # CONFIG_FEALNX is not set +CONFIG_NET_VENDOR_NI=y +CONFIG_NI_XGE_MANAGEMENT_ENET=m # CONFIG_NET_VENDOR_NATSEMI is not set CONFIG_NET_VENDOR_NETERION=y # CONFIG_S2IO is not set -# CONFIG_VXGE is not set # CONFIG_NET_VENDOR_NETRONOME is not set -CONFIG_NET_VENDOR_NI=y -CONFIG_NI_XGE_MANAGEMENT_ENET=m # CONFIG_NET_VENDOR_NVIDIA is not set # CONFIG_NET_VENDOR_OKI is not set # CONFIG_ETHOC is not set @@ -2671,6 +2717,7 @@ CONFIG_NET_VENDOR_PACKET_ENGINES=y # CONFIG_YELLOWFIN is not set CONFIG_NET_VENDOR_PENSANDO=y # CONFIG_NET_VENDOR_QLOGIC is not set +# CONFIG_NET_VENDOR_BROCADE is not set # CONFIG_NET_VENDOR_QUALCOMM is not set # CONFIG_NET_VENDOR_RDC is not set # CONFIG_NET_VENDOR_REALTEK is not set @@ -2678,9 +2725,9 @@ CONFIG_NET_VENDOR_PENSANDO=y # CONFIG_NET_VENDOR_ROCKER is not set # CONFIG_NET_VENDOR_SAMSUNG is not set # CONFIG_NET_VENDOR_SEEQ is not set -# CONFIG_NET_VENDOR_SOLARFLARE is not set # CONFIG_NET_VENDOR_SILAN is not set # CONFIG_NET_VENDOR_SIS is not set +# CONFIG_NET_VENDOR_SOLARFLARE is not set # CONFIG_NET_VENDOR_SMSC is not set CONFIG_NET_VENDOR_SOCIONEXT=y # CONFIG_NET_VENDOR_STMICRO is not set @@ -2688,75 +2735,172 @@ CONFIG_NET_VENDOR_SOCIONEXT=y # CONFIG_NET_VENDOR_SYNOPSYS is not set # CONFIG_NET_VENDOR_TEHUTI is not set # CONFIG_NET_VENDOR_TI is not set +CONFIG_NET_VENDOR_VERTEXCOM=y +# CONFIG_MSE102X is not set # CONFIG_NET_VENDOR_VIA is not set +CONFIG_NET_VENDOR_WANGXUN=y +# CONFIG_NGBE is not set +# CONFIG_TXGBE is not set # CONFIG_NET_VENDOR_WIZNET is not set CONFIG_NET_VENDOR_XILINX=y +# CONFIG_XILINX_EMACLITE is not set CONFIG_XILINX_AXI_EMAC=m CONFIG_XILINX_LL_TEMAC=m # CONFIG_FDDI is not set # CONFIG_HIPPI is not set -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_BCM_UNIMAC=m -# CONFIG_MDIO_BITBANG is not set -CONFIG_MDIO_BUS_MUX=m -# CONFIG_MDIO_BUS_MUX_GPIO is not set -# CONFIG_MDIO_BUS_MUX_MMIOREG is not set -CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m -# CONFIG_MDIO_HISI_FEMAC is not set -CONFIG_MDIO_IPQ8064=m -# CONFIG_MDIO_MSCC_MIIM is not set -CONFIG_MDIO_MVUSB=m -CONFIG_MDIO_XPCS=m -CONFIG_PHYLINK=y +CONFIG_PHYLINK=m CONFIG_PHYLIB=y CONFIG_SWPHY=y # CONFIG_LED_TRIGGER_PHY is not set +CONFIG_PHYLIB_LEDS=y +CONFIG_FIXED_PHY=y +# CONFIG_SFP is not set # # MII PHY device drivers # -# CONFIG_SFP is not set -CONFIG_ADIN_PHY=m # CONFIG_AMD_PHY is not set +CONFIG_ADIN_PHY=m +# CONFIG_ADIN1100_PHY is not set # CONFIG_AQUANTIA_PHY is not set CONFIG_AX88796B_PHY=m -# CONFIG_BCM7XXX_PHY is not set -# CONFIG_BCM87XX_PHY is not set # CONFIG_BROADCOM_PHY is not set +# CONFIG_BCM54140_PHY is not set +# CONFIG_BCM7XXX_PHY is not set CONFIG_BCM84881_PHY=m +# CONFIG_BCM87XX_PHY is not set # CONFIG_CICADA_PHY is not set # CONFIG_CORTINA_PHY is not set # CONFIG_DAVICOM_PHY is not set -# CONFIG_DP83822_PHY is not set -# CONFIG_DP83TC811_PHY is not set -# CONFIG_DP83848_PHY is not set -# CONFIG_DP83867_PHY is not set -CONFIG_DP83869_PHY=m -CONFIG_FIXED_PHY=y CONFIG_ICPLUS_PHY=y +# CONFIG_LXT_PHY is not set # CONFIG_INTEL_XWAY_PHY is not set # CONFIG_LSI_ET1011C_PHY is not set -# CONFIG_LXT_PHY is not set # CONFIG_MARVELL_PHY is not set # CONFIG_MARVELL_10G_PHY is not set +# CONFIG_MARVELL_88Q2XXX_PHY is not set +# CONFIG_MARVELL_88X2222_PHY is not set +# CONFIG_MAXLINEAR_GPHY is not set +CONFIG_MEDIATEK_GE_PHY=m +# CONFIG_MEDIATEK_GE_SOC_PHY is not set # CONFIG_MICREL_PHY is not set +# CONFIG_MICROCHIP_T1S_PHY is not set CONFIG_MICROCHIP_PHY=m # CONFIG_MICROCHIP_T1_PHY is not set # CONFIG_MICROSEMI_PHY is not set +# CONFIG_MOTORCOMM_PHY is not set # CONFIG_NATIONAL_PHY is not set +# CONFIG_NXP_CBTX_PHY is not set +# CONFIG_NXP_C45_TJA11XX_PHY is not set CONFIG_NXP_TJA11XX_PHY=m +# CONFIG_NCN26000_PHY is not set # CONFIG_AT803X_PHY is not set # CONFIG_QSEMI_PHY is not set # CONFIG_REALTEK_PHY is not set # CONFIG_RENESAS_PHY is not set # CONFIG_ROCKCHIP_PHY is not set -# CONFIG_SMSC_PHY is not set +CONFIG_SMSC_PHY=m # CONFIG_STE10XP is not set # CONFIG_TERANETICS_PHY is not set +# CONFIG_DP83822_PHY is not set +# CONFIG_DP83TC811_PHY is not set +# CONFIG_DP83848_PHY is not set +# CONFIG_DP83867_PHY is not set +CONFIG_DP83869_PHY=m +# CONFIG_DP83TD510_PHY is not set CONFIG_VITESSE_PHY=m # CONFIG_XILINX_GMII2RGMII is not set CONFIG_MICREL_KS8995MA=m +# CONFIG_PSE_CONTROLLER is not set +CONFIG_CAN_DEV=m +CONFIG_CAN_VCAN=m +CONFIG_CAN_VXCAN=m +CONFIG_CAN_NETLINK=y +CONFIG_CAN_CALC_BITTIMING=y +CONFIG_CAN_RX_OFFLOAD=y +# CONFIG_CAN_CAN327 is not set +CONFIG_CAN_FLEXCAN=m +CONFIG_CAN_GRCAN=m +CONFIG_CAN_KVASER_PCIEFD=m +CONFIG_CAN_SLCAN=m +CONFIG_CAN_TI_HECC=m +CONFIG_CAN_C_CAN=m +CONFIG_CAN_C_CAN_PLATFORM=m +CONFIG_CAN_C_CAN_PCI=m +CONFIG_CAN_CC770=m +CONFIG_CAN_CC770_ISA=m +CONFIG_CAN_CC770_PLATFORM=m +# CONFIG_CAN_CTUCANFD_PCI is not set +# CONFIG_CAN_CTUCANFD_PLATFORM is not set +# CONFIG_CAN_IFI_CANFD is not set +CONFIG_CAN_M_CAN=m +# CONFIG_CAN_M_CAN_PCI is not set +CONFIG_CAN_M_CAN_PLATFORM=m +CONFIG_CAN_M_CAN_TCAN4X5X=m +CONFIG_CAN_PEAK_PCIEFD=m +CONFIG_CAN_SJA1000=m +CONFIG_CAN_EMS_PCI=m +CONFIG_CAN_F81601=m +CONFIG_CAN_KVASER_PCI=m +CONFIG_CAN_PEAK_PCI=m +CONFIG_CAN_PEAK_PCIEC=y +CONFIG_CAN_PLX_PCI=m +CONFIG_CAN_SJA1000_ISA=m +CONFIG_CAN_SJA1000_PLATFORM=m +CONFIG_CAN_SOFTING=m + +# +# CAN SPI interfaces +# +CONFIG_CAN_HI311X=m +CONFIG_CAN_MCP251X=m +# CONFIG_CAN_MCP251XFD is not set +# end of CAN SPI interfaces + +# +# CAN USB interfaces +# +CONFIG_CAN_8DEV_USB=m +CONFIG_CAN_EMS_USB=m +# CONFIG_CAN_ESD_USB is not set +# CONFIG_CAN_ETAS_ES58X is not set +# CONFIG_CAN_F81604 is not set +CONFIG_CAN_GS_USB=m +CONFIG_CAN_KVASER_USB=m +# CONFIG_CAN_MCBA_USB is not set +CONFIG_CAN_PEAK_USB=m +CONFIG_CAN_UCAN=m +# end of CAN USB interfaces + +# CONFIG_CAN_DEBUG_DEVICES is not set +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_BUS=y +CONFIG_FWNODE_MDIO=y +CONFIG_OF_MDIO=y +CONFIG_MDIO_DEVRES=y +# CONFIG_MDIO_BITBANG is not set +CONFIG_MDIO_BCM_UNIMAC=m +# CONFIG_MDIO_HISI_FEMAC is not set +CONFIG_MDIO_MVUSB=m +# CONFIG_MDIO_MSCC_MIIM is not set +# CONFIG_MDIO_IPQ4019 is not set +CONFIG_MDIO_IPQ8064=m + +# +# MDIO Multiplexers +# +CONFIG_MDIO_BUS_MUX=m +# CONFIG_MDIO_BUS_MUX_GPIO is not set +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set + +# +# PCS device drivers +# +CONFIG_PCS_XPCS=m +CONFIG_PCS_MTK_LYNXI=m +# end of PCS device drivers + CONFIG_PLIP=m CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m @@ -2766,6 +2910,11 @@ CONFIG_PPP_MPPE=m CONFIG_PPP_MULTILINK=y CONFIG_PPPOATM=m CONFIG_PPPOE=m +# CONFIG_PPPOE_HASH_BITS_1 is not set +# CONFIG_PPPOE_HASH_BITS_2 is not set +CONFIG_PPPOE_HASH_BITS_4=y +# CONFIG_PPPOE_HASH_BITS_8 is not set +CONFIG_PPPOE_HASH_BITS=4 CONFIG_PPTP=m CONFIG_PPPOL2TP=m CONFIG_PPP_ASYNC=m @@ -2819,8 +2968,8 @@ CONFIG_USB_SIERRA_NET=m CONFIG_USB_VL600=m CONFIG_USB_NET_CH9200=m CONFIG_USB_NET_AQC111=m +CONFIG_USB_RTL8153_ECM=m CONFIG_WLAN=y -# CONFIG_WIRELESS_WDS is not set CONFIG_WLAN_VENDOR_ADMTEK=y CONFIG_ADM8211=m CONFIG_ATH_COMMON=m @@ -2877,6 +3026,8 @@ CONFIG_ATH10K_SDIO=m CONFIG_ATH10K_DFS_CERTIFIED=y CONFIG_WCN36XX=m # CONFIG_WCN36XX_DEBUGFS is not set +# CONFIG_ATH11K is not set +# CONFIG_ATH12K is not set CONFIG_WLAN_VENDOR_ATMEL=y CONFIG_ATMEL=m CONFIG_PCI_ATMEL=m @@ -2922,6 +3073,7 @@ CONFIG_BRCMFMAC_PCIE=y CONFIG_BRCM_TRACING=y # CONFIG_BRCMDBG is not set CONFIG_WLAN_VENDOR_CISCO=y +# CONFIG_AIRO is not set CONFIG_WLAN_VENDOR_INTEL=y CONFIG_IPW2100=m CONFIG_IPW2100_MONITOR=y @@ -2949,7 +3101,6 @@ CONFIG_IWLWIFI_LEDS=y CONFIG_IWLDVM=m CONFIG_IWLMVM=m CONFIG_IWLWIFI_OPMODE_MODULAR=y -CONFIG_IWLWIFI_BCAST_FILTERING=y # # Debugging Options @@ -2962,7 +3113,6 @@ CONFIG_WLAN_VENDOR_INTERSIL=y # CONFIG_HOSTAP is not set # CONFIG_HERMES is not set # CONFIG_P54_COMMON is not set -# CONFIG_PRISM54 is not set CONFIG_WLAN_VENDOR_MARVELL=y CONFIG_LIBERTAS=m CONFIG_LIBERTAS_USB=m @@ -2985,6 +3135,7 @@ CONFIG_MT76_LEDS=y CONFIG_MT76_USB=m CONFIG_MT76x02_LIB=m CONFIG_MT76x02_USB=m +CONFIG_MT76_CONNAC_LIB=m CONFIG_MT76x0_COMMON=m CONFIG_MT76x0U=m CONFIG_MT76x0E=m @@ -2992,8 +3143,21 @@ CONFIG_MT76x2_COMMON=m CONFIG_MT76x2E=m CONFIG_MT76x2U=m CONFIG_MT7603E=m +CONFIG_MT7615_COMMON=m CONFIG_MT7615E=m CONFIG_MT7622_WMAC=y +# CONFIG_MT7663U is not set +# CONFIG_MT7663S is not set +# CONFIG_MT7915E is not set +# CONFIG_MT7921E is not set +# CONFIG_MT7921S is not set +# CONFIG_MT7921U is not set +# CONFIG_MT7996E is not set +CONFIG_WLAN_VENDOR_MICROCHIP=y +# CONFIG_WILC1000_SDIO is not set +# CONFIG_WILC1000_SPI is not set +CONFIG_WLAN_VENDOR_PURELIFI=y +# CONFIG_PLFXLC is not set CONFIG_WLAN_VENDOR_RALINK=y CONFIG_RT2X00=m CONFIG_RT2400PCI=m @@ -3049,16 +3213,30 @@ CONFIG_RTL8XXXU=m CONFIG_RTW88=m CONFIG_RTW88_CORE=m CONFIG_RTW88_PCI=m +CONFIG_RTW88_8822C=m # CONFIG_RTW88_8822BE is not set -CONFIG_RTW88_8822CE=y +# CONFIG_RTW88_8822BS is not set +# CONFIG_RTW88_8822BU is not set +CONFIG_RTW88_8822CE=m +# CONFIG_RTW88_8822CS is not set +# CONFIG_RTW88_8822CU is not set +# CONFIG_RTW88_8723DE is not set +# CONFIG_RTW88_8723DS is not set +# CONFIG_RTW88_8723DU is not set +# CONFIG_RTW88_8821CE is not set +# CONFIG_RTW88_8821CS is not set +# CONFIG_RTW88_8821CU is not set # CONFIG_RTW88_DEBUG is not set # CONFIG_RTW88_DEBUGFS is not set +# CONFIG_RTW89 is not set CONFIG_WLAN_VENDOR_RSI=y CONFIG_RSI_91X=m # CONFIG_RSI_DEBUGFS is not set CONFIG_RSI_SDIO=m CONFIG_RSI_USB=m CONFIG_RSI_COEX=y +CONFIG_WLAN_VENDOR_SILABS=y +CONFIG_WFX=m CONFIG_WLAN_VENDOR_ST=y CONFIG_CW1200=m CONFIG_CW1200_WLAN_SDIO=m @@ -3072,15 +3250,6 @@ CONFIG_WL18XX=m CONFIG_WLCORE=m CONFIG_WLCORE_SPI=m CONFIG_WLCORE_SDIO=m -CONFIG_WILINK_PLATFORM_DATA=y -CONFIG_RTL8723DU=m -CONFIG_RTL8723DS=m -CONFIG_RTL8822BU=m -CONFIG_RTL8188EU=m -CONFIG_RTL8821CU=m -CONFIG_88XXAU=m -CONFIG_RTL8189FS=m -CONFIG_RTL8189ES=m CONFIG_WLAN_VENDOR_ZYDAS=y CONFIG_USB_ZD1201=m CONFIG_ZD1211RW=m @@ -3088,27 +3257,22 @@ CONFIG_ZD1211RW=m CONFIG_WLAN_VENDOR_QUANTENNA=y CONFIG_QTNFMAC=m CONFIG_QTNFMAC_PCIE=m -CONFIG_MAC80211_HWSIM=m CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_MAC80211_HWSIM=m CONFIG_VIRT_WIFI=m +# CONFIG_WAN is not set +# CONFIG_IEEE802154_DRIVERS is not set # -# WiMAX Wireless Broadband devices +# Wireless WAN # -CONFIG_WIMAX_I2400M=m -CONFIG_WIMAX_I2400M_USB=m -CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8 -# end of WiMAX Wireless Broadband devices +# CONFIG_WWAN is not set +# end of Wireless WAN -# CONFIG_WAN is not set -# CONFIG_IEEE802154_DRIVERS is not set # CONFIG_VMXNET3 is not set CONFIG_NETDEVSIM=m CONFIG_NET_FAILOVER=y # CONFIG_ISDN is not set -CONFIG_NVM=y -CONFIG_NVM_PBLK=m -# CONFIG_NVM_PBLK_DEBUG is not set # # Input device support @@ -3116,9 +3280,9 @@ CONFIG_NVM_PBLK=m CONFIG_INPUT=y CONFIG_INPUT_LEDS=y CONFIG_INPUT_FF_MEMLESS=m -CONFIG_INPUT_POLLDEV=m # CONFIG_INPUT_SPARSEKMAP is not set CONFIG_INPUT_MATRIXKMAP=y +CONFIG_INPUT_VIVALDIFMAP=m # # Userland interfaces @@ -3156,6 +3320,7 @@ CONFIG_KEYBOARD_GPIO=m # CONFIG_KEYBOARD_MPR121 is not set # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_PINEPHONE is not set CONFIG_KEYBOARD_SAMSUNG=m # CONFIG_KEYBOARD_STOWAWAY is not set # CONFIG_KEYBOARD_SUNKBD is not set @@ -3167,7 +3332,9 @@ CONFIG_KEYBOARD_IQS62X=m CONFIG_KEYBOARD_CROS_EC=m # CONFIG_KEYBOARD_CAP11XX is not set # CONFIG_KEYBOARD_BCM is not set -# CONFIG_KEYBOARD_MTK_PMIC is not set +# CONFIG_KEYBOARD_MT6779 is not set +CONFIG_KEYBOARD_MTK_PMIC=m +# CONFIG_KEYBOARD_CYPRESS_SF is not set CONFIG_INPUT_MOUSE=y # CONFIG_MOUSE_PS2 is not set # CONFIG_MOUSE_SERIAL is not set @@ -3182,6 +3349,7 @@ CONFIG_MOUSE_SYNAPTICS_USB=m CONFIG_INPUT_JOYSTICK=y # CONFIG_JOYSTICK_ANALOG is not set # CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADC is not set # CONFIG_JOYSTICK_ADI is not set # CONFIG_JOYSTICK_COBRA is not set # CONFIG_JOYSTICK_GF2K is not set @@ -3201,14 +3369,20 @@ CONFIG_JOYSTICK_IFORCE_USB=m # CONFIG_JOYSTICK_STINGER is not set # CONFIG_JOYSTICK_TWIDJOY is not set # CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_DB9 is not set +# CONFIG_JOYSTICK_GAMECON is not set +# CONFIG_JOYSTICK_TURBOGRAFX is not set # CONFIG_JOYSTICK_AS5011 is not set # CONFIG_JOYSTICK_JOYDUMP is not set CONFIG_JOYSTICK_XPAD=m CONFIG_JOYSTICK_XPAD_FF=y CONFIG_JOYSTICK_XPAD_LEDS=y +# CONFIG_JOYSTICK_WALKERA0701 is not set # CONFIG_JOYSTICK_PSXPAD_SPI is not set # CONFIG_JOYSTICK_PXRC is not set +# CONFIG_JOYSTICK_QWIIC is not set # CONFIG_JOYSTICK_FSIA6B is not set +# CONFIG_JOYSTICK_SENSEHAT is not set # CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set CONFIG_INPUT_MISC=y @@ -3216,10 +3390,8 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_ATMEL_CAPTOUCH is not set # CONFIG_INPUT_BMA150 is not set # CONFIG_INPUT_E3X0_BUTTON is not set -CONFIG_INPUT_MSM_VIBRATOR=m CONFIG_INPUT_MAX77650_ONKEY=m # CONFIG_INPUT_MMA8450 is not set -# CONFIG_INPUT_GP2A is not set # CONFIG_INPUT_GPIO_BEEPER is not set # CONFIG_INPUT_GPIO_DECODER is not set CONFIG_INPUT_GPIO_VIBRA=m @@ -3237,10 +3409,15 @@ CONFIG_INPUT_GPIO_VIBRA=m # CONFIG_INPUT_PWM_BEEPER is not set # CONFIG_INPUT_PWM_VIBRA is not set # CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_DA7280_HAPTICS is not set CONFIG_INPUT_ADXL34X=m CONFIG_INPUT_ADXL34X_I2C=m CONFIG_INPUT_ADXL34X_SPI=m +# CONFIG_INPUT_IBM_PANEL is not set # CONFIG_INPUT_IMS_PCU is not set +# CONFIG_INPUT_IQS269A is not set +# CONFIG_INPUT_IQS626A is not set +# CONFIG_INPUT_IQS7222 is not set # CONFIG_INPUT_CMA3000 is not set # CONFIG_INPUT_DRV260X_HAPTICS is not set # CONFIG_INPUT_DRV2665_HAPTICS is not set @@ -3279,6 +3456,7 @@ CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set +CONFIG_LEGACY_TIOCSTI=y CONFIG_LDISC_AUTOLOAD=y # @@ -3291,28 +3469,29 @@ CONFIG_SERIAL_8250_16550A_VARIANTS=y # CONFIG_SERIAL_8250_FINTEK is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_DMA=y +CONFIG_SERIAL_8250_PCILIB=y CONFIG_SERIAL_8250_PCI=y CONFIG_SERIAL_8250_EXAR=y CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y # CONFIG_SERIAL_8250_MANY_PORTS is not set -# CONFIG_SERIAL_8250_ASPEED_VUART is not set +# CONFIG_SERIAL_8250_PCI1XXXX is not set CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set # CONFIG_SERIAL_8250_RSA is not set CONFIG_SERIAL_8250_DWLIB=y CONFIG_SERIAL_8250_FSL=y CONFIG_SERIAL_8250_DW=y -CONFIG_SERIAL_8250_EM=y # CONFIG_SERIAL_8250_RT288X is not set CONFIG_SERIAL_8250_MT6577=y +CONFIG_SERIAL_8250_PERICOM=y CONFIG_SERIAL_OF_PLATFORM=y # # Non-8250 serial port support # -# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set +# CONFIG_SERIAL_EARLYCON_SEMIHOST is not set # CONFIG_SERIAL_MAX3100 is not set # CONFIG_SERIAL_MAX310X is not set # CONFIG_SERIAL_UARTLITE is not set @@ -3322,11 +3501,8 @@ CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_SIFIVE=m # CONFIG_SERIAL_SCCNXP is not set # CONFIG_SERIAL_SC16IS7XX is not set -CONFIG_SERIAL_BCM63XX=y -CONFIG_SERIAL_BCM63XX_CONSOLE=y # CONFIG_SERIAL_ALTERA_JTAGUART is not set # CONFIG_SERIAL_ALTERA_UART is not set -# CONFIG_SERIAL_IFX6X60 is not set CONFIG_SERIAL_XILINX_PS_UART=y CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y # CONFIG_SERIAL_ARC is not set @@ -3346,9 +3522,9 @@ CONFIG_SERIAL_MCTRL_GPIO=y # CONFIG_N_GSM is not set # CONFIG_NOZOMI is not set CONFIG_NULL_TTY=m -# CONFIG_TRACE_SINK is not set CONFIG_HVC_DRIVER=y # CONFIG_HVC_DCC is not set +# CONFIG_RPMSG_TTY is not set # CONFIG_SERIAL_DEV_BUS is not set # CONFIG_TTY_PRINTK is not set CONFIG_PRINTER=m @@ -3356,22 +3532,24 @@ CONFIG_PRINTER=m CONFIG_PPDEV=m CONFIG_VIRTIO_CONSOLE=y # CONFIG_IPMI_HANDLER is not set +# CONFIG_SSIF_IPMI_BMC is not set CONFIG_IPMB_DEVICE_INTERFACE=m CONFIG_HW_RANDOM=y # CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_HW_RANDOM_BA431 is not set # CONFIG_HW_RANDOM_VIRTIO is not set CONFIG_HW_RANDOM_MTK=y +# CONFIG_HW_RANDOM_CCTRNG is not set +# CONFIG_HW_RANDOM_XIPHERA is not set +CONFIG_HW_RANDOM_ARM_SMCCC_TRNG=y # CONFIG_APPLICOM is not set CONFIG_DEVMEM=y -# CONFIG_DEVKMEM is not set -# CONFIG_RAW_DRIVER is not set CONFIG_DEVPORT=y # CONFIG_TCG_TPM is not set # CONFIG_XILLYBUS is not set +# CONFIG_XILLYUSB is not set # end of Character devices -# CONFIG_RANDOM_TRUST_BOOTLOADER is not set - # # I2C support # @@ -3398,7 +3576,7 @@ CONFIG_I2C_DEMUX_PINCTRL=m CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_SMBUS=m -CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_ALGOBIT=m # # I2C Hardware Bus support @@ -3407,6 +3585,7 @@ CONFIG_I2C_ALGOBIT=y # # PC SMBus host controller drivers # +CONFIG_I2C_CCGX_UCSI=m CONFIG_I2C_ALI1535=m CONFIG_I2C_ALI1563=m CONFIG_I2C_ALI15X3=m @@ -3443,7 +3622,9 @@ CONFIG_I2C_MT65XX=m # External I2C/SMBus adapter drivers # # CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_CP2615 is not set CONFIG_I2C_PARPORT=m +# CONFIG_I2C_PCI1XXXX is not set # CONFIG_I2C_ROBOTFUZZ_OSIF is not set # CONFIG_I2C_TAOS_EVM is not set # CONFIG_I2C_TINY_USB is not set @@ -3452,11 +3633,13 @@ CONFIG_I2C_PARPORT=m # Other I2C/SMBus bus drivers # CONFIG_I2C_CROS_EC_TUNNEL=m +# CONFIG_I2C_VIRTIO is not set # end of I2C Hardware Bus support # CONFIG_I2C_STUB is not set CONFIG_I2C_SLAVE=y CONFIG_I2C_SLAVE_EEPROM=y +# CONFIG_I2C_SLAVE_TESTUNIT is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -3465,6 +3648,8 @@ CONFIG_I2C_SLAVE_EEPROM=y CONFIG_I3C=m CONFIG_CDNS_I3C_MASTER=m CONFIG_DW_I3C_MASTER=m +# CONFIG_SVC_I3C_MASTER is not set +# CONFIG_MIPI_I3C_HCI is not set CONFIG_SPI=y # CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y @@ -3478,22 +3663,27 @@ CONFIG_SPI_MEM=y CONFIG_SPI_BITBANG=y # CONFIG_SPI_BUTTERFLY is not set # CONFIG_SPI_CADENCE is not set +# CONFIG_SPI_CADENCE_QUADSPI is not set +# CONFIG_SPI_CADENCE_XSPI is not set # CONFIG_SPI_DESIGNWARE is not set -CONFIG_SPI_NXP_FLEXSPI=m CONFIG_SPI_GPIO=m # CONFIG_SPI_LM70_LLP is not set # CONFIG_SPI_FSL_SPI is not set +# CONFIG_SPI_MICROCHIP_CORE is not set +# CONFIG_SPI_MICROCHIP_CORE_QSPI is not set CONFIG_SPI_MT65XX=m CONFIG_SPI_MTK_NOR=m # CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PCI1XXXX is not set # CONFIG_SPI_PXA2XX is not set -# CONFIG_SPI_ROCKCHIP is not set # CONFIG_SPI_SC18IS602 is not set CONFIG_SPI_SIFIVE=m +# CONFIG_SPI_SN_F_OSPI is not set CONFIG_SPI_MXIC=m # CONFIG_SPI_XCOMM is not set # CONFIG_SPI_XILINX is not set # CONFIG_SPI_ZYNQMP_GQSPI is not set +# CONFIG_SPI_AMD is not set # # SPI Multiplexer support @@ -3507,7 +3697,10 @@ CONFIG_SPI_SPIDEV=m # CONFIG_SPI_LOOPBACK_TEST is not set # CONFIG_SPI_TLE62X0 is not set # CONFIG_SPI_SLAVE is not set +CONFIG_SPI_DYNAMIC=y CONFIG_SPMI=y +# CONFIG_SPMI_HISI3670 is not set +CONFIG_SPMI_MTK_PMIF=m # CONFIG_HSI is not set CONFIG_PPS=y # CONFIG_PPS_DEBUG is not set @@ -3528,10 +3721,14 @@ CONFIG_PPS_CLIENT_GPIO=m # PTP clock support # CONFIG_PTP_1588_CLOCK=y +CONFIG_PTP_1588_CLOCK_OPTIONAL=y CONFIG_DP83640_PHY=m CONFIG_PTP_1588_CLOCK_INES=m +CONFIG_PTP_1588_CLOCK_KVM=y CONFIG_PTP_1588_CLOCK_IDT82P33=m CONFIG_PTP_1588_CLOCK_IDTCM=m +# CONFIG_PTP_1588_CLOCK_MOCK is not set +# CONFIG_PTP_1588_CLOCK_OCP is not set # end of PTP clock support CONFIG_PINCTRL=y @@ -3541,35 +3738,41 @@ CONFIG_GENERIC_PINMUX_FUNCTIONS=y CONFIG_PINCONF=y CONFIG_GENERIC_PINCONF=y # CONFIG_DEBUG_PINCTRL is not set -# CONFIG_PINCTRL_AMD is not set +# CONFIG_PINCTRL_CY8C95X0 is not set # CONFIG_PINCTRL_MCP23S08 is not set +# CONFIG_PINCTRL_MICROCHIP_SGPIO is not set +# CONFIG_PINCTRL_OCELOT is not set CONFIG_PINCTRL_SINGLE=y -# CONFIG_PINCTRL_SX150X is not set CONFIG_PINCTRL_STMFX=m -# CONFIG_PINCTRL_OCELOT is not set +# CONFIG_PINCTRL_SX150X is not set # # MediaTek pinctrl drivers # CONFIG_EINT_MTK=y -CONFIG_PINCTRL_MTK=y +CONFIG_PINCTRL_MTK_V2=y CONFIG_PINCTRL_MTK_MOORE=y -CONFIG_PINCTRL_MT2701=y +# CONFIG_PINCTRL_MT2701 is not set CONFIG_PINCTRL_MT7623=y -CONFIG_PINCTRL_MT7629=y -CONFIG_PINCTRL_MT8135=y -CONFIG_PINCTRL_MT8127=y -CONFIG_PINCTRL_MT6397=y +# CONFIG_PINCTRL_MT7629 is not set +# CONFIG_PINCTRL_MT8135 is not set +# CONFIG_PINCTRL_MT8127 is not set +# CONFIG_PINCTRL_MT6397 is not set # end of MediaTek pinctrl drivers -CONFIG_PINCTRL_EQUILIBRIUM=m -CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +# +# Renesas pinctrl drivers +# +# end of Renesas pinctrl drivers + CONFIG_GPIOLIB=y CONFIG_GPIOLIB_FASTPATH_LIMIT=512 CONFIG_OF_GPIO=y CONFIG_GPIOLIB_IRQCHIP=y # CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_CDEV=y +CONFIG_GPIO_CDEV_V1=y CONFIG_GPIO_GENERIC=y # @@ -3587,7 +3790,6 @@ CONFIG_GPIO_GENERIC_PLATFORM=y CONFIG_GPIO_LOGICVC=m # CONFIG_GPIO_MB86S7X is not set # CONFIG_GPIO_MPC8XXX is not set -CONFIG_GPIO_SAMA5D2_PIOBU=m # CONFIG_GPIO_SIFIVE is not set CONFIG_GPIO_SYSCON=m # CONFIG_GPIO_XILINX is not set @@ -3598,12 +3800,14 @@ CONFIG_GPIO_AMD_FCH=m # # I2C GPIO expanders # -# CONFIG_GPIO_ADP5588 is not set # CONFIG_GPIO_ADNP is not set +# CONFIG_GPIO_FXL6408 is not set +# CONFIG_GPIO_DS4520 is not set CONFIG_GPIO_GW_PLD=m # CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCA9570 is not set # CONFIG_GPIO_PCF857X is not set # CONFIG_GPIO_TPIC2810 is not set # end of I2C GPIO expanders @@ -3611,7 +3815,7 @@ CONFIG_GPIO_GW_PLD=m # # MFD GPIO expanders # -CONFIG_GPIO_BD70528=m +# CONFIG_GPIO_BD71815 is not set CONFIG_GPIO_BD71828=m # CONFIG_HTC_EGPIO is not set CONFIG_GPIO_MAX77650=m @@ -3645,7 +3849,16 @@ CONFIG_GPIO_MOXTET=m # # end of USB GPIO expanders +# +# Virtual GPIO drivers +# +# CONFIG_GPIO_AGGREGATOR is not set +# CONFIG_GPIO_LATCH is not set # CONFIG_GPIO_MOCKUP is not set +# CONFIG_GPIO_VIRTIO is not set +# CONFIG_GPIO_SIM is not set +# end of Virtual GPIO drivers + CONFIG_W1=m # @@ -3654,7 +3867,6 @@ CONFIG_W1=m # CONFIG_W1_MASTER_MATROX is not set CONFIG_W1_MASTER_DS2490=m CONFIG_W1_MASTER_DS2482=m -# CONFIG_W1_MASTER_DS1WM is not set CONFIG_W1_MASTER_GPIO=m CONFIG_W1_MASTER_SGI=m # end of 1-wire Bus Masters @@ -3681,8 +3893,6 @@ CONFIG_W1_SLAVE_DS250X=m # CONFIG_W1_SLAVE_DS28E17 is not set # end of 1-wire Slaves -CONFIG_POWER_AVS=y -CONFIG_QCOM_CPR=m CONFIG_POWER_RESET=y CONFIG_POWER_RESET_BRCMKONA=y CONFIG_POWER_RESET_BRCMSTB=y @@ -3690,6 +3900,7 @@ CONFIG_POWER_RESET_GPIO=y CONFIG_POWER_RESET_GPIO_RESTART=y # CONFIG_POWER_RESET_LTC2952 is not set # CONFIG_POWER_RESET_MT6323 is not set +# CONFIG_POWER_RESET_REGULATOR is not set # CONFIG_POWER_RESET_RESTART is not set # CONFIG_POWER_RESET_VERSATILE is not set CONFIG_POWER_RESET_VEXPRESS=y @@ -3701,15 +3912,16 @@ CONFIG_NVMEM_REBOOT_MODE=m CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set CONFIG_POWER_SUPPLY_HWMON=y -# CONFIG_PDA_POWER is not set # CONFIG_GENERIC_ADC_BATTERY is not set +# CONFIG_IP5XXX_POWER is not set # CONFIG_TEST_POWER is not set CONFIG_CHARGER_ADP5061=m +# CONFIG_BATTERY_CW2015 is not set CONFIG_BATTERY_DS2760=m # CONFIG_BATTERY_DS2780 is not set # CONFIG_BATTERY_DS2781 is not set # CONFIG_BATTERY_DS2782 is not set -# CONFIG_BATTERY_LEGO_EV3 is not set +# CONFIG_BATTERY_SAMSUNG_SDI is not set CONFIG_BATTERY_SBS=y # CONFIG_CHARGER_SBS is not set # CONFIG_MANAGER_SBS is not set @@ -3724,19 +3936,30 @@ CONFIG_BATTERY_MAX17042=m # CONFIG_CHARGER_GPIO is not set # CONFIG_CHARGER_MANAGER is not set CONFIG_CHARGER_LT3651=m +# CONFIG_CHARGER_LTC4162L is not set # CONFIG_CHARGER_DETECTOR_MAX14656 is not set CONFIG_CHARGER_MAX77650=m +# CONFIG_CHARGER_MAX77976 is not set # CONFIG_CHARGER_BQ2415X is not set # CONFIG_CHARGER_BQ24190 is not set # CONFIG_CHARGER_BQ24257 is not set # CONFIG_CHARGER_BQ24735 is not set +# CONFIG_CHARGER_BQ2515X is not set # CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_BQ25980 is not set +# CONFIG_CHARGER_BQ256XX is not set # CONFIG_CHARGER_SMB347 is not set # CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_BATTERY_GOLDFISH is not set +# CONFIG_BATTERY_RT5033 is not set # CONFIG_CHARGER_RT9455 is not set +# CONFIG_CHARGER_RT9467 is not set +# CONFIG_CHARGER_RT9471 is not set CONFIG_CHARGER_CROS_USBPD=m +CONFIG_CHARGER_CROS_PCHG=m CONFIG_CHARGER_UCS1002=m -CONFIG_CHARGER_BD70528=m +# CONFIG_CHARGER_BD99954 is not set +# CONFIG_BATTERY_UG3105 is not set CONFIG_HWMON=y CONFIG_HWMON_VID=m # CONFIG_HWMON_DEBUG_CHIP is not set @@ -3747,7 +3970,6 @@ CONFIG_HWMON_VID=m CONFIG_SENSORS_AD7314=m CONFIG_SENSORS_AD7414=m CONFIG_SENSORS_AD7418=m -CONFIG_SENSORS_ADM1021=m CONFIG_SENSORS_ADM1025=m CONFIG_SENSORS_ADM1026=m CONFIG_SENSORS_ADM1029=m @@ -3761,11 +3983,14 @@ CONFIG_SENSORS_ADT7411=m CONFIG_SENSORS_ADT7462=m CONFIG_SENSORS_ADT7470=m CONFIG_SENSORS_ADT7475=m +# CONFIG_SENSORS_AHT10 is not set +# CONFIG_SENSORS_AQUACOMPUTER_D5NEXT is not set CONFIG_SENSORS_AS370=m CONFIG_SENSORS_ASC7621=m CONFIG_SENSORS_AXI_FAN_CONTROL=m -# CONFIG_SENSORS_ASPEED is not set CONFIG_SENSORS_ATXP1=m +# CONFIG_SENSORS_CORSAIR_CPRO is not set +# CONFIG_SENSORS_CORSAIR_PSU is not set CONFIG_SENSORS_DRIVETEMP=m CONFIG_SENSORS_DS620=m CONFIG_SENSORS_DS1621=m @@ -3780,6 +4005,7 @@ CONFIG_SENSORS_G760A=m CONFIG_SENSORS_G762=m CONFIG_SENSORS_GPIO_FAN=m CONFIG_SENSORS_HIH6130=m +# CONFIG_SENSORS_HS3001 is not set # CONFIG_SENSORS_IIO_HWMON is not set CONFIG_SENSORS_IT87=m CONFIG_SENSORS_JC42=m @@ -3790,6 +4016,7 @@ CONFIG_SENSORS_LTC2947=m CONFIG_SENSORS_LTC2947_I2C=m CONFIG_SENSORS_LTC2947_SPI=m CONFIG_SENSORS_LTC2990=m +# CONFIG_SENSORS_LTC2992 is not set CONFIG_SENSORS_LTC4151=m CONFIG_SENSORS_LTC4215=m CONFIG_SENSORS_LTC4222=m @@ -3797,20 +4024,26 @@ CONFIG_SENSORS_LTC4245=m CONFIG_SENSORS_LTC4260=m CONFIG_SENSORS_LTC4261=m CONFIG_SENSORS_MAX1111=m +# CONFIG_SENSORS_MAX127 is not set CONFIG_SENSORS_MAX16065=m CONFIG_SENSORS_MAX1619=m CONFIG_SENSORS_MAX1668=m CONFIG_SENSORS_MAX197=m CONFIG_SENSORS_MAX31722=m CONFIG_SENSORS_MAX31730=m +# CONFIG_SENSORS_MAX31760 is not set +# CONFIG_MAX31827 is not set +# CONFIG_SENSORS_MAX6620 is not set # CONFIG_SENSORS_MAX6621 is not set CONFIG_SENSORS_MAX6639=m -CONFIG_SENSORS_MAX6642=m CONFIG_SENSORS_MAX6650=m CONFIG_SENSORS_MAX6697=m CONFIG_SENSORS_MAX31790=m +# CONFIG_SENSORS_MC34VR500 is not set CONFIG_SENSORS_MCP3021=m # CONFIG_SENSORS_TC654 is not set +# CONFIG_SENSORS_TPS23861 is not set +# CONFIG_SENSORS_MR75203 is not set CONFIG_SENSORS_ADCXX=m CONFIG_SENSORS_LM63=m CONFIG_SENSORS_LM70=m @@ -3832,23 +4065,29 @@ CONFIG_SENSORS_PC87360=m CONFIG_SENSORS_PC87427=m CONFIG_SENSORS_NTC_THERMISTOR=m CONFIG_SENSORS_NCT6683=m -CONFIG_SENSORS_NCT6775=m +# CONFIG_SENSORS_NCT6775_I2C is not set CONFIG_SENSORS_NCT7802=m CONFIG_SENSORS_NCT7904=m CONFIG_SENSORS_NPCM7XX=m +# CONFIG_SENSORS_NZXT_KRAKEN2 is not set +# CONFIG_SENSORS_NZXT_SMART2 is not set CONFIG_SENSORS_OCC_P8_I2C=m CONFIG_SENSORS_OCC=m CONFIG_SENSORS_PCF8591=m # CONFIG_PMBUS is not set CONFIG_SENSORS_PWM_FAN=m +# CONFIG_SENSORS_SBTSI is not set +# CONFIG_SENSORS_SBRMI is not set CONFIG_SENSORS_SHT15=m CONFIG_SENSORS_SHT21=m CONFIG_SENSORS_SHT3x=m +# CONFIG_SENSORS_SHT4x is not set CONFIG_SENSORS_SHTC1=m CONFIG_SENSORS_SIS5595=m CONFIG_SENSORS_DME1737=m CONFIG_SENSORS_EMC1403=m CONFIG_SENSORS_EMC2103=m +# CONFIG_SENSORS_EMC2305 is not set CONFIG_SENSORS_EMC6W201=m CONFIG_SENSORS_SMSC47M1=m CONFIG_SENSORS_SMSC47M192=m @@ -3857,13 +4096,13 @@ CONFIG_SENSORS_SCH56XX_COMMON=m CONFIG_SENSORS_SCH5627=m CONFIG_SENSORS_SCH5636=m CONFIG_SENSORS_STTS751=m -CONFIG_SENSORS_SMM665=m CONFIG_SENSORS_ADC128D818=m CONFIG_SENSORS_ADS7828=m CONFIG_SENSORS_ADS7871=m CONFIG_SENSORS_AMC6821=m CONFIG_SENSORS_INA209=m CONFIG_SENSORS_INA2XX=m +# CONFIG_SENSORS_INA238 is not set CONFIG_SENSORS_INA3221=m CONFIG_SENSORS_TC74=m CONFIG_SENSORS_THMC50=m @@ -3872,6 +4111,7 @@ CONFIG_SENSORS_TMP103=m # CONFIG_SENSORS_TMP108 is not set CONFIG_SENSORS_TMP401=m CONFIG_SENSORS_TMP421=m +# CONFIG_SENSORS_TMP464 is not set CONFIG_SENSORS_TMP513=m CONFIG_SENSORS_VEXPRESS=m # CONFIG_SENSORS_VIA686A is not set @@ -3889,6 +4129,7 @@ CONFIG_SENSORS_W83L786NG=m CONFIG_SENSORS_W83627HF=m CONFIG_SENSORS_W83627EHF=m CONFIG_THERMAL=y +# CONFIG_THERMAL_NETLINK is not set # CONFIG_THERMAL_STATISTICS is not set CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 CONFIG_THERMAL_HWMON=y @@ -3897,18 +4138,26 @@ CONFIG_THERMAL_WRITABLE_TRIPS=y # CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE is not set # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE=y +# CONFIG_THERMAL_DEFAULT_GOV_BANG_BANG is not set CONFIG_THERMAL_GOV_FAIR_SHARE=y CONFIG_THERMAL_GOV_STEP_WISE=y CONFIG_THERMAL_GOV_BANG_BANG=y CONFIG_THERMAL_GOV_USER_SPACE=y CONFIG_CPU_THERMAL=y CONFIG_CPU_FREQ_THERMAL=y -# CONFIG_CLOCK_THERMAL is not set # CONFIG_DEVFREQ_THERMAL is not set # CONFIG_THERMAL_EMULATION is not set CONFIG_THERMAL_MMIO=m -# CONFIG_QORIQ_THERMAL is not set + +# +# Mediatek thermal drivers +# CONFIG_MTK_THERMAL=y +CONFIG_MTK_SOC_THERMAL=m +CONFIG_MTK_LVTS_THERMAL=m +# CONFIG_MTK_LVTS_THERMAL_DEBUGFS is not set +# end of Mediatek thermal drivers + # CONFIG_GENERIC_ADC_THERMAL is not set CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y @@ -3916,6 +4165,7 @@ CONFIG_WATCHDOG_CORE=y CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y CONFIG_WATCHDOG_OPEN_TIMEOUT=0 # CONFIG_WATCHDOG_SYSFS is not set +# CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set # # Watchdog Pretimeout Governors @@ -3926,7 +4176,6 @@ CONFIG_WATCHDOG_OPEN_TIMEOUT=0 # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_BD70528_WATCHDOG=m # CONFIG_GPIO_WATCHDOG is not set # CONFIG_XILINX_WATCHDOG is not set # CONFIG_ZIIRAVE_WATCHDOG is not set @@ -3936,6 +4185,7 @@ CONFIG_BD70528_WATCHDOG=m # CONFIG_TWL4030_WATCHDOG is not set # CONFIG_MAX63XX_WATCHDOG is not set CONFIG_MEDIATEK_WATCHDOG=y +# CONFIG_ARM_SMC_WATCHDOG is not set CONFIG_STPMIC1_WATCHDOG=m # CONFIG_ALIM7101_WDT is not set # CONFIG_I6300ESB_WDT is not set @@ -3980,6 +4230,7 @@ CONFIG_BCMA_DRIVER_PCI=y CONFIG_MFD_CORE=y # CONFIG_MFD_ACT8945A is not set # CONFIG_MFD_AS3711 is not set +# CONFIG_MFD_SMPRO is not set # CONFIG_MFD_AS3722 is not set # CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_AAT2870_CORE is not set @@ -3989,8 +4240,10 @@ CONFIG_MFD_CORE=y # CONFIG_MFD_BD9571MWV is not set # CONFIG_MFD_AXP20X_I2C is not set CONFIG_MFD_CROS_EC_DEV=m +# CONFIG_MFD_CS42L43_I2C is not set +# CONFIG_MFD_CS42L43_SDW is not set # CONFIG_MFD_MADERA is not set -# CONFIG_MFD_ASIC3 is not set +# CONFIG_MFD_MAX5970 is not set # CONFIG_PMIC_DA903X is not set # CONFIG_MFD_DA9052_SPI is not set # CONFIG_MFD_DA9052_I2C is not set @@ -3999,11 +4252,12 @@ CONFIG_MFD_CROS_EC_DEV=m # CONFIG_MFD_DA9063 is not set # CONFIG_MFD_DA9150 is not set # CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_GATEWORKS_GSC is not set # CONFIG_MFD_MC13XXX_SPI is not set # CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_MP2629 is not set # CONFIG_MFD_HI6421_PMIC is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_HTC_I2CPLD is not set +# CONFIG_MFD_HI6421_SPMI is not set # CONFIG_LPC_ICH is not set CONFIG_LPC_SCH=m CONFIG_MFD_IQS62X=m @@ -4013,37 +4267,44 @@ CONFIG_MFD_IQS62X=m # CONFIG_MFD_88PM805 is not set # CONFIG_MFD_88PM860X is not set # CONFIG_MFD_MAX14577 is not set +# CONFIG_MFD_MAX77541 is not set # CONFIG_MFD_MAX77620 is not set CONFIG_MFD_MAX77650=m # CONFIG_MFD_MAX77686 is not set # CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77714 is not set # CONFIG_MFD_MAX77843 is not set # CONFIG_MFD_MAX8907 is not set # CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_MAX8997 is not set # CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6360 is not set +# CONFIG_MFD_MT6370 is not set CONFIG_MFD_MT6397=y # CONFIG_MFD_MENF21BMC is not set +# CONFIG_MFD_OCELOT is not set # CONFIG_EZX_PCAP is not set # CONFIG_MFD_CPCAP is not set # CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_NTXEC is not set # CONFIG_MFD_RETU is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_MFD_PM8XXX is not set +# CONFIG_MFD_SY7636A is not set # CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_RT4831 is not set # CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RT5120 is not set # CONFIG_MFD_RC5T583 is not set -# CONFIG_MFD_RK808 is not set +# CONFIG_MFD_RK8XX_I2C is not set +# CONFIG_MFD_RK8XX_SPI is not set # CONFIG_MFD_RN5T618 is not set # CONFIG_MFD_SEC_CORE is not set # CONFIG_MFD_SI476X_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SKY81452 is not set -# CONFIG_MFD_SMSC is not set -# CONFIG_ABX500_CORE is not set # CONFIG_MFD_STMPE is not set CONFIG_MFD_SYSCON=y -# CONFIG_MFD_TI_AM335X_TSCADC is not set # CONFIG_MFD_LP3943 is not set # CONFIG_MFD_LP8788 is not set # CONFIG_MFD_TI_LMU is not set @@ -4057,11 +4318,13 @@ CONFIG_MFD_SYSCON=y # CONFIG_MFD_TI_LP873X is not set # CONFIG_MFD_TI_LP87565 is not set # CONFIG_MFD_TPS65218 is not set +# CONFIG_MFD_TPS65219 is not set # CONFIG_MFD_TPS6586X is not set # CONFIG_MFD_TPS65910 is not set # CONFIG_MFD_TPS65912_I2C is not set # CONFIG_MFD_TPS65912_SPI is not set -# CONFIG_MFD_TPS80031 is not set +# CONFIG_MFD_TPS6594_I2C is not set +# CONFIG_MFD_TPS6594_SPI is not set CONFIG_TWL4030_CORE=y CONFIG_TWL4030_POWER=y # CONFIG_MFD_TWL4030_AUDIO is not set @@ -4069,9 +4332,6 @@ CONFIG_TWL4030_POWER=y # CONFIG_MFD_WL1273_CORE is not set # CONFIG_MFD_LM3533 is not set # CONFIG_MFD_TC3589X is not set -# CONFIG_MFD_T7L66XB is not set -# CONFIG_MFD_TC6387XB is not set -# CONFIG_MFD_TC6393XB is not set CONFIG_MFD_TQMX86=m # CONFIG_MFD_VX855 is not set # CONFIG_MFD_LOCHNAGAR is not set @@ -4083,11 +4343,16 @@ CONFIG_MFD_TQMX86=m # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_WM8994 is not set CONFIG_MFD_ROHM_BD718XX=m -CONFIG_MFD_ROHM_BD70528=m CONFIG_MFD_ROHM_BD71828=m +# CONFIG_MFD_ROHM_BD957XMUF is not set CONFIG_MFD_STPMIC1=m CONFIG_MFD_STMFX=m +# CONFIG_MFD_ATC260X_I2C is not set +# CONFIG_MFD_QCOM_PM8008 is not set CONFIG_MFD_VEXPRESS_SYSREG=y +# CONFIG_MFD_INTEL_M10_BMC_SPI is not set +# CONFIG_MFD_RSMU_I2C is not set +# CONFIG_MFD_RSMU_SPI is not set # end of Multifunction device drivers CONFIG_REGULATOR=y @@ -4098,12 +4363,16 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y # CONFIG_REGULATOR_88PG86X is not set # CONFIG_REGULATOR_ACT8865 is not set # CONFIG_REGULATOR_AD5398 is not set -CONFIG_REGULATOR_BD70528=m +# CONFIG_REGULATOR_AW37503 is not set +# CONFIG_REGULATOR_BD71815 is not set CONFIG_REGULATOR_BD71828=m CONFIG_REGULATOR_BD718XX=m +# CONFIG_REGULATOR_CROS_EC is not set +# CONFIG_REGULATOR_DA9121 is not set # CONFIG_REGULATOR_DA9210 is not set # CONFIG_REGULATOR_DA9211 is not set # CONFIG_REGULATOR_FAN53555 is not set +# CONFIG_REGULATOR_FAN53880 is not set # CONFIG_REGULATOR_GPIO is not set # CONFIG_REGULATOR_ISL9305 is not set # CONFIG_REGULATOR_ISL6271A is not set @@ -4115,32 +4384,63 @@ CONFIG_REGULATOR_BD718XX=m # CONFIG_REGULATOR_LTC3676 is not set # CONFIG_REGULATOR_MAX1586 is not set CONFIG_REGULATOR_MAX77650=m +# CONFIG_REGULATOR_MAX77857 is not set # CONFIG_REGULATOR_MAX8649 is not set # CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_MAX8893 is not set # CONFIG_REGULATOR_MAX8952 is not set # CONFIG_REGULATOR_MAX8973 is not set +# CONFIG_REGULATOR_MAX20086 is not set +# CONFIG_REGULATOR_MAX20411 is not set +# CONFIG_REGULATOR_MAX77826 is not set CONFIG_REGULATOR_MCP16502=m CONFIG_REGULATOR_MP5416=m CONFIG_REGULATOR_MP8859=m CONFIG_REGULATOR_MP886X=m CONFIG_REGULATOR_MPQ7920=m # CONFIG_REGULATOR_MT6311 is not set +# CONFIG_REGULATOR_MT6315 is not set CONFIG_REGULATOR_MT6323=y +# CONFIG_REGULATOR_MT6331 is not set +# CONFIG_REGULATOR_MT6332 is not set +# CONFIG_REGULATOR_MT6357 is not set +# CONFIG_REGULATOR_MT6358 is not set +# CONFIG_REGULATOR_MT6359 is not set # CONFIG_REGULATOR_MT6380 is not set # CONFIG_REGULATOR_MT6397 is not set +# CONFIG_REGULATOR_PCA9450 is not set +# CONFIG_REGULATOR_PF8X00 is not set # CONFIG_REGULATOR_PFUZE100 is not set # CONFIG_REGULATOR_PV88060 is not set # CONFIG_REGULATOR_PV88080 is not set # CONFIG_REGULATOR_PV88090 is not set # CONFIG_REGULATOR_PWM is not set # CONFIG_REGULATOR_QCOM_SPMI is not set +# CONFIG_REGULATOR_QCOM_USB_VBUS is not set +# CONFIG_REGULATOR_RAA215300 is not set +# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY is not set CONFIG_REGULATOR_ROHM=m +# CONFIG_REGULATOR_RT4801 is not set +# CONFIG_REGULATOR_RT4803 is not set +# CONFIG_REGULATOR_RT5190A is not set +# CONFIG_REGULATOR_RT5739 is not set +# CONFIG_REGULATOR_RT5759 is not set +# CONFIG_REGULATOR_RT6160 is not set +# CONFIG_REGULATOR_RT6190 is not set +# CONFIG_REGULATOR_RT6245 is not set +# CONFIG_REGULATOR_RTQ2134 is not set +# CONFIG_REGULATOR_RTMV20 is not set +# CONFIG_REGULATOR_RTQ6752 is not set +# CONFIG_REGULATOR_RTQ2208 is not set CONFIG_REGULATOR_SLG51000=m CONFIG_REGULATOR_STPMIC1=m # CONFIG_REGULATOR_SY8106A is not set CONFIG_REGULATOR_SY8824X=m +# CONFIG_REGULATOR_SY8827N is not set # CONFIG_REGULATOR_TPS51632 is not set # CONFIG_REGULATOR_TPS62360 is not set +# CONFIG_REGULATOR_TPS6286X is not set +# CONFIG_REGULATOR_TPS6287X is not set # CONFIG_REGULATOR_TPS65023 is not set # CONFIG_REGULATOR_TPS6507X is not set # CONFIG_REGULATOR_TPS65132 is not set @@ -4148,65 +4448,115 @@ CONFIG_REGULATOR_SY8824X=m # CONFIG_REGULATOR_TWL4030 is not set # CONFIG_REGULATOR_VCTRL is not set # CONFIG_REGULATOR_VEXPRESS is not set -CONFIG_CEC_CORE=m -CONFIG_CEC_NOTIFIER=y +# CONFIG_REGULATOR_QCOM_LABIBB is not set CONFIG_RC_CORE=m -CONFIG_RC_MAP=m CONFIG_LIRC=y +CONFIG_RC_MAP=m CONFIG_RC_DECODERS=y +CONFIG_IR_IMON_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m CONFIG_IR_NEC_DECODER=m CONFIG_IR_RC5_DECODER=m CONFIG_IR_RC6_DECODER=m -CONFIG_IR_JVC_DECODER=m -CONFIG_IR_SONY_DECODER=m +CONFIG_IR_RCMM_DECODER=m CONFIG_IR_SANYO_DECODER=m CONFIG_IR_SHARP_DECODER=m -CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_SONY_DECODER=m CONFIG_IR_XMP_DECODER=m -CONFIG_IR_IMON_DECODER=m -CONFIG_IR_RCMM_DECODER=m CONFIG_RC_DEVICES=y -# CONFIG_RC_ATI_REMOTE is not set +CONFIG_IR_GPIO_CIR=m +# CONFIG_IR_GPIO_TX is not set # CONFIG_IR_HIX5HD2 is not set +# CONFIG_IR_IGORPLUGUSB is not set +# CONFIG_IR_IGUANA is not set # CONFIG_IR_IMON is not set # CONFIG_IR_IMON_RAW is not set # CONFIG_IR_MCEUSB is not set CONFIG_IR_MTK=m +# CONFIG_IR_PWM_TX is not set # CONFIG_IR_REDRAT3 is not set +# CONFIG_IR_SERIAL is not set # CONFIG_IR_SPI is not set # CONFIG_IR_STREAMZAP is not set -# CONFIG_IR_IGORPLUGUSB is not set -# CONFIG_IR_IGUANA is not set +# CONFIG_IR_TOY is not set # CONFIG_IR_TTUSBIR is not set +# CONFIG_RC_ATI_REMOTE is not set # CONFIG_RC_LOOPBACK is not set -CONFIG_IR_GPIO_CIR=m -# CONFIG_IR_GPIO_TX is not set -# CONFIG_IR_PWM_TX is not set -# CONFIG_IR_SERIAL is not set -# CONFIG_IR_SIR is not set CONFIG_RC_XBOX_DVD=m +CONFIG_CEC_CORE=m + +# +# CEC support +# +# CONFIG_MEDIA_CEC_RC is not set +CONFIG_MEDIA_CEC_SUPPORT=y +# CONFIG_CEC_CH7322 is not set +# CONFIG_CEC_CROS_EC is not set +CONFIG_USB_PULSE8_CEC=m +# CONFIG_USB_RAINSHADOW_CEC is not set +# end of CEC support + CONFIG_MEDIA_SUPPORT=m +# CONFIG_MEDIA_SUPPORT_FILTER is not set +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set # -# Multimedia core support +# Media device types # CONFIG_MEDIA_CAMERA_SUPPORT=y -# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set -# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set -# CONFIG_MEDIA_RADIO_SUPPORT is not set -# CONFIG_MEDIA_SDR_SUPPORT is not set -CONFIG_MEDIA_CEC_SUPPORT=y -# CONFIG_MEDIA_CEC_RC is not set -CONFIG_MEDIA_CONTROLLER=y +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_SDR_SUPPORT=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y +CONFIG_MEDIA_TEST_SUPPORT=y +# end of Media device types + +# +# Media core support +# CONFIG_VIDEO_DEV=m -CONFIG_VIDEO_V4L2_SUBDEV_API=y -CONFIG_VIDEO_V4L2=m +CONFIG_MEDIA_CONTROLLER=y +CONFIG_DVB_CORE=m +# end of Media core support + +# +# Video4Linux options +# CONFIG_VIDEO_V4L2_I2C=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y # CONFIG_VIDEO_ADV_DEBUG is not set # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set CONFIG_V4L2_MEM2MEM_DEV=m # CONFIG_V4L2_FLASH_LED_CLASS is not set CONFIG_V4L2_FWNODE=m +CONFIG_V4L2_ASYNC=m +CONFIG_V4L2_CCI=m +CONFIG_V4L2_CCI_I2C=m +# end of Video4Linux options + +# +# Media controller options +# +# CONFIG_MEDIA_CONTROLLER_DVB is not set +CONFIG_MEDIA_CONTROLLER_REQUEST_API=y +# end of Media controller options + +# +# Digital TV options +# +# CONFIG_DVB_MMAP is not set +CONFIG_DVB_NET=y +CONFIG_DVB_MAX_ADAPTERS=16 +CONFIG_DVB_DYNAMIC_MINORS=y +# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set +# CONFIG_DVB_ULE_DEBUG is not set +# end of Digital TV options + +# +# Media drivers +# # # Media drivers @@ -4216,12 +4566,7 @@ CONFIG_MEDIA_USB_SUPPORT=y # # Webcam devices # -CONFIG_USB_VIDEO_CLASS=m -CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y CONFIG_USB_GSPCA=m -# CONFIG_USB_M5602 is not set -# CONFIG_USB_STV06XX is not set -# CONFIG_USB_GL860 is not set # CONFIG_USB_GSPCA_BENQ is not set # CONFIG_USB_GSPCA_CONEX is not set # CONFIG_USB_GSPCA_CPIA1 is not set @@ -4246,13 +4591,13 @@ CONFIG_USB_GSPCA=m # CONFIG_USB_GSPCA_SN9C20X is not set # CONFIG_USB_GSPCA_SONIXB is not set # CONFIG_USB_GSPCA_SONIXJ is not set +# CONFIG_USB_GSPCA_SPCA1528 is not set # CONFIG_USB_GSPCA_SPCA500 is not set # CONFIG_USB_GSPCA_SPCA501 is not set # CONFIG_USB_GSPCA_SPCA505 is not set # CONFIG_USB_GSPCA_SPCA506 is not set # CONFIG_USB_GSPCA_SPCA508 is not set # CONFIG_USB_GSPCA_SPCA561 is not set -# CONFIG_USB_GSPCA_SPCA1528 is not set # CONFIG_USB_GSPCA_SQ905 is not set # CONFIG_USB_GSPCA_SQ905C is not set # CONFIG_USB_GSPCA_SQ930X is not set @@ -4268,12 +4613,39 @@ CONFIG_USB_GSPCA=m # CONFIG_USB_GSPCA_VICAM is not set # CONFIG_USB_GSPCA_XIRLINK_CIT is not set # CONFIG_USB_GSPCA_ZC3XX is not set +# CONFIG_USB_GL860 is not set +# CONFIG_USB_M5602 is not set +# CONFIG_USB_STV06XX is not set # CONFIG_USB_PWC is not set -# CONFIG_VIDEO_CPIA2 is not set -# CONFIG_USB_ZR364XX is not set -# CONFIG_USB_STKWEBCAM is not set # CONFIG_USB_S2255 is not set # CONFIG_VIDEO_USBTV is not set +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y + +# +# Analog TV USB devices +# +# CONFIG_VIDEO_GO7007 is not set +# CONFIG_VIDEO_HDPVR is not set +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_STK1160 is not set + +# +# Analog/digital TV USB devices +# +# CONFIG_VIDEO_AU0828 is not set +# CONFIG_VIDEO_CX231XX is not set + +# +# Digital TV USB devices +# +# CONFIG_DVB_AS102 is not set +# CONFIG_DVB_B2C2_FLEXCOP_USB is not set +# CONFIG_DVB_USB_V2 is not set +# CONFIG_DVB_USB is not set +# CONFIG_SMS_USB_DRV is not set +# CONFIG_DVB_TTUSB_BUDGET is not set +# CONFIG_DVB_TTUSB_DEC is not set # # Webcam, TV (analog/digital) USB devices @@ -4281,79 +4653,274 @@ CONFIG_USB_GSPCA=m # CONFIG_VIDEO_EM28XX is not set # -# USB HDMI CEC adapters +# Software defined radio USB devices # -CONFIG_USB_PULSE8_CEC=m -# CONFIG_USB_RAINSHADOW_CEC is not set +# CONFIG_USB_AIRSPY is not set +# CONFIG_USB_HACKRF is not set +# CONFIG_USB_MSI2500 is not set # CONFIG_MEDIA_PCI_SUPPORT is not set +CONFIG_RADIO_ADAPTERS=m +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_SAA7706H is not set +# CONFIG_RADIO_SHARK is not set +# CONFIG_RADIO_SHARK2 is not set +# CONFIG_RADIO_SI4713 is not set +# CONFIG_RADIO_TEA5764 is not set +# CONFIG_RADIO_TEF6862 is not set +# CONFIG_RADIO_WL1273 is not set +# CONFIG_USB_DSBR is not set +# CONFIG_USB_KEENE is not set +# CONFIG_USB_MA901 is not set +# CONFIG_USB_MR800 is not set +# CONFIG_USB_RAREMONO is not set +# CONFIG_RADIO_SI470X is not set +CONFIG_MEDIA_PLATFORM_DRIVERS=y CONFIG_V4L_PLATFORM_DRIVERS=y -# CONFIG_VIDEO_CAFE_CCIC is not set -# CONFIG_VIDEO_CADENCE is not set -CONFIG_VIDEO_ASPEED=m -# CONFIG_VIDEO_MUX is not set -# CONFIG_VIDEO_XILINX is not set +# CONFIG_SDR_PLATFORM_DRIVERS is not set +# CONFIG_DVB_PLATFORM_DRIVERS is not set CONFIG_V4L_MEM2MEM_DRIVERS=y +# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set +# CONFIG_VIDEO_MUX is not set + +# +# Allegro DVT media platform drivers +# + +# +# Amlogic media platform drivers +# + +# +# Amphion drivers +# + +# +# Aspeed media platform drivers +# + +# +# Atmel media platform drivers +# + +# +# Cadence media platform drivers +# +# CONFIG_VIDEO_CADENCE_CSI2RX is not set +# CONFIG_VIDEO_CADENCE_CSI2TX is not set + +# +# Chips&Media media platform drivers +# + +# +# Intel media platform drivers +# + +# +# Marvell media platform drivers +# +# CONFIG_VIDEO_CAFE_CCIC is not set + +# +# Mediatek media platform drivers +# CONFIG_VIDEO_MEDIATEK_JPEG=m -# CONFIG_VIDEO_MEDIATEK_VPU is not set # CONFIG_VIDEO_MEDIATEK_MDP is not set -# CONFIG_VIDEO_MEDIATEK_VCODEC is not set -# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set -# CONFIG_VIDEO_SH_VEU is not set +# CONFIG_VIDEO_MEDIATEK_VPU is not set + +# +# Microchip Technology, Inc. media platform drivers +# + +# +# NVidia media platform drivers +# + +# +# NXP media platform drivers +# + +# +# Qualcomm media platform drivers +# + +# +# Renesas media platform drivers +# + +# +# Rockchip media platform drivers +# + +# +# Samsung media platform drivers +# + +# +# STMicroelectronics media platform drivers +# + +# +# Sunxi media platform drivers +# + +# +# Texas Instruments drivers +# + +# +# Verisilicon media platform drivers +# + +# +# VIA media platform drivers +# + +# +# Xilinx media platform drivers +# +# CONFIG_VIDEO_XILINX is not set + +# +# MMC/SDIO DVB adapters +# +# CONFIG_SMS_SDIO_DRV is not set CONFIG_V4L_TEST_DRIVERS=y +# CONFIG_VIDEO_VIM2M is not set +CONFIG_VIDEO_VICODEC=m # CONFIG_VIDEO_VIMC is not set CONFIG_VIDEO_VIVID=m # CONFIG_VIDEO_VIVID_CEC is not set CONFIG_VIDEO_VIVID_MAX_DEVS=64 -# CONFIG_VIDEO_VIM2M is not set -CONFIG_VIDEO_VICODEC=m -CONFIG_CEC_PLATFORM_DRIVERS=y -CONFIG_VIDEO_CROS_EC_CEC=m - -# -# Supported MMC/SDIO adapters -# -# CONFIG_CYPRESS_FIRMWARE is not set +# CONFIG_VIDEO_VISL is not set +# CONFIG_DVB_TEST_DRIVERS is not set +CONFIG_UVC_COMMON=m +CONFIG_VIDEO_V4L2_TPG=m CONFIG_VIDEOBUF2_CORE=m CONFIG_VIDEOBUF2_V4L2=m CONFIG_VIDEOBUF2_MEMOPS=m CONFIG_VIDEOBUF2_DMA_CONTIG=m CONFIG_VIDEOBUF2_VMALLOC=m -CONFIG_VIDEO_V4L2_TPG=m +CONFIG_VIDEOBUF2_DMA_SG=m +# end of Media drivers # -# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) +# Media ancillary drivers # -# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +CONFIG_MEDIA_ATTACH=y CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_CAMERA_SENSOR=y +# CONFIG_VIDEO_AR0521 is not set +CONFIG_VIDEO_HI556=m +# CONFIG_VIDEO_HI846 is not set +# CONFIG_VIDEO_HI847 is not set +# CONFIG_VIDEO_IMX208 is not set +CONFIG_VIDEO_IMX214=m +CONFIG_VIDEO_IMX219=m +# CONFIG_VIDEO_IMX258 is not set +# CONFIG_VIDEO_IMX274 is not set +CONFIG_VIDEO_IMX290=m +# CONFIG_VIDEO_IMX296 is not set +CONFIG_VIDEO_IMX319=m +# CONFIG_VIDEO_IMX334 is not set +# CONFIG_VIDEO_IMX335 is not set +CONFIG_VIDEO_IMX355=m +# CONFIG_VIDEO_IMX412 is not set +# CONFIG_VIDEO_IMX415 is not set +CONFIG_VIDEO_MT9M001=m +# CONFIG_VIDEO_MT9M111 is not set +# CONFIG_VIDEO_MT9P031 is not set +# CONFIG_VIDEO_MT9T112 is not set +# CONFIG_VIDEO_MT9V011 is not set +# CONFIG_VIDEO_MT9V032 is not set +CONFIG_VIDEO_MT9V111=m +# CONFIG_VIDEO_OG01A1B is not set +# CONFIG_VIDEO_OV01A10 is not set +# CONFIG_VIDEO_OV02A10 is not set +# CONFIG_VIDEO_OV08D10 is not set +# CONFIG_VIDEO_OV08X40 is not set +# CONFIG_VIDEO_OV13858 is not set +# CONFIG_VIDEO_OV13B10 is not set +# CONFIG_VIDEO_OV2640 is not set +# CONFIG_VIDEO_OV2659 is not set +CONFIG_VIDEO_OV2680=m +# CONFIG_VIDEO_OV2685 is not set +# CONFIG_VIDEO_OV4689 is not set +# CONFIG_VIDEO_OV5640 is not set +# CONFIG_VIDEO_OV5645 is not set +# CONFIG_VIDEO_OV5647 is not set +# CONFIG_VIDEO_OV5648 is not set +# CONFIG_VIDEO_OV5670 is not set +CONFIG_VIDEO_OV5675=m +# CONFIG_VIDEO_OV5693 is not set +# CONFIG_VIDEO_OV5695 is not set +# CONFIG_VIDEO_OV6650 is not set +# CONFIG_VIDEO_OV7251 is not set +# CONFIG_VIDEO_OV7640 is not set +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_OV772X is not set +# CONFIG_VIDEO_OV7740 is not set +CONFIG_VIDEO_OV8856=m +# CONFIG_VIDEO_OV8858 is not set +# CONFIG_VIDEO_OV8865 is not set +# CONFIG_VIDEO_OV9282 is not set +CONFIG_VIDEO_OV9640=m +# CONFIG_VIDEO_OV9650 is not set +# CONFIG_VIDEO_RDACM20 is not set +# CONFIG_VIDEO_RDACM21 is not set +# CONFIG_VIDEO_RJ54N1 is not set +# CONFIG_VIDEO_S5C73M3 is not set +# CONFIG_VIDEO_S5K5BAF is not set +# CONFIG_VIDEO_S5K6A3 is not set +# CONFIG_VIDEO_ST_VGXY61 is not set +# CONFIG_VIDEO_CCS is not set +# CONFIG_VIDEO_ET8EK8 is not set # -# I2C Encoders, decoders, sensors and other helper chips +# Lens drivers # +# CONFIG_VIDEO_AD5820 is not set +CONFIG_VIDEO_AK7375=m +# CONFIG_VIDEO_DW9714 is not set +# CONFIG_VIDEO_DW9719 is not set +# CONFIG_VIDEO_DW9768 is not set +# CONFIG_VIDEO_DW9807_VCM is not set +# end of Lens drivers + +# +# Flash devices +# +# CONFIG_VIDEO_ADP1653 is not set +# CONFIG_VIDEO_LM3560 is not set +# CONFIG_VIDEO_LM3646 is not set +# end of Flash devices # # Audio decoders, processors and mixers # -# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_CS3308 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_SONY_BTF_MPX is not set +# CONFIG_VIDEO_TDA1997X is not set # CONFIG_VIDEO_TDA7432 is not set # CONFIG_VIDEO_TDA9840 is not set -# CONFIG_VIDEO_TDA1997X is not set # CONFIG_VIDEO_TEA6415C is not set # CONFIG_VIDEO_TEA6420 is not set -# CONFIG_VIDEO_MSP3400 is not set -# CONFIG_VIDEO_CS3308 is not set -# CONFIG_VIDEO_CS5345 is not set -# CONFIG_VIDEO_CS53L32A is not set # CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_TVAUDIO is not set # CONFIG_VIDEO_UDA1342 is not set -# CONFIG_VIDEO_WM8775 is not set -# CONFIG_VIDEO_WM8739 is not set # CONFIG_VIDEO_VP27SMPX is not set -# CONFIG_VIDEO_SONY_BTF_MPX is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_WM8775 is not set +# end of Audio decoders, processors and mixers # # RDS decoders # # CONFIG_VIDEO_SAA6588 is not set +# end of RDS decoders # # Video decoders @@ -4366,11 +4933,14 @@ CONFIG_VIDEO_ADV7180=m # CONFIG_VIDEO_BT819 is not set # CONFIG_VIDEO_BT856 is not set # CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_ISL7998X is not set # CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_MAX9286 is not set CONFIG_VIDEO_ML86V7667=m # CONFIG_VIDEO_SAA7110 is not set # CONFIG_VIDEO_SAA711X is not set # CONFIG_VIDEO_TC358743 is not set +# CONFIG_VIDEO_TC358746 is not set # CONFIG_VIDEO_TVP514X is not set # CONFIG_VIDEO_TVP5150 is not set # CONFIG_VIDEO_TVP7002 is not set @@ -4385,155 +4955,303 @@ CONFIG_VIDEO_ML86V7667=m # # CONFIG_VIDEO_SAA717X is not set # CONFIG_VIDEO_CX25840 is not set +# end of Video decoders # # Video encoders # -# CONFIG_VIDEO_SAA7127 is not set -# CONFIG_VIDEO_SAA7185 is not set # CONFIG_VIDEO_ADV7170 is not set # CONFIG_VIDEO_ADV7175 is not set # CONFIG_VIDEO_ADV7343 is not set # CONFIG_VIDEO_ADV7393 is not set -# CONFIG_VIDEO_AD9389B is not set # CONFIG_VIDEO_AK881X is not set +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set # CONFIG_VIDEO_THS8200 is not set - -# -# Camera sensor devices -# -CONFIG_VIDEO_HI556=m -CONFIG_VIDEO_IMX214=m -CONFIG_VIDEO_IMX219=m -# CONFIG_VIDEO_IMX258 is not set -# CONFIG_VIDEO_IMX274 is not set -CONFIG_VIDEO_IMX290=m -CONFIG_VIDEO_IMX319=m -CONFIG_VIDEO_IMX355=m -# CONFIG_VIDEO_OV2640 is not set -# CONFIG_VIDEO_OV2659 is not set -CONFIG_VIDEO_OV2680=m -# CONFIG_VIDEO_OV2685 is not set -# CONFIG_VIDEO_OV5640 is not set -# CONFIG_VIDEO_OV5645 is not set -# CONFIG_VIDEO_OV5647 is not set -# CONFIG_VIDEO_OV6650 is not set -# CONFIG_VIDEO_OV5670 is not set -CONFIG_VIDEO_OV5675=m -# CONFIG_VIDEO_OV5695 is not set -# CONFIG_VIDEO_OV7251 is not set -# CONFIG_VIDEO_OV772X is not set -# CONFIG_VIDEO_OV7640 is not set -# CONFIG_VIDEO_OV7670 is not set -# CONFIG_VIDEO_OV7740 is not set -CONFIG_VIDEO_OV8856=m -CONFIG_VIDEO_OV9640=m -# CONFIG_VIDEO_OV9650 is not set -# CONFIG_VIDEO_OV13858 is not set -# CONFIG_VIDEO_VS6624 is not set -CONFIG_VIDEO_MT9M001=m -# CONFIG_VIDEO_MT9M032 is not set -# CONFIG_VIDEO_MT9M111 is not set -# CONFIG_VIDEO_MT9P031 is not set -# CONFIG_VIDEO_MT9T001 is not set -# CONFIG_VIDEO_MT9T112 is not set -# CONFIG_VIDEO_MT9V011 is not set -# CONFIG_VIDEO_MT9V032 is not set -CONFIG_VIDEO_MT9V111=m -# CONFIG_VIDEO_SR030PC30 is not set -# CONFIG_VIDEO_NOON010PC30 is not set -# CONFIG_VIDEO_M5MOLS is not set -# CONFIG_VIDEO_RJ54N1 is not set -# CONFIG_VIDEO_S5K6AA is not set -# CONFIG_VIDEO_S5K6A3 is not set -# CONFIG_VIDEO_S5K4ECGX is not set -# CONFIG_VIDEO_S5K5BAF is not set -# CONFIG_VIDEO_SMIAPP is not set -# CONFIG_VIDEO_ET8EK8 is not set -# CONFIG_VIDEO_S5C73M3 is not set - -# -# Lens drivers -# -# CONFIG_VIDEO_AD5820 is not set -CONFIG_VIDEO_AK7375=m -# CONFIG_VIDEO_DW9714 is not set -# CONFIG_VIDEO_DW9807_VCM is not set - -# -# Flash devices -# -# CONFIG_VIDEO_ADP1653 is not set -# CONFIG_VIDEO_LM3560 is not set -# CONFIG_VIDEO_LM3646 is not set +# end of Video encoders # # Video improvement chips # # CONFIG_VIDEO_UPD64031A is not set # CONFIG_VIDEO_UPD64083 is not set +# end of Video improvement chips # # Audio/Video compression chips # # CONFIG_VIDEO_SAA6752HS is not set +# end of Audio/Video compression chips # # SDR tuner chips # +# CONFIG_SDR_MAX2175 is not set +# end of SDR tuner chips # # Miscellaneous helper chips # -# CONFIG_VIDEO_THS7303 is not set -# CONFIG_VIDEO_M52790 is not set # CONFIG_VIDEO_I2C is not set +# CONFIG_VIDEO_M52790 is not set CONFIG_VIDEO_ST_MIPID02=m -# end of I2C Encoders, decoders, sensors and other helper chips +# CONFIG_VIDEO_THS7303 is not set +# end of Miscellaneous helper chips # -# SPI helper chips +# Video serializers and deserializers # -# CONFIG_VIDEO_GS1662 is not set -# end of SPI helper chips +# CONFIG_VIDEO_DS90UB913 is not set +# CONFIG_VIDEO_DS90UB953 is not set +# CONFIG_VIDEO_DS90UB960 is not set +# end of Video serializers and deserializers # # Media SPI Adapters # +CONFIG_CXD2880_SPI_DRV=m +# CONFIG_VIDEO_GS1662 is not set # end of Media SPI Adapters +CONFIG_MEDIA_TUNER=m + +# +# Customize TV tuners +# +CONFIG_MEDIA_TUNER_E4000=m +CONFIG_MEDIA_TUNER_FC0011=m +CONFIG_MEDIA_TUNER_FC0012=m +CONFIG_MEDIA_TUNER_FC0013=m +CONFIG_MEDIA_TUNER_FC2580=m +CONFIG_MEDIA_TUNER_IT913X=m +CONFIG_MEDIA_TUNER_M88RS6000T=m +CONFIG_MEDIA_TUNER_MAX2165=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MSI001=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2063=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MXL301RF=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_QM1D1B0004=m +CONFIG_MEDIA_TUNER_QM1D1C0042=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_R820T=m +CONFIG_MEDIA_TUNER_SI2157=m +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA18212=m +CONFIG_MEDIA_TUNER_TDA18218=m +CONFIG_MEDIA_TUNER_TDA18250=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_TUA9001=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC4000=m +CONFIG_MEDIA_TUNER_XC5000=m +# end of Customize TV tuners + # # Customise DVB Frontends # +# +# Multistandard (satellite) frontends +# +CONFIG_DVB_M88DS3103=m +CONFIG_DVB_MXL5XX=m +CONFIG_DVB_STB0899=m +CONFIG_DVB_STB6100=m +CONFIG_DVB_STV090x=m +CONFIG_DVB_STV0910=m +CONFIG_DVB_STV6110x=m +CONFIG_DVB_STV6111=m + +# +# Multistandard (cable + terrestrial) frontends +# +CONFIG_DVB_DRXK=m +CONFIG_DVB_MN88472=m +CONFIG_DVB_MN88473=m +CONFIG_DVB_SI2165=m +CONFIG_DVB_TDA18271C2DD=m + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24117=m +CONFIG_DVB_CX24120=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DS3000=m +CONFIG_DVB_MB86A16=m +CONFIG_DVB_MT312=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_STV0900=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_TDA10071=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA8261=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TS2020=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10036=m +CONFIG_DVB_ZL10039=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_AF9013=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CXD2820R=m +CONFIG_DVB_CXD2841ER=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_DIB9000=m +CONFIG_DVB_DRXD=m +CONFIG_DVB_EC100=m +CONFIG_DVB_L64781=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_RTL2830=m +CONFIG_DVB_RTL2832=m +CONFIG_DVB_RTL2832_SDR=m +CONFIG_DVB_S5H1432=m +CONFIG_DVB_SI2168=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STV0367=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_ZD1301_DEMOD=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_CXD2880=m + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_STV0297=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_VES1820=m + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +CONFIG_DVB_AU8522=m +CONFIG_DVB_AU8522_DTV=m +CONFIG_DVB_AU8522_V4L=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LG2160=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_LGDT3306A=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_MXL692=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_S5H1411=m + +# +# ISDB-T (terrestrial) frontends +# +CONFIG_DVB_DIB8000=m +CONFIG_DVB_MB86A20S=m +CONFIG_DVB_S921=m + +# +# ISDB-S (satellite) & ISDB-T (terrestrial) frontends +# +CONFIG_DVB_MN88443X=m +CONFIG_DVB_TC90522=m + +# +# Digital terrestrial only tuners/PLL +# +CONFIG_DVB_PLL=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_DIB0090=m + +# +# SEC control devices for DVB-S +# +CONFIG_DVB_A8293=m +CONFIG_DVB_AF9033=m +CONFIG_DVB_ASCOT2E=m +CONFIG_DVB_ATBM8830=m +CONFIG_DVB_HELENE=m +CONFIG_DVB_HORUS3A=m +CONFIG_DVB_ISL6405=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_ISL6423=m +CONFIG_DVB_IX2505V=m +CONFIG_DVB_LGS8GL5=m +CONFIG_DVB_LGS8GXX=m +CONFIG_DVB_LNBH25=m +CONFIG_DVB_LNBH29=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_LNBP22=m +CONFIG_DVB_M88RS2000=m +CONFIG_DVB_TDA665x=m +CONFIG_DVB_DRX39XYJ=m + +# +# Common Interface (EN50221) controller drivers +# +CONFIG_DVB_CXD2099=m +CONFIG_DVB_SP2=m +# end of Customise DVB Frontends + # # Tools to develop new frontends # -# end of Customise DVB Frontends +# CONFIG_DVB_DUMMY_FE is not set +# end of Media ancillary drivers # # Graphics support # -CONFIG_VGA_ARB=y -CONFIG_VGA_ARB_MAX_GPUS=16 -# CONFIG_IMX_IPUV3_CORE is not set +CONFIG_APERTURE_HELPERS=y +CONFIG_VIDEO_CMDLINE=y +CONFIG_VIDEO_NOMODESET=y +# CONFIG_AUXDISPLAY is not set +# CONFIG_PANEL is not set CONFIG_DRM=y CONFIG_DRM_MIPI_DBI=m CONFIG_DRM_MIPI_DSI=y -# CONFIG_DRM_DP_AUX_CHARDEV is not set # CONFIG_DRM_DEBUG_MM is not set -# CONFIG_DRM_DEBUG_SELFTEST is not set CONFIG_DRM_KMS_HELPER=y -CONFIG_DRM_KMS_FB_HELPER=y # CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set +# CONFIG_DRM_DEBUG_MODESET_LOCK is not set CONFIG_DRM_FBDEV_EMULATION=y CONFIG_DRM_FBDEV_OVERALLOC=100 # CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set # CONFIG_DRM_LOAD_EDID_FIRMWARE is not set +CONFIG_DRM_DP_AUX_BUS=m +CONFIG_DRM_DISPLAY_HELPER=m +CONFIG_DRM_DISPLAY_DP_HELPER=y +# CONFIG_DRM_DP_AUX_CHARDEV is not set # CONFIG_DRM_DP_CEC is not set -CONFIG_DRM_GEM_CMA_HELPER=y -CONFIG_DRM_KMS_CMA_HELPER=y -CONFIG_DRM_GEM_SHMEM_HELPER=y +CONFIG_DRM_GEM_DMA_HELPER=m +CONFIG_DRM_GEM_SHMEM_HELPER=m CONFIG_DRM_SCHED=m # @@ -4558,73 +5276,104 @@ CONFIG_DRM_KOMEDA=m # CONFIG_DRM_NOUVEAU is not set # CONFIG_DRM_VGEM is not set # CONFIG_DRM_VKMS is not set -# CONFIG_DRM_EXYNOS is not set # CONFIG_DRM_UDL is not set # CONFIG_DRM_AST is not set # CONFIG_DRM_MGAG200 is not set -# CONFIG_DRM_CIRRUS_QEMU is not set # CONFIG_DRM_ARMADA is not set -# CONFIG_DRM_RCAR_DW_HDMI is not set -# CONFIG_DRM_RCAR_LVDS is not set -# CONFIG_DRM_OMAP is not set # CONFIG_DRM_TILCDC is not set # CONFIG_DRM_QXL is not set -# CONFIG_DRM_BOCHS is not set # CONFIG_DRM_VIRTIO_GPU is not set # CONFIG_DRM_FSL_DCU is not set -# CONFIG_DRM_STM is not set CONFIG_DRM_PANEL=y # # Display Panels # +# CONFIG_DRM_PANEL_ABT_Y030XX067A is not set # CONFIG_DRM_PANEL_ARM_VERSATILE is not set +# CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 is not set +# CONFIG_DRM_PANEL_AUO_A030JTN01 is not set +# CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0 is not set CONFIG_DRM_PANEL_BOE_HIMAX8279D=m CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m +# CONFIG_DRM_PANEL_DSI_CM is not set # CONFIG_DRM_PANEL_LVDS is not set CONFIG_DRM_PANEL_SIMPLE=y +# CONFIG_DRM_PANEL_EDP is not set +# CONFIG_DRM_PANEL_EBBG_FT8719 is not set CONFIG_DRM_PANEL_ELIDA_KD35T133=m CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02=m CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D=m +# CONFIG_DRM_PANEL_HIMAX_HX8394 is not set # CONFIG_DRM_PANEL_ILITEK_IL9322 is not set +# CONFIG_DRM_PANEL_ILITEK_ILI9341 is not set CONFIG_DRM_PANEL_ILITEK_ILI9881C=m +# CONFIG_DRM_PANEL_INNOLUX_EJ030NA is not set # CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set +# CONFIG_DRM_PANEL_JADARD_JD9365DA_H3 is not set # CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set +# CONFIG_DRM_PANEL_JDI_R63452 is not set +# CONFIG_DRM_PANEL_KHADAS_TS050 is not set CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04=m +# CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W is not set CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829=m CONFIG_DRM_PANEL_SAMSUNG_LD9040=m CONFIG_DRM_PANEL_LG_LB035Q02=m # CONFIG_DRM_PANEL_LG_LG4573 is not set +# CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966 is not set CONFIG_DRM_PANEL_NEC_NL8048HL11=m +# CONFIG_DRM_PANEL_NEWVISION_NV3051D is not set +# CONFIG_DRM_PANEL_NEWVISION_NV3052C is not set CONFIG_DRM_PANEL_NOVATEK_NT35510=m +# CONFIG_DRM_PANEL_NOVATEK_NT35560 is not set +# CONFIG_DRM_PANEL_NOVATEK_NT35950 is not set +# CONFIG_DRM_PANEL_NOVATEK_NT36523 is not set +# CONFIG_DRM_PANEL_NOVATEK_NT36672A is not set CONFIG_DRM_PANEL_NOVATEK_NT39016=m +# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO=m +# CONFIG_DRM_PANEL_ORISETECH_OTA5601A is not set # CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS=m # CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set # CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set CONFIG_DRM_PANEL_RAYDIUM_RM67191=m # CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set -CONFIG_DRM_PANEL_ROCKTECH_JH057N00900=m CONFIG_DRM_PANEL_RONBO_RB070D30=m +# CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20 is not set +# CONFIG_DRM_PANEL_SAMSUNG_DB7430 is not set CONFIG_DRM_PANEL_SAMSUNG_S6D16D0=m +# CONFIG_DRM_PANEL_SAMSUNG_S6D27A1 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6D7AA0 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set CONFIG_DRM_PANEL_SAMSUNG_S6E63M0=m +CONFIG_DRM_PANEL_SAMSUNG_S6E63M0_SPI=m +# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0_DSI is not set CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01=m CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m +# CONFIG_DRM_PANEL_SAMSUNG_SOFEF00 is not set # CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set # CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m # CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set +# CONFIG_DRM_PANEL_SHARP_LS060T1SX01 is not set CONFIG_DRM_PANEL_SITRONIX_ST7701=m +# CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set # CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set -CONFIG_DRM_PANEL_SONY_ACX424AKP=m CONFIG_DRM_PANEL_SONY_ACX565AKM=m +# CONFIG_DRM_PANEL_SONY_TD4353_JDI is not set +# CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521 is not set +# CONFIG_DRM_PANEL_STARTEK_KD070FHFID015 is not set +# CONFIG_DRM_PANEL_TDO_TL070WSH30 is not set CONFIG_DRM_PANEL_TPO_TD028TTEC1=m CONFIG_DRM_PANEL_TPO_TD043MTEA1=m CONFIG_DRM_PANEL_TPO_TPG110=m CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m +# CONFIG_DRM_PANEL_VISIONOX_RM69299 is not set +# CONFIG_DRM_PANEL_VISIONOX_VTDR6130 is not set +# CONFIG_DRM_PANEL_VISIONOX_R66451 is not set +# CONFIG_DRM_PANEL_WIDECHIPS_WS2401 is not set CONFIG_DRM_PANEL_XINPENG_XPP055C272=m # end of Display Panels @@ -4634,40 +5383,63 @@ CONFIG_DRM_PANEL_BRIDGE=y # # Display Interface Bridges # -# CONFIG_DRM_CDNS_DSI is not set +# CONFIG_DRM_CHIPONE_ICN6211 is not set +# CONFIG_DRM_CHRONTEL_CH7033 is not set +# CONFIG_DRM_CROS_EC_ANX7688 is not set CONFIG_DRM_DISPLAY_CONNECTOR=m +# CONFIG_DRM_ITE_IT6505 is not set +# CONFIG_DRM_LONTIUM_LT8912B is not set +# CONFIG_DRM_LONTIUM_LT9211 is not set +# CONFIG_DRM_LONTIUM_LT9611 is not set +# CONFIG_DRM_LONTIUM_LT9611UXC is not set +# CONFIG_DRM_ITE_IT66121 is not set CONFIG_DRM_LVDS_CODEC=m # CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set +# CONFIG_DRM_NWL_MIPI_DSI is not set CONFIG_DRM_NXP_PTN3460=m CONFIG_DRM_PARADE_PS8622=m CONFIG_DRM_PARADE_PS8640=m +# CONFIG_DRM_SAMSUNG_DSIM is not set # CONFIG_DRM_SIL_SII8620 is not set # CONFIG_DRM_SII902X is not set CONFIG_DRM_SII9234=m CONFIG_DRM_SIMPLE_BRIDGE=m # CONFIG_DRM_THINE_THC63LVD1024 is not set +# CONFIG_DRM_TOSHIBA_TC358762 is not set CONFIG_DRM_TOSHIBA_TC358764=m # CONFIG_DRM_TOSHIBA_TC358767 is not set CONFIG_DRM_TOSHIBA_TC358768=m +# CONFIG_DRM_TOSHIBA_TC358775 is not set +# CONFIG_DRM_TI_DLPC3433 is not set # CONFIG_DRM_TI_TFP410 is not set +# CONFIG_DRM_TI_SN65DSI83 is not set CONFIG_DRM_TI_SN65DSI86=m CONFIG_DRM_TI_TPD12S015=m CONFIG_DRM_ANALOGIX_ANX6345=m # CONFIG_DRM_ANALOGIX_ANX78XX is not set CONFIG_DRM_ANALOGIX_DP=m +# CONFIG_DRM_ANALOGIX_ANX7625 is not set CONFIG_DRM_I2C_ADV7511=m CONFIG_DRM_I2C_ADV7511_AUDIO=y CONFIG_DRM_I2C_ADV7511_CEC=y +# CONFIG_DRM_CDNS_DSI is not set +# CONFIG_DRM_CDNS_MHDP8546 is not set # end of Display Interface Bridges -# CONFIG_DRM_STI is not set +# CONFIG_DRM_LOONGSON is not set # CONFIG_DRM_ETNAVIV is not set -# CONFIG_DRM_ARCPGU is not set +# CONFIG_DRM_LOGICVC is not set CONFIG_DRM_MEDIATEK=y +# CONFIG_DRM_MEDIATEK_DP is not set CONFIG_DRM_MEDIATEK_HDMI=y -# CONFIG_DRM_MXSFB is not set +# CONFIG_DRM_ARCPGU is not set +# CONFIG_DRM_BOCHS is not set +# CONFIG_DRM_CIRRUS_QEMU is not set # CONFIG_DRM_GM12U320 is not set +# CONFIG_DRM_PANEL_MIPI_DBI is not set +# CONFIG_DRM_SIMPLEDRM is not set CONFIG_TINYDRM_HX8357D=m +# CONFIG_TINYDRM_ILI9163 is not set CONFIG_TINYDRM_ILI9225=m CONFIG_TINYDRM_ILI9341=m CONFIG_TINYDRM_ILI9486=m @@ -4681,31 +5453,15 @@ CONFIG_DRM_LIMA=m CONFIG_DRM_PANFROST=m CONFIG_DRM_MCDE=m CONFIG_DRM_TIDSS=m +# CONFIG_DRM_GUD is not set +# CONFIG_DRM_SSD130X is not set # CONFIG_DRM_LEGACY is not set CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y # # Frame buffer Devices # -CONFIG_FB_CMDLINE=y -CONFIG_FB_NOTIFY=y CONFIG_FB=y -# CONFIG_FIRMWARE_EDID is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_SYS_FILLRECT=y -CONFIG_FB_SYS_COPYAREA=y -CONFIG_FB_SYS_IMAGEBLIT=y -# CONFIG_FB_FOREIGN_ENDIAN is not set -CONFIG_FB_SYS_FOPS=y -CONFIG_FB_DEFERRED_IO=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 @@ -4742,6 +5498,26 @@ CONFIG_FB_EFI=y CONFIG_FB_SIMPLE=y # CONFIG_FB_SSD1307 is not set # CONFIG_FB_SM712 is not set +CONFIG_FB_CORE=y +CONFIG_FB_NOTIFY=y +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FB_DEVICE=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_SYS_FOPS=y +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_DMAMEM_HELPERS=y +CONFIG_FB_IOMEM_FOPS=y +CONFIG_FB_IOMEM_HELPERS=y +CONFIG_FB_SYSMEM_HELPERS=y +CONFIG_FB_SYSMEM_HELPERS_DEFERRED=y +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set # end of Frame buffer Devices # @@ -4761,7 +5537,8 @@ CONFIG_LCD_PLATFORM=m # CONFIG_LCD_HX8357 is not set # CONFIG_LCD_OTM3225A is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_BACKLIGHT_GENERIC=y +# CONFIG_BACKLIGHT_KTD253 is not set +# CONFIG_BACKLIGHT_KTZ8866 is not set CONFIG_BACKLIGHT_PWM=y # CONFIG_BACKLIGHT_QCOM_WLED is not set # CONFIG_BACKLIGHT_ADP8860 is not set @@ -4785,15 +5562,16 @@ CONFIG_HDMI=y # CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION is not set CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y # CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set -CONFIG_BOOTSPLASH=y # end of Console display driver support # CONFIG_LOGO is not set # end of Graphics support +# CONFIG_DRM_ACCEL is not set CONFIG_SOUND=m CONFIG_SND=m CONFIG_SND_TIMER=m @@ -4814,11 +5592,14 @@ CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_PROC_FS=y CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_CTL_FAST_LOOKUP=y # CONFIG_SND_DEBUG is not set +# CONFIG_SND_CTL_INPUT_VALIDATION is not set # CONFIG_SND_SEQUENCER is not set CONFIG_SND_DRIVERS=y # CONFIG_SND_DUMMY is not set # CONFIG_SND_ALOOP is not set +# CONFIG_SND_PCMTEST is not set # CONFIG_SND_MTPAV is not set # CONFIG_SND_MTS64 is not set # CONFIG_SND_SERIAL_U16550 is not set @@ -4889,6 +5670,7 @@ CONFIG_SND_ARM=y CONFIG_SND_SPI=y CONFIG_SND_USB=y CONFIG_SND_USB_AUDIO=m +# CONFIG_SND_USB_AUDIO_MIDI_V2 is not set CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y # CONFIG_SND_USB_UA101 is not set # CONFIG_SND_USB_CAIAQ is not set @@ -4901,7 +5683,9 @@ CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y # CONFIG_SND_USB_VARIAX is not set CONFIG_SND_SOC=m CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y +# CONFIG_SND_SOC_ADI is not set # CONFIG_SND_SOC_AMD_ACP is not set +# CONFIG_SND_AMD_ACP_CONFIG is not set # CONFIG_SND_ATMEL_SOC is not set CONFIG_SND_BCM63XX_I2S_WHISTLER=m # CONFIG_SND_DESIGNWARE_I2S is not set @@ -4921,9 +5705,13 @@ CONFIG_SND_SOC_FSL_AUDMIX=m # CONFIG_SND_SOC_FSL_SPDIF is not set # CONFIG_SND_SOC_FSL_ESAI is not set CONFIG_SND_SOC_FSL_MICFIL=m +# CONFIG_SND_SOC_FSL_XCVR is not set +CONFIG_SND_SOC_FSL_UTILS=m +# CONFIG_SND_SOC_FSL_RPMSG is not set # CONFIG_SND_SOC_IMX_AUDMUX is not set # end of SoC Audio for Freescale CPUs +# CONFIG_SND_SOC_CHV3_I2S is not set # CONFIG_SND_I2S_HI6210_I2S is not set # CONFIG_SND_SOC_IMG is not set CONFIG_SND_SOC_MEDIATEK=m @@ -4931,11 +5719,16 @@ CONFIG_SND_SOC_MT2701=m CONFIG_SND_SOC_MT2701_CS42448=m CONFIG_SND_SOC_MT2701_WM8960=m # CONFIG_SND_SOC_MT6797 is not set +# CONFIG_SND_SOC_MT7986 is not set # CONFIG_SND_SOC_MT8173 is not set CONFIG_SND_SOC_MT8183=m CONFIG_SND_SOC_MT8183_MT6358_TS3A227E_MAX98357A=m CONFIG_SND_SOC_MT8183_DA7219_MAX98357A=m +# CONFIG_SND_SOC_MT8186 is not set CONFIG_SND_SOC_MTK_BTCVSD=m +# CONFIG_SND_SOC_MT8188 is not set +# CONFIG_SND_SOC_MT8192 is not set +# CONFIG_SND_SOC_MT8195 is not set # CONFIG_SND_SOC_SOF_TOPLEVEL is not set # @@ -4947,13 +5740,14 @@ CONFIG_SND_SOC_XILINX_I2S=m CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER=m CONFIG_SND_SOC_XILINX_SPDIF=m # CONFIG_SND_SOC_XTFPGA_I2S is not set -# CONFIG_ZX_TDM is not set CONFIG_SND_SOC_I2C_AND_SPI=m # # CODEC drivers # # CONFIG_SND_SOC_AC97_CODEC is not set +# CONFIG_SND_SOC_ADAU1372_I2C is not set +# CONFIG_SND_SOC_ADAU1372_SPI is not set # CONFIG_SND_SOC_ADAU1701 is not set # CONFIG_SND_SOC_ADAU1761_I2C is not set # CONFIG_SND_SOC_ADAU1761_SPI is not set @@ -4963,6 +5757,7 @@ CONFIG_SND_SOC_ADAU7118_HW=m CONFIG_SND_SOC_ADAU7118_I2C=m # CONFIG_SND_SOC_AK4104 is not set CONFIG_SND_SOC_AK4118=m +# CONFIG_SND_SOC_AK4375 is not set # CONFIG_SND_SOC_AK4458 is not set # CONFIG_SND_SOC_AK4554 is not set # CONFIG_SND_SOC_AK4613 is not set @@ -4970,19 +5765,34 @@ CONFIG_SND_SOC_AK4642=m # CONFIG_SND_SOC_AK5386 is not set # CONFIG_SND_SOC_AK5558 is not set # CONFIG_SND_SOC_ALC5623 is not set +# CONFIG_SND_SOC_AUDIO_IIO_AUX is not set +# CONFIG_SND_SOC_AW8738 is not set +# CONFIG_SND_SOC_AW88395 is not set +# CONFIG_SND_SOC_AW88261 is not set # CONFIG_SND_SOC_BD28623 is not set CONFIG_SND_SOC_BT_SCO=m +# CONFIG_SND_SOC_CHV3_CODEC is not set CONFIG_SND_SOC_CROS_EC_CODEC=m # CONFIG_SND_SOC_CS35L32 is not set # CONFIG_SND_SOC_CS35L33 is not set # CONFIG_SND_SOC_CS35L34 is not set # CONFIG_SND_SOC_CS35L35 is not set CONFIG_SND_SOC_CS35L36=m +# CONFIG_SND_SOC_CS35L41_SPI is not set +# CONFIG_SND_SOC_CS35L41_I2C is not set +# CONFIG_SND_SOC_CS35L45_SPI is not set +# CONFIG_SND_SOC_CS35L45_I2C is not set +# CONFIG_SND_SOC_CS35L56_I2C is not set +# CONFIG_SND_SOC_CS35L56_SPI is not set +# CONFIG_SND_SOC_CS35L56_SDW is not set # CONFIG_SND_SOC_CS42L42 is not set +# CONFIG_SND_SOC_CS42L42_SDW is not set # CONFIG_SND_SOC_CS42L51_I2C is not set # CONFIG_SND_SOC_CS42L52 is not set # CONFIG_SND_SOC_CS42L56 is not set # CONFIG_SND_SOC_CS42L73 is not set +# CONFIG_SND_SOC_CS42L83 is not set +# CONFIG_SND_SOC_CS4234 is not set # CONFIG_SND_SOC_CS4265 is not set # CONFIG_SND_SOC_CS4270 is not set # CONFIG_SND_SOC_CS4271_I2C is not set @@ -5001,16 +5811,27 @@ CONFIG_SND_SOC_HDMI_CODEC=m # CONFIG_SND_SOC_ES7134 is not set # CONFIG_SND_SOC_ES7241 is not set # CONFIG_SND_SOC_ES8316 is not set +# CONFIG_SND_SOC_ES8326 is not set # CONFIG_SND_SOC_ES8328_I2C is not set # CONFIG_SND_SOC_ES8328_SPI is not set # CONFIG_SND_SOC_GTM601 is not set +# CONFIG_SND_SOC_HDA is not set +# CONFIG_SND_SOC_ICS43432 is not set +# CONFIG_SND_SOC_IDT821034 is not set # CONFIG_SND_SOC_INNO_RK3036 is not set CONFIG_SND_SOC_MAX98088=m +# CONFIG_SND_SOC_MAX98090 is not set CONFIG_SND_SOC_MAX98357A=m # CONFIG_SND_SOC_MAX98504 is not set # CONFIG_SND_SOC_MAX9867 is not set # CONFIG_SND_SOC_MAX98927 is not set -# CONFIG_SND_SOC_MAX98373 is not set +# CONFIG_SND_SOC_MAX98520 is not set +# CONFIG_SND_SOC_MAX98363 is not set +# CONFIG_SND_SOC_MAX98373_I2C is not set +# CONFIG_SND_SOC_MAX98373_SDW is not set +# CONFIG_SND_SOC_MAX98388 is not set +# CONFIG_SND_SOC_MAX98390 is not set +# CONFIG_SND_SOC_MAX98396 is not set # CONFIG_SND_SOC_MAX9860 is not set # CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set # CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set @@ -5025,60 +5846,89 @@ CONFIG_SND_SOC_PCM3060_I2C=m CONFIG_SND_SOC_PCM3060_SPI=m # CONFIG_SND_SOC_PCM3168A_I2C is not set # CONFIG_SND_SOC_PCM3168A_SPI is not set +# CONFIG_SND_SOC_PCM5102A is not set # CONFIG_SND_SOC_PCM512x_I2C is not set # CONFIG_SND_SOC_PCM512x_SPI is not set +# CONFIG_SND_SOC_PEB2466 is not set CONFIG_SND_SOC_RK3328=m CONFIG_SND_SOC_RL6231=m +CONFIG_SND_SOC_RT1015=m +CONFIG_SND_SOC_RT1015P=m +# CONFIG_SND_SOC_RT1017_SDCA_SDW is not set CONFIG_SND_SOC_RT1308_SDW=m +# CONFIG_SND_SOC_RT1316_SDW is not set +# CONFIG_SND_SOC_RT1318_SDW is not set # CONFIG_SND_SOC_RT5616 is not set # CONFIG_SND_SOC_RT5631 is not set +# CONFIG_SND_SOC_RT5640 is not set +# CONFIG_SND_SOC_RT5659 is not set CONFIG_SND_SOC_RT5682=m CONFIG_SND_SOC_RT5682_SDW=m CONFIG_SND_SOC_RT700=m CONFIG_SND_SOC_RT700_SDW=m CONFIG_SND_SOC_RT711=m CONFIG_SND_SOC_RT711_SDW=m +# CONFIG_SND_SOC_RT711_SDCA_SDW is not set +# CONFIG_SND_SOC_RT712_SDCA_SDW is not set +# CONFIG_SND_SOC_RT712_SDCA_DMIC_SDW is not set +# CONFIG_SND_SOC_RT722_SDCA_SDW is not set CONFIG_SND_SOC_RT715=m CONFIG_SND_SOC_RT715_SDW=m +# CONFIG_SND_SOC_RT715_SDCA_SDW is not set +# CONFIG_SND_SOC_RT9120 is not set +# CONFIG_SND_SOC_SDW_MOCKUP is not set CONFIG_SND_SOC_SGTL5000=m # CONFIG_SND_SOC_SIMPLE_AMPLIFIER is not set -# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set +# CONFIG_SND_SOC_SIMPLE_MUX is not set +# CONFIG_SND_SOC_SMA1303 is not set CONFIG_SND_SOC_SPDIF=m +# CONFIG_SND_SOC_SRC4XXX_I2C is not set # CONFIG_SND_SOC_SSM2305 is not set +# CONFIG_SND_SOC_SSM2518 is not set # CONFIG_SND_SOC_SSM2602_SPI is not set # CONFIG_SND_SOC_SSM2602_I2C is not set +# CONFIG_SND_SOC_SSM3515 is not set # CONFIG_SND_SOC_SSM4567 is not set # CONFIG_SND_SOC_STA32X is not set # CONFIG_SND_SOC_STA350 is not set CONFIG_SND_SOC_STI_SAS=m # CONFIG_SND_SOC_TAS2552 is not set CONFIG_SND_SOC_TAS2562=m +# CONFIG_SND_SOC_TAS2764 is not set CONFIG_SND_SOC_TAS2770=m +# CONFIG_SND_SOC_TAS2780 is not set +# CONFIG_SND_SOC_TAS2781_I2C is not set # CONFIG_SND_SOC_TAS5086 is not set # CONFIG_SND_SOC_TAS571X is not set # CONFIG_SND_SOC_TAS5720 is not set +# CONFIG_SND_SOC_TAS5805M is not set # CONFIG_SND_SOC_TAS6424 is not set # CONFIG_SND_SOC_TDA7419 is not set # CONFIG_SND_SOC_TFA9879 is not set +# CONFIG_SND_SOC_TFA989X is not set +# CONFIG_SND_SOC_TLV320ADC3XXX is not set CONFIG_SND_SOC_TLV320AIC23=m CONFIG_SND_SOC_TLV320AIC23_I2C=m # CONFIG_SND_SOC_TLV320AIC23_SPI is not set # CONFIG_SND_SOC_TLV320AIC31XX is not set # CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set # CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set -# CONFIG_SND_SOC_TLV320AIC3X is not set +# CONFIG_SND_SOC_TLV320AIC3X_I2C is not set +# CONFIG_SND_SOC_TLV320AIC3X_SPI is not set CONFIG_SND_SOC_TLV320ADCX140=m CONFIG_SND_SOC_TS3A227E=m # CONFIG_SND_SOC_TSCS42XX is not set # CONFIG_SND_SOC_TSCS454 is not set CONFIG_SND_SOC_UDA1334=m +# CONFIG_SND_SOC_WCD938X_SDW is not set # CONFIG_SND_SOC_WM8510 is not set # CONFIG_SND_SOC_WM8523 is not set # CONFIG_SND_SOC_WM8524 is not set # CONFIG_SND_SOC_WM8580 is not set # CONFIG_SND_SOC_WM8711 is not set # CONFIG_SND_SOC_WM8728 is not set -# CONFIG_SND_SOC_WM8731 is not set +# CONFIG_SND_SOC_WM8731_I2C is not set +# CONFIG_SND_SOC_WM8731_SPI is not set # CONFIG_SND_SOC_WM8737 is not set # CONFIG_SND_SOC_WM8741 is not set # CONFIG_SND_SOC_WM8750 is not set @@ -5090,30 +5940,42 @@ CONFIG_SND_SOC_WM8753=m # CONFIG_SND_SOC_WM8804_SPI is not set CONFIG_SND_SOC_WM8903=m CONFIG_SND_SOC_WM8904=m +# CONFIG_SND_SOC_WM8940 is not set CONFIG_SND_SOC_WM8960=m +# CONFIG_SND_SOC_WM8961 is not set # CONFIG_SND_SOC_WM8962 is not set # CONFIG_SND_SOC_WM8974 is not set CONFIG_SND_SOC_WM8978=m # CONFIG_SND_SOC_WM8985 is not set CONFIG_SND_SOC_WSA881X=m -# CONFIG_SND_SOC_ZX_AUD96P22 is not set +# CONFIG_SND_SOC_WSA883X is not set +# CONFIG_SND_SOC_WSA884X is not set +# CONFIG_SND_SOC_ZL38060 is not set # CONFIG_SND_SOC_MAX9759 is not set # CONFIG_SND_SOC_MT6351 is not set CONFIG_SND_SOC_MT6358=m +# CONFIG_SND_SOC_MT6359 is not set +# CONFIG_SND_SOC_MT6359_ACCDET is not set CONFIG_SND_SOC_MT6660=m +# CONFIG_SND_SOC_NAU8315 is not set # CONFIG_SND_SOC_NAU8540 is not set # CONFIG_SND_SOC_NAU8810 is not set +# CONFIG_SND_SOC_NAU8821 is not set CONFIG_SND_SOC_NAU8822=m # CONFIG_SND_SOC_NAU8824 is not set # CONFIG_SND_SOC_TPA6130A2 is not set +# CONFIG_SND_SOC_LPASS_WSA_MACRO is not set +# CONFIG_SND_SOC_LPASS_VA_MACRO is not set +# CONFIG_SND_SOC_LPASS_RX_MACRO is not set +# CONFIG_SND_SOC_LPASS_TX_MACRO is not set # end of CODEC drivers # CONFIG_SND_SIMPLE_CARD is not set # CONFIG_SND_AUDIO_GRAPH_CARD is not set - -# -# HID support -# +# CONFIG_SND_AUDIO_GRAPH_CARD2 is not set +# CONFIG_SND_TEST_COMPONENT is not set +# CONFIG_SND_VIRTIO is not set +CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_BATTERY_STRENGTH is not set CONFIG_HIDRAW=y @@ -5148,18 +6010,24 @@ CONFIG_HID_CREATIVE_SB0540=m # CONFIG_HID_ELAN is not set # CONFIG_HID_ELECOM is not set # CONFIG_HID_ELO is not set +# CONFIG_HID_EVISION is not set # CONFIG_HID_EZKEY is not set +# CONFIG_HID_FT260 is not set # CONFIG_HID_GEMBIRD is not set # CONFIG_HID_GFRM is not set CONFIG_HID_GLORIOUS=m # CONFIG_HID_HOLTEK is not set # CONFIG_HID_GOOGLE_HAMMER is not set +# CONFIG_HID_GOOGLE_STADIA_FF is not set +# CONFIG_HID_VIVALDI is not set # CONFIG_HID_GT683R is not set # CONFIG_HID_KEYTOUCH is not set # CONFIG_HID_KYE is not set # CONFIG_HID_UCLOGIC is not set # CONFIG_HID_WALTOP is not set CONFIG_HID_VIEWSONIC=m +# CONFIG_HID_VRC2 is not set +# CONFIG_HID_XIAOMI is not set # CONFIG_HID_GYRATION is not set # CONFIG_HID_ICADE is not set # CONFIG_HID_ITE is not set @@ -5169,27 +6037,35 @@ CONFIG_HID_VIEWSONIC=m # CONFIG_HID_LCPOWER is not set # CONFIG_HID_LED is not set # CONFIG_HID_LENOVO is not set +# CONFIG_HID_LETSKETCH is not set # CONFIG_HID_LOGITECH is not set # CONFIG_HID_MAGICMOUSE is not set CONFIG_HID_MALTRON=m # CONFIG_HID_MAYFLASH is not set +# CONFIG_HID_MEGAWORLD_FF is not set # CONFIG_HID_REDRAGON is not set # CONFIG_HID_MICROSOFT is not set # CONFIG_HID_MONTEREY is not set # CONFIG_HID_MULTITOUCH is not set +# CONFIG_HID_NINTENDO is not set # CONFIG_HID_NTI is not set # CONFIG_HID_NTRIG is not set +# CONFIG_HID_NVIDIA_SHIELD is not set # CONFIG_HID_ORTEK is not set # CONFIG_HID_PANTHERLORD is not set # CONFIG_HID_PENMOUNT is not set # CONFIG_HID_PETALYNX is not set # CONFIG_HID_PICOLCD is not set # CONFIG_HID_PLANTRONICS is not set +# CONFIG_HID_PXRC is not set +# CONFIG_HID_RAZER is not set # CONFIG_HID_PRIMAX is not set # CONFIG_HID_RETRODE is not set # CONFIG_HID_ROCCAT is not set # CONFIG_HID_SAITEK is not set # CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SEMITEK is not set +# CONFIG_HID_SIGMAMICRO is not set # CONFIG_HID_SONY is not set # CONFIG_HID_SPEEDLINK is not set # CONFIG_HID_STEAM is not set @@ -5200,6 +6076,7 @@ CONFIG_HID_MALTRON=m # CONFIG_HID_SMARTJOYPLUS is not set # CONFIG_HID_TIVO is not set # CONFIG_HID_TOPSEED is not set +# CONFIG_HID_TOPRE is not set # CONFIG_HID_THINGM is not set # CONFIG_HID_THRUSTMASTER is not set # CONFIG_HID_UDRAW_PS3 is not set @@ -5214,6 +6091,11 @@ CONFIG_HID_U2FZERO=m CONFIG_HID_MCP2221=m # end of Special HID drivers +# +# HID-BPF support +# +# end of HID-BPF support + # # USB HID support # @@ -5222,13 +6104,7 @@ CONFIG_USB_HID=y CONFIG_USB_HIDDEV=y # end of USB HID support -# -# I2C HID support -# # CONFIG_I2C_HID is not set -# end of I2C HID support -# end of HID support - CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_SUPPORT=y CONFIG_USB_COMMON=y @@ -5244,10 +6120,11 @@ CONFIG_USB_PCI=y # Miscellaneous USB options # CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_FEW_INIT_RETRIES is not set # CONFIG_USB_DYNAMIC_MINORS is not set CONFIG_USB_OTG=y -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_OTG_PRODUCTLIST is not set +# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set # CONFIG_USB_OTG_FSM is not set # CONFIG_USB_LEDS_TRIGGER_USBPORT is not set CONFIG_USB_AUTOSUSPEND_DELAY=2 @@ -5260,12 +6137,12 @@ CONFIG_USB_AUTOSUSPEND_DELAY=2 CONFIG_USB_XHCI_HCD=y # CONFIG_USB_XHCI_DBGCAP is not set CONFIG_USB_XHCI_PCI=y +# CONFIG_USB_XHCI_PCI_RENESAS is not set CONFIG_USB_XHCI_PLATFORM=m CONFIG_USB_XHCI_MTK=y # CONFIG_USB_EHCI_HCD is not set # CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_FOTG210_HCD is not set # CONFIG_USB_MAX3421_HCD is not set # CONFIG_USB_OHCI_HCD is not set # CONFIG_USB_UHCI_HCD is not set @@ -5319,9 +6196,11 @@ CONFIG_USBIP_VHCI_NR_HCS=1 CONFIG_USBIP_HOST=m CONFIG_USBIP_VUDC=m # CONFIG_USBIP_DEBUG is not set -CONFIG_USB_CDNS3=m -# CONFIG_USB_CDNS3_GADGET is not set -# CONFIG_USB_CDNS3_HOST is not set + +# +# USB dual-mode controller drivers +# +# CONFIG_USB_CDNS_SUPPORT is not set CONFIG_USB_MTU3=m # CONFIG_USB_MTU3_HOST is not set # CONFIG_USB_MTU3_GADGET is not set @@ -5336,7 +6215,6 @@ CONFIG_USB_MTU3_DUAL_ROLE=y # # USB port drivers # -CONFIG_USB_USS720=m CONFIG_USB_SERIAL=y # CONFIG_USB_SERIAL_CONSOLE is not set # CONFIG_USB_SERIAL_GENERIC is not set @@ -5381,7 +6259,6 @@ CONFIG_USB_SERIAL=y # CONFIG_USB_SERIAL_SYMBOL is not set # CONFIG_USB_SERIAL_TI is not set # CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set # CONFIG_USB_SERIAL_OPTION is not set # CONFIG_USB_SERIAL_OMNINET is not set # CONFIG_USB_SERIAL_OPTICON is not set @@ -5390,11 +6267,13 @@ CONFIG_USB_SERIAL=y # CONFIG_USB_SERIAL_SSU100 is not set # CONFIG_USB_SERIAL_QT2 is not set # CONFIG_USB_SERIAL_UPD78F0730 is not set +# CONFIG_USB_SERIAL_XR is not set # CONFIG_USB_SERIAL_DEBUG is not set # # USB Miscellaneous drivers # +CONFIG_USB_USS720=m # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set # CONFIG_USB_ADUTUX is not set @@ -5404,7 +6283,6 @@ CONFIG_USB_SERIAL=y # 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_APPLE_MFI_FASTCHARGE=m # CONFIG_USB_LD is not set @@ -5420,6 +6298,7 @@ CONFIG_APPLE_MFI_FASTCHARGE=m # CONFIG_USB_HSIC_USB4604 is not set # CONFIG_USB_LINK_LAYER_TEST is not set # CONFIG_USB_CHAOSKEY is not set +# CONFIG_USB_ONBOARD_HUB is not set CONFIG_USB_ATM=m # CONFIG_USB_SPEEDTOUCH is not set # CONFIG_USB_CXACRU is not set @@ -5451,7 +6330,6 @@ CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 # USB Peripheral Controller # # CONFIG_USB_FUSB300 is not set -# CONFIG_USB_FOTG210_UDC is not set # CONFIG_USB_GR_UDC is not set # CONFIG_USB_R8A66597 is not set # CONFIG_USB_PXA27X is not set @@ -5461,11 +6339,6 @@ CONFIG_USB_SNP_CORE=m CONFIG_USB_SNP_UDC_PLAT=m # CONFIG_USB_M66592 is not set CONFIG_USB_BDC_UDC=m - -# -# Platform Support -# -CONFIG_USB_BDC_PCI=m # CONFIG_USB_AMD5536UDC is not set # CONFIG_USB_NET2272 is not set # CONFIG_USB_NET2280 is not set @@ -5514,9 +6387,11 @@ CONFIG_USB_CONFIGFS_F_UAC1=y CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y CONFIG_USB_CONFIGFS_F_UAC2=y CONFIG_USB_CONFIGFS_F_MIDI=y +# CONFIG_USB_CONFIGFS_F_MIDI2 is not set CONFIG_USB_CONFIGFS_F_HID=y CONFIG_USB_CONFIGFS_F_UVC=y CONFIG_USB_CONFIGFS_F_PRINTER=y +# CONFIG_USB_CONFIGFS_F_TCM is not set # # USB Gadget precomposed configurations @@ -5530,6 +6405,7 @@ CONFIG_USB_ETH_RNDIS=y # CONFIG_USB_GADGETFS is not set # CONFIG_USB_FUNCTIONFS is not set # CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_GADGET_TARGET is not set # CONFIG_USB_G_SERIAL is not set # CONFIG_USB_MIDI_GADGET is not set # CONFIG_USB_G_PRINTER is not set @@ -5567,22 +6443,24 @@ CONFIG_MMC_ALCOR=m # CONFIG_MMC_VUB300 is not set # CONFIG_MMC_USHC is not set # CONFIG_MMC_USDHI6ROL0 is not set -# CONFIG_MMC_CQHCI is not set +CONFIG_MMC_CQHCI=y CONFIG_MMC_HSQ=m # CONFIG_MMC_TOSHIBA_PCI is not set CONFIG_MMC_MTK=y +# CONFIG_SCSI_UFSHCD is not set # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_CLASS_FLASH=m +# CONFIG_LEDS_CLASS_MULTICOLOR is not set # CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set # # LED drivers # -# CONFIG_LEDS_AAT1290 is not set CONFIG_LEDS_AN30259A=m -# CONFIG_LEDS_AS3645A is not set +# CONFIG_LEDS_AW200XX is not set +# CONFIG_LEDS_AW2013 is not set # CONFIG_LEDS_BCM6328 is not set # CONFIG_LEDS_BCM6358 is not set # CONFIG_LEDS_CR0014114 is not set @@ -5591,29 +6469,27 @@ CONFIG_LEDS_EL15203000=m CONFIG_LEDS_LM3532=m # CONFIG_LEDS_LM3642 is not set # CONFIG_LEDS_LM3692X is not set -# CONFIG_LEDS_LM3601X is not set CONFIG_LEDS_MT6323=y # CONFIG_LEDS_PCA9532 is not set CONFIG_LEDS_GPIO=y # CONFIG_LEDS_LP3944 is not set # CONFIG_LEDS_LP3952 is not set -# CONFIG_LEDS_LP5521 is not set -# CONFIG_LEDS_LP5523 is not set -# CONFIG_LEDS_LP5562 is not set -# CONFIG_LEDS_LP8501 is not set +# CONFIG_LEDS_LP50XX is not set +# CONFIG_LEDS_LP55XX_COMMON is not set # CONFIG_LEDS_LP8860 is not set # CONFIG_LEDS_PCA955X is not set CONFIG_LEDS_PCA963X=y +# CONFIG_LEDS_PCA995X is not set # CONFIG_LEDS_DAC124S085 is not set CONFIG_LEDS_PWM=y # CONFIG_LEDS_REGULATOR is not set +# CONFIG_LEDS_BD2606MVV is not set # CONFIG_LEDS_BD2802 is not set # CONFIG_LEDS_LT3593 is not set # CONFIG_LEDS_TCA6507 is not set # CONFIG_LEDS_TLC591XX is not set CONFIG_LEDS_MAX77650=m # CONFIG_LEDS_LM355x is not set -# CONFIG_LEDS_KTD2692 is not set # CONFIG_LEDS_IS31FL319X is not set # CONFIG_LEDS_IS31FL32XX is not set @@ -5628,6 +6504,21 @@ CONFIG_LEDS_SPI_BYTE=m CONFIG_LEDS_TI_LMU_COMMON=m CONFIG_LEDS_LM3697=m +# +# Flash and Torch LED drivers +# +# CONFIG_LEDS_AAT1290 is not set +# CONFIG_LEDS_AS3645A is not set +# CONFIG_LEDS_KTD2692 is not set +# CONFIG_LEDS_LM3601X is not set +# CONFIG_LEDS_RT4505 is not set +# CONFIG_LEDS_RT8515 is not set +# CONFIG_LEDS_SGM3140 is not set + +# +# RGB LED drivers +# + # # LED Triggers # @@ -5640,7 +6531,6 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_BACKLIGHT=y CONFIG_LEDS_TRIGGER_CPU=y # CONFIG_LEDS_TRIGGER_ACTIVITY is not set -CONFIG_LEDS_TRIGGER_GPIO=y CONFIG_LEDS_TRIGGER_DEFAULT_ON=y # @@ -5652,6 +6542,11 @@ CONFIG_LEDS_TRIGGER_CAMERA=y # CONFIG_LEDS_TRIGGER_NETDEV is not set CONFIG_LEDS_TRIGGER_PATTERN=m CONFIG_LEDS_TRIGGER_AUDIO=m +# CONFIG_LEDS_TRIGGER_TTY is not set + +# +# Simple LED drivers +# # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set CONFIG_EDAC_ATOMIC_SCRUB=y @@ -5689,6 +6584,7 @@ CONFIG_RTC_DRV_DS1307_CENTURY=y # CONFIG_RTC_DRV_DS1672 is not set CONFIG_RTC_DRV_HYM8563=m # CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_NCT3018Y is not set CONFIG_RTC_DRV_RS5C372=m # CONFIG_RTC_DRV_ISL1208 is not set # CONFIG_RTC_DRV_ISL12022 is not set @@ -5710,6 +6606,7 @@ CONFIG_RTC_DRV_RX8581=m # CONFIG_RTC_DRV_RX8025 is not set CONFIG_RTC_DRV_EM3027=y CONFIG_RTC_DRV_RV3028=m +# CONFIG_RTC_DRV_RV3032 is not set # CONFIG_RTC_DRV_RV8803 is not set CONFIG_RTC_DRV_SD3078=m @@ -5726,7 +6623,6 @@ CONFIG_RTC_DRV_SD3078=m # CONFIG_RTC_DRV_MAX6916 is not set # CONFIG_RTC_DRV_R9701 is not set # CONFIG_RTC_DRV_RX4581 is not set -# CONFIG_RTC_DRV_RX6110 is not set # CONFIG_RTC_DRV_RS5C348 is not set # CONFIG_RTC_DRV_MAX6902 is not set # CONFIG_RTC_DRV_PCF2123 is not set @@ -5739,6 +6635,7 @@ CONFIG_RTC_I2C_AND_SPI=y # CONFIG_RTC_DRV_DS3232 is not set # CONFIG_RTC_DRV_PCF2127 is not set # CONFIG_RTC_DRV_RV3029C2 is not set +# CONFIG_RTC_DRV_RX6110 is not set # # Platform RTC drivers @@ -5756,9 +6653,7 @@ CONFIG_RTC_DRV_EFI=m # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set # CONFIG_RTC_DRV_MSM6242 is not set -# CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_V3020 is not set # CONFIG_RTC_DRV_ZYNQMP is not set CONFIG_RTC_DRV_CROS_EC=m @@ -5775,6 +6670,7 @@ CONFIG_RTC_DRV_MT6397=y # # HID Sensor RTC drivers # +# CONFIG_RTC_DRV_GOLDFISH is not set CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set @@ -5792,8 +6688,11 @@ CONFIG_FSL_QDMA=m # CONFIG_INTEL_IDMA64 is not set # CONFIG_NBPFAXI_DMA is not set CONFIG_PLX_DMA=m +# CONFIG_XILINX_DMA is not set +# CONFIG_XILINX_XDMA is not set +# CONFIG_XILINX_ZYNQMP_DPDMA is not set CONFIG_MTK_HSDMA=y -CONFIG_MTK_CQDMA=m +CONFIG_MTK_CQDMA=y CONFIG_MTK_UART_APDMA=m # CONFIG_QCOM_HIDMA_MGMT is not set # CONFIG_QCOM_HIDMA is not set @@ -5817,16 +6716,19 @@ CONFIG_SYNC_FILE=y # CONFIG_SW_SYNC is not set # CONFIG_UDMABUF is not set # CONFIG_DMABUF_MOVE_NOTIFY is not set +# CONFIG_DMABUF_DEBUG is not set CONFIG_DMABUF_SELFTESTS=m # CONFIG_DMABUF_HEAPS is not set +# CONFIG_DMABUF_SYSFS_STATS is not set # end of DMABUF options -# CONFIG_AUXDISPLAY is not set -# CONFIG_PANEL is not set # CONFIG_UIO is not set # CONFIG_VFIO is not set # CONFIG_VIRT_DRIVERS is not set +CONFIG_VIRTIO_ANCHOR=y CONFIG_VIRTIO=y +CONFIG_VIRTIO_PCI_LIB=y +CONFIG_VIRTIO_PCI_LIB_LEGACY=y CONFIG_VIRTIO_MENU=y CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_PCI_LEGACY=y @@ -5837,12 +6739,17 @@ CONFIG_VIRTIO_MMIO=y # CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set CONFIG_VDPA=m CONFIG_VDPA_SIM=m +# CONFIG_VDPA_SIM_NET is not set +# CONFIG_VDPA_SIM_BLOCK is not set +# CONFIG_VDPA_USER is not set CONFIG_IFCVF=m +# CONFIG_MLX5_VDPA_STEERING_DEBUG is not set +# CONFIG_VP_VDPA is not set CONFIG_VHOST_IOTLB=m CONFIG_VHOST_RING=m -CONFIG_VHOST_DPN=y CONFIG_VHOST_MENU=y # CONFIG_VHOST_NET is not set +# CONFIG_VHOST_SCSI is not set # CONFIG_VHOST_VSOCK is not set # CONFIG_VHOST_VDPA is not set # CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set @@ -5853,14 +6760,13 @@ CONFIG_VHOST_MENU=y # end of Microsoft Hyper-V guest support # CONFIG_GREYBUS is not set +# CONFIG_COMEDI is not set CONFIG_STAGING=y # CONFIG_PRISM2_USB is not set -# CONFIG_COMEDI is not set # CONFIG_RTL8192U is not set # CONFIG_RTLLIB is not set # CONFIG_RTL8723BS is not set # CONFIG_R8712U is not set -# CONFIG_R8188EU is not set # CONFIG_RTS5208 is not set # CONFIG_VT6655 is not set # CONFIG_VT6656 is not set @@ -5880,7 +6786,6 @@ CONFIG_STAGING=y # Analog to digital converters # # CONFIG_AD7816 is not set -# CONFIG_AD7280 is not set # end of Analog to digital converters # @@ -5889,13 +6794,6 @@ CONFIG_STAGING=y # CONFIG_ADT7316 is not set # end of Analog digital bi-direction converters -# -# Capacitance to digital converters -# -# CONFIG_AD7150 is not set -# CONFIG_AD7746 is not set -# end of Capacitance to digital converters - # # Direct Digital Synthesis # @@ -5909,12 +6807,6 @@ CONFIG_STAGING=y # CONFIG_AD5933 is not set # end of Network Analyzer, Impedance Converters -# -# Active energy metering IC -# -# CONFIG_ADE7854 is not set -# end of Active energy metering IC - # # Resolver to digital converters # @@ -5923,65 +6815,47 @@ CONFIG_STAGING=y # end of IIO staging drivers # CONFIG_FB_SM750 is not set - -# -# Speakup console speech -# -# CONFIG_SPEAKUP is not set -# end of Speakup console speech - # CONFIG_STAGING_MEDIA is not set - -# -# Android -# -# end of Android - CONFIG_STAGING_BOARD=y # CONFIG_LTE_GDM724X is not set -# CONFIG_GS_FPGABOOT is not set -# CONFIG_UNISYSSPAR is not set -# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set # CONFIG_FB_TFT is not set -# CONFIG_WILC1000_SDIO is not set -# CONFIG_WILC1000_SPI is not set # CONFIG_KS7010 is not set # CONFIG_PI433 is not set - -# -# Gasket devices -# -# end of Gasket devices - CONFIG_XIL_AXIS_FIFO=m # CONFIG_FIELDBUS_DEV is not set CONFIG_QLGE=m -CONFIG_WFX=m +# CONFIG_VME_BUS is not set # CONFIG_GOLDFISH is not set -# CONFIG_MFD_CROS_EC is not set CONFIG_CHROME_PLATFORMS=y CONFIG_CROS_EC=m CONFIG_CROS_EC_I2C=m # CONFIG_CROS_EC_RPMSG is not set CONFIG_CROS_EC_SPI=m CONFIG_CROS_EC_PROTO=y +# CONFIG_CROS_KBD_LED_BACKLIGHT is not set CONFIG_CROS_EC_CHARDEV=m CONFIG_CROS_EC_LIGHTBAR=m CONFIG_CROS_EC_VBC=m CONFIG_CROS_EC_DEBUGFS=m CONFIG_CROS_EC_SENSORHUB=m CONFIG_CROS_EC_SYSFS=m +# CONFIG_CROS_HPS_I2C is not set CONFIG_CROS_USBPD_LOGGER=m CONFIG_CROS_USBPD_NOTIFY=m # CONFIG_MELLANOX_PLATFORM is not set -CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK=y CONFIG_HAVE_CLK_PREPARE=y CONFIG_COMMON_CLK=y # -# Common Clock Framework +# Clock driver for ARM Reference designs # -# CONFIG_CLK_HSDK is not set +# CONFIG_CLK_ICST is not set +# CONFIG_CLK_SP810 is not set +# CONFIG_CLK_VEXPRESS_OSC is not set +# end of Clock driver for ARM Reference designs + +# CONFIG_LMK04832 is not set CONFIG_COMMON_CLK_MAX9485=m CONFIG_COMMON_CLK_SI5341=m # CONFIG_COMMON_CLK_SI5351 is not set @@ -5991,9 +6865,13 @@ CONFIG_COMMON_CLK_SI5341=m # CONFIG_COMMON_CLK_CDCE706 is not set # CONFIG_COMMON_CLK_CDCE925 is not set # CONFIG_COMMON_CLK_CS2000_CP is not set -# CONFIG_CLK_QORIQ is not set +# CONFIG_COMMON_CLK_AXI_CLKGEN is not set # CONFIG_COMMON_CLK_PWM is not set +# CONFIG_COMMON_CLK_RS9_PCIE is not set +# CONFIG_COMMON_CLK_SI521XX is not set +# CONFIG_COMMON_CLK_VC3 is not set # CONFIG_COMMON_CLK_VC5 is not set +# CONFIG_COMMON_CLK_VC7 is not set CONFIG_COMMON_CLK_BD718XX=m # CONFIG_COMMON_CLK_FIXED_MMIO is not set @@ -6001,6 +6879,7 @@ CONFIG_COMMON_CLK_BD718XX=m # Clock driver for MediaTek SoC # CONFIG_COMMON_CLK_MEDIATEK=y +CONFIG_COMMON_CLK_MEDIATEK_FHCTL=y CONFIG_COMMON_CLK_MT2701=y CONFIG_COMMON_CLK_MT2701_MMSYS=y CONFIG_COMMON_CLK_MT2701_IMGSYS=y @@ -6010,6 +6889,11 @@ CONFIG_COMMON_CLK_MT2701_ETHSYS=y CONFIG_COMMON_CLK_MT2701_BDPSYS=y CONFIG_COMMON_CLK_MT2701_AUDSYS=y CONFIG_COMMON_CLK_MT2701_G3DSYS=y +CONFIG_COMMON_CLK_MT6795=y +CONFIG_COMMON_CLK_MT6795_MFGCFG=y +CONFIG_COMMON_CLK_MT6795_MMSYS=y +CONFIG_COMMON_CLK_MT6795_VDECSYS=y +CONFIG_COMMON_CLK_MT6795_VENCSYS=y CONFIG_COMMON_CLK_MT7622=y # CONFIG_COMMON_CLK_MT7622_ETHSYS is not set # CONFIG_COMMON_CLK_MT7622_HIFSYS is not set @@ -6017,13 +6901,18 @@ CONFIG_COMMON_CLK_MT7622=y CONFIG_COMMON_CLK_MT7629=y # CONFIG_COMMON_CLK_MT7629_ETHSYS is not set # CONFIG_COMMON_CLK_MT7629_HIFSYS is not set +CONFIG_COMMON_CLK_MT7981=y +CONFIG_COMMON_CLK_MT7981_ETHSYS=y +CONFIG_COMMON_CLK_MT7986=y +CONFIG_COMMON_CLK_MT7986_ETHSYS=y CONFIG_COMMON_CLK_MT8135=y -CONFIG_COMMON_CLK_MT8173=y +# CONFIG_COMMON_CLK_MT8365 is not set CONFIG_COMMON_CLK_MT8516=y # CONFIG_COMMON_CLK_MT8516_AUDSYS is not set # end of Clock driver for MediaTek SoC -# end of Common Clock Framework +# CONFIG_XILINX_VCU is not set +# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set # CONFIG_HWSPINLOCK is not set # @@ -6035,7 +6924,7 @@ CONFIG_CLKSRC_MMIO=y CONFIG_ARM_ARCH_TIMER=y CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y CONFIG_MTK_TIMER=y -CONFIG_CLKSRC_VERSATILE=y +CONFIG_MTK_CPUX_TIMER=y # CONFIG_MICROCHIP_PIT64B is not set # end of Clock Source drivers @@ -6043,8 +6932,9 @@ CONFIG_MAILBOX=y # CONFIG_PLATFORM_MHU is not set # CONFIG_ALTERA_MBOX is not set # CONFIG_MAILBOX_TEST is not set +CONFIG_MTK_ADSP_MBOX=m CONFIG_MTK_CMDQ_MBOX=y -CONFIG_IOMMU_IOVA=y +CONFIG_IOMMU_IOVA=m CONFIG_IOMMU_API=y CONFIG_IOMMU_SUPPORT=y @@ -6059,12 +6949,14 @@ CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y # end of Generic IOMMU Pagetable Support # CONFIG_IOMMU_DEBUGFS is not set +CONFIG_IOMMU_DEFAULT_DMA_STRICT=y +# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set # CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set CONFIG_OF_IOMMU=y -CONFIG_IOMMU_DMA=y +# CONFIG_IOMMUFD is not set # CONFIG_ARM_SMMU is not set CONFIG_MTK_IOMMU=y -# CONFIG_MTK_IOMMU_V1 is not set +CONFIG_MTK_IOMMU_V1=y # # Remoteproc drivers @@ -6077,6 +6969,8 @@ CONFIG_MTK_IOMMU=y # CONFIG_RPMSG=m # CONFIG_RPMSG_CHAR is not set +# CONFIG_RPMSG_CTRL is not set +CONFIG_RPMSG_NS=m # CONFIG_RPMSG_QCOM_GLINK_RPM is not set CONFIG_RPMSG_VIRTIO=m # end of Rpmsg drivers @@ -6086,6 +6980,7 @@ CONFIG_SOUNDWIRE=m # # SoundWire Devices # +# CONFIG_SOUNDWIRE_QCOM is not set # # SOC (System On Chip) specific Drivers @@ -6096,11 +6991,6 @@ CONFIG_SOUNDWIRE=m # # end of Amlogic SoC drivers -# -# Aspeed SoC drivers -# -# end of Aspeed SoC drivers - # # Broadcom SoC drivers # @@ -6114,20 +7004,38 @@ CONFIG_SOC_BRCMSTB=y # CONFIG_FSL_RCPM is not set # end of NXP/Freescale QorIQ SoC drivers +# +# fujitsu SoC drivers +# +# end of fujitsu SoC drivers + # # i.MX SoC drivers # # end of i.MX SoC drivers +# +# Enable LiteX SoC Builder specific drivers +# +# CONFIG_LITEX_SOC_CONTROLLER is not set +# end of Enable LiteX SoC Builder specific drivers + # # MediaTek SoC drivers # CONFIG_MTK_CMDQ=y +# CONFIG_MTK_DEVAPC is not set CONFIG_MTK_INFRACFG=y CONFIG_MTK_PMIC_WRAP=y +CONFIG_MTK_REGULATOR_COUPLER=y CONFIG_MTK_SCPSYS=y +CONFIG_MTK_SCPSYS_PM_DOMAINS=y +CONFIG_MTK_MMSYS=y +CONFIG_MTK_SVS=y # end of MediaTek SoC drivers +# CONFIG_WPCM450_SOC is not set + # # Qualcomm SoC drivers # @@ -6138,7 +7046,6 @@ CONFIG_MTK_SCPSYS=y # # Xilinx SoC drivers # -# CONFIG_XILINX_VCU is not set # end of Xilinx SoC drivers # end of SOC (System On Chip) specific Drivers @@ -6156,6 +7063,7 @@ CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=m # # DEVFREQ Drivers # +# CONFIG_ARM_MEDIATEK_CCI_DEVFREQ is not set # CONFIG_PM_DEVFREQ_EVENT is not set CONFIG_EXTCON=y @@ -6176,6 +7084,8 @@ CONFIG_MTK_SMI=y CONFIG_IIO=y CONFIG_IIO_BUFFER=y # CONFIG_IIO_BUFFER_CB is not set +# CONFIG_IIO_BUFFER_DMA is not set +# CONFIG_IIO_BUFFER_DMAENGINE is not set # CONFIG_IIO_BUFFER_HW_CONSUMER is not set CONFIG_IIO_KFIFO_BUF=y CONFIG_IIO_TRIGGERED_BUFFER=y @@ -6184,12 +7094,19 @@ CONFIG_IIO_TRIGGER=y CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 # CONFIG_IIO_SW_DEVICE is not set CONFIG_IIO_SW_TRIGGER=y +# CONFIG_IIO_TRIGGERED_EVENT is not set # # Accelerometers # # CONFIG_ADIS16201 is not set # CONFIG_ADIS16209 is not set +# CONFIG_ADXL313_I2C is not set +# CONFIG_ADXL313_SPI is not set +# CONFIG_ADXL355_I2C is not set +# CONFIG_ADXL355_SPI is not set +# CONFIG_ADXL367_SPI is not set +# CONFIG_ADXL367_I2C is not set CONFIG_ADXL372=m CONFIG_ADXL372_SPI=m CONFIG_ADXL372_I2C=m @@ -6197,14 +7114,20 @@ CONFIG_ADXL372_I2C=m # CONFIG_BMA220 is not set CONFIG_BMA400=m CONFIG_BMA400_I2C=m +CONFIG_BMA400_SPI=m # CONFIG_BMC150_ACCEL is not set +# CONFIG_BMI088_ACCEL is not set # CONFIG_DA280 is not set # CONFIG_DA311 is not set # CONFIG_DMARD06 is not set # CONFIG_DMARD09 is not set # CONFIG_DMARD10 is not set +# CONFIG_FXLS8962AF_I2C is not set +# CONFIG_FXLS8962AF_SPI is not set # CONFIG_IIO_CROS_EC_ACCEL_LEGACY is not set # CONFIG_IIO_ST_ACCEL_3AXIS is not set +# CONFIG_IIO_KX022A_SPI is not set +# CONFIG_IIO_KX022A_I2C is not set # CONFIG_KXSD9 is not set # CONFIG_KXCJK1013 is not set # CONFIG_MC3230 is not set @@ -6214,9 +7137,11 @@ CONFIG_BMA400_I2C=m # CONFIG_MMA8452 is not set # CONFIG_MMA9551 is not set # CONFIG_MMA9553 is not set +# CONFIG_MSA311 is not set # CONFIG_MXC4005 is not set # CONFIG_MXC6255 is not set # CONFIG_SCA3000 is not set +# CONFIG_SCA3300 is not set # CONFIG_STK8312 is not set # CONFIG_STK8BA50 is not set # end of Accelerometers @@ -6225,10 +7150,12 @@ CONFIG_BMA400_I2C=m # Analog to digital converters # CONFIG_AD_SIGMA_DELTA=m +# CONFIG_AD4130 is not set CONFIG_AD7091R5=m CONFIG_AD7124=m # CONFIG_AD7192 is not set # CONFIG_AD7266 is not set +# CONFIG_AD7280 is not set # CONFIG_AD7291 is not set CONFIG_AD7292=m # CONFIG_AD7298 is not set @@ -6245,6 +7172,8 @@ CONFIG_AD7768_1=m # CONFIG_AD7923 is not set CONFIG_AD7949=m # CONFIG_AD799X is not set +# CONFIG_AD9467 is not set +# CONFIG_ADI_AXI_ADC is not set # CONFIG_CC10001_ADC is not set # CONFIG_ENVELOPE_DETECTOR is not set # CONFIG_HI8435 is not set @@ -6257,6 +7186,9 @@ CONFIG_LTC2496=m # CONFIG_MAX1027 is not set # CONFIG_MAX11100 is not set # CONFIG_MAX1118 is not set +# CONFIG_MAX11205 is not set +# CONFIG_MAX11410 is not set +# CONFIG_MAX1241 is not set # CONFIG_MAX1363 is not set # CONFIG_MAX9611 is not set # CONFIG_MCP320X is not set @@ -6268,6 +7200,7 @@ CONFIG_QCOM_VADC_COMMON=m # CONFIG_QCOM_SPMI_IADC is not set # CONFIG_QCOM_SPMI_VADC is not set CONFIG_QCOM_SPMI_ADC5=m +# CONFIG_RICHTEK_RTQ6056 is not set # CONFIG_SD_ADC_MODULATOR is not set # CONFIG_TI_ADC081C is not set # CONFIG_TI_ADC0832 is not set @@ -6277,17 +7210,29 @@ CONFIG_QCOM_SPMI_ADC5=m # CONFIG_TI_ADC128S052 is not set # CONFIG_TI_ADC161S626 is not set # CONFIG_TI_ADS1015 is not set +# CONFIG_TI_ADS7924 is not set +# CONFIG_TI_ADS1100 is not set # CONFIG_TI_ADS7950 is not set CONFIG_TI_ADS8344=m # CONFIG_TI_ADS8688 is not set CONFIG_TI_ADS124S08=m +# CONFIG_TI_ADS131E08 is not set +# CONFIG_TI_LMP92064 is not set # CONFIG_TI_TLC4541 is not set +# CONFIG_TI_TSC2046 is not set # CONFIG_TWL4030_MADC is not set # CONFIG_TWL6030_GPADC is not set CONFIG_VF610_ADC=m CONFIG_XILINX_XADC=m # end of Analog to digital converters +# +# Analog to digital and digital to analog converters +# +# CONFIG_AD74115 is not set +# CONFIG_AD74413R is not set +# end of Analog to digital and digital to analog converters + # # Analog Front Ends # @@ -6298,20 +7243,33 @@ CONFIG_XILINX_XADC=m # Amplifiers # # CONFIG_AD8366 is not set +# CONFIG_ADA4250 is not set CONFIG_HMC425=m # end of Amplifiers +# +# Capacitance to digital converters +# +# CONFIG_AD7150 is not set +# CONFIG_AD7746 is not set +# end of Capacitance to digital converters + # # Chemical Sensors # # CONFIG_ATLAS_PH_SENSOR is not set +# CONFIG_ATLAS_EZO_SENSOR is not set CONFIG_BME680=m CONFIG_BME680_I2C=m CONFIG_BME680_SPI=m # CONFIG_CCS811 is not set # CONFIG_IAQCORE is not set +# CONFIG_SCD30_CORE is not set +# CONFIG_SCD4X is not set CONFIG_SENSIRION_SGP30=m -CONFIG_SPS30=m +# CONFIG_SENSIRION_SGP40 is not set +# CONFIG_SPS30_I2C is not set +# CONFIG_SENSEAIR_SUNRISE_CO2 is not set # CONFIG_VZ89X is not set # end of Chemical Sensors @@ -6324,6 +7282,11 @@ CONFIG_IIO_CROS_EC_SENSORS_LID_ANGLE=m # # end of Hid Sensor IIO Common +# +# IIO SCMI Sensors +# +# end of IIO SCMI Sensors + # # SSP Sensor Common # @@ -6333,6 +7296,7 @@ CONFIG_IIO_CROS_EC_SENSORS_LID_ANGLE=m # # Digital to analog converters # +# CONFIG_AD3552R is not set # CONFIG_AD5064 is not set # CONFIG_AD5360 is not set # CONFIG_AD5380 is not set @@ -6343,14 +7307,17 @@ CONFIG_IIO_CROS_EC_SENSORS_LID_ANGLE=m # CONFIG_AD5593R is not set # CONFIG_AD5504 is not set # CONFIG_AD5624R_SPI is not set +# CONFIG_LTC2688 is not set # CONFIG_AD5686_SPI is not set # CONFIG_AD5696_I2C is not set # CONFIG_AD5755 is not set CONFIG_AD5758=m # CONFIG_AD5761 is not set # CONFIG_AD5764 is not set +# CONFIG_AD5766 is not set CONFIG_AD5770R=m # CONFIG_AD5791 is not set +# CONFIG_AD7293 is not set # CONFIG_AD7303 is not set # CONFIG_AD8801 is not set # CONFIG_DPOT_DAC is not set @@ -6359,8 +7326,10 @@ CONFIG_LTC1660=m # CONFIG_LTC2632 is not set # CONFIG_M62332 is not set # CONFIG_MAX517 is not set +# CONFIG_MAX5522 is not set # CONFIG_MAX5821 is not set # CONFIG_MCP4725 is not set +# CONFIG_MCP4728 is not set # CONFIG_MCP4922 is not set # CONFIG_TI_DAC082S085 is not set # CONFIG_TI_DAC5571 is not set @@ -6374,6 +7343,11 @@ CONFIG_TI_DAC7612=m # # end of IIO dummy driver +# +# Filters +# +# end of Filters + # # Frequency Synthesizers DDS/PLL # @@ -6389,6 +7363,10 @@ CONFIG_TI_DAC7612=m # # CONFIG_ADF4350 is not set CONFIG_ADF4371=m +# CONFIG_ADF4377 is not set +# CONFIG_ADMV1013 is not set +# CONFIG_ADMV4420 is not set +# CONFIG_ADRF6780 is not set # end of Phase-Locked Loop (PLL) frequency synthesizers # end of Frequency Synthesizers DDS/PLL @@ -6399,6 +7377,7 @@ CONFIG_ADF4371=m # CONFIG_ADIS16130 is not set # CONFIG_ADIS16136 is not set # CONFIG_ADIS16260 is not set +# CONFIG_ADXRS290 is not set # CONFIG_ADXRS450 is not set # CONFIG_BMG160 is not set CONFIG_FXAS21002C=m @@ -6430,6 +7409,7 @@ CONFIG_MPU3050_I2C=y # CONFIG_AM2315 is not set # CONFIG_DHT11 is not set # CONFIG_HDC100X is not set +# CONFIG_HDC2010 is not set # CONFIG_HTS221 is not set # CONFIG_HTU21 is not set # CONFIG_SI7005 is not set @@ -6441,16 +7421,21 @@ CONFIG_MPU3050_I2C=y # # CONFIG_ADIS16400 is not set CONFIG_ADIS16460=m +# CONFIG_ADIS16475 is not set # CONFIG_ADIS16480 is not set # CONFIG_BMI160_I2C is not set # CONFIG_BMI160_SPI is not set +# CONFIG_BOSCH_BNO055_I2C is not set CONFIG_FXOS8700=m CONFIG_FXOS8700_I2C=m CONFIG_FXOS8700_SPI=m # CONFIG_KMX61 is not set +# CONFIG_INV_ICM42600_I2C is not set +# CONFIG_INV_ICM42600_SPI is not set # CONFIG_INV_MPU6050_I2C is not set # CONFIG_INV_MPU6050_SPI is not set # CONFIG_IIO_ST_LSM6DSX is not set +# CONFIG_IIO_ST_LSM9DS0 is not set # end of Inertial measurement units CONFIG_IIO_ADIS_LIB=m @@ -6465,6 +7450,7 @@ CONFIG_AL3010=m # CONFIG_AL3320A is not set # CONFIG_APDS9300 is not set # CONFIG_APDS9960 is not set +# CONFIG_AS73211 is not set # CONFIG_BH1750 is not set # CONFIG_BH1780 is not set # CONFIG_CM32181 is not set @@ -6480,13 +7466,17 @@ CONFIG_SENSORS_ISL29018=y CONFIG_SENSORS_ISL29028=y # CONFIG_ISL29125 is not set # CONFIG_JSA1212 is not set +# CONFIG_ROHM_BU27008 is not set +# CONFIG_ROHM_BU27034 is not set # CONFIG_RPR0521 is not set # CONFIG_LTR501 is not set +# CONFIG_LTRF216A is not set # CONFIG_LV0104CS is not set # CONFIG_MAX44000 is not set CONFIG_MAX44009=m CONFIG_NOA1305=m # CONFIG_OPT3001 is not set +# CONFIG_OPT4001 is not set # CONFIG_PA12203001 is not set CONFIG_SI1133=m # CONFIG_SI1145 is not set @@ -6496,6 +7486,7 @@ CONFIG_SI1133=m # CONFIG_TCS3472 is not set # CONFIG_SENSORS_TSL2563 is not set # CONFIG_TSL2583 is not set +# CONFIG_TSL2591 is not set # CONFIG_TSL2772 is not set # CONFIG_TSL4531 is not set # CONFIG_US5182D is not set @@ -6523,6 +7514,8 @@ CONFIG_AK8975=y CONFIG_SENSORS_RM3100=m CONFIG_SENSORS_RM3100_I2C=m CONFIG_SENSORS_RM3100_SPI=m +# CONFIG_TI_TMAG5273 is not set +# CONFIG_YAMAHA_YAS530 is not set # end of Magnetometer sensors # @@ -6554,6 +7547,7 @@ CONFIG_IQS624_POS=m # # Digital potentiometers # +# CONFIG_AD5110 is not set # CONFIG_AD5272 is not set # CONFIG_DS1803 is not set CONFIG_MAX5432=m @@ -6564,6 +7558,7 @@ CONFIG_MAX5432=m # CONFIG_MCP4531 is not set CONFIG_MCP41010=m # CONFIG_TPL0102 is not set +# CONFIG_X9250 is not set # end of Digital potentiometers # @@ -6585,6 +7580,7 @@ CONFIG_ICP10100=m # CONFIG_MPL115_I2C is not set # CONFIG_MPL115_SPI is not set # CONFIG_MPL3115 is not set +# CONFIG_MPRLS0025PA is not set # CONFIG_MS5611 is not set # CONFIG_MS5637 is not set # CONFIG_IIO_ST_PRESS is not set @@ -6602,14 +7598,20 @@ CONFIG_ICP10100=m # # Proximity and distance sensors # +# CONFIG_CROS_EC_MKBP_PROXIMITY is not set +# CONFIG_IRSD200 is not set CONFIG_ISL29501=m # CONFIG_LIDAR_LITE_V2 is not set CONFIG_MB1232=m CONFIG_PING=m # CONFIG_RFD77402 is not set # CONFIG_SRF04 is not set +# CONFIG_SX9310 is not set +# CONFIG_SX9324 is not set +# CONFIG_SX9360 is not set # CONFIG_SX9500 is not set # CONFIG_SRF08 is not set +# CONFIG_VCNL3020 is not set CONFIG_VL53L0X_I2C=m # end of Proximity and distance sensors @@ -6630,23 +7632,30 @@ CONFIG_LTC2983=m # CONFIG_MLX90632 is not set # CONFIG_TMP006 is not set # CONFIG_TMP007 is not set +# CONFIG_TMP117 is not set # CONFIG_TSYS01 is not set # CONFIG_TSYS02D is not set +# CONFIG_MAX30208 is not set CONFIG_MAX31856=m +# CONFIG_MAX31865 is not set # end of Temperature sensors # CONFIG_NTB is not set -# CONFIG_VME_BUS is not set CONFIG_PWM=y CONFIG_PWM_SYSFS=y # CONFIG_PWM_DEBUG is not set +# CONFIG_PWM_ATMEL_TCB is not set +# CONFIG_PWM_CLK is not set CONFIG_PWM_CROS_EC=m +# CONFIG_PWM_DWC is not set # CONFIG_PWM_FSL_FTM is not set +# CONFIG_PWM_IQS620A is not set # CONFIG_PWM_MTK_DISP is not set CONFIG_PWM_MEDIATEK=m # CONFIG_PWM_PCA9685 is not set # CONFIG_PWM_TWL is not set # CONFIG_PWM_TWL_LED is not set +# CONFIG_PWM_XILINX is not set # # IRQ chip support @@ -6655,34 +7664,47 @@ CONFIG_IRQCHIP=y CONFIG_ARM_GIC=y CONFIG_ARM_GIC_MAX_NR=1 # CONFIG_AL_FIC is not set +# CONFIG_XILINX_INTC is not set +CONFIG_MST_IRQ=y # end of IRQ chip support # CONFIG_IPACK_BUS is not set CONFIG_RESET_CONTROLLER=y -# CONFIG_RESET_BRCMSTB_RESCAL is not set -# CONFIG_RESET_INTEL_GW is not set +# CONFIG_RESET_SIMPLE is not set # CONFIG_RESET_TI_SYSCON is not set +# CONFIG_RESET_TI_TPS380X is not set # # PHY Subsystem # CONFIG_GENERIC_PHY=y CONFIG_GENERIC_PHY_MIPI_DPHY=y +# CONFIG_PHY_CAN_TRANSCEIVER is not set + +# +# PHY drivers for Broadcom platforms +# # CONFIG_BCM_KONA_USB2_PHY is not set +# end of PHY drivers for Broadcom platforms + CONFIG_PHY_CADENCE_TORRENT=m CONFIG_PHY_CADENCE_DPHY=m +# CONFIG_PHY_CADENCE_DPHY_RX is not set CONFIG_PHY_CADENCE_SIERRA=m -CONFIG_PHY_FSL_IMX8MQ_USB=m -CONFIG_PHY_MIXEL_MIPI_DPHY=m +# CONFIG_PHY_CADENCE_SALVO is not set # CONFIG_PHY_PXA_28NM_HSIC is not set # CONFIG_PHY_PXA_28NM_USB2 is not set +CONFIG_PHY_MTK_PCIE=y CONFIG_PHY_MTK_TPHY=y CONFIG_PHY_MTK_UFS=m CONFIG_PHY_MTK_XSPHY=y +CONFIG_PHY_MTK_HDMI=y +CONFIG_PHY_MTK_MIPI_DSI=y +CONFIG_PHY_MTK_DP=m +# CONFIG_PHY_LAN966X_SERDES is not set # CONFIG_PHY_CPCAP_USB is not set # CONFIG_PHY_MAPPHONE_MDM6600 is not set CONFIG_PHY_OCELOT_SERDES=m -CONFIG_PHY_INTEL_EMMC=m # end of PHY Subsystem # CONFIG_POWERCAP is not set @@ -6694,21 +7716,33 @@ CONFIG_PHY_INTEL_EMMC=m # CONFIG_ARM_CCI_PMU is not set # CONFIG_ARM_CCN is not set CONFIG_ARM_PMU=y +# CONFIG_ARM_PMUV3 is not set # end of Performance monitor support CONFIG_RAS=y +# CONFIG_USB4 is not set # # Android # -# CONFIG_ANDROID is not set +# CONFIG_ANDROID_BINDER_IPC is not set # end of Android # CONFIG_DAX is not set CONFIG_NVMEM=y CONFIG_NVMEM_SYSFS=y -CONFIG_MTK_EFUSE=m + +# +# Layout Types +# +# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set +# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set +# end of Layout Types + +CONFIG_NVMEM_MTK_EFUSE=y +# CONFIG_NVMEM_RMEM is not set CONFIG_NVMEM_SPMI_SDAM=m +# CONFIG_NVMEM_U_BOOT_ENV is not set # # HW tracing support @@ -6734,10 +7768,12 @@ CONFIG_MULTIPLEXER=m CONFIG_PM_OPP=y # CONFIG_SIOX is not set # CONFIG_SLIMBUS is not set -CONFIG_INTERCONNECT=m +# CONFIG_INTERCONNECT is not set CONFIG_COUNTER=m -CONFIG_FTM_QUADDEC=m +# CONFIG_INTERRUPT_CNT is not set # CONFIG_MOST is not set +# CONFIG_PECI is not set +# CONFIG_HTE is not set # end of Device Drivers # @@ -6746,6 +7782,8 @@ CONFIG_FTM_QUADDEC=m CONFIG_DCACHE_WORD_ACCESS=y # CONFIG_VALIDATE_FS_PARSER is not set CONFIG_FS_IOMAP=y +CONFIG_BUFFER_HEAD=y +CONFIG_LEGACY_DIRECT_IO=y # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set CONFIG_EXT4_FS=y @@ -6759,6 +7797,8 @@ CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set CONFIG_XFS_FS=m +CONFIG_XFS_SUPPORT_V4=y +CONFIG_XFS_SUPPORT_ASCII_CI=y # CONFIG_XFS_QUOTA is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set @@ -6783,11 +7823,17 @@ CONFIG_F2FS_FS_POSIX_ACL=y # CONFIG_F2FS_CHECK_FS is not set # CONFIG_F2FS_FAULT_INJECTION is not set CONFIG_F2FS_FS_COMPRESSION=y +CONFIG_F2FS_FS_LZO=y +CONFIG_F2FS_FS_LZORLE=y +CONFIG_F2FS_FS_LZ4=y +CONFIG_F2FS_FS_LZ4HC=y +CONFIG_F2FS_FS_ZSTD=y +CONFIG_F2FS_IOSTAT=y +# CONFIG_F2FS_UNFAIR_RWSEM is not set CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y CONFIG_EXPORTFS_BLOCK_OPS=y CONFIG_FILE_LOCKING=y -CONFIG_MANDATORY_FILE_LOCKING=y # CONFIG_FS_ENCRYPTION is not set # CONFIG_FS_VERITY is not set CONFIG_FSNOTIFY=y @@ -6795,7 +7841,6 @@ CONFIG_DNOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_FANOTIFY is not set # CONFIG_QUOTA is not set -CONFIG_AUTOFS4_FS=y CONFIG_AUTOFS_FS=y CONFIG_FUSE_FS=y # CONFIG_CUSE is not set @@ -6805,10 +7850,13 @@ CONFIG_OVERLAY_FS=y CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y # CONFIG_OVERLAY_FS_INDEX is not set # CONFIG_OVERLAY_FS_METACOPY is not set +# CONFIG_OVERLAY_FS_DEBUG is not set # # Caches # +CONFIG_NETFS_SUPPORT=m +# CONFIG_NETFS_STATS is not set # CONFIG_FSCACHE is not set # end of Caches @@ -6833,6 +7881,7 @@ CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" CONFIG_NTFS_FS=y # CONFIG_NTFS_DEBUG is not set # CONFIG_NTFS_RW is not set +# CONFIG_NTFS3_FS is not set # end of DOS/FAT/EXFAT/NT Filesystems # @@ -6847,7 +7896,7 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_TMPFS_XATTR=y -CONFIG_MEMFD_CREATE=y +# CONFIG_TMPFS_QUOTA is not set CONFIG_CONFIGFS_FS=y CONFIG_EFIVAR_FS=m # end of Pseudo filesystems @@ -6877,8 +7926,10 @@ CONFIG_SQUASHFS=y CONFIG_SQUASHFS_FILE_CACHE=y # CONFIG_SQUASHFS_FILE_DIRECT is not set CONFIG_SQUASHFS_DECOMP_SINGLE=y -# CONFIG_SQUASHFS_DECOMP_MULTI is not set -# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set +# CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT is not set +CONFIG_SQUASHFS_COMPILE_DECOMP_SINGLE=y +# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI is not set +# CONFIG_SQUASHFS_COMPILE_DECOMP_MULTI_PERCPU is not set # CONFIG_SQUASHFS_XATTR is not set CONFIG_SQUASHFS_ZLIB=y # CONFIG_SQUASHFS_LZ4 is not set @@ -6896,38 +7947,15 @@ CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 # CONFIG_QNX6FS_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_PSTORE=y -CONFIG_PSTORE_DEFLATE_COMPRESS=y -# CONFIG_PSTORE_LZO_COMPRESS is not set -# CONFIG_PSTORE_LZ4_COMPRESS is not set -# CONFIG_PSTORE_LZ4HC_COMPRESS is not set -# CONFIG_PSTORE_842_COMPRESS is not set -# CONFIG_PSTORE_ZSTD_COMPRESS is not set +CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 CONFIG_PSTORE_COMPRESS=y -CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y -CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" CONFIG_PSTORE_CONSOLE=y CONFIG_PSTORE_PMSG=y CONFIG_PSTORE_RAM=y +# CONFIG_PSTORE_BLK is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set # CONFIG_EROFS_FS is not set -CONFIG_AUFS_FS=m -CONFIG_AUFS_BRANCH_MAX_127=y -# CONFIG_AUFS_BRANCH_MAX_511 is not set -# CONFIG_AUFS_BRANCH_MAX_1023 is not set -# CONFIG_AUFS_BRANCH_MAX_32767 is not set -CONFIG_AUFS_SBILIST=y -# CONFIG_AUFS_HNOTIFY is not set -# CONFIG_AUFS_EXPORT is not set -# CONFIG_AUFS_XATTR is not set -# CONFIG_AUFS_FHSM is not set -# CONFIG_AUFS_RDU is not set -# CONFIG_AUFS_DIRREN is not set -# CONFIG_AUFS_SHWH is not set -# CONFIG_AUFS_BR_RAMFS is not set -# CONFIG_AUFS_BR_FUSE is not set -CONFIG_AUFS_BDEV_LOOP=y -# CONFIG_AUFS_DEBUG is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V2=m @@ -6942,16 +7970,12 @@ CONFIG_PNFS_BLOCK=m CONFIG_PNFS_FLEXFILE_LAYOUT=m CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" CONFIG_NFS_V4_1_MIGRATION=y -CONFIG_NFS_V4_SECURITY_LABEL=y -CONFIG_NFS_FSCACHE=y # CONFIG_NFS_USE_LEGACY_DNS is not set CONFIG_NFS_USE_KERNEL_DNS=y -CONFIG_NFS_DEBUG=y CONFIG_NFS_DISABLE_UDP_SUPPORT=y # CONFIG_NFS_V4_2_READ_PLUS is not set CONFIG_NFSD=m -CONFIG_NFSD_V2_ACL=y -CONFIG_NFSD_V3=y +# CONFIG_NFSD_V2 is not set CONFIG_NFSD_V3_ACL=y CONFIG_NFSD_V4=y CONFIG_NFSD_PNFS=y @@ -6959,28 +7983,31 @@ CONFIG_NFSD_BLOCKLAYOUT=y CONFIG_NFSD_SCSILAYOUT=y CONFIG_NFSD_FLEXFILELAYOUT=y # CONFIG_NFSD_V4_2_INTER_SSC is not set -CONFIG_NFSD_V4_SECURITY_LABEL=y -CONFIG_GRACE_PERIOD=y -CONFIG_LOCKD=y +CONFIG_GRACE_PERIOD=m +CONFIG_LOCKD=m CONFIG_LOCKD_V4=y -CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_ACL_SUPPORT=m CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y +CONFIG_NFS_V4_2_SSC_HELPER=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m CONFIG_SUNRPC_BACKCHANNEL=y CONFIG_SUNRPC_SWAP=y +CONFIG_RPCSEC_GSS_KRB5=m # CONFIG_SUNRPC_DEBUG is not set # CONFIG_CEPH_FS is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS2 is not set CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y -# CONFIG_CIFS_WEAK_PW_HASH is not set # CONFIG_CIFS_UPCALL is not set # CONFIG_CIFS_XATTR is not set CONFIG_CIFS_DEBUG=y # CONFIG_CIFS_DEBUG2 is not set # CONFIG_CIFS_DEBUG_DUMP_KEYS is not set # CONFIG_CIFS_DFS_UPCALL is not set +# CONFIG_CIFS_SWN_UPCALL is not set +# CONFIG_SMB_SERVER is not set +CONFIG_SMBFS=m # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set # CONFIG_9P_FS is not set @@ -7035,6 +8062,7 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_MAC_ROMANIAN is not set # CONFIG_NLS_MAC_TURKISH is not set CONFIG_NLS_UTF8=y +CONFIG_NLS_UCS2_UTILS=m # CONFIG_DLM is not set # CONFIG_UNICODE is not set CONFIG_IO_WQ=y @@ -7046,13 +8074,12 @@ CONFIG_IO_WQ=y CONFIG_KEYS=y # CONFIG_KEYS_REQUEST_CACHE is not set # CONFIG_PERSISTENT_KEYRINGS is not set -# CONFIG_BIG_KEYS is not set +# CONFIG_TRUSTED_KEYS is not set # CONFIG_ENCRYPTED_KEYS is not set # CONFIG_KEY_DH_OPERATIONS is not set # CONFIG_SECURITY_DMESG_RESTRICT is not set # CONFIG_SECURITY is not set # CONFIG_SECURITYFS is not set -CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y # CONFIG_HARDENED_USERCOPY is not set # CONFIG_FORTIFY_SOURCE is not set # CONFIG_STATIC_USERMODEHELPER is not set @@ -7066,10 +8093,26 @@ CONFIG_LSM="m" # # Memory initialization # +CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN=y +CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_BARE=y +CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO=y CONFIG_INIT_STACK_NONE=y +# CONFIG_INIT_STACK_ALL_PATTERN is not set +# CONFIG_INIT_STACK_ALL_ZERO is not set # CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set # CONFIG_INIT_ON_FREE_DEFAULT_ON is not set +CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y +# CONFIG_ZERO_CALL_USED_REGS is not set # end of Memory initialization + +# +# Hardening of kernel data structures +# +# CONFIG_LIST_HARDENED is not set +# CONFIG_BUG_ON_DATA_CORRUPTION is not set +# end of Hardening of kernel data structures + +CONFIG_RANDSTRUCT_NONE=y # end of Kernel hardening options # end of Security options @@ -7088,6 +8131,8 @@ CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=y CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_SIG=y +CONFIG_CRYPTO_SIG2=y CONFIG_CRYPTO_SKCIPHER=y CONFIG_CRYPTO_SKCIPHER2=y CONFIG_CRYPTO_HASH=y @@ -7104,7 +8149,6 @@ CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -CONFIG_CRYPTO_GF128MUL=y CONFIG_CRYPTO_NULL=y CONFIG_CRYPTO_NULL2=y # CONFIG_CRYPTO_PCRYPT is not set @@ -7113,6 +8157,7 @@ CONFIG_CRYPTO_AUTHENC=y # CONFIG_CRYPTO_TEST is not set CONFIG_CRYPTO_SIMD=m CONFIG_CRYPTO_ENGINE=m +# end of Crypto core or helper # # Public-key cryptography @@ -7121,93 +8166,99 @@ CONFIG_CRYPTO_RSA=y # CONFIG_CRYPTO_DH is not set CONFIG_CRYPTO_ECC=y CONFIG_CRYPTO_ECDH=y +# CONFIG_CRYPTO_ECDSA is not set CONFIG_CRYPTO_ECRDSA=m +# CONFIG_CRYPTO_SM2 is not set # CONFIG_CRYPTO_CURVE25519 is not set +# end of Public-key cryptography # -# Authenticated Encryption with Associated Data +# Block ciphers # -CONFIG_CRYPTO_CCM=y -CONFIG_CRYPTO_GCM=y -CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_AEGIS128=m -CONFIG_CRYPTO_AEGIS128_SIMD=y -CONFIG_CRYPTO_SEQIV=y -CONFIG_CRYPTO_ECHAINIV=m +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_AES_TI is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARIA is not set +# 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_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_SM4_GENERIC is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set +# end of Block ciphers # -# Block modes +# Length-preserving ciphers and modes # +CONFIG_CRYPTO_ADIANTUM=m +CONFIG_CRYPTO_ARC4=y +CONFIG_CRYPTO_CHACHA20=m CONFIG_CRYPTO_CBC=y # CONFIG_CRYPTO_CFB is not set CONFIG_CRYPTO_CTR=y # CONFIG_CRYPTO_CTS is not set CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_HCTR2 is not set +# CONFIG_CRYPTO_KEYWRAP is not set # CONFIG_CRYPTO_LRW is not set CONFIG_CRYPTO_OFB=m # CONFIG_CRYPTO_PCBC is not set # CONFIG_CRYPTO_XTS is not set -# CONFIG_CRYPTO_KEYWRAP is not set CONFIG_CRYPTO_NHPOLY1305=m -CONFIG_CRYPTO_ADIANTUM=m -CONFIG_CRYPTO_ESSIV=y +# end of Length-preserving ciphers and modes # -# Hash modes +# AEAD (authenticated encryption with associated data) ciphers # -CONFIG_CRYPTO_CMAC=y -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_VMAC is not set +CONFIG_CRYPTO_AEGIS128=m +CONFIG_CRYPTO_AEGIS128_SIMD=y +CONFIG_CRYPTO_CHACHA20POLY1305=m +CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_GCM=y +CONFIG_CRYPTO_GENIV=y +CONFIG_CRYPTO_SEQIV=y +CONFIG_CRYPTO_ECHAINIV=m +CONFIG_CRYPTO_ESSIV=y +# end of AEAD (authenticated encryption with associated data) ciphers # -# Digest +# Hashes, digests, and MACs # -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_CRC32=m -CONFIG_CRYPTO_XXHASH=y CONFIG_CRYPTO_BLAKE2B=y -CONFIG_CRYPTO_BLAKE2S=m -CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_CMAC=y CONFIG_CRYPTO_GHASH=y -CONFIG_CRYPTO_POLY1305=m +CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MICHAEL_MIC=m -# CONFIG_CRYPTO_RMD128 is not set +CONFIG_CRYPTO_POLY1305=m # CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RMD256 is not set -# CONFIG_CRYPTO_RMD320 is not set CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y -CONFIG_CRYPTO_SHA3=m -# CONFIG_CRYPTO_SM3 is not set +CONFIG_CRYPTO_SHA3=y +# CONFIG_CRYPTO_SM3_GENERIC is not set CONFIG_CRYPTO_STREEBOG=m -# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_VMAC is not set # CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_XCBC is not set +CONFIG_CRYPTO_XXHASH=y +# end of Hashes, digests, and MACs # -# Ciphers +# CRCs (cyclic redundancy checks) # -CONFIG_CRYPTO_AES=y -# CONFIG_CRYPTO_AES_TI is not set -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_ARC4=y -# 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 is not set -CONFIG_CRYPTO_CHACHA20=m -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_SM4 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRC32=m +CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_CRC64_ROCKSOFT=y +# end of CRCs (cyclic redundancy checks) # # Compression @@ -7218,9 +8269,10 @@ CONFIG_CRYPTO_LZO=y # CONFIG_CRYPTO_LZ4 is not set # CONFIG_CRYPTO_LZ4HC is not set CONFIG_CRYPTO_ZSTD=y +# end of Compression # -# Random Number Generation +# Random number generation # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_DRBG_MENU=y @@ -7229,40 +8281,59 @@ CONFIG_CRYPTO_DRBG_HMAC=y # CONFIG_CRYPTO_DRBG_CTR is not set CONFIG_CRYPTO_DRBG=y CONFIG_CRYPTO_JITTERENTROPY=y +# CONFIG_CRYPTO_JITTERENTROPY_TESTINTERFACE is not set +# end of Random number generation + +# +# Userspace interface +# CONFIG_CRYPTO_USER_API=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m CONFIG_CRYPTO_USER_API_RNG=m +# CONFIG_CRYPTO_USER_API_RNG_CAVP is not set CONFIG_CRYPTO_USER_API_AEAD=m +CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y # CONFIG_CRYPTO_STATS is not set +# end of Userspace interface + CONFIG_CRYPTO_HASH_INFO=y # -# Crypto library routines +# Accelerated Cryptographic Algorithms for CPU (arm) # -CONFIG_CRYPTO_LIB_AES=y -CONFIG_CRYPTO_LIB_ARC4=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=m -CONFIG_CRYPTO_LIB_BLAKE2S=m -CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m -CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m -CONFIG_CRYPTO_LIB_CHACHA=m -CONFIG_CRYPTO_ARCH_HAVE_LIB_CURVE25519=m -CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m -CONFIG_CRYPTO_LIB_CURVE25519=m -CONFIG_CRYPTO_LIB_DES=m -CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 -CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m -CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m -CONFIG_CRYPTO_LIB_POLY1305=m -CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m -CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_CURVE25519_NEON=m +CONFIG_CRYPTO_GHASH_ARM_CE=m +CONFIG_CRYPTO_NHPOLY1305_NEON=m +CONFIG_CRYPTO_POLY1305_ARM=m +CONFIG_CRYPTO_BLAKE2S_ARM=y +# CONFIG_CRYPTO_BLAKE2B_NEON is not set +CONFIG_CRYPTO_SHA1_ARM=m +CONFIG_CRYPTO_SHA1_ARM_NEON=m +CONFIG_CRYPTO_SHA1_ARM_CE=m +CONFIG_CRYPTO_SHA2_ARM_CE=m +CONFIG_CRYPTO_SHA256_ARM=m +CONFIG_CRYPTO_SHA512_ARM=m +CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRYPTO_AES_ARM_BS=m +CONFIG_CRYPTO_AES_ARM_CE=m +CONFIG_CRYPTO_CHACHA20_NEON=m +CONFIG_CRYPTO_CRC32_ARM_CE=m +CONFIG_CRYPTO_CRCT10DIF_ARM_CE=m +# end of Accelerated Cryptographic Algorithms for CPU (arm) + CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set CONFIG_CRYPTO_DEV_ATMEL_I2C=m CONFIG_CRYPTO_DEV_ATMEL_ECC=m CONFIG_CRYPTO_DEV_ATMEL_SHA204A=m -CONFIG_CRYPTO_DEV_MEDIATEK=y +# CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set +# CONFIG_CRYPTO_DEV_QAT_C3XXX is not set +# CONFIG_CRYPTO_DEV_QAT_C62X is not set +# CONFIG_CRYPTO_DEV_QAT_4XXX is not set +# CONFIG_CRYPTO_DEV_QAT_DH895xCCVF is not set +# CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set +# CONFIG_CRYPTO_DEV_QAT_C62XVF is not set # CONFIG_CRYPTO_DEV_VIRTIO is not set CONFIG_CRYPTO_DEV_SAFEXCEL=m # CONFIG_CRYPTO_DEV_CCREE is not set @@ -7275,6 +8346,7 @@ CONFIG_PKCS8_PRIVATE_KEY_PARSER=m CONFIG_PKCS7_MESSAGE_PARSER=y # CONFIG_PKCS7_TEST_KEY is not set # CONFIG_SIGNED_PE_FILE_VERIFICATION is not set +# CONFIG_FIPS_SIGNATURE_SELFTEST is not set # # Certificates for signature checking @@ -7293,6 +8365,7 @@ CONFIG_BINARY_PRINTF=y # CONFIG_RAID6_PQ=y CONFIG_RAID6_PQ_BENCHMARK=y +CONFIG_LINEAR_RANGES=y CONFIG_PACKING=y CONFIG_BITREVERSE=y CONFIG_HAVE_ARCH_BITREVERSE=y @@ -7300,12 +8373,39 @@ CONFIG_GENERIC_STRNCPY_FROM_USER=y CONFIG_GENERIC_STRNLEN_USER=y CONFIG_GENERIC_NET_UTILS=y CONFIG_CORDIC=m +# CONFIG_PRIME_NUMBERS is not set CONFIG_RATIONAL=y CONFIG_GENERIC_PCI_IOMAP=y CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y + +# +# Crypto library routines +# +CONFIG_CRYPTO_LIB_UTILS=y +CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_ARC4=y +CONFIG_CRYPTO_LIB_GF128MUL=y +CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S=y +CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m +CONFIG_CRYPTO_LIB_CHACHA_GENERIC=m +CONFIG_CRYPTO_LIB_CHACHA=m +CONFIG_CRYPTO_ARCH_HAVE_LIB_CURVE25519=m +CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m +CONFIG_CRYPTO_LIB_CURVE25519=m +CONFIG_CRYPTO_LIB_DES=m +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 +CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m +CONFIG_CRYPTO_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m +CONFIG_CRYPTO_LIB_SHA1=y +CONFIG_CRYPTO_LIB_SHA256=y +# end of Crypto library routines + CONFIG_CRC_CCITT=m CONFIG_CRC16=y CONFIG_CRC_T10DIF=y +CONFIG_CRC64_ROCKSOFT=y CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC32_SELFTEST is not set @@ -7313,7 +8413,7 @@ CONFIG_CRC32_SLICEBY8=y # CONFIG_CRC32_SLICEBY4 is not set # CONFIG_CRC32_SARWATE is not set # CONFIG_CRC32_BIT is not set -# CONFIG_CRC64 is not set +CONFIG_CRC64=y # CONFIG_CRC4 is not set CONFIG_CRC7=m CONFIG_LIBCRC32C=y @@ -7324,7 +8424,10 @@ CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y CONFIG_LZO_COMPRESS=y CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_COMPRESS=m +CONFIG_LZ4HC_COMPRESS=m CONFIG_LZ4_DECOMPRESS=y +CONFIG_ZSTD_COMMON=y CONFIG_ZSTD_COMPRESS=y CONFIG_ZSTD_DECOMPRESS=y CONFIG_XZ_DEC=y @@ -7334,6 +8437,7 @@ CONFIG_XZ_DEC_IA64=y CONFIG_XZ_DEC_ARM=y CONFIG_XZ_DEC_ARMTHUMB=y CONFIG_XZ_DEC_SPARC=y +# CONFIG_XZ_DEC_MICROLZMA is not set CONFIG_XZ_DEC_BCJ=y # CONFIG_XZ_DEC_TEST is not set CONFIG_DECOMPRESS_GZIP=y @@ -7342,6 +8446,7 @@ CONFIG_DECOMPRESS_LZMA=y CONFIG_DECOMPRESS_XZ=y CONFIG_DECOMPRESS_LZO=y CONFIG_DECOMPRESS_LZ4=y +CONFIG_DECOMPRESS_ZSTD=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_REED_SOLOMON=y CONFIG_REED_SOLOMON_ENC8=y @@ -7352,17 +8457,21 @@ CONFIG_TEXTSEARCH=y CONFIG_TEXTSEARCH_KMP=m CONFIG_TEXTSEARCH_BM=m CONFIG_TEXTSEARCH_FSM=m +CONFIG_XARRAY_MULTI=y CONFIG_ASSOCIATIVE_ARRAY=y CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y CONFIG_HAS_IOPORT_MAP=y CONFIG_HAS_DMA=y +CONFIG_DMA_OPS=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DMA_DECLARE_COHERENT=y CONFIG_ARCH_HAS_SETUP_DMA_OPS=y CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y +CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y +CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU=y CONFIG_DMA_NONCOHERENT_MMAP=y -CONFIG_DMA_REMAP=y CONFIG_DMA_CMA=y # @@ -7375,7 +8484,9 @@ CONFIG_CMA_SIZE_SEL_MBYTES=y # CONFIG_CMA_SIZE_SEL_MAX is not set CONFIG_CMA_ALIGNMENT=8 # CONFIG_DMA_API_DEBUG is not set +# CONFIG_DMA_MAP_BENCHMARK is not set CONFIG_SGL_ALLOC=y +# CONFIG_FORCE_NR_CPUS is not set CONFIG_CPU_RMAP=y CONFIG_DQL=y CONFIG_GLOB=y @@ -7384,6 +8495,7 @@ CONFIG_NLATTR=y CONFIG_CLZ_TAB=y # CONFIG_IRQ_POLL is not set CONFIG_MPILIB=y +CONFIG_DIMLIB=y CONFIG_LIBFDT=y CONFIG_OID_REGISTRY=y CONFIG_UCS2_STRING=y @@ -7395,10 +8507,13 @@ CONFIG_FONT_SUPPORT=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y CONFIG_SG_POOL=y +CONFIG_ARCH_STACKWALK=y +CONFIG_STACKDEPOT=y CONFIG_SBITMAP=y -# CONFIG_STRING_SELFTEST is not set # end of Library routines +CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y + # # Kernel hacking # @@ -7408,26 +8523,35 @@ CONFIG_SBITMAP=y # CONFIG_PRINTK_TIME=y # CONFIG_PRINTK_CALLER is not set +# CONFIG_STACKTRACE_BUILD_ID is not set CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 CONFIG_CONSOLE_LOGLEVEL_QUIET=4 CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DYNAMIC_DEBUG_CORE is not set CONFIG_SYMBOLIC_ERRNAME=y CONFIG_DEBUG_BUGVERBOSE=y # end of printk and dmesg options +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_MISC=y + # # Compile-time checks and compiler options # -# CONFIG_DEBUG_INFO is not set -CONFIG_ENABLE_MUST_CHECK=y +CONFIG_AS_HAS_NON_CONST_LEB128=y +CONFIG_DEBUG_INFO_NONE=y +# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set +# CONFIG_DEBUG_INFO_DWARF4 is not set +# CONFIG_DEBUG_INFO_DWARF5 is not set CONFIG_FRAME_WARN=1024 # CONFIG_STRIP_ASM_SYMS is not set # CONFIG_READABLE_ASM is not set # CONFIG_HEADERS_INSTALL is not set # CONFIG_DEBUG_SECTION_MISMATCH is not set CONFIG_SECTION_MISMATCH_WARN_ONLY=y +# CONFIG_VMLINUX_MAP is not set # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # end of Compile-time checks and compiler options @@ -7439,28 +8563,40 @@ CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 CONFIG_MAGIC_SYSRQ_SERIAL=y CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="m" CONFIG_DEBUG_FS=y +CONFIG_DEBUG_FS_ALLOW_ALL=y +# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set +# CONFIG_DEBUG_FS_ALLOW_NONE is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set +CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y # CONFIG_UBSAN is not set +CONFIG_HAVE_KCSAN_COMPILER=y # end of Generic Kernel Debugging Instruments -CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_MISC=y +# +# Networking Debugging +# +# CONFIG_NET_DEV_REFCNT_TRACKER is not set +# CONFIG_NET_NS_REFCNT_TRACKER is not set +# CONFIG_DEBUG_NET is not set +# end of Networking Debugging # # Memory Debugging # CONFIG_PAGE_EXTENSION=y # CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set # CONFIG_PAGE_OWNER is not set # CONFIG_PAGE_POISONING is not set # CONFIG_DEBUG_PAGE_REF is not set # CONFIG_DEBUG_RODATA_TEST is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_WX is not set CONFIG_HAVE_DEBUG_KMEMLEAK=y # CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SHRINKER_DEBUG is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_SCHED_STACK_END_CHECK is not set # CONFIG_DEBUG_VM is not set @@ -7468,9 +8604,15 @@ CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y # CONFIG_DEBUG_VIRTUAL is not set # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_DEBUG_KMAP_LOCAL is not set # CONFIG_DEBUG_HIGHMEM is not set +CONFIG_HAVE_ARCH_KASAN=y +CONFIG_HAVE_ARCH_KASAN_VMALLOC=y CONFIG_CC_HAS_KASAN_GENERIC=y -CONFIG_KASAN_STACK=1 +CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y +# CONFIG_KASAN is not set +CONFIG_HAVE_ARCH_KFENCE=y +# CONFIG_KFENCE is not set # end of Memory Debugging # CONFIG_DEBUG_SHIRQ is not set @@ -7482,8 +8624,11 @@ CONFIG_KASAN_STACK=1 CONFIG_PANIC_ON_OOPS_VALUE=0 CONFIG_PANIC_TIMEOUT=0 # CONFIG_SOFTLOCKUP_DETECTOR is not set +CONFIG_HAVE_HARDLOCKUP_DETECTOR_BUDDY=y +# CONFIG_HARDLOCKUP_DETECTOR is not set # CONFIG_DETECT_HUNG_TASK is not set # CONFIG_WQ_WATCHDOG is not set +# CONFIG_WQ_CPU_INTENSIVE_REPORT is not set CONFIG_TEST_LOCKUP=m # end of Debug Oops, Lockups and Hangs @@ -7512,8 +8657,10 @@ CONFIG_LOCK_DEBUGGING_SUPPORT=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_LOCK_TORTURE_TEST is not set # CONFIG_WW_MUTEX_SELFTEST is not set +# CONFIG_SCF_TORTURE_TEST is not set # end of Lock Debugging (spinlocks, mutexes, etc...) +# CONFIG_DEBUG_IRQFLAGS is not set CONFIG_STACKTRACE=y # CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set # CONFIG_DEBUG_KOBJECT is not set @@ -7525,25 +8672,26 @@ CONFIG_STACKTRACE=y # CONFIG_DEBUG_PLIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_BUG_ON_DATA_CORRUPTION is not set +# CONFIG_DEBUG_MAPLE_TREE is not set # end of Debug kernel data structures -# CONFIG_DEBUG_CREDENTIALS is not set - # # RCU Debugging # -# CONFIG_RCU_PERF_TEST is not set +# CONFIG_RCU_SCALE_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_REF_SCALE_TEST is not set CONFIG_RCU_CPU_STALL_TIMEOUT=21 +CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0 +# CONFIG_RCU_CPU_STALL_CPUTIME is not set CONFIG_RCU_TRACE=y # CONFIG_RCU_EQS_DEBUG is not set # end of RCU Debugging # CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set # CONFIG_LATENCYTOP is not set +# CONFIG_DEBUG_CGROUP_REF is not set CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y @@ -7552,6 +8700,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_BUILDTIME_MCOUNT_SORT=y CONFIG_TRACE_CLOCK=y CONFIG_RING_BUFFER=y CONFIG_EVENT_TRACING=y @@ -7562,10 +8711,11 @@ CONFIG_FTRACE=y # CONFIG_BOOTTIME_TRACING is not set # CONFIG_FUNCTION_TRACER is not set # CONFIG_STACK_TRACER is not set -# CONFIG_PREEMPTIRQ_EVENTS is not set # CONFIG_IRQSOFF_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_HWLAT_TRACER is not set +# CONFIG_OSNOISE_TRACER is not set +# CONFIG_TIMERLAT_TRACER is not set # CONFIG_ENABLE_DEFAULT_TRACERS is not set # CONFIG_FTRACE_SYSCALLS is not set # CONFIG_TRACER_SNAPSHOT is not set @@ -7573,28 +8723,34 @@ CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set # CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_KPROBE_EVENTS=y CONFIG_UPROBE_EVENTS=y CONFIG_BPF_EVENTS=y CONFIG_DYNAMIC_EVENTS=y CONFIG_PROBE_EVENTS=y +# CONFIG_SYNTH_EVENTS is not set +# CONFIG_USER_EVENTS is not set +# CONFIG_HIST_TRIGGERS is not set # CONFIG_TRACE_EVENT_INJECT is not set # CONFIG_TRACEPOINT_BENCHMARK is not set # CONFIG_RING_BUFFER_BENCHMARK is not set # CONFIG_TRACE_EVAL_MAP_FILE is not set # CONFIG_RING_BUFFER_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS is not set # CONFIG_PREEMPTIRQ_DELAY_TEST is not set +# CONFIG_KPROBE_EVENT_GEN_TEST is not set +# CONFIG_RV is not set # CONFIG_SAMPLES is not set -CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y # CONFIG_STRICT_DEVMEM is not set # # arm Debugging # # CONFIG_ARM_PTDUMP_DEBUGFS is not set -# CONFIG_DEBUG_WX is not set # CONFIG_UNWINDER_FRAME_POINTER is not set CONFIG_UNWINDER_ARM=y CONFIG_ARM_UNWIND=y +# CONFIG_BACKTRACE_VERBOSE is not set # CONFIG_DEBUG_USER is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_MT6589_UART0 is not set @@ -7604,16 +8760,16 @@ CONFIG_DEBUG_LL=y # CONFIG_DEBUG_SEMIHOSTING is not set CONFIG_DEBUG_LL_UART_8250=y # CONFIG_DEBUG_LL_UART_PL01X is not set +# CONFIG_DEBUG_UART_FLOW_CONTROL is not set CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" CONFIG_DEBUG_UART_PHYS=0x11004000 CONFIG_DEBUG_UART_VIRT=0xf1004000 CONFIG_DEBUG_UART_8250_SHIFT=2 # CONFIG_DEBUG_UART_8250_WORD is not set # CONFIG_DEBUG_UART_8250_PALMCHIP is not set -# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set -# CONFIG_DEBUG_UNCOMPRESS is not set CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" CONFIG_EARLY_PRINTK=y +# CONFIG_ARM_KPROBES_TEST is not set # CONFIG_PID_IN_CONTEXTIDR is not set # CONFIG_CORESIGHT is not set # end of arm Debugging @@ -7623,16 +8779,18 @@ CONFIG_EARLY_PRINTK=y # # CONFIG_KUNIT is not set # CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FUNCTION_ERROR_INJECTION is not set # CONFIG_FAULT_INJECTION is not set CONFIG_ARCH_HAS_KCOV=y CONFIG_CC_HAS_SANCOV_TRACE_PC=y # CONFIG_KCOV is not set CONFIG_RUNTIME_TESTING_MENU=y +# CONFIG_TEST_DHRY is not set # CONFIG_LKDTM is not set -# CONFIG_TEST_LIST_SORT is not set CONFIG_TEST_MIN_HEAP=m -# CONFIG_TEST_SORT is not set +# CONFIG_TEST_DIV64 is not set # CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_TEST_REF_TRACKER is not set # CONFIG_RBTREE_TEST is not set CONFIG_REED_SOLOMON_TEST=m # CONFIG_INTERVAL_TREE_TEST is not set @@ -7640,19 +8798,19 @@ CONFIG_REED_SOLOMON_TEST=m # CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_ASYNC_RAID6_TEST is not set # CONFIG_TEST_HEXDUMP is not set +# CONFIG_STRING_SELFTEST is not set # CONFIG_TEST_STRING_HELPERS is not set -CONFIG_TEST_STRSCPY=m # CONFIG_TEST_KSTRTOX is not set # CONFIG_TEST_PRINTF is not set +# CONFIG_TEST_SCANF is not set # CONFIG_TEST_BITMAP is not set -# CONFIG_TEST_BITFIELD is not set # CONFIG_TEST_UUID is not set CONFIG_TEST_XARRAY=m -# CONFIG_TEST_OVERFLOW is not set +# CONFIG_TEST_MAPLE_TREE is not set # CONFIG_TEST_RHASHTABLE is not set -# CONFIG_TEST_HASH is not set # CONFIG_TEST_IDA is not set # CONFIG_TEST_LKM is not set +# CONFIG_TEST_BITOPS is not set CONFIG_TEST_VMALLOC=m # CONFIG_TEST_USER_COPY is not set # CONFIG_TEST_BPF is not set @@ -7664,17 +8822,14 @@ CONFIG_TEST_BLACKHOLE_DEV=m # CONFIG_TEST_STATIC_KEYS is not set # CONFIG_TEST_KMOD is not set CONFIG_TEST_MEMCAT_P=m -CONFIG_TEST_STACKINIT=m CONFIG_TEST_MEMINIT=m +# CONFIG_TEST_FREE_PAGES is not set +CONFIG_ARCH_USE_MEMTEST=y # CONFIG_MEMTEST is not set # end of Kernel Testing and Coverage -# end of Kernel hacking - -## LinuxIO - iSCSI Target modules -CONFIG_TARGET_CORE=m -CONFIG_ISCSI_TARGET=m -CONFIG_TCM_IBLOCK=m -CONFIG_TCM_FILEIO=m -CONFIG_TCM_PSCSI=m -CONFIG_TCM_USER2=m +# +# Rust hacking +# +# end of Rust hacking +# end of Kernel hacking diff --git a/config/kernel/linux-mt7623-legacy.config b/config/kernel/linux-mt7623-legacy.config deleted file mode 100644 index f454aacbe7f0..000000000000 --- a/config/kernel/linux-mt7623-legacy.config +++ /dev/null @@ -1,6831 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# Linux/arm 4.19.315 Kernel Configuration -# - -# -# Compiler: arm-linux-gnueabihf-gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0 -# -CONFIG_CC_IS_GCC=y -CONFIG_GCC_VERSION=110400 -CONFIG_CLANG_VERSION=0 -CONFIG_CC_HAS_ASM_GOTO=y -CONFIG_IRQ_WORK=y -CONFIG_BUILDTIME_EXTABLE_SORT=y - -# -# General setup -# -CONFIG_INIT_ENV_ARG_LIMIT=32 -# CONFIG_COMPILE_TEST is not set -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_BUILD_SALT="" -CONFIG_HAVE_KERNEL_GZIP=y -CONFIG_HAVE_KERNEL_LZMA=y -CONFIG_HAVE_KERNEL_XZ=y -CONFIG_HAVE_KERNEL_LZO=y -CONFIG_HAVE_KERNEL_LZ4=y -CONFIG_KERNEL_GZIP=y -# CONFIG_KERNEL_LZMA is not set -# CONFIG_KERNEL_XZ is not set -# CONFIG_KERNEL_LZO is not set -# CONFIG_KERNEL_LZ4 is not set -CONFIG_DEFAULT_HOSTNAME="(none)" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -CONFIG_POSIX_MQUEUE_SYSCTL=y -CONFIG_CROSS_MEMORY_ATTACH=y -# CONFIG_USELIB is not set -# CONFIG_AUDIT is not set -CONFIG_HAVE_ARCH_AUDITSYSCALL=y - -# -# IRQ subsystem -# -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_MIGRATION=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_SPARSE_IRQ=y -# CONFIG_GENERIC_IRQ_DEBUGFS is not set -CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -CONFIG_ARCH_CLOCKSOURCE_DATA=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_ARCH_HAS_TICK_BROADCAST=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y - -# -# Timers subsystem -# -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ_COMMON=y -# CONFIG_HZ_PERIODIC is not set -CONFIG_NO_HZ_IDLE=y -# CONFIG_NO_HZ_FULL is not set -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set - -# -# CPU/Task time and stats accounting -# -CONFIG_TICK_CPU_ACCOUNTING=y -# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set -# CONFIG_IRQ_TIME_ACCOUNTING is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -CONFIG_CPU_ISOLATION=y - -# -# RCU Subsystem -# -CONFIG_TREE_RCU=y -# CONFIG_RCU_EXPERT is not set -CONFIG_SRCU=y -CONFIG_TREE_SRCU=y -CONFIG_RCU_STALL_COMMON=y -CONFIG_RCU_NEED_SEGCBLIST=y -CONFIG_BUILD_BIN2C=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=17 -CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 -CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_CGROUPS=y -CONFIG_PAGE_COUNTER=y -CONFIG_MEMCG=y -CONFIG_MEMCG_SWAP=y -CONFIG_MEMCG_SWAP_ENABLED=y -CONFIG_MEMCG_KMEM=y -CONFIG_BLK_CGROUP=y -# CONFIG_DEBUG_BLK_CGROUP is not set -CONFIG_CGROUP_WRITEBACK=y -CONFIG_CGROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_CFS_BANDWIDTH=y -CONFIG_RT_GROUP_SCHED=y -CONFIG_CGROUP_PIDS=y -CONFIG_CGROUP_RDMA=y -CONFIG_CGROUP_FREEZER=y -CONFIG_CPUSETS=y -CONFIG_PROC_PID_CPUSET=y -CONFIG_CGROUP_DEVICE=y -CONFIG_CGROUP_CPUACCT=y -CONFIG_CGROUP_PERF=y -CONFIG_CGROUP_BPF=y -# CONFIG_CGROUP_DEBUG is not set -CONFIG_SOCK_CGROUP_DATA=y -CONFIG_NAMESPACES=y -CONFIG_UTS_NS=y -CONFIG_IPC_NS=y -CONFIG_USER_NS=y -CONFIG_PID_NS=y -CONFIG_NET_NS=y -# CONFIG_CHECKPOINT_RESTORE is not set -# CONFIG_SCHED_AUTOGROUP is not set -# CONFIG_SYSFS_DEPRECATED is not set -# CONFIG_RELAY is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_RD_GZIP=y -CONFIG_RD_BZIP2=y -CONFIG_RD_LZMA=y -CONFIG_RD_XZ=y -CONFIG_RD_LZO=y -CONFIG_RD_LZ4=y -CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y -CONFIG_HAVE_UID16=y -CONFIG_BPF=y -CONFIG_EXPERT=y -CONFIG_UID16=y -CONFIG_MULTIUSER=y -# CONFIG_SGETMASK_SYSCALL is not set -CONFIG_SYSFS_SYSCALL=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_FHANDLE=y -CONFIG_POSIX_TIMERS=y -CONFIG_PRINTK=y -CONFIG_PRINTK_NMI=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_FUTEX_PI=y -CONFIG_HAVE_FUTEX_CMPXCHG=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y -CONFIG_ADVISE_SYSCALLS=y -CONFIG_MEMBARRIER=y -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y -CONFIG_KALLSYMS_BASE_RELATIVE=y -CONFIG_BPF_SYSCALL=y -# CONFIG_BPF_JIT_ALWAYS_ON is not set -# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set -# CONFIG_USERFAULTFD is not set -CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y -CONFIG_RSEQ=y -# CONFIG_DEBUG_RSEQ is not set -CONFIG_EMBEDDED=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_PERF_USE_VMALLOC=y -# CONFIG_PC104 is not set - -# -# Kernel Performance Events And Counters -# -CONFIG_PERF_EVENTS=y -# CONFIG_DEBUG_PERF_USE_VMALLOC is not set -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLUB_DEBUG=y -# CONFIG_SLUB_MEMCG_SYSFS_ON is not set -CONFIG_COMPAT_BRK=y -# CONFIG_SLAB is not set -CONFIG_SLUB=y -# CONFIG_SLOB is not set -CONFIG_SLAB_MERGE_DEFAULT=y -# CONFIG_SLAB_FREELIST_RANDOM is not set -# CONFIG_SLAB_FREELIST_HARDENED is not set -CONFIG_SLUB_CPU_PARTIAL=y -CONFIG_SYSTEM_DATA_VERIFICATION=y -# CONFIG_PROFILING is not set -CONFIG_TRACEPOINTS=y -CONFIG_ARM=y -CONFIG_ARM_HAS_SG_CHAIN=y -CONFIG_ARM_DMA_USE_IOMMU=y -CONFIG_ARM_DMA_IOMMU_ALIGNMENT=8 -CONFIG_MIGHT_HAVE_PCI=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_HAVE_PROC_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_ARCH_SUPPORTS_UPROBES=y -CONFIG_ARM_PATCH_PHYS_VIRT=y -CONFIG_GENERIC_BUG=y -CONFIG_PGTABLE_LEVELS=2 - -# -# System Type -# -CONFIG_MMU=y -CONFIG_ARCH_MMAP_RND_BITS_MIN=8 -CONFIG_ARCH_MMAP_RND_BITS_MAX=16 -CONFIG_ARCH_MULTIPLATFORM=y -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_IOP13XX is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_DOVE is not set -# CONFIG_ARCH_KS8695 is not set -# CONFIG_ARCH_W90X900 is not set -# CONFIG_ARCH_LPC32XX is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C24XX is not set -# CONFIG_ARCH_DAVINCI is not set -# CONFIG_ARCH_OMAP1 is not set - -# -# Multiple platform selection -# - -# -# CPU Core family selection -# -# CONFIG_ARCH_MULTI_V6 is not set -CONFIG_ARCH_MULTI_V7=y -CONFIG_ARCH_MULTI_V6_V7=y -# CONFIG_ARCH_VIRT is not set -# CONFIG_ARCH_ACTIONS is not set -# CONFIG_ARCH_ALPINE is not set -# CONFIG_ARCH_ARTPEC is not set -# CONFIG_ARCH_AT91 is not set -# CONFIG_ARCH_BCM is not set -# CONFIG_ARCH_BERLIN is not set -# CONFIG_ARCH_DIGICOLOR is not set -# CONFIG_ARCH_EXYNOS is not set -# CONFIG_ARCH_HIGHBANK is not set -# CONFIG_ARCH_HISI is not set -# CONFIG_ARCH_MXC is not set -# CONFIG_ARCH_KEYSTONE is not set -CONFIG_ARCH_MEDIATEK=y -CONFIG_MACH_MT2701=y -CONFIG_MACH_MT6589=y -CONFIG_MACH_MT6592=y -CONFIG_MACH_MT7623=y -CONFIG_MACH_MT8127=y -CONFIG_MACH_MT8135=y -# CONFIG_ARCH_MESON is not set -# CONFIG_ARCH_MMP is not set -# CONFIG_ARCH_MVEBU is not set -# CONFIG_ARCH_NPCM is not set - -# -# TI OMAP/AM/DM/DRA Family -# -# CONFIG_ARCH_OMAP3 is not set -# CONFIG_ARCH_OMAP4 is not set -# CONFIG_SOC_OMAP5 is not set -# CONFIG_SOC_AM33XX is not set -# CONFIG_SOC_AM43XX is not set -# CONFIG_SOC_DRA7XX is not set -# CONFIG_ARCH_SIRF is not set -# CONFIG_ARCH_QCOM is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_ROCKCHIP is not set -# CONFIG_ARCH_S5PV210 is not set -# CONFIG_ARCH_RENESAS is not set -# CONFIG_ARCH_SOCFPGA is not set -# CONFIG_PLAT_SPEAR is not set -# CONFIG_ARCH_STI is not set -# CONFIG_ARCH_STM32 is not set -# CONFIG_ARCH_SUNXI is not set -# CONFIG_ARCH_TANGO is not set -# CONFIG_ARCH_TEGRA is not set -# CONFIG_ARCH_UNIPHIER is not set -# CONFIG_ARCH_U8500 is not set -# CONFIG_ARCH_VEXPRESS is not set -# CONFIG_ARCH_WM8850 is not set -# CONFIG_ARCH_ZX is not set -# CONFIG_ARCH_ZYNQ is not set - -# -# Processor Type -# -CONFIG_CPU_V7=y -CONFIG_CPU_THUMB_CAPABLE=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_HAS_ASID=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y - -# -# Processor Features -# -# CONFIG_ARM_LPAE is not set -CONFIG_ARM_THUMB=y -CONFIG_ARM_THUMBEE=y -CONFIG_ARM_VIRT_EXT=y -CONFIG_SWP_EMULATE=y -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_CPU_SPECTRE=y -CONFIG_HARDEN_BRANCH_PREDICTOR=y -CONFIG_HARDEN_BRANCH_HISTORY=y -CONFIG_KUSER_HELPERS=y -CONFIG_VDSO=y -CONFIG_OUTER_CACHE=y -CONFIG_OUTER_CACHE_SYNC=y -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -CONFIG_CACHE_L2X0=y -# CONFIG_CACHE_L2X0_PMU is not set -CONFIG_PL310_ERRATA_588369=y -CONFIG_PL310_ERRATA_727915=y -CONFIG_PL310_ERRATA_753970=y -CONFIG_PL310_ERRATA_769419=y -CONFIG_ARM_L1_CACHE_SHIFT_6=y -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_DMA_MEM_BUFFERABLE=y -CONFIG_ARM_HEAVY_MB=y -CONFIG_DEBUG_ALIGN_RODATA=y -CONFIG_ARM_ERRATA_430973=y -CONFIG_ARM_ERRATA_643719=y -CONFIG_ARM_ERRATA_720789=y -CONFIG_ARM_ERRATA_754322=y -CONFIG_ARM_ERRATA_754327=y -CONFIG_ARM_ERRATA_764369=y -CONFIG_ARM_ERRATA_775420=y -CONFIG_ARM_ERRATA_798181=y -# CONFIG_ARM_ERRATA_773022 is not set -# CONFIG_ARM_ERRATA_818325_852422 is not set -# CONFIG_ARM_ERRATA_821420 is not set -# CONFIG_ARM_ERRATA_825619 is not set -# CONFIG_ARM_ERRATA_852421 is not set -# CONFIG_ARM_ERRATA_852423 is not set - -# -# Bus support -# -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_DOMAINS_GENERIC=y -CONFIG_PCI_SYSCALL=y -CONFIG_PCIEPORTBUS=y -CONFIG_PCIEAER=y -# CONFIG_PCIEAER_INJECT is not set -# CONFIG_PCIE_ECRC is not set -CONFIG_PCIEASPM=y -# CONFIG_PCIEASPM_DEBUG is not set -CONFIG_PCIEASPM_DEFAULT=y -# CONFIG_PCIEASPM_POWERSAVE is not set -# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set -# CONFIG_PCIEASPM_PERFORMANCE is not set -CONFIG_PCIE_PME=y -# CONFIG_PCIE_DPC is not set -# CONFIG_PCIE_PTM is not set -CONFIG_PCI_MSI=y -CONFIG_PCI_MSI_IRQ_DOMAIN=y -CONFIG_PCI_QUIRKS=y -# CONFIG_PCI_DEBUG is not set -# CONFIG_PCI_STUB is not set -CONFIG_PCI_ECAM=y -# CONFIG_PCI_IOV is not set -# CONFIG_PCI_PRI is not set -# CONFIG_PCI_PASID is not set -CONFIG_PCI_LABEL=y -# CONFIG_HOTPLUG_PCI is not set - -# -# PCI controller drivers -# - -# -# Cadence PCIe controllers support -# -# CONFIG_PCIE_CADENCE_HOST is not set -# CONFIG_PCIE_CADENCE_EP is not set -# CONFIG_PCI_FTPCI100 is not set -CONFIG_PCI_HOST_COMMON=y -CONFIG_PCI_HOST_GENERIC=y -# CONFIG_PCIE_XILINX is not set -# CONFIG_PCI_V3_SEMI is not set -# CONFIG_PCIE_ALTERA is not set -CONFIG_PCIE_MEDIATEK=y - -# -# DesignWare PCI Core Support -# -# CONFIG_PCIE_DW_PLAT_HOST is not set -# CONFIG_PCIE_DW_PLAT_EP is not set -# CONFIG_PCI_LAYERSCAPE is not set - -# -# PCI Endpoint -# -CONFIG_PCI_ENDPOINT=y -CONFIG_PCI_ENDPOINT_CONFIGFS=y -CONFIG_PCI_EPF_TEST=m - -# -# PCI switch controller drivers -# -# CONFIG_PCI_SW_SWITCHTEC is not set -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -CONFIG_HAVE_SMP=y -CONFIG_SMP=y -CONFIG_SMP_ON_UP=y -CONFIG_ARM_CPU_TOPOLOGY=y -# CONFIG_SCHED_MC is not set -# CONFIG_SCHED_SMT is not set -CONFIG_HAVE_ARM_ARCH_TIMER=y -CONFIG_MCPM=y -# CONFIG_BIG_LITTLE is not set -CONFIG_VMSPLIT_3G=y -# CONFIG_VMSPLIT_3G_OPT is not set -# CONFIG_VMSPLIT_2G is not set -# CONFIG_VMSPLIT_1G is not set -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_NR_CPUS=16 -CONFIG_HOTPLUG_CPU=y -CONFIG_ARM_PSCI=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_HZ_FIXED=0 -# CONFIG_HZ_100 is not set -# CONFIG_HZ_200 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_500 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_SCHED_HRTICK=y -# CONFIG_THUMB2_KERNEL is not set -CONFIG_ARM_PATCH_IDIV=y -CONFIG_AEABI=y -# CONFIG_OABI_COMPAT is not set -CONFIG_HAVE_ARCH_PFN_VALID=y -CONFIG_HIGHMEM=y -CONFIG_HIGHPTE=y -CONFIG_CPU_SW_DOMAIN_PAN=y -CONFIG_HW_PERF_EVENTS=y -CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -# CONFIG_ARM_MODULE_PLTS is not set -CONFIG_FORCE_MAX_ZONEORDER=12 -CONFIG_ALIGNMENT_TRAP=y -# CONFIG_UACCESS_WITH_MEMCPY is not set -CONFIG_SECCOMP=y -# CONFIG_PARAVIRT is not set -# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -# CONFIG_XEN is not set - -# -# Boot options -# -CONFIG_USE_OF=y -CONFIG_ATAGS=y -# CONFIG_DEPRECATED_PARAM_STRUCT is not set -CONFIG_ZBOOT_ROM_TEXT=0 -CONFIG_ZBOOT_ROM_BSS=0 -# CONFIG_ARM_APPENDED_DTB is not set -CONFIG_CMDLINE="" -CONFIG_KEXEC=y -CONFIG_ATAGS_PROC=y -# CONFIG_CRASH_DUMP is not set -CONFIG_AUTO_ZRELADDR=y -CONFIG_EFI_STUB=y -CONFIG_EFI=y -CONFIG_DMI=y - -# -# CPU Power Management -# - -# -# CPU Frequency scaling -# -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_STAT=y -# 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=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set -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_CPU_FREQ_GOV_SCHEDUTIL=y - -# -# CPU frequency scaling drivers -# -CONFIG_CPUFREQ_DT=y -CONFIG_CPUFREQ_DT_PLATDEV=y -# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set -CONFIG_ARM_MEDIATEK_CPUFREQ=y -# CONFIG_QORIQ_CPUFREQ is not set - -# -# CPU Idle -# -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_DT_IDLE_STATES=y - -# -# ARM CPU Idle Drivers -# -CONFIG_ARM_CPUIDLE=y -# CONFIG_ARM_HIGHBANK_CPUIDLE is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_VFP=y -CONFIG_VFPv3=y -CONFIG_NEON=y -CONFIG_KERNEL_MODE_NEON=y - -# -# Power management options -# -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -# CONFIG_SUSPEND_SKIP_SYNC is not set -# CONFIG_HIBERNATION is not set -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -CONFIG_PM_AUTOSLEEP=y -# CONFIG_PM_WAKELOCKS is not set -CONFIG_PM=y -# CONFIG_PM_DEBUG is not set -# CONFIG_APM_EMULATION is not set -CONFIG_PM_CLK=y -CONFIG_PM_GENERIC_DOMAINS=y -# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -CONFIG_PM_GENERIC_DOMAINS_SLEEP=y -CONFIG_PM_GENERIC_DOMAINS_OF=y -CONFIG_CPU_PM=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y - -# -# Firmware Drivers -# -CONFIG_ARM_PSCI_FW=y -# CONFIG_ARM_PSCI_CHECKER is not set -# CONFIG_ARM_SCMI_PROTOCOL is not set -# CONFIG_ARM_SCPI_PROTOCOL is not set -# CONFIG_FIRMWARE_MEMMAP is not set -CONFIG_DMIID=y -# CONFIG_DMI_SYSFS is not set -CONFIG_FW_CFG_SYSFS=m -# CONFIG_FW_CFG_SYSFS_CMDLINE is not set -CONFIG_HAVE_ARM_SMCCC=y -# CONFIG_GOOGLE_FIRMWARE is not set - -# -# EFI (Extensible Firmware Interface) Support -# -CONFIG_EFI_VARS=m -CONFIG_EFI_ESRT=y -CONFIG_EFI_VARS_PSTORE=m -# CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE is not set -CONFIG_EFI_PARAMS_FROM_FDT=y -CONFIG_EFI_RUNTIME_WRAPPERS=y -CONFIG_EFI_ARMSTUB=y -# CONFIG_EFI_ARMSTUB_DTB_LOADER is not set -# CONFIG_EFI_BOOTLOADER_CONTROL is not set -CONFIG_EFI_CAPSULE_LOADER=m -# CONFIG_EFI_TEST is not set -# CONFIG_RESET_ATTACK_MITIGATION is not set - -# -# Tegra firmware driver -# -CONFIG_ARM_CRYPTO=y -CONFIG_CRYPTO_SHA1_ARM=m -CONFIG_CRYPTO_SHA1_ARM_NEON=m -CONFIG_CRYPTO_SHA1_ARM_CE=m -CONFIG_CRYPTO_SHA2_ARM_CE=m -CONFIG_CRYPTO_SHA256_ARM=m -CONFIG_CRYPTO_SHA512_ARM=m -CONFIG_CRYPTO_AES_ARM=m -CONFIG_CRYPTO_AES_ARM_BS=m -CONFIG_CRYPTO_AES_ARM_CE=m -CONFIG_CRYPTO_GHASH_ARM_CE=m -CONFIG_CRYPTO_CRCT10DIF_ARM_CE=m -CONFIG_CRYPTO_CRC32_ARM_CE=m -CONFIG_CRYPTO_CHACHA20_NEON=m -# CONFIG_VIRTUALIZATION is not set - -# -# General architecture-dependent options -# -CONFIG_CRASH_CORE=y -CONFIG_KEXEC_CORE=y -CONFIG_HAVE_OPROFILE=y -CONFIG_KPROBES=y -# CONFIG_JUMP_LABEL is not set -CONFIG_OPTPROBES=y -CONFIG_UPROBES=y -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_ARCH_USE_BUILTIN_BSWAP=y -CONFIG_KRETPROBES=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_OPTPROBES=y -CONFIG_HAVE_NMI=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_ARCH_HAS_FORTIFY_SOURCE=y -CONFIG_ARCH_HAS_SET_MEMORY=y -CONFIG_ARCH_HAS_CPU_FINALIZE_INIT=y -CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_RSEQ=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_HW_BREAKPOINT=y -CONFIG_HAVE_PERF_REGS=y -CONFIG_HAVE_PERF_USER_STACK_DUMP=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -CONFIG_SECCOMP_FILTER=y -CONFIG_HAVE_STACKPROTECTOR=y -CONFIG_CC_HAS_STACKPROTECTOR_NONE=y -CONFIG_STACKPROTECTOR=y -CONFIG_STACKPROTECTOR_STRONG=y -CONFIG_HAVE_CONTEXT_TRACKING=y -CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -CONFIG_HAVE_EXIT_THREAD=y -CONFIG_ARCH_MMAP_RND_BITS=8 -CONFIG_CLONE_BACKWARDS=y -CONFIG_OLD_SIGSUSPEND3=y -CONFIG_OLD_SIGACTION=y -CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y -CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y -CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y -CONFIG_STRICT_KERNEL_RWX=y -CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y -CONFIG_STRICT_MODULE_RWX=y -CONFIG_ARCH_HAS_PHYS_TO_DMA=y -CONFIG_REFCOUNT_FULL=y - -# -# GCOV-based kernel profiling -# -# CONFIG_GCOV_KERNEL is not set -CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -CONFIG_PLUGIN_HOSTCC="" -CONFIG_HAVE_GCC_PLUGINS=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -CONFIG_MODULE_FORCE_LOAD=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_MODULE_SIG is not set -# CONFIG_MODULE_COMPRESS is not set -# CONFIG_TRIM_UNUSED_KSYMS is not set -CONFIG_MODULES_TREE_LOOKUP=y -CONFIG_BLOCK=y -CONFIG_LBDAF=y -CONFIG_BLK_SCSI_REQUEST=y -CONFIG_BLK_DEV_BSG=y -CONFIG_BLK_DEV_BSGLIB=y -CONFIG_BLK_DEV_INTEGRITY=y -# CONFIG_BLK_DEV_ZONED is not set -CONFIG_BLK_DEV_THROTTLING=y -# CONFIG_BLK_DEV_THROTTLING_LOW is not set -CONFIG_BLK_CMDLINE_PARSER=y -# CONFIG_BLK_WBT is not set -# CONFIG_BLK_CGROUP_IOLATENCY is not set -CONFIG_BLK_DEBUG_FS=y -# CONFIG_BLK_SED_OPAL is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_AIX_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=y -# CONFIG_SYSV68_PARTITION is not set -CONFIG_CMDLINE_PARTITION=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_MQ_VIRTIO=y - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_CFQ_GROUP_IOSCHED=y -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_MQ_IOSCHED_DEADLINE=y -CONFIG_MQ_IOSCHED_KYBER=y -CONFIG_IOSCHED_BFQ=y -CONFIG_BFQ_GROUP_IOSCHED=y -CONFIG_ASN1=y -CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -CONFIG_INLINE_READ_UNLOCK=y -CONFIG_INLINE_READ_UNLOCK_IRQ=y -CONFIG_INLINE_WRITE_UNLOCK=y -CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_FREEZER=y - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_ELF_FDPIC is not set -CONFIG_ELFCORE=y -CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -CONFIG_BINFMT_SCRIPT=y -# CONFIG_BINFMT_FLAT is not set -CONFIG_BINFMT_MISC=m -CONFIG_COREDUMP=y - -# -# Memory Management options -# -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_NO_BOOTMEM=y -CONFIG_MEMORY_ISOLATION=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_COMPACTION=y -CONFIG_MIGRATION=y -CONFIG_BOUNCE=y -CONFIG_KSM=y -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -CONFIG_CLEANCACHE=y -CONFIG_FRONTSWAP=y -CONFIG_CMA=y -# CONFIG_CMA_DEBUG is not set -# CONFIG_CMA_DEBUGFS is not set -CONFIG_CMA_AREAS=7 -CONFIG_ZSWAP=y -CONFIG_ZPOOL=y -CONFIG_ZBUD=y -CONFIG_Z3FOLD=y -CONFIG_ZSMALLOC=y -# CONFIG_PGTABLE_MAPPING is not set -# CONFIG_ZSMALLOC_STAT is not set -CONFIG_GENERIC_EARLY_IOREMAP=y -# CONFIG_IDLE_PAGE_TRACKING is not set -CONFIG_FRAME_VECTOR=y -# CONFIG_PERCPU_STATS is not set -# CONFIG_GUP_BENCHMARK is not set -CONFIG_NET=y -CONFIG_NET_INGRESS=y -CONFIG_NET_EGRESS=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_DIAG=m -CONFIG_UNIX=y -CONFIG_UNIX_SCM=y -CONFIG_UNIX_DIAG=m -# CONFIG_TLS is not set -CONFIG_XFRM=y -CONFIG_XFRM_OFFLOAD=y -CONFIG_XFRM_ALGO=y -CONFIG_XFRM_USER=y -CONFIG_XFRM_INTERFACE=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=y -# CONFIG_NET_KEY_MIGRATE is not set -# CONFIG_XDP_SOCKETS is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_FIB_TRIE_STATS=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_ROUTE_CLASSID=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE_DEMUX=m -CONFIG_NET_IP_TUNNEL=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE_COMMON=y -CONFIG_IP_MROUTE=y -CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_SYN_COOKIES=y -# CONFIG_NET_IPVTI is not set -CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_ESP_OFFLOAD=m -CONFIG_INET_IPCOMP=m -CONFIG_INET_TABLE_PERTURB_ORDER=16 -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=m -CONFIG_INET_DIAG=m -CONFIG_INET_TCP_DIAG=m -CONFIG_INET_UDP_DIAG=m -# CONFIG_INET_RAW_DIAG is not set -# CONFIG_INET_DIAG_DESTROY is not set -CONFIG_TCP_CONG_ADVANCED=y -CONFIG_TCP_CONG_BIC=y -CONFIG_TCP_CONG_CUBIC=y -CONFIG_TCP_CONG_WESTWOOD=y -CONFIG_TCP_CONG_HTCP=y -CONFIG_TCP_CONG_HSTCP=y -CONFIG_TCP_CONG_HYBLA=y -CONFIG_TCP_CONG_VEGAS=y -CONFIG_TCP_CONG_NV=y -CONFIG_TCP_CONG_SCALABLE=y -CONFIG_TCP_CONG_LP=y -CONFIG_TCP_CONG_VENO=y -CONFIG_TCP_CONG_YEAH=y -CONFIG_TCP_CONG_ILLINOIS=y -# CONFIG_TCP_CONG_DCTCP is not set -# CONFIG_TCP_CONG_CDG is not set -CONFIG_TCP_CONG_BBR=m -# CONFIG_DEFAULT_BIC is not set -CONFIG_DEFAULT_CUBIC=y -# CONFIG_DEFAULT_HTCP is not set -# CONFIG_DEFAULT_HYBLA is not set -# CONFIG_DEFAULT_VEGAS is not set -# CONFIG_DEFAULT_VENO is not set -# CONFIG_DEFAULT_WESTWOOD is not set -# CONFIG_DEFAULT_RENO is not set -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_TCP_MD5SIG=y -CONFIG_IPV6=y -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y -CONFIG_IPV6_OPTIMISTIC_DAD=y -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_ESP_OFFLOAD=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_MIP6=m -CONFIG_IPV6_ILA=m -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=m -CONFIG_IPV6_VTI=m -CONFIG_IPV6_SIT=m -CONFIG_IPV6_SIT_6RD=y -CONFIG_IPV6_NDISC_NODETYPE=y -CONFIG_IPV6_TUNNEL=m -CONFIG_IPV6_GRE=m -CONFIG_IPV6_MULTIPLE_TABLES=y -CONFIG_IPV6_SUBTREES=y -CONFIG_IPV6_MROUTE=y -CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y -CONFIG_IPV6_PIMSM_V2=y -CONFIG_IPV6_SEG6_LWTUNNEL=y -CONFIG_IPV6_SEG6_HMAC=y -CONFIG_IPV6_SEG6_BPF=y -CONFIG_NETWORK_SECMARK=y -CONFIG_NET_PTP_CLASSIFY=y -CONFIG_NETWORK_PHY_TIMESTAMPING=y -CONFIG_NETFILTER=y -CONFIG_NETFILTER_ADVANCED=y -CONFIG_BRIDGE_NETFILTER=m - -# -# Core Netfilter Configuration -# -CONFIG_NETFILTER_INGRESS=y -CONFIG_NETFILTER_NETLINK=m -CONFIG_NETFILTER_FAMILY_BRIDGE=y -CONFIG_NETFILTER_FAMILY_ARP=y -CONFIG_NETFILTER_NETLINK_ACCT=m -CONFIG_NETFILTER_NETLINK_QUEUE=m -CONFIG_NETFILTER_NETLINK_LOG=m -CONFIG_NETFILTER_NETLINK_OSF=m -CONFIG_NF_CONNTRACK=m -CONFIG_NF_LOG_COMMON=m -CONFIG_NF_LOG_NETDEV=m -CONFIG_NETFILTER_CONNCOUNT=m -CONFIG_NF_CONNTRACK_MARK=y -CONFIG_NF_CONNTRACK_SECMARK=y -CONFIG_NF_CONNTRACK_ZONES=y -CONFIG_NF_CONNTRACK_PROCFS=y -CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CONNTRACK_TIMEOUT=y -CONFIG_NF_CONNTRACK_TIMESTAMP=y -CONFIG_NF_CONNTRACK_LABELS=y -CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_GRE=m -CONFIG_NF_CT_PROTO_SCTP=y -CONFIG_NF_CT_PROTO_UDPLITE=y -CONFIG_NF_CONNTRACK_AMANDA=m -CONFIG_NF_CONNTRACK_FTP=m -CONFIG_NF_CONNTRACK_H323=m -CONFIG_NF_CONNTRACK_IRC=m -CONFIG_NF_CONNTRACK_BROADCAST=m -CONFIG_NF_CONNTRACK_NETBIOS_NS=m -CONFIG_NF_CONNTRACK_SNMP=m -CONFIG_NF_CONNTRACK_PPTP=m -CONFIG_NF_CONNTRACK_SANE=m -CONFIG_NF_CONNTRACK_SIP=m -CONFIG_NF_CONNTRACK_TFTP=m -CONFIG_NF_CT_NETLINK=m -CONFIG_NF_CT_NETLINK_TIMEOUT=m -CONFIG_NF_CT_NETLINK_HELPER=m -CONFIG_NETFILTER_NETLINK_GLUE_CT=y -CONFIG_NF_NAT=m -CONFIG_NF_NAT_NEEDED=y -CONFIG_NF_NAT_PROTO_DCCP=y -CONFIG_NF_NAT_PROTO_UDPLITE=y -CONFIG_NF_NAT_PROTO_SCTP=y -CONFIG_NF_NAT_AMANDA=m -CONFIG_NF_NAT_FTP=m -CONFIG_NF_NAT_IRC=m -CONFIG_NF_NAT_SIP=m -CONFIG_NF_NAT_TFTP=m -CONFIG_NF_NAT_REDIRECT=y -CONFIG_NETFILTER_SYNPROXY=m -CONFIG_NF_TABLES=m -CONFIG_NF_TABLES_SET=m -CONFIG_NF_TABLES_INET=y -CONFIG_NF_TABLES_NETDEV=y -CONFIG_NFT_NUMGEN=m -CONFIG_NFT_CT=m -CONFIG_NFT_FLOW_OFFLOAD=m -CONFIG_NFT_COUNTER=m -CONFIG_NFT_CONNLIMIT=m -CONFIG_NFT_LOG=m -CONFIG_NFT_LIMIT=m -CONFIG_NFT_MASQ=m -CONFIG_NFT_REDIR=m -CONFIG_NFT_NAT=m -CONFIG_NFT_TUNNEL=m -CONFIG_NFT_OBJREF=m -CONFIG_NFT_QUEUE=m -CONFIG_NFT_QUOTA=m -CONFIG_NFT_REJECT=m -CONFIG_NFT_REJECT_INET=m -CONFIG_NFT_COMPAT=m -CONFIG_NFT_HASH=m -CONFIG_NFT_FIB=m -CONFIG_NFT_FIB_INET=m -CONFIG_NFT_SOCKET=m -CONFIG_NFT_OSF=m -CONFIG_NFT_TPROXY=m -CONFIG_NF_DUP_NETDEV=m -CONFIG_NFT_DUP_NETDEV=m -CONFIG_NFT_FWD_NETDEV=m -CONFIG_NFT_FIB_NETDEV=m -CONFIG_NF_FLOW_TABLE_INET=m -CONFIG_NF_FLOW_TABLE=m -CONFIG_NETFILTER_XTABLES=m - -# -# Xtables combined modules -# -CONFIG_NETFILTER_XT_MARK=m -CONFIG_NETFILTER_XT_CONNMARK=m -CONFIG_NETFILTER_XT_SET=m - -# -# Xtables targets -# -CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m -CONFIG_NETFILTER_XT_TARGET_CT=m -CONFIG_NETFILTER_XT_TARGET_DSCP=m -CONFIG_NETFILTER_XT_TARGET_HL=m -CONFIG_NETFILTER_XT_TARGET_HMARK=m -CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m -CONFIG_NETFILTER_XT_TARGET_LED=m -CONFIG_NETFILTER_XT_TARGET_LOG=m -CONFIG_NETFILTER_XT_TARGET_MARK=m -CONFIG_NETFILTER_XT_NAT=m -CONFIG_NETFILTER_XT_TARGET_NETMAP=m -CONFIG_NETFILTER_XT_TARGET_NFLOG=m -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_NOTRACK=m -CONFIG_NETFILTER_XT_TARGET_RATEEST=m -CONFIG_NETFILTER_XT_TARGET_REDIRECT=m -CONFIG_NETFILTER_XT_TARGET_TEE=m -CONFIG_NETFILTER_XT_TARGET_TPROXY=m -CONFIG_NETFILTER_XT_TARGET_TRACE=m -CONFIG_NETFILTER_XT_TARGET_SECMARK=m -CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m - -# -# Xtables matches -# -CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m -CONFIG_NETFILTER_XT_MATCH_BPF=m -CONFIG_NETFILTER_XT_MATCH_CGROUP=m -CONFIG_NETFILTER_XT_MATCH_CLUSTER=m -CONFIG_NETFILTER_XT_MATCH_COMMENT=m -CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m -CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -CONFIG_NETFILTER_XT_MATCH_CPU=m -CONFIG_NETFILTER_XT_MATCH_DCCP=m -CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m -CONFIG_NETFILTER_XT_MATCH_DSCP=m -CONFIG_NETFILTER_XT_MATCH_ECN=m -CONFIG_NETFILTER_XT_MATCH_ESP=m -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -CONFIG_NETFILTER_XT_MATCH_HELPER=m -CONFIG_NETFILTER_XT_MATCH_HL=m -CONFIG_NETFILTER_XT_MATCH_IPCOMP=m -CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -CONFIG_NETFILTER_XT_MATCH_IPVS=m -CONFIG_NETFILTER_XT_MATCH_L2TP=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_NFACCT=m -CONFIG_NETFILTER_XT_MATCH_OSF=m -CONFIG_NETFILTER_XT_MATCH_OWNER=m -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=m -CONFIG_NETFILTER_XT_MATCH_REALM=m -CONFIG_NETFILTER_XT_MATCH_RECENT=m -CONFIG_NETFILTER_XT_MATCH_SCTP=m -CONFIG_NETFILTER_XT_MATCH_SOCKET=m -CONFIG_NETFILTER_XT_MATCH_STATE=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_SET=m -CONFIG_IP_SET_MAX=256 -CONFIG_IP_SET_BITMAP_IP=m -CONFIG_IP_SET_BITMAP_IPMAC=m -CONFIG_IP_SET_BITMAP_PORT=m -CONFIG_IP_SET_HASH_IP=m -CONFIG_IP_SET_HASH_IPMARK=m -CONFIG_IP_SET_HASH_IPPORT=m -CONFIG_IP_SET_HASH_IPPORTIP=m -CONFIG_IP_SET_HASH_IPPORTNET=m -CONFIG_IP_SET_HASH_IPMAC=m -CONFIG_IP_SET_HASH_MAC=m -CONFIG_IP_SET_HASH_NETPORTNET=m -CONFIG_IP_SET_HASH_NET=m -CONFIG_IP_SET_HASH_NETNET=m -CONFIG_IP_SET_HASH_NETPORT=m -CONFIG_IP_SET_HASH_NETIFACE=m -CONFIG_IP_SET_LIST_SET=m -CONFIG_IP_VS=m -CONFIG_IP_VS_IPV6=y -CONFIG_IP_VS_DEBUG=y -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 -CONFIG_IP_VS_PROTO_SCTP=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_FO=m -CONFIG_IP_VS_OVF=m -CONFIG_IP_VS_LBLC=m -CONFIG_IP_VS_LBLCR=m -CONFIG_IP_VS_DH=m -CONFIG_IP_VS_SH=m -CONFIG_IP_VS_MH=m -CONFIG_IP_VS_SED=m -CONFIG_IP_VS_NQ=m - -# -# IPVS SH scheduler -# -CONFIG_IP_VS_SH_TAB_BITS=8 - -# -# IPVS MH scheduler -# -CONFIG_IP_VS_MH_TAB_INDEX=12 - -# -# IPVS application helper -# -CONFIG_IP_VS_FTP=m -CONFIG_IP_VS_NFCT=y -CONFIG_IP_VS_PE_SIP=m - -# -# IP: Netfilter Configuration -# -CONFIG_NF_DEFRAG_IPV4=m -CONFIG_NF_SOCKET_IPV4=m -CONFIG_NF_TPROXY_IPV4=m -CONFIG_NF_TABLES_IPV4=y -CONFIG_NFT_CHAIN_ROUTE_IPV4=m -CONFIG_NFT_REJECT_IPV4=m -CONFIG_NFT_DUP_IPV4=m -CONFIG_NFT_FIB_IPV4=m -CONFIG_NF_TABLES_ARP=y -CONFIG_NF_FLOW_TABLE_IPV4=m -CONFIG_NF_DUP_IPV4=m -CONFIG_NF_LOG_ARP=m -CONFIG_NF_LOG_IPV4=m -CONFIG_NF_REJECT_IPV4=m -CONFIG_NF_NAT_IPV4=m -CONFIG_NF_NAT_MASQUERADE_IPV4=y -CONFIG_NFT_CHAIN_NAT_IPV4=m -CONFIG_NFT_MASQ_IPV4=m -CONFIG_NFT_REDIR_IPV4=m -CONFIG_NF_NAT_SNMP_BASIC=m -CONFIG_NF_NAT_PROTO_GRE=m -CONFIG_NF_NAT_PPTP=m -CONFIG_NF_NAT_H323=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_AH=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_RPFILTER=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_SYNPROXY=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_CLUSTERIP=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 - -# -# IPv6: Netfilter Configuration -# -CONFIG_NF_SOCKET_IPV6=m -CONFIG_NF_TPROXY_IPV6=m -CONFIG_NF_TABLES_IPV6=y -CONFIG_NFT_CHAIN_ROUTE_IPV6=m -CONFIG_NFT_CHAIN_NAT_IPV6=m -CONFIG_NFT_MASQ_IPV6=m -CONFIG_NFT_REDIR_IPV6=m -CONFIG_NFT_REJECT_IPV6=m -CONFIG_NFT_DUP_IPV6=m -CONFIG_NFT_FIB_IPV6=m -CONFIG_NF_FLOW_TABLE_IPV6=m -CONFIG_NF_DUP_IPV6=m -CONFIG_NF_REJECT_IPV6=m -CONFIG_NF_LOG_IPV6=m -CONFIG_NF_NAT_IPV6=m -CONFIG_NF_NAT_MASQUERADE_IPV6=y -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=m -CONFIG_IP6_NF_MATCH_RPFILTER=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_MATCH_SRH=m -CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_REJECT=m -CONFIG_IP6_NF_TARGET_SYNPROXY=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_RAW=m -CONFIG_IP6_NF_NAT=m -CONFIG_IP6_NF_TARGET_MASQUERADE=m -CONFIG_IP6_NF_TARGET_NPT=m -CONFIG_NF_DEFRAG_IPV6=m -CONFIG_NF_TABLES_BRIDGE=y -CONFIG_NFT_BRIDGE_REJECT=m -CONFIG_NF_LOG_BRIDGE=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=m -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_NFLOG=m -# CONFIG_BPFILTER is not set -CONFIG_IP_DCCP=m -CONFIG_INET_DCCP_DIAG=m - -# -# DCCP CCIDs Configuration -# -# CONFIG_IP_DCCP_CCID2_DEBUG is not set -CONFIG_IP_DCCP_CCID3=y -# CONFIG_IP_DCCP_CCID3_DEBUG is not set -CONFIG_IP_DCCP_TFRC_LIB=y - -# -# DCCP Kernel Hacking -# -# CONFIG_IP_DCCP_DEBUG is not set -CONFIG_IP_SCTP=m -CONFIG_SCTP_DBG_OBJCNT=y -CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y -# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set -# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set -CONFIG_SCTP_COOKIE_HMAC_MD5=y -CONFIG_SCTP_COOKIE_HMAC_SHA1=y -CONFIG_INET_SCTP_DIAG=m -CONFIG_RDS=m -CONFIG_RDS_TCP=m -# CONFIG_RDS_DEBUG is not set -CONFIG_TIPC=m -CONFIG_TIPC_MEDIA_UDP=y -CONFIG_TIPC_DIAG=m -CONFIG_ATM=m -CONFIG_ATM_CLIP=m -CONFIG_ATM_CLIP_NO_ICMP=y -# CONFIG_ATM_LANE is not set -CONFIG_ATM_BR2684=m -CONFIG_ATM_BR2684_IPFILTER=y -CONFIG_L2TP=m -# CONFIG_L2TP_DEBUGFS is not set -CONFIG_L2TP_V3=y -CONFIG_L2TP_IP=m -CONFIG_L2TP_ETH=m -CONFIG_STP=y -CONFIG_GARP=y -CONFIG_MRP=y -CONFIG_BRIDGE=y -CONFIG_BRIDGE_IGMP_SNOOPING=y -CONFIG_BRIDGE_VLAN_FILTERING=y -CONFIG_HAVE_NET_DSA=y -CONFIG_NET_DSA=m -CONFIG_NET_DSA_LEGACY=y -CONFIG_NET_DSA_TAG_MTK=y -CONFIG_VLAN_8021Q=y -CONFIG_VLAN_8021Q_GVRP=y -CONFIG_VLAN_8021Q_MVRP=y -CONFIG_LLC=y -# CONFIG_LLC2 is not set -CONFIG_ATALK=m -CONFIG_DEV_APPLETALK=m -CONFIG_IPDDP=m -CONFIG_IPDDP_ENCAP=y -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_PHONET is not set -CONFIG_6LOWPAN=m -# CONFIG_6LOWPAN_DEBUGFS is not set -CONFIG_6LOWPAN_NHC=m -CONFIG_6LOWPAN_NHC_DEST=m -CONFIG_6LOWPAN_NHC_FRAGMENT=m -CONFIG_6LOWPAN_NHC_HOP=m -CONFIG_6LOWPAN_NHC_IPV6=m -CONFIG_6LOWPAN_NHC_MOBILITY=m -CONFIG_6LOWPAN_NHC_ROUTING=m -CONFIG_6LOWPAN_NHC_UDP=m -# CONFIG_6LOWPAN_GHC_EXT_HDR_HOP is not set -# CONFIG_6LOWPAN_GHC_UDP is not set -# CONFIG_6LOWPAN_GHC_ICMPV6 is not set -# CONFIG_6LOWPAN_GHC_EXT_HDR_DEST is not set -# CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG is not set -# CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE is not set -CONFIG_IEEE802154=m -CONFIG_IEEE802154_NL802154_EXPERIMENTAL=y -CONFIG_IEEE802154_SOCKET=m -CONFIG_IEEE802154_6LOWPAN=m -CONFIG_MAC802154=m -CONFIG_NET_SCHED=y - -# -# Queueing/Scheduling -# -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_MULTIQ=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFB=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_CBS=m -CONFIG_NET_SCH_ETF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_NETEM=m -CONFIG_NET_SCH_DRR=m -CONFIG_NET_SCH_MQPRIO=m -CONFIG_NET_SCH_SKBPRIO=m -CONFIG_NET_SCH_CHOKE=m -CONFIG_NET_SCH_QFQ=m -CONFIG_NET_SCH_CODEL=m -CONFIG_NET_SCH_FQ_CODEL=m -CONFIG_NET_SCH_CAKE=m -CONFIG_NET_SCH_FQ=m -CONFIG_NET_SCH_HHF=m -CONFIG_NET_SCH_PIE=m -CONFIG_NET_SCH_INGRESS=m -CONFIG_NET_SCH_PLUG=m -# CONFIG_NET_SCH_DEFAULT is not set - -# -# Classification -# -CONFIG_NET_CLS=y -CONFIG_NET_CLS_BASIC=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -CONFIG_CLS_U32_PERF=y -CONFIG_CLS_U32_MARK=y -CONFIG_NET_CLS_FLOW=m -CONFIG_NET_CLS_CGROUP=m -CONFIG_NET_CLS_BPF=m -CONFIG_NET_CLS_FLOWER=m -# CONFIG_NET_CLS_MATCHALL 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_EMATCH_CANID=m -# CONFIG_NET_EMATCH_IPSET is not set -CONFIG_NET_EMATCH_IPT=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_SAMPLE is not set -CONFIG_NET_ACT_IPT=m -CONFIG_NET_ACT_NAT=m -CONFIG_NET_ACT_PEDIT=m -CONFIG_NET_ACT_SIMP=m -CONFIG_NET_ACT_SKBEDIT=m -CONFIG_NET_ACT_CSUM=m -CONFIG_NET_ACT_VLAN=m -CONFIG_NET_ACT_BPF=m -CONFIG_NET_ACT_CONNMARK=m -# CONFIG_NET_ACT_SKBMOD is not set -# CONFIG_NET_ACT_IFE is not set -# CONFIG_NET_ACT_TUNNEL_KEY is not set -CONFIG_NET_CLS_IND=y -CONFIG_NET_SCH_FIFO=y -CONFIG_DCB=y -CONFIG_DNS_RESOLVER=y -CONFIG_BATMAN_ADV=m -CONFIG_BATMAN_ADV_BATMAN_V=y -CONFIG_BATMAN_ADV_BLA=y -CONFIG_BATMAN_ADV_DAT=y -CONFIG_BATMAN_ADV_NC=y -CONFIG_BATMAN_ADV_MCAST=y -# CONFIG_BATMAN_ADV_DEBUGFS is not set -CONFIG_OPENVSWITCH=m -CONFIG_OPENVSWITCH_GRE=m -CONFIG_OPENVSWITCH_VXLAN=m -CONFIG_VSOCKETS=m -CONFIG_VSOCKETS_DIAG=m -# CONFIG_VIRTIO_VSOCKETS is not set -CONFIG_NETLINK_DIAG=m -CONFIG_MPLS=y -CONFIG_NET_MPLS_GSO=m -CONFIG_MPLS_ROUTING=m -CONFIG_MPLS_IPTUNNEL=m -CONFIG_NET_NSH=m -CONFIG_HSR=m -CONFIG_NET_SWITCHDEV=y -CONFIG_NET_L3_MASTER_DEV=y -# CONFIG_NET_NCSI is not set -CONFIG_RPS=y -CONFIG_RFS_ACCEL=y -CONFIG_XPS=y -CONFIG_CGROUP_NET_PRIO=y -CONFIG_CGROUP_NET_CLASSID=y -CONFIG_NET_RX_BUSY_POLL=y -CONFIG_BQL=y -CONFIG_BPF_JIT=y -# CONFIG_BPF_STREAM_PARSER is not set -CONFIG_NET_FLOW_LIMIT=y - -# -# 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=y -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_BAYCOM_PAR is not set -# CONFIG_BAYCOM_EPP is not set -CONFIG_YAM=m -CONFIG_CAN=m -CONFIG_CAN_RAW=m -CONFIG_CAN_BCM=m -CONFIG_CAN_GW=m - -# -# CAN Device Drivers -# -CONFIG_CAN_VCAN=m -CONFIG_CAN_VXCAN=m -CONFIG_CAN_SLCAN=m -CONFIG_CAN_DEV=m -CONFIG_CAN_CALC_BITTIMING=y -CONFIG_CAN_FLEXCAN=m -CONFIG_CAN_GRCAN=m -CONFIG_CAN_TI_HECC=m -CONFIG_CAN_C_CAN=m -CONFIG_CAN_C_CAN_PLATFORM=m -CONFIG_CAN_C_CAN_PCI=m -CONFIG_CAN_CC770=m -CONFIG_CAN_CC770_ISA=m -CONFIG_CAN_CC770_PLATFORM=m -# CONFIG_CAN_IFI_CANFD is not set -CONFIG_CAN_M_CAN=m -CONFIG_CAN_PEAK_PCIEFD=m -CONFIG_CAN_RCAR=m -CONFIG_CAN_RCAR_CANFD=m -CONFIG_CAN_SJA1000=m -CONFIG_CAN_SJA1000_ISA=m -CONFIG_CAN_SJA1000_PLATFORM=m -CONFIG_CAN_EMS_PCI=m -CONFIG_CAN_PEAK_PCI=m -CONFIG_CAN_PEAK_PCIEC=y -CONFIG_CAN_KVASER_PCI=m -CONFIG_CAN_PLX_PCI=m -CONFIG_CAN_SOFTING=m - -# -# CAN SPI interfaces -# -CONFIG_CAN_HI311X=m -CONFIG_CAN_MCP251X=m - -# -# CAN USB interfaces -# -CONFIG_CAN_8DEV_USB=m -CONFIG_CAN_EMS_USB=m -CONFIG_CAN_ESD_USB2=m -CONFIG_CAN_GS_USB=m -CONFIG_CAN_KVASER_USB=m -# CONFIG_CAN_MCBA_USB is not set -CONFIG_CAN_PEAK_USB=m -CONFIG_CAN_UCAN=m -# CONFIG_CAN_DEBUG_DEVICES is not set -CONFIG_BT=y -CONFIG_BT_BREDR=y -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 -CONFIG_BT_HS=y -CONFIG_BT_LE=y -CONFIG_BT_6LOWPAN=m -CONFIG_BT_LEDS=y -# CONFIG_BT_SELFTEST is not set -CONFIG_BT_DEBUGFS=y - -# -# Bluetooth device drivers -# -CONFIG_BT_INTEL=m -CONFIG_BT_BCM=m -CONFIG_BT_RTL=m -CONFIG_BT_HCIBTUSB=m -# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set -CONFIG_BT_HCIBTUSB_BCM=y -CONFIG_BT_HCIBTUSB_RTL=y -CONFIG_BT_HCIBTSDIO=m -CONFIG_BT_HCIUART=m -CONFIG_BT_HCIUART_H4=y -CONFIG_BT_HCIUART_BCSP=y -CONFIG_BT_HCIUART_ATH3K=y -CONFIG_BT_HCIUART_INTEL=y -# CONFIG_BT_HCIUART_AG6XX is not set -# CONFIG_BT_HCIUART_MRVL is not set -CONFIG_BT_HCIBCM203X=m -CONFIG_BT_HCIBPA10X=m -CONFIG_BT_HCIBFUSB=m -CONFIG_BT_HCIVHCI=m -CONFIG_BT_MRVL=m -CONFIG_BT_MRVL_SDIO=m -CONFIG_BT_ATH3K=m -CONFIG_BT_HCIRSI=m -CONFIG_AF_RXRPC=m -# CONFIG_AF_RXRPC_IPV6 is not set -# CONFIG_AF_RXRPC_INJECT_LOSS is not set -# CONFIG_AF_RXRPC_DEBUG is not set -# CONFIG_RXKAD is not set -CONFIG_AF_KCM=m -CONFIG_STREAM_PARSER=m -CONFIG_FIB_RULES=y -CONFIG_WIRELESS=y -CONFIG_WIRELESS_EXT=y -CONFIG_WEXT_CORE=y -CONFIG_WEXT_PROC=y -CONFIG_WEXT_SPY=y -CONFIG_WEXT_PRIV=y -CONFIG_CFG80211=y -CONFIG_NL80211_TESTMODE=y -# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -CONFIG_CFG80211_CERTIFICATION_ONUS=y -CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y -CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y -CONFIG_CFG80211_EXTRA_REGDB_KEYDIR="" -CONFIG_CFG80211_REG_CELLULAR_HINTS=y -CONFIG_CFG80211_REG_RELAX_NO_IR=y -# CONFIG_CFG80211_DEFAULT_PS is not set -# CONFIG_CFG80211_DEBUGFS is not set -CONFIG_CFG80211_CRDA_SUPPORT=y -CONFIG_CFG80211_WEXT=y -CONFIG_CFG80211_WEXT_EXPORT=y -CONFIG_LIB80211=m -CONFIG_LIB80211_CRYPT_WEP=m -CONFIG_LIB80211_CRYPT_CCMP=m -CONFIG_LIB80211_CRYPT_TKIP=m -# CONFIG_LIB80211_DEBUG is not set -CONFIG_MAC80211=y -CONFIG_MAC80211_HAS_RC=y -CONFIG_MAC80211_RC_MINSTREL=y -CONFIG_MAC80211_RC_MINSTREL_HT=y -# CONFIG_MAC80211_RC_MINSTREL_VHT is not set -CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y -CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" -CONFIG_MAC80211_MESH=y -CONFIG_MAC80211_LEDS=y -# CONFIG_MAC80211_DEBUGFS is not set -# CONFIG_MAC80211_MESSAGE_TRACING is not set -# CONFIG_MAC80211_DEBUG_MENU is not set -CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -CONFIG_WIMAX=y -CONFIG_WIMAX_DEBUG_LEVEL=8 -CONFIG_RFKILL=y -CONFIG_RFKILL_LEDS=y -CONFIG_RFKILL_INPUT=y -CONFIG_RFKILL_GPIO=y -CONFIG_NET_9P=m -CONFIG_NET_9P_VIRTIO=m -# CONFIG_NET_9P_DEBUG is not set -# CONFIG_CAIF is not set -CONFIG_CEPH_LIB=m -# CONFIG_CEPH_LIB_PRETTYDEBUG is not set -CONFIG_CEPH_LIB_USE_DNS_RESOLVER=y -CONFIG_NFC=m -CONFIG_NFC_DIGITAL=m -CONFIG_NFC_NCI=m -CONFIG_NFC_NCI_SPI=m -CONFIG_NFC_NCI_UART=m -CONFIG_NFC_HCI=m -CONFIG_NFC_SHDLC=y - -# -# Near Field Communication (NFC) devices -# -CONFIG_NFC_TRF7970A=m -CONFIG_NFC_SIM=m -CONFIG_NFC_PORT100=m -CONFIG_NFC_FDP=m -CONFIG_NFC_FDP_I2C=m -CONFIG_NFC_PN544=m -CONFIG_NFC_PN544_I2C=m -# CONFIG_NFC_PN533_USB is not set -# CONFIG_NFC_PN533_I2C is not set -CONFIG_NFC_MICROREAD=m -CONFIG_NFC_MICROREAD_I2C=m -CONFIG_NFC_MRVL=m -CONFIG_NFC_MRVL_USB=m -CONFIG_NFC_MRVL_UART=m -CONFIG_NFC_MRVL_I2C=m -CONFIG_NFC_MRVL_SPI=m -CONFIG_NFC_ST21NFCA=m -CONFIG_NFC_ST21NFCA_I2C=m -CONFIG_NFC_ST_NCI=m -CONFIG_NFC_ST_NCI_I2C=m -CONFIG_NFC_ST_NCI_SPI=m -CONFIG_NFC_NXP_NCI=m -CONFIG_NFC_NXP_NCI_I2C=m -CONFIG_NFC_S3FWRN5=m -CONFIG_NFC_S3FWRN5_I2C=m -# CONFIG_NFC_ST95HF is not set -# CONFIG_PSAMPLE is not set -# CONFIG_NET_IFE is not set -CONFIG_LWTUNNEL=y -CONFIG_LWTUNNEL_BPF=y -CONFIG_DST_CACHE=y -CONFIG_GRO_CELLS=y -# CONFIG_NET_DEVLINK is not set -CONFIG_MAY_USE_DEVLINK=y -CONFIG_FAILOVER=y -CONFIG_HAVE_EBPF_JIT=y - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER=y -CONFIG_UEVENT_HELPER_PATH="" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y - -# -# Firmware loader -# -CONFIG_FW_LOADER=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_FW_LOADER_USER_HELPER is not set -CONFIG_WANT_DEV_COREDUMP=y -CONFIG_ALLOW_DEV_COREDUMP=y -CONFIG_DEV_COREDUMP=y -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set -# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_CPU_VULNERABILITIES=y -CONFIG_SOC_BUS=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_SPI=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGMAP_IRQ=y -CONFIG_DMA_SHARED_BUFFER=y -# CONFIG_DMA_FENCE_TRACE is not set -CONFIG_DMA_CMA=y - -# -# Default contiguous memory area size: -# -CONFIG_CMA_SIZE_MBYTES=64 -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_ALIGNMENT=8 -CONFIG_GENERIC_ARCH_TOPOLOGY=y - -# -# Bus devices -# -# CONFIG_BRCMSTB_GISB_ARB is not set -# CONFIG_SIMPLE_PM_BUS is not set -CONFIG_VEXPRESS_CONFIG=y -CONFIG_CONNECTOR=m -CONFIG_GNSS=m -CONFIG_MTD=y -# CONFIG_MTD_TESTS is not set -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y -# CONFIG_MTD_AFS_PARTS is not set -CONFIG_MTD_OF_PARTS=y -# CONFIG_MTD_AR7_PARTS is not set - -# -# Partition parsers -# - -# -# User Modules And Translation Layers -# -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# 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_SM_FTL is not set -# CONFIG_MTD_OOPS is not set -# CONFIG_MTD_SWAP is not set -# CONFIG_MTD_PARTITIONED_MASTER is not set - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -# CONFIG_MTD_JEDECPROBE 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_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# 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_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_DATAFLASH is not set -CONFIG_MTD_M25P80=y -# CONFIG_MTD_MCHP23K256 is not set -# CONFIG_MTD_SST25L 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_DOCG3 is not set -# CONFIG_MTD_ONENAND is not set -CONFIG_MTD_NAND_ECC=y -# CONFIG_MTD_NAND_ECC_SMC is not set -CONFIG_MTD_NAND=y -# CONFIG_MTD_NAND_ECC_BCH is not set -CONFIG_MTD_NAND_DENALI=y -# CONFIG_MTD_NAND_DENALI_PCI is not set -CONFIG_MTD_NAND_DENALI_DT=y -# CONFIG_MTD_NAND_GPIO is not set -# CONFIG_MTD_NAND_RICOH is not set -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_DOCG4 is not set -# CONFIG_MTD_NAND_CAFE is not set -# CONFIG_MTD_NAND_NANDSIM is not set -CONFIG_MTD_NAND_BRCMNAND=y -# CONFIG_MTD_NAND_PLATFORM is not set -# CONFIG_MTD_NAND_MTK is not set -# CONFIG_MTD_SPI_NAND is not set - -# -# LPDDR & LPDDR2 PCM memory drivers -# -# CONFIG_MTD_LPDDR is not set -# CONFIG_MTD_LPDDR2_NVM is not set -CONFIG_MTD_SPI_NOR=y -# CONFIG_MTD_MT81xx_NOR is not set -CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y -# CONFIG_SPI_CADENCE_QUADSPI is not set -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MTD_UBI_BEB_LIMIT=20 -# CONFIG_MTD_UBI_FASTMAP is not set -# CONFIG_MTD_UBI_GLUEBI is not set -# CONFIG_MTD_UBI_BLOCK is not set -CONFIG_DTC=y -CONFIG_OF=y -# CONFIG_OF_UNITTEST is not set -CONFIG_OF_FLATTREE=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_KOBJ=y -CONFIG_OF_DYNAMIC=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_IRQ=y -CONFIG_OF_NET=y -CONFIG_OF_MDIO=y -CONFIG_OF_RESERVED_MEM=y -CONFIG_OF_RESOLVE=y -CONFIG_OF_OVERLAY=y -CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -CONFIG_PARPORT=m -# CONFIG_PARPORT_PC is not set -CONFIG_PARPORT_AX88796=m -# CONFIG_PARPORT_1284 is not set -CONFIG_PARPORT_NOT_PC=y -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_NULL_BLK is not set -CONFIG_CDROM=y -# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set -CONFIG_ZRAM=m -CONFIG_ZRAM_WRITEBACK=y -# CONFIG_ZRAM_MEMORY_TRACKING is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 -CONFIG_BLK_DEV_CRYPTOLOOP=m -# CONFIG_BLK_DEV_DRBD is not set -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=4 -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_CDROM_PKTCDVD is not set -CONFIG_ATA_OVER_ETH=m -CONFIG_VIRTIO_BLK=m -# CONFIG_VIRTIO_BLK_SCSI is not set -CONFIG_BLK_DEV_RBD=m -# CONFIG_BLK_DEV_RSXX is not set - -# -# NVME Support -# -CONFIG_NVME_CORE=y -CONFIG_BLK_DEV_NVME=y -# CONFIG_NVME_MULTIPATH is not set -# CONFIG_NVME_FC is not set -# CONFIG_NVME_TARGET is not set - -# -# Misc devices -# -CONFIG_AD525X_DPOT=y -CONFIG_AD525X_DPOT_I2C=y -# CONFIG_AD525X_DPOT_SPI is not set -# CONFIG_DUMMY_IRQ is not set -# CONFIG_PHANTOM is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set -CONFIG_ICS932S401=y -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_HP_ILO is not set -CONFIG_APDS9802ALS=y -CONFIG_ISL29003=y -# CONFIG_ISL29020 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_SENSORS_BH1770 is not set -# CONFIG_SENSORS_APDS990X is not set -# CONFIG_HMC6352 is not set -# CONFIG_DS1682 is not set -# CONFIG_USB_SWITCH_FSA9480 is not set -# CONFIG_LATTICE_ECP3_CONFIG is not set -CONFIG_SRAM=y -CONFIG_SRAM_EXEC=y -CONFIG_VEXPRESS_SYSCFG=y -CONFIG_PCI_ENDPOINT_TEST=m -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -CONFIG_EEPROM_AT24=y -# CONFIG_EEPROM_AT25 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_MAX6875 is not set -CONFIG_EEPROM_93CX6=y -# CONFIG_EEPROM_93XX46 is not set -# CONFIG_EEPROM_IDT_89HPESX is not set -# CONFIG_CB710_CORE is not set - -# -# Texas Instruments shared transport line discipline -# -# CONFIG_TI_ST is not set -# CONFIG_SENSORS_LIS3_SPI is not set -# CONFIG_SENSORS_LIS3_I2C is not set -# CONFIG_ALTERA_STAPL is not set - -# -# Intel MIC & related support -# - -# -# Intel MIC Bus Driver -# - -# -# SCIF Bus Driver -# - -# -# VOP Bus Driver -# - -# -# Intel MIC Host Driver -# - -# -# Intel MIC Card Driver -# - -# -# SCIF Driver -# - -# -# Intel MIC Coprocessor State Management (COSM) Drivers -# - -# -# VOP Driver -# -# CONFIG_ECHO is not set -# CONFIG_MISC_RTSX_PCI is not set -# CONFIG_MISC_RTSX_USB is not set - -# -# Mediatek Peripherals -# -CONFIG_MTK_PLATFORM="mt7623" -CONFIG_MTK_BTIF=y - -# -# Modem & Connectivity related configs -# -CONFIG_MTK_COMBO=y -# CONFIG_MTK_COMBO_CHIP_MT6620 is not set -# CONFIG_MTK_COMBO_CHIP_MT6628 is not set -# CONFIG_MTK_COMBO_CHIP_MT6630 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6572 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6582 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_8127 is not set -CONFIG_MTK_COMBO_CHIP_CONSYS_7623=y -# CONFIG_MTK_COMBO_CHIP_CONSYS_6752 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6592 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_8163 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6735 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6755 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6580 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6797 is not set -CONFIG_MTK_COMBO_CHIP="CONSYS_7623" -CONFIG_MTK_COMBO_PLAT_PATH="" -CONFIG_MTK_COMBO_COMM=y -# CONFIG_MTK_COMBO_COMM_UART is not set -# CONFIG_MTK_COMBO_COMM_SDIO is not set -# CONFIG_MTK_COMBO_COMM_NPWR is not set -# CONFIG_MTK_COMBO_COMM_APO is not set -# CONFIG_MTK_COMBO_BT is not set -# CONFIG_MTK_COMBO_BT_HCI is not set -CONFIG_MTK_COMBO_WIFI=y -# CONFIG_MTK_WAPI_SUPPORT is not set -# CONFIG_MTK_PASSPOINT_R1_SUPPORT is not set -# CONFIG_MTK_PASSPOINT_R2_SUPPORT is not set -# CONFIG_MTK_WIFI_MCC_SUPPORT is not set -# CONFIG_MTK_DHCPV6C_WIFI is not set -# CONFIG_MTK_CONN_LTE_IDC_SUPPORT is not set -# CONFIG_GPS is not set -# CONFIG_MTK_GPS_SUPPORT is not set -CONFIG_HAVE_IDE=y -CONFIG_IDE=y - -# -# Please see Documentation/ide/ide.txt for help/info on IDE drives -# -# 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 is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_IDE_TASK_IOCTL is not set -CONFIG_IDE_PROC_FS=y - -# -# IDE chipset support/bugfixes -# -# CONFIG_BLK_DEV_PLATFORM is not set - -# -# PCI IDE chipsets support -# -# CONFIG_BLK_DEV_GENERIC is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_JMICRON 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_SL82C105 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 - -# -# SCSI device support -# -CONFIG_SCSI_MOD=y -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -CONFIG_SCSI_MQ_DEFAULT=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=y -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set - -# -# SCSI Transports -# -CONFIG_SCSI_SPI_ATTRS=m -# CONFIG_SCSI_FC_ATTRS is not set -CONFIG_SCSI_ISCSI_ATTRS=m -CONFIG_SCSI_SAS_ATTRS=m -CONFIG_SCSI_SAS_LIBSAS=m -CONFIG_SCSI_SAS_ATA=y -CONFIG_SCSI_SAS_HOST_SMP=y -# CONFIG_SCSI_SRP_ATTRS is not set -CONFIG_SCSI_LOWLEVEL=y -CONFIG_ISCSI_TCP=m -CONFIG_ISCSI_BOOT_SYSFS=m -# CONFIG_SCSI_CXGB3_ISCSI is not set -# CONFIG_SCSI_CXGB4_ISCSI is not set -# CONFIG_SCSI_BNX2_ISCSI is not set -# CONFIG_BE2ISCSI is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_HPSA is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_3W_SAS is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -CONFIG_SCSI_MVSAS=m -# CONFIG_SCSI_MVSAS_DEBUG is not set -CONFIG_SCSI_MVSAS_TASKLET=y -CONFIG_SCSI_MVUMI=m -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_SCSI_ESAS2R is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_MPT3SAS is not set -# CONFIG_SCSI_MPT2SAS is not set -# CONFIG_SCSI_SMARTPQI is not set -# CONFIG_SCSI_UFSHCD is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_SNIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_WD719X is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_PMCRAID is not set -# CONFIG_SCSI_PM8001 is not set -CONFIG_SCSI_VIRTIO=m -# CONFIG_SCSI_DH is not set -# CONFIG_SCSI_OSD_INITIATOR is not set -CONFIG_ATA=y -# CONFIG_ATA_VERBOSE_ERROR is not set -CONFIG_SATA_PMP=y - -# -# Controllers with non-SFF native interface -# -CONFIG_SATA_AHCI=y -CONFIG_SATA_MOBILE_LPM_POLICY=0 -CONFIG_SATA_AHCI_PLATFORM=y -# CONFIG_AHCI_CEVA is not set -CONFIG_AHCI_MTK=m -# CONFIG_AHCI_QORIQ is not set -# CONFIG_SATA_INIC162X is not set -# CONFIG_SATA_ACARD_AHCI is not set -# CONFIG_SATA_SIL24 is not set -CONFIG_ATA_SFF=y - -# -# SFF controllers with custom DMA interface -# -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_SX4 is not set -CONFIG_ATA_BMDMA=y - -# -# SATA SFF controllers with BMDMA -# -# CONFIG_ATA_PIIX is not set -# CONFIG_SATA_DWC is not set -# CONFIG_SATA_MV is not set -# CONFIG_SATA_NV is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SIL is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_SVW is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set - -# -# PATA SFF controllers with BMDMA -# -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_ATP867X is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT8213 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_MARVELL is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NINJA32 is not set -# CONFIG_PATA_NS87415 is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RDC is not set -# CONFIG_PATA_SCH is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_TOSHIBA is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set - -# -# PIO-only SFF controllers -# -# CONFIG_PATA_CMD640_PCI is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_PLATFORM is not set -# CONFIG_PATA_RZ1000 is not set - -# -# Generic fallback / legacy drivers -# -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_LEGACY is not set -CONFIG_MD=y -CONFIG_BLK_DEV_MD=m -# CONFIG_MD_LINEAR is not set -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID10=m -CONFIG_MD_RAID456=m -CONFIG_MD_MULTIPATH=m -CONFIG_MD_FAULTY=m -# CONFIG_BCACHE is not set -CONFIG_BLK_DEV_DM_BUILTIN=y -CONFIG_BLK_DEV_DM=m -# CONFIG_DM_MQ_DEFAULT is not set -# CONFIG_DM_DEBUG is not set -CONFIG_DM_BUFIO=m -# CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set -CONFIG_DM_BIO_PRISON=m -CONFIG_DM_PERSISTENT_DATA=m -CONFIG_DM_UNSTRIPED=m -CONFIG_DM_CRYPT=m -CONFIG_DM_SNAPSHOT=m -CONFIG_DM_THIN_PROVISIONING=m -CONFIG_DM_CACHE=m -CONFIG_DM_CACHE_SMQ=m -CONFIG_DM_WRITECACHE=m -CONFIG_DM_ERA=m -CONFIG_DM_MIRROR=m -CONFIG_DM_LOG_USERSPACE=m -CONFIG_DM_RAID=m -CONFIG_DM_ZERO=m -CONFIG_DM_MULTIPATH=m -CONFIG_DM_MULTIPATH_QL=m -CONFIG_DM_MULTIPATH_ST=m -# CONFIG_DM_DELAY is not set -# CONFIG_DM_UEVENT is not set -CONFIG_DM_FLAKEY=m -CONFIG_DM_VERITY=m -# CONFIG_DM_VERITY_FEC is not set -# CONFIG_DM_SWITCH is not set -CONFIG_DM_LOG_WRITES=m -CONFIG_DM_INTEGRITY=m -CONFIG_TARGET_CORE=m -CONFIG_TCM_IBLOCK=m -CONFIG_TCM_FILEIO=m -CONFIG_TCM_PSCSI=m -CONFIG_LOOPBACK_TARGET=m -CONFIG_ISCSI_TARGET=m -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_FIREWIRE is not set -# CONFIG_FIREWIRE_NOSY is not set -CONFIG_NETDEVICES=y -CONFIG_MII=m -CONFIG_NET_CORE=y -CONFIG_BONDING=m -CONFIG_DUMMY=m -# CONFIG_EQUALIZER is not set -# CONFIG_NET_FC is not set -CONFIG_IFB=m -CONFIG_NET_TEAM=m -# CONFIG_NET_TEAM_MODE_BROADCAST is not set -# CONFIG_NET_TEAM_MODE_ROUNDROBIN is not set -# CONFIG_NET_TEAM_MODE_RANDOM is not set -# CONFIG_NET_TEAM_MODE_ACTIVEBACKUP is not set -# CONFIG_NET_TEAM_MODE_LOADBALANCE is not set -CONFIG_MACVLAN=m -CONFIG_MACVTAP=m -CONFIG_IPVLAN=m -CONFIG_IPVTAP=m -CONFIG_VXLAN=m -# CONFIG_GENEVE is not set -# CONFIG_GTP is not set -# CONFIG_MACSEC is not set -# CONFIG_NETCONSOLE is not set -CONFIG_TUN=m -CONFIG_TAP=m -# CONFIG_TUN_VNET_CROSS_LE is not set -CONFIG_VETH=y -CONFIG_VIRTIO_NET=y -# CONFIG_NLMON is not set -CONFIG_NET_VRF=m -# CONFIG_ARCNET is not set -CONFIG_ATM_DRIVERS=y -# CONFIG_ATM_DUMMY is not set -# CONFIG_ATM_TCP is not set -# CONFIG_ATM_LANAI is not set -# CONFIG_ATM_ENI is not set -# CONFIG_ATM_NICSTAR is not set -# CONFIG_ATM_IDT77252 is not set -# CONFIG_ATM_IA is not set -# CONFIG_ATM_FORE200E is not set -# CONFIG_ATM_HE is not set -# CONFIG_ATM_SOLOS is not set - -# -# CAIF transport drivers -# - -# -# Distributed Switch Architecture drivers -# -# CONFIG_B53 is not set -# CONFIG_NET_DSA_BCM_SF2 is not set -# CONFIG_NET_DSA_LOOP is not set -CONFIG_NET_DSA_MT7530=m -# CONFIG_NET_DSA_MV88E6060 is not set -# CONFIG_MICROCHIP_KSZ is not set -# CONFIG_NET_DSA_MV88E6XXX is not set -# CONFIG_NET_DSA_QCA8K is not set -# CONFIG_NET_DSA_REALTEK_SMI is not set -# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set -# CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set -# CONFIG_NET_DSA_VITESSE_VSC73XX is not set -CONFIG_ETHERNET=y -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_VENDOR_ADAPTEC is not set -# CONFIG_NET_VENDOR_AGERE is not set -# CONFIG_NET_VENDOR_ALACRITECH is not set -# CONFIG_NET_VENDOR_ALTEON is not set -# CONFIG_ALTERA_TSE is not set -# CONFIG_NET_VENDOR_AMAZON is not set -# CONFIG_NET_VENDOR_AMD is not set -# CONFIG_NET_VENDOR_AQUANTIA is not set -# CONFIG_NET_VENDOR_ARC is not set -# CONFIG_NET_VENDOR_ATHEROS is not set -# CONFIG_NET_VENDOR_AURORA is not set -# CONFIG_NET_VENDOR_BROADCOM is not set -# CONFIG_NET_VENDOR_BROCADE is not set -CONFIG_NET_VENDOR_CADENCE=y -# CONFIG_MACB is not set -# CONFIG_NET_VENDOR_CAVIUM is not set -# CONFIG_NET_VENDOR_CHELSIO is not set -# CONFIG_NET_VENDOR_CIRRUS is not set -# CONFIG_NET_VENDOR_CISCO is not set -CONFIG_NET_VENDOR_CORTINA=y -CONFIG_GEMINI_ETHERNET=m -# CONFIG_DM9000 is not set -# CONFIG_DNET is not set -# CONFIG_NET_VENDOR_DEC is not set -# CONFIG_NET_VENDOR_DLINK is not set -# CONFIG_NET_VENDOR_EMULEX is not set -# CONFIG_NET_VENDOR_EZCHIP is not set -# CONFIG_NET_VENDOR_FARADAY is not set -# CONFIG_NET_VENDOR_HISILICON is not set -# CONFIG_NET_VENDOR_HP is not set -# CONFIG_NET_VENDOR_HUAWEI is not set -# CONFIG_NET_VENDOR_INTEL is not set -# CONFIG_JME is not set -# CONFIG_NET_VENDOR_MARVELL is not set -CONFIG_NET_VENDOR_MEDIATEK=y -CONFIG_NET_MEDIATEK_SOC=y -# CONFIG_NET_VENDOR_MELLANOX is not set -# CONFIG_NET_VENDOR_MICREL is not set -# CONFIG_NET_VENDOR_MICROCHIP is not set -CONFIG_NET_VENDOR_MICROSEMI=y -CONFIG_MSCC_OCELOT_SWITCH=m -# CONFIG_MSCC_OCELOT_SWITCH_OCELOT is not set -# CONFIG_NET_VENDOR_MYRI is not set -# CONFIG_FEALNX is not set -# CONFIG_NET_VENDOR_NATSEMI is not set -CONFIG_NET_VENDOR_NETERION=y -# CONFIG_S2IO is not set -# CONFIG_VXGE is not set -# CONFIG_NET_VENDOR_NETRONOME is not set -CONFIG_NET_VENDOR_NI=y -# CONFIG_NET_VENDOR_NVIDIA is not set -# CONFIG_NET_VENDOR_OKI is not set -# CONFIG_ETHOC is not set -CONFIG_NET_VENDOR_PACKET_ENGINES=y -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_NET_VENDOR_QLOGIC is not set -# CONFIG_NET_VENDOR_QUALCOMM is not set -# CONFIG_NET_VENDOR_RDC is not set -# CONFIG_NET_VENDOR_REALTEK is not set -# CONFIG_NET_VENDOR_RENESAS is not set -# CONFIG_NET_VENDOR_ROCKER is not set -# CONFIG_NET_VENDOR_SAMSUNG is not set -# CONFIG_NET_VENDOR_SEEQ is not set -# CONFIG_NET_VENDOR_SOLARFLARE is not set -# CONFIG_NET_VENDOR_SILAN is not set -# CONFIG_NET_VENDOR_SIS is not set -# CONFIG_NET_VENDOR_SMSC is not set -CONFIG_NET_VENDOR_SOCIONEXT=y -# CONFIG_NET_VENDOR_STMICRO is not set -# CONFIG_NET_VENDOR_SUN is not set -# CONFIG_NET_VENDOR_SYNOPSYS is not set -# CONFIG_NET_VENDOR_TEHUTI is not set -# CONFIG_NET_VENDOR_TI is not set -# CONFIG_NET_VENDOR_VIA is not set -# CONFIG_NET_VENDOR_WIZNET is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_BCM_UNIMAC=m -# CONFIG_MDIO_BITBANG is not set -# CONFIG_MDIO_BUS_MUX_GPIO is not set -# CONFIG_MDIO_BUS_MUX_MMIOREG is not set -# CONFIG_MDIO_HISI_FEMAC is not set -# CONFIG_MDIO_MSCC_MIIM is not set -CONFIG_PHYLINK=m -CONFIG_PHYLIB=y -CONFIG_SWPHY=y -# CONFIG_LED_TRIGGER_PHY is not set - -# -# MII PHY device drivers -# -# CONFIG_SFP is not set -# CONFIG_AMD_PHY is not set -# CONFIG_AQUANTIA_PHY is not set -CONFIG_AX88796B_PHY=m -# CONFIG_AT803X_PHY is not set -# CONFIG_BCM7XXX_PHY is not set -# CONFIG_BCM87XX_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_CORTINA_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_DP83822_PHY is not set -# CONFIG_DP83TC811_PHY is not set -# CONFIG_DP83848_PHY is not set -# CONFIG_DP83867_PHY is not set -CONFIG_FIXED_PHY=y -CONFIG_ICPLUS_PHY=y -# CONFIG_INTEL_XWAY_PHY is not set -# CONFIG_LSI_ET1011C_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_MARVELL_PHY is not set -# CONFIG_MARVELL_10G_PHY is not set -# CONFIG_MICREL_PHY is not set -CONFIG_MICROCHIP_PHY=m -# CONFIG_MICROCHIP_T1_PHY is not set -# CONFIG_MICROSEMI_PHY is not set -# CONFIG_NATIONAL_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_RENESAS_PHY is not set -# CONFIG_ROCKCHIP_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_STE10XP is not set -# CONFIG_TERANETICS_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_XILINX_GMII2RGMII is not set -CONFIG_MICREL_KS8995MA=m -CONFIG_PLIP=m -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_MPPE=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPPOATM=m -CONFIG_PPPOE=m -CONFIG_PPTP=m -CONFIG_PPPOL2TP=m -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_SLIP=m -CONFIG_SLHC=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLIP_SMART=y -CONFIG_SLIP_MODE_SLIP6=y -CONFIG_USB_NET_DRIVERS=y -CONFIG_USB_CATC=m -CONFIG_USB_KAWETH=m -CONFIG_USB_PEGASUS=m -CONFIG_USB_RTL8150=m -CONFIG_USB_RTL8152=m -CONFIG_USB_LAN78XX=m -CONFIG_USB_USBNET=m -CONFIG_USB_NET_AX8817X=m -CONFIG_USB_NET_AX88179_178A=m -CONFIG_USB_NET_CDCETHER=m -CONFIG_USB_NET_CDC_EEM=m -CONFIG_USB_NET_CDC_NCM=m -CONFIG_USB_NET_HUAWEI_CDC_NCM=m -CONFIG_USB_NET_CDC_MBIM=m -CONFIG_USB_NET_DM9601=m -CONFIG_USB_NET_SR9700=m -CONFIG_USB_NET_SR9800=m -CONFIG_USB_NET_SMSC75XX=m -CONFIG_USB_NET_SMSC95XX=m -CONFIG_USB_NET_GL620A=m -CONFIG_USB_NET_NET1080=m -CONFIG_USB_NET_PLUSB=m -CONFIG_USB_NET_MCS7830=m -CONFIG_USB_NET_RNDIS_HOST=m -CONFIG_USB_NET_CDC_SUBSET_ENABLE=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=y -CONFIG_USB_NET_ZAURUS=m -CONFIG_USB_NET_CX82310_ETH=m -CONFIG_USB_NET_KALMIA=m -CONFIG_USB_NET_QMI_WWAN=m -CONFIG_USB_HSO=m -CONFIG_USB_NET_INT51X1=m -CONFIG_USB_IPHETH=m -CONFIG_USB_SIERRA_NET=m -CONFIG_USB_VL600=m -CONFIG_USB_NET_CH9200=m -CONFIG_WLAN=y -# CONFIG_WIRELESS_WDS is not set -CONFIG_WLAN_VENDOR_ADMTEK=y -CONFIG_ADM8211=m -CONFIG_ATH_COMMON=m -CONFIG_WLAN_VENDOR_ATH=y -# CONFIG_ATH_DEBUG is not set -CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y -# CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING is not set -CONFIG_ATH5K=m -# CONFIG_ATH5K_DEBUG is not set -# CONFIG_ATH5K_TRACER is not set -CONFIG_ATH5K_PCI=y -# CONFIG_ATH5K_TEST_CHANNELS is not set -CONFIG_ATH9K_HW=m -CONFIG_ATH9K_COMMON=m -CONFIG_ATH9K_BTCOEX_SUPPORT=y -CONFIG_ATH9K=m -CONFIG_ATH9K_PCI=y -CONFIG_ATH9K_AHB=y -# CONFIG_ATH9K_DEBUGFS is not set -CONFIG_ATH9K_DFS_CERTIFIED=y -CONFIG_ATH9K_DYNACK=y -CONFIG_ATH9K_WOW=y -CONFIG_ATH9K_RFKILL=y -CONFIG_ATH9K_CHANNEL_CONTEXT=y -CONFIG_ATH9K_PCOEM=y -CONFIG_ATH9K_HTC=m -# CONFIG_ATH9K_HTC_DEBUGFS is not set -# CONFIG_ATH9K_HWRNG is not set -CONFIG_CARL9170=m -CONFIG_CARL9170_LEDS=y -CONFIG_CARL9170_WPC=y -CONFIG_CARL9170_HWRNG=y -CONFIG_ATH6KL=m -CONFIG_ATH6KL_SDIO=m -CONFIG_ATH6KL_USB=m -# CONFIG_ATH6KL_DEBUG is not set -# CONFIG_ATH6KL_TRACING is not set -CONFIG_ATH6KL_REGDOMAIN=y -CONFIG_AR5523=m -CONFIG_WIL6210=m -CONFIG_WIL6210_ISR_COR=y -# CONFIG_WIL6210_TRACING is not set -CONFIG_WIL6210_DEBUGFS=y -CONFIG_ATH10K=m -CONFIG_ATH10K_CE=y -CONFIG_ATH10K_PCI=m -# CONFIG_ATH10K_AHB is not set -CONFIG_ATH10K_SDIO=m -# CONFIG_ATH10K_USB is not set -# CONFIG_ATH10K_DEBUG is not set -# CONFIG_ATH10K_DEBUGFS is not set -# CONFIG_ATH10K_TRACING is not set -CONFIG_ATH10K_DFS_CERTIFIED=y -CONFIG_WCN36XX=m -# CONFIG_WCN36XX_DEBUGFS is not set -CONFIG_WLAN_VENDOR_ATMEL=y -CONFIG_ATMEL=m -CONFIG_PCI_ATMEL=m -CONFIG_AT76C50X_USB=m -CONFIG_WLAN_VENDOR_BROADCOM=y -CONFIG_B43=m -CONFIG_B43_BCMA=y -CONFIG_B43_SSB=y -CONFIG_B43_BUSES_BCMA_AND_SSB=y -# CONFIG_B43_BUSES_BCMA is not set -# CONFIG_B43_BUSES_SSB is not set -CONFIG_B43_PCI_AUTOSELECT=y -CONFIG_B43_PCICORE_AUTOSELECT=y -CONFIG_B43_SDIO=y -CONFIG_B43_BCMA_PIO=y -CONFIG_B43_PIO=y -CONFIG_B43_PHY_G=y -CONFIG_B43_PHY_N=y -CONFIG_B43_PHY_LP=y -CONFIG_B43_PHY_HT=y -CONFIG_B43_LEDS=y -CONFIG_B43_HWRNG=y -# CONFIG_B43_DEBUG is not set -CONFIG_B43LEGACY=m -CONFIG_B43LEGACY_PCI_AUTOSELECT=y -CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y -CONFIG_B43LEGACY_LEDS=y -CONFIG_B43LEGACY_HWRNG=y -# CONFIG_B43LEGACY_DEBUG is not set -CONFIG_B43LEGACY_DMA=y -CONFIG_B43LEGACY_PIO=y -CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y -# CONFIG_B43LEGACY_DMA_MODE is not set -# CONFIG_B43LEGACY_PIO_MODE is not set -CONFIG_BRCMUTIL=m -# CONFIG_BRCMSMAC is not set -CONFIG_BRCMFMAC=m -CONFIG_BRCMFMAC_PROTO_BCDC=y -CONFIG_BRCMFMAC_PROTO_MSGBUF=y -CONFIG_BRCMFMAC_SDIO=y -CONFIG_BRCMFMAC_USB=y -CONFIG_BRCMFMAC_PCIE=y -CONFIG_BRCM_TRACING=y -# CONFIG_BRCMDBG is not set -CONFIG_WLAN_VENDOR_CISCO=y -CONFIG_WLAN_VENDOR_INTEL=y -CONFIG_IPW2100=m -CONFIG_IPW2100_MONITOR=y -# CONFIG_IPW2100_DEBUG is not set -CONFIG_IPW2200=m -CONFIG_IPW2200_MONITOR=y -CONFIG_IPW2200_RADIOTAP=y -CONFIG_IPW2200_PROMISCUOUS=y -CONFIG_IPW2200_QOS=y -# CONFIG_IPW2200_DEBUG is not set -CONFIG_LIBIPW=m -# CONFIG_LIBIPW_DEBUG is not set -CONFIG_IWLEGACY=m -CONFIG_IWL4965=m -CONFIG_IWL3945=m - -# -# iwl3945 / iwl4965 Debugging Options -# -# CONFIG_IWLEGACY_DEBUG is not set -CONFIG_IWLWIFI=m -CONFIG_IWLWIFI_LEDS=y -CONFIG_IWLDVM=m -CONFIG_IWLMVM=m -CONFIG_IWLWIFI_OPMODE_MODULAR=y -CONFIG_IWLWIFI_BCAST_FILTERING=y -# CONFIG_IWLWIFI_PCIE_RTPM is not set - -# -# Debugging Options -# -# CONFIG_IWLWIFI_DEBUG is not set -CONFIG_IWLWIFI_DEVICE_TRACING=y -CONFIG_WLAN_VENDOR_INTERSIL=y -# CONFIG_HOSTAP is not set -# CONFIG_HERMES is not set -# CONFIG_P54_COMMON is not set -# CONFIG_PRISM54 is not set -CONFIG_WLAN_VENDOR_MARVELL=y -CONFIG_LIBERTAS=m -CONFIG_LIBERTAS_USB=m -CONFIG_LIBERTAS_SDIO=m -CONFIG_LIBERTAS_SPI=m -# CONFIG_LIBERTAS_DEBUG is not set -CONFIG_LIBERTAS_MESH=y -CONFIG_LIBERTAS_THINFIRM=m -# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set -CONFIG_LIBERTAS_THINFIRM_USB=m -CONFIG_MWIFIEX=m -CONFIG_MWIFIEX_SDIO=m -CONFIG_MWIFIEX_PCIE=m -CONFIG_MWIFIEX_USB=m -CONFIG_MWL8K=m -CONFIG_WLAN_VENDOR_MEDIATEK=y -CONFIG_MT7601U=m -CONFIG_MT76_CORE=m -CONFIG_MT76_LEDS=y -CONFIG_MT76_USB=m -CONFIG_MT76x2_COMMON=m -CONFIG_MT76x0U=m -CONFIG_MT76x2E=m -CONFIG_MT76x2U=m -CONFIG_WLAN_VENDOR_RALINK=y -CONFIG_RT2X00=m -CONFIG_RT2400PCI=m -CONFIG_RT2500PCI=m -CONFIG_RT61PCI=m -CONFIG_RT2800PCI=m -CONFIG_RT2800PCI_RT33XX=y -CONFIG_RT2800PCI_RT35XX=y -CONFIG_RT2800PCI_RT53XX=y -CONFIG_RT2800PCI_RT3290=y -CONFIG_RT2500USB=m -CONFIG_RT73USB=m -CONFIG_RT2800USB=m -CONFIG_RT2800USB_RT33XX=y -CONFIG_RT2800USB_RT35XX=y -CONFIG_RT2800USB_RT3573=y -CONFIG_RT2800USB_RT53XX=y -CONFIG_RT2800USB_RT55XX=y -CONFIG_RT2800USB_UNKNOWN=y -CONFIG_RT2800_LIB=m -CONFIG_RT2800_LIB_MMIO=m -CONFIG_RT2X00_LIB_MMIO=m -CONFIG_RT2X00_LIB_PCI=m -CONFIG_RT2X00_LIB_USB=m -CONFIG_RT2X00_LIB=m -CONFIG_RT2X00_LIB_FIRMWARE=y -CONFIG_RT2X00_LIB_CRYPTO=y -CONFIG_RT2X00_LIB_LEDS=y -# CONFIG_RT2X00_DEBUG is not set -CONFIG_WLAN_VENDOR_REALTEK=y -CONFIG_RTL8180=m -CONFIG_RTL8187=m -CONFIG_RTL8187_LEDS=y -CONFIG_RTL_CARDS=m -CONFIG_RTL8192CE=m -CONFIG_RTL8192SE=m -CONFIG_RTL8192DE=m -CONFIG_RTL8723AE=m -CONFIG_RTL8723BE=m -CONFIG_RTL8188EE=m -CONFIG_RTL8192EE=m -CONFIG_RTL8821AE=m -CONFIG_RTL8192CU=m -CONFIG_RTLWIFI=m -CONFIG_RTLWIFI_PCI=m -CONFIG_RTLWIFI_USB=m -# CONFIG_RTLWIFI_DEBUG is not set -CONFIG_RTL8192C_COMMON=m -CONFIG_RTL8723_COMMON=m -CONFIG_RTLBTCOEXIST=m -CONFIG_RTL8XXXU=m -# CONFIG_RTL8XXXU_UNTESTED is not set -CONFIG_WLAN_VENDOR_RSI=y -CONFIG_RSI_91X=m -# CONFIG_RSI_DEBUGFS is not set -CONFIG_RSI_SDIO=m -CONFIG_RSI_USB=m -CONFIG_RSI_COEX=y -CONFIG_WLAN_VENDOR_ST=y -CONFIG_CW1200=m -CONFIG_CW1200_WLAN_SDIO=m -CONFIG_CW1200_WLAN_SPI=m -CONFIG_WLAN_VENDOR_TI=y -CONFIG_WL1251=m -CONFIG_WL1251_SPI=m -CONFIG_WL1251_SDIO=m -CONFIG_WL12XX=m -CONFIG_WL18XX=m -CONFIG_WLCORE=m -CONFIG_WLCORE_SPI=m -CONFIG_WLCORE_SDIO=m -CONFIG_WILINK_PLATFORM_DATA=y -CONFIG_WLAN_VENDOR_ZYDAS=y -CONFIG_USB_ZD1201=m -CONFIG_ZD1211RW=m -# CONFIG_ZD1211RW_DEBUG is not set -CONFIG_WLAN_VENDOR_QUANTENNA=y -# CONFIG_QTNFMAC_PEARL_PCIE is not set -CONFIG_MAC80211_HWSIM=m -CONFIG_USB_NET_RNDIS_WLAN=m - -# -# WiMAX Wireless Broadband devices -# -CONFIG_WIMAX_I2400M=m -CONFIG_WIMAX_I2400M_USB=m -CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8 -# CONFIG_WAN is not set -# CONFIG_IEEE802154_DRIVERS is not set -# CONFIG_VMXNET3 is not set -CONFIG_NETDEVSIM=m -CONFIG_NET_FAILOVER=y -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y -CONFIG_INPUT_LEDS=y -CONFIG_INPUT_FF_MEMLESS=m -CONFIG_INPUT_POLLDEV=m -# CONFIG_INPUT_SPARSEKMAP is not set -CONFIG_INPUT_MATRIXKMAP=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=m -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -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_ADC is not set -# CONFIG_KEYBOARD_ADP5588 is not set -# CONFIG_KEYBOARD_ADP5589 is not set -CONFIG_KEYBOARD_ATKBD=m -# CONFIG_KEYBOARD_QT1070 is not set -# CONFIG_KEYBOARD_QT2160 is not set -# CONFIG_KEYBOARD_DLINK_DIR685 is not set -# CONFIG_KEYBOARD_LKKBD is not set -CONFIG_KEYBOARD_GPIO=m -# CONFIG_KEYBOARD_GPIO_POLLED is not set -# CONFIG_KEYBOARD_TCA6416 is not set -# CONFIG_KEYBOARD_TCA8418 is not set -# CONFIG_KEYBOARD_MATRIX is not set -# CONFIG_KEYBOARD_LM8323 is not set -# CONFIG_KEYBOARD_LM8333 is not set -# CONFIG_KEYBOARD_MAX7359 is not set -# CONFIG_KEYBOARD_MCS is not set -# CONFIG_KEYBOARD_MPR121 is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_OPENCORES is not set -CONFIG_KEYBOARD_SAMSUNG=m -# CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_OMAP4 is not set -# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set -# CONFIG_KEYBOARD_TWL4030 is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_CAP11XX is not set -# CONFIG_KEYBOARD_BCM is not set -# CONFIG_KEYBOARD_MTK_PMIC is not set -CONFIG_INPUT_MOUSE=y -# CONFIG_MOUSE_PS2 is not set -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_APPLETOUCH is not set -# CONFIG_MOUSE_BCM5974 is not set -# CONFIG_MOUSE_CYAPA is not set -# CONFIG_MOUSE_ELAN_I2C is not set -# CONFIG_MOUSE_VSXXXAA is not set -CONFIG_MOUSE_GPIO=m -# CONFIG_MOUSE_SYNAPTICS_I2C is not set -CONFIG_MOUSE_SYNAPTICS_USB=m -CONFIG_INPUT_JOYSTICK=y -# CONFIG_JOYSTICK_ANALOG is not set -# CONFIG_JOYSTICK_A3D is not set -# CONFIG_JOYSTICK_ADI is not set -# CONFIG_JOYSTICK_COBRA is not set -# CONFIG_JOYSTICK_GF2K is not set -# CONFIG_JOYSTICK_GRIP is not set -# CONFIG_JOYSTICK_GRIP_MP is not set -# CONFIG_JOYSTICK_GUILLEMOT is not set -# CONFIG_JOYSTICK_INTERACT is not set -# CONFIG_JOYSTICK_SIDEWINDER is not set -# CONFIG_JOYSTICK_TMDC is not set -CONFIG_JOYSTICK_IFORCE=m -# CONFIG_JOYSTICK_IFORCE_USB is not set -# CONFIG_JOYSTICK_IFORCE_232 is not set -# CONFIG_JOYSTICK_WARRIOR is not set -# CONFIG_JOYSTICK_MAGELLAN is not set -# CONFIG_JOYSTICK_SPACEORB is not set -# CONFIG_JOYSTICK_SPACEBALL is not set -# CONFIG_JOYSTICK_STINGER is not set -# CONFIG_JOYSTICK_TWIDJOY is not set -# CONFIG_JOYSTICK_ZHENHUA is not set -CONFIG_JOYSTICK_DB9=m -CONFIG_JOYSTICK_GAMECON=m -CONFIG_JOYSTICK_TURBOGRAFX=m -# CONFIG_JOYSTICK_AS5011 is not set -# CONFIG_JOYSTICK_JOYDUMP is not set -CONFIG_JOYSTICK_XPAD=m -CONFIG_JOYSTICK_XPAD_FF=y -CONFIG_JOYSTICK_XPAD_LEDS=y -CONFIG_JOYSTICK_WALKERA0701=m -# CONFIG_JOYSTICK_PSXPAD_SPI is not set -# CONFIG_JOYSTICK_PXRC is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -CONFIG_INPUT_MISC=y -# CONFIG_INPUT_AD714X is not set -# CONFIG_INPUT_ATMEL_CAPTOUCH is not set -# CONFIG_INPUT_BMA150 is not set -# CONFIG_INPUT_E3X0_BUTTON is not set -# CONFIG_INPUT_MMA8450 is not set -# CONFIG_INPUT_GP2A is not set -# CONFIG_INPUT_GPIO_BEEPER is not set -# CONFIG_INPUT_GPIO_DECODER is not set -# CONFIG_INPUT_ATI_REMOTE2 is not set -# CONFIG_INPUT_KEYSPAN_REMOTE is not set -# CONFIG_INPUT_KXTJ9 is not set -# CONFIG_INPUT_POWERMATE is not set -# CONFIG_INPUT_YEALINK is not set -# CONFIG_INPUT_CM109 is not set -# CONFIG_INPUT_REGULATOR_HAPTIC is not set -# CONFIG_INPUT_TWL4030_PWRBUTTON is not set -# CONFIG_INPUT_TWL4030_VIBRA is not set -# CONFIG_INPUT_UINPUT is not set -# CONFIG_INPUT_PCF8574 is not set -# CONFIG_INPUT_PWM_BEEPER is not set -# CONFIG_INPUT_PWM_VIBRA is not set -# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -CONFIG_INPUT_ADXL34X=m -CONFIG_INPUT_ADXL34X_I2C=m -CONFIG_INPUT_ADXL34X_SPI=m -# CONFIG_INPUT_IMS_PCU is not set -# CONFIG_INPUT_CMA3000 is not set -# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set -# CONFIG_INPUT_DRV260X_HAPTICS is not set -# CONFIG_INPUT_DRV2665_HAPTICS is not set -# CONFIG_INPUT_DRV2667_HAPTICS is not set -# CONFIG_RMI4_CORE is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=m -CONFIG_SERIO_SERPORT=m -CONFIG_SERIO_PARKBD=m -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=m -# CONFIG_SERIO_RAW is not set -# CONFIG_SERIO_ALTERA_PS2 is not set -# CONFIG_SERIO_PS2MULT is not set -# CONFIG_SERIO_ARC_PS2 is not set -# CONFIG_SERIO_APBPS2 is not set -# CONFIG_SERIO_GPIO_PS2 is not set -# CONFIG_USERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_TTY=y -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_VT_CONSOLE_SLEEP=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_NOZOMI is not set -# CONFIG_N_GSM is not set -# CONFIG_TRACE_SINK is not set -CONFIG_LDISC_AUTOLOAD=y -CONFIG_DEVMEM=y -# CONFIG_DEVKMEM is not set - -# -# Serial drivers -# -CONFIG_SERIAL_EARLYCON=y -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y -# CONFIG_SERIAL_8250_FINTEK is not set -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_DMA=y -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_EXAR=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_EXTENDED=y -# CONFIG_SERIAL_8250_MANY_PORTS is not set -# CONFIG_SERIAL_8250_ASPEED_VUART is not set -CONFIG_SERIAL_8250_SHARE_IRQ=y -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_RSA is not set -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_DW=y -CONFIG_SERIAL_8250_EM=y -# CONFIG_SERIAL_8250_RT288X is not set -CONFIG_SERIAL_8250_MT6577=y -# CONFIG_SERIAL_8250_MOXA is not set -CONFIG_SERIAL_OF_PLATFORM=y - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -# CONFIG_SERIAL_MAX3100 is not set -# CONFIG_SERIAL_MAX310X is not set -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_SCCNXP is not set -# CONFIG_SERIAL_SC16IS7XX is not set -CONFIG_SERIAL_BCM63XX=y -CONFIG_SERIAL_BCM63XX_CONSOLE=y -# CONFIG_SERIAL_ALTERA_JTAGUART is not set -# CONFIG_SERIAL_ALTERA_UART is not set -# CONFIG_SERIAL_IFX6X60 is not set -CONFIG_SERIAL_XILINX_PS_UART=y -CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y -# CONFIG_SERIAL_ARC is not set -# CONFIG_SERIAL_RP2 is not set -CONFIG_SERIAL_FSL_LPUART=y -CONFIG_SERIAL_FSL_LPUART_CONSOLE=y -CONFIG_SERIAL_CONEXANT_DIGICOLOR=y -CONFIG_SERIAL_CONEXANT_DIGICOLOR_CONSOLE=y -CONFIG_SERIAL_ST_ASC=y -CONFIG_SERIAL_ST_ASC_CONSOLE=y -# CONFIG_SERIAL_DEV_BUS is not set -# CONFIG_TTY_PRINTK is not set -CONFIG_PRINTER=m -# CONFIG_LP_CONSOLE is not set -CONFIG_PPDEV=m -CONFIG_HVC_DRIVER=y -# CONFIG_HVC_DCC is not set -CONFIG_VIRTIO_CONSOLE=y -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -# CONFIG_HW_RANDOM_TIMERIOMEM is not set -# CONFIG_HW_RANDOM_VIRTIO is not set -CONFIG_HW_RANDOM_MTK=y -# CONFIG_APPLICOM is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -CONFIG_DEVPORT=y -# CONFIG_XILLYBUS is not set -CONFIG_RANDOM_TRUST_BOOTLOADER=y - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MUX=y - -# -# Multiplexer I2C Chip support -# -CONFIG_I2C_ARB_GPIO_CHALLENGE=m -CONFIG_I2C_MUX_GPIO=m -CONFIG_I2C_MUX_GPMUX=m -CONFIG_I2C_MUX_LTC4306=m -CONFIG_I2C_MUX_PCA9541=m -CONFIG_I2C_MUX_PCA954x=m -CONFIG_I2C_MUX_PINCTRL=m -CONFIG_I2C_MUX_REG=m -CONFIG_I2C_DEMUX_PINCTRL=m -# CONFIG_I2C_MUX_MLXCPLD is not set -CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_SMBUS=m -CONFIG_I2C_ALGOBIT=y - -# -# 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=m -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_CBUS_GPIO is not set -# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -# CONFIG_I2C_DESIGNWARE_PCI is not set -# CONFIG_I2C_EMEV2 is not set -CONFIG_I2C_GPIO=m -# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set -CONFIG_I2C_MT65XX=m -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_RK3X is not set -# CONFIG_I2C_SIMTEC is not set -# CONFIG_I2C_XILINX is not set - -# -# External I2C/SMBus adapter drivers -# -# CONFIG_I2C_DIOLAN_U2C is not set -CONFIG_I2C_PARPORT=m -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_ROBOTFUZZ_OSIF is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set - -# -# Other I2C/SMBus bus drivers -# -# CONFIG_I2C_STUB is not set -CONFIG_I2C_SLAVE=y -CONFIG_I2C_SLAVE_EEPROM=y -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -CONFIG_SPI=y -# CONFIG_SPI_DEBUG is not set -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y - -# -# SPI Master Controller Drivers -# -# CONFIG_SPI_ALTERA is not set -# CONFIG_SPI_AXI_SPI_ENGINE is not set -CONFIG_SPI_BITBANG=y -# CONFIG_SPI_BUTTERFLY is not set -# CONFIG_SPI_CADENCE is not set -# CONFIG_SPI_DESIGNWARE is not set -CONFIG_SPI_GPIO=m -# CONFIG_SPI_LM70_LLP is not set -# CONFIG_SPI_FSL_SPI is not set -CONFIG_SPI_MT65XX=m -# CONFIG_SPI_OC_TINY is not set -# CONFIG_SPI_PXA2XX is not set -# CONFIG_SPI_ROCKCHIP is not set -# CONFIG_SPI_SC18IS602 is not set -# CONFIG_SPI_XCOMM is not set -# CONFIG_SPI_XILINX is not set -# CONFIG_SPI_ZYNQMP_GQSPI is not set - -# -# SPI Protocol Masters -# -CONFIG_SPI_SPIDEV=m -# CONFIG_SPI_LOOPBACK_TEST is not set -# CONFIG_SPI_TLE62X0 is not set -# CONFIG_SPI_SLAVE is not set -CONFIG_SPI_DYNAMIC=y -CONFIG_SPMI=y -# CONFIG_HSI is not set -CONFIG_PPS=y -# CONFIG_PPS_DEBUG is not set - -# -# PPS clients support -# -# CONFIG_PPS_CLIENT_KTIMER is not set -CONFIG_PPS_CLIENT_LDISC=m -# CONFIG_PPS_CLIENT_PARPORT is not set -CONFIG_PPS_CLIENT_GPIO=m - -# -# PPS generators support -# - -# -# PTP clock support -# -CONFIG_PTP_1588_CLOCK=y -CONFIG_DP83640_PHY=m -CONFIG_PINCTRL=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_PINMUX=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_PINCONF=y -CONFIG_GENERIC_PINCONF=y -# CONFIG_DEBUG_PINCTRL is not set -# CONFIG_PINCTRL_AMD is not set -# CONFIG_PINCTRL_MCP23S08 is not set -CONFIG_PINCTRL_SINGLE=y -# CONFIG_PINCTRL_SX150X is not set - -# -# MediaTek pinctrl drivers -# -CONFIG_EINT_MTK=y -CONFIG_PINCTRL_MTK=y -CONFIG_PINCTRL_MT2701=y -CONFIG_PINCTRL_MT8135=y -CONFIG_PINCTRL_MT8127=y -CONFIG_PINCTRL_MT6397=y -CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -CONFIG_GPIOLIB=y -CONFIG_GPIOLIB_FASTPATH_LIMIT=512 -CONFIG_OF_GPIO=y -CONFIG_GPIOLIB_IRQCHIP=y -# CONFIG_DEBUG_GPIO is not set -CONFIG_GPIO_SYSFS=y -CONFIG_GPIO_GENERIC=y - -# -# Memory mapped GPIO drivers -# -# CONFIG_GPIO_74XX_MMIO is not set -# CONFIG_GPIO_ALTERA is not set -# CONFIG_GPIO_DWAPB is not set -# CONFIG_GPIO_EXAR is not set -# CONFIG_GPIO_FTGPIO010 is not set -CONFIG_GPIO_GENERIC_PLATFORM=y -# CONFIG_GPIO_GRGPIO is not set -# CONFIG_GPIO_HLWD is not set -# CONFIG_GPIO_MB86S7X is not set -# CONFIG_GPIO_MOCKUP is not set -# CONFIG_GPIO_MPC8XXX is not set -# CONFIG_GPIO_SYSCON is not set -# CONFIG_GPIO_XILINX is not set -# CONFIG_GPIO_ZEVIO is not set - -# -# I2C GPIO expanders -# -# CONFIG_GPIO_ADP5588 is not set -# CONFIG_GPIO_ADNP is not set -# CONFIG_GPIO_MAX7300 is not set -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_GPIO_PCF857X is not set -# CONFIG_GPIO_TPIC2810 is not set - -# -# MFD GPIO expanders -# -# CONFIG_HTC_EGPIO is not set -# CONFIG_GPIO_TWL4030 is not set - -# -# PCI GPIO expanders -# -# CONFIG_GPIO_BT8XX is not set -# CONFIG_GPIO_PCI_IDIO_16 is not set -# CONFIG_GPIO_PCIE_IDIO_24 is not set -# CONFIG_GPIO_RDC321X is not set - -# -# SPI GPIO expanders -# -# CONFIG_GPIO_74X164 is not set -# CONFIG_GPIO_MAX3191X is not set -# CONFIG_GPIO_MAX7301 is not set -# CONFIG_GPIO_MC33880 is not set -# CONFIG_GPIO_PISOSR is not set -# CONFIG_GPIO_XRA1403 is not set - -# -# USB GPIO expanders -# -CONFIG_W1=m -CONFIG_W1_CON=y - -# -# 1-wire Bus Masters -# -# CONFIG_W1_MASTER_MATROX is not set -CONFIG_W1_MASTER_DS2490=m -CONFIG_W1_MASTER_DS2482=m -# CONFIG_W1_MASTER_DS1WM is not set -CONFIG_W1_MASTER_GPIO=m - -# -# 1-wire Slaves -# -CONFIG_W1_SLAVE_THERM=m -# CONFIG_W1_SLAVE_SMEM is not set -# CONFIG_W1_SLAVE_DS2405 is not set -# CONFIG_W1_SLAVE_DS2408 is not set -# CONFIG_W1_SLAVE_DS2413 is not set -# CONFIG_W1_SLAVE_DS2406 is not set -# CONFIG_W1_SLAVE_DS2423 is not set -# CONFIG_W1_SLAVE_DS2805 is not set -# CONFIG_W1_SLAVE_DS2431 is not set -# CONFIG_W1_SLAVE_DS2433 is not set -# CONFIG_W1_SLAVE_DS2438 is not set -# CONFIG_W1_SLAVE_DS2780 is not set -# CONFIG_W1_SLAVE_DS2781 is not set -# CONFIG_W1_SLAVE_DS28E04 is not set -# CONFIG_W1_SLAVE_DS28E17 is not set -CONFIG_POWER_AVS=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_BRCMKONA=y -CONFIG_POWER_RESET_BRCMSTB=y -CONFIG_POWER_RESET_GPIO=y -CONFIG_POWER_RESET_GPIO_RESTART=y -# CONFIG_POWER_RESET_LTC2952 is not set -# CONFIG_POWER_RESET_RESTART is not set -# CONFIG_POWER_RESET_VERSATILE is not set -CONFIG_POWER_RESET_VEXPRESS=y -CONFIG_POWER_RESET_SYSCON=y -CONFIG_POWER_RESET_SYSCON_POWEROFF=y -# CONFIG_SYSCON_REBOOT_MODE is not set -CONFIG_POWER_SUPPLY=y -# CONFIG_POWER_SUPPLY_DEBUG is not set -# CONFIG_PDA_POWER is not set -# CONFIG_GENERIC_ADC_BATTERY is not set -# CONFIG_TEST_POWER is not set -CONFIG_CHARGER_ADP5061=m -CONFIG_BATTERY_DS2760=m -# CONFIG_BATTERY_DS2780 is not set -# CONFIG_BATTERY_DS2781 is not set -# CONFIG_BATTERY_DS2782 is not set -# CONFIG_BATTERY_LEGO_EV3 is not set -CONFIG_BATTERY_SBS=y -# CONFIG_CHARGER_SBS is not set -# CONFIG_MANAGER_SBS is not set -# CONFIG_BATTERY_BQ27XXX is not set -CONFIG_BATTERY_MAX17040=m -CONFIG_BATTERY_MAX17042=m -# CONFIG_BATTERY_MAX1721X is not set -# CONFIG_CHARGER_ISP1704 is not set -# CONFIG_CHARGER_MAX8903 is not set -# CONFIG_CHARGER_TWL4030 is not set -# CONFIG_CHARGER_LP8727 is not set -# CONFIG_CHARGER_GPIO is not set -# CONFIG_CHARGER_MANAGER is not set -# CONFIG_CHARGER_LTC3651 is not set -# CONFIG_CHARGER_DETECTOR_MAX14656 is not set -# CONFIG_CHARGER_BQ2415X is not set -# CONFIG_CHARGER_BQ24190 is not set -# CONFIG_CHARGER_BQ24257 is not set -# CONFIG_CHARGER_BQ24735 is not set -# CONFIG_CHARGER_BQ25890 is not set -# CONFIG_CHARGER_SMB347 is not set -# CONFIG_BATTERY_GAUGE_LTC2941 is not set -CONFIG_BATTERY_RT5033=m -# CONFIG_CHARGER_RT9455 is not set -CONFIG_HWMON=y -CONFIG_HWMON_VID=m -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Native drivers -# -CONFIG_SENSORS_AD7314=m -CONFIG_SENSORS_AD7414=m -CONFIG_SENSORS_AD7418=m -CONFIG_SENSORS_ADM1021=m -CONFIG_SENSORS_ADM1025=m -CONFIG_SENSORS_ADM1026=m -CONFIG_SENSORS_ADM1029=m -CONFIG_SENSORS_ADM1031=m -CONFIG_SENSORS_ADM9240=m -CONFIG_SENSORS_ADT7X10=m -CONFIG_SENSORS_ADT7310=m -CONFIG_SENSORS_ADT7410=m -CONFIG_SENSORS_ADT7411=m -CONFIG_SENSORS_ADT7462=m -CONFIG_SENSORS_ADT7470=m -CONFIG_SENSORS_ADT7475=m -CONFIG_SENSORS_ASC7621=m -# CONFIG_SENSORS_ASPEED is not set -CONFIG_SENSORS_ATXP1=m -CONFIG_SENSORS_DS620=m -CONFIG_SENSORS_DS1621=m -CONFIG_SENSORS_I5K_AMB=m -CONFIG_SENSORS_F71805F=m -CONFIG_SENSORS_F71882FG=m -CONFIG_SENSORS_F75375S=m -CONFIG_SENSORS_FTSTEUTATES=m -CONFIG_SENSORS_GL518SM=m -CONFIG_SENSORS_GL520SM=m -CONFIG_SENSORS_G760A=m -CONFIG_SENSORS_G762=m -CONFIG_SENSORS_GPIO_FAN=m -CONFIG_SENSORS_HIH6130=m -# CONFIG_SENSORS_IIO_HWMON is not set -CONFIG_SENSORS_IT87=m -CONFIG_SENSORS_JC42=m -CONFIG_SENSORS_POWR1220=m -CONFIG_SENSORS_LINEAGE=m -CONFIG_SENSORS_LTC2945=m -CONFIG_SENSORS_LTC2990=m -CONFIG_SENSORS_LTC4151=m -CONFIG_SENSORS_LTC4215=m -CONFIG_SENSORS_LTC4222=m -CONFIG_SENSORS_LTC4245=m -CONFIG_SENSORS_LTC4260=m -CONFIG_SENSORS_LTC4261=m -CONFIG_SENSORS_MAX1111=m -CONFIG_SENSORS_MAX16065=m -CONFIG_SENSORS_MAX1619=m -CONFIG_SENSORS_MAX1668=m -CONFIG_SENSORS_MAX197=m -CONFIG_SENSORS_MAX31722=m -# CONFIG_SENSORS_MAX6621 is not set -CONFIG_SENSORS_MAX6639=m -CONFIG_SENSORS_MAX6642=m -CONFIG_SENSORS_MAX6650=m -CONFIG_SENSORS_MAX6697=m -CONFIG_SENSORS_MAX31790=m -CONFIG_SENSORS_MCP3021=m -# CONFIG_SENSORS_TC654 is not set -CONFIG_SENSORS_ADCXX=m -CONFIG_SENSORS_LM63=m -CONFIG_SENSORS_LM70=m -CONFIG_SENSORS_LM73=m -CONFIG_SENSORS_LM75=m -CONFIG_SENSORS_LM77=m -CONFIG_SENSORS_LM78=m -CONFIG_SENSORS_LM80=m -CONFIG_SENSORS_LM83=m -CONFIG_SENSORS_LM85=m -CONFIG_SENSORS_LM87=m -CONFIG_SENSORS_LM90=m -CONFIG_SENSORS_LM92=m -CONFIG_SENSORS_LM93=m -CONFIG_SENSORS_LM95234=m -CONFIG_SENSORS_LM95241=m -CONFIG_SENSORS_LM95245=m -CONFIG_SENSORS_PC87360=m -CONFIG_SENSORS_PC87427=m -CONFIG_SENSORS_NTC_THERMISTOR=m -CONFIG_SENSORS_NCT6683=m -CONFIG_SENSORS_NCT6775=m -CONFIG_SENSORS_NCT7802=m -CONFIG_SENSORS_NCT7904=m -CONFIG_SENSORS_NPCM7XX=m -CONFIG_SENSORS_PCF8591=m -# CONFIG_PMBUS is not set -CONFIG_SENSORS_PWM_FAN=m -CONFIG_SENSORS_SHT15=m -CONFIG_SENSORS_SHT21=m -CONFIG_SENSORS_SHT3x=m -CONFIG_SENSORS_SHTC1=m -CONFIG_SENSORS_SIS5595=m -CONFIG_SENSORS_DME1737=m -CONFIG_SENSORS_EMC1403=m -CONFIG_SENSORS_EMC2103=m -CONFIG_SENSORS_EMC6W201=m -CONFIG_SENSORS_SMSC47M1=m -CONFIG_SENSORS_SMSC47M192=m -CONFIG_SENSORS_SMSC47B397=m -CONFIG_SENSORS_SCH56XX_COMMON=m -CONFIG_SENSORS_SCH5627=m -CONFIG_SENSORS_SCH5636=m -CONFIG_SENSORS_STTS751=m -CONFIG_SENSORS_SMM665=m -CONFIG_SENSORS_ADC128D818=m -CONFIG_SENSORS_ADS1015=m -CONFIG_SENSORS_ADS7828=m -CONFIG_SENSORS_ADS7871=m -CONFIG_SENSORS_AMC6821=m -CONFIG_SENSORS_INA209=m -CONFIG_SENSORS_INA2XX=m -CONFIG_SENSORS_INA3221=m -CONFIG_SENSORS_TC74=m -CONFIG_SENSORS_THMC50=m -CONFIG_SENSORS_TMP102=m -CONFIG_SENSORS_TMP103=m -# CONFIG_SENSORS_TMP108 is not set -CONFIG_SENSORS_TMP401=m -CONFIG_SENSORS_TMP421=m -CONFIG_SENSORS_VEXPRESS=m -# CONFIG_SENSORS_VIA686A is not set -CONFIG_SENSORS_VT1211=m -CONFIG_SENSORS_VT8231=m -CONFIG_SENSORS_W83773G=m -CONFIG_SENSORS_W83781D=m -CONFIG_SENSORS_W83791D=m -CONFIG_SENSORS_W83792D=m -CONFIG_SENSORS_W83793=m -CONFIG_SENSORS_W83795=m -# CONFIG_SENSORS_W83795_FANCTRL is not set -CONFIG_SENSORS_W83L785TS=m -CONFIG_SENSORS_W83L786NG=m -CONFIG_SENSORS_W83627HF=m -CONFIG_SENSORS_W83627EHF=m -CONFIG_THERMAL=y -# CONFIG_THERMAL_STATISTICS is not set -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_HWMON=y -CONFIG_THERMAL_OF=y -CONFIG_THERMAL_WRITABLE_TRIPS=y -# CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE is not set -# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set -CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE=y -# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set -CONFIG_THERMAL_GOV_FAIR_SHARE=y -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_GOV_BANG_BANG=y -CONFIG_THERMAL_GOV_USER_SPACE=y -CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y -CONFIG_CPU_THERMAL=y -# CONFIG_CLOCK_THERMAL is not set -# CONFIG_DEVFREQ_THERMAL is not set -# CONFIG_THERMAL_EMULATION is not set -# CONFIG_QORIQ_THERMAL is not set - -# -# ACPI INT340X thermal drivers -# -CONFIG_MTK_THERMAL=y -# CONFIG_QCOM_SPMI_TEMP_ALARM is not set -# CONFIG_GENERIC_ADC_THERMAL is not set -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_CORE=y -# CONFIG_WATCHDOG_NOWAYOUT is not set -CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y -# CONFIG_WATCHDOG_SYSFS is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -# CONFIG_GPIO_WATCHDOG is not set -# CONFIG_XILINX_WATCHDOG is not set -# CONFIG_ZIIRAVE_WATCHDOG is not set -# CONFIG_CADENCE_WATCHDOG is not set -# CONFIG_FTWDT010_WATCHDOG is not set -# CONFIG_DW_WATCHDOG is not set -# CONFIG_TWL4030_WATCHDOG is not set -# CONFIG_MAX63XX_WATCHDOG is not set -CONFIG_MEDIATEK_WATCHDOG=y -# CONFIG_ALIM7101_WDT is not set -# CONFIG_I6300ESB_WDT is not set -# CONFIG_MEN_A21_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 - -# -# Watchdog Pretimeout Governors -# -# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set -CONFIG_SSB_POSSIBLE=y -CONFIG_SSB=m -CONFIG_SSB_SPROM=y -CONFIG_SSB_BLOCKIO=y -CONFIG_SSB_PCIHOST_POSSIBLE=y -CONFIG_SSB_PCIHOST=y -CONFIG_SSB_B43_PCI_BRIDGE=y -CONFIG_SSB_SDIOHOST_POSSIBLE=y -CONFIG_SSB_SDIOHOST=y -CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y -CONFIG_SSB_DRIVER_PCICORE=y -# CONFIG_SSB_DRIVER_GPIO is not set -CONFIG_BCMA_POSSIBLE=y -CONFIG_BCMA=m -CONFIG_BCMA_BLOCKIO=y -CONFIG_BCMA_HOST_PCI_POSSIBLE=y -CONFIG_BCMA_HOST_PCI=y -# CONFIG_BCMA_HOST_SOC is not set -CONFIG_BCMA_DRIVER_PCI=y -# CONFIG_BCMA_DRIVER_GMAC_CMN is not set -# CONFIG_BCMA_DRIVER_GPIO is not set -# CONFIG_BCMA_DEBUG is not set - -# -# Multifunction device drivers -# -CONFIG_MFD_CORE=y -# CONFIG_MFD_ACT8945A is not set -# CONFIG_MFD_AS3711 is not set -# CONFIG_MFD_AS3722 is not set -# CONFIG_PMIC_ADP5520 is not set -# CONFIG_MFD_AAT2870_CORE is not set -# CONFIG_MFD_ATMEL_FLEXCOM is not set -# CONFIG_MFD_ATMEL_HLCDC is not set -# CONFIG_MFD_BCM590XX is not set -# CONFIG_MFD_BD9571MWV is not set -# CONFIG_MFD_AXP20X_I2C is not set -# CONFIG_MFD_CROS_EC is not set -# CONFIG_MFD_MADERA is not set -# CONFIG_MFD_ASIC3 is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_MFD_DA9052_SPI is not set -# CONFIG_MFD_DA9052_I2C is not set -# CONFIG_MFD_DA9055 is not set -# CONFIG_MFD_DA9062 is not set -# CONFIG_MFD_DA9063 is not set -# CONFIG_MFD_DA9150 is not set -# CONFIG_MFD_DLN2 is not set -# CONFIG_MFD_MC13XXX_SPI is not set -# CONFIG_MFD_MC13XXX_I2C is not set -# CONFIG_MFD_HI6421_PMIC is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_HTC_I2CPLD is not set -# CONFIG_LPC_ICH is not set -CONFIG_LPC_SCH=m -# CONFIG_MFD_JANZ_CMODIO is not set -# CONFIG_MFD_KEMPLD is not set -# CONFIG_MFD_88PM800 is not set -# CONFIG_MFD_88PM805 is not set -# CONFIG_MFD_88PM860X is not set -# CONFIG_MFD_MAX14577 is not set -# CONFIG_MFD_MAX77620 is not set -# CONFIG_MFD_MAX77686 is not set -# CONFIG_MFD_MAX77693 is not set -# CONFIG_MFD_MAX77843 is not set -# CONFIG_MFD_MAX8907 is not set -# CONFIG_MFD_MAX8925 is not set -# CONFIG_MFD_MAX8997 is not set -# CONFIG_MFD_MAX8998 is not set -CONFIG_MFD_MT6397=y -# CONFIG_MFD_MENF21BMC is not set -# CONFIG_EZX_PCAP is not set -# CONFIG_MFD_CPCAP is not set -# CONFIG_MFD_VIPERBOARD is not set -# CONFIG_MFD_RETU is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_MFD_PM8XXX is not set -# CONFIG_MFD_RDC321X is not set -# CONFIG_MFD_RT5033 is not set -# CONFIG_MFD_RC5T583 is not set -# CONFIG_MFD_RK808 is not set -# CONFIG_MFD_RN5T618 is not set -# CONFIG_MFD_SEC_CORE is not set -# CONFIG_MFD_SI476X_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_MFD_SKY81452 is not set -# CONFIG_MFD_SMSC is not set -# CONFIG_ABX500_CORE is not set -# CONFIG_MFD_STMPE is not set -CONFIG_MFD_SYSCON=y -# CONFIG_MFD_LP3943 is not set -# CONFIG_MFD_LP8788 is not set -# CONFIG_MFD_TI_LMU is not set -# CONFIG_MFD_PALMAS is not set -# CONFIG_TPS6105X is not set -# CONFIG_TPS65010 is not set -# CONFIG_TPS6507X is not set -# CONFIG_MFD_TPS65086 is not set -# CONFIG_MFD_TPS65090 is not set -# CONFIG_MFD_TPS65217 is not set -# CONFIG_MFD_TI_LP873X is not set -# CONFIG_MFD_TI_LP87565 is not set -# CONFIG_MFD_TPS65218 is not set -# CONFIG_MFD_TPS6586X is not set -# CONFIG_MFD_TPS65910 is not set -# CONFIG_MFD_TPS65912_I2C is not set -# CONFIG_MFD_TPS65912_SPI is not set -# CONFIG_MFD_TPS80031 is not set -CONFIG_TWL4030_CORE=y -CONFIG_TWL4030_POWER=y -# CONFIG_MFD_TWL4030_AUDIO is not set -# CONFIG_TWL6040_CORE is not set -# CONFIG_MFD_WL1273_CORE is not set -# CONFIG_MFD_LM3533 is not set -# CONFIG_MFD_TC3589X is not set -# CONFIG_MFD_T7L66XB is not set -# CONFIG_MFD_TC6387XB is not set -# CONFIG_MFD_TC6393XB is not set -# CONFIG_MFD_VX855 is not set -# CONFIG_MFD_ARIZONA_I2C is not set -# CONFIG_MFD_ARIZONA_SPI is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM831X_I2C is not set -# CONFIG_MFD_WM831X_SPI is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_WM8994 is not set -CONFIG_MFD_ROHM_BD718XX=m -CONFIG_MFD_VEXPRESS_SYSREG=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_DEBUG=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set -# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set -# CONFIG_REGULATOR_88PG86X is not set -# CONFIG_REGULATOR_ACT8865 is not set -# CONFIG_REGULATOR_AD5398 is not set -# CONFIG_REGULATOR_ANATOP is not set -CONFIG_REGULATOR_BD718XX=m -# CONFIG_REGULATOR_DA9210 is not set -# CONFIG_REGULATOR_DA9211 is not set -# CONFIG_REGULATOR_FAN53555 is not set -# CONFIG_REGULATOR_GPIO is not set -# CONFIG_REGULATOR_ISL9305 is not set -# CONFIG_REGULATOR_ISL6271A is not set -# CONFIG_REGULATOR_LP3971 is not set -# CONFIG_REGULATOR_LP3972 is not set -# CONFIG_REGULATOR_LP872X is not set -# CONFIG_REGULATOR_LP8755 is not set -# CONFIG_REGULATOR_LTC3589 is not set -# CONFIG_REGULATOR_LTC3676 is not set -# CONFIG_REGULATOR_MAX1586 is not set -# CONFIG_REGULATOR_MAX8649 is not set -# CONFIG_REGULATOR_MAX8660 is not set -# CONFIG_REGULATOR_MAX8952 is not set -# CONFIG_REGULATOR_MAX8973 is not set -# CONFIG_REGULATOR_MT6311 is not set -CONFIG_REGULATOR_MT6323=y -# CONFIG_REGULATOR_MT6380 is not set -# CONFIG_REGULATOR_MT6397 is not set -# CONFIG_REGULATOR_PFUZE100 is not set -# CONFIG_REGULATOR_PV88060 is not set -# CONFIG_REGULATOR_PV88080 is not set -# CONFIG_REGULATOR_PV88090 is not set -# CONFIG_REGULATOR_PWM is not set -# CONFIG_REGULATOR_QCOM_SPMI is not set -# CONFIG_REGULATOR_SY8106A is not set -# CONFIG_REGULATOR_TPS51632 is not set -# CONFIG_REGULATOR_TPS62360 is not set -# CONFIG_REGULATOR_TPS65023 is not set -# CONFIG_REGULATOR_TPS6507X is not set -# CONFIG_REGULATOR_TPS65132 is not set -# CONFIG_REGULATOR_TPS6524X is not set -# CONFIG_REGULATOR_TWL4030 is not set -# CONFIG_REGULATOR_VCTRL is not set -# CONFIG_REGULATOR_VEXPRESS is not set -CONFIG_CEC_CORE=m -CONFIG_RC_CORE=m -CONFIG_RC_MAP=m -CONFIG_LIRC=y -CONFIG_RC_DECODERS=y -CONFIG_IR_NEC_DECODER=m -CONFIG_IR_RC5_DECODER=m -CONFIG_IR_RC6_DECODER=m -CONFIG_IR_JVC_DECODER=m -CONFIG_IR_SONY_DECODER=m -CONFIG_IR_SANYO_DECODER=m -CONFIG_IR_SHARP_DECODER=m -CONFIG_IR_MCE_KBD_DECODER=m -CONFIG_IR_XMP_DECODER=m -CONFIG_IR_IMON_DECODER=m -CONFIG_RC_DEVICES=y -# CONFIG_RC_ATI_REMOTE is not set -# CONFIG_IR_HIX5HD2 is not set -# CONFIG_IR_IMON is not set -# CONFIG_IR_IMON_RAW is not set -# CONFIG_IR_MCEUSB is not set -CONFIG_IR_MTK=m -# CONFIG_IR_REDRAT3 is not set -# CONFIG_IR_SPI is not set -# CONFIG_IR_STREAMZAP is not set -# CONFIG_IR_IGORPLUGUSB is not set -# CONFIG_IR_IGUANA is not set -# CONFIG_IR_TTUSBIR is not set -# CONFIG_RC_LOOPBACK is not set -CONFIG_IR_GPIO_CIR=m -# CONFIG_IR_GPIO_TX is not set -# CONFIG_IR_PWM_TX is not set -# CONFIG_IR_SERIAL is not set -# CONFIG_IR_SIR is not set -CONFIG_MEDIA_SUPPORT=m - -# -# Multimedia core support -# -CONFIG_MEDIA_CAMERA_SUPPORT=y -# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set -# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set -# CONFIG_MEDIA_RADIO_SUPPORT is not set -# CONFIG_MEDIA_SDR_SUPPORT is not set -CONFIG_MEDIA_CEC_SUPPORT=y -# CONFIG_MEDIA_CEC_RC is not set -CONFIG_MEDIA_CONTROLLER=y -CONFIG_VIDEO_DEV=m -CONFIG_VIDEO_V4L2_SUBDEV_API=y -CONFIG_VIDEO_V4L2=m -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -# CONFIG_VIDEO_PCI_SKELETON is not set -CONFIG_V4L2_MEM2MEM_DEV=m -# CONFIG_V4L2_FLASH_LED_CLASS is not set -CONFIG_V4L2_FWNODE=m - -# -# Media drivers -# -CONFIG_MEDIA_USB_SUPPORT=y - -# -# Webcam devices -# -CONFIG_USB_VIDEO_CLASS=m -CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -CONFIG_USB_GSPCA=m -# CONFIG_USB_M5602 is not set -# CONFIG_USB_STV06XX is not set -# CONFIG_USB_GL860 is not set -# CONFIG_USB_GSPCA_BENQ is not set -# CONFIG_USB_GSPCA_CONEX is not set -# CONFIG_USB_GSPCA_CPIA1 is not set -# CONFIG_USB_GSPCA_DTCS033 is not set -# CONFIG_USB_GSPCA_ETOMS is not set -# CONFIG_USB_GSPCA_FINEPIX is not set -# CONFIG_USB_GSPCA_JEILINJ is not set -# CONFIG_USB_GSPCA_JL2005BCD is not set -# CONFIG_USB_GSPCA_KINECT is not set -# CONFIG_USB_GSPCA_KONICA is not set -# CONFIG_USB_GSPCA_MARS is not set -# CONFIG_USB_GSPCA_MR97310A is not set -# CONFIG_USB_GSPCA_NW80X is not set -# CONFIG_USB_GSPCA_OV519 is not set -# CONFIG_USB_GSPCA_OV534 is not set -# CONFIG_USB_GSPCA_OV534_9 is not set -# CONFIG_USB_GSPCA_PAC207 is not set -# CONFIG_USB_GSPCA_PAC7302 is not set -# CONFIG_USB_GSPCA_PAC7311 is not set -# CONFIG_USB_GSPCA_SE401 is not set -# CONFIG_USB_GSPCA_SN9C2028 is not set -# CONFIG_USB_GSPCA_SN9C20X is not set -# CONFIG_USB_GSPCA_SONIXB is not set -# CONFIG_USB_GSPCA_SONIXJ is not set -# CONFIG_USB_GSPCA_SPCA500 is not set -# CONFIG_USB_GSPCA_SPCA501 is not set -# CONFIG_USB_GSPCA_SPCA505 is not set -# CONFIG_USB_GSPCA_SPCA506 is not set -# CONFIG_USB_GSPCA_SPCA508 is not set -# CONFIG_USB_GSPCA_SPCA561 is not set -# CONFIG_USB_GSPCA_SPCA1528 is not set -# CONFIG_USB_GSPCA_SQ905 is not set -# CONFIG_USB_GSPCA_SQ905C is not set -# CONFIG_USB_GSPCA_SQ930X is not set -# CONFIG_USB_GSPCA_STK014 is not set -# CONFIG_USB_GSPCA_STK1135 is not set -# CONFIG_USB_GSPCA_STV0680 is not set -# CONFIG_USB_GSPCA_SUNPLUS is not set -# CONFIG_USB_GSPCA_T613 is not set -# CONFIG_USB_GSPCA_TOPRO is not set -# CONFIG_USB_GSPCA_TOUPTEK is not set -# CONFIG_USB_GSPCA_TV8532 is not set -# CONFIG_USB_GSPCA_VC032X is not set -# CONFIG_USB_GSPCA_VICAM is not set -# CONFIG_USB_GSPCA_XIRLINK_CIT is not set -# CONFIG_USB_GSPCA_ZC3XX is not set -# CONFIG_USB_PWC is not set -# CONFIG_VIDEO_CPIA2 is not set -# CONFIG_USB_ZR364XX is not set -# CONFIG_USB_STKWEBCAM is not set -# CONFIG_USB_S2255 is not set -# CONFIG_VIDEO_USBTV is not set - -# -# Webcam, TV (analog/digital) USB devices -# -# CONFIG_VIDEO_EM28XX is not set - -# -# USB HDMI CEC adapters -# -CONFIG_USB_PULSE8_CEC=m -# CONFIG_USB_RAINSHADOW_CEC is not set -# CONFIG_MEDIA_PCI_SUPPORT is not set -CONFIG_V4L_PLATFORM_DRIVERS=y -# CONFIG_VIDEO_CAFE_CCIC is not set -# CONFIG_VIDEO_CADENCE is not set -# CONFIG_VIDEO_MUX is not set -CONFIG_SOC_CAMERA=m -CONFIG_SOC_CAMERA_PLATFORM=m -# CONFIG_VIDEO_XILINX is not set -CONFIG_V4L_MEM2MEM_DRIVERS=y -# CONFIG_VIDEO_MEDIATEK_VPU is not set -# CONFIG_VIDEO_MEDIATEK_MDP is not set -# CONFIG_VIDEO_MEDIATEK_VCODEC is not set -# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set -# CONFIG_VIDEO_SH_VEU is not set -CONFIG_V4L_TEST_DRIVERS=y -# CONFIG_VIDEO_VIMC is not set -CONFIG_VIDEO_VIVID=m -# CONFIG_VIDEO_VIVID_CEC is not set -CONFIG_VIDEO_VIVID_MAX_DEVS=64 -# CONFIG_VIDEO_VIM2M is not set -CONFIG_VIDEO_VICODEC=m -CONFIG_CEC_PLATFORM_DRIVERS=y - -# -# Supported MMC/SDIO adapters -# -# CONFIG_CYPRESS_FIRMWARE is not set -CONFIG_VIDEOBUF2_CORE=m -CONFIG_VIDEOBUF2_V4L2=m -CONFIG_VIDEOBUF2_MEMOPS=m -CONFIG_VIDEOBUF2_DMA_CONTIG=m -CONFIG_VIDEOBUF2_VMALLOC=m -CONFIG_VIDEO_V4L2_TPG=m - -# -# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) -# -# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set -CONFIG_VIDEO_IR_I2C=m - -# -# I2C Encoders, decoders, sensors and other helper chips -# - -# -# Audio decoders, processors and mixers -# -# CONFIG_VIDEO_TVAUDIO is not set -# CONFIG_VIDEO_TDA7432 is not set -# CONFIG_VIDEO_TDA9840 is not set -# CONFIG_VIDEO_TDA1997X is not set -# CONFIG_VIDEO_TEA6415C is not set -# CONFIG_VIDEO_TEA6420 is not set -# CONFIG_VIDEO_MSP3400 is not set -# CONFIG_VIDEO_CS3308 is not set -# CONFIG_VIDEO_CS5345 is not set -# CONFIG_VIDEO_CS53L32A is not set -# CONFIG_VIDEO_TLV320AIC23B is not set -# CONFIG_VIDEO_UDA1342 is not set -# CONFIG_VIDEO_WM8775 is not set -# CONFIG_VIDEO_WM8739 is not set -# CONFIG_VIDEO_VP27SMPX is not set -# CONFIG_VIDEO_SONY_BTF_MPX is not set - -# -# RDS decoders -# -# CONFIG_VIDEO_SAA6588 is not set - -# -# Video decoders -# -CONFIG_VIDEO_ADV7180=m -# CONFIG_VIDEO_ADV7183 is not set -# CONFIG_VIDEO_ADV748X is not set -# CONFIG_VIDEO_ADV7604 is not set -# CONFIG_VIDEO_ADV7842 is not set -# CONFIG_VIDEO_BT819 is not set -# CONFIG_VIDEO_BT856 is not set -# CONFIG_VIDEO_BT866 is not set -# CONFIG_VIDEO_KS0127 is not set -CONFIG_VIDEO_ML86V7667=m -# CONFIG_VIDEO_AD5820 is not set -CONFIG_VIDEO_AK7375=m -# CONFIG_VIDEO_DW9714 is not set -# CONFIG_VIDEO_DW9807_VCM is not set -# CONFIG_VIDEO_SAA7110 is not set -# CONFIG_VIDEO_SAA711X is not set -# CONFIG_VIDEO_TC358743 is not set -# CONFIG_VIDEO_TVP514X is not set -# CONFIG_VIDEO_TVP5150 is not set -# CONFIG_VIDEO_TVP7002 is not set -# CONFIG_VIDEO_TW2804 is not set -# CONFIG_VIDEO_TW9903 is not set -# CONFIG_VIDEO_TW9906 is not set -# CONFIG_VIDEO_TW9910 is not set -# CONFIG_VIDEO_VPX3220 is not set - -# -# Video and audio decoders -# -# CONFIG_VIDEO_SAA717X is not set -# CONFIG_VIDEO_CX25840 is not set - -# -# Video encoders -# -# CONFIG_VIDEO_SAA7127 is not set -# CONFIG_VIDEO_SAA7185 is not set -# CONFIG_VIDEO_ADV7170 is not set -# CONFIG_VIDEO_ADV7175 is not set -# CONFIG_VIDEO_ADV7343 is not set -# CONFIG_VIDEO_ADV7393 is not set -# CONFIG_VIDEO_ADV7511 is not set -# CONFIG_VIDEO_AD9389B is not set -# CONFIG_VIDEO_AK881X is not set -# CONFIG_VIDEO_THS8200 is not set - -# -# Camera sensor devices -# -# CONFIG_VIDEO_IMX258 is not set -# CONFIG_VIDEO_IMX274 is not set -# CONFIG_VIDEO_OV2640 is not set -# CONFIG_VIDEO_OV2659 is not set -CONFIG_VIDEO_OV2680=m -# CONFIG_VIDEO_OV2685 is not set -# CONFIG_VIDEO_OV5640 is not set -# CONFIG_VIDEO_OV5645 is not set -# CONFIG_VIDEO_OV5647 is not set -# CONFIG_VIDEO_OV6650 is not set -# CONFIG_VIDEO_OV5670 is not set -# CONFIG_VIDEO_OV5695 is not set -# CONFIG_VIDEO_OV7251 is not set -# CONFIG_VIDEO_OV772X is not set -# CONFIG_VIDEO_OV7640 is not set -# CONFIG_VIDEO_OV7670 is not set -# CONFIG_VIDEO_OV7740 is not set -# CONFIG_VIDEO_OV9650 is not set -# CONFIG_VIDEO_OV13858 is not set -# CONFIG_VIDEO_VS6624 is not set -# CONFIG_VIDEO_MT9M032 is not set -# CONFIG_VIDEO_MT9M111 is not set -# CONFIG_VIDEO_MT9P031 is not set -# CONFIG_VIDEO_MT9T001 is not set -# CONFIG_VIDEO_MT9T112 is not set -# CONFIG_VIDEO_MT9V011 is not set -# CONFIG_VIDEO_MT9V032 is not set -CONFIG_VIDEO_MT9V111=m -# CONFIG_VIDEO_SR030PC30 is not set -# CONFIG_VIDEO_NOON010PC30 is not set -# CONFIG_VIDEO_M5MOLS is not set -# CONFIG_VIDEO_RJ54N1 is not set -# CONFIG_VIDEO_S5K6AA is not set -# CONFIG_VIDEO_S5K6A3 is not set -# CONFIG_VIDEO_S5K4ECGX is not set -# CONFIG_VIDEO_S5K5BAF is not set -# CONFIG_VIDEO_SMIAPP is not set -# CONFIG_VIDEO_ET8EK8 is not set -# CONFIG_VIDEO_S5C73M3 is not set - -# -# Flash devices -# -# CONFIG_VIDEO_ADP1653 is not set -# CONFIG_VIDEO_LM3560 is not set -# CONFIG_VIDEO_LM3646 is not set - -# -# Video improvement chips -# -# CONFIG_VIDEO_UPD64031A is not set -# CONFIG_VIDEO_UPD64083 is not set - -# -# Audio/Video compression chips -# -# CONFIG_VIDEO_SAA6752HS is not set - -# -# SDR tuner chips -# - -# -# Miscellaneous helper chips -# -# CONFIG_VIDEO_THS7303 is not set -# CONFIG_VIDEO_M52790 is not set -# CONFIG_VIDEO_I2C is not set - -# -# Sensors used on soc_camera driver -# - -# -# soc_camera sensor drivers -# -# CONFIG_SOC_CAMERA_MT9M001 is not set -# CONFIG_SOC_CAMERA_MT9M111 is not set -# CONFIG_SOC_CAMERA_MT9T112 is not set -# CONFIG_SOC_CAMERA_MT9V022 is not set -# CONFIG_SOC_CAMERA_OV5642 is not set -# CONFIG_SOC_CAMERA_OV772X is not set -# CONFIG_SOC_CAMERA_OV9640 is not set -# CONFIG_SOC_CAMERA_OV9740 is not set -# CONFIG_SOC_CAMERA_RJ54N1 is not set -# CONFIG_SOC_CAMERA_TW9910 is not set - -# -# SPI helper chips -# -# CONFIG_VIDEO_GS1662 is not set - -# -# Media SPI Adapters -# - -# -# Customise DVB Frontends -# - -# -# Tools to develop new frontends -# - -# -# Graphics support -# -CONFIG_VGA_ARB=y -CONFIG_VGA_ARB_MAX_GPUS=16 -# CONFIG_IMX_IPUV3_CORE is not set -CONFIG_DRM=y -CONFIG_DRM_MIPI_DSI=y -# CONFIG_DRM_DP_AUX_CHARDEV is not set -# CONFIG_DRM_DEBUG_MM is not set -# CONFIG_DRM_DEBUG_SELFTEST is not set -CONFIG_DRM_KMS_HELPER=y -CONFIG_DRM_KMS_FB_HELPER=y -CONFIG_DRM_FBDEV_EMULATION=y -CONFIG_DRM_FBDEV_OVERALLOC=100 -# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set -# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set -# CONFIG_DRM_DP_CEC is not set -CONFIG_DRM_TTM=m -CONFIG_DRM_GEM_CMA_HELPER=y -CONFIG_DRM_KMS_CMA_HELPER=y -CONFIG_DRM_VM=y - -# -# I2C encoder or helper chips -# -# CONFIG_DRM_I2C_CH7006 is not set -# CONFIG_DRM_I2C_SIL164 is not set -# CONFIG_DRM_I2C_NXP_TDA998X is not set -# CONFIG_DRM_I2C_NXP_TDA9950 is not set -# CONFIG_DRM_HDLCD is not set -# CONFIG_DRM_MALI_DISPLAY is not set -# CONFIG_DRM_RADEON is not set -# CONFIG_DRM_AMDGPU is not set - -# -# ACP (Audio CoProcessor) Configuration -# - -# -# AMD Library routines -# -CONFIG_DRM_NOUVEAU=m -CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT=y -CONFIG_NOUVEAU_DEBUG=5 -CONFIG_NOUVEAU_DEBUG_DEFAULT=3 -# CONFIG_NOUVEAU_DEBUG_MMU is not set -CONFIG_DRM_NOUVEAU_BACKLIGHT=y -# CONFIG_DRM_VGEM is not set -# CONFIG_DRM_VKMS is not set -CONFIG_DRM_EXYNOS=m - -# -# CRTCs -# -CONFIG_DRM_EXYNOS_FIMD=y -# CONFIG_DRM_EXYNOS5433_DECON is not set -# CONFIG_DRM_EXYNOS7_DECON is not set -CONFIG_DRM_EXYNOS_MIXER=y -# CONFIG_DRM_EXYNOS_VIDI is not set - -# -# Encoders and Bridges -# -CONFIG_DRM_EXYNOS_DPI=y -CONFIG_DRM_EXYNOS_DSI=y -CONFIG_DRM_EXYNOS_DP=y -CONFIG_DRM_EXYNOS_HDMI=y - -# -# Sub-drivers -# -# CONFIG_DRM_EXYNOS_G2D is not set -# CONFIG_DRM_EXYNOS_FIMC is not set -# CONFIG_DRM_EXYNOS_ROTATOR is not set -# CONFIG_DRM_EXYNOS_SCALER is not set -# CONFIG_DRM_EXYNOS_GSC is not set -# CONFIG_DRM_UDL is not set -# CONFIG_DRM_AST is not set -# CONFIG_DRM_MGAG200 is not set -# CONFIG_DRM_CIRRUS_QEMU is not set -# CONFIG_DRM_ARMADA is not set -# CONFIG_DRM_RCAR_DW_HDMI is not set -CONFIG_DRM_RCAR_LVDS=y -# CONFIG_DRM_OMAP is not set -# CONFIG_DRM_TILCDC is not set -# CONFIG_DRM_QXL is not set -# CONFIG_DRM_BOCHS is not set -# CONFIG_DRM_VIRTIO_GPU is not set -CONFIG_DRM_FSL_DCU=m -# CONFIG_DRM_STM is not set -CONFIG_DRM_PANEL=y - -# -# Display Panels -# -# CONFIG_DRM_PANEL_ARM_VERSATILE is not set -# CONFIG_DRM_PANEL_LVDS is not set -CONFIG_DRM_PANEL_SIMPLE=y -# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set -CONFIG_DRM_PANEL_ILITEK_ILI9881C=m -# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set -# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set -CONFIG_DRM_PANEL_SAMSUNG_LD9040=m -# CONFIG_DRM_PANEL_LG_LG4573 is not set -# CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set -# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set -# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set -# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set -CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m -# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set -# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set -# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set -# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set -CONFIG_DRM_BRIDGE=y -CONFIG_DRM_PANEL_BRIDGE=y - -# -# Display Interface Bridges -# -# CONFIG_DRM_ANALOGIX_ANX78XX is not set -# CONFIG_DRM_CDNS_DSI is not set -CONFIG_DRM_DUMB_VGA_DAC=m -# CONFIG_DRM_LVDS_ENCODER is not set -# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set -CONFIG_DRM_NXP_PTN3460=m -CONFIG_DRM_PARADE_PS8622=m -# CONFIG_DRM_SIL_SII8620 is not set -# CONFIG_DRM_SII902X is not set -CONFIG_DRM_SII9234=m -# CONFIG_DRM_THINE_THC63LVD1024 is not set -# CONFIG_DRM_TOSHIBA_TC358767 is not set -# CONFIG_DRM_TI_TFP410 is not set -CONFIG_DRM_ANALOGIX_DP=m -CONFIG_DRM_I2C_ADV7511=m -CONFIG_DRM_I2C_ADV7511_AUDIO=y -CONFIG_DRM_I2C_ADV7533=y -CONFIG_DRM_I2C_ADV7511_CEC=y -CONFIG_DRM_STI=m -# CONFIG_DRM_ARCPGU is not set -# CONFIG_DRM_HISI_HIBMC is not set -# CONFIG_DRM_MEDIATEK is not set -# CONFIG_DRM_TINYDRM is not set -# CONFIG_DRM_PL111 is not set -# CONFIG_DRM_TVE200 is not set -# CONFIG_DRM_LEGACY is not set -CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y - -# -# Frame buffer Devices -# -CONFIG_FB_CMDLINE=y -CONFIG_FB_NOTIFY=y -CONFIG_FB=y -# CONFIG_FIRMWARE_EDID is not set -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_SYS_FILLRECT=y -CONFIG_FB_SYS_COPYAREA=y -CONFIG_FB_SYS_IMAGEBLIT=y -# CONFIG_FB_FOREIGN_ENDIAN is not set -CONFIG_FB_SYS_FOPS=y -CONFIG_FB_DEFERRED_IO=y -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_UVESA is not set -CONFIG_FB_EFI=y -# CONFIG_FB_OPENCORES is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_NVIDIA is not set -# CONFIG_FB_RIVA is not set -# CONFIG_FB_I740 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_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_SMSCUFX is not set -# CONFIG_FB_UDL is not set -# CONFIG_FB_IBM_GXT4500 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_FB_SIMPLE=y -# CONFIG_FB_SSD1307 is not set -# CONFIG_FB_SM712 is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=m -# CONFIG_LCD_L4F00242T03 is not set -# CONFIG_LCD_LMS283GF05 is not set -# CONFIG_LCD_LTV350QV is not set -# CONFIG_LCD_ILI922X is not set -# CONFIG_LCD_ILI9320 is not set -# CONFIG_LCD_TDO24M is not set -# CONFIG_LCD_VGG2432A4 is not set -CONFIG_LCD_PLATFORM=m -# CONFIG_LCD_S6E63M0 is not set -# CONFIG_LCD_LD9040 is not set -# CONFIG_LCD_AMS369FG06 is not set -# CONFIG_LCD_LMS501KF03 is not set -# CONFIG_LCD_HX8357 is not set -# CONFIG_LCD_OTM3225A is not set -CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_BACKLIGHT_GENERIC=y -CONFIG_BACKLIGHT_PWM=y -# CONFIG_BACKLIGHT_PM8941_WLED is not set -# CONFIG_BACKLIGHT_ADP8860 is not set -# CONFIG_BACKLIGHT_ADP8870 is not set -# CONFIG_BACKLIGHT_LM3630A is not set -# CONFIG_BACKLIGHT_LM3639 is not set -# CONFIG_BACKLIGHT_LP855X is not set -# CONFIG_BACKLIGHT_PANDORA is not set -# CONFIG_BACKLIGHT_GPIO is not set -# CONFIG_BACKLIGHT_LV5207LP is not set -# CONFIG_BACKLIGHT_BD6107 is not set -# CONFIG_BACKLIGHT_ARCXCNN is not set -CONFIG_VIDEOMODE_HELPERS=y -CONFIG_HDMI=y - -# -# Console display driver support -# -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y -# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set -# CONFIG_LOGO is not set -CONFIG_SOUND=m -CONFIG_SND=m -CONFIG_SND_TIMER=m -CONFIG_SND_PCM=m -CONFIG_SND_PCM_ELD=y -CONFIG_SND_PCM_IEC958=y -CONFIG_SND_DMAENGINE_PCM=m -CONFIG_SND_HWDEP=m -CONFIG_SND_RAWMIDI=m -CONFIG_SND_JACK=y -CONFIG_SND_JACK_INPUT_DEV=y -# CONFIG_SND_OSSEMUL is not set -CONFIG_SND_PCM_TIMER=y -# CONFIG_SND_HRTIMER is not set -CONFIG_SND_DYNAMIC_MINORS=y -CONFIG_SND_MAX_CARDS=32 -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_PROC_FS=y -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set -# CONFIG_SND_SEQUENCER is not set -CONFIG_SND_DRIVERS=y -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_ALOOP is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_MTS64 is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set -# CONFIG_SND_PORTMAN2X4 is not set -CONFIG_SND_PCI=y -# CONFIG_SND_AD1889 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_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_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_ENS1370 is not set -# CONFIG_SND_ENS1371 is not set -# CONFIG_SND_FM801 is not set -# CONFIG_SND_HDSP is not set -# CONFIG_SND_HDSPM 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_LOLA is not set -CONFIG_SND_LX6464ES=m -# 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_SE6X 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 - -# -# HD-Audio -# -# CONFIG_SND_HDA_INTEL is not set -CONFIG_SND_HDA_PREALLOC_SIZE=64 -CONFIG_SND_ARM=y -CONFIG_SND_SPI=y -CONFIG_SND_USB=y -CONFIG_SND_USB_AUDIO=m -# CONFIG_SND_USB_UA101 is not set -# CONFIG_SND_USB_CAIAQ is not set -# CONFIG_SND_USB_6FIRE is not set -# CONFIG_SND_USB_HIFACE is not set -# CONFIG_SND_BCD2000 is not set -# CONFIG_SND_USB_POD is not set -# CONFIG_SND_USB_PODHD is not set -# CONFIG_SND_USB_TONEPORT is not set -# CONFIG_SND_USB_VARIAX is not set -CONFIG_SND_SOC=m -CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y -# CONFIG_SND_SOC_AMD_ACP is not set -# CONFIG_SND_ATMEL_SOC is not set -# CONFIG_SND_DESIGNWARE_I2S is not set - -# -# SoC Audio for Freescale CPUs -# - -# -# Common SoC Audio options for Freescale CPUs: -# -# CONFIG_SND_SOC_FSL_ASRC is not set -CONFIG_SND_SOC_FSL_SAI=m -# CONFIG_SND_SOC_FSL_SSI is not set -# CONFIG_SND_SOC_FSL_SPDIF is not set -# CONFIG_SND_SOC_FSL_ESAI is not set -# CONFIG_SND_SOC_IMX_AUDMUX is not set -# CONFIG_SND_I2S_HI6210_I2S is not set -# CONFIG_SND_SOC_IMG is not set -CONFIG_SND_SOC_MEDIATEK=m -CONFIG_SND_SOC_MT2701=m -CONFIG_SND_SOC_MT2701_CS42448=m -CONFIG_SND_SOC_MT2701_WM8960=m -# CONFIG_SND_SOC_MT6797 is not set -# CONFIG_SND_SOC_MT8173 is not set - -# -# STMicroelectronics STM32 SOC audio support -# -# CONFIG_SND_SOC_XTFPGA_I2S is not set -# CONFIG_ZX_TDM is not set -CONFIG_SND_SOC_I2C_AND_SPI=m - -# -# CODEC drivers -# -# CONFIG_SND_SOC_AC97_CODEC is not set -# CONFIG_SND_SOC_ADAU1701 is not set -# CONFIG_SND_SOC_ADAU1761_I2C is not set -# CONFIG_SND_SOC_ADAU1761_SPI is not set -# CONFIG_SND_SOC_ADAU7002 is not set -# CONFIG_SND_SOC_AK4104 is not set -# CONFIG_SND_SOC_AK4458 is not set -# CONFIG_SND_SOC_AK4554 is not set -# CONFIG_SND_SOC_AK4613 is not set -CONFIG_SND_SOC_AK4642=m -# CONFIG_SND_SOC_AK5386 is not set -# CONFIG_SND_SOC_AK5558 is not set -# CONFIG_SND_SOC_ALC5623 is not set -# CONFIG_SND_SOC_BD28623 is not set -CONFIG_SND_SOC_BT_SCO=m -# CONFIG_SND_SOC_CS35L32 is not set -# CONFIG_SND_SOC_CS35L33 is not set -# CONFIG_SND_SOC_CS35L34 is not set -# CONFIG_SND_SOC_CS35L35 is not set -# CONFIG_SND_SOC_CS42L42 is not set -# CONFIG_SND_SOC_CS42L51_I2C is not set -# CONFIG_SND_SOC_CS42L52 is not set -# CONFIG_SND_SOC_CS42L56 is not set -# CONFIG_SND_SOC_CS42L73 is not set -# CONFIG_SND_SOC_CS4265 is not set -# CONFIG_SND_SOC_CS4270 is not set -# CONFIG_SND_SOC_CS4271_I2C is not set -# CONFIG_SND_SOC_CS4271_SPI is not set -CONFIG_SND_SOC_CS42XX8=m -CONFIG_SND_SOC_CS42XX8_I2C=m -# CONFIG_SND_SOC_CS43130 is not set -# CONFIG_SND_SOC_CS4349 is not set -# CONFIG_SND_SOC_CS53L30 is not set -CONFIG_SND_SOC_HDMI_CODEC=m -# CONFIG_SND_SOC_ES7134 is not set -# CONFIG_SND_SOC_ES7241 is not set -# CONFIG_SND_SOC_ES8316 is not set -# CONFIG_SND_SOC_ES8328_I2C is not set -# CONFIG_SND_SOC_ES8328_SPI is not set -# CONFIG_SND_SOC_GTM601 is not set -# CONFIG_SND_SOC_INNO_RK3036 is not set -# CONFIG_SND_SOC_MAX98504 is not set -# CONFIG_SND_SOC_MAX9867 is not set -# CONFIG_SND_SOC_MAX98927 is not set -# CONFIG_SND_SOC_MAX98373 is not set -# CONFIG_SND_SOC_MAX9860 is not set -# CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set -# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set -# CONFIG_SND_SOC_PCM1681 is not set -# CONFIG_SND_SOC_PCM1789_I2C is not set -# CONFIG_SND_SOC_PCM179X_I2C is not set -# CONFIG_SND_SOC_PCM179X_SPI is not set -# CONFIG_SND_SOC_PCM186X_I2C is not set -# CONFIG_SND_SOC_PCM186X_SPI is not set -# CONFIG_SND_SOC_PCM3168A_I2C is not set -# CONFIG_SND_SOC_PCM3168A_SPI is not set -# CONFIG_SND_SOC_PCM512x_I2C is not set -# CONFIG_SND_SOC_PCM512x_SPI is not set -# CONFIG_SND_SOC_RT5616 is not set -# CONFIG_SND_SOC_RT5631 is not set -CONFIG_SND_SOC_SGTL5000=m -# CONFIG_SND_SOC_SIMPLE_AMPLIFIER is not set -# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set -CONFIG_SND_SOC_SPDIF=m -# CONFIG_SND_SOC_SSM2305 is not set -# CONFIG_SND_SOC_SSM2602_SPI is not set -# CONFIG_SND_SOC_SSM2602_I2C is not set -# CONFIG_SND_SOC_SSM4567 is not set -# CONFIG_SND_SOC_STA32X is not set -# CONFIG_SND_SOC_STA350 is not set -CONFIG_SND_SOC_STI_SAS=m -# CONFIG_SND_SOC_TAS2552 is not set -# CONFIG_SND_SOC_TAS5086 is not set -# CONFIG_SND_SOC_TAS571X is not set -# CONFIG_SND_SOC_TAS5720 is not set -# CONFIG_SND_SOC_TAS6424 is not set -# CONFIG_SND_SOC_TDA7419 is not set -# CONFIG_SND_SOC_TFA9879 is not set -CONFIG_SND_SOC_TLV320AIC23=m -CONFIG_SND_SOC_TLV320AIC23_I2C=m -# CONFIG_SND_SOC_TLV320AIC23_SPI is not set -# CONFIG_SND_SOC_TLV320AIC31XX is not set -# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set -# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set -# CONFIG_SND_SOC_TLV320AIC3X is not set -CONFIG_SND_SOC_TS3A227E=m -# CONFIG_SND_SOC_TSCS42XX is not set -# CONFIG_SND_SOC_TSCS454 is not set -# CONFIG_SND_SOC_WM8510 is not set -# CONFIG_SND_SOC_WM8523 is not set -# CONFIG_SND_SOC_WM8524 is not set -# CONFIG_SND_SOC_WM8580 is not set -# CONFIG_SND_SOC_WM8711 is not set -# CONFIG_SND_SOC_WM8728 is not set -# CONFIG_SND_SOC_WM8731 is not set -# CONFIG_SND_SOC_WM8737 is not set -# CONFIG_SND_SOC_WM8741 is not set -# CONFIG_SND_SOC_WM8750 is not set -CONFIG_SND_SOC_WM8753=m -# CONFIG_SND_SOC_WM8770 is not set -# CONFIG_SND_SOC_WM8776 is not set -# CONFIG_SND_SOC_WM8782 is not set -# CONFIG_SND_SOC_WM8804_I2C is not set -# CONFIG_SND_SOC_WM8804_SPI is not set -CONFIG_SND_SOC_WM8903=m -CONFIG_SND_SOC_WM8960=m -# CONFIG_SND_SOC_WM8962 is not set -# CONFIG_SND_SOC_WM8974 is not set -CONFIG_SND_SOC_WM8978=m -# CONFIG_SND_SOC_WM8985 is not set -# CONFIG_SND_SOC_ZX_AUD96P22 is not set -# CONFIG_SND_SOC_MAX9759 is not set -# CONFIG_SND_SOC_MT6351 is not set -# CONFIG_SND_SOC_NAU8540 is not set -# CONFIG_SND_SOC_NAU8810 is not set -# CONFIG_SND_SOC_NAU8824 is not set -# CONFIG_SND_SOC_TPA6130A2 is not set -# CONFIG_SND_SIMPLE_CARD is not set -# CONFIG_SND_SIMPLE_SCU_CARD is not set -# CONFIG_SND_AUDIO_GRAPH_CARD is not set -# CONFIG_SND_AUDIO_GRAPH_SCU_CARD is not set - -# -# HID support -# -CONFIG_HID=y -# CONFIG_HID_BATTERY_STRENGTH is not set -CONFIG_HIDRAW=y -# CONFIG_UHID is not set -CONFIG_HID_GENERIC=y - -# -# Special HID drivers -# -# CONFIG_HID_A4TECH is not set -# CONFIG_HID_ACCUTOUCH is not set -# CONFIG_HID_ACRUX is not set -# CONFIG_HID_APPLE is not set -# CONFIG_HID_APPLEIR is not set -# CONFIG_HID_ASUS is not set -# CONFIG_HID_AUREAL is not set -# CONFIG_HID_BELKIN is not set -# CONFIG_HID_BETOP_FF is not set -# CONFIG_HID_CHERRY is not set -# CONFIG_HID_CHICONY is not set -# CONFIG_HID_CORSAIR is not set -# CONFIG_HID_COUGAR is not set -# CONFIG_HID_PRODIKEYS is not set -# CONFIG_HID_CMEDIA is not set -CONFIG_HID_CP2112=m -# CONFIG_HID_CYPRESS is not set -# CONFIG_HID_DRAGONRISE is not set -# CONFIG_HID_EMS_FF is not set -# CONFIG_HID_ELAN is not set -# CONFIG_HID_ELECOM is not set -# CONFIG_HID_ELO is not set -# CONFIG_HID_EZKEY is not set -# CONFIG_HID_GEMBIRD is not set -# CONFIG_HID_GFRM is not set -# CONFIG_HID_HOLTEK is not set -# CONFIG_HID_GOOGLE_HAMMER is not set -# CONFIG_HID_GT683R is not set -# CONFIG_HID_KEYTOUCH is not set -# CONFIG_HID_KYE is not set -# CONFIG_HID_UCLOGIC is not set -# CONFIG_HID_WALTOP is not set -# CONFIG_HID_GYRATION is not set -# CONFIG_HID_ICADE is not set -# CONFIG_HID_ITE is not set -# CONFIG_HID_JABRA is not set -# CONFIG_HID_TWINHAN is not set -# CONFIG_HID_KENSINGTON is not set -# CONFIG_HID_LCPOWER is not set -# CONFIG_HID_LED is not set -# CONFIG_HID_LENOVO is not set -# CONFIG_HID_LOGITECH is not set -# CONFIG_HID_MAGICMOUSE is not set -# CONFIG_HID_MAYFLASH is not set -# CONFIG_HID_REDRAGON is not set -# CONFIG_HID_MICROSOFT is not set -# CONFIG_HID_MONTEREY is not set -# CONFIG_HID_MULTITOUCH is not set -# CONFIG_HID_NTI is not set -# CONFIG_HID_NTRIG is not set -# CONFIG_HID_ORTEK is not set -# CONFIG_HID_PANTHERLORD is not set -# CONFIG_HID_PENMOUNT is not set -# CONFIG_HID_PETALYNX is not set -# CONFIG_HID_PICOLCD is not set -# CONFIG_HID_PLANTRONICS is not set -# CONFIG_HID_PRIMAX is not set -# CONFIG_HID_RETRODE is not set -# CONFIG_HID_ROCCAT is not set -# CONFIG_HID_SAITEK is not set -# CONFIG_HID_SAMSUNG is not set -# CONFIG_HID_SONY is not set -# CONFIG_HID_SPEEDLINK is not set -# CONFIG_HID_STEAM is not set -# CONFIG_HID_STEELSERIES is not set -# CONFIG_HID_SUNPLUS is not set -# CONFIG_HID_RMI is not set -# CONFIG_HID_GREENASIA is not set -# CONFIG_HID_SMARTJOYPLUS is not set -# CONFIG_HID_TIVO is not set -# CONFIG_HID_TOPSEED is not set -# CONFIG_HID_THINGM is not set -# CONFIG_HID_THRUSTMASTER is not set -# CONFIG_HID_UDRAW_PS3 is not set -# CONFIG_HID_WACOM is not set -# CONFIG_HID_WIIMOTE is not set -# CONFIG_HID_XINMO is not set -# CONFIG_HID_ZEROPLUS is not set -# CONFIG_HID_ZYDACRON is not set -# CONFIG_HID_SENSOR_HUB is not set -# CONFIG_HID_ALPS is not set - -# -# USB HID support -# -CONFIG_USB_HID=y -# CONFIG_HID_PID is not set -CONFIG_USB_HIDDEV=y - -# -# I2C HID support -# -# CONFIG_I2C_HID is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -CONFIG_USB_SUPPORT=y -CONFIG_USB_COMMON=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB=y -CONFIG_USB_PCI=y -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEFAULT_PERSIST=y -# CONFIG_USB_DYNAMIC_MINORS is not set -CONFIG_USB_OTG=y -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -# CONFIG_USB_OTG_FSM is not set -# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set -# CONFIG_USB_MON 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=y -# CONFIG_USB_XHCI_DBGCAP is not set -CONFIG_USB_XHCI_PCI=y -# CONFIG_USB_XHCI_PLATFORM is not set -CONFIG_USB_XHCI_MTK=y -# CONFIG_USB_EHCI_HCD is not set -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_FOTG210_HCD is not set -# CONFIG_USB_MAX3421_HCD is not set -# CONFIG_USB_OHCI_HCD is not set -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -CONFIG_USB_HCD_BCMA=m -CONFIG_USB_HCD_SSB=m -# CONFIG_USB_HCD_TEST_MODE is not set - -# -# USB Device Class drivers -# -CONFIG_USB_ACM=m -# CONFIG_USB_PRINTER is not set -CONFIG_USB_WDM=m -# 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_REALTEK 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 is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_STORAGE_ENE_UB6250 is not set -CONFIG_USB_UAS=m - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set -CONFIG_USBIP_CORE=m -CONFIG_USBIP_VHCI_HCD=m -CONFIG_USBIP_VHCI_HC_PORTS=8 -CONFIG_USBIP_VHCI_NR_HCS=1 -CONFIG_USBIP_HOST=m -CONFIG_USBIP_VUDC=m -# CONFIG_USBIP_DEBUG is not set -CONFIG_USB_MTU3=m -# CONFIG_USB_MTU3_HOST is not set -# CONFIG_USB_MTU3_GADGET is not set -CONFIG_USB_MTU3_DUAL_ROLE=y -# CONFIG_USB_MTU3_DEBUG is not set -# CONFIG_USB_MUSB_HDRC is not set -# CONFIG_USB_DWC3 is not set -# CONFIG_USB_DWC2 is not set -# CONFIG_USB_CHIPIDEA is not set -# CONFIG_USB_ISP1760 is not set - -# -# USB port drivers -# -CONFIG_USB_USS720=m -CONFIG_USB_SERIAL=y -# CONFIG_USB_SERIAL_CONSOLE is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_SIMPLE is not set -# CONFIG_USB_SERIAL_AIRCABLE is not set -# CONFIG_USB_SERIAL_ARK3116 is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_CH341 is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_CP210X is not set -# CONFIG_USB_SERIAL_CYPRESS_M8 is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT_TI is not set -# CONFIG_USB_SERIAL_F81232 is not set -# CONFIG_USB_SERIAL_F8153X is not set -# CONFIG_USB_SERIAL_GARMIN is not set -# CONFIG_USB_SERIAL_IPW is not set -# CONFIG_USB_SERIAL_IUU is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_KOBIL_SCT is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_METRO is not set -# CONFIG_USB_SERIAL_MOS7720 is not set -# CONFIG_USB_SERIAL_MOS7840 is not set -# CONFIG_USB_SERIAL_MXUPORT is not set -# CONFIG_USB_SERIAL_NAVMAN is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_OTI6858 is not set -# CONFIG_USB_SERIAL_QCAUX is not set -# CONFIG_USB_SERIAL_QUALCOMM is not set -# CONFIG_USB_SERIAL_SPCP8X5 is not set -# CONFIG_USB_SERIAL_SAFE is not set -# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set -# CONFIG_USB_SERIAL_SYMBOL is not set -# CONFIG_USB_SERIAL_TI is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OPTION is not set -# CONFIG_USB_SERIAL_OMNINET is not set -# CONFIG_USB_SERIAL_OPTICON is not set -# CONFIG_USB_SERIAL_XSENS_MT is not set -# CONFIG_USB_SERIAL_WISHBONE is not set -# CONFIG_USB_SERIAL_SSU100 is not set -# CONFIG_USB_SERIAL_QT2 is not set -# CONFIG_USB_SERIAL_UPD78F0730 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_LEGOTOWER is not set -# CONFIG_USB_LCD 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_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_EHSET_TEST_FIXTURE is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_YUREX is not set -# CONFIG_USB_EZUSB_FX2 is not set -# CONFIG_USB_HUB_USB251XB is not set -# CONFIG_USB_HSIC_USB3503 is not set -# CONFIG_USB_HSIC_USB4604 is not set -# CONFIG_USB_LINK_LAYER_TEST is not set -# CONFIG_USB_CHAOSKEY is not set -CONFIG_USB_ATM=m -# CONFIG_USB_SPEEDTOUCH is not set -# CONFIG_USB_CXACRU is not set -# CONFIG_USB_UEAGLEATM is not set -# CONFIG_USB_XUSBATM is not set - -# -# USB Physical Layer drivers -# -CONFIG_USB_PHY=y -CONFIG_NOP_USB_XCEIV=m -CONFIG_AM335X_CONTROL_USB=m -CONFIG_AM335X_PHY_USB=m -CONFIG_USB_GPIO_VBUS=m -CONFIG_USB_ISP1301=y -CONFIG_USB_ULPI=y -CONFIG_USB_ULPI_VIEWPORT=y -CONFIG_USB_GADGET=m -# CONFIG_USB_GADGET_DEBUG is not set -# CONFIG_USB_GADGET_DEBUG_FILES is not set -# CONFIG_USB_GADGET_DEBUG_FS is not set -CONFIG_USB_GADGET_VBUS_DRAW=2 -CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 -# CONFIG_U_SERIAL_CONSOLE is not set - -# -# USB Peripheral Controller -# -# CONFIG_USB_FUSB300 is not set -# CONFIG_USB_FOTG210_UDC is not set -# CONFIG_USB_GR_UDC is not set -# CONFIG_USB_R8A66597 is not set -# CONFIG_USB_PXA27X is not set -# CONFIG_USB_MV_UDC is not set -# CONFIG_USB_MV_U3D is not set -CONFIG_USB_SNP_CORE=m -CONFIG_USB_SNP_UDC_PLAT=m -# CONFIG_USB_M66592 is not set -CONFIG_USB_BDC_UDC=m - -# -# Platform Support -# -# CONFIG_USB_AMD5536UDC is not set -# CONFIG_USB_NET2272 is not set -# CONFIG_USB_NET2280 is not set -# CONFIG_USB_GOKU is not set -# CONFIG_USB_EG20T is not set -# CONFIG_USB_GADGET_XILINX is not set -# CONFIG_USB_DUMMY_HCD is not set -CONFIG_USB_LIBCOMPOSITE=m -CONFIG_USB_F_ACM=m -CONFIG_USB_F_SS_LB=m -CONFIG_USB_U_SERIAL=m -CONFIG_USB_U_ETHER=m -CONFIG_USB_U_AUDIO=m -CONFIG_USB_F_SERIAL=m -CONFIG_USB_F_OBEX=m -CONFIG_USB_F_NCM=m -CONFIG_USB_F_ECM=m -CONFIG_USB_F_EEM=m -CONFIG_USB_F_SUBSET=m -CONFIG_USB_F_RNDIS=m -CONFIG_USB_F_MASS_STORAGE=m -CONFIG_USB_F_FS=m -CONFIG_USB_F_UAC1=m -CONFIG_USB_F_UAC1_LEGACY=m -CONFIG_USB_F_UAC2=m -CONFIG_USB_F_UVC=m -CONFIG_USB_F_MIDI=m -CONFIG_USB_F_HID=m -CONFIG_USB_F_PRINTER=m -CONFIG_USB_F_TCM=m -CONFIG_USB_CONFIGFS=m -CONFIG_USB_CONFIGFS_SERIAL=y -CONFIG_USB_CONFIGFS_ACM=y -CONFIG_USB_CONFIGFS_OBEX=y -CONFIG_USB_CONFIGFS_NCM=y -CONFIG_USB_CONFIGFS_ECM=y -CONFIG_USB_CONFIGFS_ECM_SUBSET=y -CONFIG_USB_CONFIGFS_RNDIS=y -CONFIG_USB_CONFIGFS_EEM=y -CONFIG_USB_CONFIGFS_MASS_STORAGE=y -CONFIG_USB_CONFIGFS_F_LB_SS=y -CONFIG_USB_CONFIGFS_F_FS=y -CONFIG_USB_CONFIGFS_F_UAC1=y -CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y -CONFIG_USB_CONFIGFS_F_UAC2=y -CONFIG_USB_CONFIGFS_F_MIDI=y -CONFIG_USB_CONFIGFS_F_HID=y -CONFIG_USB_CONFIGFS_F_UVC=y -CONFIG_USB_CONFIGFS_F_PRINTER=y -# CONFIG_USB_CONFIGFS_F_TCM is not set -# CONFIG_USB_ZERO is not set -# CONFIG_USB_AUDIO is not set -CONFIG_USB_ETH=m -CONFIG_USB_ETH_RNDIS=y -# CONFIG_USB_ETH_EEM is not set -# CONFIG_USB_G_NCM is not set -# CONFIG_USB_GADGETFS is not set -# CONFIG_USB_FUNCTIONFS is not set -# CONFIG_USB_MASS_STORAGE is not set -CONFIG_USB_GADGET_TARGET=m -# CONFIG_USB_G_SERIAL is not set -# CONFIG_USB_MIDI_GADGET is not set -# CONFIG_USB_G_PRINTER is not set -# CONFIG_USB_CDC_COMPOSITE is not set -# CONFIG_USB_G_ACM_MS is not set -# CONFIG_USB_G_MULTI is not set -# CONFIG_USB_G_HID is not set -# CONFIG_USB_G_DBGP is not set -# CONFIG_USB_G_WEBCAM is not set -# CONFIG_TYPEC is not set -CONFIG_USB_ROLE_SWITCH=m -# CONFIG_USB_LED_TRIG is not set -# CONFIG_USB_ULPI_BUS is not set -# CONFIG_UWB is not set -CONFIG_MMC=y -CONFIG_PWRSEQ_EMMC=y -# CONFIG_PWRSEQ_SD8787 is not set -CONFIG_PWRSEQ_SIMPLE=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=16 -# CONFIG_SDIO_UART is not set -# CONFIG_MMC_TEST is not set - -# -# MMC/SD/SDIO Host Controller Drivers -# -# CONFIG_MMC_DEBUG is not set -# 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_MMC_DW is not set -# CONFIG_MMC_VUB300 is not set -# CONFIG_MMC_USHC is not set -# CONFIG_MMC_USDHI6ROL0 is not set -# CONFIG_MMC_CQHCI is not set -# CONFIG_MMC_TOSHIBA_PCI is not set -CONFIG_MMC_MTK=y -# CONFIG_MEMSTICK is not set -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_CLASS_FLASH=m -# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set - -# -# LED drivers -# -# CONFIG_LEDS_AAT1290 is not set -# CONFIG_LEDS_AS3645A is not set -# CONFIG_LEDS_BCM6328 is not set -# CONFIG_LEDS_BCM6358 is not set -# CONFIG_LEDS_CR0014114 is not set -# CONFIG_LEDS_LM3530 is not set -# CONFIG_LEDS_LM3642 is not set -# CONFIG_LEDS_LM3692X is not set -# CONFIG_LEDS_LM3601X is not set -CONFIG_LEDS_MT6323=y -# CONFIG_LEDS_PCA9532 is not set -CONFIG_LEDS_GPIO=y -# CONFIG_LEDS_LP3944 is not set -# CONFIG_LEDS_LP3952 is not set -# CONFIG_LEDS_LP5521 is not set -# CONFIG_LEDS_LP5523 is not set -# CONFIG_LEDS_LP5562 is not set -# CONFIG_LEDS_LP8501 is not set -# CONFIG_LEDS_LP8860 is not set -# CONFIG_LEDS_PCA955X is not set -CONFIG_LEDS_PCA963X=y -# CONFIG_LEDS_DAC124S085 is not set -CONFIG_LEDS_PWM=y -# CONFIG_LEDS_REGULATOR is not set -# CONFIG_LEDS_BD2802 is not set -# CONFIG_LEDS_LT3593 is not set -# CONFIG_LEDS_TCA6507 is not set -# CONFIG_LEDS_TLC591XX is not set -# CONFIG_LEDS_LM355x is not set -# CONFIG_LEDS_KTD2692 is not set -# CONFIG_LEDS_IS31FL319X is not set -# CONFIG_LEDS_IS31FL32XX is not set - -# -# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) -# -# CONFIG_LEDS_BLINKM is not set -# CONFIG_LEDS_SYSCON is not set -# CONFIG_LEDS_MLXREG is not set -# CONFIG_LEDS_USER is not set - -# -# LED Triggers -# -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_TIMER=y -CONFIG_LEDS_TRIGGER_ONESHOT=y -# CONFIG_LEDS_TRIGGER_DISK is not set -# CONFIG_LEDS_TRIGGER_MTD is not set -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_LEDS_TRIGGER_BACKLIGHT=y -CONFIG_LEDS_TRIGGER_CPU=y -# CONFIG_LEDS_TRIGGER_ACTIVITY is not set -CONFIG_LEDS_TRIGGER_GPIO=y -CONFIG_LEDS_TRIGGER_DEFAULT_ON=y - -# -# iptables trigger is under Netfilter config (LED target) -# -CONFIG_LEDS_TRIGGER_TRANSIENT=y -CONFIG_LEDS_TRIGGER_CAMERA=y -# CONFIG_LEDS_TRIGGER_PANIC is not set -# CONFIG_LEDS_TRIGGER_NETDEV is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_INFINIBAND is not set -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EDAC=y -CONFIG_EDAC_LEGACY_SYSFS=y -# CONFIG_EDAC_DEBUG is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -CONFIG_RTC_SYSTOHC=y -CONFIG_RTC_SYSTOHC_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set -CONFIG_RTC_NVMEM=y - -# -# 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_ABB5ZES3 is not set -# CONFIG_RTC_DRV_ABX80X is not set -CONFIG_RTC_DRV_DS1307=y -CONFIG_RTC_DRV_DS1307_CENTURY=y -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -CONFIG_RTC_DRV_HYM8563=m -# CONFIG_RTC_DRV_MAX6900 is not set -CONFIG_RTC_DRV_RS5C372=m -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_ISL12022 is not set -# CONFIG_RTC_DRV_ISL12026 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8523 is not set -# CONFIG_RTC_DRV_PCF85063 is not set -# CONFIG_RTC_DRV_PCF85363 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_BQ32K=m -CONFIG_RTC_DRV_TWL4030=y -CONFIG_RTC_DRV_S35390A=m -# CONFIG_RTC_DRV_FM3130 is not set -# CONFIG_RTC_DRV_RX8010 is not set -CONFIG_RTC_DRV_RX8581=m -# CONFIG_RTC_DRV_RX8025 is not set -CONFIG_RTC_DRV_EM3027=y -# CONFIG_RTC_DRV_RV8803 is not set - -# -# SPI RTC drivers -# -# CONFIG_RTC_DRV_M41T93 is not set -# CONFIG_RTC_DRV_M41T94 is not set -# CONFIG_RTC_DRV_DS1302 is not set -# CONFIG_RTC_DRV_DS1305 is not set -# CONFIG_RTC_DRV_DS1343 is not set -# CONFIG_RTC_DRV_DS1347 is not set -# CONFIG_RTC_DRV_DS1390 is not set -# CONFIG_RTC_DRV_MAX6916 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RX4581 is not set -# CONFIG_RTC_DRV_RX6110 is not set -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_PCF2123 is not set -# CONFIG_RTC_DRV_MCP795 is not set -CONFIG_RTC_I2C_AND_SPI=y - -# -# SPI and I2C RTC drivers -# -# CONFIG_RTC_DRV_DS3232 is not set -# CONFIG_RTC_DRV_PCF2127 is not set -# CONFIG_RTC_DRV_RV3029C2 is not set - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1685_FAMILY is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_DS2404 is not set -CONFIG_RTC_DRV_EFI=m -# 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_MSM6242 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_V3020 is not set -# CONFIG_RTC_DRV_ZYNQMP is not set - -# -# on-CPU RTC drivers -# -# CONFIG_RTC_DRV_FTRTC010 is not set -# CONFIG_RTC_DRV_SNVS is not set -CONFIG_RTC_DRV_MT6397=y -# CONFIG_RTC_DRV_MT7622 is not set -# CONFIG_RTC_DRV_R7301 is not set - -# -# HID Sensor RTC drivers -# -# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set -CONFIG_DMADEVICES=y -# CONFIG_DMADEVICES_DEBUG is not set - -# -# DMA Devices -# -CONFIG_DMA_ENGINE=y -CONFIG_DMA_VIRTUAL_CHANNELS=y -CONFIG_DMA_OF=y -# CONFIG_ALTERA_MSGDMA is not set -# CONFIG_DW_AXI_DMAC is not set -# CONFIG_FSL_EDMA is not set -# CONFIG_INTEL_IDMA64 is not set -# CONFIG_NBPFAXI_DMA is not set -CONFIG_MTK_HSDMA=y -# CONFIG_QCOM_HIDMA_MGMT is not set -# CONFIG_QCOM_HIDMA is not set -# CONFIG_DW_DMAC is not set -# CONFIG_DW_DMAC_PCI is not set - -# -# DMA Clients -# -# CONFIG_ASYNC_TX_DMA is not set -CONFIG_DMATEST=m -CONFIG_DMA_ENGINE_RAID=y - -# -# DMABUF options -# -CONFIG_SYNC_FILE=y -# CONFIG_SW_SYNC is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_PANEL is not set -# CONFIG_UIO is not set -# CONFIG_VFIO is not set -# CONFIG_VIRT_DRIVERS is not set -CONFIG_VIRTIO=y -CONFIG_VIRTIO_MENU=y -CONFIG_VIRTIO_PCI=y -CONFIG_VIRTIO_PCI_LEGACY=y -# CONFIG_VIRTIO_BALLOON is not set -# CONFIG_VIRTIO_INPUT is not set -CONFIG_VIRTIO_MMIO=y -# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set - -# -# Microsoft Hyper-V guest support -# -CONFIG_STAGING=y -# CONFIG_PRISM2_USB is not set -# CONFIG_COMEDI is not set -# CONFIG_RTL8192U is not set -# CONFIG_RTLLIB is not set -# CONFIG_RTL8723BS is not set -# CONFIG_R8712U is not set -# CONFIG_R8188EU is not set -# CONFIG_R8822BE is not set -# CONFIG_RTS5208 is not set -# CONFIG_VT6655 is not set -# CONFIG_VT6656 is not set - -# -# IIO staging drivers -# - -# -# Accelerometers -# -# CONFIG_ADIS16203 is not set -# CONFIG_ADIS16240 is not set - -# -# Analog to digital converters -# -# CONFIG_AD7606 is not set -# CONFIG_AD7780 is not set -# CONFIG_AD7816 is not set -# CONFIG_AD7192 is not set -# CONFIG_AD7280 is not set - -# -# Analog digital bi-direction converters -# -# CONFIG_ADT7316 is not set - -# -# Capacitance to digital converters -# -# CONFIG_AD7150 is not set -# CONFIG_AD7152 is not set -# CONFIG_AD7746 is not set - -# -# Direct Digital Synthesis -# -# CONFIG_AD9832 is not set -# CONFIG_AD9834 is not set - -# -# Network Analyzer, Impedance Converters -# -# CONFIG_AD5933 is not set - -# -# Active energy metering IC -# -# CONFIG_ADE7854 is not set - -# -# Resolver to digital converters -# -# CONFIG_AD2S90 is not set -# CONFIG_AD2S1210 is not set -# CONFIG_FB_SM750 is not set -# CONFIG_FB_XGI is not set - -# -# Speakup console speech -# -# CONFIG_SPEAKUP is not set -# CONFIG_STAGING_MEDIA is not set - -# -# Android -# -CONFIG_STAGING_BOARD=y -# CONFIG_LTE_GDM724X is not set -# CONFIG_MTD_SPINAND_MT29F is not set -# CONFIG_DGNC is not set -# CONFIG_GS_FPGABOOT is not set -# CONFIG_UNISYSSPAR is not set -# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set -# CONFIG_FB_TFT is not set -# CONFIG_WILC1000_SDIO is not set -# CONFIG_WILC1000_SPI is not set -# CONFIG_MOST is not set -# CONFIG_KS7010 is not set -# CONFIG_GREYBUS is not set -# CONFIG_PI433 is not set - -# -# Gasket devices -# -CONFIG_XIL_AXIS_FIFO=m -# CONFIG_EROFS_FS is not set -# CONFIG_GOLDFISH is not set -CONFIG_CHROME_PLATFORMS=y -# CONFIG_MELLANOX_PLATFORM is not set -CONFIG_CLKDEV_LOOKUP=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_COMMON_CLK=y - -# -# Common Clock Framework -# -# CONFIG_CLK_HSDK is not set -CONFIG_COMMON_CLK_MAX9485=m -# CONFIG_COMMON_CLK_SI5351 is not set -# CONFIG_COMMON_CLK_SI514 is not set -# CONFIG_COMMON_CLK_SI544 is not set -# CONFIG_COMMON_CLK_SI570 is not set -# CONFIG_COMMON_CLK_CDCE706 is not set -# CONFIG_COMMON_CLK_CDCE925 is not set -# CONFIG_COMMON_CLK_CS2000_CP is not set -# CONFIG_CLK_QORIQ is not set -# CONFIG_COMMON_CLK_PWM is not set -# CONFIG_COMMON_CLK_VC5 is not set - -# -# Clock driver for MediaTek SoC -# -CONFIG_COMMON_CLK_MEDIATEK=y -CONFIG_COMMON_CLK_MT2701=y -CONFIG_COMMON_CLK_MT2701_MMSYS=y -CONFIG_COMMON_CLK_MT2701_IMGSYS=y -CONFIG_COMMON_CLK_MT2701_VDECSYS=y -CONFIG_COMMON_CLK_MT2701_HIFSYS=y -CONFIG_COMMON_CLK_MT2701_ETHSYS=y -CONFIG_COMMON_CLK_MT2701_BDPSYS=y -CONFIG_COMMON_CLK_MT2701_AUDSYS=y -CONFIG_COMMON_CLK_MT2701_G3DSYS=y -CONFIG_COMMON_CLK_MT7622=y -# CONFIG_COMMON_CLK_MT7622_ETHSYS is not set -# CONFIG_COMMON_CLK_MT7622_HIFSYS is not set -# CONFIG_COMMON_CLK_MT7622_AUDSYS is not set -CONFIG_COMMON_CLK_MT8135=y -CONFIG_COMMON_CLK_MT8173=y -# CONFIG_HWSPINLOCK is not set - -# -# Clock Source drivers -# -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_CLKSRC_MMIO=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_TIMER_SP804=y -CONFIG_MTK_TIMER=y -CONFIG_CLKSRC_VERSATILE=y -CONFIG_MAILBOX=y -# CONFIG_PLATFORM_MHU is not set -# CONFIG_ALTERA_MBOX is not set -# CONFIG_MAILBOX_TEST is not set -CONFIG_MTK_CMDQ_MBOX=m -CONFIG_IOMMU_API=y -CONFIG_IOMMU_SUPPORT=y - -# -# Generic IOMMU Pagetable Support -# -CONFIG_IOMMU_IO_PGTABLE=y -# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set -CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y -# CONFIG_IOMMU_IO_PGTABLE_ARMV7S_SELFTEST is not set -# CONFIG_IOMMU_DEBUGFS is not set -# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set -CONFIG_IOMMU_IOVA=y -CONFIG_OF_IOMMU=y -CONFIG_IOMMU_DMA=y -# CONFIG_ARM_SMMU is not set -CONFIG_MTK_IOMMU=y -# CONFIG_MTK_IOMMU_V1 is not set - -# -# Remoteproc drivers -# -CONFIG_REMOTEPROC=m - -# -# Rpmsg drivers -# -CONFIG_RPMSG=m -# CONFIG_RPMSG_CHAR is not set -# CONFIG_RPMSG_QCOM_GLINK_RPM is not set -CONFIG_RPMSG_VIRTIO=m - -# -# SOC (System On Chip) specific Drivers -# - -# -# Amlogic SoC drivers -# - -# -# Broadcom SoC drivers -# -CONFIG_SOC_BRCMSTB=y - -# -# NXP/Freescale QorIQ SoC drivers -# - -# -# i.MX SoC drivers -# - -# -# MediaTek SoC drivers -# -CONFIG_MTK_INFRACFG=y -CONFIG_MTK_PMIC_WRAP=y -CONFIG_MTK_SCPSYS=y - -# -# Qualcomm SoC drivers -# -# CONFIG_SOC_TI is not set - -# -# Xilinx SoC drivers -# -# CONFIG_XILINX_VCU is not set -CONFIG_PM_DEVFREQ=y - -# -# DEVFREQ Governors -# -CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=m -# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set -# CONFIG_DEVFREQ_GOV_POWERSAVE is not set -# CONFIG_DEVFREQ_GOV_USERSPACE is not set -# CONFIG_DEVFREQ_GOV_PASSIVE is not set - -# -# DEVFREQ Drivers -# -# CONFIG_PM_DEVFREQ_EVENT is not set -CONFIG_EXTCON=y - -# -# Extcon Device Drivers -# -# CONFIG_EXTCON_ADC_JACK is not set -# CONFIG_EXTCON_GPIO is not set -# CONFIG_EXTCON_MAX3355 is not set -# CONFIG_EXTCON_RT8973A is not set -# CONFIG_EXTCON_SM5502 is not set -# CONFIG_EXTCON_USB_GPIO is not set -CONFIG_MEMORY=y -CONFIG_MTK_SMI=y -CONFIG_IIO=y -CONFIG_IIO_BUFFER=y -# CONFIG_IIO_BUFFER_CB is not set -# CONFIG_IIO_BUFFER_HW_CONSUMER is not set -CONFIG_IIO_KFIFO_BUF=y -CONFIG_IIO_TRIGGERED_BUFFER=y -CONFIG_IIO_CONFIGFS=y -CONFIG_IIO_TRIGGER=y -CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 -# CONFIG_IIO_SW_DEVICE is not set -CONFIG_IIO_SW_TRIGGER=y - -# -# Accelerometers -# -# CONFIG_ADIS16201 is not set -# CONFIG_ADIS16209 is not set -# CONFIG_BMA180 is not set -# CONFIG_BMA220 is not set -# CONFIG_BMC150_ACCEL is not set -# CONFIG_DA280 is not set -# CONFIG_DA311 is not set -# CONFIG_DMARD06 is not set -# CONFIG_DMARD09 is not set -# CONFIG_DMARD10 is not set -# CONFIG_IIO_CROS_EC_ACCEL_LEGACY is not set -# CONFIG_IIO_ST_ACCEL_3AXIS is not set -# CONFIG_KXSD9 is not set -# CONFIG_KXCJK1013 is not set -# CONFIG_MC3230 is not set -# CONFIG_MMA7455_I2C is not set -# CONFIG_MMA7455_SPI is not set -# CONFIG_MMA7660 is not set -# CONFIG_MMA8452 is not set -# CONFIG_MMA9551 is not set -# CONFIG_MMA9553 is not set -# CONFIG_MXC4005 is not set -# CONFIG_MXC6255 is not set -# CONFIG_SCA3000 is not set -# CONFIG_STK8312 is not set -# CONFIG_STK8BA50 is not set - -# -# Analog to digital converters -# -# CONFIG_AD7266 is not set -# CONFIG_AD7291 is not set -# CONFIG_AD7298 is not set -# CONFIG_AD7476 is not set -# CONFIG_AD7766 is not set -# CONFIG_AD7791 is not set -# CONFIG_AD7793 is not set -# CONFIG_AD7887 is not set -# CONFIG_AD7923 is not set -# CONFIG_AD799X is not set -# CONFIG_CC10001_ADC is not set -# CONFIG_ENVELOPE_DETECTOR is not set -# CONFIG_HI8435 is not set -# CONFIG_HX711 is not set -# CONFIG_INA2XX_ADC is not set -# CONFIG_LTC2471 is not set -# CONFIG_LTC2485 is not set -# CONFIG_LTC2497 is not set -# CONFIG_MAX1027 is not set -# CONFIG_MAX11100 is not set -# CONFIG_MAX1118 is not set -# CONFIG_MAX1363 is not set -# CONFIG_MAX9611 is not set -# CONFIG_MCP320X is not set -# CONFIG_MCP3422 is not set -CONFIG_MEDIATEK_MT6577_AUXADC=m -# CONFIG_NAU7802 is not set -# CONFIG_QCOM_SPMI_IADC is not set -# CONFIG_QCOM_SPMI_VADC is not set -# CONFIG_SD_ADC_MODULATOR is not set -# CONFIG_TI_ADC081C is not set -# CONFIG_TI_ADC0832 is not set -# CONFIG_TI_ADC084S021 is not set -# CONFIG_TI_ADC12138 is not set -# CONFIG_TI_ADC108S102 is not set -# CONFIG_TI_ADC128S052 is not set -# CONFIG_TI_ADC161S626 is not set -# CONFIG_TI_ADS1015 is not set -# CONFIG_TI_ADS7950 is not set -# CONFIG_TI_ADS8688 is not set -# CONFIG_TI_TLC4541 is not set -# CONFIG_TWL4030_MADC is not set -# CONFIG_TWL6030_GPADC is not set -CONFIG_VF610_ADC=m - -# -# Analog to digital and digital to analog converters -# - -# -# Analog Front Ends -# -# CONFIG_IIO_RESCALE is not set - -# -# Amplifiers -# -# CONFIG_AD8366 is not set - -# -# Chemical Sensors -# -# CONFIG_ATLAS_PH_SENSOR is not set -CONFIG_BME680=m -CONFIG_BME680_I2C=m -CONFIG_BME680_SPI=m -# CONFIG_CCS811 is not set -# CONFIG_IAQCORE is not set -# CONFIG_VZ89X is not set - -# -# Hid Sensor IIO Common -# - -# -# SSP Sensor Common -# -# CONFIG_IIO_SSP_SENSORHUB is not set - -# -# Counters -# - -# -# Digital to analog converters -# -# CONFIG_AD5064 is not set -# CONFIG_AD5360 is not set -# CONFIG_AD5380 is not set -# CONFIG_AD5421 is not set -# CONFIG_AD5446 is not set -# CONFIG_AD5449 is not set -# CONFIG_AD5592R is not set -# CONFIG_AD5593R is not set -# CONFIG_AD5504 is not set -# CONFIG_AD5624R_SPI is not set -# CONFIG_LTC2632 is not set -# CONFIG_AD5686_SPI is not set -# CONFIG_AD5696_I2C is not set -# CONFIG_AD5755 is not set -CONFIG_AD5758=m -# CONFIG_AD5761 is not set -# CONFIG_AD5764 is not set -# CONFIG_AD5791 is not set -# CONFIG_AD7303 is not set -# CONFIG_AD8801 is not set -# CONFIG_DPOT_DAC is not set -# CONFIG_DS4424 is not set -# CONFIG_M62332 is not set -# CONFIG_MAX517 is not set -# CONFIG_MAX5821 is not set -# CONFIG_MCP4725 is not set -# CONFIG_MCP4922 is not set -# CONFIG_TI_DAC082S085 is not set -# CONFIG_TI_DAC5571 is not set -# CONFIG_VF610_DAC is not set - -# -# IIO dummy driver -# - -# -# Frequency Synthesizers DDS/PLL -# - -# -# Clock Generator/Distribution -# -# CONFIG_AD9523 is not set - -# -# Phase-Locked Loop (PLL) frequency synthesizers -# -# CONFIG_ADF4350 is not set - -# -# Digital gyroscope sensors -# -# CONFIG_ADIS16080 is not set -# CONFIG_ADIS16130 is not set -# CONFIG_ADIS16136 is not set -# CONFIG_ADIS16260 is not set -# CONFIG_ADXRS450 is not set -# CONFIG_BMG160 is not set -CONFIG_MPU3050=y -CONFIG_MPU3050_I2C=y -# CONFIG_IIO_ST_GYRO_3AXIS is not set -# CONFIG_ITG3200 is not set - -# -# Health Sensors -# - -# -# Heart Rate Monitors -# -# CONFIG_AFE4403 is not set -# CONFIG_AFE4404 is not set -# CONFIG_MAX30100 is not set -# CONFIG_MAX30102 is not set - -# -# Humidity sensors -# -# CONFIG_AM2315 is not set -# CONFIG_DHT11 is not set -# CONFIG_HDC100X is not set -# CONFIG_HTS221 is not set -# CONFIG_HTU21 is not set -# CONFIG_SI7005 is not set -# CONFIG_SI7020 is not set - -# -# Inertial measurement units -# -# CONFIG_ADIS16400 is not set -# CONFIG_ADIS16480 is not set -# CONFIG_BMI160_I2C is not set -# CONFIG_BMI160_SPI is not set -# CONFIG_KMX61 is not set -# CONFIG_INV_MPU6050_I2C is not set -# CONFIG_INV_MPU6050_SPI is not set -# CONFIG_IIO_ST_LSM6DSX is not set - -# -# Light sensors -# -# CONFIG_ADJD_S311 is not set -# CONFIG_AL3320A is not set -# CONFIG_APDS9300 is not set -# CONFIG_APDS9960 is not set -# CONFIG_BH1750 is not set -# CONFIG_BH1780 is not set -# CONFIG_CM32181 is not set -# CONFIG_CM3232 is not set -# CONFIG_CM3323 is not set -# CONFIG_CM3605 is not set -CONFIG_CM36651=m -# CONFIG_GP2AP020A00F is not set -CONFIG_SENSORS_ISL29018=y -CONFIG_SENSORS_ISL29028=y -# CONFIG_ISL29125 is not set -# CONFIG_JSA1212 is not set -# CONFIG_RPR0521 is not set -# CONFIG_LTR501 is not set -# CONFIG_LV0104CS is not set -# CONFIG_MAX44000 is not set -# CONFIG_OPT3001 is not set -# CONFIG_PA12203001 is not set -CONFIG_SI1133=m -# CONFIG_SI1145 is not set -# CONFIG_STK3310 is not set -# CONFIG_ST_UVIS25 is not set -# CONFIG_TCS3414 is not set -# CONFIG_TCS3472 is not set -# CONFIG_SENSORS_TSL2563 is not set -# CONFIG_TSL2583 is not set -# CONFIG_TSL2772 is not set -# CONFIG_TSL4531 is not set -# CONFIG_US5182D is not set -# CONFIG_VCNL4000 is not set -# CONFIG_VEML6070 is not set -# CONFIG_VL6180 is not set -# CONFIG_ZOPT2201 is not set - -# -# Magnetometer sensors -# -# CONFIG_AK8974 is not set -CONFIG_AK8975=y -# CONFIG_AK09911 is not set -# CONFIG_BMC150_MAGN_I2C is not set -# CONFIG_BMC150_MAGN_SPI is not set -# CONFIG_MAG3110 is not set -# CONFIG_MMC35240 is not set -# CONFIG_IIO_ST_MAGN_3AXIS is not set -# CONFIG_SENSORS_HMC5843_I2C is not set -# CONFIG_SENSORS_HMC5843_SPI is not set - -# -# Multiplexers -# -# CONFIG_IIO_MUX is not set - -# -# Inclinometer sensors -# - -# -# Triggers - standalone -# -CONFIG_IIO_HRTIMER_TRIGGER=y -# CONFIG_IIO_INTERRUPT_TRIGGER is not set -# CONFIG_IIO_TIGHTLOOP_TRIGGER is not set -# CONFIG_IIO_SYSFS_TRIGGER is not set - -# -# Digital potentiometers -# -# CONFIG_AD5272 is not set -# CONFIG_DS1803 is not set -# CONFIG_MAX5481 is not set -# CONFIG_MAX5487 is not set -# CONFIG_MCP4018 is not set -# CONFIG_MCP4131 is not set -# CONFIG_MCP4531 is not set -# CONFIG_TPL0102 is not set - -# -# Digital potentiostats -# -# CONFIG_LMP91000 is not set - -# -# Pressure sensors -# -# CONFIG_ABP060MG is not set -# CONFIG_BMP280 is not set -# CONFIG_HP03 is not set -# CONFIG_MPL115_I2C is not set -# CONFIG_MPL115_SPI is not set -# CONFIG_MPL3115 is not set -# CONFIG_MS5611 is not set -# CONFIG_MS5637 is not set -# CONFIG_IIO_ST_PRESS is not set -# CONFIG_T5403 is not set -# CONFIG_HP206C is not set -# CONFIG_ZPA2326 is not set - -# -# Lightning sensors -# -# CONFIG_AS3935 is not set - -# -# Proximity and distance sensors -# -CONFIG_ISL29501=m -# CONFIG_LIDAR_LITE_V2 is not set -# CONFIG_RFD77402 is not set -# CONFIG_SRF04 is not set -# CONFIG_SX9500 is not set -# CONFIG_SRF08 is not set - -# -# Resolver to digital converters -# -# CONFIG_AD2S1200 is not set - -# -# Temperature sensors -# -# CONFIG_MAXIM_THERMOCOUPLE is not set -# CONFIG_MLX90614 is not set -# CONFIG_MLX90632 is not set -# CONFIG_TMP006 is not set -# CONFIG_TMP007 is not set -# CONFIG_TSYS01 is not set -# CONFIG_TSYS02D is not set -# CONFIG_NTB is not set -# CONFIG_VME_BUS is not set -CONFIG_PWM=y -CONFIG_PWM_SYSFS=y -# CONFIG_PWM_FSL_FTM is not set -# CONFIG_PWM_MTK_DISP is not set -CONFIG_PWM_MEDIATEK=m -# CONFIG_PWM_PCA9685 is not set -# CONFIG_PWM_TWL is not set -# CONFIG_PWM_TWL_LED is not set - -# -# IRQ chip support -# -CONFIG_IRQCHIP=y -CONFIG_ARM_GIC=y -CONFIG_ARM_GIC_MAX_NR=1 -# CONFIG_IPACK_BUS is not set -CONFIG_RESET_CONTROLLER=y -# CONFIG_RESET_TI_SYSCON is not set -# CONFIG_FMC is not set - -# -# PHY Subsystem -# -CONFIG_GENERIC_PHY=y -# CONFIG_BCM_KONA_USB2_PHY is not set -# CONFIG_PHY_PXA_28NM_HSIC is not set -# CONFIG_PHY_PXA_28NM_USB2 is not set -CONFIG_PHY_MTK_TPHY=y -CONFIG_PHY_MTK_XSPHY=y -# CONFIG_PHY_CPCAP_USB is not set -# CONFIG_PHY_MAPPHONE_MDM6600 is not set -# CONFIG_POWERCAP is not set -# CONFIG_MCB is not set - -# -# Performance monitor support -# -# CONFIG_ARM_CCI_PMU is not set -# CONFIG_ARM_CCN is not set -CONFIG_ARM_PMU=y -CONFIG_RAS=y - -# -# Android -# -# CONFIG_ANDROID is not set -# CONFIG_DAX is not set -CONFIG_NVMEM=y -CONFIG_MTK_EFUSE=m - -# -# HW tracing support -# -# CONFIG_STM is not set -# CONFIG_INTEL_TH is not set -# CONFIG_FPGA is not set -# CONFIG_FSI is not set -# CONFIG_TEE is not set -CONFIG_MULTIPLEXER=m - -# -# Multiplexer drivers -# -# CONFIG_MUX_ADG792A is not set -# CONFIG_MUX_ADGS1408 is not set -# CONFIG_MUX_GPIO is not set -# CONFIG_MUX_MMIO is not set -CONFIG_PM_OPP=y -# CONFIG_SIOX is not set -# CONFIG_SLIMBUS is not set - -# -# File systems -# -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_FS_IOMAP=y -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -CONFIG_EXT4_FS=y -CONFIG_EXT4_USE_FOR_EXT2=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -# CONFIG_EXT4_ENCRYPTION is not set -# CONFIG_EXT4_DEBUG is not set -CONFIG_JBD2=y -# CONFIG_JBD2_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_XFS_FS=m -# CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_POSIX_ACL is not set -# CONFIG_XFS_RT is not set -# CONFIG_XFS_ONLINE_SCRUB is not set -# CONFIG_XFS_WARN is not set -# CONFIG_XFS_DEBUG is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -CONFIG_BTRFS_FS=y -# CONFIG_BTRFS_FS_POSIX_ACL is not set -# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set -# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set -# CONFIG_BTRFS_DEBUG is not set -# CONFIG_BTRFS_ASSERT is not set -# CONFIG_BTRFS_FS_REF_VERIFY is not set -# CONFIG_NILFS2_FS is not set -CONFIG_F2FS_FS=m -CONFIG_F2FS_STAT_FS=y -CONFIG_F2FS_FS_XATTR=y -CONFIG_F2FS_FS_POSIX_ACL=y -# CONFIG_F2FS_FS_SECURITY is not set -# CONFIG_F2FS_CHECK_FS is not set -# CONFIG_F2FS_FS_ENCRYPTION is not set -# CONFIG_F2FS_FAULT_INJECTION is not set -CONFIG_FS_POSIX_ACL=y -CONFIG_EXPORTFS=y -CONFIG_EXPORTFS_BLOCK_OPS=y -CONFIG_FILE_LOCKING=y -CONFIG_MANDATORY_FILE_LOCKING=y -# CONFIG_FS_ENCRYPTION is not set -CONFIG_FSNOTIFY=y -CONFIG_DNOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_FANOTIFY is not set -# CONFIG_QUOTA is not set -CONFIG_AUTOFS4_FS=y -CONFIG_AUTOFS_FS=y -CONFIG_FUSE_FS=y -# CONFIG_CUSE is not set -CONFIG_OVERLAY_FS=y -# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set -CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y -# CONFIG_OVERLAY_FS_INDEX is not set -# CONFIG_OVERLAY_FS_XINO_AUTO is not set -# CONFIG_OVERLAY_FS_METACOPY is not set - -# -# Caches -# -# CONFIG_FSCACHE is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_FAT_DEFAULT_UTF8 is not set -CONFIG_NTFS_FS=y -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y -CONFIG_PROC_PAGE_MONITOR=y -# CONFIG_PROC_CHILDREN is not set -CONFIG_KERNFS=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_TMPFS_XATTR=y -CONFIG_MEMFD_CREATE=y -CONFIG_CONFIGFS_FS=y -CONFIG_EFIVAR_FS=m -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ORANGEFS_FS is not set -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_ECRYPT_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_UBIFS_FS=y -# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -CONFIG_UBIFS_FS_LZO=y -CONFIG_UBIFS_FS_ZLIB=y -# CONFIG_UBIFS_ATIME_SUPPORT is not set -CONFIG_UBIFS_FS_XATTR=y -# CONFIG_UBIFS_FS_ENCRYPTION is not set -CONFIG_UBIFS_FS_SECURITY=y -# CONFIG_CRAMFS is not set -CONFIG_SQUASHFS=y -CONFIG_SQUASHFS_FILE_CACHE=y -# CONFIG_SQUASHFS_FILE_DIRECT is not set -CONFIG_SQUASHFS_DECOMP_SINGLE=y -# CONFIG_SQUASHFS_DECOMP_MULTI is not set -# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set -# CONFIG_SQUASHFS_XATTR is not set -CONFIG_SQUASHFS_ZLIB=y -# CONFIG_SQUASHFS_LZ4 is not set -CONFIG_SQUASHFS_LZO=y -CONFIG_SQUASHFS_XZ=y -# CONFIG_SQUASHFS_ZSTD is not set -# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX6FS_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_PSTORE=y -CONFIG_PSTORE_DEFLATE_COMPRESS=y -# CONFIG_PSTORE_LZO_COMPRESS is not set -# CONFIG_PSTORE_LZ4_COMPRESS is not set -# CONFIG_PSTORE_LZ4HC_COMPRESS is not set -# CONFIG_PSTORE_842_COMPRESS is not set -# CONFIG_PSTORE_ZSTD_COMPRESS is not set -CONFIG_PSTORE_COMPRESS=y -CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y -CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" -CONFIG_PSTORE_CONSOLE=y -CONFIG_PSTORE_PMSG=y -CONFIG_PSTORE_RAM=y -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_AUFS_FS=m -CONFIG_AUFS_BRANCH_MAX_127=y -# CONFIG_AUFS_BRANCH_MAX_511 is not set -# CONFIG_AUFS_BRANCH_MAX_1023 is not set -# CONFIG_AUFS_BRANCH_MAX_32767 is not set -CONFIG_AUFS_SBILIST=y -# CONFIG_AUFS_HNOTIFY is not set -# CONFIG_AUFS_EXPORT is not set -# CONFIG_AUFS_XATTR is not set -# CONFIG_AUFS_FHSM is not set -# CONFIG_AUFS_RDU is not set -# CONFIG_AUFS_DIRREN is not set -# CONFIG_AUFS_SHWH is not set -# CONFIG_AUFS_BR_RAMFS is not set -# CONFIG_AUFS_BR_FUSE is not set -CONFIG_AUFS_BDEV_LOOP=y -# CONFIG_AUFS_DEBUG is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=m -CONFIG_NFS_V2=m -CONFIG_NFS_V3=m -CONFIG_NFS_V3_ACL=y -CONFIG_NFS_V4=m -CONFIG_NFS_SWAP=y -CONFIG_NFS_V4_1=y -CONFIG_NFS_V4_2=y -CONFIG_PNFS_FILE_LAYOUT=m -CONFIG_PNFS_BLOCK=m -CONFIG_PNFS_FLEXFILE_LAYOUT=m -CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" -CONFIG_NFS_V4_1_MIGRATION=y -# CONFIG_NFS_USE_LEGACY_DNS is not set -CONFIG_NFS_USE_KERNEL_DNS=y -CONFIG_NFSD=m -CONFIG_NFSD_V2_ACL=y -CONFIG_NFSD_V3=y -CONFIG_NFSD_V3_ACL=y -CONFIG_NFSD_V4=y -CONFIG_NFSD_PNFS=y -CONFIG_NFSD_BLOCKLAYOUT=y -CONFIG_NFSD_SCSILAYOUT=y -CONFIG_NFSD_FLEXFILELAYOUT=y -# CONFIG_NFSD_FAULT_INJECTION is not set -CONFIG_GRACE_PERIOD=m -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -CONFIG_NFS_ACL_SUPPORT=m -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=m -CONFIG_SUNRPC_GSS=m -CONFIG_SUNRPC_BACKCHANNEL=y -CONFIG_SUNRPC_SWAP=y -# CONFIG_SUNRPC_DEBUG is not set -# CONFIG_CEPH_FS is not set -CONFIG_CIFS=m -# CONFIG_CIFS_STATS2 is not set -CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_UPCALL is not set -# CONFIG_CIFS_XATTR is not set -CONFIG_CIFS_DEBUG=y -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_DEBUG_DUMP_KEYS is not set -# CONFIG_CIFS_DFS_UPCALL is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ASCII=y -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_MAC_ROMAN is not set -# CONFIG_NLS_MAC_CELTIC is not set -# CONFIG_NLS_MAC_CENTEURO is not set -# CONFIG_NLS_MAC_CROATIAN is not set -# CONFIG_NLS_MAC_CYRILLIC is not set -# CONFIG_NLS_MAC_GAELIC is not set -# CONFIG_NLS_MAC_GREEK is not set -# CONFIG_NLS_MAC_ICELAND is not set -# CONFIG_NLS_MAC_INUIT is not set -# CONFIG_NLS_MAC_ROMANIAN is not set -# CONFIG_NLS_MAC_TURKISH is not set -CONFIG_NLS_UTF8=y -# CONFIG_DLM is not set - -# -# Security options -# -CONFIG_KEYS=y -# CONFIG_PERSISTENT_KEYRINGS is not set -# CONFIG_BIG_KEYS is not set -# CONFIG_ENCRYPTED_KEYS is not set -# CONFIG_KEY_DH_OPERATIONS is not set -# CONFIG_SECURITY_DMESG_RESTRICT is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -# CONFIG_HARDENED_USERCOPY is not set -# CONFIG_FORTIFY_SOURCE is not set -# CONFIG_STATIC_USERMODEHELPER is not set -CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_DEFAULT_SECURITY="" -CONFIG_XOR_BLOCKS=y -CONFIG_ASYNC_CORE=m -CONFIG_ASYNC_MEMCPY=m -CONFIG_ASYNC_XOR=m -CONFIG_ASYNC_PQ=m -CONFIG_ASYNC_RAID6_RECOV=m -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_RNG_DEFAULT=y -CONFIG_CRYPTO_AKCIPHER2=y -CONFIG_CRYPTO_AKCIPHER=y -CONFIG_CRYPTO_KPP2=y -CONFIG_CRYPTO_KPP=y -CONFIG_CRYPTO_ACOMP2=y -CONFIG_CRYPTO_RSA=y -# CONFIG_CRYPTO_DH is not set -CONFIG_CRYPTO_ECDH=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_USER=m -CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -CONFIG_CRYPTO_GF128MUL=y -CONFIG_CRYPTO_NULL=y -CONFIG_CRYPTO_NULL2=y -# CONFIG_CRYPTO_PCRYPT is not set -CONFIG_CRYPTO_WORKQUEUE=y -CONFIG_CRYPTO_CRYPTD=m -# CONFIG_CRYPTO_MCRYPTD is not set -CONFIG_CRYPTO_AUTHENC=m -# CONFIG_CRYPTO_TEST is not set -CONFIG_CRYPTO_SIMD=m - -# -# Authenticated Encryption with Associated Data -# -CONFIG_CRYPTO_CCM=y -CONFIG_CRYPTO_GCM=y -# CONFIG_CRYPTO_CHACHA20POLY1305 is not set -CONFIG_CRYPTO_AEGIS128=m -CONFIG_CRYPTO_AEGIS128L=m -CONFIG_CRYPTO_AEGIS256=m -CONFIG_CRYPTO_MORUS640=m -CONFIG_CRYPTO_MORUS1280=m -CONFIG_CRYPTO_SEQIV=y -CONFIG_CRYPTO_ECHAINIV=m - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -# CONFIG_CRYPTO_CFB is not set -CONFIG_CRYPTO_CTR=y -# 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 -# CONFIG_CRYPTO_KEYWRAP is not set - -# -# Hash modes -# -CONFIG_CRYPTO_CMAC=y -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_VMAC is not set - -# -# Digest -# -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_CRC32=m -CONFIG_CRYPTO_CRCT10DIF=y -CONFIG_CRYPTO_GHASH=y -# CONFIG_CRYPTO_POLY1305 is not set -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=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -# CONFIG_CRYPTO_SHA3 is not set -# CONFIG_CRYPTO_SM3 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -CONFIG_CRYPTO_AES=y -# CONFIG_CRYPTO_AES_TI is not set -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_ARC4=y -# 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 is not set -CONFIG_CRYPTO_CHACHA20=m -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_SM4 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_LZO=y -# CONFIG_CRYPTO_842 is not set -# CONFIG_CRYPTO_LZ4 is not set -# CONFIG_CRYPTO_LZ4HC is not set -CONFIG_CRYPTO_ZSTD=m - -# -# Random Number Generation -# -# CONFIG_CRYPTO_ANSI_CPRNG is not set -CONFIG_CRYPTO_DRBG_MENU=y -CONFIG_CRYPTO_DRBG_HMAC=y -# CONFIG_CRYPTO_DRBG_HASH is not set -# CONFIG_CRYPTO_DRBG_CTR is not set -CONFIG_CRYPTO_DRBG=y -CONFIG_CRYPTO_JITTERENTROPY=y -CONFIG_CRYPTO_USER_API=m -CONFIG_CRYPTO_USER_API_HASH=m -CONFIG_CRYPTO_USER_API_SKCIPHER=m -CONFIG_CRYPTO_USER_API_RNG=m -CONFIG_CRYPTO_USER_API_AEAD=m -CONFIG_CRYPTO_HASH_INFO=y -CONFIG_CRYPTO_HW=y -# CONFIG_CRYPTO_DEV_HIFN_795X is not set -CONFIG_CRYPTO_DEV_MEDIATEK=y -# CONFIG_CRYPTO_DEV_VIRTIO is not set -# CONFIG_CRYPTO_DEV_CCREE is not set -CONFIG_ASYMMETRIC_KEY_TYPE=y -CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y -CONFIG_X509_CERTIFICATE_PARSER=y -CONFIG_PKCS7_MESSAGE_PARSER=y -# CONFIG_PKCS7_TEST_KEY is not set -# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set - -# -# Certificates for signature checking -# -CONFIG_SYSTEM_TRUSTED_KEYRING=y -CONFIG_SYSTEM_TRUSTED_KEYS="" -# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set -# CONFIG_SECONDARY_TRUSTED_KEYRING is not set -# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set -CONFIG_BINARY_PRINTF=y - -# -# Library routines -# -CONFIG_RAID6_PQ=y -CONFIG_BITREVERSE=y -CONFIG_HAVE_ARCH_BITREVERSE=y -CONFIG_RATIONAL=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_NET_UTILS=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -CONFIG_CRC_CCITT=m -CONFIG_CRC16=y -CONFIG_CRC_T10DIF=y -CONFIG_CRC_ITU_T=m -CONFIG_CRC32=y -# CONFIG_CRC32_SELFTEST is not set -CONFIG_CRC32_SLICEBY8=y -# CONFIG_CRC32_SLICEBY4 is not set -# CONFIG_CRC32_SARWATE is not set -# CONFIG_CRC32_BIT is not set -# CONFIG_CRC64 is not set -# CONFIG_CRC4 is not set -CONFIG_CRC7=m -CONFIG_LIBCRC32C=y -CONFIG_CRC8=m -CONFIG_XXHASH=y -# CONFIG_RANDOM32_SELFTEST is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_LZ4_DECOMPRESS=y -CONFIG_ZSTD_COMPRESS=y -CONFIG_ZSTD_DECOMPRESS=y -CONFIG_XZ_DEC=y -CONFIG_XZ_DEC_X86=y -CONFIG_XZ_DEC_POWERPC=y -CONFIG_XZ_DEC_IA64=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_ARMTHUMB=y -CONFIG_XZ_DEC_SPARC=y -CONFIG_XZ_DEC_BCJ=y -# CONFIG_XZ_DEC_TEST is not set -CONFIG_DECOMPRESS_GZIP=y -CONFIG_DECOMPRESS_BZIP2=y -CONFIG_DECOMPRESS_LZMA=y -CONFIG_DECOMPRESS_XZ=y -CONFIG_DECOMPRESS_LZO=y -CONFIG_DECOMPRESS_LZ4=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_REED_SOLOMON=y -CONFIG_REED_SOLOMON_ENC8=y -CONFIG_REED_SOLOMON_DEC8=y -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=m -CONFIG_TEXTSEARCH_BM=m -CONFIG_TEXTSEARCH_FSM=m -CONFIG_ASSOCIATIVE_ARRAY=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HAS_DMA=y -CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_SGL_ALLOC=y -CONFIG_CPU_RMAP=y -CONFIG_DQL=y -CONFIG_GLOB=y -# CONFIG_GLOB_SELFTEST is not set -CONFIG_NLATTR=y -CONFIG_CLZ_TAB=y -# CONFIG_CORDIC is not set -# CONFIG_DDR is not set -# CONFIG_IRQ_POLL is not set -CONFIG_MPILIB=y -CONFIG_LIBFDT=y -CONFIG_OID_REGISTRY=y -CONFIG_UCS2_STRING=y -CONFIG_FONT_SUPPORT=y -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -CONFIG_SG_POOL=y -CONFIG_ARCH_HAS_SG_CHAIN=y -CONFIG_SBITMAP=y -# CONFIG_STRING_SELFTEST is not set - -# -# Kernel hacking -# - -# -# printk and dmesg options -# -CONFIG_PRINTK_TIME=y -CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 -CONFIG_CONSOLE_LOGLEVEL_QUIET=4 -CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_DYNAMIC_DEBUG is not set - -# -# Compile-time checks and compiler options -# -# CONFIG_DEBUG_INFO is not set -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 -# CONFIG_STRIP_ASM_SYMS is not set -# CONFIG_READABLE_ASM is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_PAGE_OWNER is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_SECTION_MISMATCH is not set -CONFIG_SECTION_MISMATCH_WARN_ONLY=y -# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -CONFIG_MAGIC_SYSRQ=y -CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 -CONFIG_MAGIC_SYSRQ_SERIAL=y -CONFIG_DEBUG_KERNEL=y - -# -# Memory Debugging -# -CONFIG_PAGE_EXTENSION=y -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_PAGE_POISONING is not set -# CONFIG_DEBUG_PAGE_REF is not set -# CONFIG_DEBUG_RODATA_TEST is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_STATS is not set -CONFIG_HAVE_DEBUG_KMEMLEAK=y -# CONFIG_DEBUG_KMEMLEAK is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_VM is not set -CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y -# CONFIG_DEBUG_VIRTUAL is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_PER_CPU_MAPS is not set -# CONFIG_DEBUG_HIGHMEM is not set -CONFIG_ARCH_HAS_KCOV=y -CONFIG_CC_HAS_SANCOV_TRACE_PC=y -# CONFIG_KCOV is not set -# CONFIG_DEBUG_SHIRQ is not set - -# -# Debug Lockups and Hangs -# -# CONFIG_SOFTLOCKUP_DETECTOR is not set -# CONFIG_DETECT_HUNG_TASK is not set -# CONFIG_WQ_WATCHDOG is not set -# CONFIG_PANIC_ON_OOPS is not set -CONFIG_PANIC_ON_OOPS_VALUE=0 -CONFIG_PANIC_TIMEOUT=0 -CONFIG_SCHED_DEBUG=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_SCHED_STACK_END_CHECK is not set -# CONFIG_DEBUG_TIMEKEEPING is not set - -# -# Lock Debugging (spinlocks, mutexes, etc...) -# -CONFIG_LOCK_DEBUGGING_SUPPORT=y -# CONFIG_PROVE_LOCKING is not set -# CONFIG_LOCK_STAT is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set -# CONFIG_DEBUG_RWSEMS is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_DEBUG_ATOMIC_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_LOCK_TORTURE_TEST is not set -# CONFIG_WW_MUTEX_SELFTEST is not set -CONFIG_STACKTRACE=y -# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_PI_LIST is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_DEBUG_CREDENTIALS is not set - -# -# RCU Debugging -# -# CONFIG_RCU_PERF_TEST is not set -# CONFIG_RCU_TORTURE_TEST is not set -CONFIG_RCU_CPU_STALL_TIMEOUT=21 -CONFIG_RCU_TRACE=y -# CONFIG_RCU_EQS_DEBUG is not set -# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set -# CONFIG_NOTIFIER_ERROR_INJECTION is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set -CONFIG_NOP_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_TRACE_CLOCK=y -CONFIG_RING_BUFFER=y -CONFIG_EVENT_TRACING=y -CONFIG_CONTEXT_SWITCH_TRACER=y -CONFIG_TRACING=y -CONFIG_TRACING_SUPPORT=y -CONFIG_FTRACE=y -# CONFIG_FUNCTION_TRACER is not set -# CONFIG_PREEMPTIRQ_EVENTS is not set -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_HWLAT_TRACER is not set -# CONFIG_ENABLE_DEFAULT_TRACERS is not set -# CONFIG_FTRACE_SYSCALLS is not set -# CONFIG_TRACER_SNAPSHOT is not set -CONFIG_BRANCH_PROFILE_NONE=y -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set -# CONFIG_STACK_TRACER is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -CONFIG_KPROBE_EVENTS=y -CONFIG_UPROBE_EVENTS=y -CONFIG_BPF_EVENTS=y -CONFIG_PROBE_EVENTS=y -# CONFIG_TRACEPOINT_BENCHMARK is not set -# CONFIG_RING_BUFFER_BENCHMARK is not set -# CONFIG_RING_BUFFER_STARTUP_TEST is not set -# CONFIG_PREEMPTIRQ_DELAY_TEST is not set -# CONFIG_TRACE_EVAL_MAP_FILE is not set -CONFIG_TRACING_EVENTS_GPIO=y -# CONFIG_DMA_API_DEBUG is not set -CONFIG_RUNTIME_TESTING_MENU=y -# CONFIG_LKDTM is not set -# CONFIG_TEST_LIST_SORT is not set -# CONFIG_TEST_SORT is not set -# CONFIG_KPROBES_SANITY_TEST is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_RBTREE_TEST is not set -# CONFIG_INTERVAL_TREE_TEST is not set -# CONFIG_PERCPU_TEST is not set -# CONFIG_ATOMIC64_SELFTEST is not set -# CONFIG_ASYNC_RAID6_TEST is not set -# CONFIG_TEST_HEXDUMP is not set -# CONFIG_TEST_STRING_HELPERS is not set -# CONFIG_TEST_KSTRTOX is not set -# CONFIG_TEST_PRINTF is not set -# CONFIG_TEST_BITMAP is not set -# CONFIG_TEST_BITFIELD is not set -# CONFIG_TEST_UUID is not set -# CONFIG_TEST_OVERFLOW is not set -# CONFIG_TEST_RHASHTABLE is not set -# CONFIG_TEST_HASH is not set -# CONFIG_TEST_IDA is not set -# CONFIG_TEST_LKM is not set -# CONFIG_TEST_USER_COPY is not set -# CONFIG_TEST_BPF is not set -# CONFIG_FIND_BIT_BENCHMARK is not set -# CONFIG_TEST_FIRMWARE is not set -# CONFIG_TEST_SYSCTL is not set -# CONFIG_TEST_UDELAY is not set -# CONFIG_TEST_STATIC_KEYS is not set -# CONFIG_TEST_KMOD is not set -# CONFIG_MEMTEST is not set -# CONFIG_BUG_ON_DATA_CORRUPTION is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -# CONFIG_UBSAN is not set -CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y -# CONFIG_STRICT_DEVMEM is not set -# CONFIG_ARM_PTDUMP_DEBUGFS is not set -# CONFIG_DEBUG_WX is not set -# CONFIG_UNWINDER_FRAME_POINTER is not set -CONFIG_UNWINDER_ARM=y -CONFIG_ARM_UNWIND=y -# CONFIG_DEBUG_USER is not set -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_MT6589_UART0 is not set -# CONFIG_DEBUG_MT8127_UART0 is not set -# CONFIG_DEBUG_MT8135_UART3 is not set -# CONFIG_DEBUG_ICEDCC is not set -# CONFIG_DEBUG_SEMIHOSTING is not set -CONFIG_DEBUG_LL_UART_8250=y -# CONFIG_DEBUG_LL_UART_PL01X is not set -CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" -CONFIG_DEBUG_UART_PHYS=0x11004000 -CONFIG_DEBUG_UART_VIRT=0xf1004000 -CONFIG_DEBUG_UART_8250_SHIFT=2 -# CONFIG_DEBUG_UART_8250_WORD is not set -# CONFIG_DEBUG_UART_8250_PALMCHIP is not set -# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set -# CONFIG_DEBUG_UNCOMPRESS is not set -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -CONFIG_EARLY_PRINTK=y -# CONFIG_ARM_KPROBES_TEST is not set -# CONFIG_PID_IN_CONTEXTIDR is not set -# CONFIG_CORESIGHT is not set diff --git a/config/sources/families/mt7623.conf b/config/sources/families/mt7623.conf index 81e81acec331..8e8dd7103155 100644 --- a/config/sources/families/mt7623.conf +++ b/config/sources/families/mt7623.conf @@ -9,19 +9,19 @@ BOOTSCRIPT='boot-mt7623.cmd:boot.cmd' BOOTENV_FILE='mt7623.txt' UBOOT_TARGET_MAP=";;$SRC/packages/blobs/mt7623n/BPI-R2-HEAD440-0k.img $SRC/packages/blobs/mt7623n/BPI-R2-HEAD1-512b.img $SRC/packages/blobs/mt7623n/BPI-R2-preloader-2k.img $SRC/packages/blobs/mt7623n/BPI-R2-EMMC-boot0-0K-0905.img u-boot.bin" -BOOTPATCHDIR='legacy' -BOOTBRANCH='tag:v2023.04' +BOOTPATCHDIR='v2024.07' +BOOTBRANCH='tag:v2024.07' ARCH=armhf ATF_COMPILE="no" EXTRAWIFI="no" case $BRANCH in - legacy) - - declare -g KERNEL_MAJOR_MINOR="4.19" # Major and minor versions of this kernel. - KERNELBRANCH='branch:linux-4.19.y' - KERNELPATCHDIR='archive/mt7623-4.19' + # 07/2024: This family only has one board (BananaPi R2) and has not been properly maintained in many years, so 'current' LTS kernel is enough. + # No need for 'edge' kernel unless someone plans to step in as maintainer who bumps and tests it on every new kernel release. + current) + KERNEL_MAJOR_MINOR="6.6" # Major and minor versions of this kernel. + # No need to set KERNELPATCHDIR, since default is: KERNELPATCHDIR='archive/${BOARDFAMILY}-${KERNEL_MAJOR_MINOR}' ;; esac @@ -30,6 +30,9 @@ CPUMIN=98000 CPUMAX=1300000 GOVERNOR="ondemand" +declare -g NETWORKING_STACK="systemd-networkd" # Always use systemd-networkd since 'family_tweaks()' includes some network config that currently is only available for networkd; @TODO Change this config to Netplan config + +# @TODO Can probably be deleted, especially after the config (see 'NETWORKING_STACK' above) has been converted to Netplan. Then it won't matter if networkd or Network-Manager is used. function pre_install_kernel_debs__network_manager_ignore_devices() { display_alert "Board: ${BOARD}: Disabling Network-Manager for all devices" "interface-name:eth*,interface-name:wan*,interface-name:lan*,interface-name:br*" "info" @@ -63,12 +66,5 @@ write_uboot_platform() { } family_tweaks() { - [[ -f $SDCARD/etc/netplan/armbian-default.yaml ]] && sed -i "s/^ renderer.*/ renderer: networkd/" $SDCARD/etc/netplan/armbian-default.yaml - cp $SRC/packages/bsp/mt7623/mt7623-wifi.service $SDCARD/lib/systemd/system/ - install -m 755 $SRC/packages/bsp/mt7623/mt7623-wifi.bash $SDCARD/usr/local/bin/mt7623-wifi.bash - # very unstable wifi driver, disabled by default http://www.fw-web.de/dokuwiki/doku.php?id=en:bpi-r2:wlan#internal - # chroot $SDCARD /bin/bash -c "systemctl --no-reload enable mt7623-wifi.service >/dev/null 2>&1" - cp $SRC/packages/bsp/mt7623/10* $SDCARD/etc/systemd/network/ - cp $SRC/packages/blobs/mt7623n/wireless/{stp_uart_launcher,wmt_loader,wmt_loopback} $SDCARD/usr/local/bin } diff --git a/packages/blobs/mt7623n/BPI-R2-preloader-2k.img.old b/packages/blobs/mt7623n/BPI-R2-preloader-2k.img.old deleted file mode 100644 index 6107c764354e..000000000000 Binary files a/packages/blobs/mt7623n/BPI-R2-preloader-2k.img.old and /dev/null differ diff --git a/packages/blobs/mt7623n/wireless/source.txt b/packages/blobs/mt7623n/wireless/source.txt deleted file mode 100644 index f5088aa9d004..000000000000 --- a/packages/blobs/mt7623n/wireless/source.txt +++ /dev/null @@ -1 +0,0 @@ -https://github.com/BPI-SINOVOIP/BPI-R2-bsp/tree/master/vendor/mediatek/connectivity/tools/binary diff --git a/packages/blobs/mt7623n/wireless/stp_uart_launcher b/packages/blobs/mt7623n/wireless/stp_uart_launcher deleted file mode 100755 index ee071c3e17d1..000000000000 Binary files a/packages/blobs/mt7623n/wireless/stp_uart_launcher and /dev/null differ diff --git a/packages/blobs/mt7623n/wireless/wmt_loader b/packages/blobs/mt7623n/wireless/wmt_loader deleted file mode 100755 index 63fc7648ce0c..000000000000 Binary files a/packages/blobs/mt7623n/wireless/wmt_loader and /dev/null differ diff --git a/packages/blobs/mt7623n/wireless/wmt_loopback b/packages/blobs/mt7623n/wireless/wmt_loopback deleted file mode 100755 index 0e2c33eec592..000000000000 Binary files a/packages/blobs/mt7623n/wireless/wmt_loopback and /dev/null differ diff --git a/packages/bsp/mt7623/mt7623-wifi.bash b/packages/bsp/mt7623/mt7623-wifi.bash deleted file mode 100644 index e25029341fb1..000000000000 --- a/packages/bsp/mt7623/mt7623-wifi.bash +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -/usr/local/bin/wmt_loader & -sleep 3 -/usr/local/bin/stp_uart_launcher -p /lib/firmware/mediatek & -sleep 3 -/bin/echo A >/dev/wmtWifi diff --git a/packages/bsp/mt7623/mt7623-wifi.service b/packages/bsp/mt7623/mt7623-wifi.service deleted file mode 100644 index ed76c83258a8..000000000000 --- a/packages/bsp/mt7623/mt7623-wifi.service +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=MT7623 Wireless -DefaultDependencies=no -Wants=rsyslog.service systemd-journald.service -Before=syslog.target sysinit.target -After=local-fs.target - -[Service] -Type=oneshot -ExecStart=/usr/local/bin/mt7623-wifi.bash -RemainAfterExit=no - -[Install] -WantedBy=sysinit.target diff --git a/patch/kernel/archive/mt7623-4.19/0001-r2-wifi-add-driver-folder.patch b/patch/kernel/archive/mt7623-4.19/0001-r2-wifi-add-driver-folder.patch deleted file mode 100644 index 0c08ccfbcbc6..000000000000 --- a/patch/kernel/archive/mt7623-4.19/0001-r2-wifi-add-driver-folder.patch +++ /dev/null @@ -1,216262 +0,0 @@ -From ce8c582c6121469db64197b1b4aa4e4c377c660f Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 23 Oct 2018 13:12:12 +0200 -Subject: [PATCH] [wifi] adding driver-folder - ---- - drivers/misc/Kconfig | 1 + - drivers/misc/Makefile | 1 + - drivers/misc/mediatek/Kconfig | 11 + - drivers/misc/mediatek/Makefile | 19 + - drivers/misc/mediatek/btif/Kconfig | 4 + - drivers/misc/mediatek/btif/Makefile | 33 + - drivers/misc/mediatek/btif/common/Makefile | 31 + - .../misc/mediatek/btif/common/btif_dma_plat.c | 1436 ++ - drivers/misc/mediatek/btif/common/btif_plat.c | 1396 ++ - .../misc/mediatek/btif/common/inc/mtk_btif.h | 370 + - .../mediatek/btif/common/inc/mtk_btif_exp.h | 280 + - drivers/misc/mediatek/btif/common/mtk_btif.c | 3472 +++++ - .../misc/mediatek/btif/common/mtk_btif_exp.c | 786 ++ - .../btif/common/plat_inc/btif_dma_priv.h | 164 + - .../btif/common/plat_inc/btif_dma_pub.h | 197 + - .../mediatek/btif/common/plat_inc/btif_priv.h | 105 + - .../mediatek/btif/common/plat_inc/btif_pub.h | 237 + - .../btif/common/plat_inc/plat_common.h | 307 + - drivers/misc/mediatek/connectivity/Kconfig | 299 + - drivers/misc/mediatek/connectivity/Makefile | 41 + - .../mediatek/connectivity/common/Makefile | 23 + - .../common/common_detect/Makefile | 47 + - .../common/common_detect/drv_init/Makefile | 22 + - .../common_detect/drv_init/ant_drv_init.c | 38 + - .../drv_init/bluetooth_drv_init.c | 35 + - .../common_detect/drv_init/common_drv_init.c | 103 + - .../common_detect/drv_init/conn_drv_init.c | 80 + - .../common_detect/drv_init/fm_drv_init.c | 33 + - .../common_detect/drv_init/gps_drv_init.c | 35 + - .../common_detect/drv_init/inc/ant_drv_init.h | 20 + - .../drv_init/inc/bluetooth_drv_init.h | 20 + - .../drv_init/inc/common_drv_init.h | 31 + - .../drv_init/inc/conn_drv_init.h | 18 + - .../common_detect/drv_init/inc/fm_drv_init.h | 20 + - .../common_detect/drv_init/inc/gps_drv_init.h | 19 + - .../drv_init/inc/wlan_drv_init.h | 30 + - .../common_detect/drv_init/wlan_drv_init.c | 74 + - .../common/common_detect/mtk_wcn_stub_alps.c | 605 + - .../common/common_detect/sdio_detect.c | 269 + - .../common/common_detect/sdio_detect.h | 43 + - .../common/common_detect/wmt_detect.c | 380 + - .../common/common_detect/wmt_detect.h | 114 + - .../common/common_detect/wmt_detect_pwr.c | 232 + - .../common/common_detect/wmt_detect_pwr.h | 29 + - .../common/common_detect/wmt_gpio.c | 371 + - .../common/common_detect/wmt_gpio.h | 103 + - .../common/common_detect/wmt_stp_exp.c | 480 + - .../common/common_detect/wmt_stp_exp.h | 610 + - .../connectivity/common/conn_soc/Makefile | 65 + - .../common/conn_soc/core/Makefile | 22 + - .../common/conn_soc/core/btm_core.c | 1376 ++ - .../common/conn_soc/core/dbg_core.c | 13 + - .../common/conn_soc/core/include/btm_core.h | 133 + - .../common/conn_soc/core/include/dbg_core.h | 69 + - .../common/conn_soc/core/include/psm_core.h | 251 + - .../common/conn_soc/core/include/stp_core.h | 629 + - .../common/conn_soc/core/include/stp_wmt.h | 89 + - .../common/conn_soc/core/include/wmt_conf.h | 74 + - .../common/conn_soc/core/include/wmt_core.h | 428 + - .../common/conn_soc/core/include/wmt_ctrl.h | 120 + - .../common/conn_soc/core/include/wmt_func.h | 140 + - .../common/conn_soc/core/include/wmt_ic.h | 122 + - .../common/conn_soc/core/include/wmt_lib.h | 300 + - .../common/conn_soc/core/psm_core.c | 1890 +++ - .../common/conn_soc/core/stp_core.c | 3358 +++++ - .../common/conn_soc/core/wmt_conf.c | 529 + - .../common/conn_soc/core/wmt_core.c | 2521 ++++ - .../common/conn_soc/core/wmt_ctrl.c | 1019 ++ - .../common/conn_soc/core/wmt_func.c | 713 + - .../common/conn_soc/core/wmt_ic_soc.c | 2452 ++++ - .../common/conn_soc/core/wmt_lib.c | 1938 +++ - .../common/conn_soc/include/stp_exp.h | 252 + - .../common/conn_soc/include/wmt.h | 19 + - .../common/conn_soc/include/wmt_exp.h | 329 + - .../common/conn_soc/include/wmt_plat.h | 295 + - .../common/conn_soc/linux/Makefile | 6 + - .../conn_soc/linux/include/bgw_desense.h | 74 + - .../common/conn_soc/linux/include/osal.h | 349 + - .../conn_soc/linux/include/osal_typedef.h | 90 + - .../common/conn_soc/linux/include/wmt_idc.h | 97 + - .../common/conn_soc/linux/pri/Makefile | 21 + - .../conn_soc/linux/pri/include/stp_btif.h | 31 + - .../conn_soc/linux/pri/include/stp_dbg.h | 316 + - .../conn_soc/linux/pri/include/wmt_dev.h | 71 + - .../common/conn_soc/linux/pri/stp_btif.c | 279 + - .../common/conn_soc/linux/pri/stp_dbg.c | 2061 +++ - .../common/conn_soc/linux/pri/stp_exp.c | 279 + - .../common/conn_soc/linux/pri/wmt_dev.c | 2566 ++++ - .../common/conn_soc/linux/pri/wmt_exp.c | 610 + - .../common/conn_soc/linux/pub/Makefile | 27 + - .../common/conn_soc/linux/pub/bgw_desense.c | 153 + - .../common/conn_soc/linux/pub/osal.c | 1211 ++ - .../common/conn_soc/linux/pub/stp_chrdev_bt.c | 899 ++ - .../conn_soc/linux/pub/wmt_chrdev_wifi.c | 668 + - .../common/conn_soc/linux/pub/wmt_idc.c | 307 + - .../common/conn_soc/mt7623/Makefile | 25 + - .../mt7623/include/mtk_wcn_consys_hw.h | 287 + - .../conn_soc/mt7623/mtk_wcn_consys_hw.c | 738 ++ - .../common/conn_soc/mt7623/wmt_plat_alps.c | 1071 ++ - .../misc/mediatek/connectivity/wlan/Makefile | 8 + - .../mediatek/connectivity/wlan/gen2/Makefile | 237 + - .../connectivity/wlan/gen2/common/debug.c | 165 + - .../connectivity/wlan/gen2/common/dump.c | 345 + - .../connectivity/wlan/gen2/common/wlan_bow.c | 3442 +++++ - .../connectivity/wlan/gen2/common/wlan_lib.c | 6240 +++++++++ - .../connectivity/wlan/gen2/common/wlan_oid.c | 11050 ++++++++++++++++ - .../connectivity/wlan/gen2/common/wlan_p2p.c | 1654 +++ - .../wlan/gen2/include/CFG_Wifi_File.h | 238 + - .../connectivity/wlan/gen2/include/config.h | 1628 +++ - .../connectivity/wlan/gen2/include/debug.h | 466 + - .../connectivity/wlan/gen2/include/link.h | 368 + - .../wlan/gen2/include/mgmt/aa_fsm.h | 188 + - .../wlan/gen2/include/mgmt/ais_fsm.h | 573 + - .../wlan/gen2/include/mgmt/assoc.h | 112 + - .../wlan/gen2/include/mgmt/auth.h | 125 + - .../wlan/gen2/include/mgmt/bow_fsm.h | 184 + - .../connectivity/wlan/gen2/include/mgmt/bss.h | 265 + - .../connectivity/wlan/gen2/include/mgmt/cnm.h | 258 + - .../wlan/gen2/include/mgmt/cnm_mem.h | 1164 ++ - .../wlan/gen2/include/mgmt/cnm_scan.h | 169 + - .../wlan/gen2/include/mgmt/cnm_timer.h | 235 + - .../wlan/gen2/include/mgmt/hem_mbox.h | 446 + - .../wlan/gen2/include/mgmt/hs20.h | 148 + - .../connectivity/wlan/gen2/include/mgmt/mib.h | 153 + - .../wlan/gen2/include/mgmt/p2p_assoc.h | 55 + - .../wlan/gen2/include/mgmt/p2p_bss.h | 56 + - .../wlan/gen2/include/mgmt/p2p_fsm.h | 2190 +++ - .../wlan/gen2/include/mgmt/p2p_func.h | 155 + - .../wlan/gen2/include/mgmt/p2p_ie.h | 156 + - .../wlan/gen2/include/mgmt/p2p_rlm.h | 74 + - .../wlan/gen2/include/mgmt/p2p_rlm_obss.h | 64 + - .../wlan/gen2/include/mgmt/p2p_scan.h | 81 + - .../wlan/gen2/include/mgmt/p2p_state.h | 43 + - .../wlan/gen2/include/mgmt/privacy.h | 230 + - .../wlan/gen2/include/mgmt/rate.h | 93 + - .../connectivity/wlan/gen2/include/mgmt/rlm.h | 396 + - .../wlan/gen2/include/mgmt/rlm_domain.h | 557 + - .../wlan/gen2/include/mgmt/rlm_obss.h | 150 + - .../wlan/gen2/include/mgmt/rlm_protection.h | 122 + - .../wlan/gen2/include/mgmt/rlm_txpwr_init.h | 1213 ++ - .../wlan/gen2/include/mgmt/roaming_fsm.h | 171 + - .../connectivity/wlan/gen2/include/mgmt/rsn.h | 271 + - .../wlan/gen2/include/mgmt/scan.h | 988 ++ - .../wlan/gen2/include/mgmt/sec_fsm.h | 233 + - .../wlan/gen2/include/mgmt/stats.h | 368 + - .../wlan/gen2/include/mgmt/swcr.h | 187 + - .../wlan/gen2/include/mgmt/tdls.h | 262 + - .../wlan/gen2/include/mgmt/wapi.h | 104 + - .../wlan/gen2/include/mgmt/wlan_typedef.h | 87 + - .../connectivity/wlan/gen2/include/mgmt/wnm.h | 95 + - .../wlan/gen2/include/nic/adapter.h | 1506 +++ - .../connectivity/wlan/gen2/include/nic/bow.h | 322 + - .../wlan/gen2/include/nic/cmd_buf.h | 150 + - .../connectivity/wlan/gen2/include/nic/hal.h | 618 + - .../wlan/gen2/include/nic/hif_rx.h | 220 + - .../wlan/gen2/include/nic/hif_tx.h | 214 + - .../connectivity/wlan/gen2/include/nic/mac.h | 2323 ++++ - .../wlan/gen2/include/nic/mtreg.h | 272 + - .../connectivity/wlan/gen2/include/nic/nic.h | 498 + - .../wlan/gen2/include/nic/nic_rx.h | 420 + - .../wlan/gen2/include/nic/nic_tx.h | 642 + - .../connectivity/wlan/gen2/include/nic/p2p.h | 192 + - .../wlan/gen2/include/nic/p2p_cmd_buf.h | 83 + - .../wlan/gen2/include/nic/p2p_mac.h | 207 + - .../wlan/gen2/include/nic/p2p_nic.h | 62 + - .../wlan/gen2/include/nic/p2p_nic_cmd_event.h | 70 + - .../wlan/gen2/include/nic/que_mgt.h | 971 ++ - .../wlan/gen2/include/nic/wlan_def.h | 1010 ++ - .../wlan/gen2/include/nic_cmd_event.h | 2290 ++++ - .../wlan/gen2/include/nic_init_cmd_event.h | 177 + - .../wlan/gen2/include/p2p_precomp.h | 201 + - .../wlan/gen2/include/p2p_typedef.h | 165 + - .../connectivity/wlan/gen2/include/precomp.h | 388 + - .../connectivity/wlan/gen2/include/pwr_mgt.h | 141 + - .../connectivity/wlan/gen2/include/queue.h | 195 + - .../connectivity/wlan/gen2/include/rftest.h | 294 + - .../wlan/gen2/include/tdls_extr.h | 427 + - .../connectivity/wlan/gen2/include/typedef.h | 244 + - .../connectivity/wlan/gen2/include/wlan_bow.h | 352 + - .../connectivity/wlan/gen2/include/wlan_lib.h | 1001 ++ - .../connectivity/wlan/gen2/include/wlan_oid.h | 1715 +++ - .../connectivity/wlan/gen2/include/wlan_p2p.h | 307 + - .../connectivity/wlan/gen2/mgmt/aaa_fsm.c | 1303 ++ - .../connectivity/wlan/gen2/mgmt/ais_fsm.c | 5039 +++++++ - .../connectivity/wlan/gen2/mgmt/assoc.c | 1932 +++ - .../connectivity/wlan/gen2/mgmt/auth.c | 1211 ++ - .../connectivity/wlan/gen2/mgmt/bss.c | 2521 ++++ - .../connectivity/wlan/gen2/mgmt/cnm.c | 738 ++ - .../connectivity/wlan/gen2/mgmt/cnm_mem.c | 1236 ++ - .../connectivity/wlan/gen2/mgmt/cnm_timer.c | 482 + - .../connectivity/wlan/gen2/mgmt/hem_mbox.c | 816 ++ - .../connectivity/wlan/gen2/mgmt/hs20.c | 498 + - .../connectivity/wlan/gen2/mgmt/mib.c | 111 + - .../connectivity/wlan/gen2/mgmt/p2p_assoc.c | 87 + - .../connectivity/wlan/gen2/mgmt/p2p_bss.c | 58 + - .../connectivity/wlan/gen2/mgmt/p2p_fsm.c | 3139 +++++ - .../connectivity/wlan/gen2/mgmt/p2p_func.c | 3796 ++++++ - .../connectivity/wlan/gen2/mgmt/p2p_ie.c | 612 + - .../connectivity/wlan/gen2/mgmt/p2p_rlm.c | 905 ++ - .../wlan/gen2/mgmt/p2p_rlm_obss.c | 313 + - .../connectivity/wlan/gen2/mgmt/p2p_scan.c | 756 ++ - .../connectivity/wlan/gen2/mgmt/p2p_state.c | 466 + - .../connectivity/wlan/gen2/mgmt/privacy.c | 915 ++ - .../connectivity/wlan/gen2/mgmt/rate.c | 497 + - .../connectivity/wlan/gen2/mgmt/rlm.c | 1858 +++ - .../connectivity/wlan/gen2/mgmt/rlm_domain.c | 1791 +++ - .../connectivity/wlan/gen2/mgmt/rlm_obss.c | 436 + - .../wlan/gen2/mgmt/rlm_protection.c | 105 + - .../connectivity/wlan/gen2/mgmt/roaming_fsm.c | 539 + - .../connectivity/wlan/gen2/mgmt/rsn.c | 2533 ++++ - .../connectivity/wlan/gen2/mgmt/saa_fsm.c | 1788 +++ - .../connectivity/wlan/gen2/mgmt/scan.c | 3103 +++++ - .../connectivity/wlan/gen2/mgmt/scan_fsm.c | 2136 +++ - .../connectivity/wlan/gen2/mgmt/sec_fsm.c | 1112 ++ - .../connectivity/wlan/gen2/mgmt/stats.c | 1342 ++ - .../connectivity/wlan/gen2/mgmt/swcr.c | 1170 ++ - .../connectivity/wlan/gen2/mgmt/tdls.c | 5199 ++++++++ - .../connectivity/wlan/gen2/mgmt/tdls_com.c | 741 ++ - .../connectivity/wlan/gen2/mgmt/wapi.c | 491 + - .../connectivity/wlan/gen2/mgmt/wnm.c | 301 + - .../connectivity/wlan/gen2/nic/cmd_buf.c | 254 + - .../mediatek/connectivity/wlan/gen2/nic/nic.c | 4062 ++++++ - .../wlan/gen2/nic/nic_cmd_event.c | 1636 +++ - .../connectivity/wlan/gen2/nic/nic_pwr_mgt.c | 669 + - .../connectivity/wlan/gen2/nic/nic_rx.c | 3782 ++++++ - .../connectivity/wlan/gen2/nic/nic_tx.c | 2350 ++++ - .../connectivity/wlan/gen2/nic/p2p_nic.c | 192 + - .../connectivity/wlan/gen2/nic/que_mgt.c | 5038 +++++++ - .../connectivity/wlan/gen2/os/linux/gl_bow.c | 1177 ++ - .../wlan/gen2/os/linux/gl_cfg80211.c | 3110 +++++ - .../connectivity/wlan/gen2/os/linux/gl_init.c | 3502 +++++ - .../connectivity/wlan/gen2/os/linux/gl_kal.c | 4799 +++++++ - .../connectivity/wlan/gen2/os/linux/gl_p2p.c | 4672 +++++++ - .../wlan/gen2/os/linux/gl_p2p_cfg80211.c | 1935 +++ - .../wlan/gen2/os/linux/gl_p2p_init.c | 433 + - .../wlan/gen2/os/linux/gl_p2p_kal.c | 1314 ++ - .../connectivity/wlan/gen2/os/linux/gl_proc.c | 1020 ++ - .../connectivity/wlan/gen2/os/linux/gl_rst.c | 228 + - .../wlan/gen2/os/linux/gl_vendor.c | 1220 ++ - .../connectivity/wlan/gen2/os/linux/gl_wext.c | 4158 ++++++ - .../wlan/gen2/os/linux/gl_wext_priv.c | 3142 +++++ - .../wlan/gen2/os/linux/hif/ahb/ahb.c | 1643 +++ - .../wlan/gen2/os/linux/hif/ahb/arm.c | 31 + - .../wlan/gen2/os/linux/hif/ahb/include/hif.h | 340 + - .../gen2/os/linux/hif/ahb/include/hif_gdma.h | 154 + - .../gen2/os/linux/hif/ahb/include/hif_pdma.h | 141 + - .../os/linux/hif/ahb/include/mtk_porting.h | 91 + - .../gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c | 480 + - .../wlan/gen2/os/linux/include/gl_cfg80211.h | 341 + - .../wlan/gen2/os/linux/include/gl_kal.h | 1565 +++ - .../wlan/gen2/os/linux/include/gl_os.h | 1270 ++ - .../wlan/gen2/os/linux/include/gl_p2p_ioctl.h | 743 ++ - .../wlan/gen2/os/linux/include/gl_p2p_kal.h | 243 + - .../wlan/gen2/os/linux/include/gl_p2p_os.h | 242 + - .../wlan/gen2/os/linux/include/gl_rst.h | 133 + - .../wlan/gen2/os/linux/include/gl_sec.h | 21 + - .../wlan/gen2/os/linux/include/gl_typedef.h | 298 + - .../wlan/gen2/os/linux/include/gl_vendor.h | 619 + - .../wlan/gen2/os/linux/include/gl_wext.h | 357 + - .../wlan/gen2/os/linux/include/gl_wext_priv.h | 402 + - .../wlan/gen2/os/linux/platform.c | 542 + - .../connectivity/wlan/gen2/os/version.h | 190 + - drivers/misc/mediatek/include/mt-plat/aee.h | 284 + - .../misc/mediatek/include/mt-plat/mrdump.h | 204 + - .../mt-plat/mt7622/include/mach/mtk_thermal.h | 295 + - .../mt8127/include/mach/mt_freqhopping.h | 159 + - .../mt8127/include/mach/mt_spm_mtcmos.h | 37 + - .../mt8127/include/mach/mtk_boot_share_page.h | 40 + - .../mt-plat/mt8127/include/mach/mtk_thermal.h | 301 + - .../misc/mediatek/include/mt-plat/mt_sched.h | 34 + - .../misc/mediatek/include/mt-plat/mtk_io.h | 23 + - .../misc/mediatek/include/mt-plat/mtk_lpae.h | 62 + - .../include/mt-plat/mtk_mdm_monitor.h | 42 + - .../include/mt-plat/mtk_platform_debug.h | 28 + - .../include/mt-plat/mtk_ram_console.h | 162 + - .../misc/mediatek/include/mt-plat/mtk_rtc.h | 85 + - .../include/mt-plat/mtk_thermal_ext_control.h | 69 + - .../include/mt-plat/mtk_thermal_monitor.h | 102 + - .../include/mt-plat/mtk_thermal_platform.h | 114 + - .../include/mt-plat/mtk_thermal_trace.h | 47 + - .../include/mt-plat/mtk_thermal_typedefs.h | 241 + - .../include/mt-plat/mtk_wcn_cmb_stub.h | 185 + - .../misc/mediatek/include/mt-plat/rt-regmap.h | 291 + - .../mediatek/include/mt-plat/sync_write.h | 88 + - .../misc/mediatek/include/mt-plat/wakelock.h | 67 + - 285 files changed, 213970 insertions(+) - create mode 100644 drivers/misc/mediatek/Kconfig - create mode 100644 drivers/misc/mediatek/Makefile - create mode 100644 drivers/misc/mediatek/btif/Kconfig - create mode 100644 drivers/misc/mediatek/btif/Makefile - create mode 100644 drivers/misc/mediatek/btif/common/Makefile - create mode 100644 drivers/misc/mediatek/btif/common/btif_dma_plat.c - create mode 100644 drivers/misc/mediatek/btif/common/btif_plat.c - create mode 100644 drivers/misc/mediatek/btif/common/inc/mtk_btif.h - create mode 100644 drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h - create mode 100644 drivers/misc/mediatek/btif/common/mtk_btif.c - create mode 100644 drivers/misc/mediatek/btif/common/mtk_btif_exp.c - create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h - create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h - create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h - create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h - create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/plat_common.h - create mode 100644 drivers/misc/mediatek/connectivity/Kconfig - create mode 100644 drivers/misc/mediatek/connectivity/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/aee.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mrdump.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt_sched.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_io.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_lpae.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_rtc.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/rt-regmap.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/sync_write.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/wakelock.h - -diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 3726eacdf65de..9008a09172e17 100644 ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -527,4 +527,5 @@ source "drivers/misc/echo/Kconfig" - source "drivers/misc/cxl/Kconfig" - source "drivers/misc/ocxl/Kconfig" - source "drivers/misc/cardreader/Kconfig" -+source "drivers/misc/mediatek/Kconfig" - endmenu -diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index af22bbc3d00cb..cdced6d59e2c7 100644 ---- a/drivers/misc/Makefile -+++ b/drivers/misc/Makefile -@@ -58,3 +58,4 @@ obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o - obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o - obj-$(CONFIG_OCXL) += ocxl/ - obj-$(CONFIG_MISC_RTSX) += cardreader/ -+obj-$(CONFIG_MTK_COMBO) += mediatek/ -diff --git a/drivers/misc/mediatek/Kconfig b/drivers/misc/mediatek/Kconfig -new file mode 100644 -index 0000000000000..4829a6598c7aa ---- /dev/null -+++ b/drivers/misc/mediatek/Kconfig -@@ -0,0 +1,11 @@ -+menu "Mediatek Peripherals " -+ -+config MTK_PLATFORM -+ string "MTK platform name" -+source "drivers/misc/mediatek/btif/Kconfig" -+ -+menu "Modem & Connectivity related configs" -+source "drivers/misc/mediatek/connectivity/Kconfig" -+endmenu -+ -+endmenu # CONN -diff --git a/drivers/misc/mediatek/Makefile b/drivers/misc/mediatek/Makefile -new file mode 100644 -index 0000000000000..5e7f06db38f28 ---- /dev/null -+++ b/drivers/misc/mediatek/Makefile -@@ -0,0 +1,19 @@ -+# -+# Copyright (C) 2015 MediaTek Inc. -+# -+# 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. -+# -+# 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. -+# -+ -+#$(call all-subdir-src-or-makefile) -+subdir-ccflags-y += -Werror -+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/ -+ -+obj-$(CONFIG_MTK_COMBO) += connectivity/ -+obj-$(CONFIG_MTK_BTIF) += btif/ -diff --git a/drivers/misc/mediatek/btif/Kconfig b/drivers/misc/mediatek/btif/Kconfig -new file mode 100644 -index 0000000000000..908898bd95c3d ---- /dev/null -+++ b/drivers/misc/mediatek/btif/Kconfig -@@ -0,0 +1,4 @@ -+config MTK_BTIF -+ tristate"MediaTek BTIF Driver" -+ help -+ MTK connectivity BTIF driver for A/D die -diff --git a/drivers/misc/mediatek/btif/Makefile b/drivers/misc/mediatek/btif/Makefile -new file mode 100644 -index 0000000000000..2be3ab66f4268 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/Makefile -@@ -0,0 +1,33 @@ -+# -+# Copyright (C) 2015 MediaTek Inc. -+# -+# 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. -+# -+# 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. -+# -+ -+# BTIF driver for AD DIE -+# If KERNELRELEASE is defined, we've been invoked from the -+# kernel build system and can use its language. -+ifneq ($(KERNELRELEASE),) -+ #subdir-ccflags-y can be used in 2.6.34 in the future -+ MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM)) -+ subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include -+ subdir-ccflags-y += -I$(srctree)/arch/arm/mach-$(MTK_PLATFORM)/include/mach -+ subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat -+ -+ obj-y += common/ -+ -+# Otherwise we were called directly from the command -+# line; invoke the kernel build system. -+else -+ KERNELDIR ?= /lib/modules/$(shell uname -r)/build -+ PWD := $(shell pwd) -+default: -+ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules -+endif -diff --git a/drivers/misc/mediatek/btif/common/Makefile b/drivers/misc/mediatek/btif/common/Makefile -new file mode 100644 -index 0000000000000..61e9d4ea9e890 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/Makefile -@@ -0,0 +1,31 @@ -+# -+# Copyright (C) 2015 MediaTek Inc. -+# -+# 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. -+# -+# 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. -+# -+ -+# BTIF driver for AD DIE -+# If KERNELRELEASE is defined, we've been invoked from the -+# kernel build system and can use its language. -+ifneq ($(KERNELRELEASE),) -+ ccflags-y += -I$(src)/inc -+ ccflags-y += -I$(src)/plat_inc -+ -+ obj-y += btif.o -+ btif-y := mtk_btif.o mtk_btif_exp.o btif_dma_plat.o btif_plat.o -+ -+# Otherwise we were called directly from the command -+# line; invoke the kernel build system. -+else -+ KERNELDIR ?= /lib/modules/$(shell uname -r)/build -+ PWD := $(shell pwd) -+default: -+ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules -+endif -diff --git a/drivers/misc/mediatek/btif/common/btif_dma_plat.c b/drivers/misc/mediatek/btif/common/btif_dma_plat.c -new file mode 100644 -index 0000000000000..58be46927953b ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/btif_dma_plat.c -@@ -0,0 +1,1436 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#include -+#include -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "MTK-BTIF-DMA" -+ -+#include "btif_dma_priv.h" -+ -+#define DMA_USER_ID "btif_driver" -+ -+/************************************Global variable***********************************/ -+ -+static MTK_BTIF_DMA_VFIFO mtk_tx_dma_vfifo = { -+ .vfifo = { -+ .p_vir_addr = NULL, -+ .phy_addr = 0, -+ .vfifo_size = TX_DMA_VFF_SIZE, -+ .thre = DMA_TX_THRE(TX_DMA_VFF_SIZE), -+ }, -+ .wpt = 0, -+ .last_wpt_wrap = 0, -+ .rpt = 0, -+ .last_rpt_wrap = 0, -+}; -+ -+static MTK_BTIF_IRQ_STR mtk_btif_tx_dma_irq = { -+ .name = "mtk btif tx dma irq", -+ .is_irq_sup = true, -+ .reg_flag = false, -+#ifdef CONFIG_OF -+ .irq_flags = IRQF_TRIGGER_NONE, -+#else -+ .irq_id = MT_DMA_BTIF_TX_IRQ_ID, -+ .sens_type = IRQ_SENS_LVL, -+ .lvl_type = IRQ_LVL_LOW, -+#endif -+ .p_irq_handler = NULL, -+}; -+ -+static MTK_BTIF_DMA_VFIFO mtk_rx_dma_vfifo = { -+ .vfifo = { -+ .p_vir_addr = NULL, -+ .phy_addr = 0, -+ .vfifo_size = RX_DMA_VFF_SIZE, -+ .thre = DMA_RX_THRE(RX_DMA_VFF_SIZE), -+ }, -+ -+ .wpt = 0, -+ .last_wpt_wrap = 0, -+ .rpt = 0, -+ .last_rpt_wrap = 0, -+}; -+ -+static MTK_BTIF_IRQ_STR mtk_btif_rx_dma_irq = { -+ .name = "mtk btif rx dma irq", -+ .is_irq_sup = true, -+ .reg_flag = false, -+#ifdef CONFIG_OF -+ .irq_flags = IRQF_TRIGGER_NONE, -+#else -+ .irq_id = MT_DMA_BTIF_RX_IRQ_ID, -+ .sens_type = IRQ_SENS_LVL, -+ .lvl_type = IRQ_LVL_LOW, -+#endif -+ .p_irq_handler = NULL, -+}; -+ -+static MTK_DMA_INFO_STR mtk_btif_tx_dma = { -+#ifndef CONFIG_OF -+ .base = AP_DMA_BASE + BTIF_TX_DMA_OFFSET, -+#endif -+ .dir = DMA_DIR_TX, -+ .p_irq = &mtk_btif_tx_dma_irq, -+ .p_vfifo = &(mtk_tx_dma_vfifo.vfifo), -+}; -+ -+static MTK_DMA_INFO_STR mtk_btif_rx_dma = { -+#ifndef CONFIG_OF -+ .base = AP_DMA_BASE + BTIF_RX_DMA_OFFSET, -+#endif -+ .dir = DMA_DIR_RX, -+ .p_irq = &mtk_btif_rx_dma_irq, -+ .p_vfifo = &(mtk_rx_dma_vfifo.vfifo), -+}; -+ -+static spinlock_t g_clk_cg_spinlock; /*dma clock's spinlock */ -+ -+/************************************Function declearation***********************************/ -+static int _is_tx_dma_in_flush(P_MTK_DMA_INFO_STR p_dma_info); -+static int _tx_dma_flush(P_MTK_DMA_INFO_STR p_dma_info); -+static int btif_rx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_DMA_CTRL ctrl_id); -+static int btif_tx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_DMA_CTRL ctrl_id); -+static int btif_rx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en); -+static int btif_tx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en); -+static int hal_rx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_BTIF_REG_ID flag); -+static int hal_tx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_BTIF_REG_ID flag); -+static int is_tx_dma_irq_finish_done(P_MTK_DMA_INFO_STR p_dma_info); -+static int _btif_dma_dump_dbg_reg(void); -+static void hal_btif_tx_dma_vff_set_for_4g(void); -+static void hal_btif_rx_dma_vff_set_for_4g(void); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_ier_ctrl -+* DESCRIPTION -+* BTIF Tx DMA's interrupt enable/disable -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* enable [IN] control if tx interrupt enabled or not -+* dma_dir [IN] DMA's direction -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int hal_btif_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_receive_data -+* DESCRIPTION -+* receive data from btif module in DMA polling mode -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* positive means data is available, 0 means no data available -+*****************************************************************************/ -+#ifndef MTK_BTIF_MARK_UNUSED_API -+static int hal_dma_receive_data(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, -+ const unsigned int max_len); -+ -+/************************************Function***********************************/ -+#endif -+ -+#ifdef CONFIG_OF -+static void hal_dma_set_default_setting(ENUM_DMA_DIR dma_dir) -+{ -+ struct device_node *node = NULL; -+ unsigned int irq_info[3] = {0, 0, 0}; -+ unsigned int phy_base; -+ -+ if (dma_dir == DMA_DIR_RX) { -+ node = of_find_compatible_node(NULL, NULL, "mediatek,btif_rx"); -+ if (node) { -+ mtk_btif_rx_dma.p_irq->irq_id = irq_of_parse_and_map(node, 0); -+ /*fixme, be compitable arch 64bits*/ -+ mtk_btif_rx_dma.base = (unsigned long)of_iomap(node, 0); -+ BTIF_INFO_FUNC("get rx_dma irq(%d),register base(0x%lx)\n", -+ mtk_btif_rx_dma.p_irq->irq_id, mtk_btif_rx_dma.base); -+ } else { -+ BTIF_ERR_FUNC("get rx_dma device node fail\n"); -+ } -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ BTIF_ERR_FUNC("get interrupt flag from DTS fail\n"); -+ } else { -+ mtk_btif_rx_dma.p_irq->irq_flags = irq_info[2]; -+ BTIF_INFO_FUNC("get interrupt flag(0x%x)\n", -+ mtk_btif_rx_dma.p_irq->irq_flags); -+ } -+ if (of_property_read_u32_index(node, "reg", 1, &phy_base)) { -+ BTIF_ERR_FUNC("get register phy base from DTS fail,dma_dir(%d)\n", -+ dma_dir); -+ } else { -+ BTIF_INFO_FUNC("get register phy base dma_dir(%d)(0x%x)\n", -+ dma_dir, (unsigned int)phy_base); -+ } -+ } else if (dma_dir == DMA_DIR_TX) { -+ node = of_find_compatible_node(NULL, NULL, "mediatek,btif_tx"); -+ if (node) { -+ mtk_btif_tx_dma.p_irq->irq_id = irq_of_parse_and_map(node, 0); -+ /*fixme, be compitable arch 64bits*/ -+ mtk_btif_tx_dma.base = (unsigned long)of_iomap(node, 0); -+ BTIF_INFO_FUNC("get tx_dma irq(%d),register base(0x%lx)\n", -+ mtk_btif_tx_dma.p_irq->irq_id, mtk_btif_tx_dma.base); -+ } else { -+ BTIF_ERR_FUNC("get tx_dma device node fail\n"); -+ } -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ BTIF_ERR_FUNC("get interrupt flag from DTS fail\n"); -+ } else { -+ mtk_btif_tx_dma.p_irq->irq_flags = irq_info[2]; -+ BTIF_INFO_FUNC("get interrupt flag(0x%x)\n", -+ mtk_btif_tx_dma.p_irq->irq_flags); -+ } -+ -+ if (of_property_read_u32_index(node, "reg", 1, &phy_base)) { -+ BTIF_ERR_FUNC("get register phy base from DTS fail,dma_dir(%d)\n", -+ dma_dir); -+ } else { -+ BTIF_INFO_FUNC("get register phy base dma_dir(%d)(0x%x)\n", -+ dma_dir, (unsigned int)phy_base); -+ } -+ } -+ -+} -+#endif -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_info_get -+* DESCRIPTION -+* get btif tx dma channel's information -+* PARAMETERS -+* dma_dir [IN] DMA's direction -+* RETURNS -+* pointer to btif dma's information structure -+*****************************************************************************/ -+P_MTK_DMA_INFO_STR hal_btif_dma_info_get(ENUM_DMA_DIR dma_dir) -+{ -+ P_MTK_DMA_INFO_STR p_dma_info = NULL; -+ -+ BTIF_TRC_FUNC(); -+#ifdef CONFIG_OF -+ hal_dma_set_default_setting(dma_dir); -+#endif -+ if (dma_dir == DMA_DIR_RX) -+ /*Rx DMA*/ -+ p_dma_info = &mtk_btif_rx_dma; -+ else if (dma_dir == DMA_DIR_TX) -+ /*Tx DMA*/ -+ p_dma_info = &mtk_btif_tx_dma; -+ else -+ /*print error log*/ -+ BTIF_ERR_FUNC("invalid DMA dir (%d)\n", dma_dir); -+ spin_lock_init(&g_clk_cg_spinlock); -+ BTIF_TRC_FUNC(); -+ return p_dma_info; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_ctrl -+* DESCRIPTION -+* control clock output enable/disable of DMA module -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dma_clk_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_CLOCK_CTRL flag) -+{ -+/*In MTK DMA BTIF channel, there's only one global CG on AP_DMA, no sub channel's CG bit*/ -+/*according to Artis's comment, clock of DMA and BTIF is default off, so we assume it to be off by default*/ -+ int i_ret = 0; -+ unsigned long irq_flag = 0; -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ static atomic_t s_clk_ref = ATOMIC_INIT(0); -+#else -+ static ENUM_CLOCK_CTRL status = CLK_OUT_DISABLE; -+#endif -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag); -+ -+#if MTK_BTIF_ENABLE_CLK_CTL -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ -+ if (flag == CLK_OUT_ENABLE) { -+ if (atomic_inc_return(&s_clk_ref) == 1) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = enable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); -+#else -+ BTIF_DBG_FUNC("[CCF]enable clk_btif_apdma\n"); -+ i_ret = clk_enable(clk_btif_apdma); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("enable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", -+ i_ret); -+ } -+ } -+ } else if (flag == CLK_OUT_DISABLE) { -+ if (atomic_dec_return(&s_clk_ref) == 0) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = disable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("disable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", -+ i_ret); -+ } -+#else -+ BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif_apdma) calling\n"); -+ clk_disable(clk_btif_apdma); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ } -+ } else { -+ i_ret = ERR_INVALID_PAR; -+ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); -+ } -+ -+#else -+ -+ if (status == flag) { -+ i_ret = 0; -+ BTIF_DBG_FUNC("dma clock already %s\n", -+ CLK_OUT_ENABLE == -+ status ? "enabled" : "disabled"); -+ } else { -+ if (flag == CLK_OUT_ENABLE) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = enable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); -+#else -+ BTIF_DBG_FUNC("[CCF]enable clk_btif_apdma\n"); -+ i_ret = clk_enable(clk_btif_apdma); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ status = (i_ret == 0) ? flag : status; -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("enable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", -+ i_ret); -+ } -+ } else if (flag == CLK_OUT_DISABLE) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = disable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); -+ status = (i_ret == 0) ? flag : status; -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("disable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", -+ i_ret); -+ } -+#else -+ BTIF_DBG_FUNC("[CCF] clk_disable_unprepare(clk_btif_apdma) calling\n"); -+ clk_disable(clk_btif_apdma); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ } else { -+ i_ret = ERR_INVALID_PAR; -+ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); -+ } -+ } -+#endif -+ -+#else -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ -+#else -+ -+ status = flag; -+#endif -+ -+ i_ret = 0; -+#endif -+ -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ if (i_ret == 0) { -+ BTIF_DBG_FUNC("dma clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); -+ } else { -+ BTIF_ERR_FUNC("%s dma clock failed, ret(%d)\n", -+ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); -+ } -+#else -+ -+ if (i_ret == 0) { -+ BTIF_DBG_FUNC("dma clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); -+ } else { -+ BTIF_ERR_FUNC("%s dma clock failed, ret(%d)\n", -+ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); -+ } -+#endif -+#if defined(CONFIG_MTK_CLKMGR) -+ BTIF_DBG_FUNC("DMA's clock is %s\n", (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) ? "off" : "on"); -+#endif -+ return i_ret; -+} -+ -+int hal_btif_dma_hw_init(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ int i_ret = 0; -+ unsigned int dat = 0; -+ unsigned long base = p_dma_info->base; -+ unsigned long addr_h = 0; -+ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; -+ P_MTK_BTIF_DMA_VFIFO p_mtk_dma_vfifo = container_of(p_vfifo, -+ MTK_BTIF_DMA_VFIFO, -+ vfifo); -+ -+ if (p_dma_info->dir == DMA_DIR_RX) { -+ /*Rx DMA*/ -+ /*do hardware reset*/ -+ /* BTIF_SET_BIT(RX_DMA_RST(base), DMA_HARD_RST);*/ -+ /* BTIF_CLR_BIT(RX_DMA_RST(base), DMA_HARD_RST);*/ -+ BTIF_SET_BIT(RX_DMA_RST(base), DMA_WARM_RST); -+ do { -+ dat = BTIF_READ32(RX_DMA_EN(base)); -+ } while (0x01 & dat); -+ /*write vfifo base address to VFF_ADDR*/ -+ btif_reg_sync_writel(p_vfifo->phy_addr, RX_DMA_VFF_ADDR(base)); -+ if (enable_4G()) -+ hal_btif_rx_dma_vff_set_for_4g(); -+ else { -+ addr_h = p_vfifo->phy_addr >> 16; -+ addr_h = addr_h >> 16; -+ btif_reg_sync_writel(addr_h, RX_DMA_VFF_ADDR_H(base)); -+ } -+ /*write vfifo length to VFF_LEN*/ -+ btif_reg_sync_writel(p_vfifo->vfifo_size, RX_DMA_VFF_LEN(base)); -+ /*write wpt to VFF_WPT*/ -+ btif_reg_sync_writel(p_mtk_dma_vfifo->wpt, -+ RX_DMA_VFF_WPT(base)); -+ btif_reg_sync_writel(p_mtk_dma_vfifo->rpt, -+ RX_DMA_VFF_RPT(base)); -+ /*write vff_thre to VFF_THRESHOLD*/ -+ btif_reg_sync_writel(p_vfifo->thre, RX_DMA_VFF_THRE(base)); -+ /*clear Rx DMA's interrupt status*/ -+ BTIF_SET_BIT(RX_DMA_INT_FLAG(base), -+ RX_DMA_INT_DONE | RX_DMA_INT_THRE); -+ -+ /*enable Rx IER by default*/ -+ btif_rx_dma_ier_ctrl(p_dma_info, true); -+ } else { -+/*Tx DMA*/ -+/*do hardware reset*/ -+/* BTIF_SET_BIT(TX_DMA_RST(base), DMA_HARD_RST);*/ -+/* BTIF_CLR_BIT(TX_DMA_RST(base), DMA_HARD_RST);*/ -+ BTIF_SET_BIT(TX_DMA_RST(base), DMA_WARM_RST); -+ do { -+ dat = BTIF_READ32(TX_DMA_EN(base)); -+ } while (0x01 & dat); -+/*write vfifo base address to VFF_ADDR*/ -+ btif_reg_sync_writel(p_vfifo->phy_addr, TX_DMA_VFF_ADDR(base)); -+ if (enable_4G()) -+ hal_btif_tx_dma_vff_set_for_4g(); -+ else { -+ addr_h = p_vfifo->phy_addr >> 16; -+ addr_h = addr_h >> 16; -+ btif_reg_sync_writel(addr_h, TX_DMA_VFF_ADDR_H(base)); -+ } -+/*write vfifo length to VFF_LEN*/ -+ btif_reg_sync_writel(p_vfifo->vfifo_size, TX_DMA_VFF_LEN(base)); -+/*write wpt to VFF_WPT*/ -+ btif_reg_sync_writel(p_mtk_dma_vfifo->wpt, -+ TX_DMA_VFF_WPT(base)); -+ btif_reg_sync_writel(p_mtk_dma_vfifo->rpt, -+ TX_DMA_VFF_RPT(base)); -+/*write vff_thre to VFF_THRESHOLD*/ -+ btif_reg_sync_writel(p_vfifo->thre, TX_DMA_VFF_THRE(base)); -+ -+ BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), TX_DMA_INT_FLAG_MASK); -+ -+ hal_btif_dma_ier_ctrl(p_dma_info, false); -+ } -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_ctrl -+* DESCRIPTION -+* enable/disable Tx DMA channel -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* ctrl_id [IN] enable/disable ID -+* RETURNS -+* 0 means success; negative means fail -+*****************************************************************************/ -+int hal_btif_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id) -+{ -+ unsigned int i_ret = -1; -+ ENUM_DMA_DIR dir = p_dma_info->dir; -+ -+ if (dir == DMA_DIR_RX) -+ i_ret = btif_rx_dma_ctrl(p_dma_info, ctrl_id); -+ else if (dir == DMA_DIR_TX) -+ i_ret = btif_tx_dma_ctrl(p_dma_info, ctrl_id); -+ else { -+ /*TODO: print error log*/ -+ BTIF_ERR_FUNC("invalid dma ctrl id (%d)\n", ctrl_id); -+ i_ret = ERR_INVALID_PAR; -+ } -+ return i_ret; -+} -+ -+int hal_btif_dma_rx_cb_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ dma_rx_buf_write rx_cb) -+{ -+ if (p_dma_info->rx_cb != NULL) { -+ BTIF_DBG_FUNC -+ ("rx_cb already registered, replace (0x%p) with (0x%p)\n", -+ p_dma_info->rx_cb, rx_cb); -+ } -+ p_dma_info->rx_cb = rx_cb; -+ return 0; -+} -+ -+int btif_tx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int dat; -+ -+ BTIF_TRC_FUNC(); -+ if (ctrl_id == DMA_CTRL_DISABLE) { -+ /*if write 0 to EN bit, DMA will be stopped imediately*/ -+ /*if write 1 to STOP bit, DMA will be stopped after current transaction finished*/ -+ /*BTIF_CLR_BIT(TX_DMA_EN(base), DMA_EN_BIT);*/ -+ BTIF_SET_BIT(TX_DMA_STOP(base), DMA_STOP_BIT); -+ do { -+ dat = BTIF_READ32(TX_DMA_STOP(base)); -+ } while (0x1 & dat); -+ BTIF_DBG_FUNC("BTIF Tx DMA disabled,EN(0x%x),STOP(0x%x)\n", -+ BTIF_READ32(TX_DMA_EN(base)), BTIF_READ32(TX_DMA_STOP(base))); -+ i_ret = 0; -+ } else if (ctrl_id == DMA_CTRL_ENABLE) { -+ BTIF_SET_BIT(TX_DMA_EN(base), DMA_EN_BIT); -+ BTIF_DBG_FUNC("BTIF Tx DMA enabled\n"); -+ i_ret = 0; -+ } else { -+/*TODO: print error log*/ -+ BTIF_ERR_FUNC("invalid DMA ctrl_id (%d)\n", ctrl_id); -+ i_ret = ERR_INVALID_PAR; -+ } -+ BTIF_TRC_FUNC(); -+ return i_ret; -+} -+ -+int btif_rx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int dat; -+ -+ BTIF_TRC_FUNC(); -+ -+ if (ctrl_id == DMA_CTRL_DISABLE) { -+ /*if write 0 to EN bit, DMA will be stopped imediately*/ -+ /*if write 1 to STOP bit, DMA will be stopped after current transaction finished*/ -+ /*BTIF_CLR_BIT(RX_DMA_EN(base), DMA_EN_BIT);*/ -+ BTIF_SET_BIT(RX_DMA_STOP(base), DMA_STOP_BIT); -+ do { -+ dat = BTIF_READ32(RX_DMA_STOP(base)); -+ } while (0x1 & dat); -+ BTIF_DBG_FUNC("BTIF Rx DMA disabled,EN(0x%x),STOP(0x%x)\n", -+ BTIF_READ32(RX_DMA_EN(base)), BTIF_READ32(RX_DMA_STOP(base))); -+ i_ret = 0; -+ } else if (ctrl_id == DMA_CTRL_ENABLE) { -+ BTIF_SET_BIT(RX_DMA_EN(base), DMA_EN_BIT); -+ BTIF_DBG_FUNC("BTIF Rx DMA enabled\n"); -+ i_ret = 0; -+ } else { -+/*TODO: print error log*/ -+ BTIF_ERR_FUNC("invalid DMA ctrl_id (%d)\n", ctrl_id); -+ i_ret = ERR_INVALID_PAR; -+ } -+ BTIF_TRC_FUNC(); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_vfifo_reset -+* DESCRIPTION -+* reset tx virtual fifo information, except memory information -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_vfifo_reset(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ unsigned int i_ret = -1; -+ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; -+ P_MTK_BTIF_DMA_VFIFO p_mtk_dma_vfifo = container_of(p_vfifo, -+ MTK_BTIF_DMA_VFIFO, -+ vfifo); -+ -+ BTIF_TRC_FUNC(); -+ p_mtk_dma_vfifo->rpt = 0; -+ p_mtk_dma_vfifo->last_rpt_wrap = 0; -+ p_mtk_dma_vfifo->wpt = 0; -+ p_mtk_dma_vfifo->last_wpt_wrap = 0; -+ BTIF_TRC_FUNC(); -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_ier_ctrl -+* DESCRIPTION -+* BTIF Tx DMA's interrupt enable/disable -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* enable [IN] control if tx interrupt enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en) -+{ -+ unsigned int i_ret = -1; -+ ENUM_DMA_DIR dir = p_dma_info->dir; -+ -+ if (dir == DMA_DIR_RX) { -+ i_ret = btif_rx_dma_ier_ctrl(p_dma_info, en); -+ } else if (dir == DMA_DIR_TX) { -+ i_ret = btif_tx_dma_ier_ctrl(p_dma_info, en); -+ } else { -+/*TODO: print error log*/ -+ BTIF_ERR_FUNC("invalid DMA dma dir (%d)\n", dir); -+ i_ret = ERR_INVALID_PAR; -+ } -+ -+ return i_ret; -+} -+ -+int btif_rx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ -+ BTIF_TRC_FUNC(); -+ if (!en) { -+ BTIF_CLR_BIT(RX_DMA_INT_EN(base), -+ (RX_DMA_INT_THRE_EN | RX_DMA_INT_DONE_EN)); -+ } else { -+ BTIF_SET_BIT(RX_DMA_INT_EN(base), -+ (RX_DMA_INT_THRE_EN | RX_DMA_INT_DONE_EN)); -+ } -+ i_ret = 0; -+ BTIF_TRC_FUNC(); -+ -+ return i_ret; -+} -+ -+int btif_tx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ -+ BTIF_TRC_FUNC(); -+ if (!en) -+ BTIF_CLR_BIT(TX_DMA_INT_EN(base), TX_DMA_INTEN_BIT); -+ else -+ BTIF_SET_BIT(TX_DMA_INT_EN(base), TX_DMA_INTEN_BIT); -+ i_ret = 0; -+ BTIF_TRC_FUNC(); -+ -+ return i_ret; -+} -+ -+static int is_tx_dma_irq_finish_done(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ int tx_irq_done = 0; -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+/*if we enable this clock reference couner, just return , because when enter IRQ handler, DMA's clock will be opened*/ -+ tx_irq_done = 1; -+#else -+ unsigned long flag = 0; -+ unsigned long base = p_dma_info->base; -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), flag); -+ tx_irq_done = ((BTIF_READ32(TX_DMA_INT_FLAG(base)) & TX_DMA_INT_FLAG_MASK) == 0) ? 1 : 0; -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); -+#endif -+ return tx_irq_done; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_irq_handler -+* DESCRIPTION -+* lower level tx interrupt handler -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_tx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+#define MAX_CONTINIOUS_TIMES 512 -+ unsigned int i_ret = -1; -+ unsigned int valid_size = 0; -+ unsigned int vff_len = 0; -+ unsigned int left_len = 0; -+ unsigned long base = p_dma_info->base; -+ static int flush_irq_counter; -+ static struct timeval start_timer; -+ static struct timeval end_timer; -+ unsigned long flag = 0; -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), flag); -+ -+#if defined(CONFIG_MTK_CLKMGR) -+ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); -+ BTIF_ERR_FUNC -+ ("%s: clock is off before irq status clear done!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+/*check if Tx VFF Left Size equal to VFIFO size or not*/ -+ vff_len = BTIF_READ32(TX_DMA_VFF_LEN(base)); -+ valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)); -+ left_len = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base)); -+ if (flush_irq_counter == 0) -+ do_gettimeofday(&start_timer); -+ if ((valid_size > 0) && (valid_size < 8)) { -+ i_ret = _tx_dma_flush(p_dma_info); -+ flush_irq_counter++; -+ if (flush_irq_counter >= MAX_CONTINIOUS_TIMES) { -+ do_gettimeofday(&end_timer); -+/* -+ * when btif tx fifo cannot accept any data and counts of bytes left in tx vfifo < 8 for a while -+ * we assume that btif cannot send data for a long time -+ * in order not to generate interrupt continiously, which may effect system's performance. -+ * we clear tx flag and disable btif tx interrupt -+ */ -+/*clear interrupt flag*/ -+ BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), -+ TX_DMA_INT_FLAG_MASK); -+/*vFIFO data has been read by DMA controller, just disable tx dma's irq*/ -+ i_ret = hal_btif_dma_ier_ctrl(p_dma_info, false); -+ BTIF_ERR_FUNC -+ ("**********************ERROR, ERROR, ERROR**************************\n"); -+ BTIF_ERR_FUNC -+ ("BTIF Tx IRQ happened %d times (continiously), between %d.%d and %d.%d\n", -+ MAX_CONTINIOUS_TIMES, start_timer.tv_sec, -+ start_timer.tv_usec, end_timer.tv_usec, -+ end_timer.tv_usec); -+ } -+ } else if (vff_len == left_len) { -+ flush_irq_counter = 0; -+/*clear interrupt flag*/ -+ BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), TX_DMA_INT_FLAG_MASK); -+/*vFIFO data has been read by DMA controller, just disable tx dma's irq*/ -+ i_ret = hal_btif_dma_ier_ctrl(p_dma_info, false); -+ } else { -+#if 0 -+ BTIF_ERR_FUNC -+ ("**********************WARNING**************************\n"); -+ BTIF_ERR_FUNC("invalid irq condition, dump register\n"); -+ hal_dma_dump_reg(p_dma_info, REG_TX_DMA_ALL); -+#endif -+ BTIF_DBG_FUNC -+ ("superious IRQ occurs, vff_len(%d), valid_size(%d), left_len(%d)\n", -+ vff_len, valid_size, left_len); -+ } -+ -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_send_data -+* DESCRIPTION -+* send data through btif in DMA mode -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN] pointer to rx data buffer -+* max_len [IN] tx buffer length -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_dma_send_data(P_MTK_DMA_INFO_STR p_dma_info, -+ const unsigned char *p_buf, const unsigned int buf_len) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; -+ unsigned int len_to_send = buf_len; -+ unsigned int ava_len = 0; -+ unsigned int wpt = 0; -+ unsigned int last_wpt_wrap = 0; -+ unsigned int vff_size = 0; -+ unsigned char *p_data = (unsigned char *)p_buf; -+ P_MTK_BTIF_DMA_VFIFO p_mtk_vfifo = container_of(p_vfifo, -+ MTK_BTIF_DMA_VFIFO, -+ vfifo); -+ -+ BTIF_TRC_FUNC(); -+ if ((p_buf == NULL) || (buf_len == 0)) { -+ i_ret = ERR_INVALID_PAR; -+ BTIF_ERR_FUNC("invalid parameters, p_buf:0x%p, buf_len:%d\n", -+ p_buf, buf_len); -+ return i_ret; -+ } -+/*check if tx dma in flush operation? if yes, should wait until DMA finish flush operation*/ -+/*currently uplayer logic will make sure this pre-condition*/ -+/*disable Tx IER, in case Tx irq happens, flush bit may be set in irq handler*/ -+ btif_tx_dma_ier_ctrl(p_dma_info, false); -+ -+ vff_size = p_mtk_vfifo->vfifo.vfifo_size; -+ ava_len = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base)); -+ wpt = BTIF_READ32(TX_DMA_VFF_WPT(base)) & DMA_WPT_MASK; -+ last_wpt_wrap = BTIF_READ32(TX_DMA_VFF_WPT(base)) & DMA_WPT_WRAP; -+ -+/* -+ * copy data to vFIFO, Note: ava_len should always large than buf_len, -+ * otherwise common logic layer will not call hal_dma_send_data -+ */ -+ if (buf_len > ava_len) { -+ BTIF_ERR_FUNC -+ ("length to send:(%d) < length available(%d), abnormal!!!---!!!\n", -+ buf_len, ava_len); -+ WARN_ON(buf_len > ava_len); /* this will cause kernel panic */ -+ } -+ -+ len_to_send = buf_len < ava_len ? buf_len : ava_len; -+ if (len_to_send + wpt >= vff_size) { -+ unsigned int tail_len = vff_size - wpt; -+ -+ memcpy((p_mtk_vfifo->vfifo.p_vir_addr + wpt), p_data, tail_len); -+ p_data += tail_len; -+ memcpy(p_mtk_vfifo->vfifo.p_vir_addr, -+ p_data, len_to_send - tail_len); -+/*make sure all data write to memory area tx vfifo locates*/ -+ mb(); -+ -+/*calculate WPT*/ -+ wpt = wpt + len_to_send - vff_size; -+ last_wpt_wrap ^= DMA_WPT_WRAP; -+ } else { -+ memcpy((p_mtk_vfifo->vfifo.p_vir_addr + wpt), -+ p_data, len_to_send); -+/*make sure all data write to memory area tx vfifo locates*/ -+ mb(); -+ -+/*calculate WPT*/ -+ wpt += len_to_send; -+ } -+ p_mtk_vfifo->wpt = wpt; -+ p_mtk_vfifo->last_wpt_wrap = last_wpt_wrap; -+ -+/*make sure tx dma is allowed(tx flush bit is not set) to use before update WPT*/ -+ if (hal_dma_is_tx_allow(p_dma_info)) { -+ /*make sure tx dma enabled*/ -+ hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE); -+ -+ /*update WTP to Tx DMA controller's control register*/ -+ btif_reg_sync_writel(wpt | last_wpt_wrap, TX_DMA_VFF_WPT(base)); -+ -+ if ((BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)) < 8) && -+ (BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)) > 0)) { -+ /* -+ * 0 < valid size in Tx vFIFO < 8 && TX Flush is not in process? -+ * if yes, set flush bit to DMA -+ */ -+ _tx_dma_flush(p_dma_info); -+ } -+ i_ret = len_to_send; -+ } else { -+/*TODO: print error log*/ -+ BTIF_ERR_FUNC("Tx DMA flush operation is in process, this case should never happen,", -+ "please check if tx operation is allowed before call this API\n"); -+/*if flush operation is in process , we will return 0*/ -+ i_ret = 0; -+ } -+ -+/*Enable Tx IER*/ -+ btif_tx_dma_ier_ctrl(p_dma_info, true); -+ -+ BTIF_TRC_FUNC(); -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_is_tx_complete -+* DESCRIPTION -+* get tx complete flag -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* true means tx complete, false means tx in process -+*****************************************************************************/ -+bool hal_dma_is_tx_complete(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ bool b_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)); -+ unsigned int inter_size = BTIF_READ32(TX_DMA_INT_BUF_SIZE(base)); -+ unsigned int tx_done = is_tx_dma_irq_finish_done(p_dma_info); -+ -+/* -+ * only when virtual FIFO valid size and Tx channel internal buffer size are both becomes to be 0, -+ * we can identify tx operation finished -+ * confirmed with DE. -+ */ -+ if ((valid_size == 0) && (inter_size == 0) && (tx_done == 1)) { -+ b_ret = true; -+ BTIF_DBG_FUNC("DMA tx finished.\n"); -+ } else { -+ BTIF_DBG_FUNC -+ ("DMA tx is in process. vfifo valid size(%d), dma internal size (%d), tx_done(%d)\n", -+ valid_size, inter_size, tx_done); -+ b_ret = false; -+ } -+ -+ return b_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_get_ava_room -+* DESCRIPTION -+* get tx available room -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* available room size -+*****************************************************************************/ -+int hal_dma_get_ava_room(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ -+/*read vFIFO's left size*/ -+ i_ret = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base)); -+ BTIF_DBG_FUNC("DMA tx ava room (%d).\n", i_ret); -+ if (i_ret == 0) -+ BTIF_INFO_FUNC("DMA tx vfifo is full.\n"); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_is_tx_allow -+* DESCRIPTION -+* is tx operation allowed by DMA -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* true if tx operation is allowed; false if tx is not allowed -+*****************************************************************************/ -+bool hal_dma_is_tx_allow(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+#define MIN_TX_MB ((26 * 1000000 / 13) / 1000000) -+#define AVE_TX_MB ((26 * 1000000 / 8) / 1000000) -+ -+ bool b_ret = false; -+ unsigned int wait_us = 8 / MIN_TX_MB; /*only ava length */ -+/*see if flush operation is in process*/ -+ b_ret = _is_tx_dma_in_flush(p_dma_info) ? false : true; -+ if (!b_ret) { -+ usleep_range(wait_us, 2 * wait_us); -+ b_ret = _is_tx_dma_in_flush(p_dma_info) ? false : true; -+ } -+ if (!b_ret) -+ BTIF_WARN_FUNC("btif tx dma is not allowed\n"); -+/*after Tx flush operation finished, HW will set DMA_EN back to 0 and stop DMA*/ -+ return b_ret; -+} -+ -+ -+/***************************************************************************** -+* FUNCTION -+* hal_rx_dma_irq_handler -+* DESCRIPTION -+* lower level rx interrupt handler -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_rx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, const unsigned int max_len) -+{ -+ int i_ret = -1; -+ unsigned int valid_len = 0; -+ unsigned int wpt_wrap = 0; -+ unsigned int rpt_wrap = 0; -+ unsigned int wpt = 0; -+ unsigned int rpt = 0; -+ unsigned int tail_len = 0; -+ unsigned int real_len = 0; -+ unsigned long base = p_dma_info->base; -+ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; -+ dma_rx_buf_write rx_cb = p_dma_info->rx_cb; -+ unsigned char *p_vff_buf = NULL; -+ unsigned char *vff_base = p_vfifo->p_vir_addr; -+ unsigned int vff_size = p_vfifo->vfifo_size; -+ P_MTK_BTIF_DMA_VFIFO p_mtk_vfifo = container_of(p_vfifo, -+ MTK_BTIF_DMA_VFIFO, -+ vfifo); -+ unsigned long flag = 0; -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), flag); -+#if defined(CONFIG_MTK_CLKMGR) -+ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); -+ BTIF_ERR_FUNC("%s: clock is off before irq handle done!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+/*disable DMA Rx IER*/ -+ hal_btif_dma_ier_ctrl(p_dma_info, false); -+ -+/*clear Rx DMA's interrupt status*/ -+ BTIF_SET_BIT(RX_DMA_INT_FLAG(base), RX_DMA_INT_DONE | RX_DMA_INT_THRE); -+ -+ valid_len = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base)); -+ rpt = BTIF_READ32(RX_DMA_VFF_RPT(base)); -+ wpt = BTIF_READ32(RX_DMA_VFF_WPT(base)); -+ if ((valid_len == 0) && (rpt == wpt)) { -+ BTIF_DBG_FUNC -+ ("rx interrupt, no data available in Rx DMA, wpt(0x%08x), rpt(0x%08x)\n", -+ rpt, wpt); -+ } -+ -+ i_ret = 0; -+ -+ while ((valid_len > 0) || (rpt != wpt)) { -+ rpt_wrap = rpt & DMA_RPT_WRAP; -+ wpt_wrap = wpt & DMA_WPT_WRAP; -+ rpt &= DMA_RPT_MASK; -+ wpt &= DMA_WPT_MASK; -+ -+/*calcaute length of available data in vFIFO*/ -+ if (wpt_wrap != p_mtk_vfifo->last_wpt_wrap) -+ real_len = wpt + vff_size - rpt; -+ else -+ real_len = wpt - rpt; -+ -+ if (rx_cb != NULL) { -+ tail_len = vff_size - rpt; -+ p_vff_buf = vff_base + rpt; -+ if (tail_len >= real_len) { -+ (*rx_cb) (p_dma_info, p_vff_buf, real_len); -+ } else { -+ (*rx_cb) (p_dma_info, p_vff_buf, tail_len); -+ p_vff_buf = vff_base; -+ (*rx_cb) (p_dma_info, p_vff_buf, real_len - -+ tail_len); -+ } -+ i_ret += real_len; -+ } else -+ BTIF_ERR_FUNC("no rx_cb found, please check your init process\n"); -+ mb(); -+ rpt += real_len; -+ if (rpt >= vff_size) { -+ /*read wrap bit should be revert*/ -+ rpt_wrap ^= DMA_RPT_WRAP; -+ rpt %= vff_size; -+ } -+ rpt |= rpt_wrap; -+/*record wpt, last_wpt_wrap, rpt, last_rpt_wrap*/ -+ p_mtk_vfifo->wpt = wpt; -+ p_mtk_vfifo->last_wpt_wrap = wpt_wrap; -+ -+ p_mtk_vfifo->rpt = rpt; -+ p_mtk_vfifo->last_rpt_wrap = rpt_wrap; -+ -+/*update rpt information to DMA controller*/ -+ btif_reg_sync_writel(rpt, RX_DMA_VFF_RPT(base)); -+ -+/*get vff valid size again and check if rx data is processed completely*/ -+ valid_len = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base)); -+ -+ rpt = BTIF_READ32(RX_DMA_VFF_RPT(base)); -+ wpt = BTIF_READ32(RX_DMA_VFF_WPT(base)); -+ } -+ -+/*enable DMA Rx IER*/ -+ hal_btif_dma_ier_ctrl(p_dma_info, true); -+ -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); -+ -+ return i_ret; -+} -+ -+static int hal_tx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_BTIF_REG_ID flag) -+{ -+ int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int int_flag = 0; -+ unsigned int enable = 0; -+ unsigned int stop = 0; -+ unsigned int flush = 0; -+ unsigned int wpt = 0; -+ unsigned int rpt = 0; -+ unsigned int int_buf = 0; -+ unsigned int valid_size = 0; -+ /*unsigned long irq_flag = 0;*/ -+ -+#if defined(CONFIG_MTK_CLKMGR) -+ /*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/ -+ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+ int_flag = BTIF_READ32(TX_DMA_INT_FLAG(base)); -+ enable = BTIF_READ32(TX_DMA_EN(base)); -+ stop = BTIF_READ32(TX_DMA_STOP(base)); -+ flush = BTIF_READ32(TX_DMA_FLUSH(base)); -+ wpt = BTIF_READ32(TX_DMA_VFF_WPT(base)); -+ rpt = BTIF_READ32(TX_DMA_VFF_RPT(base)); -+ int_buf = BTIF_READ32(TX_DMA_INT_BUF_SIZE(base)); -+ valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)); -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ -+ BTIF_INFO_FUNC("DMA's clock is on\n"); -+ BTIF_INFO_FUNC("Tx DMA's base address: 0x%lx\n", base); -+ -+ if (flag == REG_TX_DMA_ALL) { -+ BTIF_INFO_FUNC("TX_EN(:0x%x\n", enable); -+ BTIF_INFO_FUNC("INT_FLAG:0x%x\n", int_flag); -+ BTIF_INFO_FUNC("TX_STOP:0x%x\n", stop); -+ BTIF_INFO_FUNC("TX_FLUSH:0x%x\n", flush); -+ BTIF_INFO_FUNC("TX_WPT:0x%x\n", wpt); -+ BTIF_INFO_FUNC("TX_RPT:0x%x\n", rpt); -+ BTIF_INFO_FUNC("INT_BUF_SIZE:0x%x\n", int_buf); -+ BTIF_INFO_FUNC("VALID_SIZE:0x%x\n", valid_size); -+ BTIF_INFO_FUNC("INT_EN:0x%x\n", -+ BTIF_READ32(TX_DMA_INT_EN(base))); -+ BTIF_INFO_FUNC("TX_RST:0x%x\n", BTIF_READ32(TX_DMA_RST(base))); -+ BTIF_INFO_FUNC("VFF_ADDR:0x%x\n", -+ BTIF_READ32(TX_DMA_VFF_ADDR(base))); -+ BTIF_INFO_FUNC("VFF_LEN:0x%x\n", -+ BTIF_READ32(TX_DMA_VFF_LEN(base))); -+ BTIF_INFO_FUNC("TX_THRE:0x%x\n", -+ BTIF_READ32(TX_DMA_VFF_THRE(base))); -+ BTIF_INFO_FUNC("W_INT_BUF_SIZE:0x%x\n", -+ BTIF_READ32(TX_DMA_W_INT_BUF_SIZE(base))); -+ BTIF_INFO_FUNC("LEFT_SIZE:0x%x\n", -+ BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base))); -+ BTIF_INFO_FUNC("DBG_STATUS:0x%x\n", -+ BTIF_READ32(TX_DMA_DEBUG_STATUS(base))); -+ i_ret = 0; -+ } else { -+ BTIF_WARN_FUNC("unknown flag:%d\n", flag); -+ } -+ BTIF_INFO_FUNC("tx dma %s\n", (enable & DMA_EN_BIT) && -+ (!(stop && DMA_STOP_BIT)) ? "enabled" : "stopped"); -+ BTIF_INFO_FUNC("data in tx dma is %s sent by HW\n", -+ ((wpt == rpt) && -+ (int_buf == 0)) ? "completely" : "not completely"); -+ -+ return i_ret; -+} -+ -+static int hal_rx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_BTIF_REG_ID flag) -+{ -+ int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int int_flag = 0; -+ unsigned int enable = 0; -+ unsigned int stop = 0; -+ unsigned int flush = 0; -+ unsigned int wpt = 0; -+ unsigned int rpt = 0; -+ unsigned int int_buf = 0; -+ unsigned int valid_size = 0; -+ /*unsigned long irq_flag = 0;*/ -+#if defined(CONFIG_MTK_CLKMGR) -+ /*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/ -+ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+ BTIF_INFO_FUNC("dump DMA status register\n"); -+ _btif_dma_dump_dbg_reg(); -+ -+ int_flag = BTIF_READ32(RX_DMA_INT_FLAG(base)); -+ enable = BTIF_READ32(RX_DMA_EN(base)); -+ stop = BTIF_READ32(RX_DMA_STOP(base)); -+ flush = BTIF_READ32(RX_DMA_FLUSH(base)); -+ wpt = BTIF_READ32(RX_DMA_VFF_WPT(base)); -+ rpt = BTIF_READ32(RX_DMA_VFF_RPT(base)); -+ int_buf = BTIF_READ32(RX_DMA_INT_BUF_SIZE(base)); -+ valid_size = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base)); -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ -+ BTIF_INFO_FUNC("DMA's clock is on\n"); -+ BTIF_INFO_FUNC("Rx DMA's base address: 0x%lx\n", base); -+ -+ if (flag == REG_RX_DMA_ALL) { -+ BTIF_INFO_FUNC("RX_EN(:0x%x\n", enable); -+ BTIF_INFO_FUNC("RX_STOP:0x%x\n", stop); -+ BTIF_INFO_FUNC("RX_FLUSH:0x%x\n", flush); -+ BTIF_INFO_FUNC("INT_FLAG:0x%x\n", int_flag); -+ BTIF_INFO_FUNC("RX_WPT:0x%x\n", wpt); -+ BTIF_INFO_FUNC("RX_RPT:0x%x\n", rpt); -+ BTIF_INFO_FUNC("INT_BUF_SIZE:0x%x\n", int_buf); -+ BTIF_INFO_FUNC("VALID_SIZE:0x%x\n", valid_size); -+ BTIF_INFO_FUNC("INT_EN:0x%x\n", -+ BTIF_READ32(RX_DMA_INT_EN(base))); -+ BTIF_INFO_FUNC("RX_RST:0x%x\n", BTIF_READ32(RX_DMA_RST(base))); -+ BTIF_INFO_FUNC("VFF_ADDR:0x%x\n", -+ BTIF_READ32(RX_DMA_VFF_ADDR(base))); -+ BTIF_INFO_FUNC("VFF_LEN:0x%x\n", -+ BTIF_READ32(RX_DMA_VFF_LEN(base))); -+ BTIF_INFO_FUNC("RX_THRE:0x%x\n", -+ BTIF_READ32(RX_DMA_VFF_THRE(base))); -+ BTIF_INFO_FUNC("RX_FLOW_CTRL_THRE:0x%x\n", -+ BTIF_READ32(RX_DMA_FLOW_CTRL_THRE(base))); -+ BTIF_INFO_FUNC("LEFT_SIZE:0x%x\n", -+ BTIF_READ32(RX_DMA_VFF_LEFT_SIZE(base))); -+ BTIF_INFO_FUNC("DBG_STATUS:0x%x\n", -+ BTIF_READ32(RX_DMA_DEBUG_STATUS(base))); -+ i_ret = 0; -+ } else { -+ BTIF_WARN_FUNC("unknown flag:%d\n", flag); -+ } -+ BTIF_INFO_FUNC("rx dma %s\n", (enable & DMA_EN_BIT) && -+ (!(stop && DMA_STOP_BIT)) ? "enabled" : "stopped"); -+ BTIF_INFO_FUNC("data in rx dma is %s by driver\n", -+ ((wpt == rpt) && -+ (int_buf == 0)) ? "received" : "not received"); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_dump_reg -+* DESCRIPTION -+* dump BTIF module's information when needed -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* flag [IN] register id flag -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ENUM_BTIF_REG_ID flag) -+{ -+ unsigned int i_ret = -1; -+ -+ if (p_dma_info->dir == DMA_DIR_TX) -+ i_ret = hal_tx_dma_dump_reg(p_dma_info, flag); -+ else if (p_dma_info->dir == DMA_DIR_RX) -+ i_ret = hal_rx_dma_dump_reg(p_dma_info, flag); -+ else -+ BTIF_WARN_FUNC("unknown dir:%d\n", p_dma_info->dir); -+ -+ return i_ret; -+} -+ -+static int _tx_dma_flush(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int stop = BTIF_READ32(TX_DMA_STOP(base)); -+ -+/*in MTK DMA BTIF channel we cannot set STOP and FLUSH bit at the same time*/ -+ if ((stop && DMA_STOP_BIT) != 0) -+ BTIF_ERR_FUNC("BTIF's DMA in stop state, omit flush operation\n"); -+ else { -+ BTIF_DBG_FUNC("flush tx dma\n"); -+ BTIF_SET_BIT(TX_DMA_FLUSH(base), DMA_FLUSH_BIT); -+ i_ret = 0; -+ } -+ return i_ret; -+} -+ -+static int _is_tx_dma_in_flush(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ bool b_ret = true; -+ unsigned long base = p_dma_info->base; -+ -+/*see if flush operation is in process*/ -+ b_ret = ((DMA_FLUSH_BIT & BTIF_READ32(TX_DMA_FLUSH(base))) != 0) ? true : false; -+ -+ return b_ret; -+} -+ -+int hal_dma_pm_ops(P_MTK_DMA_INFO_STR p_dma_info, MTK_BTIF_PM_OPID opid) -+{ -+ int i_ret = -1; -+ -+ BTIF_INFO_FUNC("op id: %d\n", opid); -+ switch (opid) { -+ case BTIF_PM_DPIDLE_EN: -+ i_ret = 0; -+ break; -+ case BTIF_PM_DPIDLE_DIS: -+ i_ret = 0; -+ break; -+ case BTIF_PM_SUSPEND: -+ i_ret = 0; -+ break; -+ case BTIF_PM_RESUME: -+ i_ret = 0; -+ break; -+ case BTIF_PM_RESTORE_NOIRQ:{ -+ unsigned int flag = 0; -+ P_MTK_BTIF_IRQ_STR p_irq = p_dma_info->p_irq; -+ -+#ifdef CONFIG_OF -+ flag = p_irq->irq_flags; -+#else -+ switch (p_irq->sens_type) { -+ case IRQ_SENS_EDGE: -+ if (p_irq->edge_type == IRQ_EDGE_FALL) -+ flag = IRQF_TRIGGER_FALLING; -+ else if (p_irq->edge_type == IRQ_EDGE_RAISE) -+ flag = IRQF_TRIGGER_RISING; -+ else if (p_irq->edge_type == IRQ_EDGE_BOTH) -+ flag = IRQF_TRIGGER_RISING | -+ IRQF_TRIGGER_FALLING; -+ else -+ flag = IRQF_TRIGGER_FALLING; /*make this as default type */ -+ break; -+ case IRQ_SENS_LVL: -+ if (p_irq->lvl_type == IRQ_LVL_LOW) -+ flag = IRQF_TRIGGER_LOW; -+ else if (p_irq->lvl_type == IRQ_LVL_HIGH) -+ flag = IRQF_TRIGGER_HIGH; -+ else -+ flag = IRQF_TRIGGER_LOW; /*make this as default type */ -+ break; -+ default: -+ flag = IRQF_TRIGGER_LOW; /*make this as default type */ -+ break; -+ } -+#endif -+/* irq_set_irq_type(p_irq->irq_id, flag); */ -+ i_ret = 0; -+ } -+ i_ret = 0; -+ break; -+ default: -+ i_ret = ERR_INVALID_PAR; -+ break; -+ } -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_receive_data -+* DESCRIPTION -+* receive data from btif module in DMA polling mode -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* positive means data is available, 0 means no data available -+*****************************************************************************/ -+#ifndef MTK_BTIF_MARK_UNUSED_API -+int hal_dma_receive_data(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, const unsigned int max_len) -+{ -+ unsigned int i_ret = -1; -+ -+ return i_ret; -+} -+#endif -+ -+int _btif_dma_dump_dbg_reg(void) -+{ -+#if 0 -+ static MTK_BTIF_DMA_REG_DMP_DBG g_dma_dbg_regs[] = { -+ {0x10201180, 0x0}, -+ {0x10201184, 0x0}, -+ {0x10201188, 0x0}, -+ {0x1020118C, 0x0}, -+ {0x10201190, 0x0}, -+ {0x1000320C, 0x0}, -+ {0x10003210, 0x0}, -+ {0x10003214, 0x0}, -+ }; -+ -+ int i = 0; -+ char *addr1 = NULL; -+ char *addr2 = NULL; -+ -+ int array_num = ARRAY_SIZE(g_dma_dbg_regs) -+ -+ addr1 = ioremap(g_dma_dbg_regs[0].reg_addr, 0x20); -+ if (addr1) { -+ for (i = 0; i < 5; i++) -+ g_dma_dbg_regs[i].reg_val = *(volatile unsigned int*)(addr1 + i*4); -+ iounmap(addr1); -+ } -+ -+ addr2 = ioremap(g_dma_dbg_regs[5].reg_addr, 0x10); -+ if (addr2) { -+ g_dma_dbg_regs[5].reg_val = *(volatile unsigned int*)(addr2); -+ g_dma_dbg_regs[6].reg_val = *(volatile unsigned int*)(addr2+4); -+ g_dma_dbg_regs[7].reg_val = *(volatile unsigned int*)(addr2+8); -+ iounmap(addr2); -+ } -+ -+ for (i = 0; i < array_num; i++) -+ BTIF_INFO_FUNC("-<0x%lx, 0x%08x>\n", g_dma_dbg_regs[i].reg_addr, g_dma_dbg_regs[i].reg_val); -+#endif -+ return 0; -+} -+ -+static void hal_btif_tx_dma_vff_set_for_4g(void) -+{ -+ BTIF_DBG_FUNC("Set btif tx_vff_addr bit29\n"); -+ BTIF_SET_BIT(TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base), DMA_VFF_BIT29_OFFSET); -+ BTIF_DBG_FUNC("Dump value of bit29 0x%x:(0x%x)\n", TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base), -+ BTIF_READ32(TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base))); -+} -+static void hal_btif_rx_dma_vff_set_for_4g(void) -+{ -+ BTIF_DBG_FUNC("Set btif rx_vff_addr bit29\n"); -+ BTIF_SET_BIT(RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base), DMA_VFF_BIT29_OFFSET); -+ BTIF_DBG_FUNC("Dump value of bit29 0x%x:(0x%x)\n", RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base), -+ BTIF_READ32(RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base))); -+} -+ -diff --git a/drivers/misc/mediatek/btif/common/btif_plat.c b/drivers/misc/mediatek/btif/common/btif_plat.c -new file mode 100644 -index 0000000000000..e098e902317cc ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/btif_plat.c -@@ -0,0 +1,1396 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "MTK-BTIF" -+ -+#define NEW_TX_HANDLING_SUPPORT 1 -+ -+#include "btif_pub.h" -+#include "btif_priv.h" -+ -+#define BTIF_USER_ID "btif_driver" -+ -+static spinlock_t g_clk_cg_spinlock; /*BTIF clock's spinlock */ -+ -+/*-----------------------------BTIF Module Clock and Power Control Defination------------------*/ -+ -+MTK_BTIF_IRQ_STR mtk_btif_irq = { -+ .name = "mtk btif irq", -+ .is_irq_sup = true, -+ .reg_flag = false, -+#ifdef CONFIG_OF -+ .irq_flags = IRQF_TRIGGER_NONE, -+#else -+ .irq_id = MT_BTIF_IRQ_ID, -+ .sens_type = IRQ_SENS_LVL, -+ .lvl_type = IRQ_LVL_LOW, -+#endif -+ .p_irq_handler = NULL, -+}; -+ -+/* -+ * will call clock manager's API export by WCP to control BTIF's clock, -+ * but we may need to access these registers in case of btif clock control logic is wrong in clock manager -+ */ -+ -+MTK_BTIF_INFO_STR mtk_btif = { -+#ifndef CONFIG_OF -+ .base = MTK_BTIF_REG_BASE, -+#endif -+ .p_irq = &mtk_btif_irq, -+ .tx_fifo_size = BTIF_TX_FIFO_SIZE, -+ .rx_fifo_size = BTIF_RX_FIFO_SIZE, -+ .tx_tri_lvl = BTIF_TX_FIFO_THRE, -+ .rx_tri_lvl = BTIF_RX_FIFO_THRE, -+ .rx_data_len = 0, -+ .p_tx_fifo = NULL, -+}; -+#if !(NEW_TX_HANDLING_SUPPORT) -+static bool _btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif); -+#endif -+ -+static int btif_rx_irq_handler(P_MTK_BTIF_INFO_STR p_btif_info, -+ unsigned char *p_buf, -+ const unsigned int max_len); -+static int btif_tx_irq_handler(P_MTK_BTIF_INFO_STR p_btif); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_ier_ctrl -+* DESCRIPTION -+* BTIF Rx interrupt enable/disable -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* enable [IN] control if rx interrupt enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int hal_btif_rx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_tx_ier_ctrl -+* DESCRIPTION -+* BTIF Tx interrupt enable/disable -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* enable [IN] control if tx interrupt enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int hal_btif_tx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); -+ -+#ifndef MTK_BTIF_MARK_UNUSED_API -+static int btif_sleep_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); -+ -+/***************************************************************************** -+* FUNCTION -+* _btif_receive_data -+* DESCRIPTION -+* receive data from btif module in FIFO polling mode -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* positive means data is available, 0 means no data available -+*****************************************************************************/ -+static int _btif_receive_data(P_MTK_BTIF_INFO_STR p_btif, -+ unsigned char *p_buf, const unsigned int max_len); -+static int btif_tx_thr_set(P_MTK_BTIF_INFO_STR p_btif, unsigned int thr_count); -+#endif -+ -+static int btif_dump_array(char *string, char *p_buf, int len) -+{ -+ unsigned int idx = 0; -+ unsigned char str[30]; -+ unsigned char *p_str; -+ -+ pr_debug("========dump %s start ========\n", string, len); -+ p_str = &str[0]; -+ for (idx = 0; idx < len; idx++, p_buf++) { -+ sprintf(p_str, "%02x ", *p_buf); -+ p_str += 3; -+ if (7 == (idx % 8)) { -+ *p_str++ = '\n'; -+ *p_str = '\0'; -+ pr_debug("%s", str); -+ p_str = &str[0]; -+ } -+ } -+ if (len % 8) { -+ *p_str++ = '\n'; -+ *p_str = '\0'; -+ pr_debug("%s", str); -+ } -+ pr_debug("========dump %s end========\n", string); -+ return 0; -+} -+ -+#if NEW_TX_HANDLING_SUPPORT -+static int _btif_tx_fifo_init(P_MTK_BTIF_INFO_STR p_btif_info) -+{ -+ int i_ret = -1; -+ -+ spin_lock_init(&(p_btif_info->tx_fifo_spinlock)); -+ -+ if (p_btif_info->p_tx_fifo == NULL) { -+ p_btif_info->p_tx_fifo = kzalloc(sizeof(struct kfifo), -+ GFP_ATOMIC); -+ if (p_btif_info->p_tx_fifo == NULL) { -+ i_ret = -ENOMEM; -+ BTIF_ERR_FUNC("kzalloc for p_btif->p_tx_fifo failed\n"); -+ goto ret; -+ } -+ -+ i_ret = kfifo_alloc(p_btif_info->p_tx_fifo, -+ BTIF_HAL_TX_FIFO_SIZE, GFP_ATOMIC); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("kfifo_alloc failed, errno(%d)\n", i_ret); -+ i_ret = -ENOMEM; -+ goto ret; -+ } -+ i_ret = 0; -+ } else { -+ BTIF_WARN_FUNC -+ ("p_btif_info->p_tx_fifo is already init p_btif_info->p_tx_fifo(0x%p)\n", -+ p_btif_info->p_tx_fifo); -+ i_ret = 0; -+ } -+ret: -+ return i_ret; -+} -+ -+static int _get_btif_tx_fifo_room(P_MTK_BTIF_INFO_STR p_btif_info) -+{ -+ int i_ret = 0; -+ unsigned long flag = 0; -+ -+ spin_lock_irqsave(&(p_btif_info->tx_fifo_spinlock), flag); -+ if (p_btif_info->p_tx_fifo == NULL) -+ i_ret = 0; -+ else -+ i_ret = kfifo_avail(p_btif_info->p_tx_fifo); -+ spin_unlock_irqrestore(&(p_btif_info->tx_fifo_spinlock), flag); -+ BTIF_DBG_FUNC("tx kfifo:0x%p, available room:%d\n", p_btif_info->p_tx_fifo, i_ret); -+ return i_ret; -+} -+ -+static int _btif_tx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif_info) -+{ -+ int i_ret = 0; -+ -+ if (p_btif_info->p_tx_fifo != NULL) -+ kfifo_reset(p_btif_info->p_tx_fifo); -+ return i_ret; -+} -+ -+#endif -+ -+#ifdef CONFIG_OF -+static void _btif_set_default_setting(void) -+{ -+ struct device_node *node = NULL; -+ unsigned int irq_info[3] = {0, 0, 0}; -+ unsigned int phy_base; -+ -+ node = of_find_compatible_node(NULL, NULL, "mediatek,mtk-btif"); -+ if (node) { -+ mtk_btif.p_irq->irq_id = irq_of_parse_and_map(node, 0); -+ /*fixme, be compitable arch 64bits*/ -+ mtk_btif.base = (unsigned long)of_iomap(node, 0); -+ BTIF_INFO_FUNC("get btif irq(%d),register base(0x%lx)\n", -+ mtk_btif.p_irq->irq_id, mtk_btif.base); -+ } else { -+ BTIF_ERR_FUNC("get btif device node fail\n"); -+ } -+ -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ BTIF_ERR_FUNC("get interrupt flag from DTS fail\n"); -+ } else { -+ mtk_btif.p_irq->irq_flags = irq_info[2]; -+ BTIF_INFO_FUNC("get interrupt flag(0x%x)\n", mtk_btif.p_irq->irq_flags); -+ } -+ -+ if (of_property_read_u32_index(node, "reg", 1, &phy_base)) -+ BTIF_ERR_FUNC("get register phy base from DTS fail\n"); -+ else -+ BTIF_INFO_FUNC("get register phy base(0x%x)\n", (unsigned int)phy_base); -+} -+#endif -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_info_get -+* DESCRIPTION -+* get btif's information included base address , irq related information -+* PARAMETERS -+* RETURNS -+* BTIF's information -+*****************************************************************************/ -+P_MTK_BTIF_INFO_STR hal_btif_info_get(void) -+{ -+#if NEW_TX_HANDLING_SUPPORT -+ int i_ret = 0; -+/*tx fifo and fifo lock init*/ -+ i_ret = _btif_tx_fifo_init(&mtk_btif); -+ if (i_ret == 0) -+ BTIF_INFO_FUNC("_btif_tx_fifo_init succeed\n"); -+ else -+ BTIF_ERR_FUNC("_btif_tx_fifo_init failed, i_ret:%d\n", i_ret); -+ -+#endif -+ -+#ifdef CONFIG_OF -+ _btif_set_default_setting(); -+#endif -+ -+ spin_lock_init(&g_clk_cg_spinlock); -+ -+ return &mtk_btif; -+} -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_get_and_prepare -+* DESCRIPTION -+* get clock from device tree and prepare for enable/disable control -+* PARAMETERS -+* pdev device pointer -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+#if !defined(CONFIG_MTK_CLKMGR) -+int hal_btif_clk_get_and_prepare(struct platform_device *pdev) -+{ -+ int i_ret = -1; -+ -+ clk_btif = devm_clk_get(&pdev->dev, "main"); -+ if (IS_ERR(clk_btif)) { -+ BTIF_ERR_FUNC("[CCF]cannot get clk_btif clock.\n"); -+ return PTR_ERR(clk_btif); -+ } -+ BTIF_ERR_FUNC("[CCF]clk_btif=%p\n", clk_btif); -+ clk_btif_apdma = devm_clk_get(&pdev->dev, "apdmac"); -+ if (IS_ERR(clk_btif_apdma)) { -+ BTIF_ERR_FUNC("[CCF]cannot get clk_btif_apdma clock.\n"); -+ return PTR_ERR(clk_btif_apdma); -+ } -+ BTIF_ERR_FUNC("[CCF]clk_btif_apdma=%p\n", clk_btif_apdma); -+ -+ i_ret = clk_prepare(clk_btif); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("clk_prepare clk_btif failed! ret:%d\n", i_ret); -+ return i_ret; -+ } -+ -+ i_ret = clk_prepare(clk_btif_apdma); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("clk_prepare clk_btif_apdma failed! ret:%d\n", i_ret); -+ return i_ret; -+ } -+ return i_ret; -+} -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_unprepare -+* DESCRIPTION -+* unprepare btif clock and apdma clock -+* PARAMETERS -+* none -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_clk_unprepare(void) -+{ -+ clk_unprepare(clk_btif); -+ clk_unprepare(clk_btif_apdma); -+ return 0; -+} -+#endif -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_ctrl -+* DESCRIPTION -+* control clock output enable/disable of BTIF module -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_clk_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_CLOCK_CTRL flag) -+{ -+/*In MTK BTIF, there's only one global CG on AP_DMA, no sub channel's CG bit*/ -+/*according to Artis's comment, clock of DMA and BTIF is default off, so we assume it to be off by default*/ -+ int i_ret = 0; -+ unsigned long irq_flag = 0; -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ static atomic_t s_clk_ref = ATOMIC_INIT(0); -+#else -+ static ENUM_CLOCK_CTRL status = CLK_OUT_DISABLE; -+#endif -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag); -+ -+#if MTK_BTIF_ENABLE_CLK_CTL -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ -+ if (flag == CLK_OUT_ENABLE) { -+ if (atomic_inc_return(&s_clk_ref) == 1) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = enable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); -+#else -+ BTIF_DBG_FUNC("[CCF]enable clk_btif\n"); -+ i_ret = clk_enable(clk_btif); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("enable_clock for MTK_BTIF_CG_BIT failed, ret:%d", -+ i_ret); -+ } -+ } -+ } else if (flag == CLK_OUT_DISABLE) { -+ if (atomic_dec_return(&s_clk_ref) == 0) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = disable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("disable_clock for MTK_BTIF_CG_BIT failed, ret:%d", -+ i_ret); -+ } -+#else -+ BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif) calling\n"); -+ clk_disable(clk_btif); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ } -+ } else { -+ i_ret = ERR_INVALID_PAR; -+ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); -+ } -+ -+#else -+ -+ if (status == flag) { -+ i_ret = 0; -+ BTIF_DBG_FUNC("btif clock already %s\n", -+ CLK_OUT_ENABLE == -+ status ? "enabled" : "disabled"); -+ } else { -+ if (flag == CLK_OUT_ENABLE) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = enable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); -+#else -+ BTIF_DBG_FUNC("[CCF]enable clk_btif\n"); -+ i_ret = clk_enable(clk_btif); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ status = (i_ret == 0) ? flag : status; -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("enable_clock for MTK_BTIF_CG_BIT failed, ret:%d", -+ i_ret); -+ } -+ } else if (flag == CLK_OUT_DISABLE) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = disable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); -+ status = (i_ret == 0) ? flag : status; -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("disable_clock for MTK_BTIF_CG_BIT failed, ret:%d", -+ i_ret); -+ } -+#else -+ BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif) calling\n"); -+ clk_disable(clk_btif); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ } else { -+ i_ret = ERR_INVALID_PAR; -+ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); -+ } -+ } -+#endif -+ -+#else -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ -+#else -+ -+ status = flag; -+#endif -+ -+ i_ret = 0; -+#endif -+ -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ if (i_ret == 0) { -+ BTIF_DBG_FUNC("btif clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); -+ } else { -+ BTIF_ERR_FUNC("%s btif clock failed, ret(%d)\n", -+ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); -+ } -+#else -+ -+ if (i_ret == 0) { -+ BTIF_DBG_FUNC("btif clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); -+ } else { -+ BTIF_ERR_FUNC("%s btif clock failed, ret(%d)\n", -+ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); -+ } -+#endif -+#if defined(CONFIG_MTK_CLKMGR) -+ BTIF_DBG_FUNC("BTIF's clock is %s\n", (clock_is_on(MTK_BTIF_CG_BIT) == 0) ? "off" : "on"); -+#endif -+ return i_ret; -+} -+ -+static int btif_new_handshake_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool enable) -+{ -+ unsigned long base = p_btif->base; -+ -+ if (enable == true) -+ BTIF_SET_BIT(BTIF_HANDSHAKE(base), BTIF_HANDSHAKE_EN_HANDSHAKE); -+ else -+ BTIF_CLR_BIT(BTIF_HANDSHAKE(base), BTIF_HANDSHAKE_EN_HANDSHAKE); -+ return true; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_hw_init -+* DESCRIPTION -+* BTIF hardware init -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_hw_init(P_MTK_BTIF_INFO_STR p_btif) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+#if NEW_TX_HANDLING_SUPPORT -+ _btif_tx_fifo_reset(p_btif); -+#endif -+ -+/*set to normal mode*/ -+ btif_reg_sync_writel(BTIF_FAKELCR_NORMAL_MODE, BTIF_FAKELCR(base)); -+/*set to newhandshake mode*/ -+ btif_new_handshake_ctrl(p_btif, true); -+/*No need to access: enable sleep mode*/ -+/*No need to access: set Rx timeout count*/ -+/*set Tx threshold*/ -+/*set Rx threshold*/ -+/*disable internal loopback test*/ -+ -+/*set Rx FIFO clear bit to 1*/ -+ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); -+/*clear Rx FIFO clear bit to 0*/ -+ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); -+/*set Tx FIFO clear bit to 1*/ -+ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); -+/*clear Tx FIFO clear bit to 0*/ -+ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); -+ -+ btif_reg_sync_writel(BTIF_TRI_LVL_TX(p_btif->tx_tri_lvl) -+ | BTIF_TRI_LVL_RX(p_btif->rx_tri_lvl) -+ | BTIF_TRI_LOOP_DIS, BTIF_TRI_LVL(base)); -+ hal_btif_loopback_ctrl(p_btif, false); -+/*disable BTIF Tx DMA mode*/ -+ hal_btif_tx_mode_ctrl(p_btif, false); -+/*disable BTIF Rx DMA mode*/ -+ hal_btif_rx_mode_ctrl(p_btif, false); -+/*auto reset*/ -+ BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_AUTORST_EN); -+/*disable Tx IER*/ -+ hal_btif_tx_ier_ctrl(p_btif, false); -+/*enable Rx IER by default*/ -+ hal_btif_rx_ier_ctrl(p_btif, true); -+ -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_ier_ctrl -+* DESCRIPTION -+* BTIF Rx interrupt enable/disable -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* enable [IN] control if rx interrupt enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_rx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (en == false) -+ BTIF_CLR_BIT(BTIF_IER(base), BTIF_IER_RXFEN); -+ else -+ BTIF_SET_BIT(BTIF_IER(base), BTIF_IER_RXFEN); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_tx_ier_ctrl -+* DESCRIPTION -+* BTIF Tx interrupt enable/disable -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* enable [IN] control if tx interrupt enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_tx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (en == false) -+ BTIF_CLR_BIT(BTIF_IER(base), BTIF_IER_TXEEN); -+ else -+ BTIF_SET_BIT(BTIF_IER(base), BTIF_IER_TXEEN); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+ i_ret = 0; -+ -+ return i_ret; -+} -+ -+#ifndef MTK_BTIF_MARK_UNUSED_API -+ -+/***************************************************************************** -+* FUNCTION -+* _btif_receive_data -+* DESCRIPTION -+* receive data from btif module in FIFO polling mode -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* positive means data is available, 0 means no data available -+*****************************************************************************/ -+int _btif_receive_data(P_MTK_BTIF_INFO_STR p_btif, -+ unsigned char *p_buf, const unsigned int max_len) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ -+/*check parameter valid or not*/ -+ if ((p_buf == NULL) || (max_len == 0)) { -+ i_ret = ERR_INVALID_PAR; -+ return i_ret; -+ } -+ i_ret = btif_rx_irq_handler(p_btif, p_buf, max_len); -+ -+ return i_ret; -+} -+ -+int btif_sleep_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (en == false) -+ BTIF_CLR_BIT(BTIF_SLEEP_EN(base), BTIF_SLEEP_EN_BIT); -+ else -+ BTIF_SET_BIT(BTIF_SLEEP_EN(base), BTIF_SLEEP_EN_BIT); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+/*TODO:do we need to dsb?*/ -+ i_ret = 0; -+ return i_ret; -+} -+ -+static int btif_tx_thr_set(P_MTK_BTIF_INFO_STR p_btif, unsigned int thr_count) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ unsigned int value = 0; -+ -+/*read BTIF_TRI_LVL*/ -+ value = BTIF_READ32(BTIF_TRI_LVL(base)); -+/*clear Tx threshold bits*/ -+ value &= (~BTIF_TRI_LVL_TX_MASK); -+/*set tx threshold bits*/ -+ value |= BTIF_TRI_LVL_TX(BTIF_TX_FIFO_THRE); -+/*write back to BTIF_TRI_LVL*/ -+ btif_reg_sync_writel(value, BTIF_TRI_LVL(base)); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* btif_rx_fifo_reset -+* DESCRIPTION -+* reset BTIF's rx fifo -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* ec [IN] control if loopback mode is enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int btif_rx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+/*set Rx FIFO clear bit to 1*/ -+ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); -+ -+/*clear Rx FIFO clear bit to 0*/ -+ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+/*TODO:do we need to dsb?*/ -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* btif_tx_fifo_reset -+* DESCRIPTION -+* reset BTIF's tx fifo -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int btif_tx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+/*set Tx FIFO clear bit to 1*/ -+ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); -+ -+/*clear Tx FIFO clear bit to 0*/ -+ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+/*TODO:do we need to dsb?*/ -+ i_ret = 0; -+ return i_ret; -+} -+ -+#endif -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_loopback_ctrl -+* DESCRIPTION -+* BTIF Tx/Rx loopback mode set, this operation can only be done after set BTIF to normal mode -+* PARAMETERS -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_loopback_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (en == false) -+ BTIF_CLR_BIT(BTIF_TRI_LVL(base), BTIF_TRI_LOOP_EN); -+ else -+ BTIF_SET_BIT(BTIF_TRI_LVL(base), BTIF_TRI_LOOP_EN); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+/*TODO:do we need to dsb?*/ -+ i_ret = 0; -+ return i_ret; -+} -+ -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_handler -+* DESCRIPTION -+* lower level interrupt handler -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* 0 means success; negative means fail; positive means rx data length -+*****************************************************************************/ -+int hal_btif_irq_handler(P_MTK_BTIF_INFO_STR p_btif, -+ unsigned char *p_buf, const unsigned int max_len) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ unsigned int iir = 0; -+ unsigned int rx_len = 0; -+ unsigned long base = p_btif->base; -+ -+#if 0 -+/*check parameter valid or not*/ -+ if ((p_buf == NULL) || (max_len == 0)) { -+ i_ret = ERR_INVALID_PAR; -+ return i_ret; -+ } -+#endif -+ unsigned long irq_flag = 0; -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag); -+ -+#if defined(CONFIG_MTK_CLKMGR) -+ if (clock_is_on(MTK_BTIF_CG_BIT) == 0) { -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); -+ BTIF_ERR_FUNC("%s: clock is off before irq handle done!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+/*read interrupt identifier register*/ -+ iir = BTIF_READ32(BTIF_IIR(base)); -+ -+/*is rx interrupt exist?*/ -+#if 0 -+ while ((iir & BTIF_IIR_RX) && (rx_len < max_len)) { -+ rx_len += -+ btif_rx_irq_handler(p_btif, (p_buf + rx_len), -+ (max_len - rx_len)); -+ -+/*update IIR*/ -+ iir = BTIF_READ32(BTIF_IIR(base)); -+ } -+#endif -+ -+ while (iir & (BTIF_IIR_RX | BTIF_IIR_RX_TIMEOUT)) { -+ rx_len += btif_rx_irq_handler(p_btif, p_buf, max_len); -+ -+/*update IIR*/ -+ iir = BTIF_READ32(BTIF_IIR(base)); -+ } -+ -+/*is tx interrupt exist?*/ -+ if (iir & BTIF_IIR_TX_EMPTY) -+ i_ret = btif_tx_irq_handler(p_btif); -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); -+ -+ i_ret = rx_len != 0 ? rx_len : i_ret; -+ return i_ret; -+} -+ -+int hal_btif_rx_cb_reg(P_MTK_BTIF_INFO_STR p_btif_info, btif_rx_buf_write rx_cb) -+{ -+ if (p_btif_info->rx_cb != NULL) -+ BTIF_DBG_FUNC("rx_cb already registered, replace (0x%p) with (0x%p)\n", -+ p_btif_info->rx_cb, rx_cb); -+ p_btif_info->rx_cb = rx_cb; -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* btif_rx_irq_handler -+* DESCRIPTION -+* lower level rx interrupt handler -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* positive means length of rx data , negative means fail -+*****************************************************************************/ -+static int btif_rx_irq_handler(P_MTK_BTIF_INFO_STR p_btif_info, -+ unsigned char *p_buf, const unsigned int max_len) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = 0; -+ unsigned int iir = 0; -+ unsigned int rx_len = 0; -+ unsigned long base = p_btif_info->base; -+ unsigned char rx_buf[256]; -+ unsigned int local_buf_len = 256; -+ btif_rx_buf_write rx_cb = p_btif_info->rx_cb; -+ unsigned int total_len = 0; -+ -+/*read interrupt identifier register*/ -+ iir = BTIF_READ32(BTIF_IIR(base)); -+ while ((iir & (BTIF_IIR_RX | BTIF_IIR_RX_TIMEOUT)) && -+ (rx_len < local_buf_len)) { -+ rx_buf[rx_len] = BTIF_READ8(base); -+ rx_len++; -+/*need to consult CC Hwang for advice */ -+/* -+ * whether we need to do memory barrier here -+ * Ans: no -+ */ -+/* -+ * whether we need to d memory barrier when call BTIF_SET_BIT or BTIF_CLR_BIT -+ * Ans: no -+ */ -+ if (rx_len == local_buf_len) { -+ if (rx_cb) -+ (*rx_cb) (p_btif_info, rx_buf, rx_len); -+ rx_len = 0; -+ total_len += rx_len; -+ } -+ iir = BTIF_READ32(BTIF_IIR(base)); -+ } -+ total_len += rx_len; -+ if (rx_len && rx_cb) -+ (*rx_cb) (p_btif_info, rx_buf, rx_len); -+ -+/* -+ * make sure all data write back to memory, mb or dsb? -+ * need to consult CC Hwang for advice -+ * Ans: no need here -+ */ -+ i_ret = total_len; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* btif_tx_irq_handler -+* DESCRIPTION -+* lower level tx interrupt handler -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int btif_tx_irq_handler(P_MTK_BTIF_INFO_STR p_btif) -+{ -+ int i_ret = -1; -+ -+#if NEW_TX_HANDLING_SUPPORT -+ int how_many = 0; -+ unsigned int lsr; -+ unsigned int ava_len = 0; -+ unsigned long base = p_btif->base; -+ char local_buf[BTIF_TX_FIFO_SIZE]; -+ char *p_data = local_buf; -+ unsigned long flag = 0; -+ -+ struct kfifo *p_tx_fifo = p_btif->p_tx_fifo; -+ -+/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ -+ if (lsr & BTIF_LSR_TEMT_BIT) -+ /*Tx Holding Register if empty, which means we can write tx FIFO count to BTIF*/ -+ ava_len = BTIF_TX_FIFO_SIZE; -+ else if (lsr & BTIF_LSR_THRE_BIT) -+ /*Tx Holding Register if empty, which means we can write (Tx FIFO count - Tx threshold)to BTIF*/ -+ ava_len = BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE; -+ else { -+ /*this means data size in tx FIFO is more than Tx threshold, we will not write data to THR*/ -+ ava_len = 0; -+ goto ret; -+ } -+ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); -+ how_many = kfifo_out(p_tx_fifo, local_buf, ava_len); -+ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); -+ BTIF_DBG_FUNC("BTIF tx size %d done, left:%d\n", how_many, -+ kfifo_avail(p_tx_fifo)); -+ while (how_many--) -+ btif_reg_sync_writeb(*(p_data++), BTIF_THR(base)); -+ -+ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); -+/*clear Tx enable flag if necessary*/ -+ if (kfifo_is_empty(p_tx_fifo)) { -+ hal_btif_tx_ier_ctrl(p_btif, false); -+ BTIF_DBG_FUNC("BTIF tx FIFO is empty\n"); -+ } -+ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); -+ret: -+#else -+/*clear Tx enable flag*/ -+ hal_btif_tx_ier_ctrl(p_btif, false); -+#endif -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_tx_mode_ctrl -+* DESCRIPTION -+* set BTIF tx to corresponding mode (PIO/DMA) -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* mode [IN] rx mode -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_tx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (mode == BTIF_MODE_DMA) -+ /*set to DMA mode*/ -+ BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_TX); -+ else -+ /*set to PIO mode*/ -+ BTIF_CLR_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_TX); -+ -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_mode_ctrl -+* DESCRIPTION -+* set BTIF rx to corresponding mode (PIO/DMA) -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* mode [IN] rx mode -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_rx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (mode == BTIF_MODE_DMA) -+ /*set to DMA mode*/ -+ BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_RX); -+ else -+ /*set to PIO mode*/ -+ BTIF_CLR_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_RX); -+ -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_send_data -+* DESCRIPTION -+* send data through btif in FIFO mode -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN] pointer to rx data buffer -+* max_len [IN] tx buffer length -+* RETURNS -+* positive means number of data sent; 0 means no data put to FIFO; negative means error happens -+*****************************************************************************/ -+int hal_btif_send_data(P_MTK_BTIF_INFO_STR p_btif, -+ const unsigned char *p_buf, const unsigned int buf_len) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ -+ unsigned int ava_len = 0; -+ unsigned int sent_len = 0; -+ -+#if !(NEW_TX_HANDLING_SUPPORT) -+ unsigned long base = p_btif->base; -+ unsigned int lsr = 0; -+ unsigned int left_len = 0; -+ unsigned char *p_data = (unsigned char *)p_buf; -+#endif -+ -+/*check parameter valid or not*/ -+ if ((p_buf == NULL) || (buf_len == 0)) { -+ i_ret = ERR_INVALID_PAR; -+ return i_ret; -+ } -+#if NEW_TX_HANDLING_SUPPORT -+ ava_len = _get_btif_tx_fifo_room(p_btif); -+ sent_len = buf_len <= ava_len ? buf_len : ava_len; -+ if (sent_len > 0) { -+ int enqueue_len = 0; -+ unsigned long flag = 0; -+ -+ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); -+ enqueue_len = kfifo_in(p_btif->p_tx_fifo, -+ (unsigned char *)p_buf, sent_len); -+ if (sent_len != enqueue_len) { -+ BTIF_ERR_FUNC("target tx len:%d, len sent:%d\n", -+ sent_len, enqueue_len); -+ } -+ i_ret = enqueue_len; -+ mb(); -+/*enable BTIF Tx IRQ*/ -+ hal_btif_tx_ier_ctrl(p_btif, true); -+ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); -+ BTIF_DBG_FUNC("enqueue len:%d\n", enqueue_len); -+ } else { -+ i_ret = 0; -+ } -+#else -+ while ((_btif_is_tx_allow(p_btif)) && (sent_len < buf_len)) { -+ /*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ -+ if (lsr & BTIF_LSR_TEMT_BIT) -+ /*Tx Holding Register if empty, which means we can write tx FIFO count to BTIF*/ -+ ava_len = BTIF_TX_FIFO_SIZE; -+ else if (lsr & BTIF_LSR_THRE_BIT) -+ /*Tx Holding Register if empty, which means we can write (Tx FIFO count - Tx threshold)to BTIF*/ -+ ava_len = BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE; -+ else { -+ /*this means data size in tx FIFO is more than Tx threshold, we will not write data to THR*/ -+ ava_len = 0; -+ break; -+ } -+ -+ left_len = buf_len - sent_len; -+/*ava_len will be real length will write to BTIF THR*/ -+ ava_len = ava_len > left_len ? left_len : ava_len; -+/*update sent length valud after this operation*/ -+ sent_len += ava_len; -+/* -+ * whether we need memory barrier here? -+ * Ans: No, no memory ordering issue exist, -+ * CPU will make sure logically right -+ */ -+ while (ava_len--) -+ btif_reg_sync_writeb(*(p_data++), BTIF_THR(base)); -+ -+ } -+/* while ((hal_btif_is_tx_allow()) && (sent_len < buf_len)); */ -+ -+ i_ret = sent_len; -+ -+/*enable BTIF Tx IRQ*/ -+ hal_btif_tx_ier_ctrl(p_btif, true); -+#endif -+ return i_ret; -+} -+ -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_raise_wak_sig -+* DESCRIPTION -+* raise wakeup signal to counterpart -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_raise_wak_sig(P_MTK_BTIF_INFO_STR p_btif) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+#if defined(CONFIG_MTK_CLKMGR) -+ if (clock_is_on(MTK_BTIF_CG_BIT) == 0) { -+ BTIF_ERR_FUNC("%s: clock is off before send wakeup signal!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+/*write 0 to BTIF_WAK to pull ap_wakeup_consyss low */ -+ BTIF_CLR_BIT(BTIF_WAK(base), BTIF_WAK_BIT); -+ -+/*wait for a period for longer than 1/32k period, here we use 40us*/ -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ usleep_range(128, 160); -+/* -+ * according to linux/documentation/timers/timers-how-to, we choose usleep_range -+ * SLEEPING FOR ~USECS OR SMALL MSECS ( 10us - 20ms): * Use usleep_range -+ */ -+/*write 1 to pull ap_wakeup_consyss high*/ -+ BTIF_SET_BIT(BTIF_WAK(base), BTIF_WAK_BIT); -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_dump_reg -+* DESCRIPTION -+* dump BTIF module's information when needed -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* flag [IN] register id flag -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dump_reg(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_REG_ID flag) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ int idx = 0; -+ /*unsigned long irq_flag = 0;*/ -+ unsigned long base = p_btif->base; -+ unsigned char reg_map[0xE0 / 4] = { 0 }; -+ unsigned int lsr = 0x0; -+ unsigned int dma_en = 0; -+ -+ /*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/ -+#if defined(CONFIG_MTK_CLKMGR) -+ if (clock_is_on(MTK_BTIF_CG_BIT) == 0) { -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ dma_en = BTIF_READ32(BTIF_DMA_EN(base)); -+ /* -+ * here we omit 1st register which is THR/RBR register to avoid -+ * Rx data read by this debug information accidently -+ */ -+ for (idx = 1; idx < sizeof(reg_map); idx++) -+ reg_map[idx] = BTIF_READ8(p_btif->base + (4 * idx)); -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ BTIF_INFO_FUNC("BTIF's clock is on\n"); -+ BTIF_INFO_FUNC("base address: 0x%lx\n", base); -+ switch (flag) { -+ case REG_BTIF_ALL: -+#if 0 -+ BTIF_INFO_FUNC("BTIF_IER:0x%x\n", BTIF_READ32(BTIF_IER(base))); -+ BTIF_INFO_FUNC("BTIF_IIR:0x%x\n", BTIF_READ32(BTIF_IIR(base))); -+ BTIF_INFO_FUNC("BTIF_FAKELCR:0x%x\n", -+ BTIF_READ32(BTIF_FAKELCR(base))); -+ BTIF_INFO_FUNC("BTIF_LSR:0x%x\n", BTIF_READ32(BTIF_LSR(base))); -+ BTIF_INFO_FUNC("BTIF_SLEEP_EN:0x%x\n", -+ BTIF_READ32(BTIF_SLEEP_EN(base))); -+ BTIF_INFO_FUNC("BTIF_DMA_EN:0x%x\n", -+ BTIF_READ32(BTIF_DMA_EN(base))); -+ BTIF_INFO_FUNC("BTIF_RTOCNT:0x%x\n", -+ BTIF_READ32(BTIF_RTOCNT(base))); -+ BTIF_INFO_FUNC("BTIF_TRI_LVL:0x%x\n", -+ BTIF_READ32(BTIF_TRI_LVL(base))); -+ BTIF_INFO_FUNC("BTIF_WAT_TIME:0x%x\n", -+ BTIF_READ32(BTIF_WAT_TIME(base))); -+ BTIF_INFO_FUNC("BTIF_HANDSHAKE:0x%x\n", -+ BTIF_READ32(BTIF_HANDSHAKE(base))); -+#endif -+ btif_dump_array("BTIF register", reg_map, sizeof(reg_map)); -+ break; -+ default: -+ break; -+ } -+ -+ BTIF_INFO_FUNC("Tx DMA %s\n", -+ (dma_en & BTIF_DMA_EN_TX) ? "enabled" : "disabled"); -+ BTIF_INFO_FUNC("Rx DMA %s\n", -+ (dma_en & BTIF_DMA_EN_RX) ? "enabled" : "disabled"); -+ -+ BTIF_INFO_FUNC("Rx data is %s\n", -+ (lsr & BTIF_LSR_DR_BIT) ? "not empty" : "empty"); -+ BTIF_INFO_FUNC("Tx data is %s\n", -+ (lsr & BTIF_LSR_TEMT_BIT) ? "empty" : "not empty"); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_is_tx_complete -+* DESCRIPTION -+* get tx complete flag -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* true means tx complete, false means tx in process -+*****************************************************************************/ -+bool hal_btif_is_tx_complete(P_MTK_BTIF_INFO_STR p_btif) -+{ -+/*Chaozhong: To be implement*/ -+ bool b_ret = false; -+ unsigned int lsr = 0; -+ unsigned long flags = 0; -+ unsigned long base = p_btif->base; -+ unsigned int tx_empty = 0; -+ unsigned int rx_dr = 0; -+ unsigned int tx_irq_disable = 0; -+ -+/* -+ * 3 conditions allow clock to be disable -+ * 1. if TEMT is set or not -+ * 2. if DR is set or not -+ * 3. Tx IRQ is disabled or not -+ */ -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ tx_empty = lsr & BTIF_LSR_TEMT_BIT; -+ rx_dr = lsr & BTIF_LSR_DR_BIT; -+ tx_irq_disable = BTIF_READ32(BTIF_IER(base)) & BTIF_IER_TXEEN; -+ -+ b_ret = -+ (tx_empty && (tx_irq_disable == 0) && (rx_dr == 0)) ? true : false; -+ if (!b_ret) { -+ BTIF_DBG_FUNC -+ ("BTIF flag, tx_empty:%d, rx_dr:%d, tx_irq_disable:%d\n", -+ tx_empty, rx_dr, tx_irq_disable); -+ } -+#if NEW_TX_HANDLING_SUPPORT -+ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flags); -+/*clear Tx enable flag if necessary*/ -+ if (!(kfifo_is_empty(p_btif->p_tx_fifo))) { -+ BTIF_DBG_FUNC("BTIF tx FIFO is not empty\n"); -+ b_ret = false; -+ } -+ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flags); -+#endif -+ return b_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_is_tx_allow -+* DESCRIPTION -+* whether tx is allowed -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* true if tx operation is allowed; false if tx is not allowed -+*****************************************************************************/ -+bool hal_btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif) -+{ -+#define MIN_TX_MB ((26 * 1000000 / 13) / 1000000) -+#define AVE_TX_MB ((26 * 1000000 / 8) / 1000000) -+ -+/*Chaozhong: To be implement*/ -+ bool b_ret = false; -+ -+#if NEW_TX_HANDLING_SUPPORT -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flags); -+/*clear Tx enable flag if necessary*/ -+ if (kfifo_is_full(p_btif->p_tx_fifo)) { -+ BTIF_WARN_FUNC("BTIF tx FIFO is full\n"); -+ b_ret = false; -+ } else { -+ b_ret = true; -+ } -+ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flags); -+#else -+ unsigned int lsr = 0; -+ unsigned long base = p_btif->base; -+ unsigned int wait_us = (BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE) / MIN_TX_MB; /*only ava length */ -+ -+/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ -+ if (!(lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT))) { -+ BTIF_DBG_FUNC("wait for %d ~ %d us\n", wait_us, 3 * wait_us); -+/* usleep_range(wait_us, 3 * 10 * wait_us); */ -+ usleep_range(wait_us, 3 * wait_us); -+ } -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ b_ret = (lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT)) ? true : false; -+ if (!b_ret) -+ BTIF_DBG_FUNC(" tx is not allowed for the moment\n"); -+ else -+ BTIF_DBG_FUNC(" tx is allowed\n"); -+#endif -+ return b_ret; -+} -+ -+#if !(NEW_TX_HANDLING_SUPPORT) -+ -+static bool _btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif) -+{ -+/*Chaozhong: To be implement*/ -+ bool b_ret = false; -+ unsigned long base = p_btif->base; -+ unsigned int lsr = 0; -+ -+/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ b_ret = (lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT)) ? true : false; -+ return b_ret; -+} -+#endif -+ -+int hal_btif_pm_ops(P_MTK_BTIF_INFO_STR p_btif_info, MTK_BTIF_PM_OPID opid) -+{ -+ int i_ret = -1; -+ -+ BTIF_DBG_FUNC("op id: %d\n", opid); -+ switch (opid) { -+ case BTIF_PM_DPIDLE_EN: -+ i_ret = 0; -+ break; -+ case BTIF_PM_DPIDLE_DIS: -+ i_ret = 0; -+ break; -+ case BTIF_PM_SUSPEND: -+ i_ret = 0; -+ break; -+ case BTIF_PM_RESUME: -+ i_ret = 0; -+ break; -+ case BTIF_PM_RESTORE_NOIRQ:{ -+ unsigned int flag = 0; -+ P_MTK_BTIF_IRQ_STR p_irq = p_btif_info->p_irq; -+ -+#ifdef CONFIG_OF -+ flag = p_irq->irq_flags; -+#else -+ switch (p_irq->sens_type) { -+ case IRQ_SENS_EDGE: -+ if (p_irq->edge_type == IRQ_EDGE_FALL) -+ flag = IRQF_TRIGGER_FALLING; -+ else if (p_irq->edge_type == IRQ_EDGE_RAISE) -+ flag = IRQF_TRIGGER_RISING; -+ else if (p_irq->edge_type == IRQ_EDGE_BOTH) -+ flag = IRQF_TRIGGER_RISING | -+ IRQF_TRIGGER_FALLING; -+ else -+ flag = IRQF_TRIGGER_FALLING; /*make this as default type */ -+ break; -+ case IRQ_SENS_LVL: -+ if (p_irq->lvl_type == IRQ_LVL_LOW) -+ flag = IRQF_TRIGGER_LOW; -+ else if (p_irq->lvl_type == IRQ_LVL_HIGH) -+ flag = IRQF_TRIGGER_HIGH; -+ else -+ flag = IRQF_TRIGGER_LOW; /*make this as default type */ -+ break; -+ default: -+ flag = IRQF_TRIGGER_LOW; /*make this as default type */ -+ break; -+ } -+#endif -+/* irq_set_irq_type(p_irq->irq_id, flag); */ -+ i_ret = 0; -+ } -+ break; -+ default: -+ i_ret = ERR_INVALID_PAR; -+ break; -+ } -+ -+ return i_ret; -+} -+void mtk_btif_read_cpu_sw_rst_debug_plat(void) -+{ -+#define CONSYS_AP2CONN_WAKEUP_OFFSET 0x00000064 -+ BTIF_WARN_FUNC("+CONSYS_AP2CONN_WAKEUP_OFFSET(0x%x)\n", -+ BTIF_READ32(mtk_btif.base + CONSYS_AP2CONN_WAKEUP_OFFSET)); -+} -+ -diff --git a/drivers/misc/mediatek/btif/common/inc/mtk_btif.h b/drivers/misc/mediatek/btif/common/inc/mtk_btif.h -new file mode 100644 -index 0000000000000..5e2f5a9857d91 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/inc/mtk_btif.h -@@ -0,0 +1,370 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef __MTK_BTIF_H_ -+#define __MTK_BTIF_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include /* gettimeofday */ -+#include -+ -+#include "btif_pub.h" -+#include "btif_dma_pub.h" -+#include "mtk_btif_exp.h" -+ -+#define BTIF_PORT_NR 1 -+#define BTIF_USER_NAME_MAX_LEN 32 -+ -+/*-------------Register Defination Start ---------------*/ -+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD)) -+#define BTIF_RX_BUFFER_SIZE (1024 * 32) -+#else -+#define BTIF_RX_BUFFER_SIZE (1024 * 64) -+#endif -+#define BTIF_TX_FIFO_SIZE (1024 * 4) -+ -+/*------------Register Defination End ----------------*/ -+ -+/*------------BTIF Module Clock and Power Control Defination---------------*/ -+typedef enum _ENUM_BTIF_RX_TYPE_ { -+ BTIF_IRQ_CTX = 0, -+ BTIF_TASKLET_CTX = BTIF_IRQ_CTX + 1, -+ BTIF_THREAD_CTX = BTIF_TASKLET_CTX + 1, -+ BTIF_WQ_CTX = BTIF_THREAD_CTX + 1, -+ BTIF_RX_TYPE_MAX, -+} ENUM_BTIF_RX_TYPE; -+ -+typedef enum _ENUM_BTIF_TX_TYPE_ { -+ BTIF_TX_USER_CTX = 0, -+ BTIF_TX_SINGLE_CTX = BTIF_TX_USER_CTX + 1, -+ BTIF_TX_TYPE_MAX, -+} ENUM_BTIF_TX_TYPE; -+ -+typedef enum _ENUM_BTIF_STATE_ { -+ B_S_OFF = 0, -+ B_S_SUSPEND = B_S_OFF + 1, -+ B_S_DPIDLE = B_S_SUSPEND + 1, -+ B_S_ON = B_S_DPIDLE + 1, -+ B_S_MAX, -+} ENUM_BTIF_STATE; -+ -+#define ENABLE_BTIF_RX_DMA 1 -+#define ENABLE_BTIF_TX_DMA 1 -+ -+#if ENABLE_BTIF_TX_DMA -+#define BTIF_TX_MODE BTIF_MODE_DMA -+#else -+#define BTIF_TX_MODE BTIF_MODE_PIO -+#endif -+ -+#if ENABLE_BTIF_RX_DMA -+#define BTIF_RX_MODE BTIF_MODE_DMA -+#else -+#define BTIF_RX_MODE BTIF_MODE_PIO -+#endif -+ -+#define BTIF_RX_BTM_CTX BTIF_THREAD_CTX/*BTIF_WQ_CTX*//* BTIF_TASKLET_CTX */ -+/* -+ * -- cannot be used because , -+ * mtk_wcn_stp_parser data will call *(stp_if_tx) to send ack, -+ * in which context sleepable lock or usleep operation may be used, -+ * these operation is not allowed in tasklet, may cause schedule_bug -+ */ -+ -+#define BTIF_TX_CTX BTIF_TX_USER_CTX /* BTIF_TX_SINGLE_CTX */ -+ -+#define ENABLE_BTIF_RX_THREAD_RT_SCHED 0 -+#define MAX_BTIF_RXD_TIME_REC 3 -+ -+/*Structure Defination*/ -+ -+/*-----------------BTIF setting--------------*/ -+typedef struct _mtk_btif_setting_ { -+ ENUM_BTIF_MODE tx_mode; /*BTIF Tx Mode Setting */ -+ ENUM_BTIF_MODE rx_mode; /*BTIF Tx Mode Setting */ -+ ENUM_BTIF_RX_TYPE rx_type; /*rx handle type */ -+ ENUM_BTIF_TX_TYPE tx_type; /*tx type */ -+} mtk_btif_setting, *p_mtk_btif_setting; -+/*---------------------------------------------------------------------------*/ -+ -+#if 0 -+/*---------------------------------------------------------------------------*/ -+typedef struct _mtk_btif_register_ { -+ unsigned int iir; /*Interrupt Identification Register */ -+ unsigned int lsr; /*Line Status Register */ -+ unsigned int fake_lcr; /*Fake Lcr Regiseter */ -+ unsigned int fifo_ctrl; /*FIFO Control Register */ -+ unsigned int ier; /*Interrupt Enable Register */ -+ unsigned int sleep_en; /*Sleep Enable Register */ -+ unsigned int rto_counter; /*Rx Timeout Counter Register */ -+ unsigned int dma_en; /*DMA Enalbe Register */ -+ unsigned int tri_lvl; /*Tx/Rx Trigger Level Register */ -+ unsigned int wat_time; /*Async Wait Time Register */ -+ unsigned int handshake; /*New HandShake Mode Register */ -+ unsigned int sleep_wak; /*Sleep Wakeup Reigster */ -+} mtk_btif_register, *p_mtk_btif_register; -+/*---------------------------------------------------------------------------*/ -+ -+#endif -+ -+typedef struct _btif_buf_str_ { -+ unsigned int size; -+ unsigned char *p_buf; -+ /* -+ * For Tx: next Tx data pointer to FIFO; -+ * For Rx: next read data pointer from BTIF user -+ */ -+ unsigned int rd_idx; -+ /* -+ * For Tx: next Tx data pointer from BTIF user; -+ * For Rx: next write data(from FIFO) pointer -+ */ -+ unsigned int wr_idx; -+} btif_buf_str, *p_btif_buf_str; -+ -+/*---------------------------------------------------------------------------*/ -+typedef struct _mtk_btif_dma_ { -+ /*p_mtk_btif*/ void *p_btif; -+ /*BTIF pointer to which DMA belongs */ -+ -+#if 0 -+ unsigned int channel; /*DMA's channel */ -+#endif -+ -+ ENUM_BTIF_DIR dir; /*DMA's direction: */ -+ bool enable; /*DMA enable or disable flag */ -+ -+ P_MTK_DMA_INFO_STR p_dma_info; /*DMA's IRQ information */ -+ -+#if 0 -+ mtk_dma_register register; /*DMA's register */ -+#endif -+ -+ spinlock_t iolock; /*io lock for DMA channel */ -+ atomic_t entry; /* entry count */ -+} mtk_btif_dma, *p_mtk_btif_dma; -+ -+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD)) -+#define BTIF_LOG_ENTRY_NUM 10 -+#else -+#define BTIF_LOG_ENTRY_NUM 30 -+#endif -+ -+#define BTIF_LOG_SZ 1536 -+ -+typedef void (*MTK_BTIF_RX_NOTIFY) (void); -+ -+typedef struct _btif_log_buf_t_ { -+ unsigned int len; -+ struct timeval timer; -+ unsigned char buffer[BTIF_LOG_SZ]; -+} BTIF_LOG_BUF_T, *P_BTIF_LOG_BUF_T; -+ -+typedef struct _btif_log_queue_t_ { -+ ENUM_BTIF_DIR dir; -+ bool enable; -+ bool output_flag; -+ unsigned int in; -+ unsigned int out; -+ unsigned int size; -+ spinlock_t lock; -+ P_BTIF_LOG_BUF_T p_queue[BTIF_LOG_ENTRY_NUM]; -+} BTIF_LOG_QUEUE_T, *P_BTIF_LOG_QUEUE_T; -+ -+/*---------------------------------------------------------------------------*/ -+typedef struct _mtk_btif_ { -+ unsigned int open_counter; /*open counter */ -+ bool enable; /*BTIF module enable flag */ -+ bool lpbk_flag; /*BTIF module enable flag */ -+#if 0 -+ unsigned long base; /* BTIF controller base address */ -+#endif -+ -+ ENUM_BTIF_STATE state; /*BTIF state mechanism */ -+ struct mutex state_mtx; /*lock to BTIF state mechanism's state change */ -+ struct mutex ops_mtx; /*lock to BTIF's open and close */ -+ -+#if 0 -+ mtk_btif_register register; /*BTIF registers */ -+#endif -+ -+ ENUM_BTIF_MODE tx_mode; /* BTIF Tx channel mode */ -+ ENUM_BTIF_MODE rx_mode; /* BTIF Rx channel mode */ -+ struct mutex tx_mtx; /*lock to BTIF's tx process */ -+/*rx handling */ -+ ENUM_BTIF_RX_TYPE btm_type; /*BTIF Rx bottom half context */ -+/*tx handling*/ -+ ENUM_BTIF_TX_TYPE tx_ctx; /*BTIF tx context */ -+/* unsigned char rx_buf[BTIF_RX_BUFFER_SIZE]; */ -+ btif_buf_str btif_buf; -+ spinlock_t rx_irq_spinlock; /*lock for rx irq handling */ -+ -+/*rx workqueue information*/ -+ /*lock to BTIF's rx bottom half when kernel thread is used */ -+ struct mutex rx_mtx; -+ struct workqueue_struct *p_rx_wq; -+ struct work_struct rx_work; -+ -+ struct workqueue_struct *p_tx_wq; -+ struct work_struct tx_work; -+ struct kfifo *p_tx_fifo; -+ -+/*rx tasklet information*/ -+ struct tasklet_struct rx_tasklet; -+ /*lock to BTIF's rx bottom half when tasklet is used */ -+ spinlock_t rx_tasklet_spinlock; -+ -+/*rx thread information*/ -+ struct task_struct *p_task; -+ struct completion rx_comp; -+ -+ mtk_btif_setting *setting; /*BTIF setting */ -+ -+ p_mtk_btif_dma p_tx_dma; /*BTIF Tx channel DMA */ -+ p_mtk_btif_dma p_rx_dma; /*BTIF Rx channel DMA */ -+ -+ MTK_WCN_BTIF_RX_CB rx_cb; /*Rx callback function */ -+ MTK_BTIF_RX_NOTIFY rx_notify; -+ -+ P_MTK_BTIF_INFO_STR p_btif_info; /*BTIF's information */ -+ -+/*Log Tx data to buffer*/ -+ BTIF_LOG_QUEUE_T tx_log; -+ -+/*Log Rx data to buffer*/ -+ BTIF_LOG_QUEUE_T rx_log; -+ -+/* struct list_head *p_user_list; */ -+ struct list_head user_list; -+/* get btif dev pointer*/ -+ void *private_data; -+} mtk_btif, *p_mtk_btif; -+/*---------------------------------------------------------------------------*/ -+ -+/*---------------------------------------------------------------------------*/ -+#if 0 -+/*---------------------------------------------------------------------------*/ -+typedef struct _mtk_dma_register_ { -+ unsigned int int_flag; /*Tx offset:0x0 Rx offset:0x0 */ -+ unsigned int int_enable; /*Tx offset:0x4 Rx offset:0x4 */ -+ unsigned int dma_enable; /*Tx offset:0x8 Rx offset:0x8 */ -+ unsigned int dma_reset; /*Tx offset:0xc Rx offset:0xc */ -+ unsigned int dma_stop; /*Tx offset:0x10 Rx offset:0x10 */ -+ unsigned int dma_flush; /*Tx offset:0x14 Rx offset:0x14 */ -+ unsigned int vff_addr; /*Tx offset:0x1c Rx offset:0x1c */ -+ unsigned int vff_len; /*Tx offset:0x24 Rx offset:0x24 */ -+ unsigned int vff_thr; /*Tx offset:0x28 Rx offset:0x28 */ -+ unsigned int vff_wpt; /*Tx offset:0x2c Rx offset:0x2c */ -+ unsigned int vff_rpt; /*Tx offset:0x30 Rx offset:0x30 */ -+ unsigned int rx_fc_thr; /*Tx:No this register Rx offset:0x34 */ -+ unsigned int int_buf_size; /*Tx offset:0x38 Rx offset:0x38 */ -+ unsigned int vff_valid_size; /*Tx offset:0x3c Rx offset:0x3c */ -+ unsigned int vff_left_size; /*Tx offset:0x40 Rx offset:0x40 */ -+ unsigned int debug_status; /*Tx offset:0x50 Rx offset:0x50 */ -+} mtk_dma_register, *p_mtk_dma_register; -+/*---------------------------------------------------------------------------*/ -+#endif -+ -+/*---------------------------------------------------------------------------*/ -+typedef struct _mtk_btif_user_ { -+ bool enable; /*register its state */ -+ struct list_head entry; /*btif_user's bi-direction list table */ -+ /*BTIF's user, static allocation */ -+ char u_name[BTIF_USER_NAME_MAX_LEN]; -+ unsigned long u_id; -+ p_mtk_btif p_btif; -+} mtk_btif_user, *p_mtk_btif_user; -+ -+/*---------------------------------------------------------------------------*/ -+#define BBS_PTR(ptr, idx) ((ptr->p_buf) + idx) -+ -+#define BBS_SIZE(ptr) ((ptr)->size) -+#define BBS_MASK(ptr) (BBS_SIZE(ptr) - 1) -+#define BBS_COUNT(ptr) ((ptr)->wr_idx >= (ptr)->rd_idx ? (ptr)->wr_idx - \ -+(ptr)->rd_idx : BBS_SIZE(ptr) - \ -+((ptr)->rd_idx - (ptr)->wr_idx)) -+#define BBS_COUNT_CUR(ptr, wr_idx) (wr_idx >= (ptr)->rd_idx ? wr_idx - \ -+(ptr)->rd_idx : BBS_SIZE(ptr) - \ -+((ptr)->rd_idx - wr_idx)) -+ -+#define BBS_LEFT(ptr) (BBS_SIZE(ptr) - BBS_COUNT(ptr)) -+ -+#define BBS_AVL_SIZE(ptr) (BBS_SIZE(ptr) - BBS_COUNT(ptr)) -+#define BBS_FULL(ptr) (BBS_COUNT(ptr) - BBS_SIZE(ptr)) -+#define BBS_EMPTY(ptr) ((ptr)->wr_idx == (ptr)->rd_idx) -+#define BBS_WRITE_MOVE_NEXT(ptr) ((ptr)->wr_idx = \ -+((ptr)->wr_idx + 1) & BBS_MASK(ptr)) -+#define BBS_READ_MOVE_NEXT(ptr) ((ptr)->rd_idx = \ -+((ptr)->rd_idx + 1) & BBS_MASK(ptr)) -+ -+#define BBS_INIT(ptr) \ -+{ \ -+(ptr)->rd_idx = (ptr)->wr_idx = 0; \ -+(ptr)->size = BTIF_RX_BUFFER_SIZE; \ -+} -+ -+ -+#define BTIF_MUTEX_UNLOCK(x) mutex_unlock(x) -+ -+extern mtk_btif g_btif[]; -+ -+int btif_open(p_mtk_btif p_btif); -+int btif_close(p_mtk_btif p_btif); -+int btif_send_data(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len); -+int btif_enter_dpidle(p_mtk_btif p_btif); -+int btif_exit_dpidle(p_mtk_btif p_btif); -+int btif_rx_cb_reg(p_mtk_btif p_btif, MTK_WCN_BTIF_RX_CB rx_cb); -+ -+/*for test purpose*/ -+int _btif_suspend(p_mtk_btif p_btif); -+int _btif_resume(p_mtk_btif p_btif); -+int _btif_restore_noirq(p_mtk_btif p_btif); -+ -+int btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag); -+int btif_log_buf_dmp_in(P_BTIF_LOG_QUEUE_T p_log_que, const char *p_buf, -+ int len); -+int btif_dump_data(char *p_buf, int len); -+int btif_log_buf_dmp_out(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_buf_enable(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_buf_disable(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_output_enable(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_output_disable(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_buf_reset(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_buf_init(p_mtk_btif p_btif); -+int btif_dump_reg(p_mtk_btif p_btif); -+int btif_rx_notify_reg(p_mtk_btif p_btif, MTK_BTIF_RX_NOTIFY rx_notify); -+int btif_raise_wak_signal(p_mtk_btif p_btif); -+int btif_clock_ctrl(p_mtk_btif p_btif, int en); -+bool btif_parser_wmt_evt(p_mtk_btif p_btif, -+ const char *sub_str, -+ unsigned int sub_len); -+void mtk_btif_read_cpu_sw_rst_debug(void); -+ -+#endif /*__MTK_BTIF_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h b/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h -new file mode 100644 -index 0000000000000..3752644fe0aae ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h -@@ -0,0 +1,280 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef _MTK_BTIF_EXP_H_ -+#define _MTK_BTIF_EXP_H_ -+ -+/*--------------marco defination---------------*/ -+#define BTIF_MAX_LEN_PER_PKT 2048 -+#define BTIF_RXD_BE_BLOCKED_DETECT 1 -+/*--------------Enum Defination---------------*/ -+typedef enum _ENUM_BTIF_DPIDLE_ { -+ BTIF_DPIDLE_DISABLE = 0, -+ BTIF_DPIDLE_ENABLE = BTIF_DPIDLE_DISABLE + 1, -+ BTIF_DPIDLE_MAX, -+} ENUM_BTIF_DPIDLE_CTRL; -+ -+typedef enum _ENUM_BTIF_LPBK_MODE_ { -+ BTIF_LPBK_DISABLE = 0, -+ BTIF_LPBK_ENABLE = BTIF_LPBK_DISABLE + 1, -+ BTIF_LPBK_MAX, -+} ENUM_BTIF_LPBK_MODE; -+ -+typedef enum _ENUM_BTIF_DBG_ID_ { -+ BTIF_DISABLE_LOGGER = 0, -+ BTIF_ENABLE_LOGGER = BTIF_DISABLE_LOGGER + 1, -+ BTIF_DUMP_LOG = BTIF_ENABLE_LOGGER + 1, -+ BTIF_CLR_LOG = BTIF_DUMP_LOG + 1, -+ BTIF_DUMP_BTIF_REG = BTIF_CLR_LOG + 1, -+ BTIF_ENABLE_RT_LOG = BTIF_DUMP_BTIF_REG + 1, -+ BTIF_DISABLE_RT_LOG = BTIF_ENABLE_RT_LOG + 1, -+ BTIF_DBG_MAX, -+} ENUM_BTIF_DBG_ID; -+ -+typedef enum _ENUM_BTIF_OP_ERROR_CODE_ { -+ E_BTIF_AGAIN = 0, -+ E_BTIF_FAIL = -1, -+ E_BTIF_BAD_POINTER = -2, -+ E_BTIF_NO_SPACE = -3, -+ E_BTIF_INTR = -4, -+ E_BTIF_INVAL_PARAM = -5, -+ E_BTIF_ALREADY_OPEN = -6, -+ E_BTIF_NOT_OPEN = -7, -+ E_BTIF_INVAL_STATE = -8, -+} ENUM_BTIF_OP_ERROR_CODE; -+ -+/*--------------End of Enum Defination---------------*/ -+ -+/*--------------Type Definition---------------*/ -+ -+typedef int (*MTK_WCN_BTIF_RX_CB) (const unsigned char *p_buf, -+ unsigned int len); -+ -+/*--------------End of Type Definition---------------*/ -+ -+/*--------------Normal Mode API declearation---------------*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_open -+* DESCRIPTION -+* open BTIF interface, will do BTIF module HW and SW initialization -+* PARAMETERS -+* p_owner [IN] pointer to owner who call this API, -+* currently there are 2 owner ("stp" or "btif_tester") -+* may use this module -+* user's id string must be less than 32 bytes -+* for "stp", BTIF will call rx callback function to route rx data to STP module -+* for "stp_tester", BTIF will save rx data -+* and wait for native process to access -+* p_id [IN] BTIF's user id will be put to this address -+* RETURNS -+* int 0 = succeed; others = fail, for detailed information, -+* please see ENUM_BTIF_OP_ERROR_CODE -+* if open success, value p_id will be the only identifier for -+* user to access BTIF's other operations -+* including read/write/dpidle_ctrl/rx_cb_retister -+* this user id is only an identifier used for owner identification -+*****************************************************************************/ -+int mtk_wcn_btif_open(char *p_owner, unsigned long *p_id); -+//EXPORT_SYMBOL(mtk_wcn_btif_open) -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_close -+* DESCRIPTION -+* close BTIF interface, will do BTIF module HW and SW de-initialization -+* once this API is called, p_btif should never be used by BTIF's user again -+* PARAMETERS -+* u_id [IN] BTIF's user id -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_close(unsigned long u_id); -+//EXPORT_SYMBOL(mtk_wcn_btif_close) -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_write -+* DESCRIPTION -+* send data throuth BTIF module -+* there's no internal buffer to cache STP data in BTIF driver, -+* if in DMA mode -+* btif driver will check if there's enough space -+* in vFIFO for data to send in DMA mode -+* if yes, put data to vFIFO and return corresponding data length to caller -+* if no, corresponding error code will be returned to called -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* p_buf [IN] pointer to target data to send -+* len [IN] data length (should be less than 2014 bytes per STP package) -+* -+* if in non-DMA mode, BTIF driver will try to write to THR of BTIF controller -+* if btif driver detected that no space is available in Tx FIFO, -+* will return E_BTIF_NO_SPACE, -+* mostly something is wrong with BTIF or consys when this -+* return value is returned -+* RETURNS -+* int positive: data length send through BTIF; -+* negative: please see ENUM_BTIF_OP_ERROR_CODE -+* E_BTIF_AGAIN (0) will be returned to caller if btif does not have -+* enough vFIFO to send data, when caller get 0, -+* he should wait for a moment (5~10ms maybe) and -+* try a few times (maybe 10~20) -+* if still get E_BTIF_AGAIN, should call BTIF's debug API and -+* dump BTIF driver and BTIF/DMA register information to kernel log -+* for debug -+* E_BTIF_BAD_POINTER will be returned to caller if btif is not -+* opened successfully before call this API -+* E_BTIF_INVAL_PARAM will be returned if parameter is not valid -+ -+*****************************************************************************/ -+int mtk_wcn_btif_write(unsigned long u_id, -+ const unsigned char *p_buf, unsigned int len); -+//EXPORT_SYMBOL(mtk_wcn_btif_write) -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_read -+* DESCRIPTION -+* read data from BTIF module -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* p_buf [IN/OUT] pointer to buffer where rx data will be put -+* max_len [IN] max buffer length -+* RETURNS -+* int positive: data length read from BTIF; -+* negative: please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_read(unsigned long u_id, -+ unsigned char *p_buf, unsigned int max_len); -+//EXPORT_SYMBOL(mtk_wcn_btif_read) -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_dpidle_ctrl -+* DESCRIPTION -+* control if BTIF module allow system enter deepidle state or not -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* en_flag [IN] one of ENUM_BTIF_DPIDLE_CTRL -+* RETURNS -+* int always return 0 -+*****************************************************************************/ -+int mtk_wcn_btif_dpidle_ctrl(unsigned long u_id, ENUM_BTIF_DPIDLE_CTRL en_flag); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_rx_cb_register -+* DESCRIPTION -+* register rx callback function to BTIF module by btif user -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* rx_cb [IN] pointer to stp rx handler callback function, -+* should be comply with MTK_WCN_BTIF_RX_CB -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_rx_cb_register(unsigned long u_id, MTK_WCN_BTIF_RX_CB rx_cb); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_wakeup_consys -+* DESCRIPTION -+* once sleep command is sent to con sys, -+* should call this API before send wakeup command to -+* make con sys aware host want to send data to consys -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_wakeup_consys(unsigned long u_id); -+ -+/*--------------End of Normal Mode API declearation----------------*/ -+ -+/*--------------Debug Purpose API declearation----------------*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_loopback_ctrl -+* DESCRIPTION -+* enable/disable BTIF internal loopback function, -+* when this function is enabled, -+* data send to btif will be received by btif itself -+* only for debug purpose, should never use this function in normal mode -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* enable [IN] loopback mode control flag, enable or disable, -+* shou be one of ENUM_BTIF_LPBK_MODE -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_loopback_ctrl(unsigned long u_id, ENUM_BTIF_LPBK_MODE enable); -+//EXPORT_SYMBOL(mtk_wcn_btif_loopback_ctrl) -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_logger_ctrl -+* DESCRIPTION -+* control BTIF logger function's behavior -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* flag [IN] should be one of ENUM_BTIF_DBG_ID -+* BTIF_DISABLE_LOGGER - disable btif logger -+* BTIF_ENABLE_LOGGER - enable btif logger -+* BTIF_DUMP_LOG - dump log logged by btif -+* BTIF_CLR_LOG - clear btif log buffer -+* BTIF_DUMP_BTIF_REG - dump btif controller's register -+* BTIF_DUMP_DMA_REG - dump DMA controller's register -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, -+* please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_dbg_ctrl(unsigned long u_id, ENUM_BTIF_DBG_ID flag); -+//EXPORT_SYMBOL(mtk_wcn_btif_dbg_ctrl); -+/*-----------End of Debug Purpose API declearation------------*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_parser_wmt_evt -+* DESCRIPTION -+* parser wmt sleep/wakeup evt in btif bbs buffer for debug -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* sub_str [IN] the str to be parsered -+* str_len [IN] the length of sub_str -+* RETURNS -+* bool true = succeed; -+* false = fail; -+*****************************************************************************/ -+bool mtk_wcn_btif_parser_wmt_evt(unsigned long u_id, -+ const char *sub_str, unsigned int str_len); -+ -+int mtk_btif_exp_open_test(void); -+int mtk_btif_exp_close_test(void); -+int mtk_btif_exp_write_test(void); -+int mtk_btif_exp_suspend_test(void); -+int mtk_btif_exp_resume_test(void); -+int mtk_btif_exp_enter_dpidle_test(void); -+int mtk_btif_exp_exit_dpidle_test(void); -+int mtk_btif_exp_write_stress_test(unsigned int length, unsigned int loop); -+int mtk_btif_exp_log_debug_test(int flag); -+int mtk_btif_exp_restore_noirq_test(void); -+int btif_wakeup_consys_no_id(void); -+int mtk_btif_exp_clock_ctrl(int en); -+#if BTIF_RXD_BE_BLOCKED_DETECT -+int mtk_btif_rxd_be_blocked_flag_get(void); -+#endif -+void mtk_btif_read_cpu_sw_rst_debug_exp(void); -+#endif /*_MTK_BTIF_EXP_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/mtk_btif.c b/drivers/misc/mediatek/btif/common/mtk_btif.c -new file mode 100644 -index 0000000000000..0212ad41049f0 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/mtk_btif.c -@@ -0,0 +1,3472 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+/*-----------linux system header files----------------*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/*#include */ -+/*-----------driver own header files----------------*/ -+#ifdef CONFIG_COMPAT -+#include -+#endif -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "MTK-BTIF" -+ -+#define BTIF_CDEV_SUPPORT 1 -+ -+#include "btif_pub.h" -+#include "btif_dma_pub.h" -+#include "mtk_btif_exp.h" -+#include "mtk_btif.h" -+ -+/*-----------static function declearation----------------*/ -+static int mtk_btif_probe(struct platform_device *pdev); -+static int mtk_btif_remove(struct platform_device *pdev); -+static int mtk_btif_suspend(struct platform_device *pdev, pm_message_t state); -+static int mtk_btif_resume(struct platform_device *pdev); -+static int mtk_btif_drv_resume(struct device *dev); -+static int mtk_btif_drv_suspend(struct device *pdev); -+ -+static int mtk_btif_restore_noirq(struct device *device); -+static int btif_file_open(struct inode *pinode, struct file *pfile); -+static int btif_file_release(struct inode *pinode, struct file *pfile); -+static ssize_t btif_file_read(struct file *pfile, -+ char __user *buf, size_t count, loff_t *f_ops); -+static unsigned int btif_poll(struct file *filp, poll_table *wait); -+static int _btif_irq_reg(P_MTK_BTIF_IRQ_STR p_irq, -+ mtk_btif_irq_handler irq_handler, void *data); -+static int _btif_irq_free(P_MTK_BTIF_IRQ_STR p_irq, void *data); -+static int _btif_irq_ctrl(P_MTK_BTIF_IRQ_STR p_irq, bool en); -+static int _btif_irq_ctrl_sync(P_MTK_BTIF_IRQ_STR p_irq, bool en); -+static irqreturn_t btif_irq_handler(int irq, void *data); -+static unsigned int btif_pio_rx_data_receiver(P_MTK_BTIF_INFO_STR p_btif_info, -+ unsigned char *p_buf, -+ unsigned int buf_len); -+ -+static irqreturn_t btif_tx_dma_irq_handler(int irq, void *data); -+static irqreturn_t btif_rx_dma_irq_handler(int irq, void *data); -+ -+static unsigned int btif_dma_rx_data_receiver(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, -+ unsigned int buf_len); -+static int _btif_controller_tx_setup(p_mtk_btif p_btif); -+static int _btif_controller_tx_free(p_mtk_btif p_btif); -+static int _btif_controller_rx_setup(p_mtk_btif p_btif); -+static int _btif_controller_rx_free(p_mtk_btif p_btif); -+static int _btif_tx_pio_setup(p_mtk_btif p_btif); -+static int _btif_rx_pio_setup(p_mtk_btif p_btif); -+static int _btif_rx_dma_setup(p_mtk_btif p_btif); -+static int _btif_rx_dma_free(p_mtk_btif p_btif); -+static int _btif_tx_dma_setup(p_mtk_btif p_btif); -+static int _btif_tx_dma_free(p_mtk_btif p_btif); -+static int _btif_controller_setup(p_mtk_btif p_btif); -+static int _btif_controller_free(p_mtk_btif p_btif); -+ -+static int _btif_pio_write(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len); -+static int _btif_dma_write(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len); -+ -+static unsigned int btif_bbs_wr_direct(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len); -+static unsigned int btif_bbs_read(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len); -+static unsigned int btif_bbs_write(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len); -+static void btif_dump_bbs_str(unsigned char *p_str, p_btif_buf_str p_bbs); -+static int _btif_dump_memory(char *str, unsigned char *p_buf, unsigned int buf_len); -+static int _btif_rx_btm_deinit(p_mtk_btif p_btif); -+static int _btif_rx_btm_sched(p_mtk_btif p_btif); -+static int _btif_rx_btm_init(p_mtk_btif p_btif); -+static void btif_rx_tasklet(unsigned long func_data); -+static void btif_rx_worker(struct work_struct *p_work); -+static int btif_rx_thread(void *p_data); -+static int btif_rx_data_consummer(p_mtk_btif p_btif); -+ -+static int _btif_tx_ctx_init(p_mtk_btif p_btif); -+static int _btif_tx_ctx_deinit(p_mtk_btif p_btif); -+static void btif_tx_worker(struct work_struct *p_work); -+ -+static int _btif_state_deinit(p_mtk_btif p_btif); -+static int _btif_state_release(p_mtk_btif p_btif); -+static ENUM_BTIF_STATE _btif_state_get(p_mtk_btif p_btif); -+static int _btif_state_set(p_mtk_btif p_btif, ENUM_BTIF_STATE state); -+static int _btif_state_hold(p_mtk_btif p_btif); -+static int _btif_state_init(p_mtk_btif p_btif); -+ -+static int _btif_dpidle_notify_ctrl(p_mtk_btif p_btif, -+ ENUM_BTIF_DPIDLE_CTRL en_flag); -+static int _btif_enter_dpidle(p_mtk_btif p_btif); -+static int _btif_exit_dpidle(p_mtk_btif p_btif); -+static int _btif_exit_dpidle_from_sus(p_mtk_btif p_btif); -+static int _btif_exit_dpidle_from_dpidle(p_mtk_btif p_btif); -+static int _btif_enter_dpidle_from_on(p_mtk_btif p_btif); -+static int _btif_enter_dpidle_from_sus(p_mtk_btif p_btif); -+ -+#if ENABLE_BTIF_TX_DMA -+static int _btif_vfifo_deinit(p_mtk_btif_dma p_dma); -+static int _btif_vfifo_init(p_mtk_btif_dma p_dma); -+#endif -+ -+static bool _btif_is_tx_complete(p_mtk_btif p_btif); -+static int _btif_init(p_mtk_btif p_btif); -+static int _btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag); -+static int btif_rx_dma_mode_set(int en); -+static int btif_tx_dma_mode_set(int en); -+ -+static int _btif_send_data(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len); -+ -+/*-----------end of static function declearation----------------*/ -+ -+static const char *g_state[B_S_MAX] = { -+ "OFF", -+ "SUSPEND", -+ "DPIDLE", -+ "ON", -+}; -+ -+/*-----------BTIF setting--------------*/ -+mtk_btif_setting g_btif_setting[BTIF_PORT_NR] = { -+ { -+ .tx_mode = BTIF_TX_MODE, -+ .rx_mode = BTIF_RX_MODE, -+ .rx_type = BTIF_RX_BTM_CTX, -+ .tx_type = BTIF_TX_CTX, -+ }, -+}; -+ -+mtk_btif g_btif[BTIF_PORT_NR] = { -+ { -+ .open_counter = 0, -+ .state = B_S_OFF, -+ .setting = &g_btif_setting[0], -+ .p_tx_dma = NULL, -+ .p_rx_dma = NULL, -+ .rx_cb = NULL, -+ .p_btif_info = NULL, -+ }, -+}; -+ -+mtk_btif_dma g_dma[BTIF_PORT_NR][BTIF_DIR_MAX] = { -+ { -+ { -+ .p_btif = NULL, -+ .dir = BTIF_TX, -+ .p_dma_info = NULL, -+ .entry = ATOMIC_INIT(0), -+ }, -+ { -+ .p_btif = NULL, -+ .dir = BTIF_RX, -+ .p_dma_info = NULL, -+ .entry = ATOMIC_INIT(0), -+ }, -+ }, -+}; -+ -+#define G_MAX_PKG_LEN (7 * 1024) -+static int g_max_pkg_len = G_MAX_PKG_LEN; /*DMA vFIFO is set to 8 * 1024, we set this to 7/8 * vFIFO size*/ -+static int g_max_pding_data_size = BTIF_RX_BUFFER_SIZE * 3 / 4; -+ -+ -+static int mtk_btif_dbg_lvl = BTIF_LOG_ERR; -+ -+#if BTIF_RXD_BE_BLOCKED_DETECT -+static struct timeval btif_rxd_time_stamp[MAX_BTIF_RXD_TIME_REC]; -+#endif -+/*-----------Platform bus related structures----------------*/ -+#define DRV_NAME "mtk_btif" -+ -+#ifdef CONFIG_OF -+const struct of_device_id apbtif_of_ids[] = { -+ { .compatible = "mediatek,mtk-btif", }, -+ {} -+}; -+#endif -+ -+const struct dev_pm_ops mtk_btif_drv_pm_ops = { -+ .restore_noirq = mtk_btif_restore_noirq, -+ .suspend = mtk_btif_drv_suspend, -+ .resume = mtk_btif_drv_resume, -+}; -+ -+struct platform_driver mtk_btif_dev_drv = { -+ .probe = mtk_btif_probe, -+ .remove = mtk_btif_remove, -+#ifdef CONFIG_PM -+ .suspend = mtk_btif_suspend, -+ .resume = mtk_btif_resume, -+#endif -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+#ifdef CONFIG_PM -+ .pm = &mtk_btif_drv_pm_ops, -+#endif -+#ifdef CONFIG_OF -+ .of_match_table = apbtif_of_ids, -+#endif -+ } -+}; -+ -+#define BTIF_STATE_RELEASE(x) _btif_state_release(x) -+ -+/*-----------End of Platform bus related structures----------------*/ -+ -+/*-----------platform bus related operation APIs----------------*/ -+ -+static int mtk_btif_probe(struct platform_device *pdev) -+{ -+/*Chaozhong: ToDo: to be implement*/ -+/*register IRQ for BTIF and Tx Rx DMA and disable them by default*/ -+ BTIF_INFO_FUNC("DO BTIF PROBE\n"); -+ platform_set_drvdata(pdev, &g_btif[0]); -+ g_btif[0].private_data = (struct device *)&pdev->dev; -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+ hal_btif_clk_get_and_prepare(pdev); -+#endif -+ -+ return 0; -+} -+ -+static int mtk_btif_remove(struct platform_device *pdev) -+{ -+/*Chaozhong: ToDo: to be implement*/ -+ BTIF_INFO_FUNC("DO BTIF REMOVE\n"); -+ platform_set_drvdata(pdev, NULL); -+ g_btif[0].private_data = NULL; -+ return 0; -+} -+ -+int _btif_suspend(p_mtk_btif p_btif) -+{ -+ int i_ret; -+ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ if (p_btif != NULL) { -+ if (!(p_btif->enable)) -+ i_ret = 0; -+ else { -+ if (_btif_state_get(p_btif) == B_S_ON) { -+ BTIF_ERR_FUNC("BTIF in ON state,", -+ "there are data need to be send or recev,suspend fail\n"); -+ i_ret = -1; -+ } else { -+ /* -+ * before disable BTIF controller and DMA controller -+ * we need to set BTIF to ON state -+ */ -+ i_ret = _btif_exit_dpidle(p_btif); -+ if (i_ret == 0) { -+ i_ret += _btif_controller_free(p_btif); -+ i_ret = _btif_controller_tx_free(p_btif); -+ i_ret += _btif_controller_rx_free(p_btif); -+ } -+ if (i_ret != 0) { -+ BTIF_INFO_FUNC("failed\n"); -+ /*Chaozhong: what if failed*/ -+ } else { -+ BTIF_INFO_FUNC("succeed\n"); -+ i_ret = _btif_state_set(p_btif, B_S_SUSPEND); -+ if (i_ret && _btif_init(p_btif)) { -+ /*Chaozhong:BTIF re-init failed? what to do*/ -+ i_ret = _btif_state_set(p_btif, B_S_OFF); -+ } -+ } -+ } -+ } -+ } else -+ i_ret = -1; -+ BTIF_STATE_RELEASE(p_btif); -+ -+ return i_ret; -+} -+ -+ -+static int mtk_btif_drv_suspend(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ pm_message_t state = PMSG_SUSPEND; -+ -+ return mtk_btif_suspend(pdev, state); -+} -+ -+static int mtk_btif_drv_resume(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ -+ return mtk_btif_resume(pdev); -+} -+ -+static int mtk_btif_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = NULL; -+ -+/*Chaozhong: ToDo: to be implement*/ -+ BTIF_DBG_FUNC("++\n"); -+ p_btif = platform_get_drvdata(pdev); -+ i_ret = _btif_suspend(p_btif); -+ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); -+ return i_ret; -+} -+ -+int _btif_restore_noirq(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+/*BTIF IRQ restore no irq*/ -+ i_ret = hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_RESTORE_NOIRQ); -+ if (i_ret == 0) { -+ BTIF_INFO_FUNC("BTIF HW IRQ restore succeed\n"); -+ } else { -+ BTIF_INFO_FUNC("BTIF HW IRQ restore failed, i_ret:%d\n", i_ret); -+ return i_ret; -+ } -+/*BTIF DMA restore no irq*/ -+ if (p_btif->tx_mode & BTIF_MODE_DMA) { -+ i_ret = hal_dma_pm_ops(p_btif->p_tx_dma->p_dma_info, -+ BTIF_PM_RESTORE_NOIRQ); -+ if (i_ret == 0) { -+ BTIF_INFO_FUNC("BTIF Tx DMA IRQ restore succeed\n"); -+ } else { -+ BTIF_INFO_FUNC -+ ("BTIF Tx DMA IRQ restore failed, i_ret:%d\n", -+ i_ret); -+ return i_ret; -+ } -+ } -+ if (p_btif->rx_mode & BTIF_MODE_DMA) { -+ i_ret = hal_dma_pm_ops(p_btif->p_rx_dma->p_dma_info, -+ BTIF_PM_RESTORE_NOIRQ); -+ if (i_ret == 0) { -+ BTIF_INFO_FUNC("BTIF Rx DMA IRQ restore succeed\n"); -+ } else { -+ BTIF_INFO_FUNC -+ ("BTIF Rx DMA IRQ restore failed, i_ret:%d\n", -+ i_ret); -+ return i_ret; -+ } -+ } -+ return i_ret; -+} -+ -+static int mtk_btif_restore_noirq(struct device *dev) -+{ -+ int i_ret = 0; -+ struct platform_device *pdev = to_platform_device(dev); -+ p_mtk_btif p_btif = platform_get_drvdata(pdev); -+ -+ BTIF_INFO_FUNC("++\n"); -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ if (p_btif->enable) -+ BTIF_ERR_FUNC("!!!-----------------!BTIF is not closed before IPOH shutdown!!!---------------!\n"); -+ WARN_ON(p_btif->enable); -+ -+ i_ret = _btif_restore_noirq(p_btif); -+ BTIF_STATE_RELEASE(p_btif); -+ BTIF_INFO_FUNC("--\n"); -+ return 0; -+} -+ -+int _btif_resume(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ ENUM_BTIF_STATE state = B_S_MAX; -+ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ if (p_btif != NULL) { -+ state = _btif_state_get(p_btif); -+ if (!(p_btif->enable)) -+ i_ret = 0; -+ else if (state == B_S_SUSPEND) -+ i_ret = _btif_enter_dpidle(p_btif); -+ else -+ BTIF_INFO_FUNC -+ ("BTIF state: %s before resume, do nothing\n", g_state[state]); -+ } else -+ i_ret = -1; -+ BTIF_STATE_RELEASE(p_btif); -+ -+ return i_ret; -+} -+ -+static int mtk_btif_resume(struct platform_device *pdev) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = NULL; -+/*Chaozhong: ToDo: to be implement*/ -+ BTIF_DBG_FUNC("++\n"); -+ p_btif = platform_get_drvdata(pdev); -+ i_ret = _btif_resume(p_btif); -+ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); -+ return 0; -+} -+ -+/*-----------device node----------------*/ -+#if BTIF_CDEV_SUPPORT -+ -+dev_t btif_dev; -+struct class *p_btif_class; -+struct device *p_btif_dev; -+const char *p_btif_dev_name = "btif"; -+static struct semaphore wr_mtx; -+static struct semaphore rd_mtx; -+unsigned char wr_buf[2048]; -+unsigned char rd_buf[2048]; -+static int rx_notify_flag; -+static DECLARE_WAIT_QUEUE_HEAD(btif_wq); -+static int btif_file_open(struct inode *pinode, struct file *pfile); -+static int btif_file_release(struct inode *pinode, struct file *pfile); -+static ssize_t btif_file_read(struct file *pfile, -+ char __user *buf, size_t count, loff_t *f_ops); -+ -+static ssize_t btif_file_write(struct file *filp, -+ const char __user *buf, size_t count, loff_t *f_pos); -+static long btif_unlocked_ioctl(struct file *filp, unsigned int cmd, -+ unsigned long arg); -+#ifdef CONFIG_COMPAT -+static long btif_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -+#endif -+static struct cdev btif_dev_c; -+static wait_queue_head_t btif_read_inq; /* read queues */ -+ -+const struct file_operations mtk_btif_fops = { -+ .owner = THIS_MODULE, -+ .open = btif_file_open, -+ .release = btif_file_release, -+ .read = btif_file_read, -+ .write = btif_file_write, -+ .unlocked_ioctl = btif_unlocked_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = btif_compat_ioctl, -+#endif -+ .poll = btif_poll, -+}; -+ -+static int btif_chrdev_init(void) -+{ -+ int i_ret; -+ -+ int i_err; -+ -+ /* alloc device number dynamically */ -+ i_ret = alloc_chrdev_region(&btif_dev, 0, 1, p_btif_dev_name); -+ if (i_ret) { -+ BTIF_ERR_FUNC("devuce number allocation failed, i_ret:%d\n", -+ i_ret); -+ } else { -+ BTIF_INFO_FUNC("devuce number allocation succeed\n"); -+ } -+ cdev_init(&btif_dev_c, &mtk_btif_fops); -+ btif_dev_c.owner = THIS_MODULE; -+ i_err = cdev_add(&btif_dev_c, btif_dev, 1); -+ if (i_err) { -+ BTIF_ERR_FUNC("error add btif dev to kernel, error code:%d\n", -+ i_err); -+ unregister_chrdev_region(btif_dev, 1); -+ btif_dev = 0; -+ return -1; -+ } -+ BTIF_INFO_FUNC("add btif dev to kernel succeed\n"); -+ -+ p_btif_class = class_create(THIS_MODULE, p_btif_dev_name); -+ if (IS_ERR(p_btif_class)) { -+ BTIF_ERR_FUNC("error happened when doing class_create\n"); -+ unregister_chrdev_region(btif_dev, 1); -+ btif_dev = 0; -+ return -2; -+ } -+ BTIF_INFO_FUNC("create class for btif succeed\n"); -+ -+ p_btif_dev = device_create(p_btif_class, -+ NULL, btif_dev, 0, p_btif_dev_name); -+ if (IS_ERR(p_btif_dev)) { -+ BTIF_ERR_FUNC("error happened when doing device_create\n"); -+ class_destroy(p_btif_class); -+ p_btif_class = NULL; -+ unregister_chrdev_region(btif_dev, 1); -+ btif_dev = 0; -+ return -3; -+ } -+ BTIF_INFO_FUNC("create device for btif succeed\n"); -+ -+ return 0; -+} -+ -+void btif_rx_notify_cb(void) -+{ -+ BTIF_DBG_FUNC("++\n"); -+ rx_notify_flag = 1; -+ wake_up(&btif_wq); -+ wake_up_interruptible(&btif_read_inq); -+ BTIF_DBG_FUNC("--\n"); -+} -+ -+unsigned int btif_poll(struct file *filp, poll_table *wait) -+{ -+ unsigned int mask = 0; -+ unsigned int ava_len = 0; -+/* btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); */ -+ unsigned int wr_idx = g_btif[0].btif_buf.wr_idx; -+ -+/* BTIF_Rx_IRQ_Disable(); */ -+ ava_len = BBS_COUNT_CUR(&(g_btif[0].btif_buf), wr_idx); -+ BTIF_INFO_FUNC("++\n"); -+ if (ava_len == 0) { -+ poll_wait(filp, &btif_read_inq, wait); -+ wr_idx = g_btif[0].btif_buf.wr_idx; -+ ava_len = BBS_COUNT_CUR(&(g_btif[0].btif_buf), wr_idx); -+/* btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); */ -+ if (ava_len) -+ mask |= POLLIN | POLLRDNORM; /* readable */ -+ } else { -+ mask |= POLLIN | POLLRDNORM; /* readable */ -+ } -+/*make for writable*/ -+ mask |= POLLOUT | POLLWRNORM; /* writable */ -+ BTIF_INFO_FUNC("--, mask:%d\n", mask); -+ return mask; -+} -+ -+static int _btif_file_open(void) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ BTIF_INFO_FUNC("++\n"); -+ -+/*Chaozhong: ToDo: to be implement*/ -+ i_ret = btif_open(p_btif); -+ if ((i_ret != 0) && (i_ret != E_BTIF_ALREADY_OPEN)) { -+ BTIF_ERR_FUNC("btif_open failed, error code:%d\n", i_ret); -+ } else { -+ BTIF_INFO_FUNC("btif_open succeed\n"); -+ i_ret = 0; -+ } -+/*semaphore for read and write operation init*/ -+ sema_init(&wr_mtx, 1); -+ sema_init(&rd_mtx, 1); -+ -+/*buffer for read and write init*/ -+ memset(wr_buf, 0, sizeof(wr_buf)); -+ memset(rd_buf, 0, sizeof(rd_buf)); -+ init_waitqueue_head(&(btif_read_inq)); -+ btif_rx_notify_reg(p_btif, btif_rx_notify_cb); -+ BTIF_INFO_FUNC("--\n"); -+ return i_ret; -+} -+ -+static int _btif_file_close(void) -+{ -+ int i_ret = -1; -+ -+ BTIF_INFO_FUNC("++\n"); -+/*Chaozhong: ToDo: to be implement*/ -+ i_ret = btif_close(&g_btif[0]); -+ if (i_ret != 0) -+ BTIF_ERR_FUNC("btif_close failed, error code:%d\n", i_ret); -+ else -+ BTIF_INFO_FUNC("btif_close succeed\n"); -+ -+ BTIF_INFO_FUNC("--\n"); -+ return i_ret; -+} -+ -+static int btif_file_open(struct inode *pinode, struct file *pfile) -+{ -+ int i_ret = -1; -+ -+ BTIF_INFO_FUNC("pid:%d\n", current->pid); -+ i_ret = 0; -+ return i_ret; -+} -+ -+static int btif_file_release(struct inode *pinode, struct file *pfile) -+{ -+ int i_ret = -1; -+ -+ BTIF_INFO_FUNC("pid:%d\n", current->pid); -+ i_ret = 0; -+ return i_ret; -+} -+ -+static ssize_t btif_file_read(struct file *pfile, -+ char __user *buf, size_t count, loff_t *f_ops) -+{ -+ int i_ret = 0; -+ int rd_len = 0; -+ -+ BTIF_INFO_FUNC("++\n"); -+ down(&rd_mtx); -+ rd_len = btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); -+ while (rd_len == 0) { -+ if (pfile->f_flags & O_NONBLOCK) -+ break; -+ -+ wait_event(btif_wq, rx_notify_flag != 0); -+ rx_notify_flag = 0; -+ rd_len = -+ btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, -+ sizeof(rd_buf)); -+ } -+ -+ if (rd_len == 0) -+ i_ret = 0; -+ else if ((rd_len > 0) && (copy_to_user(buf, rd_buf, rd_len) == 0)) -+ i_ret = rd_len; -+ else -+ i_ret = -EFAULT; -+ -+ up(&rd_mtx); -+ BTIF_INFO_FUNC("--, i_ret:%d\n", i_ret); -+ return i_ret; -+} -+ -+ssize_t btif_file_write(struct file *filp, -+ const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ int i_ret = 0; -+ int copy_size = 0; -+ -+ copy_size = count > sizeof(wr_buf) ? sizeof(wr_buf) : count; -+ -+ BTIF_INFO_FUNC("++\n"); -+ down(&wr_mtx); -+ if (copy_from_user(&wr_buf[0], &buf[0], copy_size)) -+ i_ret = -EFAULT; -+ else -+ i_ret = btif_send_data(&g_btif[0], wr_buf, copy_size); -+ -+ up(&wr_mtx); -+ BTIF_INFO_FUNC("--, i_ret:%d\n", i_ret); -+ -+ return i_ret; -+} -+#ifdef CONFIG_COMPAT -+long btif_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ long ret; -+ -+ BTIF_INFO_FUNC("cmd[0x%x]\n", cmd); -+ ret = btif_unlocked_ioctl(filp, cmd, arg); -+ return ret; -+} -+#endif -+long btif_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+#define BTIF_IOC_MAGIC 0xb0 -+#define BTIF_IOCTL_OPEN _IOW(BTIF_IOC_MAGIC, 1, int) -+#define BTIF_IOCTL_CLOSE _IOW(BTIF_IOC_MAGIC, 2, int) -+#define BTIF_IOCTL_LPBK_CTRL _IOWR(BTIF_IOC_MAGIC, 3, int) -+#define BTIF_IOCTL_LOG_FUNC_CTRL _IOWR(BTIF_IOC_MAGIC, 4, int) -+#define BTIF_IOCTL_RT_LOG_CTRL _IOWR(BTIF_IOC_MAGIC, 5, int) -+#define BTIF_IOCTL_LOG_DUMP _IOWR(BTIF_IOC_MAGIC, 6, int) -+#define BTIF_IOCTL_REG_DUMP _IOWR(BTIF_IOC_MAGIC, 7, int) -+#define BTIF_IOCTL_DMA_CTRL _IOWR(BTIF_IOC_MAGIC, 8, int) -+ -+ long ret = 0; -+/* unsigned char p_buf[NAME_MAX + 1]; */ -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ BTIF_INFO_FUNC("++\n"); -+ BTIF_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg); -+ -+ switch (cmd) { -+ case BTIF_IOCTL_OPEN: -+ ret = _btif_file_open(); -+ break; -+ case BTIF_IOCTL_CLOSE: -+ ret = _btif_file_close(); -+ break; -+ case BTIF_IOCTL_LPBK_CTRL: -+ ret = btif_lpbk_ctrl(p_btif, arg == 0 ? 0 : 1); -+ break; -+ case BTIF_IOCTL_LOG_FUNC_CTRL: -+ if (arg == 0) { -+ ret += btif_log_buf_disable(&p_btif->tx_log); -+ ret += btif_log_buf_disable(&p_btif->rx_log); -+ } else { -+ ret += btif_log_buf_enable(&p_btif->tx_log); -+ ret += btif_log_buf_enable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_IOCTL_RT_LOG_CTRL: -+ if (arg == 0) { -+ ret += btif_log_output_disable(&p_btif->tx_log); -+ ret += btif_log_output_disable(&p_btif->rx_log); -+ } else { -+ ret += btif_log_output_enable(&p_btif->tx_log); -+ ret += btif_log_output_enable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_IOCTL_LOG_DUMP: -+ -+ ret += btif_log_buf_dmp_out(&p_btif->tx_log); -+ ret += btif_log_buf_dmp_out(&p_btif->rx_log); -+ break; -+ case BTIF_IOCTL_REG_DUMP: -+ ret += btif_dump_reg(p_btif); -+ break; -+ case BTIF_IOCTL_DMA_CTRL: -+ if (arg == 0) { -+ ret += btif_tx_dma_mode_set(0); -+ ret += btif_rx_dma_mode_set(0); -+ } else { -+ ret += btif_tx_dma_mode_set(1); -+ ret += btif_rx_dma_mode_set(1); -+ } -+ break; -+ default: -+ BTIF_INFO_FUNC("unknown cmd(%d)\n", cmd); -+ ret = -2; -+ break; -+ } -+ BTIF_INFO_FUNC("--\n"); -+ return ret; -+} -+ -+#endif -+ -+/*-----------device property----------------*/ -+//static ssize_t driver_flag_read(struct device_driver *drv, char *buf) -+static ssize_t flag_show(struct device_driver *drv, char *buf) -+{ -+ return sprintf(buf, "btif driver debug level:%d\n", mtk_btif_dbg_lvl); -+} -+ -+//static ssize_t driver_flag_set(struct device_driver *drv, -+static ssize_t flag_store(struct device_driver *drv, -+ const char *buffer, size_t count) -+{ -+ char buf[256]; -+ char *p_buf; -+ unsigned long len = count; -+ long x = 0; -+ long y = 0; -+ long z = 0; -+ int result = 0; -+ char *p_token = NULL; -+ char *p_delimiter = " \t"; -+ -+ BTIF_INFO_FUNC("buffer = %s, count = %zd\n", buffer, count); -+ if (len >= sizeof(buf)) { -+ BTIF_ERR_FUNC("input handling fail!\n"); -+ len = sizeof(buf) - 1; -+ return -1; -+ } -+ -+ memcpy(buf, buffer, sizeof(buf)); -+ p_buf = buf; -+ -+ p_token = strsep(&p_buf, p_delimiter); -+ if (p_token != NULL) { -+ result = kstrtol(p_token, 16, &x); -+ BTIF_INFO_FUNC("x = 0x%08x\n\r", x); -+ } else -+ x = 0; -+/* x = (NULL != p_token) ? kstrtol(p_token, 16, NULL) : 0;*/ -+ -+ p_token = strsep(&p_buf, "\t\n "); -+ if (p_token != NULL) { -+ result = kstrtol(p_token, 16, &y); -+ BTIF_INFO_FUNC("y = 0x%08x\n\r", y); -+ } else -+ y = 0; -+ -+ p_token = strsep(&p_buf, "\t\n "); -+ if (p_token != NULL) -+ result = kstrtol(p_token, 16, &z); -+ else -+ z = 0; -+ -+ BTIF_INFO_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); -+ -+ switch (x) { -+ case 1: -+ mtk_btif_exp_open_test(); -+ break; -+ case 2: -+ mtk_btif_exp_close_test(); -+ break; -+ case 3: -+ mtk_btif_exp_write_test(); -+ break; -+ case 4: -+ mtk_btif_exp_enter_dpidle_test(); -+ break; -+ case 5: -+ mtk_btif_exp_exit_dpidle_test(); -+ break; -+ case 6: -+ mtk_btif_exp_suspend_test(); -+ break; -+ case 7: -+ mtk_btif_exp_resume_test(); -+ break; -+ case 8: -+ if (y > BTIF_LOG_LOUD) -+ mtk_btif_dbg_lvl = BTIF_LOG_LOUD; -+ else if (y < BTIF_LOG_ERR) -+ mtk_btif_dbg_lvl = BTIF_LOG_WARN; -+ else -+ mtk_btif_dbg_lvl = y; -+ BTIF_ERR_FUNC("mtk_btif_dbg_lvl set to %d\n", mtk_btif_dbg_lvl); -+ break; -+ case 9: -+ mtk_btif_exp_open_test(); -+ mtk_btif_exp_write_test(); -+ mtk_btif_exp_close_test(); -+ break; -+ case 0xa: -+ mtk_btif_exp_log_debug_test(y); -+ break; -+ case 0xb: -+ btif_tx_dma_mode_set(1); -+ btif_rx_dma_mode_set(1); -+ break; -+ case 0xc: -+ btif_tx_dma_mode_set(0); -+ btif_rx_dma_mode_set(0); -+ break; -+ case 0xd: -+ mtk_btif_exp_restore_noirq_test(); -+ break; -+ case 0xe: -+ btif_wakeup_consys_no_id(); -+ break; -+ case 0xf: -+ mtk_btif_exp_clock_ctrl(y); -+ break; -+ case 0x10: -+ y = y > G_MAX_PKG_LEN ? G_MAX_PKG_LEN : y; -+ y = y < 1024 ? 1024 : y; -+ BTIF_INFO_FUNC("g_max_pkg_len is set to %d\n", y); -+ g_max_pkg_len = y; -+ break; -+ case 0x11: -+ y = y > BTIF_RX_BUFFER_SIZE ? BTIF_RX_BUFFER_SIZE : y; -+ y = y < 1024 ? 1024 : y; -+ BTIF_INFO_FUNC("g_max_pding_data_size is set to %d\n", y); -+ g_max_pding_data_size = y; -+ break; -+ default: -+ mtk_btif_exp_open_test(); -+ mtk_btif_exp_write_stress_test(3030, 1); -+ mtk_btif_exp_close_test(); -+ BTIF_WARN_FUNC("not supported.\n"); -+ break; -+ } -+ -+ return count; -+} -+ -+//FWU: driver_ATTR dropped in 4.14 -+//static DRIVER_ATTR(flag, S_IRUGO | S_IWUSR, driver_flag_read, driver_flag_set); -+static DRIVER_ATTR_RW(flag); -+ -+/*-----------End of platform bus related operation APIs------------*/ -+ -+/*-----------------------platform driver ----------------*/ -+ -+int _btif_irq_reg(P_MTK_BTIF_IRQ_STR p_irq, -+ mtk_btif_irq_handler irq_handler, void *data) -+{ -+ int i_ret = -1; -+ unsigned int irq_id; -+ unsigned int flag; -+ -+ if ((p_irq == NULL) || (irq_handler == NULL)) -+ return E_BTIF_INVAL_PARAM; -+ -+ if (!(p_irq->is_irq_sup)) { -+ BTIF_WARN_FUNC("%s is not supported\n", p_irq->name); -+ return 0; -+ } -+ -+ irq_id = p_irq->irq_id; -+ -+#ifdef CONFIG_OF -+ flag = p_irq->irq_flags; -+#else -+ switch (p_irq->sens_type) { -+ case IRQ_SENS_EDGE: -+ if (p_irq->edge_type == IRQ_EDGE_FALL) -+ flag = IRQF_TRIGGER_FALLING; -+ else if (p_irq->edge_type == IRQ_EDGE_RAISE) -+ flag = IRQF_TRIGGER_RISING; -+ else if (p_irq->edge_type == IRQ_EDGE_BOTH) -+ flag = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; -+ else -+ /*make this as default type */ -+ flag = IRQF_TRIGGER_FALLING; -+ break; -+ case IRQ_SENS_LVL: -+ if (p_irq->lvl_type == IRQ_LVL_LOW) -+ flag = IRQF_TRIGGER_LOW; -+ else if (p_irq->lvl_type == IRQ_LVL_HIGH) -+ flag = IRQF_TRIGGER_HIGH; -+ else -+ /*make this as default type */ -+ flag = IRQF_TRIGGER_LOW; -+ break; -+ default: -+ /*make this as default type */ -+ flag = IRQF_TRIGGER_LOW; -+ break; -+ } -+#endif -+ -+ p_irq->p_irq_handler = irq_handler; -+ i_ret = request_irq(irq_id, -+ (irq_handler_t) irq_handler, -+ flag, p_irq->name, data); -+ if (i_ret) -+ return i_ret; -+ -+ p_irq->reg_flag = true; -+ return 0; -+} -+ -+int _btif_irq_free(P_MTK_BTIF_IRQ_STR p_irq, void *data) -+{ -+ int i_ret = 0; -+ unsigned int eint_num = p_irq->irq_id; -+ -+ if ((p_irq->is_irq_sup) && (p_irq->reg_flag)) { -+ _btif_irq_ctrl(p_irq, false); -+ free_irq(eint_num, data); -+ p_irq->reg_flag = false; -+ } -+/*do nothing for this operation*/ -+ return i_ret; -+} -+ -+int _btif_irq_ctrl(P_MTK_BTIF_IRQ_STR p_irq, bool en) -+{ -+ unsigned int eint_num = p_irq->irq_id; -+ -+ if (en) -+ enable_irq(eint_num); -+ else -+ disable_irq_nosync(eint_num); -+ -+ return 0; -+} -+ -+int _btif_irq_ctrl_sync(P_MTK_BTIF_IRQ_STR p_irq, bool en) -+{ -+ unsigned int eint_num = p_irq->irq_id; -+ -+ if (en) -+ enable_irq(eint_num); -+ else -+ disable_irq(eint_num); -+ -+ return 0; -+} -+ -+ -+irqreturn_t btif_irq_handler(int irq, void *data) -+{ -+/*search BTIF? just use index 0*/ -+/*Chaozhong: do we need lock here?*/ -+ -+ p_mtk_btif p_btif = (p_mtk_btif) data; /*&(g_btif[index]); */ -+ -+ BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data); -+ -+ _btif_irq_ctrl(p_btif->p_btif_info->p_irq, false); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); -+#endif -+ -+ hal_btif_irq_handler(p_btif->p_btif_info, NULL, 0); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); -+#endif -+ -+ _btif_irq_ctrl(p_btif->p_btif_info->p_irq, true); -+ _btif_rx_btm_sched(p_btif); -+ -+ BTIF_DBG_FUNC("--\n"); -+ return IRQ_HANDLED; -+} -+ -+irqreturn_t btif_tx_dma_irq_handler(int irq, void *data) -+{ -+/*search BTIF? just use index 0*/ -+ -+ p_mtk_btif p_btif = (p_mtk_btif) data; /*&(g_btif[index]); */ -+ p_mtk_btif_dma p_tx_dma = p_btif->p_tx_dma; -+ P_MTK_DMA_INFO_STR p_dma_info = p_tx_dma->p_dma_info; -+ -+ BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data); -+ _btif_irq_ctrl(p_dma_info->p_irq, false); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE); -+#endif -+ -+ hal_tx_dma_irq_handler(p_dma_info); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); -+#endif -+ _btif_irq_ctrl(p_dma_info->p_irq, true); -+ BTIF_DBG_FUNC("--\n"); -+ return IRQ_HANDLED; -+} -+ -+irqreturn_t btif_rx_dma_irq_handler(int irq, void *data) -+{ -+/*search BTIF? just use index 0*/ -+ -+ p_mtk_btif p_btif = (p_mtk_btif) data; /*&(g_btif[index]); */ -+ p_mtk_btif_dma p_rx_dma = p_btif->p_rx_dma; -+ P_MTK_DMA_INFO_STR p_rx_dma_info = p_rx_dma->p_dma_info; -+ -+ BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data); -+ -+ _btif_irq_ctrl(p_rx_dma_info->p_irq, false); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); -+ hal_btif_dma_clk_ctrl(p_rx_dma_info, CLK_OUT_ENABLE); -+#endif -+ -+ hal_rx_dma_irq_handler(p_rx_dma_info, NULL, 0); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_dma_clk_ctrl(p_rx_dma_info, CLK_OUT_DISABLE); -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); -+#endif -+ -+ _btif_irq_ctrl(p_rx_dma_info->p_irq, true); -+ -+ _btif_rx_btm_sched(p_btif); -+ -+ BTIF_DBG_FUNC("--\n"); -+ -+ return IRQ_HANDLED; -+} -+ -+unsigned int btif_dma_rx_data_receiver(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, -+ unsigned int buf_len) -+{ -+ unsigned int index = 0; -+ p_mtk_btif p_btif = &(g_btif[index]); -+ -+#if 0 -+ _btif_dump_memory("", p_buf, buf_len); -+#endif -+ -+ btif_bbs_write(&(p_btif->btif_buf), p_buf, buf_len); -+/*save DMA Rx packet here*/ -+ if (buf_len > 0) -+ btif_log_buf_dmp_in(&p_btif->rx_log, p_buf, buf_len); -+ -+ return 0; -+} -+ -+unsigned int btif_pio_rx_data_receiver(P_MTK_BTIF_INFO_STR p_btif_info, -+ unsigned char *p_buf, -+ unsigned int buf_len) -+{ -+ unsigned int index = 0; -+ p_mtk_btif p_btif = &(g_btif[index]); -+ -+#if 0 -+ _btif_dump_memory("", p_buf, buf_len); -+#endif -+ btif_bbs_write(&(p_btif->btif_buf), p_buf, buf_len); -+ -+/*save PIO Rx packet here*/ -+ if (buf_len > 0) -+ btif_log_buf_dmp_in(&p_btif->rx_log, p_buf, buf_len); -+ -+ return 0; -+} -+ -+bool btif_parser_wmt_evt(p_mtk_btif p_btif, -+ const char *sub_str, -+ unsigned int str_len) -+{ -+ unsigned int data_cnt = 0; -+ unsigned int copy_cnt = 0; -+ char *local_buf = NULL; -+ bool b_ret = false; -+ p_btif_buf_str p_bbs = &(p_btif->btif_buf); -+ unsigned int wr_idx = p_bbs->wr_idx; -+ unsigned int rd_idx = p_bbs->rd_idx; -+ -+ data_cnt = copy_cnt = BBS_COUNT(p_bbs); -+ -+ if (data_cnt < str_len) { -+ BTIF_WARN_FUNC("there is not enough data for parser,need(%d),have(%d)\n", str_len, data_cnt); -+ return false; -+ } -+ BTIF_INFO_FUNC("data count in bbs buffer:%d,wr_idx(%d),rd_idx(%d)\n", data_cnt, wr_idx, rd_idx); -+ local_buf = vmalloc((data_cnt + 3) & ~0x3UL); -+ if (!local_buf) { -+ BTIF_WARN_FUNC("vmalloc memory fail\n"); -+ return false; -+ } -+ -+ if (wr_idx >= rd_idx) { -+ memcpy(local_buf, BBS_PTR(p_bbs, rd_idx), copy_cnt); -+ } else { -+ unsigned int tail_len = BBS_SIZE(p_bbs) - rd_idx; -+ -+ BTIF_INFO_FUNC("tail_Len(%d)\n", tail_len); -+ memcpy(local_buf, BBS_PTR(p_bbs, rd_idx), tail_len); -+ memcpy(local_buf + tail_len, BBS_PTR(p_bbs, 0), copy_cnt - tail_len); -+ } -+ -+ do { -+ int i = 0; -+ int j = 0; -+ int k = 0; -+ int d = 0; -+ -+ BTIF_INFO_FUNC("sub_str_len:%d\n", str_len); -+ for (i = 0; i < copy_cnt; i++) { -+ BTIF_DBG_FUNC("i:%d\n", i); -+ k = i; -+ while (1) { -+ if ((j >= str_len) || (k >= copy_cnt) || (sub_str[j++] != local_buf[k++])) -+ break; -+ } -+ -+ if (j == str_len) { -+ for (d = i; d < (str_len + i); d++) -+ BTIF_INFO_FUNC("0x%2x", local_buf[d]); -+ BTIF_INFO_FUNC("find sub str index:%d\n", i); -+ b_ret = true; -+ break; -+ } -+ if (j < str_len) -+ j = 0; -+ } -+ -+ } while (0); -+ -+ vfree(local_buf); -+ return b_ret; -+} -+int _btif_controller_tx_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif->tx_mode == BTIF_MODE_DMA) { -+ i_ret = _btif_tx_dma_setup(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_tx_dma_setup failed,i_ret(%d),", -+ "set tx to PIO mode\n", i_ret); -+ i_ret = _btif_tx_pio_setup(p_btif); -+ } -+ } else -+/*enable Tx PIO mode*/ -+ i_ret = _btif_tx_pio_setup(p_btif); -+ -+ return i_ret; -+} -+ -+int _btif_controller_tx_free(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif->tx_mode == BTIF_MODE_DMA) { -+ i_ret = _btif_tx_dma_free(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_tx_dma_free failed, i_ret(%d)\n", -+ i_ret); -+ } -+ } else { -+/*do nothing for Tx PIO mode*/ -+ } -+ return i_ret; -+} -+ -+int _btif_controller_rx_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif->rx_mode == BTIF_MODE_DMA) { -+ i_ret = _btif_rx_dma_setup(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_tx_dma_setup failed, i_ret(%d),", -+ "set tx to PIO mode\n", i_ret); -+ i_ret = _btif_rx_pio_setup(p_btif); -+ } -+ } else { -+/*enable Tx PIO mode*/ -+ i_ret = _btif_rx_pio_setup(p_btif); -+ } -+ return i_ret; -+} -+ -+int _btif_controller_rx_free(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif->rx_mode == BTIF_MODE_DMA) { -+ i_ret = _btif_rx_dma_free(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_rx_dma_free failed, i_ret(%d)\n", -+ i_ret); -+ } -+ } else { -+/*do nothing for Rx PIO mode*/ -+ } -+ return i_ret; -+} -+ -+int _btif_tx_pio_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ -+/*set Tx to PIO mode*/ -+ p_btif->tx_mode = BTIF_MODE_PIO; -+/*enable Tx PIO mode*/ -+ i_ret = hal_btif_tx_mode_ctrl(p_btif_info, BTIF_MODE_PIO); -+ return i_ret; -+} -+ -+int _btif_rx_pio_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ P_MTK_BTIF_IRQ_STR p_btif_irq = p_btif_info->p_irq; -+ -+ p_btif->rx_mode = BTIF_MODE_PIO; -+/*Enable Rx IRQ*/ -+ _btif_irq_ctrl(p_btif_irq, true); -+/*enable Rx PIO mode*/ -+ i_ret = hal_btif_rx_mode_ctrl(p_btif_info, BTIF_MODE_PIO); -+ return i_ret; -+} -+ -+int _btif_rx_dma_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ P_MTK_BTIF_INFO_STR p_btif_info = NULL; -+ P_MTK_BTIF_IRQ_STR p_btif_irq = NULL; -+ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_rx_dma->p_dma_info; -+ -+ p_btif_info = p_btif->p_btif_info; -+ p_btif_irq = p_dma_info->p_irq; -+ -+/*vFIFO reset*/ -+ hal_btif_vfifo_reset(p_dma_info); -+ -+ i_ret = hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE); -+ if (i_ret) { -+ BTIF_ERR_FUNC("hal_btif_dma_clk_ctrl failed, i_ret(%d),", -+ "set rx to pio mode\n", i_ret); -+/*DMA control failed set Rx to PIO mode*/ -+ return _btif_rx_pio_setup(p_btif); -+ } -+/*hardware init*/ -+ hal_btif_dma_hw_init(p_dma_info); -+ -+ hal_btif_dma_rx_cb_reg(p_dma_info, -+ (dma_rx_buf_write) btif_dma_rx_data_receiver); -+ -+/*DMA controller enable*/ -+ i_ret = hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE); -+ if (i_ret) { -+ BTIF_ERR_FUNC("hal_btif_dma_ctrl failed, i_ret(%d),", -+ "set rx to pio mode\n", i_ret); -+ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); -+/*DMA control failed set Rx to PIO mode*/ -+ i_ret = _btif_rx_pio_setup(p_btif); -+ } else { -+/*enable Rx DMA mode*/ -+ hal_btif_rx_mode_ctrl(p_btif_info, BTIF_MODE_DMA); -+ -+/*DMA Rx IRQ register*/ -+ _btif_irq_reg(p_btif_irq, btif_rx_dma_irq_handler, p_btif); -+#if 0 -+/*Enable DMA Rx IRQ*/ -+ _btif_irq_ctrl(p_btif_irq, true); -+#endif -+ BTIF_DBG_FUNC("succeed\n"); -+ } -+ return i_ret; -+} -+ -+int _btif_rx_dma_free(p_mtk_btif p_btif) -+{ -+ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_rx_dma->p_dma_info; -+ P_MTK_BTIF_IRQ_STR p_irq = p_btif->p_rx_dma->p_dma_info->p_irq; -+ -+ hal_btif_dma_rx_cb_reg(p_dma_info, (dma_rx_buf_write) NULL); -+ _btif_irq_free(p_irq, p_btif); -+/*disable BTIF Rx DMA channel*/ -+ hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_DISABLE); -+/*disable clock output*/ -+ return hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); -+} -+ -+int _btif_tx_dma_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info; -+ P_MTK_BTIF_IRQ_STR p_btif_irq = p_dma_info->p_irq; -+ -+/*vFIFO reset*/ -+ hal_btif_vfifo_reset(p_dma_info); -+ -+ i_ret = hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE); -+ if (i_ret) { -+ BTIF_ERR_FUNC("hal_btif_dma_clk_ctrl failed, i_ret(%d)\n", -+ i_ret); -+ return i_ret; -+ } -+/*DMA controller setup*/ -+ hal_btif_dma_hw_init(p_dma_info); -+ -+/*DMA HW Enable*/ -+ i_ret = hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE); -+ if (i_ret) { -+ BTIF_ERR_FUNC("hal_btif_dma_ctrl failed, i_ret(%d),", -+ "set tx to pio mode\n", i_ret); -+ -+#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) -+ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); -+#endif -+ -+ _btif_tx_pio_setup(p_btif); -+ } else { -+ hal_btif_tx_mode_ctrl(p_btif_info, BTIF_MODE_DMA); -+/*DMA Tx IRQ register*/ -+ _btif_irq_reg(p_btif_irq, btif_tx_dma_irq_handler, p_btif); -+#if 0 -+/*disable DMA Tx IRQ*/ -+ _btif_irq_ctrl(p_btif_irq, false); -+#endif -+ -+ BTIF_DBG_FUNC("succeed\n"); -+ } -+ return i_ret; -+} -+ -+int _btif_tx_dma_free(p_mtk_btif p_btif) -+{ -+ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info; -+ P_MTK_BTIF_IRQ_STR p_irq = p_btif->p_tx_dma->p_dma_info->p_irq; -+ -+ _btif_irq_free(p_irq, p_btif); -+/*disable BTIF Tx DMA channel*/ -+ hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_DISABLE); -+/*disable clock output*/ -+ return hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); -+} -+ -+int btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag) -+{ -+ int i_ret = -1; -+ -+/*hold state mechine lock*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+#if 0 -+ state = _btif_state_get(p_btif); -+ if (p_btif->enable && B_S_ON == state) -+ i_ret = _btif_lpbk_ctrl(p_btif, flag); -+ else -+ i_ret = E_BTIF_INVAL_STATE; -+#endif -+ i_ret = _btif_exit_dpidle(p_btif); -+ if (i_ret == 0) -+ i_ret = _btif_lpbk_ctrl(p_btif, flag); -+ else -+ i_ret = E_BTIF_INVAL_STATE; -+ -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+} -+ -+int _btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag) -+{ -+ int i_ret = -1; -+ -+ if (flag) { -+ i_ret = hal_btif_loopback_ctrl(p_btif->p_btif_info, true); -+ BTIF_DBG_FUNC("loopback function enabled\n"); -+ } else { -+ i_ret = hal_btif_loopback_ctrl(p_btif->p_btif_info, false); -+ BTIF_DBG_FUNC("loopback function disabled\n"); -+ } -+ if (i_ret == 0) -+ p_btif->lpbk_flag = flag; -+ -+ return i_ret; -+} -+ -+int btif_clock_ctrl(p_mtk_btif p_btif, int en) -+{ -+ int i_ret = 0; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ ENUM_CLOCK_CTRL ctrl_flag = en == 0 ? CLK_OUT_DISABLE : CLK_OUT_ENABLE; -+ -+ i_ret = hal_btif_clk_ctrl(p_btif_info, ctrl_flag); -+ -+ if (p_btif->rx_mode == BTIF_MODE_DMA) -+ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info, ctrl_flag); -+ -+ if (p_btif->tx_mode == BTIF_MODE_DMA) -+ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info, ctrl_flag); -+ -+ return i_ret; -+} -+ -+int _btif_controller_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ P_MTK_BTIF_IRQ_STR p_btif_irq = p_btif_info->p_irq; -+ -+/*BTIF rx buffer init*/ -+/* memset(p_btif->rx_buf, 0, BTIF_RX_BUFFER_SIZE); */ -+ BBS_INIT(&(p_btif->btif_buf)); -+/************************************************/ -+ hal_btif_rx_cb_reg(p_btif_info, -+ (btif_rx_buf_write) btif_pio_rx_data_receiver); -+ -+ i_ret = hal_btif_clk_ctrl(p_btif_info, CLK_OUT_ENABLE); -+ if (i_ret) { -+ BTIF_ERR_FUNC("hal_btif_clk_ctrl failed, i_ret(%d)\n", i_ret); -+ return i_ret; -+ } -+/*BTIF controller init*/ -+ i_ret = hal_btif_hw_init(p_btif_info); -+ if (i_ret) { -+ hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE); -+ BTIF_ERR_FUNC("hal_btif_hw_init failed, i_ret(%d)\n", i_ret); -+ return i_ret; -+ } -+ _btif_lpbk_ctrl(p_btif, p_btif->lpbk_flag); -+/*BTIF IRQ register*/ -+ i_ret = _btif_irq_reg(p_btif_irq, btif_irq_handler, p_btif); -+ if (i_ret) { -+ hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE); -+ -+ BTIF_ERR_FUNC("_btif_irq_reg failed, i_ret(%d)\n", i_ret); -+ return i_ret; -+ } -+ -+/*disable IRQ*/ -+ _btif_irq_ctrl(p_btif_irq, false); -+ i_ret = 0; -+ BTIF_DBG_FUNC("succeed\n"); -+ return i_ret; -+} -+ -+int _btif_controller_free(p_mtk_btif p_btif) -+{ -+/*No need to set BTIF to PIO mode, only enable BTIF CG*/ -+ hal_btif_rx_cb_reg(p_btif->p_btif_info, (btif_rx_buf_write) NULL); -+ _btif_irq_free(p_btif->p_btif_info->p_irq, p_btif); -+ return hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); -+} -+ -+int _btif_init(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+ i_ret = _btif_controller_setup(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_controller_init failed, i_ret(%d)\n", -+ i_ret); -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+ } -+ -+ i_ret = _btif_controller_tx_setup(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_controller_tx_setup failed, i_ret(%d)\n", -+ i_ret); -+ _btif_controller_free(p_btif); -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+ } -+ -+ i_ret = _btif_controller_rx_setup(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_controller_tx_setup failed, i_ret(%d)\n", -+ i_ret); -+ _btif_controller_tx_free(p_btif); -+ _btif_controller_free(p_btif); -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+ } -+ return i_ret; -+} -+ -+int btif_open(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif->enable) -+ return E_BTIF_ALREADY_OPEN; -+ -+/*hold state mechine lock*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+/*disable deepidle*/ -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_DISABLE); -+ -+ i_ret = _btif_init(p_btif); -+ if (i_ret == 0) { -+ /*set BTIF's enable flag*/ -+ p_btif->enable = true; -+ _btif_state_set(p_btif, B_S_ON); -+ } else { -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); -+ } -+ btif_log_buf_reset(&p_btif->tx_log); -+ btif_log_buf_reset(&p_btif->rx_log); -+ -+ BTIF_STATE_RELEASE(p_btif); -+ -+ BTIF_DBG_FUNC("BTIF's Tx Mode:%d, Rx Mode(%d)\n", -+ p_btif->tx_mode, p_btif->rx_mode); -+ return i_ret; -+} -+ -+int btif_close(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+ if (!(p_btif->enable)) -+ return E_BTIF_NOT_OPEN; -+ -+/*hold state mechine lock*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+/*always set state back to B_S_ON before do close operation*/ -+ _btif_exit_dpidle(p_btif); -+/*set BTIF's state to disable state*/ -+ p_btif->enable = false; -+ -+ _btif_controller_free(p_btif); -+ _btif_controller_tx_free(p_btif); -+ _btif_controller_rx_free(p_btif); -+ -+/*reset BTIF's rx_cb function*/ -+ p_btif->rx_cb = NULL; -+ p_btif->rx_notify = NULL; -+ p_btif->lpbk_flag = false; -+ -+/*set state mechine to B_S_OFF*/ -+ _btif_state_set(p_btif, B_S_OFF); -+ -+ btif_log_buf_disable(&p_btif->tx_log); -+ btif_log_buf_disable(&p_btif->rx_log); -+ -+ BTIF_STATE_RELEASE(p_btif); -+ -+ return i_ret; -+} -+ -+int _btif_exit_dpidle(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ ENUM_BTIF_STATE state = B_S_MAX; -+ -+ state = _btif_state_get(p_btif); -+ switch (state) { -+ case B_S_DPIDLE: -+ i_ret = _btif_exit_dpidle_from_dpidle(p_btif); -+ break; -+ case B_S_SUSPEND: -+/*in suspend state, need to do reinit of btif*/ -+ i_ret = _btif_exit_dpidle_from_sus(p_btif); -+ break; -+ case B_S_OFF: -+ i_ret = _btif_init(p_btif); -+ break; -+ case B_S_ON: -+ i_ret = 0; /* for btif_close case */ -+ break; -+ default: -+ i_ret = E_BTIF_INVAL_PARAM; -+ BTIF_INFO_FUNC("invalid state change:%d->\n", state, B_S_ON); -+ break; -+ } -+ -+ if (i_ret == 0) -+ i_ret = _btif_state_set(p_btif, B_S_ON); -+ return i_ret; -+} -+ -+int btif_exit_dpidle(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+/*hold state mechine lock*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ i_ret = _btif_exit_dpidle(p_btif); -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+} -+ -+int _btif_enter_dpidle(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ ENUM_BTIF_STATE state = B_S_MAX; -+ -+ state = _btif_state_get(p_btif); -+ if (state == B_S_ON) { -+ i_ret = _btif_enter_dpidle_from_on(p_btif); -+ } else if (state == B_S_SUSPEND) { -+ /*do reinit and enter deepidle*/ -+ i_ret = _btif_enter_dpidle_from_sus(p_btif); -+ } else if (state == B_S_DPIDLE) { -+ /*do nothing*/ -+ i_ret = 0; -+ } else { -+ BTIF_WARN_FUNC("operation is not allowed, current state:%d\n", -+ state); -+ i_ret = E_BTIF_INVAL_STATE; -+ } -+/*anyway, set to B_S_DPIDLE state*/ -+ if (i_ret == 0) -+ i_ret = _btif_state_set(p_btif, B_S_DPIDLE); -+ return i_ret; -+} -+ -+int btif_enter_dpidle(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+/*hold state mechine lock*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ i_ret = _btif_enter_dpidle(p_btif); -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+} -+ -+int _btif_exit_dpidle_from_dpidle(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+/*in dpidle state, only need to open related clock*/ -+ if (p_btif->tx_mode == BTIF_MODE_DMA) { -+ /*enable BTIF Tx DMA's clock*/ -+ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info, -+ CLK_OUT_ENABLE); -+ } -+ if (p_btif->rx_mode == BTIF_MODE_DMA) { -+ /*enable BTIF Rx DMA's clock*/ -+ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info, -+ CLK_OUT_ENABLE); -+ } -+/*enable BTIF's clock*/ -+ i_ret += hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); -+ -+ if (i_ret != 0) -+ BTIF_WARN_FUNC("failed, i_ret:%d\n", i_ret); -+ return i_ret; -+} -+ -+int _btif_exit_dpidle_from_sus(p_mtk_btif p_btif) -+{ -+/*in suspend state, need to do driver re-init*/ -+ -+ int i_ret = _btif_init(p_btif); -+ -+ return i_ret; -+} -+ -+int _btif_enter_dpidle_from_sus(p_mtk_btif p_btif) -+{ -+/*do driiver reinit*/ -+ int i_ret = _btif_init(p_btif); -+ -+ if (i_ret == 0) -+ i_ret = _btif_enter_dpidle_from_on(p_btif); -+ return i_ret; -+} -+ -+int _btif_enter_dpidle_from_on(p_mtk_btif p_btif) -+{ -+#define MAX_WAIT_TIME_MS 5000 -+/* -+ * this max wait time cannot exceed 12s, -+ * because dpm will monitor each device's -+ * resume/suspend process by start up a watch dog timer of 12s -+ * incase of one driver's suspend/resume process block other device's suspend/resume -+ */ -+ int i_ret = 0; -+ unsigned int retry = 0; -+ unsigned int wait_period = 1; -+ unsigned int max_retry = MAX_WAIT_TIME_MS / wait_period; -+ struct timeval timer_start; -+ struct timeval timer_now; -+ -+ do_gettimeofday(&timer_start); -+ -+ while ((!_btif_is_tx_complete(p_btif)) && (retry < max_retry)) { -+ do_gettimeofday(&timer_now); -+ if ((MAX_WAIT_TIME_MS/1000) <= (timer_now.tv_sec - timer_start.tv_sec)) { -+ BTIF_WARN_FUNC("max retry timer expired, timer_start.tv_sec:%d, timer_now.tv_sec:%d,", -+ "retry:%d\n", timer_start.tv_sec, timer_now.tv_sec, retry); -+ break; -+ } -+ msleep(wait_period); -+ retry++; -+ } -+ -+ if (retry < max_retry) { -+ if (p_btif->tx_mode == BTIF_MODE_DMA) { -+ /*disable BTIF Tx DMA's clock*/ -+ i_ret += -+ hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info, -+ CLK_OUT_DISABLE); -+ } -+ if (p_btif->rx_mode == BTIF_MODE_DMA) { -+ /*disable BTIF Rx DMA's clock*/ -+ i_ret += -+ hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info, -+ CLK_OUT_DISABLE); -+ } -+/*disable BTIF's clock*/ -+ i_ret += -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); -+ -+ if (i_ret) -+ BTIF_WARN_FUNC("failed, i_ret:%d\n", i_ret); -+ } else -+ i_ret = -1; -+ -+ return i_ret; -+} -+ -+int _btif_dpidle_notify_ctrl(p_mtk_btif p_btif, ENUM_BTIF_DPIDLE_CTRL en_flag) -+{ -+/*call WCP's API to control deepidle's enable/disable*/ -+ if (en_flag == BTIF_DPIDLE_DISABLE) -+ hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_DPIDLE_DIS); -+ else -+ hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_DPIDLE_EN); -+ -+ return 0; -+} -+ -+int btif_rx_cb_reg(p_mtk_btif p_btif, MTK_WCN_BTIF_RX_CB rx_cb) -+{ -+ if (p_btif->rx_cb) { -+ BTIF_WARN_FUNC -+ ("rx cb already exist, rewrite from (0x%p) to (0x%p)\n", -+ p_btif->rx_cb, rx_cb); -+ } -+ p_btif->rx_cb = rx_cb; -+ -+ return 0; -+} -+ -+int btif_raise_wak_signal(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); -+#endif -+ -+ i_ret = hal_btif_raise_wak_sig(p_btif_info); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE); -+#endif -+ return i_ret; -+} -+ -+bool _btif_is_tx_complete(p_mtk_btif p_btif) -+{ -+ bool b_ret = false; -+ ENUM_BTIF_MODE tx_mode = p_btif->tx_mode; -+ -+/* -+ * make sure BTIF tx finished in PIO mode -+ * make sure BTIF tx finished and DMA tx finished in DMA mode -+ */ -+ if (tx_mode == BTIF_MODE_DMA) { -+ b_ret = hal_dma_is_tx_complete(p_btif->p_tx_dma->p_dma_info); -+ if (b_ret == false) { -+ BTIF_DBG_FUNC("Tx DMA is not finished\n"); -+ return b_ret; -+ } -+ } -+ -+ b_ret = hal_btif_is_tx_complete(p_btif->p_btif_info); -+ if (b_ret == false) { -+ BTIF_DBG_FUNC("BTIF Tx is not finished\n"); -+ return b_ret; -+ } -+ b_ret = true; -+ return b_ret; -+} -+ -+/*--------------------------------Functions-------------------------------------------*/ -+ -+#if ENABLE_BTIF_TX_DMA -+static int _btif_vfifo_init(p_mtk_btif_dma p_dma) -+{ -+ P_DMA_VFIFO p_vfifo = NULL; -+ struct device *dev = NULL; -+ p_mtk_btif p_btif = NULL; -+ -+ if (p_dma == NULL) { -+ BTIF_ERR_FUNC("p_dma is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ p_btif = (p_mtk_btif)p_dma->p_btif; -+ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("invalid parameter: p_btif(0x%p)\n", p_btif); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ dev = (struct device *)p_btif->private_data; -+ if (dev == NULL) -+ BTIF_WARN_FUNC("Null dev pointer!!!!\n"); -+ -+ p_vfifo = p_dma->p_dma_info->p_vfifo; -+ if (p_vfifo->p_vir_addr != NULL) { -+ BTIF_ERR_FUNC -+ ("BTIF vFIFO memory already allocated, do nothing\n"); -+ return E_BTIF_BAD_POINTER; -+ } -+ -+/*vFIFO memory allocation*/ -+ p_vfifo->p_vir_addr = dma_zalloc_coherent(dev, -+ p_vfifo->vfifo_size, -+ &p_vfifo->phy_addr, GFP_DMA | GFP_DMA32); -+ if (p_vfifo->p_vir_addr == NULL) { -+ BTIF_ERR_FUNC("alloc vFIFO memory for BTIF failed\n"); -+ return E_BTIF_FAIL; -+ } -+ -+ if (sizeof(dma_addr_t) == sizeof(unsigned long long)) -+ BTIF_INFO_FUNC("alloc vFIFO for BTIF succeed in arch64,vir addr:0x%p,", -+ "phy addr:0x%llx\n", p_vfifo->p_vir_addr, p_vfifo->phy_addr); -+ else -+ BTIF_INFO_FUNC("alloc vFIFO for BTIF succeed in arch32,vir addr:0x%p,", -+ "phy addr:0x%08x\n", p_vfifo->p_vir_addr, p_vfifo->phy_addr); -+ -+ return 0; -+} -+#endif -+#if ENABLE_BTIF_TX_DMA -+static int _btif_vfifo_deinit(p_mtk_btif_dma p_dma) -+{ -+ P_DMA_VFIFO p_vfifo = NULL; -+ struct device *dev = NULL; -+ p_mtk_btif p_btif = NULL; -+ -+ if (p_dma == NULL) { -+ BTIF_ERR_FUNC("p_dma is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ -+ p_btif = (p_mtk_btif)p_dma->p_btif; -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("invalid parameter: p_btif(0x%p)\n", p_btif); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ dev = (struct device *)p_btif->private_data; -+ if (dev == NULL) -+ BTIF_WARN_FUNC("Null dev pointer!!!!\n"); -+ -+ p_vfifo = p_dma->p_dma_info->p_vfifo; -+ -+/*free DMA memory if allocated successfully before*/ -+ if (p_vfifo->p_vir_addr != NULL) { -+ dma_free_coherent(dev, -+ p_vfifo->vfifo_size, -+ p_vfifo->p_vir_addr, p_vfifo->phy_addr); -+ p_vfifo->p_vir_addr = NULL; -+ } -+ -+ return 0; -+} -+#endif -+ -+static int _btif_state_init(p_mtk_btif p_btif) -+{ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ p_btif->state = B_S_OFF; -+ mutex_init(&(p_btif->state_mtx)); -+ -+ return 0; -+} -+ -+static int _btif_state_hold(p_mtk_btif p_btif) -+{ -+ return mutex_lock_killable(&(p_btif->state_mtx)); -+} -+ -+static int _btif_state_set(p_mtk_btif p_btif, ENUM_BTIF_STATE state) -+{ -+/*chaozhong: To do: need to finished state mechine here*/ -+ int i_ret = 0; -+ int ori_state = p_btif->state; -+ -+ if (ori_state == state) { -+ BTIF_INFO_FUNC("already in %s state\n", g_state[state]); -+ return i_ret; -+ } -+ if ((state >= B_S_OFF) && (state < B_S_MAX)) { -+ BTIF_DBG_FUNC("%s->%s request\n", g_state[ori_state], -+ g_state[state]); -+ if (state == B_S_ON) -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_DISABLE); -+ switch (ori_state) { -+ case B_S_ON: -+/*B_S_ON can only be switched to B_S_OFF, B_S_SUSPEND and B_S_DPIDLE*/ -+/*B_S_ON->B_S_OFF : do nothing here*/ -+/* -+ * B_S_ON->B_S_DPLE : disable clock backup -+ * BTIF and DMA controller's register if necessary -+ */ -+ if (state == B_S_DPIDLE) { -+ /*clock controlled id done in _btif_enter_dpidle*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else if (state == B_S_OFF) { -+ /*clock controlled is done in btif_close*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else if (state == B_S_SUSPEND) { -+ /*clock controlled is done in btif_close*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else { -+ BTIF_ERR_FUNC("%s->%s is not allowed\n", -+ g_state[ori_state], -+ g_state[state]); -+ i_ret = E_BTIF_INVAL_STATE; -+ } -+ break; -+ case B_S_DPIDLE: -+/*B_S_DPIDLE can only be switched to B_S_ON and B_S_SUSPEND*/ -+/*B_S_DPIDLE-> B_S_ON: do nothing for this moment*/ -+/* -+ * B_S_DPIDLE-> B_S_SUSPEND: -+ * disable clock backup BTIF and DMA controller's register if necessary -+ */ -+ if (state == B_S_ON) { -+ /*clock controlled id done in _btif_exit_dpidle*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else if (state == B_S_SUSPEND) { -+ /*clock controlled is done in _btif_exit_dpidle*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else { -+ BTIF_ERR_FUNC("%s->%s is not allowed\n", -+ g_state[ori_state], -+ g_state[state]); -+ i_ret = E_BTIF_INVAL_STATE; -+ } -+ break; -+ -+ case B_S_SUSPEND: -+/*B_S_SUSPEND can be switched to B_S_IDLE and B_S_ON*/ -+/*reinit BTIF controller and DMA controller*/ -+ if (state == B_S_DPIDLE) { -+ /* -+ * system call resume API, do resume operation, -+ * change to deepidle state -+ */ -+ p_btif->state = state; -+ i_ret = 0; -+ } else if (state == B_S_ON) { -+ /* -+ * when stp want to send data before -+ * system do resume operation -+ */ -+ p_btif->state = state; -+ i_ret = 0; -+ } else { -+ BTIF_ERR_FUNC("%s->%s is not allowed\n", -+ g_state[ori_state], -+ g_state[state]); -+ i_ret = E_BTIF_INVAL_STATE; -+ } -+ break; -+ -+ case B_S_OFF:{ -+/*B_S_OFF can only be switched to B_S_ON*/ -+ if (state == B_S_ON) { -+ /*clock controlled is done in btif_open*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else { -+ BTIF_ERR_FUNC("%s->%s is not allowed\n", -+ g_state[ori_state], -+ g_state[state]); -+ i_ret = E_BTIF_INVAL_STATE; -+ } -+ } -+ break; -+ default: -+/*no this possibility*/ -+ BTIF_ERR_FUNC -+ ("state change request is not allowed, this should never happen\n"); -+ break; -+ } -+ -+ if (state != B_S_ON) -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); -+ -+ } else { -+ i_ret = E_BTIF_INVAL_PARAM; -+ BTIF_ERR_FUNC("invalid state:%d, do nothing\n", state); -+ } -+ return i_ret; -+} -+ -+static ENUM_BTIF_STATE _btif_state_get(p_mtk_btif p_btif) -+{ -+ return p_btif->state; -+} -+ -+static int _btif_state_release(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+ BTIF_MUTEX_UNLOCK(&(p_btif->state_mtx)); -+ return i_ret; -+} -+ -+static int _btif_state_deinit(p_mtk_btif p_btif) -+{ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ p_btif->state = B_S_OFF; -+ mutex_destroy(&(p_btif->state_mtx)); -+ -+ return 0; -+} -+ -+static int btif_rx_data_consummer(p_mtk_btif p_btif) -+{ -+ unsigned int length = 0; -+ unsigned char *p_buf = NULL; -+/*get BTIF rx buffer's information*/ -+ p_btif_buf_str p_bbs = &(p_btif->btif_buf); -+/* -+ * wr_idx of btif_buf may be modified in IRQ handler, -+ * in order not to be effected by case in which irq interrupt this operation, -+ * we record wr_idx here -+ */ -+ unsigned int wr_idx = p_bbs->wr_idx; -+ -+ length = BBS_COUNT_CUR(p_bbs, wr_idx); -+ -+/*make sure length of rx buffer data > 0*/ -+ do { -+ if (length > 0) { -+ /* -+ * check if rx_cb empty or not, if registered , -+ * call user's rx callback to handle these data -+ */ -+ if (p_btif->rx_cb) { -+ if (p_bbs->rd_idx <= wr_idx) { -+ p_buf = BBS_PTR(p_bbs, p_bbs->rd_idx); -+ /* p_buf = &(p_bbs->buf[p_bbs->rd_idx]); */ -+ /* length = BBS_COUNT(p_bbs); */ -+ length = (wr_idx >= (p_bbs)->rd_idx) ? -+ (wr_idx - (p_bbs)->rd_idx) : -+ BBS_SIZE(p_bbs) - -+ ((p_bbs)->rd_idx - wr_idx); -+ if (p_btif->rx_cb) -+ (*(p_btif->rx_cb)) (p_buf, length); -+ else -+ BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n"); -+ /*update rx data read index*/ -+ p_bbs->rd_idx = wr_idx; -+ } else { -+ unsigned int len_tail = -+ BBS_SIZE(p_bbs) - (p_bbs)->rd_idx; -+ /*p_buf = &(p_bbs->buf[p_bbs->->rd_idx]);*/ -+ p_buf = BBS_PTR(p_bbs, p_bbs->rd_idx); -+ if (p_btif->rx_cb) -+ (*(p_btif->rx_cb)) (p_buf, len_tail); -+ else -+ BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n"); -+ length = BBS_COUNT_CUR(p_bbs, wr_idx); -+ length -= len_tail; -+ /*p_buf = &(p_bbs->buf[0]);*/ -+ p_buf = BBS_PTR(p_bbs, 0); -+ if (p_btif->rx_cb) -+ (*(p_btif->rx_cb)) (p_buf, length); -+ else -+ BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n"); -+ /*update rx data read index*/ -+ p_bbs->rd_idx = wr_idx; -+ } -+ } else if (p_btif->rx_notify != NULL) { -+ (*p_btif->rx_notify) (); -+ } else { -+ BTIF_WARN_FUNC -+ ("p_btif:0x%p, both rx_notify and rx_cb are NULL\n", -+ p_btif); -+ break; -+ } -+ } else { -+ BTIF_DBG_FUNC("length:%d\n", length); -+ break; -+ } -+ wr_idx = p_bbs->wr_idx; -+ length = BBS_COUNT_CUR(p_bbs, wr_idx); -+ } while (1); -+ return length; -+} -+ -+#if BTIF_RXD_BE_BLOCKED_DETECT -+static int mtk_btif_rxd_be_blocked_by_timer(void) -+{ -+ int ret = 0; -+ int counter = 0; -+ unsigned int i; -+ struct timeval now; -+ int time_gap[MAX_BTIF_RXD_TIME_REC]; -+ -+ do_gettimeofday(&now); -+ -+ for (i = 0; i < MAX_BTIF_RXD_TIME_REC; i++) { -+ BTIF_INFO_FUNC("btif_rxd_time_stamp[%d]=%d.%d\n", i, -+ btif_rxd_time_stamp[i].tv_sec, btif_rxd_time_stamp[i].tv_usec); -+ if (now.tv_sec >= btif_rxd_time_stamp[i].tv_sec) { -+ time_gap[i] = now.tv_sec - btif_rxd_time_stamp[i].tv_sec; -+ time_gap[i] *= 1000000; /*second*/ -+ if (now.tv_usec >= btif_rxd_time_stamp[i].tv_usec) -+ time_gap[i] += now.tv_usec - btif_rxd_time_stamp[i].tv_usec; -+ else -+ time_gap[i] += 1000000 - now.tv_usec + btif_rxd_time_stamp[i].tv_usec; -+ -+ if (time_gap[i] > 1000000) -+ counter++; -+ BTIF_INFO_FUNC("time_gap[%d]=%d,counter:%d\n", i, time_gap[i], counter); -+ } else { -+ time_gap[i] = 0; -+ BTIF_ERR_FUNC("abnormal case now:%d < time_stamp[%d]:%d\n", now.tv_sec, -+ i, btif_rxd_time_stamp[i].tv_usec); -+ } -+ } -+ if (counter > (MAX_BTIF_RXD_TIME_REC - 2)) -+ ret = 1; -+ return ret; -+} -+static int mtk_btif_rxd_be_blocked_by_data(void) -+{ -+ unsigned int out_index = 0; -+ unsigned int in_index = 0; -+ unsigned int dump_size = 0; -+ unsigned int len = 0; -+ unsigned long flags; -+ unsigned int sync_pkt_n = 0; -+ P_BTIF_LOG_BUF_T p_log_buf = NULL; -+ P_BTIF_LOG_QUEUE_T p_log_que = NULL; -+ p_mtk_btif p_btif = &(g_btif[0]); -+ -+ p_log_que = &p_btif->rx_log; -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ in_index = p_log_que->in; -+ dump_size = p_log_que->size; -+ out_index = p_log_que->size >= -+ BTIF_LOG_ENTRY_NUM ? in_index : (BTIF_LOG_ENTRY_NUM - -+ p_log_que->size + -+ in_index) % BTIF_LOG_ENTRY_NUM; -+ if (dump_size != 0) { -+ while (dump_size--) { -+ p_log_buf = p_log_que->p_queue[0] + out_index; -+ len = p_log_buf->len; -+ if (len > BTIF_LOG_SZ) -+ len = BTIF_LOG_SZ; -+ if ((0x7f == *(p_log_buf->buffer)) && (0x7f == *(p_log_buf->buffer + 1))) { -+ sync_pkt_n++; -+ BTIF_INFO_FUNC("tx pkt_count:%d is sync pkt\n", out_index); -+ } -+ out_index++; -+ out_index %= BTIF_LOG_ENTRY_NUM; -+ } -+ } -+ if (sync_pkt_n == 0) -+ BTIF_ERR_FUNC("there is no sync pkt in BTIF buffer\n"); -+ else -+ BTIF_ERR_FUNC("there are %d sync pkt in BTIF buffer\n", sync_pkt_n); -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ return sync_pkt_n; -+} -+ -+int mtk_btif_rxd_be_blocked_flag_get(void) -+{ -+ int ret = 0; -+ int condition1 = 0, condition2 = 0; -+ -+ condition1 = mtk_btif_rxd_be_blocked_by_timer(); -+ condition2 = mtk_btif_rxd_be_blocked_by_data(); -+ if (condition1 && condition2) { -+ BTIF_ERR_FUNC("btif_rxd thread be blocked too long!\n"); -+ ret = 1; -+ } -+ return ret; -+} -+#endif -+static int btif_rx_thread(void *p_data) -+{ -+#if BTIF_RXD_BE_BLOCKED_DETECT -+ unsigned int i = 0; -+#endif -+ p_mtk_btif p_btif = (p_mtk_btif)p_data; -+ -+ -+ while (1) { -+ wait_for_completion_interruptible(&p_btif->rx_comp); -+ -+ if (kthread_should_stop()) { -+ BTIF_WARN_FUNC("btif rx thread stoping ...\n"); -+ break; -+ } -+#ifdef BTIF_RXD_BE_BLOCKED_DETECT -+ do_gettimeofday(&btif_rxd_time_stamp[i]); -+ i++; -+ if (i >= MAX_BTIF_RXD_TIME_REC) -+ i = 0; -+#endif -+ btif_rx_data_consummer(p_btif); -+ } -+ return 0; -+} -+ -+static void btif_rx_worker(struct work_struct *p_work) -+{ -+/*get mtk_btif's pointer*/ -+ p_mtk_btif p_btif = container_of(p_work, mtk_btif, rx_work); -+ -+ BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif); -+/*lock rx_mutex*/ -+ -+ if (mutex_lock_killable(&(p_btif->rx_mtx))) { -+ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); -+ return; -+ } -+ btif_rx_data_consummer(p_btif); -+ BTIF_MUTEX_UNLOCK(&(p_btif->rx_mtx)); -+} -+ -+static void btif_tx_worker(struct work_struct *p_work) -+{ -+ int i_ret = 0; -+ int leng_sent = 0; -+/*tx fifo out*/ -+ int how_much_get = 0; -+ unsigned char local_buf[384]; -+ -+/*get mtk_btif's pointer*/ -+ p_mtk_btif p_btif = container_of(p_work, mtk_btif, tx_work); -+ -+ BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif); -+ -+ if (mutex_lock_killable(&(p_btif->tx_mtx))) { -+ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); -+ return; -+ } -+ how_much_get = -+ kfifo_out(p_btif->p_tx_fifo, local_buf, sizeof(local_buf)); -+ do { -+ while (leng_sent < how_much_get) { -+ i_ret = _btif_send_data(p_btif, -+ local_buf + leng_sent, -+ how_much_get - leng_sent); -+ if (i_ret > 0) { -+ leng_sent += i_ret; -+ } else if (i_ret == 0) { -+ BTIF_WARN_FUNC -+ ("_btif_send_data return 0, retry\n"); -+ } else { -+ BTIF_WARN_FUNC -+ ("btif send data fail,reset tx fifo, i_ret(%d)\n", -+ i_ret); -+ kfifo_reset(p_btif->p_tx_fifo); -+ break; -+ } -+ } -+ how_much_get = -+ kfifo_out(p_btif->p_tx_fifo, local_buf, sizeof(local_buf)); -+ leng_sent = 0; -+ } while (how_much_get > 0); -+ BTIF_MUTEX_UNLOCK(&(p_btif->tx_mtx)); -+} -+ -+static void btif_rx_tasklet(unsigned long func_data) -+{ -+ unsigned long flags; -+/*get mtk_btif's pointer*/ -+ p_mtk_btif p_btif = (p_mtk_btif) func_data; -+ -+ BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif); -+/*lock rx_spinlock*/ -+ spin_lock_irqsave(&p_btif->rx_tasklet_spinlock, flags); -+ btif_rx_data_consummer(p_btif); -+ spin_unlock_irqrestore(&p_btif->rx_tasklet_spinlock, flags); -+} -+ -+static int _btif_tx_ctx_init(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { -+ p_btif->p_tx_wq = create_singlethread_workqueue("btif_txd"); -+ -+ if (!(p_btif->p_tx_wq)) { -+ BTIF_ERR_FUNC -+ ("create_singlethread_workqueue for tx thread fail\n"); -+ i_ret = -ENOMEM; -+ goto btm_init_err; -+ } -+ mutex_init(&(p_btif->tx_mtx)); -+/* init btif tx work */ -+ INIT_WORK(&(p_btif->tx_work), btif_tx_worker); -+ BTIF_INFO_FUNC("btif_tx_worker init succeed\n"); -+ -+ p_btif->p_tx_fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC); -+ if (p_btif->p_tx_fifo == NULL) { -+ i_ret = -ENOMEM; -+ BTIF_ERR_FUNC("kzalloc for p_btif->p_tx_fifo failed\n"); -+ goto btm_init_err; -+ } -+ -+ i_ret = kfifo_alloc(p_btif->p_tx_fifo, -+ BTIF_TX_FIFO_SIZE, GFP_ATOMIC); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("kfifo_alloc failed, errno(%d)\n", i_ret); -+ i_ret = -ENOMEM; -+ goto btm_init_err; -+ } -+ } else if (p_btif->tx_ctx == BTIF_TX_USER_CTX) { -+ BTIF_INFO_FUNC -+ ("nothing is done when btif tx in user's thread\n"); -+ } else { -+ BTIF_ERR_FUNC("unsupported tx context type:%d\n", -+ p_btif->tx_ctx); -+ goto btm_init_err; -+ } -+ -+ BTIF_INFO_FUNC("succeed\n"); -+ -+ i_ret = 0; -+ return i_ret; -+btm_init_err: -+ if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { -+ if (p_btif->p_tx_wq) { -+ destroy_workqueue(p_btif->p_tx_wq); -+ p_btif->p_tx_wq = NULL; -+ BTIF_INFO_FUNC("btif_tx_workqueue destroyed\n"); -+ } -+ kfree(p_btif->p_tx_fifo); -+ } -+ return i_ret; -+} -+ -+static int _btif_tx_ctx_deinit(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+ if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { -+ if (p_btif->p_tx_wq) { -+ destroy_workqueue(p_btif->p_tx_wq); -+ p_btif->p_tx_wq = NULL; -+ BTIF_INFO_FUNC("btif_tx_workqueue destroyed\n"); -+ } -+ if (p_btif->p_tx_fifo) { -+ kfifo_free(p_btif->p_tx_fifo); -+ kfree(p_btif->p_tx_fifo); -+ p_btif->p_tx_fifo = NULL; -+ } -+ } -+ return i_ret; -+} -+ -+static int _btif_rx_btm_init(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ if (p_btif->btm_type == BTIF_THREAD_CTX) { -+ init_completion(&p_btif->rx_comp); -+ -+ /*create kernel thread for later rx data handle*/ -+ p_btif->p_task = kthread_create(btif_rx_thread, p_btif, "btif_rxd"); -+ if (p_btif->p_task == NULL) { -+ BTIF_ERR_FUNC("kthread_create fail\n"); -+ i_ret = -ENOMEM; -+ goto btm_init_err; -+ } -+ -+#if ENABLE_BTIF_RX_THREAD_RT_SCHED -+ { -+ int i_ret = -1; -+ int policy = SCHED_FIFO; -+ struct sched_param param; -+ -+ param.sched_priority = MAX_RT_PRIO - 20; -+ i_ret = sched_setscheduler(p_btif->p_task, policy, ¶m); -+ if (i_ret != 0) -+ BTIF_WARN_FUNC("set RT to btif_rxd workqueue failed\n"); -+ else -+ BTIF_INFO_FUNC("set RT to btif_rxd workqueue succeed\n"); -+ } -+#endif -+ -+ wake_up_process(p_btif->p_task); -+ BTIF_INFO_FUNC("btif_rxd start to work!\n"); -+ } else if (p_btif->btm_type == BTIF_WQ_CTX) { -+ p_btif->p_rx_wq = create_singlethread_workqueue("btif_rxwq"); -+ if (!(p_btif->p_rx_wq)) { -+ BTIF_ERR_FUNC("create_singlethread_workqueue fail\n"); -+ i_ret = -ENOMEM; -+ goto btm_init_err; -+ } -+ mutex_init(&(p_btif->rx_mtx)); -+ /* init btif rx work */ -+ INIT_WORK(&(p_btif->rx_work), btif_rx_worker); -+ BTIF_INFO_FUNC("btif_rx_worker init succeed\n"); -+ } else if (p_btif->btm_type == BTIF_TASKLET_CTX) { -+ /*init rx tasklet*/ -+ tasklet_init(&(p_btif->rx_tasklet), btif_rx_tasklet, -+ (unsigned long)p_btif); -+ spin_lock_init(&(p_btif->rx_tasklet_spinlock)); -+ BTIF_INFO_FUNC("btif_rx_tasklet init succeed\n"); -+ } else { -+ BTIF_ERR_FUNC("unsupported rx context type:%d\n", -+ p_btif->btm_type); -+ } -+ -+/*spinlock init*/ -+ spin_lock_init(&(p_btif->rx_irq_spinlock)); -+ BTIF_INFO_FUNC("rx_spin_lock init succeed\n"); -+ -+ i_ret = 0; -+ return i_ret; -+btm_init_err: -+ if (p_btif->btm_type == BTIF_THREAD_CTX) { -+ /*do nothing*/ -+ BTIF_INFO_FUNC("failed\n"); -+ } else if (p_btif->btm_type == BTIF_WQ_CTX) { -+ if (p_btif->p_rx_wq) { -+ destroy_workqueue(p_btif->p_rx_wq); -+ p_btif->p_rx_wq = NULL; -+ BTIF_INFO_FUNC("btif_rx_workqueue destroyed\n"); -+ } -+ } -+ return i_ret; -+} -+ -+static int _btif_rx_btm_sched(p_mtk_btif p_btif) -+{ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ if (p_btif->btm_type == BTIF_THREAD_CTX) { -+ complete(&p_btif->rx_comp); -+ BTIF_DBG_FUNC("schedule btif_rx_thread\n"); -+ } else if (p_btif->btm_type == BTIF_WQ_CTX) { -+ queue_work(p_btif->p_rx_wq, &(p_btif->rx_work)); -+ BTIF_DBG_FUNC("schedule btif_rx_worker\n"); -+ } else if (p_btif->btm_type == BTIF_TASKLET_CTX) { -+ /*schedule it!*/ -+ tasklet_schedule(&(p_btif->rx_tasklet)); -+ BTIF_DBG_FUNC("schedule btif_rx_tasklet\n"); -+ } else { -+ BTIF_ERR_FUNC("unsupported rx context type:%d\n", -+ p_btif->btm_type); -+ } -+ -+ return 0; -+} -+ -+static int _btif_rx_btm_deinit(p_mtk_btif p_btif) -+{ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ if (p_btif->btm_type == BTIF_THREAD_CTX) { -+ if (p_btif->p_task != NULL) { -+ BTIF_INFO_FUNC("signaling btif rx thread to stop ...\n"); -+ kthread_stop(p_btif->p_task); -+ } -+ } else if (p_btif->btm_type == BTIF_WQ_CTX) { -+ if (p_btif->p_rx_wq) { -+ cancel_work_sync(&(p_btif->rx_work)); -+ BTIF_INFO_FUNC("btif_rx_worker cancelled\n"); -+ destroy_workqueue(p_btif->p_rx_wq); -+ p_btif->p_rx_wq = NULL; -+ BTIF_INFO_FUNC("btif_rx_workqueue destroyed\n"); -+ } -+ mutex_destroy(&(p_btif->rx_mtx)); -+ } else if (p_btif->btm_type == BTIF_TASKLET_CTX) { -+ tasklet_kill(&(p_btif->rx_tasklet)); -+ BTIF_INFO_FUNC("rx_tasklet killed\n"); -+ } else { -+ BTIF_ERR_FUNC("unsupported rx context type:%d\n", -+ p_btif->btm_type); -+ } -+ -+ spin_lock_init(&(p_btif->rx_irq_spinlock)); -+ -+ return 0; -+} -+ -+ -+void btif_dump_bbs_str(unsigned char *p_str, p_btif_buf_str p_bbs) -+{ -+ BTIF_INFO_FUNC -+ ("%s UBS:0x%p\n Size:0x%p\n read:0x%08x\n write:0x%08x\n", -+ p_str, p_bbs, p_bbs->size, p_bbs->rd_idx, p_bbs->wr_idx); -+} -+ -+unsigned int btif_bbs_write(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len) -+{ -+/*in IRQ context, so read operation won't interrupt this operation*/ -+ -+ unsigned int wr_len = 0; -+ -+ unsigned int emp_len = BBS_LEFT(p_bbs); -+ unsigned int ava_len = emp_len - 1; -+ p_mtk_btif p_btif = container_of(p_bbs, mtk_btif, btif_buf); -+ -+ if (ava_len <= 0) { -+ BTIF_ERR_FUNC -+ ("no empty space left for write, (%d)ava_len, (%d)to write\n", -+ ava_len, buf_len); -+ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); -+ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); -+ return 0; -+ } -+ -+ if (ava_len < buf_len) { -+ BTIF_ERR_FUNC("BTIF overrun, (%d)empty, (%d)needed\n", -+ emp_len, buf_len); -+ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); -+ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); -+ _btif_dump_memory("", p_buf, buf_len); -+ } -+ -+ if (buf_len >= g_max_pkg_len) { -+ BTIF_WARN_FUNC("buf_len too long, (%d)ava_len, (%d)to write\n", -+ ava_len, buf_len); -+ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); -+ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); -+ _btif_dump_memory("", p_buf, buf_len); -+ } -+ -+ wr_len = min(buf_len, ava_len); -+ btif_bbs_wr_direct(p_bbs, p_buf, wr_len); -+ -+ if (BBS_COUNT(p_bbs) >= g_max_pding_data_size) { -+ BTIF_WARN_FUNC("Rx buf_len too long, size(%d)\n", -+ BBS_COUNT(p_bbs)); -+ btif_dump_bbs_str("Rx buffer tooo long", p_bbs); -+ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); -+ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); -+ _btif_dump_memory("", p_buf, buf_len); -+ BBS_INIT(p_bbs); -+ } -+ -+ return wr_len; -+} -+ -+unsigned int btif_bbs_read(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len) -+{ -+ unsigned int rd_len = 0; -+ unsigned int ava_len = 0; -+ unsigned int wr_idx = p_bbs->wr_idx; -+ -+ ava_len = BBS_COUNT_CUR(p_bbs, wr_idx); -+ if (ava_len >= 4096) { -+ BTIF_WARN_FUNC("ava_len too long, size(%d)\n", ava_len); -+ btif_dump_bbs_str("Rx buffer tooo long", p_bbs); -+ } -+ if (ava_len != 0) { -+ if (buf_len >= ava_len) { -+ rd_len = ava_len; -+ if (wr_idx >= (p_bbs)->rd_idx) { -+ memcpy(p_buf, BBS_PTR(p_bbs, -+ p_bbs->rd_idx), -+ ava_len); -+ (p_bbs)->rd_idx = wr_idx; -+ } else { -+ unsigned int tail_len = BBS_SIZE(p_bbs) - -+ (p_bbs)->rd_idx; -+ memcpy(p_buf, BBS_PTR(p_bbs, -+ p_bbs->rd_idx), -+ tail_len); -+ memcpy(p_buf + tail_len, BBS_PTR(p_bbs, -+ 0), ava_len - tail_len); -+ (p_bbs)->rd_idx = wr_idx; -+ } -+ } else { -+ rd_len = buf_len; -+ if (wr_idx >= (p_bbs)->rd_idx) { -+ memcpy(p_buf, BBS_PTR(p_bbs, -+ p_bbs->rd_idx), -+ rd_len); -+ (p_bbs)->rd_idx = (p_bbs)->rd_idx + rd_len; -+ } else { -+ unsigned int tail_len = BBS_SIZE(p_bbs) - -+ (p_bbs)->rd_idx; -+ if (tail_len >= rd_len) { -+ memcpy(p_buf, BBS_PTR(p_bbs, p_bbs->rd_idx), -+ rd_len); -+ (p_bbs)->rd_idx = -+ ((p_bbs)->rd_idx + rd_len) & (BBS_MASK(p_bbs)); -+ } else { -+ memcpy(p_buf, BBS_PTR(p_bbs, p_bbs->rd_idx), tail_len); -+ memcpy(p_buf + tail_len, -+ (p_bbs)->p_buf, rd_len - tail_len); -+ (p_bbs)->rd_idx = rd_len - tail_len; -+ } -+ } -+ } -+ } -+ mb(); -+ return rd_len; -+} -+ -+unsigned int btif_bbs_wr_direct(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len) -+{ -+ unsigned int tail_len = 0; -+ unsigned int l = 0; -+ unsigned int tmp_wr_idx = p_bbs->wr_idx; -+ -+ tail_len = BBS_SIZE(p_bbs) - (tmp_wr_idx & BBS_MASK(p_bbs)); -+ -+ l = min(tail_len, buf_len); -+ -+ memcpy((p_bbs->p_buf) + (tmp_wr_idx & BBS_MASK(p_bbs)), p_buf, l); -+ memcpy(p_bbs->p_buf, p_buf + l, buf_len - l); -+ -+ mb(); -+ -+ tmp_wr_idx += buf_len; -+ tmp_wr_idx &= BBS_MASK(p_bbs); -+ p_bbs->wr_idx = tmp_wr_idx; -+ -+ mb(); -+ return buf_len; -+} -+ -+int _btif_dma_write(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len) -+{ -+ unsigned int i_ret = 0; -+ unsigned int retry = 0; -+ unsigned int max_tx_retry = 10; -+ -+ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info; -+ -+ _btif_irq_ctrl_sync(p_dma_info->p_irq, false); -+ do { -+ /*wait until tx is allowed*/ -+ while (!hal_dma_is_tx_allow(p_dma_info) && -+ (retry < max_tx_retry)) { -+ retry++; -+ if (retry >= max_tx_retry) { -+ BTIF_ERR_FUNC("wait for tx allowed timeout\n"); -+ break; -+ } -+ } -+ if (retry >= max_tx_retry) -+ break; -+ -+ if (buf_len <= hal_dma_get_ava_room(p_dma_info)) -+ i_ret = hal_dma_send_data(p_dma_info, p_buf, buf_len); -+ else -+ i_ret = 0; -+ } while (0); -+ _btif_irq_ctrl_sync(p_dma_info->p_irq, true); -+ return i_ret; -+} -+ -+int _btif_pio_write(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len) -+{ -+ unsigned int i_ret = 0; -+ unsigned int sent_len = 0; -+ unsigned int retry = 0; -+ unsigned int max_tx_retry = 10; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ -+ while ((sent_len < buf_len)) { -+ if (hal_btif_is_tx_allow(p_btif_info)) { -+ i_ret = hal_btif_send_data(p_btif_info, -+ p_buf + sent_len, -+ buf_len - sent_len); -+ if (i_ret > 0) { -+ sent_len += i_ret; -+ BTIF_DBG_FUNC("lent sent:%d, total sent:%d\n", -+ i_ret, sent_len); -+ retry = 0; -+ } -+ } -+ if ((++retry > max_tx_retry) || (i_ret < 0)) { -+ BTIF_INFO_FUNC("exceed retry times limit :%d\n", retry); -+ break; -+ } -+ } -+ i_ret = sent_len; -+ return i_ret; -+} -+ -+int _btif_dump_memory(char *str, unsigned char *p_buf, unsigned int buf_len) -+{ -+ unsigned int idx = 0; -+ -+ pr_debug("%s:, length:%d\n", str, buf_len); -+ for (idx = 0; idx < buf_len;) { -+ pr_debug("%02x ", p_buf[idx]); -+ idx++; -+ if (idx % 8 == 0) -+ pr_debug("\n"); -+ } -+ return 0; -+} -+ -+int btif_send_data(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len) -+{ -+ int i_ret = 0; -+ -+ if (p_btif->tx_ctx == BTIF_TX_USER_CTX) { -+ i_ret = _btif_send_data(p_btif, p_buf, buf_len); -+ } else if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { -+ int length = 0; -+/*tx fifo in*/ -+ length = kfifo_in(p_btif->p_tx_fifo, -+ (unsigned char *)p_buf, buf_len); -+ if (length == buf_len) { -+ queue_work(p_btif->p_tx_wq, &(p_btif->tx_work)); -+ BTIF_DBG_FUNC("schedule btif_tx_worker\n"); -+ i_ret = length; -+ } else { -+ i_ret = 0; -+ BTIF_ERR_FUNC("fifo in failed, target len(%d),in len(%d),", -+ "don't schedule btif_tx_worker\n", buf_len, length); -+ } -+ } else { -+ BTIF_ERR_FUNC("invalid btif tx context:%d\n", p_btif->tx_ctx); -+ i_ret = 0; -+ } -+ -+ return i_ret; -+} -+ -+int _btif_send_data(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len) -+{ -+ int i_ret = 0; -+ unsigned int state = 0; -+ -+/*make sure BTIF in ON state before doing tx operation*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ state = _btif_state_get(p_btif); -+ -+ if (state != B_S_ON) -+ i_ret = _btif_exit_dpidle(p_btif); -+ -+ if (i_ret != 0) { -+ i_ret = E_BTIF_INVAL_STATE; -+ } else if (p_btif->tx_mode == BTIF_MODE_DMA) { -+ /*_btif_dump_memory("tx data:", p_buf, buf_len);*/ -+ i_ret = _btif_dma_write(p_btif, p_buf, buf_len); -+ } else if (p_btif->tx_mode == BTIF_MODE_PIO) { -+ /*_btif_dump_memory("tx data:", p_buf, buf_len);*/ -+ i_ret = _btif_pio_write(p_btif, p_buf, buf_len); -+ } else { -+ BTIF_ERR_FUNC("invalid tx mode:%d\n", p_btif->tx_mode); -+ i_ret = 0; -+ } -+ -+/*save Tx packet here*/ -+ if (i_ret > 0) -+ btif_log_buf_dmp_in(&p_btif->tx_log, p_buf, i_ret); -+ -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+} -+ -+int btif_dump_reg(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ unsigned int ori_state = 0; -+ -+/*make sure BTIF in ON state before doing tx operation*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ ori_state = _btif_state_get(p_btif); -+ -+ if (ori_state == B_S_OFF) { -+ i_ret = E_BTIF_INVAL_STATE; -+ BTIF_ERR_FUNC -+ ("BTIF in OFF state, ", -+ "should no need to dump register, ", -+ "please check wmt's operation is okay or not.\n"); -+ goto dmp_reg_err; -+ } -+ -+ if ((ori_state != B_S_ON) && (ori_state < B_S_MAX)) { -+ BTIF_ERR_FUNC("BTIF's original state is %s, not B_S_ON\n", g_state[ori_state]); -+ BTIF_ERR_FUNC("!!!!---<<>>---!!!"); -+ i_ret = _btif_exit_dpidle(p_btif); -+ } -+ -+ if (i_ret != 0) { -+ i_ret = E_BTIF_INVAL_STATE; -+ BTIF_ERR_FUNC("switch to B_S_ON failed\n"); -+ goto dmp_reg_err; -+ } -+ -+/*dump BTIF register*/ -+ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); -+ -+/*dump BTIF Tx DMA channel register if in DMA mode*/ -+ if (p_btif->tx_mode == BTIF_MODE_DMA) -+ hal_dma_dump_reg(p_btif->p_tx_dma->p_dma_info, REG_TX_DMA_ALL); -+ else -+ BTIF_INFO_FUNC("BTIF Tx in PIO mode,no need to dump Tx DMA's register\n"); -+ -+/*dump BTIF Rx DMA channel register if in DMA mode*/ -+ if (p_btif->rx_mode == BTIF_MODE_DMA) -+ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); -+ else -+ BTIF_INFO_FUNC("BTIF Rx in PIO mode,no need to dump Rx DMA's register\n"); -+ -+ switch (ori_state) { -+ case B_S_SUSPEND: -+/*return to dpidle state*/ -+/* break; */ -+ case B_S_DPIDLE: -+/*return to dpidle state*/ -+ _btif_enter_dpidle(p_btif); -+ break; -+ case B_S_ON: -+/*nothing needs to be done*/ -+ break; -+ default: -+ break; -+ } -+ -+dmp_reg_err: -+ -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+} -+ -+int btif_rx_notify_reg(p_mtk_btif p_btif, MTK_BTIF_RX_NOTIFY rx_notify) -+{ -+ if (p_btif->rx_notify) { -+ BTIF_WARN_FUNC -+ ("rx cb already exist, rewrite from (0x%p) to (0x%p)\n", -+ p_btif->rx_notify, rx_notify); -+ } -+ p_btif->rx_notify = rx_notify; -+ -+ return 0; -+} -+ -+int btif_dump_data(char *p_buf, int len) -+{ -+ unsigned int idx = 0; -+ unsigned char str[30]; -+ unsigned char *p_str; -+ -+ p_str = &str[0]; -+ for (idx = 0; idx < len; idx++, p_buf++) { -+ sprintf(p_str, "%02x ", *p_buf); -+ p_str += 3; -+ if (7 == (idx % 8)) { -+ *p_str++ = '\n'; -+ *p_str = '\0'; -+ pr_debug("%s", str); -+ p_str = &str[0]; -+ } -+ } -+ if (len % 8) { -+ *p_str++ = '\n'; -+ *p_str = '\0'; -+ pr_debug("%s", str); -+ } -+ return 0; -+} -+ -+int btif_log_buf_dmp_in(P_BTIF_LOG_QUEUE_T p_log_que, const char *p_buf, -+ int len) -+{ -+ P_BTIF_LOG_BUF_T p_log_buf = NULL; -+ char *dir = NULL; -+ struct timeval *p_timer = NULL; -+ unsigned long flags; -+ bool output_flag = false; -+ -+ BTIF_DBG_FUNC("++\n"); -+ -+ if ((p_log_que == NULL) || (p_buf == NULL) || (len == 0)) { -+ BTIF_ERR_FUNC("invalid parameter, p_log_que(0x%x), buf(0x%x), ", -+ "len(%d)\n", p_log_que, p_buf, len); -+ return 0; -+ } -+ if (!(p_log_que->enable)) -+ return 0; -+ -+ dir = p_log_que->dir == BTIF_TX ? "Tx" : "Rx"; -+ output_flag = p_log_que->output_flag; -+ -+ spin_lock_irqsave(&(p_log_que->lock), flags); -+ -+/*get next log buffer for record usage*/ -+ p_log_buf = p_log_que->p_queue[0] + p_log_que->in; -+ p_timer = &p_log_buf->timer; -+ -+/*log time stamp*/ -+ do_gettimeofday(p_timer); -+ -+/*record data information including length and content*/ -+ p_log_buf->len = len; -+ memcpy(p_log_buf->buffer, p_buf, len > BTIF_LOG_SZ ? BTIF_LOG_SZ : len); -+ -+/*update log queue size information*/ -+ p_log_que->size++; -+ p_log_que->size = p_log_que->size > -+ BTIF_LOG_ENTRY_NUM ? BTIF_LOG_ENTRY_NUM : p_log_que->size; -+ -+/*update log queue index information*/ -+ p_log_que->in++; -+ p_log_que->in %= BTIF_LOG_ENTRY_NUM; -+ -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ -+/*check if log dynamic output function is enabled or not*/ -+ if (output_flag) { -+ pr_debug("BTIF-DBG, dir:%s, %d.%ds len:%d\n", -+ dir, (int)p_timer->tv_sec, (int)p_timer->tv_usec, len); -+/*output buffer content*/ -+ btif_dump_data((char *)p_buf, len); -+ } -+ BTIF_DBG_FUNC("--\n"); -+ -+ return 0; -+} -+ -+int btif_log_buf_dmp_out(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ P_BTIF_LOG_BUF_T p_log_buf = NULL; -+ unsigned int out_index = 0; -+ unsigned int in_index = 0; -+ unsigned int dump_size = 0; -+ unsigned char *p_buf = NULL; -+ unsigned int len = 0; -+ unsigned int pkt_count = 0; -+ unsigned char *p_dir = NULL; -+ struct timeval *p_timer = NULL; -+ unsigned long flags; -+ -+#if 0 /* no matter enable or not, we allowed output */ -+ if (!(p_log_que->enable)) -+ return; -+#endif -+ BTIF_DBG_FUNC("++\n"); -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ in_index = p_log_que->in; -+ dump_size = p_log_que->size; -+ out_index = p_log_que->size >= -+ BTIF_LOG_ENTRY_NUM ? in_index : (BTIF_LOG_ENTRY_NUM - -+ p_log_que->size + -+ in_index) % BTIF_LOG_ENTRY_NUM; -+ p_dir = p_log_que->dir == BTIF_TX ? "Tx" : "Rx"; -+ -+ BTIF_INFO_FUNC("btif %s log buffer size:%d\n", p_dir, dump_size); -+ -+ if (dump_size != 0) { -+ while (dump_size--) { -+ p_log_buf = p_log_que->p_queue[0] + out_index; -+ -+ len = p_log_buf->len; -+ p_buf = p_log_buf->buffer; -+ p_timer = &p_log_buf->timer; -+ -+ len = len > BTIF_LOG_SZ ? BTIF_LOG_SZ : len; -+ -+ BTIF_INFO_FUNC("dir:%s, pkt_count:%d, %d.%ds len:%d\n", -+ p_dir, -+ pkt_count++, -+ (int)p_timer->tv_sec, -+ (int)p_timer->tv_usec, len); -+/*output buffer content*/ -+ btif_dump_data(p_log_buf->buffer, len); -+ out_index++; -+ out_index %= BTIF_LOG_ENTRY_NUM; -+ } -+ } -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_DBG_FUNC("--\n"); -+ -+ return 0; -+} -+ -+int btif_log_buf_enable(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ p_log_que->enable = true; -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_INFO_FUNC("enable %s log function\n", -+ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); -+ return 0; -+} -+ -+int btif_log_buf_disable(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ p_log_que->enable = false; -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_INFO_FUNC("disable %s log function\n", -+ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); -+ return 0; -+} -+ -+int btif_log_output_enable(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ p_log_que->output_flag = true; -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_INFO_FUNC("%s log rt output enabled\n", -+ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); -+ return 0; -+} -+ -+int btif_log_output_disable(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ p_log_que->output_flag = false; -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_INFO_FUNC("%s log rt output disabled\n", -+ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); -+ return 0; -+} -+ -+int btif_log_buf_reset(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ -+/*tx log buffer init*/ -+ p_log_que->in = 0; -+ p_log_que->out = 0; -+ p_log_que->size = 0; -+ p_log_que->enable = true; -+ memset((p_log_que->p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T)); -+ -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_DBG_FUNC("reset %s log buffer\n", -+ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); -+ return 0; -+} -+ -+int btif_log_buf_init(p_mtk_btif p_btif) -+{ -+/*tx log buffer init*/ -+ p_btif->tx_log.dir = BTIF_TX; -+ p_btif->tx_log.in = 0; -+ p_btif->tx_log.out = 0; -+ p_btif->tx_log.size = 0; -+ p_btif->tx_log.output_flag = false; -+ p_btif->tx_log.enable = true; -+ spin_lock_init(&(p_btif->tx_log.lock)); -+ BTIF_DBG_FUNC("tx_log.p_queue:0x%p\n", p_btif->tx_log.p_queue[0]); -+ memset((p_btif->tx_log.p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T)); -+ -+/*rx log buffer init*/ -+ p_btif->rx_log.dir = BTIF_RX; -+ p_btif->rx_log.in = 0; -+ p_btif->rx_log.out = 0; -+ p_btif->rx_log.size = 0; -+ p_btif->rx_log.output_flag = false; -+ p_btif->rx_log.enable = true; -+ spin_lock_init(&(p_btif->rx_log.lock)); -+ BTIF_DBG_FUNC("rx_log.p_queue:0x%p\n", p_btif->rx_log.p_queue[0]); -+ memset((p_btif->rx_log.p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T)); -+ -+ return 0; -+} -+ -+int btif_tx_dma_mode_set(int en) -+{ -+ int index = 0; -+ ENUM_BTIF_MODE mode = (en == 1) ? BTIF_MODE_DMA : BTIF_MODE_PIO; -+ -+ for (index = 0; index < BTIF_PORT_NR; index++) -+ g_btif[index].tx_mode = mode; -+ -+ return 0; -+} -+ -+int btif_rx_dma_mode_set(int en) -+{ -+ int index = 0; -+ ENUM_BTIF_MODE mode = (en == 1) ? BTIF_MODE_DMA : BTIF_MODE_PIO; -+ -+ for (index = 0; index < BTIF_PORT_NR; index++) -+ g_btif[index].rx_mode = mode; -+ -+ return 0; -+} -+ -+static int BTIF_init(void) -+{ -+ int i_ret = -1; -+ int index = 0; -+ p_mtk_btif_dma p_tx_dma = NULL; -+ p_mtk_btif_dma p_rx_dma = NULL; -+ unsigned char *p_btif_buffer = NULL; -+ unsigned char *p_tx_queue = NULL; -+ unsigned char *p_rx_queue = NULL; -+ -+ BTIF_DBG_FUNC("++\n"); -+ -+/*Platform Driver initialization*/ -+ i_ret = platform_driver_register(&mtk_btif_dev_drv); -+ if (i_ret) { -+ BTIF_ERR_FUNC("BTIF platform driver registered failed, ret(%d)\n", i_ret); -+ goto err_exit1; -+ } -+ -+ i_ret = driver_create_file(&mtk_btif_dev_drv.driver, &driver_attr_flag); -+ if (i_ret) -+ BTIF_ERR_FUNC("BTIF pdriver_create_file failed, ret(%d)\n", i_ret); -+ -+/*SW init*/ -+ for (index = 0; index < BTIF_PORT_NR; index++) { -+ p_btif_buffer = kmalloc(BTIF_RX_BUFFER_SIZE, GFP_ATOMIC); -+ if (!p_btif_buffer) { -+ BTIF_ERR_FUNC("p_btif_buffer kmalloc memory fail\n"); -+ return -1; -+ } -+ BTIF_INFO_FUNC("p_btif_buffer get memory 0x%p\n", p_btif_buffer); -+ p_tx_queue = kmalloc_array(BTIF_LOG_ENTRY_NUM, sizeof(BTIF_LOG_BUF_T), GFP_ATOMIC); -+ if (!p_tx_queue) { -+ BTIF_ERR_FUNC("p_tx_queue kmalloc memory fail\n"); -+ kfree(p_btif_buffer); -+ return -1; -+ } -+ BTIF_INFO_FUNC("p_tx_queue get memory 0x%p\n", p_tx_queue); -+ p_rx_queue = kmalloc_array(BTIF_LOG_ENTRY_NUM, sizeof(BTIF_LOG_BUF_T), GFP_ATOMIC); -+ if (!p_rx_queue) { -+ BTIF_ERR_FUNC("p_rx_queue kmalloc memory fail\n"); -+ kfree(p_btif_buffer); -+ kfree(p_tx_queue); -+ return -1; -+ } -+ BTIF_INFO_FUNC("p_rx_queue get memory 0x%p\n", p_rx_queue); -+ -+ INIT_LIST_HEAD(&(g_btif[index].user_list)); -+ BBS_INIT(&(g_btif[index].btif_buf)); -+ g_btif[index].enable = false; -+ g_btif[index].open_counter = 0; -+ g_btif[index].setting = &g_btif_setting[index]; -+ g_btif[index].p_btif_info = hal_btif_info_get(); -+ g_btif[index].tx_mode = g_btif_setting[index].tx_mode; -+ g_btif[index].rx_mode = g_btif_setting[index].rx_mode; -+ g_btif[index].btm_type = g_btif_setting[index].rx_type; -+ g_btif[index].tx_ctx = g_btif_setting[index].tx_type; -+ g_btif[index].lpbk_flag = false; -+ g_btif[index].rx_cb = NULL; -+ g_btif[index].rx_notify = NULL; -+ g_btif[index].btif_buf.p_buf = p_btif_buffer; -+ g_btif[index].tx_log.p_queue[0] = (P_BTIF_LOG_BUF_T) p_tx_queue; -+ g_btif[index].rx_log.p_queue[0] = (P_BTIF_LOG_BUF_T) p_rx_queue; -+ btif_log_buf_init(&g_btif[index]); -+ -+#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) -+/*enable BTIF clock gating by default*/ -+ i_ret = hal_btif_clk_ctrl(g_btif[index].p_btif_info, -+ CLK_OUT_DISABLE); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF controller CG failed\n"); -+ goto err_exit2; -+ } -+#endif -+ -+/* -+ * viftual FIFO memory must be physical continious, -+ * because DMA will access it directly without MMU -+ */ -+#if ENABLE_BTIF_TX_DMA -+ p_tx_dma = &g_dma[index][BTIF_TX]; -+ g_btif[index].p_tx_dma = p_tx_dma; -+ p_tx_dma->dir = BTIF_TX; -+ p_tx_dma->p_btif = &(g_btif[index]); -+ -+/*DMA Tx vFIFO initialization*/ -+ p_tx_dma->p_dma_info = hal_btif_dma_info_get(DMA_DIR_TX); -+/*spinlock init*/ -+ spin_lock_init(&(p_tx_dma->iolock)); -+/*entry setup*/ -+ atomic_set(&(p_tx_dma->entry), 0); -+/*vFIFO initialization*/ -+ i_ret = _btif_vfifo_init(p_tx_dma); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Tx vFIFO allocation failed\n"); -+ goto err_exit2; -+ } -+ -+#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) -+/*enable BTIF Tx DMA channel's clock gating by default*/ -+ i_ret = hal_btif_dma_clk_ctrl(p_tx_dma->p_dma_info, -+ CLK_OUT_DISABLE); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Tx DMA's CG failed\n"); -+ goto err_exit2; -+ } -+#endif -+ -+#else -+ g_btif[index].p_tx_dma = NULL; -+/*force tx mode to DMA no matter what it is in default setting*/ -+ g_btif[index].tx_mode = BTIF_MODE_PIO; -+#endif -+ -+#if ENABLE_BTIF_RX_DMA -+ p_rx_dma = &g_dma[index][BTIF_RX]; -+ g_btif[index].p_rx_dma = p_rx_dma; -+ p_rx_dma->p_btif = &(g_btif[index]); -+ p_rx_dma->dir = BTIF_RX; -+ -+/*DMA Tx vFIFO initialization*/ -+ p_rx_dma->p_dma_info = hal_btif_dma_info_get(DMA_DIR_RX); -+/*spinlock init*/ -+ spin_lock_init(&(p_rx_dma->iolock)); -+/*entry setup*/ -+ atomic_set(&(p_rx_dma->entry), 0); -+/*vFIFO initialization*/ -+ i_ret = _btif_vfifo_init(p_rx_dma); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Rx vFIFO allocation failed\n"); -+ goto err_exit2; -+ } -+ -+#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) -+/*enable BTIF Tx DMA channel's clock gating by default*/ -+ i_ret = hal_btif_dma_clk_ctrl(p_rx_dma->p_dma_info, -+ CLK_OUT_DISABLE); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Rx DMA's CG failed\n"); -+ goto err_exit2; -+ } -+#endif -+ -+#else -+ g_btif[index].p_rx_dma = NULL; -+/*force rx mode to DMA no matter what it is in default setting*/ -+ g_btif[index].rx_mode = BTIF_MODE_PIO; -+ -+#endif -+/*PM state mechine initialization*/ -+ i_ret = _btif_state_init(&(g_btif[index])); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF state mechanism init failed\n"); -+ goto err_exit2; -+ } -+ -+/*Rx bottom half initialization*/ -+ i_ret = _btif_rx_btm_init(&(g_btif[index])); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Rx btm init failed\n"); -+ goto err_exit3; -+ } -+ i_ret = _btif_tx_ctx_init(&(g_btif[index])); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Tx context init failed\n"); -+ goto err_exit4; -+ } -+/*Character Device initialization*/ -+/*Chaozhong: ToDo: to be initialized*/ -+ -+ mutex_init(&g_btif[index].ops_mtx); -+ } -+ -+/*Debug purpose initialization*/ -+ -+#if BTIF_CDEV_SUPPORT -+ btif_chrdev_init(); -+#endif -+ -+ return 0; -+ -+err_exit4: -+ for (index = 0; index < BTIF_PORT_NR; index++) -+ _btif_tx_ctx_deinit(&(g_btif[index])); -+ -+err_exit3: -+ for (index = 0; index < BTIF_PORT_NR; index++) { -+ _btif_rx_btm_deinit(&(g_btif[index])); -+ -+ _btif_state_deinit(&(g_btif[index])); -+ } -+ -+err_exit2: -+ for (index = 0; index < BTIF_PORT_NR; index++) { -+ p_tx_dma = &g_dma[index][BTIF_TX]; -+ p_rx_dma = &g_dma[index][BTIF_RX]; -+#if ENABLE_BTIF_TX_DMA -+ _btif_vfifo_deinit(p_tx_dma); -+#endif -+ -+#if ENABLE_BTIF_RX_DMA -+ _btif_vfifo_deinit(p_rx_dma); -+#endif -+ g_btif[index].open_counter = 0; -+ g_btif[index].enable = false; -+ } -+ driver_remove_file(&mtk_btif_dev_drv.driver, &driver_attr_flag); -+ platform_driver_unregister(&mtk_btif_dev_drv); -+ -+err_exit1: -+ i_ret = -1; -+ BTIF_DBG_FUNC("--\n"); -+ return i_ret; -+} -+ -+static void BTIF_exit(void) -+{ -+ unsigned int index = 0; -+ p_mtk_btif_dma p_tx_dma = NULL; -+ p_mtk_btif_dma p_rx_dma = NULL; -+ -+ BTIF_DBG_FUNC("++\n"); -+ -+ for (index = 0; index < BTIF_PORT_NR; index++) { -+ g_btif[index].open_counter = 0; -+ g_btif[index].enable = false; -+ p_tx_dma = &g_dma[index][BTIF_TX]; -+ p_rx_dma = &g_dma[index][BTIF_RX]; -+#if ENABLE_BTIF_TX_DMA -+ _btif_vfifo_deinit(p_tx_dma); -+#endif -+ -+#if ENABLE_BTIF_RX_DMA -+ _btif_vfifo_deinit(p_rx_dma); -+#endif -+ _btif_state_deinit(&(g_btif[index])); -+ -+ _btif_rx_btm_deinit(&(g_btif[index])); -+ -+ mutex_destroy(&g_btif[index].ops_mtx); -+ } -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+ hal_btif_clk_unprepare(); -+#endif -+ -+ driver_remove_file(&mtk_btif_dev_drv.driver, &driver_attr_flag); -+ platform_driver_unregister(&mtk_btif_dev_drv); -+ BTIF_DBG_FUNC("--\n"); -+} -+ -+int mtk_btif_hal_get_log_lvl(void) -+{ -+ return mtk_btif_dbg_lvl; -+} -+ -+void mtk_btif_read_cpu_sw_rst_debug(void) -+{ -+ mtk_btif_read_cpu_sw_rst_debug_plat(); -+} -+ -+/*---------------------------------------------------------------------------*/ -+ -+module_init(BTIF_init); -+module_exit(BTIF_exit); -+ -+/*---------------------------------------------------------------------------*/ -+ -+MODULE_AUTHOR("MBJ/WCN/SE/SS1/Chaozhong.Liang"); -+MODULE_DESCRIPTION("MTK BTIF Driver$1.0$"); -+MODULE_LICENSE("GPL"); -+ -+/*---------------------------------------------------------------------------*/ -diff --git a/drivers/misc/mediatek/btif/common/mtk_btif_exp.c b/drivers/misc/mediatek/btif/common/mtk_btif_exp.c -new file mode 100644 -index 0000000000000..c0df44558357b ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/mtk_btif_exp.c -@@ -0,0 +1,786 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "MTK-BTIF-EXP" -+ -+/*#include "mtk_btif_exp.h"*/ -+#include "mtk_btif.h" -+ -+/*---------------------------------Function----------------------------------*/ -+ -+p_mtk_btif btif_exp_srh_id(unsigned long u_id) -+{ -+ int index = 0; -+ p_mtk_btif p_btif = NULL; -+ struct list_head *p_list = NULL; -+ struct list_head *tmp = NULL; -+ p_mtk_btif_user p_user = NULL; -+ -+ for (index = 0; (index < BTIF_PORT_NR) && (p_btif == NULL); index++) { -+ p_list = &(g_btif[index].user_list); -+ list_for_each(tmp, p_list) { -+ p_user = container_of(tmp, mtk_btif_user, entry); -+ if (u_id == p_user->u_id) { -+ p_btif = p_user->p_btif; -+ BTIF_DBG_FUNC -+ ("BTIF's user id(0x%p), p_btif(0x%p)\n", -+ p_user->u_id, p_btif); -+ break; -+ } -+ } -+ } -+ if (p_btif == NULL) { -+ BTIF_INFO_FUNC -+ ("no btif structure found for BTIF's user id(0x%lx)\n", -+ u_id); -+ } -+ return p_btif; -+} -+ -+/*-----Normal Mode API declearation-------*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_open -+* DESCRIPTION -+* open BTIF interface, will do BTIF module HW and SW initialization -+* PARAMETERS -+* p_owner [IN] pointer to owner who call this API, -+* currently there are 2 owner ("stp" or "btif_tester") -+* may use this module -+* for "stp", BTIF will call rx callback function to route rx data to STP module -+* for "stp_tester", BTIF will save rx data and wait for native process to access -+* p_id [IN] BTIF's user id will be put to this address -+* RETURNS -+* int 0 = BTIF module initialization fail; negative = BTIF module initialization success -+* if open success, value p_id will be the only identifier -+* for user to access BTIF's other operations -+* including read/write/dpidle_ctrl/rx_cb_retister -+* this user id is only an identifier used for owner identification -+*****************************************************************************/ -+int mtk_wcn_btif_open(char *p_owner, unsigned long *p_id) -+{ -+ int i_ret = -1; -+ unsigned int index = 0; -+ p_mtk_btif_user p_new_user = NULL; -+ p_mtk_btif p_btif = &g_btif[index]; -+ struct list_head *p_user_list = &(p_btif->user_list); -+ -+ BTIF_DBG_FUNC("++"); -+ BTIF_DBG_FUNC("p_btif(0x%p)\n", p_btif); -+ -+ if (mutex_lock_killable(&(p_btif->ops_mtx))) { -+ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); -+ return E_BTIF_INTR; -+ } -+ if ((p_owner == NULL) || (p_id == NULL)) { -+ if (p_id) -+ *p_id = 0; -+ BTIF_ERR_FUNC("parameter invalid, p_owner(0x%p), p_id(0x%p)\n", -+ p_owner, p_id); -+ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+/*check if btif is already opened or not, if yes, just return fail*/ -+ if (!list_empty(p_user_list)) { -+ struct list_head *pos; -+ p_mtk_btif_user p_user; -+ -+ BTIF_ERR_FUNC("BTIF's user list is not empty\n"); -+ list_for_each(pos, p_user_list) { -+ p_user = container_of(pos, mtk_btif_user, entry); -+ BTIF_INFO_FUNC("BTIF's user id(0x%lx), name(%s)\n", -+ p_user->u_id, p_user->u_name); -+ } -+/*leave p_id alone*/ -+ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); -+ return E_BTIF_ALREADY_OPEN; -+ } -+ p_new_user = vmalloc(sizeof(mtk_btif_user)); -+ -+ if (p_new_user != NULL) { -+ INIT_LIST_HEAD(&(p_new_user->entry)); -+ p_new_user->enable = false; -+ p_new_user->p_btif = p_btif; -+ p_new_user->u_id = (unsigned long)p_new_user; -+ strncpy(p_new_user->u_name, p_owner, sizeof(p_new_user->u_name) - 1); -+ p_new_user->u_name[sizeof(p_new_user->u_name) - 1] = '\0'; -+ BTIF_DBG_FUNC("owner name:%s, recorded name:%s\n", -+ p_owner, p_new_user->u_name); -+ -+ i_ret = btif_open(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("btif_open failed, i_ret(%d)\n", i_ret); -+ *p_id = 0; -+/*free btif new user's structure*/ -+ vfree(p_new_user); -+ p_new_user = NULL; -+ } else { -+ BTIF_INFO_FUNC("btif_open succeed\n"); -+ *p_id = p_new_user->u_id; -+/*mark enable flag to true*/ -+ p_new_user->enable = true; -+/*add to uer lsit*/ -+ list_add_tail(&(p_new_user->entry), p_user_list); -+ } -+ } else { -+ *p_id = 0; -+ i_ret = -ENOMEM; -+ BTIF_ERR_FUNC("allocate memory for mtk_btif_user failed\n"); -+ } -+ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); -+ BTIF_DBG_FUNC("--"); -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_open); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_close -+* DESCRIPTION -+* close BTIF interface, will do BTIF module HW and SW de-initialization -+* once this API is called, p_btif should never be used by BTIF's user again -+* PARAMETERS -+* u_id [IN] BTIF's user id -+* RETURNS -+* int 0 = succeed; -+* others = fail, -+* for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_close(unsigned long u_id) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ struct list_head *pos = NULL; -+ struct list_head *p_user_list = NULL; -+ -+ BTIF_DBG_FUNC("++"); -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ -+ if (mutex_lock_killable(&(p_btif->ops_mtx))) { -+ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); -+ return E_BTIF_INTR; -+ } -+ p_user_list = &(p_btif->user_list); -+ list_for_each(pos, p_user_list) { -+ p_mtk_btif_user p_user = -+ container_of(pos, mtk_btif_user, entry); -+ -+ if (p_user->u_id == u_id) { -+ BTIF_INFO_FUNC -+ ("user who's id is 0x%lx deleted from user list\n", -+ u_id); -+ list_del(pos); -+ vfree(p_user); -+ i_ret = btif_close(p_btif); -+ if (i_ret) -+ BTIF_WARN_FUNC("BTIF close failed"); -+ break; -+ } -+ } -+ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); -+ BTIF_DBG_FUNC("--"); -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_close); -+ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_write -+* DESCRIPTION -+* send data throuth BTIF module -+* there's no internal buffer to cache STP data in BTIF driver, -+* if in DMA mode -+* btif driver will check if there's enough space in vFIFO for data to send in DMA mode -+* if yes, put data to vFIFO and return corresponding data length to caller -+* if no, corresponding error code will be returned to called -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* p_buf [IN] pointer to target data to send -+* len [IN] data length (should be less than 2014 bytes per STP package) -+* -+* if in non-DMA mode, BTIF driver will try to write to THR of BTIF controller -+* if btif driver detected that no space is available in Tx FIFO, -+* will return E_BTIF_NO_SPACE, mostly something is wrong with BTIF or -+* consys when this return value is returned -+* RETURNS -+* int positive: data length send through BTIF; -+* negative: please see ENUM_BTIF_OP_ERROR_CODE -+* E_BTIF_AGAIN (0) will be returned to caller -+* if btif does not have enough vFIFO to send data, -+* when caller get 0, he should wait for a moment -+* (5~10ms maybe) and try a few times (maybe 10~20) -+* if still get E_BTIF_AGAIN, -+* should call BTIF's debug API and dump BTIF driver -+* and BTIF/DMA register information to kernel log for debug -+* E_BTIF_BAD_POINTER will be returned to caller -+* if btif is not opened successfully before call this API -+* E_BTIF_INVAL_PARAM will be returned if parameter is not valid -+ -+*****************************************************************************/ -+int mtk_wcn_btif_write(unsigned long u_id, -+ const unsigned char *p_buf, unsigned int len) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ BTIF_DBG_FUNC("++"); -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ if (p_buf == NULL) { -+ BTIF_ERR_FUNC("invalid p_buf (0x%p)\n", p_buf); -+ return E_BTIF_INVAL_PARAM; -+ } -+ if ((len == 0) || (len > BTIF_MAX_LEN_PER_PKT)) { -+ BTIF_ERR_FUNC("invalid buffer length(%d)\n", len); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ i_ret = btif_send_data(p_btif, p_buf, len); -+ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_write); -+ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_read -+* DESCRIPTION -+* read data from BTIF module -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* p_buf [IN/OUT] pointer to buffer where rx data will be put -+* max_len [IN] max buffer length -+* RETURNS -+* int positive: data length read from BTIF; -+* negative: please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_read(unsigned long u_id, -+ unsigned char *p_buf, unsigned int max_len) -+{ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_dpidle_ctrl -+* DESCRIPTION -+* control if BTIF module allow system enter deepidle state or not -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* en_flag [IN] one of ENUM_BTIF_DPIDLE_CTRL -+* RETURNS -+* int always return 0 -+*****************************************************************************/ -+int mtk_wcn_btif_dpidle_ctrl(unsigned long u_id, ENUM_BTIF_DPIDLE_CTRL en_flag) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ -+ if (en_flag == BTIF_DPIDLE_DISABLE) -+ i_ret = btif_exit_dpidle(p_btif); -+ else -+ i_ret = btif_enter_dpidle(p_btif); -+ -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_dpidle_ctrl); -+ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_rx_cb_register -+* DESCRIPTION -+* register rx callback function to BTIF module by btif user -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* rx_cb [IN] pointer to stp rx handler callback function, -+* should be comply with MTK_WCN_BTIF_RX_CB -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, -+* please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_rx_cb_register(unsigned long u_id, MTK_WCN_BTIF_RX_CB rx_cb) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ -+ i_ret = btif_rx_cb_reg(p_btif, rx_cb); -+ -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_rx_cb_register); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_wakeup_consys -+* DESCRIPTION -+* once sleep command is sent to con sys, -+* should call this API before send wakeup command -+* to make con sys aware host want to send data to consys -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* RETURNS -+* int 0 = succeed; others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_wakeup_consys(unsigned long u_id) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ -+/*i_ret = hal_btif_raise_wak_sig(p_btif->p_btif_info);*/ -+ i_ret = btif_raise_wak_signal(p_btif); -+ -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_wakeup_consys); -+ -+ -+/***************End of Normal Mode API declearation**********/ -+ -+/***************Debug Purpose API declearation**********/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_loopback_ctrl -+* DESCRIPTION -+* enable/disable BTIF internal loopback function, -+* when this function is enabled data send to btif -+* will be received by btif itself -+* only for debug purpose, should never use this function in normal mode -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* enable [IN] loopback mode control flag, enable or disable, -+* shou be one of ENUM_BTIF_LPBK_MODE -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_loopback_ctrl(unsigned long u_id, ENUM_BTIF_LPBK_MODE enable) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ i_ret = -+ btif_lpbk_ctrl(p_btif, enable == BTIF_LPBK_ENABLE ? true : false); -+ -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_loopback_ctrl); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_logger_ctrl -+* DESCRIPTION -+* control BTIF logger function's behavior -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* flag [IN] should be one of ENUM_BTIF_DBG_ID -+* BTIF_DISABLE_LOGGER - disable btif logger -+* BTIF_ENABLE_LOGGER - enable btif logger -+* BTIF_DUMP_LOG - dump log logged by btif -+* BTIF_CLR_LOG - clear btif log buffer -+* BTIF_DUMP_BTIF_REG - dump btif controller's register -+* BTIF_DUMP_DMA_REG - dump DMA controller's register -+* RETURNS -+* int 0 = succeed; others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_dbg_ctrl(unsigned long u_id, ENUM_BTIF_DBG_ID flag) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ -+ i_ret = 0; -+ switch (flag) { -+ case BTIF_DISABLE_LOGGER:{ -+ BTIF_INFO_FUNC -+ ("disable btif log function for both Tx and Rx\n"); -+ btif_log_buf_disable(&p_btif->tx_log); -+ btif_log_buf_disable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_ENABLE_LOGGER:{ -+ BTIF_INFO_FUNC -+ ("enable btif log function for both Tx and Rx\n"); -+ btif_log_buf_enable(&p_btif->tx_log); -+ btif_log_buf_enable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_DUMP_LOG:{ -+ BTIF_INFO_FUNC("dump btif log for both Tx and Rx\n"); -+ btif_log_buf_dmp_out(&p_btif->tx_log); -+ btif_log_buf_dmp_out(&p_btif->rx_log); -+ } -+ break; -+ -+ case BTIF_CLR_LOG:{ -+ BTIF_INFO_FUNC("clear btif log for both Tx and Rx\n"); -+ btif_log_buf_reset(&p_btif->tx_log); -+ btif_log_buf_reset(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_DUMP_BTIF_REG: -+ /*TBD*/ btif_dump_reg(p_btif); -+ break; -+ case BTIF_ENABLE_RT_LOG: -+ BTIF_INFO_FUNC -+ ("enable btif real time log for both Tx and Rx\n"); -+ btif_log_output_enable(&p_btif->tx_log); -+ btif_log_output_enable(&p_btif->rx_log); -+ break; -+ case BTIF_DISABLE_RT_LOG: -+ BTIF_INFO_FUNC -+ ("disable btif real time log for both Tx and Rx\n"); -+ btif_log_output_disable(&p_btif->tx_log); -+ btif_log_output_disable(&p_btif->rx_log); -+ break; -+ default: -+ BTIF_INFO_FUNC("not supported flag:%d\n", flag); -+ i_ret = -2; -+ break; -+ } -+ -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_dbg_ctrl); -+ -+bool mtk_wcn_btif_parser_wmt_evt(unsigned long u_id, -+ const char *sub_str, unsigned int str_len) -+{ -+ bool b_ret = false; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ b_ret = btif_parser_wmt_evt(p_btif, sub_str, str_len); -+ BTIF_INFO_FUNC("parser wmt evt %s\n", b_ret ? "ok" : "fail"); -+ -+ return b_ret; -+} -+ -+/**********End of Debug Purpose API declearation**********/ -+ -+int btif_open_no_id(void) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = btif_open(p_btif); -+ -+ if (i_ret) -+ BTIF_ERR_FUNC("btif_open failed, i_ret(%d)\n", i_ret); -+ else -+ BTIF_INFO_FUNC("btif_open succeed\n"); -+ -+ return i_ret; -+} -+ -+int btif_close_no_id(void) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = btif_close(p_btif); -+ -+ if (i_ret) -+ BTIF_ERR_FUNC("btif_close failed, i_ret(%d)\n", i_ret); -+ else -+ BTIF_INFO_FUNC("btif_close succeed\n"); -+ return i_ret; -+} -+ -+int btif_write_no_id(const unsigned char *p_buf, unsigned int len) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ BTIF_DBG_FUNC("++"); -+ -+ if (p_buf == NULL) { -+ BTIF_ERR_FUNC("invalid p_buf (0x%p)\n", p_buf); -+ return E_BTIF_INVAL_PARAM; -+ } -+ if ((len == 0) || (len > BTIF_MAX_LEN_PER_PKT)) { -+ BTIF_ERR_FUNC("invalid buffer length(%d)\n", len); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ i_ret = btif_send_data(p_btif, p_buf, len); -+ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); -+ return i_ret; -+} -+ -+int btif_dpidle_ctrl_no_id(ENUM_BTIF_DPIDLE_CTRL en_flag) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ if (en_flag == BTIF_DPIDLE_DISABLE) -+ i_ret = btif_exit_dpidle(p_btif); -+ else -+ i_ret = btif_enter_dpidle(p_btif); -+ -+ return i_ret; -+} -+ -+int btif_wakeup_consys_no_id(void) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+/*i_ret = hal_btif_raise_wak_sig(p_btif->p_btif_info);*/ -+ i_ret = btif_raise_wak_signal(p_btif); -+ -+ return i_ret; -+} -+ -+int btif_loopback_ctrl_no_id(ENUM_BTIF_LPBK_MODE enable) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = -+ btif_lpbk_ctrl(p_btif, enable == BTIF_LPBK_ENABLE ? true : false); -+ -+ return i_ret; -+} -+ -+int btif_dbg_ctrl_no_id(ENUM_BTIF_DBG_ID flag) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = 0; -+ switch (flag) { -+ case BTIF_DISABLE_LOGGER:{ -+ BTIF_INFO_FUNC -+ ("disable btif log function for both Tx and Rx\n"); -+ btif_log_buf_disable(&p_btif->tx_log); -+ btif_log_buf_disable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_ENABLE_LOGGER:{ -+ BTIF_INFO_FUNC -+ ("enable btif log function for both Tx and Rx\n"); -+ btif_log_buf_enable(&p_btif->tx_log); -+ btif_log_buf_enable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_DUMP_LOG:{ -+ BTIF_INFO_FUNC("dump btif log for both Tx and Rx\n"); -+ btif_log_buf_dmp_out(&p_btif->tx_log); -+ btif_log_buf_dmp_out(&p_btif->rx_log); -+ } -+ break; -+ -+ case BTIF_CLR_LOG:{ -+ BTIF_INFO_FUNC("clear btif log for both Tx and Rx\n"); -+ btif_log_buf_reset(&p_btif->tx_log); -+ btif_log_buf_reset(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_DUMP_BTIF_REG: -+ /*TBD*/ btif_dump_reg(p_btif); -+ break; -+ case BTIF_ENABLE_RT_LOG: -+ BTIF_INFO_FUNC -+ ("enable btif real time log for both Tx and Rx\n"); -+ btif_log_output_enable(&p_btif->tx_log); -+ btif_log_output_enable(&p_btif->rx_log); -+ break; -+ case BTIF_DISABLE_RT_LOG: -+ BTIF_INFO_FUNC -+ ("disable btif real time log for both Tx and Rx\n"); -+ btif_log_output_disable(&p_btif->tx_log); -+ btif_log_output_disable(&p_btif->rx_log); -+ break; -+ default: -+ BTIF_INFO_FUNC("not supported flag:%d\n", flag); -+ i_ret = -2; -+ break; -+ } -+ -+ return i_ret; -+} -+ -+int mtk_btif_exp_open_test(void) -+{ -+ int i_ret = 0; -+ -+ i_ret = btif_open_no_id(); -+ if (i_ret < 0) { -+ BTIF_INFO_FUNC("mtk_wcn_btif_open failed\n"); -+ return -1; -+ } -+ -+ BTIF_INFO_FUNC("mtk_wcn_btif_open succeed\n"); -+ -+ return i_ret; -+} -+ -+int mtk_btif_exp_close_test(void) -+{ -+ int i_ret = 0; -+ -+ i_ret = btif_close_no_id(); -+ if (i_ret < 0) { -+ BTIF_INFO_FUNC("mtk_wcn_btif_close failed\n"); -+ return -1; -+ } -+ -+ BTIF_INFO_FUNC("mtk_wcn_btif_close succeed\n"); -+ -+ return i_ret; -+} -+ -+int mtk_btif_exp_write_test(void) -+{ -+ return mtk_btif_exp_write_stress_test(100, 10); -+} -+ -+int mtk_btif_exp_write_stress_test(unsigned int length, unsigned int max_loop) -+{ -+#define BUF_LEN 1024 -+ int i_ret = 0; -+ int idx = 0; -+ int buf_len = length > BUF_LEN ? BUF_LEN : length; -+ int loop = max_loop > 1000000 ? 1000000 : max_loop; -+ unsigned char *buffer; -+ -+ buffer = kmalloc(BUF_LEN, GFP_KERNEL); -+ if (!buffer) { -+ BTIF_ERR_FUNC("btif tester kmalloc failed\n"); -+ return -1; -+ } -+ -+ for (idx = 0; idx < buf_len; idx++) -+ /* btif_stress_test_buf[idx] = BUF_LEN -idx; */ -+ *(buffer + idx) = idx % 255; -+ i_ret = btif_loopback_ctrl_no_id(BTIF_LPBK_ENABLE); -+ BTIF_INFO_FUNC("mtk_wcn_btif_loopback_ctrl returned %d\n", i_ret); -+ while (loop--) { -+ i_ret = btif_write_no_id(buffer, buf_len); -+ BTIF_INFO_FUNC("mtk_wcn_btif_write left loop:%d, i_ret:%d\n", -+ loop, i_ret); -+ if (i_ret != buf_len) { -+ BTIF_INFO_FUNC -+ ("mtk_wcn_btif_write failed, target len %d, sent len: %d\n", -+ buf_len, i_ret); -+ break; -+ } -+ buf_len--; -+ if (buf_len <= 0) -+ buf_len = length > BUF_LEN ? BUF_LEN : length; -+ } -+ kfree(buffer); -+ return i_ret; -+} -+ -+int mtk_btif_exp_suspend_test(void) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = _btif_suspend(p_btif); -+ return i_ret; -+} -+ -+int mtk_btif_exp_restore_noirq_test(void) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = _btif_restore_noirq(p_btif); -+ return i_ret; -+} -+ -+int mtk_btif_exp_clock_ctrl(int en) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = btif_clock_ctrl(p_btif, en); -+ return i_ret; -+} -+ -+int mtk_btif_exp_resume_test(void) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = _btif_resume(p_btif); -+ return i_ret; -+} -+ -+int mtk_btif_exp_enter_dpidle_test(void) -+{ -+ return btif_dpidle_ctrl_no_id(BTIF_DPIDLE_ENABLE); -+} -+ -+int mtk_btif_exp_exit_dpidle_test(void) -+{ -+ return btif_dpidle_ctrl_no_id(BTIF_DPIDLE_DISABLE); -+} -+ -+int mtk_btif_exp_log_debug_test(int flag) -+{ -+ int i_ret = 0; -+ -+ i_ret = btif_dbg_ctrl_no_id(flag); -+ return i_ret; -+} -+ -+void mtk_btif_read_cpu_sw_rst_debug_exp(void) -+{ -+ mtk_btif_read_cpu_sw_rst_debug(); -+} -+ -+/************End of Function**********/ -diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h -new file mode 100644 -index 0000000000000..97756f684ab40 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h -@@ -0,0 +1,164 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef __HAL_BTIF_DMA_H_ -+#define __HAL_BTIF_DMA_H_ -+ -+#include -+#include "btif_dma_pub.h" -+ -+#if defined(CONFIG_MTK_CLKMGR) -+#if defined(CONFIG_ARCH_MT6580) -+#define MTK_BTIF_APDMA_CLK_CG MT_CG_APDMA_SW_CG -+#elif defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753) -+#define MTK_BTIF_APDMA_CLK_CG MT_CG_PERI_APDMA -+#endif -+#else -+extern struct clk *clk_btif_apdma; /*btif apdma clock*/ -+#endif /* !defined(CONFIG_MTK_CLKMGR) */ -+ -+#define TX_DMA_VFF_SIZE (1024 * 8) /*Tx vFIFO Len must be 8 Byte allignment */ -+#define RX_DMA_VFF_SIZE (1024 * 8) /*Rx vFIFO Len must be 8 Byte allignment */ -+ -+#define DMA_TX_THRE(n) (n - 7) /*Tx Trigger Level */ -+#define DMA_RX_THRE(n) ((n) * 3 / 4) /*Rx Trigger Level */ -+ -+/**********************************Hardware related defination**************************/ -+#ifndef CONFIG_OF -+/*DMA channel's offset refer to AP_DMA's base address*/ -+#define BTIF_TX_DMA_OFFSET 0x880 -+#define BTIF_RX_DMA_OFFSET 0x900 -+#endif -+ -+/*Register Address Mapping*/ -+#define DMA_INT_FLAG_OFFSET 0x00 -+#define DMA_INT_EN_OFFSET 0x04 -+#define DMA_EN_OFFSET 0x08 -+#define DMA_RST_OFFSET 0x0C -+#define DMA_STOP_OFFSET 0x10 -+#define DMA_FLUSH_OFFSET 0x14 -+ -+#define DMA_BASE_OFFSET 0x1C -+#define DMA_LEN_OFFSET 0x24 -+ -+#define DMA_THRE_OFFSET 0x28 -+#define DMA_WPT_OFFSET 0x2C -+#define DMA_RPT_OFFSET 0x30 -+#define DMA_VALID_OFFSET 0x3C -+#define DMA_LEFT_OFFSET 0x40 -+#define DMA_VFF_BIT29_OFFSET 0x01 -+ -+#define TX_DMA_INT_FLAG(base) (unsigned long)(base + 0x0) /*BTIF Tx Virtual FIFO Interrupt Flag Register */ -+#define TX_DMA_INT_EN(base) (unsigned long)(base + 0x4) /*BTIF Tx Virtual FIFO Interrupt Enable Register */ -+#define TX_DMA_EN(base) (unsigned long)(base + DMA_EN_OFFSET)/*BTIF Tx Virtual FIFO Enable Register */ -+#define TX_DMA_RST(base) (unsigned long)(base + DMA_RST_OFFSET)/*BTIF Tx Virtual FIFO Reset Register */ -+#define TX_DMA_STOP(base) (unsigned long)(base + DMA_STOP_OFFSET)/*BTIF Tx Virtual FIFO STOP Register */ -+#define TX_DMA_FLUSH(base) (unsigned long)(base + DMA_FLUSH_OFFSET)/*BTIF Tx Virtual FIFO Flush Register */ -+#define TX_DMA_VFF_ADDR(base) (unsigned long)(base + 0x1C) /*BTIF Tx Virtual FIFO Base Address Register */ -+#define TX_DMA_VFF_LEN(base) (unsigned long)(base + 0x24) /*BTIF Tx Virtual FIFO Length Register */ -+#define TX_DMA_VFF_THRE(base) (unsigned long)(base + 0x28) /*BTIF Tx Virtual FIFO Threshold Register */ -+#define TX_DMA_VFF_WPT(base) (unsigned long)(base + 0x2C) /*BTIF Tx Virtual FIFO Write Pointer Register */ -+#define TX_DMA_VFF_RPT(base) (unsigned long)(base + 0x30) /*BTIF Tx Virtual FIFO Read Pointer Register */ -+#define TX_DMA_W_INT_BUF_SIZE(base) (unsigned long)(base + 0x34) -+/*BTIF Tx Virtual FIFO Internal Tx Write Buffer Size Register */ -+#define TX_DMA_INT_BUF_SIZE(base) (unsigned long)(base + 0x38) -+/*BTIF Tx Virtual FIFO Internal Tx Buffer Size Register */ -+ -+#define TX_DMA_VFF_VALID_SIZE(base) (unsigned long)(base + 0x3C) /*BTIF Tx Virtual FIFO Valid Size Register */ -+#define TX_DMA_VFF_LEFT_SIZE(base) (unsigned long)(base + 0x40) /*BTIF Tx Virtual FIFO Left Size Register */ -+#define TX_DMA_DEBUG_STATUS(base) (unsigned long)(base + 0x50) /*BTIF Tx Virtual FIFO Debug Status Register */ -+#define TX_DMA_VFF_ADDR_H(base) (unsigned long)(base + 0x54) /*BTIF Tx Virtual FIFO Base High Address Register */ -+ -+/*Rx Register Address Mapping*/ -+#define RX_DMA_INT_FLAG(base) (unsigned long)(base + 0x0) /*BTIF Rx Virtual FIFO Interrupt Flag Register */ -+#define RX_DMA_INT_EN(base) (unsigned long)(base + 0x4) /*BTIF Rx Virtual FIFO Interrupt Enable Register */ -+#define RX_DMA_EN(base) (unsigned long)(base + DMA_EN_OFFSET) /*BTIF Rx Virtual FIFO Enable Register */ -+#define RX_DMA_RST(base) (unsigned long)(base + DMA_RST_OFFSET) /*BTIF Rx Virtual FIFO Reset Register */ -+#define RX_DMA_STOP(base) (unsigned long)(base + DMA_STOP_OFFSET) /*BTIF Rx Virtual FIFO Stop Register */ -+#define RX_DMA_FLUSH(base) (unsigned long)(base + DMA_FLUSH_OFFSET) /*BTIF Rx Virtual FIFO Flush Register */ -+#define RX_DMA_VFF_ADDR(base) (unsigned long)(base + 0x1C) /*BTIF Rx Virtual FIFO Base Address Register */ -+#define RX_DMA_VFF_LEN(base) (unsigned long)(base + 0x24) /*BTIF Rx Virtual FIFO Length Register */ -+#define RX_DMA_VFF_THRE(base) (unsigned long)(base + 0x28) /*BTIF Rx Virtual FIFO Threshold Register */ -+#define RX_DMA_VFF_WPT(base) (unsigned long)(base + 0x2C) /*BTIF Rx Virtual FIFO Write Pointer Register */ -+#define RX_DMA_VFF_RPT(base) (unsigned long)(base + 0x30) /*BTIF Rx Virtual FIFO Read Pointer Register */ -+#define RX_DMA_FLOW_CTRL_THRE(base) (unsigned long)(base + 0x34) /*BTIF Rx Virtual FIFO Flow Control Register */ -+#define RX_DMA_INT_BUF_SIZE(base) (unsigned long)(base + 0x38) /*BTIF Rx Virtual FIFO Internal Buffer Register */ -+#define RX_DMA_VFF_VALID_SIZE(base) (unsigned long)(base + 0x3C) /*BTIF Rx Virtual FIFO Valid Size Register */ -+#define RX_DMA_VFF_LEFT_SIZE(base) (unsigned long)(base + 0x40) /*BTIF Rx Virtual FIFO Left Size Register */ -+#define RX_DMA_DEBUG_STATUS(base) (unsigned long)(base + 0x50) /*BTIF Rx Virtual FIFO Debug Status Register */ -+#define RX_DMA_VFF_ADDR_H(base) (unsigned long)(base + 0x54) /*BTIF Rx Virtual FIFO Base High Address Register */ -+ -+#define DMA_EN_BIT (0x1) -+#define DMA_STOP_BIT (0x1) -+#define DMA_RST_BIT (0x1) -+#define DMA_FLUSH_BIT (0x1) -+ -+#define DMA_WARM_RST (0x1 << 0) -+#define DMA_HARD_RST (0x1 << 1) -+ -+#define DMA_WPT_MASK (0x0000FFFF) -+#define DMA_WPT_WRAP (0x00010000) -+ -+#define DMA_RPT_MASK (0x0000FFFF) -+#define DMA_RPT_WRAP (0x00010000) -+ -+/*APDMA BTIF Tx Reg Ctrl Bit*/ -+#define TX_DMA_INT_FLAG_MASK (0x1) -+ -+#define TX_DMA_INTEN_BIT (0x1) -+ -+#define TX_DMA_ADDR_MASK (0xFFFFFFF8) -+#define TX_DMA_LEN_MASK (0x0000FFF8) -+ -+#define TX_DMA_THRE_MASK (0x0000FFFF) -+ -+#define TX_DMA_W_INT_BUF_MASK (0x000000FF) -+ -+#define TX_DMA_VFF_VALID_MASK (0x0000FFFF) -+#define TX_DMA_VFF_LEFT_MASK (0x0000FFFF) -+ -+/*APDMA BTIF Rx Reg Ctrl Bit*/ -+#define RX_DMA_INT_THRE (0x1 << 0) -+#define RX_DMA_INT_DONE (0x1 << 1) -+ -+#define RX_DMA_INT_THRE_EN (0x1 << 0) -+#define RX_DMA_INT_DONE_EN (0x1 << 1) -+ -+#define RX_DMA_ADDR_MASK (0xFFFFFFF8) -+#define RX_DMA_LEN_MASK (0x0000FFF8) -+ -+#define RX_DMA_THRE_MASK (0x0000FFFF) -+ -+#define RX_DMA_FLOW_CTRL_THRE_MASK (0x000000FF) -+ -+#define RX_DMA_INT_BUF_SIZE_MASK (0x0000001F) -+ -+#define RX_DMA_VFF_VALID_MASK (0x0000001F) -+ -+#define RX_DMA_VFF_LEFT_MASK (0x0000FFFF) -+ -+typedef struct _MTK_BTIF_DMA_VFIFO_ { -+ DMA_VFIFO vfifo; -+ unsigned int wpt; /*DMA's write pointer, which is maintained by SW for Tx DMA and HW for Rx DMA */ -+ unsigned int last_wpt_wrap; /*last wrap bit for wpt */ -+ unsigned int rpt; /*DMA's read pointer, which is maintained by HW for Tx DMA and SW for Rx DMA */ -+ unsigned int last_rpt_wrap; /*last wrap bit for rpt */ -+} MTK_BTIF_DMA_VFIFO, *P_MTK_BTIF_DMA_VFIFO; -+ -+/*for DMA debug purpose*/ -+typedef struct _MTK_BTIF_DMA_REG_DMP_DBG_ { -+ unsigned long reg_addr; -+ unsigned int reg_val; -+} MTK_BTIF_DMA_REG_DMP_DBG, *P_MTK_BTIF_DMA_REG_DMP_DBG; -+ -+#endif /*__HAL_BTIF_DMA_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h -new file mode 100644 -index 0000000000000..0773f2ce387ac ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h -@@ -0,0 +1,197 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef __HAL_BTIFD_DMA_PUB_H_ -+#define __HAL_BTIFD_DMA_PUB_H_ -+ -+#include -+ -+#include "plat_common.h" -+ -+typedef enum _ENUM_DMA_CTRL_ { -+ DMA_CTRL_DISABLE = 0, -+ DMA_CTRL_ENABLE = DMA_CTRL_DISABLE + 1, -+ DMA_CTRL_BOTH, -+} ENUM_DMA_CTRL; -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_info_get -+* DESCRIPTION -+* get btif tx dma channel's information -+* PARAMETERS -+* dma_dir [IN] DMA's direction -+* RETURNS -+* pointer to btif dma's information structure -+*****************************************************************************/ -+P_MTK_DMA_INFO_STR hal_btif_dma_info_get(ENUM_DMA_DIR dma_dir); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_dma_hw_init -+* DESCRIPTION -+* control clock output enable/disable of DMA module -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dma_hw_init(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_ctrl -+* DESCRIPTION -+* control clock output enable/disable of DMA module -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dma_clk_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_CLOCK_CTRL flag); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_ctrl -+* DESCRIPTION -+* enable/disable Tx DMA channel -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* ctrl_id [IN] enable/disable ID -+* dma_dir [IN] DMA's direction -+* RETURNS -+* 0 means success; negative means fail -+*****************************************************************************/ -+int hal_btif_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_dma_rx_cb_reg -+* DESCRIPTION -+* register rx callback function to dma module -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* rx_cb [IN] function pointer to btif -+* RETURNS -+* 0 means success; negative means fail -+*****************************************************************************/ -+int hal_btif_dma_rx_cb_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ dma_rx_buf_write rx_cb); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_vfifo_reset -+* DESCRIPTION -+* reset tx virtual fifo information, except memory information -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* dma_dir [IN] DMA's direction -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_vfifo_reset(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_irq_handler -+* DESCRIPTION -+* lower level tx interrupt handler -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_tx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_send_data -+* DESCRIPTION -+* send data through btif in DMA mode -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN] pointer to rx data buffer -+* max_len [IN] tx buffer length -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_dma_send_data(P_MTK_DMA_INFO_STR p_dma_info, -+ const unsigned char *p_buf, const unsigned int buf_len); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_is_tx_complete -+* DESCRIPTION -+* get tx complete flag -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* true means tx complete, false means tx in process -+*****************************************************************************/ -+bool hal_dma_is_tx_complete(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_get_ava_room -+* DESCRIPTION -+* get tx available room -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* available room size -+*****************************************************************************/ -+int hal_dma_get_ava_room(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_is_tx_allow -+* DESCRIPTION -+* is tx operation allowed by DMA -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* true if tx operation is allowed; false if tx is not allowed -+*****************************************************************************/ -+bool hal_dma_is_tx_allow(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_rx_dma_irq_handler -+* DESCRIPTION -+* lower level rx interrupt handler -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_rx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, const unsigned int max_len); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_dump_reg -+* DESCRIPTION -+* dump BTIF module's information when needed -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* flag [IN] register id flag -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ENUM_BTIF_REG_ID flag); -+ -+int hal_dma_pm_ops(P_MTK_DMA_INFO_STR p_dma_info, MTK_BTIF_PM_OPID opid); -+ -+#endif /*__HAL_BTIFD_DMA_PUB_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h -new file mode 100644 -index 0000000000000..51fe58a82b49c ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h -@@ -0,0 +1,105 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef __HAL_BTIF_H_ -+#define __HAL_BTIF_H_ -+ -+#ifndef CONFIG_OF -+#define MTK_BTIF_REG_BASE BTIF_BASE -+#endif -+ -+#if defined(CONFIG_MTK_CLKMGR) -+#if defined(CONFIG_ARCH_MT6580) -+#define MTK_BTIF_CG_BIT MT_CG_BTIF_SW_CG -+#elif defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753) -+#define MTK_BTIF_CG_BIT MT_CG_PERI_BTIF -+#endif -+#else -+struct clk *clk_btif_apdma; /*btif apdma clock*/ -+struct clk *clk_btif; /*btif clock*/ -+#endif /* !defined(CONFIG_MTK_CLKMGR) */ -+ -+#define BTIF_RBR(base) (unsigned long)(base + 0x0) /*RX Buffer Register: read only */ -+#define BTIF_THR(base) (unsigned long)(base + 0x0) /*Rx Holding Register: write only */ -+#define BTIF_IER(base) (unsigned long)(base + 0x4) /*Interrupt Enable Register: read/write */ -+#define BTIF_IIR(base) (unsigned long)(base + 0x8) /*Interrupt Identification Register: read only */ -+#define BTIF_FIFOCTRL(base) (unsigned long)(base + 0x8) /*FIFO Control Register: write only */ -+#define BTIF_FAKELCR(base) (unsigned long)(base + 0xC) /*FAKE LCR Register: read/write */ -+#define BTIF_LSR(base) (unsigned long)(base + 0x14) /*Line Status Register: read only */ -+#define BTIF_SLEEP_EN(base) (unsigned long)(base + 0x48) /*Sleep Enable Register: read/write */ -+#define BTIF_DMA_EN(base) (unsigned long)(base + 0x4C) /*DMA Enable Register: read/write */ -+#define BTIF_RTOCNT(base) (unsigned long)(base + 0x54) /*Rx Timeout Count Register: read/write */ -+#define BTIF_TRI_LVL(base) (unsigned long)(base + 0x60) /*Tx/Rx Trigger Level Control Register: read/write */ -+#define BTIF_WAK(base) (unsigned long)(base + 0x64) /*BTIF module wakeup Register: write only */ -+#define BTIF_WAT_TIME(base) (unsigned long)(base + 0x68) /*BTIF ASYNC Wait Time Control Register: read/write */ -+#define BTIF_HANDSHAKE(base) (unsigned long)(base + 0x6C) /*BTIF New Handshake Control Register: read/write */ -+ -+/*BTIF_IER bits*/ -+#define BTIF_IER_TXEEN (0x1 << 1) /*1: Tx holding register is empty */ -+#define BTIF_IER_RXFEN (0x1 << 0) /*1: Rx buffer contains data */ -+ -+/*BTIF_IIR bits*/ -+#define BTIF_IIR_NINT (0x1 << 0) /*No INT Pending */ -+#define BTIF_IIR_TX_EMPTY (0x1 << 1) /*Tx Holding Register empty */ -+#define BTIF_IIR_RX (0x1 << 2) /*Rx data received */ -+#define BTIF_IIR_RX_TIMEOUT (0x11 << 2) /*Rx data received */ -+ -+/*BTIF_LSR bits*/ -+#define BTIF_LSR_DR_BIT (0x1 << 0) -+#define BTIF_LSR_THRE_BIT (0x1 << 5) -+#define BTIF_LSR_TEMT_BIT (0x1 << 6) -+ -+/*BTIF_FIFOCTRL bits*/ -+#define BTIF_FIFOCTRL_CLR_TX (0x1 << 2) /*Clear Tx FIRO */ -+#define BTIF_FIFOCTRL_CLR_RX (0x1 << 1) /*Clear Rx FIRO */ -+ -+/*BTIF_FAKELCR bits*/ -+#define BTIF_FAKELCR_NORMAL_MODE 0x0 -+ -+/*BTIF_SLEEP_EN bits*/ -+#define BTIF_SLEEP_EN_BIT (0x1 << 0) /*enable Sleep mode */ -+#define BTIF_SLEEP_DIS_BIT (0x0) /*disable sleep mode */ -+ -+/*BTIF_DMA_EN bits*/ -+#define BTIF_DMA_EN_RX (0x1 << 0) /*Enable Rx DMA */ -+#define BTIF_DMA_EN_TX (0x1 << 1) /*Enable Tx DMA */ -+#define BTIF_DMA_EN_AUTORST_EN (0x1 << 2) /*1: timeout counter will be auto reset */ -+#define BTIF_DMA_EN_AUTORST_DIS (0x0 << 2) /* -+ * 0: after Rx timeout happens, -+ * SW shall reset the interrupt by reading BTIF 0x4C -+ */ -+ -+/*BTIF_TRI_LVL bits*/ -+#define BTIF_TRI_LVL_TX_MASK ((0xf) << 0) -+#define BTIF_TRI_LVL_RX_MASK ((0x7) << 4) -+ -+#define BTIF_TRI_LVL_TX(x) ((x & 0xf) << 0) -+#define BTIF_TRI_LVL_RX(x) ((x & 0x7) << 4) -+ -+#define BTIF_TRI_LOOP_EN (0x1 << 7) -+#define BTIF_TRI_LOOP_DIS (0x0 << 7) -+ -+/*BTIF_WAK bits*/ -+#define BTIF_WAK_BIT (0x1 << 0) -+ -+/*BTIF_HANDSHAKE bits*/ -+#define BTIF_HANDSHAKE_EN_HANDSHAKE 1 -+#define BTIF_HANDSHAKE_DIS_HANDSHAKE 0 -+ -+#define BTIF_TX_FIFO_SIZE 16 -+#define BTIF_RX_FIFO_SIZE 8 -+ -+#define BTIF_TX_FIFO_THRE (BTIF_TX_FIFO_SIZE / 2) -+#define BTIF_RX_FIFO_THRE 0x1 /* 0x5 */ -+ -+#endif /*__HAL_BTIF_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h -new file mode 100644 -index 0000000000000..1555d5a50c384 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h -@@ -0,0 +1,237 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef __HAL_BTIF_PUB_H_ -+#define __HAL_BTIF_PUB_H_ -+ -+#include "plat_common.h" -+ -+/*Enum Defination*/ -+/*BTIF Mode Enum */ -+typedef enum _ENUM_BTIF_MODE_ { -+ BTIF_MODE_PIO = 0, -+ BTIF_MODE_DMA = BTIF_MODE_PIO + 1, -+ BTIF_MODE_MAX, -+} ENUM_BTIF_MODE; -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_info_get -+* DESCRIPTION -+* get btif's information included base address , irq related information -+* PARAMETERS -+* RETURNS -+* BTIF's information -+*****************************************************************************/ -+P_MTK_BTIF_INFO_STR hal_btif_info_get(void); -+ -+#if 0 /*included in hal_btif_info_get */ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_get_irq -+* DESCRIPTION -+* get BTIF module's IRQ information -+* PARAMETERS -+* RETURNS -+* pointer to BTIF's irq structure -+*****************************************************************************/ -+P_MTK_BTIF_IRQ_STR hal_btif_get_irq(void); -+#endif -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_get_and_prepare -+* DESCRIPTION -+* get clock from device tree and prepare for enable/disable control -+* PARAMETERS -+* pdev device pointer -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_clk_get_and_prepare(struct platform_device *pdev); -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_unprepare -+* DESCRIPTION -+* unprepare btif clock and apdma clock -+* PARAMETERS -+* none -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_clk_unprepare(void); -+#endif -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_ctrl -+* DESCRIPTION -+* control clock output enable/disable of BTIF module -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_clk_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_CLOCK_CTRL flag); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_hw_init -+* DESCRIPTION -+* BTIF module init, after this step, BTIF should enable to do tx/rx with PIO -+* mode -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_hw_init(P_MTK_BTIF_INFO_STR p_btif); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_cb_reg -+* DESCRIPTION -+* BTIF rx callback register API -+* PARAMETERS -+* p_btif_info [IN] pointer to BTIF's information -+* rx_cb [IN] rx callback function -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_rx_cb_reg(P_MTK_BTIF_INFO_STR p_btif_info, -+ btif_rx_buf_write rx_cb); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_loopback_ctrl -+* DESCRIPTION -+* BTIF Tx/Rx loopback mode set, this operation can only be done -+* after set BTIF to normal mode -+* PARAMETERS -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_loopback_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_handler -+* DESCRIPTION -+* lower level interrupt handler -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* 0 means success; negative means fail; positive means rx data length -+*****************************************************************************/ -+int hal_btif_irq_handler(P_MTK_BTIF_INFO_STR p_btif, -+ unsigned char *p_buf, const unsigned int max_len); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_tx_mode_ctrl -+* DESCRIPTION -+* set BTIF tx to corresponding mode (PIO/DMA) -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* mode [IN] rx mode -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_tx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_mode_ctrl -+* DESCRIPTION -+* set BTIF rx to corresponding mode (PIO/DMA) -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* mode [IN] rx mode -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_rx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_send_data -+* DESCRIPTION -+* send data through btif in FIFO mode -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN] pointer to rx data buffer -+* max_len [IN] tx buffer length -+* RETURNS -+* positive means number of data sent; -+* 0 means no data put to FIFO; -+* negative means error happens -+*****************************************************************************/ -+int hal_btif_send_data(P_MTK_BTIF_INFO_STR p_btif, -+ const unsigned char *p_buf, const unsigned int buf_len); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_raise_wak_sig -+* DESCRIPTION -+* raise wakeup signal to counterpart -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_raise_wak_sig(P_MTK_BTIF_INFO_STR p_btif); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_dump_reg -+* DESCRIPTION -+* dump BTIF module's information when needed -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* flag [IN] register id flag -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dump_reg(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_REG_ID flag); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_is_tx_complete -+* DESCRIPTION -+* get tx complete flag -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* true means tx complete, false means tx in process -+*****************************************************************************/ -+bool hal_btif_is_tx_complete(P_MTK_BTIF_INFO_STR p_btif); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_is_tx_allow -+* DESCRIPTION -+* whether tx is allowed -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* true if tx operation is allowed; false if tx is not allowed -+*****************************************************************************/ -+bool hal_btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif); -+ -+int hal_btif_pm_ops(P_MTK_BTIF_INFO_STR p_btif, MTK_BTIF_PM_OPID opid); -+ -+void mtk_btif_read_cpu_sw_rst_debug_plat(void); -+ -+#endif /*__HAL_BTIF_PUB_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h b/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h -new file mode 100644 -index 0000000000000..2a1462cb32ff4 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h -@@ -0,0 +1,307 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef __HAL_PUB_H_ -+#define __HAL_PUB_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_OF -+#include -+#include -+#include -+#else -+#include -+#include -+#endif -+#if defined(CONFIG_MTK_CLKMGR) -+#include -+#else -+#include -+#include -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+#include -+ -+extern int mtk_btif_hal_get_log_lvl(void); -+ -+#define MTK_BTIF_MARK_UNUSED_API -+ -+typedef irq_handler_t mtk_btif_irq_handler; -+ -+#define MTK_BTIF_ENABLE_CLK_CTL 1 -+#define MTK_BTIF_ENABLE_CLK_REF_COUNTER 1 -+ -+#define DBG_LOG_STR_SIZE 256 -+ -+/*Log defination*/ -+static int hal_log_print(const char *str, ...) -+{ -+ va_list args; -+ char temp_sring[DBG_LOG_STR_SIZE]; -+ -+ va_start(args, str); -+ vsnprintf(temp_sring, DBG_LOG_STR_SIZE, str, args); -+ va_end(args); -+ -+ pr_err("%s", temp_sring); -+ -+ return 0; -+} -+ -+#define BTIF_LOG_LOUD 4 -+#define BTIF_LOG_DBG 3 -+#define BTIF_LOG_INFO 2 -+#define BTIF_LOG_WARN 1 -+#define BTIF_LOG_ERR 0 -+ -+#ifndef DFT_TAG -+#define DFT_TAG "[BTIF-DFT]" -+#endif -+ -+#define BTIF_LOUD_FUNC(fmt, arg ...) \ -+do { \ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_LOUD) \ -+ hal_log_print(DFT_TAG "[L]%s:" fmt, \ -+ __func__, ## arg); \ -+} while (0) -+ -+#define BTIF_INFO_FUNC(fmt, arg ...) \ -+do { \ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_INFO)\ -+ hal_log_print(DFT_TAG "[I]%s:" fmt, \ -+ __func__, ## arg); \ -+} while (0) -+ -+#define BTIF_WARN_FUNC(fmt, arg ...) \ -+do { \ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_WARN)\ -+ hal_log_print(DFT_TAG "[W]%s:" fmt, \ -+ __func__, ## arg); \ -+} while (0) -+ -+#define BTIF_ERR_FUNC(fmt, arg ...)\ -+do {\ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_ERR)\ -+ hal_log_print(DFT_TAG "[E]%s(%d):" fmt,\ -+ __func__, __LINE__, ## arg);\ -+} while (0) -+ -+#define BTIF_DBG_FUNC(fmt, arg ...) \ -+do { \ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_DBG) \ -+ hal_log_print(DFT_TAG "[D]%s:" fmt, \ -+ __func__, ## arg); \ -+} while (0) -+ -+#define BTIF_TRC_FUNC(f) \ -+do { \ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_DBG) \ -+ hal_log_print(DFT_TAG "<%s> <%d>\n", \ -+ __func__, __LINE__); \ -+} while (0) -+ -+/*-----------------------------------Enum Defination--------------------------------*/ -+/*IRQ sensetive type */ -+typedef enum _ENUM_IRQ_SENS_TYPE_ { -+ IRQ_SENS_EDGE = 0, -+ IRQ_SENS_LVL = IRQ_SENS_EDGE + 1, -+ IRQ_SENS_TYPE_MAX -+} ENUM_IRQ_SENS_TYPE; -+ -+/*IRQ level trigger type */ -+typedef enum _ENUM_IRQ_LVL_TYPE_ { -+ IRQ_LVL_LOW = 0, -+ IRQ_LVL_HIGH = IRQ_LVL_LOW + 1, -+ IRQ_LVL_MAX -+} ENUM_IRQ_LVL; -+ -+/*IRQ edge trigger type */ -+typedef enum _ENUM_IRQ_EDGE_TYPE_ { -+ IRQ_EDGE_FALL = 0, -+ IRQ_EDGE_RAISE = IRQ_EDGE_FALL + 1, -+ IRQ_EDGE_BOTH = IRQ_EDGE_RAISE + 1, -+ IRQ_EDGE_MAX -+} ENUM_IRQ_EDGE; -+ -+typedef enum _ENUM_CLOCK_CTRL_ { -+ CLK_OUT_DISABLE = 0, -+ CLK_OUT_ENABLE = CLK_OUT_DISABLE + 1, -+ CLK_OUT_MAX -+} ENUM_CLOCK_CTRL; -+ -+/*Error No. table */ -+typedef enum _ENUM_ERROR_CODE_ { -+ ERR_NO_ERROR = 0, -+ ERR_INVALID_PAR = ERR_NO_ERROR - 1, -+ ERR_MAX = ERR_INVALID_PAR - 1, -+} ENUM_ERROR_CODE; -+ -+typedef enum _ENUM_BTIF_DIR_ { -+ BTIF_TX = 0, -+ BTIF_RX = BTIF_TX + 1, -+ BTIF_DIR_MAX, -+} ENUM_BTIF_DIR; -+ -+typedef enum _ENUM_DMA_DIR_ { -+ DMA_DIR_RX = 0, -+ DMA_DIR_TX = DMA_DIR_RX + 1, -+ DMA_DIR_BOTH, -+} ENUM_DMA_DIR; -+ -+typedef enum _ENUM_BTIF_REG_ID_ { -+ REG_IIR = 0, /*Interrupt Identification Register */ -+ REG_LSR = 1, /*Line Status Register */ -+ REG_FAKE_LCR = 2, /*Fake Lcr Regiseter */ -+ REG_FIFO_CTRL = 3, /*FIFO Control Register */ -+ REG_IER = 4, /*Interrupt Enable Register */ -+ REG_SLEEP_EN = 5, /*Sleep Enable Register */ -+ REG_RTO_COUNTER = 6, /*Rx Timeout Counter Register */ -+ REG_DMA_EN = 7, /*DMA Enalbe Register */ -+ REG_TRIG_LVL = 8, /*Tx/Rx Trigger Level Register */ -+ REG_WAT_TIME = 9, /*Async Wait Time Register */ -+ REG_HANDSHAKE = 10, /*New HandShake Mode Register */ -+ REG_SLP_WAK = 11, /*Sleep Wakeup Reigster */ -+ REG_BTIF_ALL = 12, /*all btif controller's registers */ -+ REG_TX_DMA_ALL = 13, -+ REG_RX_DMA_ALL = 14, -+ REG_MAX -+} ENUM_BTIF_REG_ID; -+ -+typedef enum _MTK_BTIF_PM_OPID_ { -+ BTIF_PM_DPIDLE_EN, -+ BTIF_PM_DPIDLE_DIS, -+ BTIF_PM_SUSPEND, -+ BTIF_PM_RESUME, -+ BTIF_PM_RESTORE_NOIRQ, -+} MTK_BTIF_PM_OPID; -+ -+#define BTIF_HAL_TX_FIFO_SIZE (1024 * 4) -+ -+/*-----------------------------------Enum Defination End--------------------------------*/ -+ -+/*****************************structure definition***************************/ -+/*IRQ related information*/ -+typedef struct _MTK_BTIF_IRQ_STR_ { -+ const char *name; -+ bool is_irq_sup; -+ unsigned int irq_id; -+#ifdef CONFIG_OF -+ unsigned int irq_flags; -+#else -+ ENUM_IRQ_SENS_TYPE sens_type; -+ union { -+ ENUM_IRQ_LVL lvl_type; -+ ENUM_IRQ_EDGE edge_type; -+ }; -+#endif -+ bool reg_flag; -+ irq_handler_t p_irq_handler; -+} MTK_BTIF_IRQ_STR, *P_MTK_BTIF_IRQ_STR; -+ -+typedef struct _DMA_VFIFO_ { -+ /*[Driver Access] vFIFO memory'svirtual address */ -+ unsigned char *p_vir_addr; -+ /*[HW Access] dma handle , physically address, set to DMA's HW Register */ -+ dma_addr_t phy_addr; -+ /*DMA's vFIFO size */ -+ unsigned int vfifo_size; -+ /*DMA's threshold value */ -+ unsigned int thre; -+} DMA_VFIFO, *P_DMA_VFIFO; -+ -+typedef unsigned int (*dma_rx_buf_write) (void *p_dma_info, -+ unsigned char *p_buf, -+ unsigned int buf_len); -+typedef unsigned int (*btif_rx_buf_write) (void *p_btif_info, -+ unsigned char *p_buf, -+ unsigned int buf_len); -+ -+/*DMA related information*/ -+typedef struct _MTK_DMA_INFO_STR_ { -+ unsigned long base; -+ ENUM_DMA_DIR dir; -+ P_MTK_BTIF_IRQ_STR p_irq; -+ dma_rx_buf_write rx_cb; -+ P_DMA_VFIFO p_vfifo; -+} MTK_DMA_INFO_STR, *P_MTK_DMA_INFO_STR; -+ -+/*DMA related information*/ -+typedef struct _MTK_BTIF_INFO_STR_ { -+ unsigned long base; /*base address */ -+ P_MTK_BTIF_IRQ_STR p_irq; /*irq related information */ -+ -+ unsigned int tx_fifo_size; /*BTIF tx FIFO size */ -+ unsigned int rx_fifo_size; /*BTIF rx FIFO size */ -+ -+ unsigned int tx_tri_lvl; /*BTIFtx trigger level in FIFO mode */ -+ unsigned int rx_tri_lvl; /*BTIFrx trigger level in FIFO mode */ -+ -+ unsigned int clk_gat_addr; /*clock gating address */ -+ unsigned int set_bit; /*enable clock gating bit */ -+ unsigned int clr_bit; /*clear clock gating bit */ -+ -+ unsigned int rx_data_len; /*rx data length */ -+ -+ btif_rx_buf_write rx_cb; -+ -+ struct kfifo *p_tx_fifo; /*tx fifo */ -+ spinlock_t tx_fifo_spinlock; /*tx fifo spinlock */ -+} MTK_BTIF_INFO_STR, *P_MTK_BTIF_INFO_STR; -+ -+/**********End of Structure Definition***********/ -+ -+/***********register operation***********/ -+#ifdef __KERNEL__ -+/*byte write <1 byte> */ -+#define btif_reg_sync_writeb(v, a) mt_reg_sync_writeb(v, a) -+/*word write <2 byte> */ -+#define btif_reg_sync_writew(v, a) mt_reg_sync_writew(v, a) -+/*long write <4 byte> */ -+#define btif_reg_sync_writel(v, a) mt_reg_sync_writel(v, a) -+#else -+/*byte write <1 byte> */ -+#define btif_reg_sync_writeb(v, a) mt65xx_reg_sync_writeb(v, a) -+/*word write <2 byte> */ -+#define btif_reg_sync_writew(v, a) mt65xx_reg_sync_writew(v, a) -+/*long write <4 byte> */ -+#define btif_reg_sync_writel(v, a) mt65xx_reg_sync_writel(v, a) -+#endif -+#define BTIF_READ8(REG) __raw_readb((unsigned char *)(REG)) -+#define BTIF_READ16(REG) __raw_readw((unsigned short *)(REG)) -+#define BTIF_READ32(REG) __raw_readl((unsigned int *)(REG)) -+ -+#define BTIF_SET_BIT(REG, BITVAL) do { \ -+*((volatile unsigned int *)(REG)) |= ((unsigned int)(BITVAL)); \ -+mb(); /**/ \ -+} \ -+while (0) -+#define BTIF_CLR_BIT(REG, BITVAL) do { \ -+(*(volatile unsigned int *)(REG)) &= ~((unsigned int)(BITVAL)); \ -+mb(); /**/\ -+} \ -+while (0) -+ -+/***********end of register operation *********/ -+ -+#endif /*__HAL_PUB_H_*/ -diff --git a/drivers/misc/mediatek/connectivity/Kconfig b/drivers/misc/mediatek/connectivity/Kconfig -new file mode 100644 -index 0000000000000..4a944b1f0ebe5 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/Kconfig -@@ -0,0 +1,299 @@ -+config MTK_COMBO -+ tristate "MediaTek Connectivity Combo Chip Support" -+ help -+ MTK connectivity combo chip driver for MT66xx -+ -+# -+# MTK Combo Chip Selection -+# -+ -+choice -+ prompt "Select Chip" -+ depends on MTK_COMBO -+ -+config MTK_COMBO_CHIP_MT6620 -+ bool "MT6620" -+ help -+ this config is used to decided combo chip version -+ in current platform -+ is -+ MT6620 -+ -+config MTK_COMBO_CHIP_MT6628 -+ bool "MT6628" -+ help -+ this config is used to decided combo chip version -+ in current platform -+ is -+ MT6628 -+ -+config MTK_COMBO_CHIP_MT6630 -+ bool "MT6630" -+ help -+ this config is used to decided combo chip version -+ in current platform -+ is -+ MT6630 -+ -+config MTK_COMBO_CHIP_CONSYS_6572 -+ bool "CONSYS_6572" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6572 -+ -+config MTK_COMBO_CHIP_CONSYS_6582 -+ bool "CONSYS_6582" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6582 -+ -+config MTK_COMBO_CHIP_CONSYS_8127 -+ bool "CONSYS_8127" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6572 -+ -+config MTK_COMBO_CHIP_CONSYS_7623 -+ bool "CONSYS_7623" -+ #select MTK_PLATFORM::="mt7623" -+ help -+ this config is used to decide SOC consys version -+ in current platform is MT7623 and prepare proper -+ system services like radio power on/off and firmware -+ download for the Bluetotoh and Wifi. -+ -+ -+config MTK_COMBO_CHIP_CONSYS_6752 -+ bool "CONSYS_6752" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6752 -+ -+config MTK_COMBO_CHIP_CONSYS_6592 -+ bool "CONSYS_6592" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6592 -+ -+config MTK_COMBO_CHIP_CONSYS_8163 -+ bool "CONSYS_8163" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT8163 -+ -+config MTK_COMBO_CHIP_CONSYS_6735 -+ bool "CONSYS_6735" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6735 -+ -+config MTK_COMBO_CHIP_CONSYS_6755 -+ bool "CONSYS_6755" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6755 -+ -+config MTK_COMBO_CHIP_CONSYS_6580 -+ bool "CONSYS_6580" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6580 -+ -+config MTK_COMBO_CHIP_CONSYS_6797 -+ bool "CONSYS_6797" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6797 -+endchoice -+ -+config MTK_COMBO_CHIP -+ string -+ default "MT6620" if MTK_COMBO_CHIP_MT6620 -+ default "MT6628" if MTK_COMBO_CHIP_MT6628 -+ default "MT6630" if MTK_COMBO_CHIP_MT6630 -+ default "CONSYS_6572" if MTK_COMBO_CHIP_CONSYS_6572 -+ default "CONSYS_6582" if MTK_COMBO_CHIP_CONSYS_6582 -+ default "CONSYS_8127" if MTK_COMBO_CHIP_CONSYS_8127 -+ default "CONSYS_7623" if MTK_COMBO_CHIP_CONSYS_7623 -+ default "CONSYS_6752" if MTK_COMBO_CHIP_CONSYS_6752 -+ default "CONSYS_6755" if MTK_COMBO_CHIP_CONSYS_6755 -+ default "CONSYS_6592" if MTK_COMBO_CHIP_CONSYS_6592 -+ default "CONSYS_8163" if MTK_COMBO_CHIP_CONSYS_8163 -+ default "CONSYS_6735" if MTK_COMBO_CHIP_CONSYS_6735 -+ default "CONSYS_6580" if MTK_COMBO_CHIP_CONSYS_6580 -+ default "CONSYS_6797" if MTK_COMBO_CHIP_CONSYS_6797 -+ help -+ this feature is used to identify combo chip version or SOC chip -+ consys version. -+ -+# -+# Target Platform Selection -+# -+config MTK_COMBO_PLAT_PATH -+ string "Platform folder name" -+ depends on MTK_COMBO -+ default "sample" if MTK_COMBO_PLAT_SAMPLE -+ help -+ Specify platform folder under common driver platform folder: -+ mtk_wcn_combo/common/platform/* -+ -+# -+# MTK COMBO Chip Configuration -+# -+config MTK_COMBO_COMM -+ depends on MTK_COMBO -+ tristate "MediaTek Combo Chip Common part driver" -+ help -+ MediaTek combo chip common part driver -+ -+#config MTK_COMBO_COMM_PS -+# depends on MTK_COMBO_COMM -+# bool "Enable PS support" -+# default n -+# help -+# Enable PS support of common UART interface -+ -+config MTK_COMBO_COMM_UART -+ depends on MTK_COMBO_COMM -+ tristate "Common interface UART" -+ help -+ Use UART for common part interface type -+ -+config MTK_COMBO_COMM_SDIO -+ depends on MTK_COMBO_COMM -+ tristate "Common interface SDIO" -+ help -+ Use SDIO for common part interface type -+ -+config MTK_COMBO_COMM_NPWR -+ depends on MTK_COMBO_COMM -+ bool "Enable NPWR support" -+ default n -+ help -+ Enable NPWR support of new power on swquence -+ -+config MTK_COMBO_COMM_APO -+ depends on MTK_COMBO_COMM -+ bool "Enable always power on support" -+ #default y -+ help -+ Enable chip will always power on -+ -+config MTK_COMBO_BT -+ tristate "MediaTek Combo Chip BT driver" -+ depends on BT && MTK_COMBO -+ select MTK_BTIF -+ help -+ MTK BT /dev/stpbt driver for Bluedroid -+ -+config MTK_COMBO_BT_HCI -+ tristate "MediaTek Combo Chip BlueZ driver" -+ depends on BT && MTK_COMBO -+ select MTK_BTIF -+ help -+ MTK BT driver for BlueZ -+ -+config MTK_COMBO_WIFI -+ tristate "MediaTek combo chip Wi-Fi support" -+ depends on MTK_COMBO -+ select MTK_BTIF -+ select WIRELESS_EXT -+ select WEXT_PRIV -+ -+config MTK_WAPI_SUPPORT -+ bool "MTK_WAPI_SUPPORT" -+ depends on MTK_COMBO_WIFI -+ #default y -+ help -+ if it is set to TRUE: Support WAPI (WLAN Authentication and -+ Privacy Infrastructure) -+ -+config MTK_PASSPOINT_R1_SUPPORT -+ bool "MTK_PASSPOINT_R1_SUPPORT" -+ depends on MTK_COMBO_WIFI -+ help -+ Support Passpoint R1 (Hotspot 2.0 R1) -+ -+config MTK_PASSPOINT_R2_SUPPORT -+ bool "MTK_PASSPOINT_R2_SUPPORT" -+ depends on MTK_COMBO_WIFI -+ help -+ Support Passpoint R2 -+ -+config MTK_WIFI_MCC_SUPPORT -+ bool "MTK_WIFI_MCC_SUPPORT" -+ depends on MTK_COMBO_WIFI -+ #default y -+ help -+ if it is set to TRUE, wlan will support Multi-Channel Concurrency, -+ otherwise, only support Single Channel Concurrency -+ -+config MTK_DHCPV6C_WIFI -+ bool "MTK_DHCPV6C_WIFI" -+ help -+ no: disable this feature -+ -+config MTK_CONN_LTE_IDC_SUPPORT -+ bool "MediaTek CONN LTE IDC support" -+ select MTK_CONN_MD -+ #default y -+ help -+ This option enables CONN LTE IDC support -+ -+menuconfig GPS -+ tristate "GPS drivers" -+ #default y -+ ---help--- -+ Say Y here for supporting GPS. -+ -+if GPS -+config MTK_GPS -+ tristate "MediaTek GPS driver" -+ #default y -+ ---help--- -+ MTK GPS driver -+ To switch gps nmea port driver. -+ Set "yes" to turn on. -+ Set "no" to turn off. -+endif # GPS -+ -+config MTK_GPS_SUPPORT -+ tristate "MediaTek GPS driver" -+ select MTK_GPS -+ help -+ to switch GPS feature on the platform. -+ Set "yes" to turn on and set "no" -+ (with MTK_AGPS_APP=no at the same time) -+ to turn off. -+ -+config MTK_GPS_REGISTER_SETTING -+ tristate "MediaTek GPS Register Setting" -+ depends on MTK_COMBO_GPS -+ help -+ GPS register settings. -+ -+config MTK_GPS_EMI -+ tristate "MediaTek GPS EMI Driver" -+ depends on MTK_COMBO_GPS -+ help -+ GPS EMI driver is for MNL OFFLOAD feature. -diff --git a/drivers/misc/mediatek/connectivity/Makefile b/drivers/misc/mediatek/connectivity/Makefile -new file mode 100644 -index 0000000000000..0947788d189a8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/Makefile -@@ -0,0 +1,41 @@ -+# -+# Copyright (C) 2015 MediaTek Inc. -+# -+# 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. -+# -+# 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. -+# -+ -+# Connectivity combo driver -+# If KERNELRELEASE is defined, we've been invoked from the -+# kernel build system and can use its language. -+ifneq ($(KERNELRELEASE),) -+subdir-ccflags-y += -D MTK_WCN_REMOVE_KERNEL_MODULE -+ifeq ($(CONFIG_ARM64), y) -+subdir-ccflags-y += -D CONFIG_MTK_WCN_ARM64 -+endif -+ -+ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y) -+ subdir-ccflags-y += -D WMT_IDC_SUPPORT=1 -+else -+ subdir-ccflags-y += -D WMT_IDC_SUPPORT=0 -+endif -+ subdir-ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ -+ obj-y += common/ -+ obj-$(CONFIG_MTK_COMBO_WIFI) += wlan/ -+ obj-n := dummy.o -+ -+# Otherwise we were called directly from the command line; -+# invoke the kernel build system. -+else -+ KERNELDIR ?= /lib/modules/$(shell uname -r)/build -+ PWD := $(shell pwd) -+default: -+ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/Makefile b/drivers/misc/mediatek/connectivity/common/Makefile -new file mode 100644 -index 0000000000000..622b74430e132 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/Makefile -@@ -0,0 +1,23 @@ -+subdir-ccflags-y += -Werror -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include -+subdir-ccflags-y += -Werror -I$(srctree)/drivers/misc/mediatek/include/mt-plat -+ -+#ifneq ($(filter "MT6620E3",$(CONFIG_MTK_COMBO_CHIP)),) -+# obj-y += combo/ -+#endif -+#ifneq ($(filter "MT6628",$(CONFIG_MTK_COMBO_CHIP)),) -+# subdir-ccflags-y += -D MT6628 -+# subdir-ccflags-y += -D MERGE_INTERFACE_SUPPORT -+# obj-y += combo/ -+#endif -+#ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) -+# subdir-ccflags-y += -D MT6630 -+#ifneq ($(CONFIG_ARCH_MT2601),y) -+# subdir-ccflags-y += -D MERGE_INTERFACE_SUPPORT -+#endif -+# obj-y += combo/ -+#endif -+ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) -+ obj-y += conn_soc/ -+endif -+ -+obj-y += common_detect/ -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/Makefile b/drivers/misc/mediatek/connectivity/common/common_detect/Makefile -new file mode 100644 -index 0000000000000..8d7dc690affd2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/Makefile -@@ -0,0 +1,47 @@ -+subdir-ccflags-y += -I$(srctree)/arch/arm/mach-$(MTK_PLATFORM)/$(ARCH_MTK_PROJECT)/dct/dct -+subdir-ccflags-y += -DWMT_PLAT_ALPS=1 -+ -+COMBO_CHIP_SUPPORT := false -+ifneq ($(filter "MT6620E3",$(CONFIG_MTK_COMBO_CHIP)),) -+ COMBO_CHIP_SUPPORT := true -+endif -+ifneq ($(filter "MT6628",$(CONFIG_MTK_COMBO_CHIP)),) -+ COMBO_CHIP_SUPPORT := true -+endif -+ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) -+ COMBO_CHIP_SUPPORT := true -+endif -+ifeq ($(COMBO_CHIP_SUPPORT), true) -+ subdir-ccflags-y += -D MTK_WCN_COMBO_CHIP_SUPPORT -+ ccflags-y += -I$(src)/../combo/linux/include -+endif -+ -+ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) -+ subdir-ccflags-y += -D MTK_WCN_SOC_CHIP_SUPPORT -+ ccflags-y += -I$(src)/../conn_soc/linux/include -+endif -+ -+ -+ifeq ($(CONFIG_MTK_COMBO),y) -+ ccflags-y += -I$(src)/drv_init/inc -+ obj-y += mtk_wcn_stub_alps.o -+ obj-y += wmt_stp_exp.o -+ obj-y += wmt_gpio.o -+ -+ obj-y += wmt_detect.o -+ obj-y += sdio_detect.o -+ obj-y += wmt_detect_pwr.o -+ -+ obj-y += drv_init/ -+endif -+ -+ifeq ($(CONFIG_MTK_COMBO),m) -+ obj-y += mtk_wcn_stub_alps.o -+ obj-y += wmt_stp_exp.o -+ obj-y += wmt_gpio.o -+ -+ obj-$(CONFIG_MTK_COMBO) += mtk_wmt_detect.o -+ mtk_wmt_detect-objs := wmt_detect.o -+ mtk_wmt_detect-objs += sdio_detect.o -+ mtk_wmt_detect-objs += wmt_detect_pwr.o -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile -new file mode 100644 -index 0000000000000..bb84384b9a24f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile -@@ -0,0 +1,22 @@ -+ifeq ($(CONFIG_MTK_COMBO),y) -+ ccflags-y += -I$(src)/inc/ -+ ccflags-y += -I$(src)/../ -+ -+ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) -+ ccflags-y += -D MTK_WCN_WLAN_GEN3 -+endif -+ifneq ($(filter "CONSYS_6797",$(CONFIG_MTK_COMBO_CHIP)),) -+ ccflags-y += -D MTK_WCN_WLAN_GEN3 -+else ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) -+ ccflags-y += -D MTK_WCN_WLAN_GEN2 -+endif -+ -+ obj-y += conn_drv_init.o -+ obj-y += common_drv_init.o -+ obj-y += bluetooth_drv_init.o -+ obj-y += gps_drv_init.o -+ obj-y += fm_drv_init.o -+ obj-y += wlan_drv_init.o -+ obj-($(CONFIG_MTK_COMBO_ANT)) += ant_drv_init.o -+ -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c -new file mode 100644 -index 0000000000000..aa453f9397a47 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c -@@ -0,0 +1,38 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[ANT-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "ant_drv_init.h" -+ -+int do_ant_drv_init(int chip_id) -+{ -+ int i_ret = -1; -+ -+ WMT_DETECT_INFO_FUNC("start to do ANT driver init\n"); -+ switch (chip_id) { -+ case 0x6630: -+ case 0x6797: -+ i_ret = mtk_wcn_stpant_drv_init(); -+ WMT_DETECT_INFO_FUNC("finish ANT driver init, i_ret:%d\n", i_ret); -+ break; -+ default: -+ WMT_DETECT_ERR_FUNC("chipid is not 6630,ANT is not supported!\n"); -+ } -+ return i_ret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c -new file mode 100644 -index 0000000000000..47b0554334433 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c -@@ -0,0 +1,35 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[BT-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "bluetooth_drv_init.h" -+ -+int do_bluetooth_drv_init(int chip_id) -+{ -+ int i_ret = -1; -+ -+#if defined(CONFIG_MTK_COMBO_BT) || defined(CONFIG_MTK_COMBO_BT_HCI) -+ WMT_DETECT_INFO_FUNC("start to do bluetooth driver init\n"); -+ i_ret = mtk_wcn_stpbt_drv_init(); -+ WMT_DETECT_INFO_FUNC("finish bluetooth driver init, i_ret:%d\n", i_ret); -+#else -+ WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_BT is not defined\n"); -+#endif -+ return i_ret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c -new file mode 100644 -index 0000000000000..f9c332ea266b9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c -@@ -0,0 +1,103 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "common_drv_init.h" -+ -+static int do_combo_common_drv_init(int chip_id) -+{ -+ int i_ret = 0; -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ int i_ret_tmp = 0; -+ -+ WMT_DETECT_DBG_FUNC("start to do combo driver init, chipid:0x%08x\n", chip_id); -+ -+ /* HIF-SDIO driver init */ -+ i_ret_tmp = mtk_wcn_hif_sdio_drv_init(); -+ i_ret += i_ret_tmp; -+ WMT_DETECT_DBG_FUNC("HIF-SDIO driver init, i_ret:%d\n", i_ret); -+ -+ /* WMT driver init */ -+ i_ret_tmp = mtk_wcn_combo_common_drv_init(); -+ i_ret += i_ret_tmp; -+ WMT_DETECT_DBG_FUNC("COMBO COMMON driver init, i_ret:%d\n", i_ret); -+ -+ /* STP-UART driver init */ -+ i_ret_tmp = mtk_wcn_stp_uart_drv_init(); -+ i_ret += i_ret_tmp; -+ WMT_DETECT_DBG_FUNC("STP-UART driver init, i_ret:%d\n", i_ret); -+ -+ /* STP-SDIO driver init */ -+ i_ret_tmp = mtk_wcn_stp_sdio_drv_init(); -+ i_ret += i_ret_tmp; -+ WMT_DETECT_DBG_FUNC("STP-SDIO driver init, i_ret:%d\n", i_ret); -+ -+#else -+ i_ret = -1; -+ WMT_DETECT_ERR_FUNC("COMBO chip is not supported, please check CONFIG_MTK_COMBO_CHIP in kernel config\n"); -+#endif -+ WMT_DETECT_DBG_FUNC("finish combo driver init\n"); -+ return i_ret; -+} -+ -+static int do_soc_common_drv_init(int chip_id) -+{ -+ int i_ret = 0; -+ -+#ifdef MTK_WCN_SOC_CHIP_SUPPORT -+ int i_ret_tmp = 0; -+ -+ WMT_DETECT_DBG_FUNC("start to do soc common driver init, chipid:0x%08x\n", chip_id); -+ -+ /* WMT driver init */ -+ i_ret_tmp = mtk_wcn_soc_common_drv_init(); -+ i_ret += i_ret_tmp; -+ WMT_DETECT_DBG_FUNC("COMBO COMMON driver init, i_ret:%d\n", i_ret); -+ -+#else -+ i_ret = -1; -+ WMT_DETECT_ERR_FUNC("SOC chip is not supported, please check CONFIG_MTK_COMBO_CHIP in kernel config\n"); -+#endif -+ -+ WMT_DETECT_DBG_FUNC("TBD........\n"); -+ return i_ret; -+} -+ -+int do_common_drv_init(int chip_id) -+{ -+ int i_ret = 0; -+ -+ WMT_DETECT_INFO_FUNC("start to do common driver init, chipid:0x%08x\n", chip_id); -+ -+ switch (chip_id) { -+ case 0x6620: -+ case 0x6628: -+ case 0x6630: -+ i_ret = do_combo_common_drv_init(chip_id); -+ break; -+ default: -+ i_ret = do_soc_common_drv_init(chip_id); -+ break; -+ } -+ -+ WMT_DETECT_INFO_FUNC("finish common driver init\n"); -+ -+ return i_ret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c -new file mode 100644 -index 0000000000000..8112d2a1d95e2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c -@@ -0,0 +1,80 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WCN-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "conn_drv_init.h" -+#include "common_drv_init.h" -+#include "fm_drv_init.h" -+#include "wlan_drv_init.h" -+#include "bluetooth_drv_init.h" -+#include "gps_drv_init.h" -+#include "ant_drv_init.h" -+ -+int __weak do_wlan_drv_init(int chip_id) -+{ -+ WMT_DETECT_ERR_FUNC("Can not find wlan module for chip: %d !\n", chip_id); -+ return 0; -+} -+ -+int __weak do_ant_drv_init(int chip_id) -+{ -+ WMT_DETECT_DBG_FUNC("Chip: %d can not support ANT !\n", chip_id); -+ return 0; -+} -+ -+int do_connectivity_driver_init(int chip_id) -+{ -+ int i_ret = 0; -+ int tmp_ret = 0; -+ -+ tmp_ret = do_common_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) { -+ WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret); -+ WMT_DETECT_ERR_FUNC("abort connectivity driver init, because common part is not ready\n"); -+ return i_ret; -+ } -+ -+ tmp_ret = do_bluetooth_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) -+ WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret); -+ -+ tmp_ret = do_gps_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) -+ WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret); -+ -+ tmp_ret = do_fm_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) -+ WMT_DETECT_ERR_FUNC("do fm module init failed, ret:%d\n", tmp_ret); -+ -+ tmp_ret = do_wlan_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) -+ WMT_DETECT_ERR_FUNC("do wlan module init failed, ret:%d\n", tmp_ret); -+ -+ tmp_ret = do_ant_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) -+ WMT_DETECT_ERR_FUNC("do ANT module init failed, ret:%d\n", tmp_ret); -+ -+ return i_ret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c -new file mode 100644 -index 0000000000000..069c1cf13bbaf ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c -@@ -0,0 +1,33 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[FM-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "fm_drv_init.h" -+ -+int do_fm_drv_init(int chip_id) -+{ -+ WMT_DETECT_INFO_FUNC("start to do fm module init\n"); -+ -+#ifdef CONFIG_MTK_FMRADIO -+ mtk_wcn_fm_init(); -+#endif -+ -+ WMT_DETECT_INFO_FUNC("finish fm module init\n"); -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c -new file mode 100644 -index 0000000000000..6da1d70a3ca65 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c -@@ -0,0 +1,35 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[GPS-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "gps_drv_init.h" -+ -+int do_gps_drv_init(int chip_id) -+{ -+ int i_ret = -1; -+#ifdef CONFIG_MTK_COMBO_GPS -+ WMT_DETECT_INFO_FUNC("start to do gps driver init\n"); -+ i_ret = mtk_wcn_stpgps_drv_init(); -+ WMT_DETECT_INFO_FUNC("finish gps driver init, i_ret:%d\n", i_ret); -+#else -+ WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_GPS is not defined\n"); -+#endif -+ return i_ret; -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h -new file mode 100644 -index 0000000000000..4a436a2362900 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h -@@ -0,0 +1,20 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef _ANT_DRIVER_INIT_H_ -+#define _ANT_DRIVER_INIT_H_ -+ -+extern int do_ant_drv_init(int chip_id); -+extern int mtk_wcn_stpant_drv_init(void); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h -new file mode 100644 -index 0000000000000..8a847d361fc8c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h -@@ -0,0 +1,20 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef _BLUETOOTH_DRIVER_INIT_H_ -+#define _BLUETOOTH_DRIVER_INIT_H_ -+ -+extern int do_bluetooth_drv_init(int chip_id); -+extern int mtk_wcn_stpbt_drv_init(void); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h -new file mode 100644 -index 0000000000000..ea01bd633c3c4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h -@@ -0,0 +1,31 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef _COMMON_DRV_INIT_H_ -+#define _COMMON_DRV_INIT_H_ -+extern int do_common_drv_init(int chip_id); -+ -+/*defined in common part driver*/ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+extern int mtk_wcn_combo_common_drv_init(void); -+extern int mtk_wcn_hif_sdio_drv_init(void); -+extern int mtk_wcn_stp_uart_drv_init(void); -+extern int mtk_wcn_stp_sdio_drv_init(void); -+#endif -+ -+#ifdef MTK_WCN_SOC_CHIP_SUPPORT -+extern int mtk_wcn_soc_common_drv_init(void); -+#endif -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h -new file mode 100644 -index 0000000000000..971193eade9e9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h -@@ -0,0 +1,18 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef _CONNECTIVITY_DRV_INIT_H_ -+#define _CONNECTIVITY_DRV_INIT_H_ -+extern int do_connectivity_driver_init(int chip_id); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h -new file mode 100644 -index 0000000000000..f6ea30addc5da ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h -@@ -0,0 +1,20 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef _FM_DRV_INIT_H_ -+#define _FM_DRV_INIT_H_ -+extern int do_fm_drv_init(int chip_id); -+extern int mtk_wcn_fm_init(void); -+extern void mtk_wcn_fm_exit(void); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h -new file mode 100644 -index 0000000000000..006ce072c53b6 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h -@@ -0,0 +1,19 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef _GPS_DRIVER_INIT_H_ -+#define _GPS_DRIVER_INIT_H_ -+extern int do_gps_drv_init(int chip_id); -+extern int mtk_wcn_stpgps_drv_init(void); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h -new file mode 100644 -index 0000000000000..cb71b50bf950d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h -@@ -0,0 +1,30 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef _WLAN_DRV_INIT_H_ -+#define _WLAN_DRV_INIT_H_ -+ -+ -+extern int do_wlan_drv_init(int chip_id); -+ -+extern int mtk_wcn_wmt_wifi_init(void); -+ -+#ifdef MTK_WCN_WLAN_GEN2 -+extern int mtk_wcn_wlan_gen2_init(void); -+#endif -+#ifdef MTK_WCN_WLAN_GEN3 -+extern int mtk_wcn_wlan_gen3_init(void); -+#endif -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c -new file mode 100644 -index 0000000000000..5b0d039a4a425 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c -@@ -0,0 +1,74 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WLAN-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "wlan_drv_init.h" -+ -+ -+int do_wlan_drv_init(int chip_id) -+{ -+ int i_ret = 0; -+ -+#ifdef CONFIG_MTK_COMBO_WIFI -+ int ret = 0; -+ -+ WMT_DETECT_INFO_FUNC("start to do wlan module init 0x%x\n", chip_id); -+ -+ /* WMT-WIFI char dev init */ -+ ret = mtk_wcn_wmt_wifi_init(); -+ WMT_DETECT_INFO_FUNC("WMT-WIFI char dev init, ret:%d\n", ret); -+ i_ret += ret; -+ -+ switch (chip_id) { -+ case 0x6630: -+ case 0x6797: -+#ifdef MTK_WCN_WLAN_GEN3 -+ /* WLAN driver init */ -+ ret = mtk_wcn_wlan_gen3_init(); -+ WMT_DETECT_INFO_FUNC("WLAN-GEN3 driver init, ret:%d\n", ret); -+ i_ret += ret; -+#else -+ WMT_DETECT_ERR_FUNC("WLAN-GEN3 driver is not supported, please check CONFIG_MTK_COMBO_CHIP\n"); -+ i_ret = -1; -+#endif -+ break; -+ -+ default: -+#ifdef MTK_WCN_WLAN_GEN2 -+ /* WLAN driver init */ -+ ret = mtk_wcn_wlan_gen2_init(); -+ WMT_DETECT_INFO_FUNC("WLAN-GEN2 driver init, ret:%d\n", ret); -+ i_ret += ret; -+#else -+ WMT_DETECT_ERR_FUNC("WLAN-GEN2 driver is not supported, please check CONFIG_MTK_COMBO_CHIP\n"); -+ i_ret = -1; -+#endif -+ break; -+ } -+ -+ WMT_DETECT_INFO_FUNC("finish wlan module init\n"); -+ -+#else -+ -+ WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_WIFI is not defined\n"); -+ -+#endif -+ -+ return i_ret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c b/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c -new file mode 100644 -index 0000000000000..fa8d437686f2d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c -@@ -0,0 +1,605 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define CMB_STUB_DBG_LOG 3 -+#define CMB_STUB_INFO_LOG 2 -+#define CMB_STUB_WARN_LOG 1 -+ -+int gCmbStubLogLevel = CMB_STUB_INFO_LOG; -+ -+#define CMB_STUB_LOG_INFO(fmt, arg...) \ -+do { \ -+ if (gCmbStubLogLevel >= CMB_STUB_INFO_LOG) \ -+ pr_warn(fmt, ##arg); \ -+} while (0) -+#define CMB_STUB_LOG_WARN(fmt, arg...) \ -+do { \ -+ if (gCmbStubLogLevel >= CMB_STUB_WARN_LOG) \ -+ pr_warn(fmt, ##arg); \ -+} while (0) -+#define CMB_STUB_LOG_DBG(fmt, arg...) \ -+do { \ -+ if (gCmbStubLogLevel >= CMB_STUB_DBG_LOG) \ -+ pr_debug(fmt, ##arg); \ -+} while (0) -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "wmt_detect.h" -+ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 0 -+#endif -+ -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+struct work_struct *g_sdio_1v_autok_wk = NULL; -+#endif -+int gConnectivityChipId = -1; -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+/* -+* current used uart port name, default is "ttyMT2", -+* will be changed when wmt driver init -+*/ -+char *wmt_uart_port_desc = "ttyMT2"; -+EXPORT_SYMBOL(wmt_uart_port_desc); -+#endif -+ -+static void mtk_wcn_cmb_sdio_request_eirq(msdc_sdio_irq_handler_t irq_handler, void *data); -+static void mtk_wcn_cmb_sdio_enable_eirq(void); -+static void mtk_wcn_cmb_sdio_disable_eirq(void); -+static void mtk_wcn_cmb_sdio_register_pm(pm_callback_t pm_cb, void *data); -+ -+struct sdio_ops mt_sdio_ops[4] = { -+ {NULL, NULL, NULL, NULL}, -+ {NULL, NULL, NULL, NULL}, -+ {mtk_wcn_cmb_sdio_request_eirq, mtk_wcn_cmb_sdio_enable_eirq, -+ mtk_wcn_cmb_sdio_disable_eirq, mtk_wcn_cmb_sdio_register_pm}, -+ {mtk_wcn_cmb_sdio_request_eirq, mtk_wcn_cmb_sdio_enable_eirq, -+ mtk_wcn_cmb_sdio_disable_eirq, mtk_wcn_cmb_sdio_register_pm} -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+static wmt_aif_ctrl_cb cmb_stub_aif_ctrl_cb; -+static wmt_func_ctrl_cb cmb_stub_func_ctrl_cb; -+static wmt_thermal_query_cb cmb_stub_thermal_ctrl_cb; -+static CMB_STUB_AIF_X cmb_stub_aif_stat = CMB_STUB_AIF_0; -+static wmt_deep_idle_ctrl_cb cmb_stub_deep_idle_ctrl_cb; -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+static wmt_get_drv_status cmb_stub_drv_status_ctrl_cb; -+#endif -+static wmt_func_do_reset cmb_stub_do_reset_cb; -+/* A temp translation table between COMBO_AUDIO_STATE_X and CMB_STUB_AIF_X. -+ * This is used for ALPS backward compatible ONLY!!! Remove this table, related -+ * functions, and type definition after modifying other kernel built-in modules, -+ * such as AUDIO. [FixMe][GeorgeKuo] -+ */ -+#if 0 -+static CMB_STUB_AIF_X audio2aif[] = { -+ [COMBO_AUDIO_STATE_0] = CMB_STUB_AIF_0, -+ [COMBO_AUDIO_STATE_1] = CMB_STUB_AIF_1, -+ [COMBO_AUDIO_STATE_2] = CMB_STUB_AIF_2, -+ [COMBO_AUDIO_STATE_3] = CMB_STUB_AIF_3, -+}; -+#endif -+static msdc_sdio_irq_handler_t mtk_wcn_cmb_sdio_eirq_handler; -+static atomic_t sdio_claim_irq_enable_flag; -+static atomic_t irq_enable_flag; -+static pm_callback_t mtk_wcn_cmb_sdio_pm_cb; -+static void *mtk_wcn_cmb_sdio_pm_data; -+static void *mtk_wcn_cmb_sdio_eirq_data; -+ -+static u32 wifi_irq = 0xffffffff; -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+static void mtk_wcn_cmb_stub_1v_autok_work(struct work_struct *work) -+{ -+ CMB_STUB_LOG_WARN("++enter++\n"); -+ mtk_wcn_cmb_stub_func_ctrl(11, 1); -+ mtk_wcn_cmb_stub_func_ctrl(11, 0); -+ CMB_STUB_LOG_WARN("--exit--\n"); -+} -+ -+/*! -+ * \brief A function for Getting current driver status:on/off -+ * -+ * \param driver type:0/bt,1/fm,2/gps,3/wifi,11/autok->run wmt turn on/off wifi flow -+ * -+ * \retval 0/off,2/on,-1/null pointer -+ */ -+static int mtk_wcn_cmb_stub_drv_status(unsigned int type) -+{ -+ int ret = -1; -+ -+ if (cmb_stub_drv_status_ctrl_cb) -+ ret = (*cmb_stub_drv_status_ctrl_cb) (type); -+ else -+ CMB_STUB_LOG_WARN("cmb_stub_drv_status_ctrl_cb is NULL\n"); -+ return ret; -+} -+ -+/*! -+ * \brief A 1v AutoK function for kernel DVFS driver calling when screen off -+ * -+ * \param void -+ * -+ * \retval int,mt6630 state:0/off,1/power on,2/func on, -1/null -+ */ -+int mtk_wcn_cmb_stub_1vautok_for_dvfs(void) -+{ -+ int wmt_status; -+ -+ CMB_STUB_LOG_WARN("DVFS driver call sdio 1v autok\n"); -+ -+ wmt_status = mtk_wcn_cmb_stub_drv_status(4); -+ CMB_STUB_LOG_WARN("current mt6630 status is %d\n", wmt_status); -+ if (0 == wmt_status) { -+ if (g_sdio_1v_autok_wk) -+ schedule_work(g_sdio_1v_autok_wk); -+ else -+ CMB_STUB_LOG_WARN("g_sdio_1v_autok_wk is NULL\n"); -+ } else if ((2 == wmt_status) || (1 == wmt_status)) { -+ CMB_STUB_LOG_WARN("mt6630 is on state,skip AUTOK\n"); -+ } else { -+ CMB_STUB_LOG_WARN("mt6630 is unknown state(%d)\n", wmt_status); -+ } -+ -+ return wmt_status; -+ -+} -+#endif -+/*! -+ * \brief A registration function for WMT-PLAT to register itself to CMB-STUB. -+ * -+ * An MTK-WCN-CMB-STUB registration function provided to WMT-PLAT to register -+ * itself and related callback functions when driver being loaded into kernel. -+ * -+ * \param p_stub_cb a pointer carrying CMB_STUB_CB information -+ * -+ * \retval 0 operation success -+ * \retval -1 invalid parameters -+ */ -+int mtk_wcn_cmb_stub_reg(P_CMB_STUB_CB p_stub_cb) -+{ -+ if ((!p_stub_cb) -+ || (p_stub_cb->size != sizeof(CMB_STUB_CB))) { -+ CMB_STUB_LOG_WARN("[cmb_stub] invalid p_stub_cb:0x%p size(%d)\n", -+ p_stub_cb, (p_stub_cb) ? p_stub_cb->size : 0); -+ return -1; -+ } -+ -+ CMB_STUB_LOG_DBG("[cmb_stub] registered, p_stub_cb:0x%p size(%d)\n", p_stub_cb, p_stub_cb->size); -+ -+ cmb_stub_aif_ctrl_cb = p_stub_cb->aif_ctrl_cb; -+ cmb_stub_func_ctrl_cb = p_stub_cb->func_ctrl_cb; -+ cmb_stub_thermal_ctrl_cb = p_stub_cb->thermal_query_cb; -+ cmb_stub_deep_idle_ctrl_cb = p_stub_cb->deep_idle_ctrl_cb; -+ cmb_stub_do_reset_cb = p_stub_cb->wmt_do_reset_cb; -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+ cmb_stub_drv_status_ctrl_cb = p_stub_cb->get_drv_status_cb; -+ g_sdio_1v_autok_wk = vmalloc(sizeof(struct work_struct)); -+ if (!g_sdio_1v_autok_wk) -+ CMB_STUB_LOG_WARN("vmalloc work_struct(%zd) fail\n", sizeof(struct work_struct)); -+ else -+ INIT_WORK(g_sdio_1v_autok_wk, mtk_wcn_cmb_stub_1v_autok_work); -+ -+#endif -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_cmb_stub_reg); -+/*! -+ * \brief A unregistration function for WMT-PLAT to unregister from CMB-STUB. -+ * -+ * An MTK-WCN-CMB-STUB unregistration function provided to WMT-PLAT to -+ * unregister itself and clear callback function references. -+ * -+ * \retval 0 operation success -+ */ -+int mtk_wcn_cmb_stub_unreg(void) -+{ -+ cmb_stub_aif_ctrl_cb = NULL; -+ cmb_stub_func_ctrl_cb = NULL; -+ cmb_stub_thermal_ctrl_cb = NULL; -+ cmb_stub_deep_idle_ctrl_cb = NULL; -+ cmb_stub_do_reset_cb = NULL; -+ CMB_STUB_LOG_INFO("[cmb_stub] unregistered\n"); /* KERN_DEBUG */ -+ -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+ if (g_sdio_1v_autok_wk) { -+ vfree(g_sdio_1v_autok_wk); -+ g_sdio_1v_autok_wk = NULL; -+ } -+#endif -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_cmb_stub_unreg); -+ -+/* stub functions for kernel to control audio path pin mux */ -+int mtk_wcn_cmb_stub_aif_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl) -+{ -+ int ret; -+ -+ if ((CMB_STUB_AIF_MAX <= state) -+ || (CMB_STUB_AIF_CTRL_MAX <= ctrl)) { -+ -+ CMB_STUB_LOG_WARN("[cmb_stub] aif_ctrl invalid (%d, %d)\n", state, ctrl); -+ return -1; -+ } -+ -+ /* avoid the early interrupt before we register the eirq_handler */ -+ if (cmb_stub_aif_ctrl_cb) { -+ ret = (*cmb_stub_aif_ctrl_cb) (state, ctrl); -+ CMB_STUB_LOG_INFO("[cmb_stub] aif_ctrl_cb state(%d->%d) ctrl(%d) ret(%d)\n", -+ cmb_stub_aif_stat, state, ctrl, ret); /* KERN_DEBUG */ -+ -+ cmb_stub_aif_stat = state; -+ } else { -+ CMB_STUB_LOG_WARN("[cmb_stub] aif_ctrl_cb null\n"); -+ ret = -2; -+ } -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_cmb_stub_aif_ctrl); -+ -+/* Use a temp translation table between COMBO_AUDIO_STATE_X and CMB_STUB_AIF_X -+ * for ALPS backward compatible ONLY!!! Remove this table, related functions, -+ * and type definition after modifying other kernel built-in modules, such as -+ * AUDIO. [FixMe][GeorgeKuo] -+ */ -+ -+void mtk_wcn_cmb_stub_func_ctrl(unsigned int type, unsigned int on) -+{ -+ if (cmb_stub_func_ctrl_cb) -+ (*cmb_stub_func_ctrl_cb) (type, on); -+ else -+ CMB_STUB_LOG_WARN("[cmb_stub] func_ctrl_cb null\n"); -+} -+EXPORT_SYMBOL(mtk_wcn_cmb_stub_func_ctrl); -+ -+int mtk_wcn_cmb_stub_query_ctrl(void) -+{ -+ signed long temp = 0; -+ -+ if (cmb_stub_thermal_ctrl_cb) -+ temp = (*cmb_stub_thermal_ctrl_cb) (); -+ else -+ CMB_STUB_LOG_WARN("[cmb_stub] thermal_ctrl_cb null\n"); -+ -+ return temp; -+} -+ -+/*platform-related APIs*/ -+/* void clr_device_working_ability(UINT32 clockId, MT6573_STATE state); */ -+/* void set_device_working_ability(UINT32 clockId, MT6573_STATE state); */ -+ -+static int _mt_combo_plt_do_deep_idle(COMBO_IF src, int enter) -+{ -+ int ret = -1; -+ -+#if 0 -+ if (src != COMBO_IF_UART && src != COMBO_IF_MSDC && src != COMBO_IF_BTIF) { -+ CMB_STUB_LOG_WARN("src = %d is error\n", src); -+ return ret; -+ } -+ if (src >= 0 && src < COMBO_IF_MAX) -+ CMB_STUB_LOG_INFO("src = %s, to enter deep idle? %d\n", combo_if_name[src], enter); -+#endif -+ /*TODO: For Common SDIO configuration, we need to do some judgement between STP and WIFI -+ to decide if the msdc will enter deep idle safely */ -+ -+ switch (src) { -+ case COMBO_IF_UART: -+ if (enter == 0) { -+ /* clr_device_working_ability(MT65XX_PDN_PERI_UART3, DEEP_IDLE_STATE); */ -+ /* disable_dpidle_by_bit(MT65XX_PDN_PERI_UART2); */ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+#if 0 -+ ret = mtk_uart_pdn_enable(wmt_uart_port_desc, 0); -+ if (ret < 0) -+ CMB_STUB_LOG_WARN("[CMB] %s exit deep idle failed\n", wmt_uart_port_desc); -+#endif -+#endif -+ } else { -+ /* set_device_working_ability(MT65XX_PDN_PERI_UART3, DEEP_IDLE_STATE); */ -+ /* enable_dpidle_by_bit(MT65XX_PDN_PERI_UART2); */ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+#if 0 -+ ret = mtk_uart_pdn_enable(wmt_uart_port_desc, 1); -+ if (ret < 0) -+ CMB_STUB_LOG_WARN("[CMB] %s enter deep idle failed\n", wmt_uart_port_desc); -+#endif -+#endif -+ } -+ ret = 0; -+ break; -+ -+ case COMBO_IF_MSDC: -+ if (enter == 0) { -+ /* for common sdio hif */ -+ /* clr_device_working_ability(MT65XX_PDN_PERI_MSDC2, DEEP_IDLE_STATE); */ -+ } else { -+ /* for common sdio hif */ -+ /* set_device_working_ability(MT65XX_PDN_PERI_MSDC2, DEEP_IDLE_STATE); */ -+ } -+ ret = 0; -+ break; -+ -+ case COMBO_IF_BTIF: -+ if (cmb_stub_deep_idle_ctrl_cb) -+ ret = (*cmb_stub_deep_idle_ctrl_cb) (enter); -+ else -+ CMB_STUB_LOG_WARN("NULL function pointer\n"); -+ -+ if (ret) -+ CMB_STUB_LOG_WARN("%s deep idle fail(%d)\n", enter == 1 ? "enter" : "exit", ret); -+ else -+ CMB_STUB_LOG_DBG("%s deep idle ok(%d)\n", enter == 1 ? "enter" : "exit", ret); -+ break; -+ default: -+ break; -+ } -+ -+ return ret; -+} -+ -+int mt_combo_plt_enter_deep_idle(COMBO_IF src) -+{ -+ /* return 0; */ -+ /* TODO: [FixMe][GeorgeKuo] handling this depends on common UART or common SDIO */ -+ return _mt_combo_plt_do_deep_idle(src, 1); -+} -+EXPORT_SYMBOL(mt_combo_plt_enter_deep_idle); -+ -+int mt_combo_plt_exit_deep_idle(COMBO_IF src) -+{ -+ /* return 0; */ -+ /* TODO: [FixMe][GeorgeKuo] handling this depends on common UART or common SDIO */ -+ return _mt_combo_plt_do_deep_idle(src, 0); -+} -+EXPORT_SYMBOL(mt_combo_plt_exit_deep_idle); -+ -+int mtk_wcn_wmt_chipid_query(void) -+{ -+ return gConnectivityChipId; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_chipid_query); -+ -+void mtk_wcn_wmt_set_chipid(int chipid) -+{ -+ CMB_STUB_LOG_INFO("set current consys chipid (0x%x)\n", chipid); -+ gConnectivityChipId = chipid; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_set_chipid); -+ -+int mtk_wcn_cmb_stub_do_reset(unsigned int type) -+{ -+ if (cmb_stub_do_reset_cb) -+ return (*cmb_stub_do_reset_cb) (type); -+ else -+ return -1; -+} -+EXPORT_SYMBOL(mtk_wcn_cmb_stub_do_reset); -+ -+static void mtk_wcn_cmb_sdio_enable_eirq(void) -+{ -+ if (atomic_read(&irq_enable_flag)) -+ CMB_STUB_LOG_DBG("wifi eint has been enabled\n"); -+ else { -+ atomic_set(&irq_enable_flag, 1); -+ if (wifi_irq != 0xfffffff) { -+ enable_irq(wifi_irq); -+ CMB_STUB_LOG_DBG(" enable WIFI EINT irq %d !!\n", wifi_irq); -+ } -+ } -+} -+ -+static void mtk_wcn_cmb_sdio_disable_eirq(void) -+{ -+ if (!atomic_read(&irq_enable_flag)) -+ CMB_STUB_LOG_DBG("wifi eint has been disabled!\n"); -+ else { -+ if (wifi_irq != 0xfffffff) { -+ disable_irq_nosync(wifi_irq); -+ CMB_STUB_LOG_DBG("disable WIFI EINT irq %d !!\n", wifi_irq); -+ } -+ atomic_set(&irq_enable_flag, 0); -+ } -+} -+ -+irqreturn_t mtk_wcn_cmb_sdio_eirq_handler_stub(int irq, void *data) -+{ -+ if ((NULL != mtk_wcn_cmb_sdio_eirq_handler)&&(0 != atomic_read(&sdio_claim_irq_enable_flag))) -+ mtk_wcn_cmb_sdio_eirq_handler(mtk_wcn_cmb_sdio_eirq_data); -+ return IRQ_HANDLED; -+} -+ -+static void mtk_wcn_cmb_sdio_request_eirq(msdc_sdio_irq_handler_t irq_handler, void *data) -+{ -+ struct device_node *node; -+ int ret = -EINVAL; -+#if 0 -+ unsigned int gpio_wifi_eint_pin; -+#endif -+ -+ CMB_STUB_LOG_INFO("enter %s\n", __func__); -+ mtk_wcn_sdio_irq_flag_set(0); -+ atomic_set(&irq_enable_flag, 0); -+ mtk_wcn_cmb_sdio_eirq_data = data; -+ mtk_wcn_cmb_sdio_eirq_handler = irq_handler; -+ -+ node = (struct device_node *)of_find_compatible_node(NULL, NULL, "mediatek,connectivity-combo"); -+ if (node) { -+#if 0 -+ gpio_wifi_eint_pin = of_get_gpio(node, 5); -+ CMB_STUB_LOG_INFO("WIFI EINT pin %d !!\n", gpio_wifi_eint_pin); -+ wifi_irq = gpio_to_irq(gpio_wifi_eint_pin); -+#else -+ wifi_irq = irq_of_parse_and_map(node, 0);/* get wifi eint num */ -+#endif -+#if 1 -+ ret = request_irq(wifi_irq, mtk_wcn_cmb_sdio_eirq_handler_stub, IRQF_TRIGGER_LOW, -+ "WIFI-eint", NULL); -+ CMB_STUB_LOG_DBG("WIFI EINT irq %d !!\n", wifi_irq); -+#endif -+ -+ if (ret) -+ CMB_STUB_LOG_WARN("WIFI EINT IRQ LINE NOT AVAILABLE!!\n"); -+ else -+ mtk_wcn_cmb_sdio_disable_eirq();/*not ,chip state is power off*/ -+ } else -+ CMB_STUB_LOG_WARN("[%s] can't find connectivity compatible node\n", __func__); -+ -+ CMB_STUB_LOG_INFO("exit %s\n", __func__); -+} -+ -+static void mtk_wcn_cmb_sdio_register_pm(pm_callback_t pm_cb, void *data) -+{ -+ CMB_STUB_LOG_DBG("mtk_wcn_cmb_sdio_register_pm (0x%p, 0x%p)\n", pm_cb, data); -+ /* register pm change callback */ -+ mtk_wcn_cmb_sdio_pm_cb = pm_cb; -+ mtk_wcn_cmb_sdio_pm_data = data; -+} -+ -+static void mtk_wcn_cmb_sdio_on(int sdio_port_num) -+{ -+ pm_message_t state = {.event = PM_EVENT_USER_RESUME }; -+ -+ CMB_STUB_LOG_INFO("mtk_wcn_cmb_sdio_on (%d)\n", sdio_port_num); -+ -+ /* 1. disable sdio eirq */ -+ mtk_wcn_cmb_sdio_disable_eirq(); -+ -+ /* 2. call sd callback */ -+ if (mtk_wcn_cmb_sdio_pm_cb) { -+ /* pr_warn("mtk_wcn_cmb_sdio_pm_cb(PM_EVENT_USER_RESUME, 0x%p, 0x%p)\n", -+ * mtk_wcn_cmb_sdio_pm_cb, mtk_wcn_cmb_sdio_pm_data); */ -+ mtk_wcn_cmb_sdio_pm_cb(state, mtk_wcn_cmb_sdio_pm_data); -+ } else -+ CMB_STUB_LOG_WARN("mtk_wcn_cmb_sdio_on no sd callback!!\n"); -+} -+ -+static void mtk_wcn_cmb_sdio_off(int sdio_port_num) -+{ -+ pm_message_t state = {.event = PM_EVENT_USER_SUSPEND }; -+ -+ CMB_STUB_LOG_INFO("mtk_wcn_cmb_sdio_off (%d)\n", sdio_port_num); -+ -+ /* 1. call sd callback */ -+ if (mtk_wcn_cmb_sdio_pm_cb) { -+ /* pr_warn("mtk_wcn_cmb_sdio_off(PM_EVENT_USER_SUSPEND, 0x%p, 0x%p)\n", -+ * mtk_wcn_cmb_sdio_pm_cb, mtk_wcn_cmb_sdio_pm_data); */ -+ mtk_wcn_cmb_sdio_pm_cb(state, mtk_wcn_cmb_sdio_pm_data); -+ } else -+ CMB_STUB_LOG_WARN("mtk_wcn_cmb_sdio_off no sd callback!!\n"); -+ -+ /* 2. disable sdio eirq */ -+ mtk_wcn_cmb_sdio_disable_eirq(); -+} -+ -+int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on) -+{ -+ CMB_STUB_LOG_DBG("mt_mtk_wcn_cmb_sdio_ctrl (%d, %d)\n", sdio_port_num, on); -+ if (on) { -+#if 1 -+ CMB_STUB_LOG_DBG("board_sdio_ctrl force off before on\n"); -+ mtk_wcn_cmb_sdio_off(sdio_port_num); -+#else -+ CMB_STUB_LOG_WARN("skip sdio off before on\n"); -+#endif -+ /* off -> on */ -+ mtk_wcn_cmb_sdio_on(sdio_port_num); -+ if (wifi_irq != 0xfffffff) -+ irq_set_irq_wake(wifi_irq, 1); -+ else -+ CMB_STUB_LOG_WARN("wifi_irq is not available\n"); -+ } else { -+ if (wifi_irq != 0xfffffff) -+ irq_set_irq_wake(wifi_irq, 0); -+ else -+ CMB_STUB_LOG_WARN("wifi_irq is not available\n"); -+ /* on -> off */ -+ mtk_wcn_cmb_sdio_off(sdio_port_num); -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(board_sdio_ctrl); -+ -+int mtk_wcn_sdio_irq_flag_set(int flag) -+{ -+ if (0 != flag) -+ atomic_set(&sdio_claim_irq_enable_flag, 1); -+ else -+ atomic_set(&sdio_claim_irq_enable_flag, 0); -+ -+ CMB_STUB_LOG_DBG("sdio_claim_irq_enable_flag:%d\n", atomic_read(&sdio_claim_irq_enable_flag)); -+ -+ return atomic_read(&sdio_claim_irq_enable_flag); -+} -+EXPORT_SYMBOL(mtk_wcn_sdio_irq_flag_set); -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c -new file mode 100644 -index 0000000000000..7ac5ac73ef5d8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c -@@ -0,0 +1,269 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[SDIO-DETECT]" -+ -+#include "wmt_detect.h" -+ -+#if MTK_HIF_SDIO_AUTOK_ENABLED -+#include -+#endif -+ -+unsigned int gComboChipId = -1; -+struct sdio_func *g_func = NULL; -+ -+MTK_WCN_HIF_SDIO_CHIP_INFO gChipInfoArray[] = { -+ /* MT6620 *//* Not an SDIO standard class device */ -+ {{SDIO_DEVICE(0x037A, 0x020A)}, 0x6620}, /* SDIO1:FUNC1:WIFI */ -+ {{SDIO_DEVICE(0x037A, 0x020B)}, 0x6620}, /* SDIO2:FUNC1:BT+FM+GPS */ -+ {{SDIO_DEVICE(0x037A, 0x020C)}, 0x6620}, /* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */ -+ -+ /* MT6628 *//* SDIO1: Wi-Fi, SDIO2: BGF */ -+ {{SDIO_DEVICE(0x037A, 0x6628)}, 0x6628}, -+ -+ /* MT6630 *//* SDIO1: Wi-Fi, SDIO2: BGF */ -+ {{SDIO_DEVICE(0x037A, 0x6630)}, 0x6630}, -+ -+}; -+ -+/* Supported SDIO device table */ -+static const struct sdio_device_id mtk_sdio_id_tbl[] = { -+ /* MT6618 *//* Not an SDIO standard class device */ -+ {SDIO_DEVICE(0x037A, 0x018A)}, /* SDIO1:WIFI */ -+ {SDIO_DEVICE(0x037A, 0x018B)}, /* SDIO2:FUNC1:BT+FM */ -+ {SDIO_DEVICE(0x037A, 0x018C)}, /* 2-function (SDIO2:FUNC1:BT+FM, FUNC2:WIFI) */ -+ -+ /* MT6619 *//* Not an SDIO standard class device */ -+ {SDIO_DEVICE(0x037A, 0x6619)}, /* SDIO2:FUNC1:BT+FM+GPS */ -+ -+ /* MT6620 *//* Not an SDIO standard class device */ -+ {SDIO_DEVICE(0x037A, 0x020A)}, /* SDIO1:FUNC1:WIFI */ -+ {SDIO_DEVICE(0x037A, 0x020B)}, /* SDIO2:FUNC1:BT+FM+GPS */ -+ {SDIO_DEVICE(0x037A, 0x020C)}, /* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */ -+ -+ /* MT5921 *//* Not an SDIO standard class device */ -+ {SDIO_DEVICE(0x037A, 0x5921)}, -+ -+ /* MT6628 *//* SDIO1: Wi-Fi, SDIO2: BGF */ -+ {SDIO_DEVICE(0x037A, 0x6628)}, -+ -+ /* MT6630 *//* SDIO1: Wi-Fi, SDIO2: BGF */ -+ {SDIO_DEVICE(0x037A, 0x6630)}, -+ { /* end: all zeroes */ }, -+}; -+ -+static int sdio_detect_probe(struct sdio_func *func, const struct sdio_device_id *id); -+ -+static void sdio_detect_remove(struct sdio_func *func); -+ -+static struct sdio_driver mtk_sdio_client_drv = { -+ .name = "mtk_sdio_client", /* MTK SDIO Client Driver */ -+ .id_table = mtk_sdio_id_tbl, /* all supported struct sdio_device_id table */ -+ .probe = sdio_detect_probe, -+ .remove = sdio_detect_remove, -+}; -+ -+static int hif_sdio_match_chipid_by_dev_id(const struct sdio_device_id *id); -+ -+int hif_sdio_is_chipid_valid(int chipId) -+{ -+ int index = -1; -+ -+ int left = 0; -+ int middle = 0; -+ int right = sizeof(gChipInfoArray) / sizeof(gChipInfoArray[0]) - 1; -+ -+ if ((chipId < gChipInfoArray[left].chipId) || (chipId > gChipInfoArray[right].chipId)) -+ return index; -+ -+ middle = (left + right) / 2; -+ -+ while (left <= right) { -+ if (chipId > gChipInfoArray[middle].chipId) { -+ left = middle + 1; -+ } else if (chipId < gChipInfoArray[middle].chipId) { -+ right = middle - 1; -+ } else { -+ index = middle; -+ break; -+ } -+ middle = (left + right) / 2; -+ } -+ -+ if (0 > index) -+ WMT_DETECT_ERR_FUNC("no supported chipid found\n"); -+ else -+ WMT_DETECT_INFO_FUNC("index:%d, chipId:0x%x\n", index, gChipInfoArray[index].chipId); -+ -+ return index; -+} -+ -+int hif_sdio_match_chipid_by_dev_id(const struct sdio_device_id *id) -+{ -+ int maxIndex = sizeof(gChipInfoArray) / sizeof(gChipInfoArray[0]); -+ int index = 0; -+ struct sdio_device_id *localId = NULL; -+ int chipId = -1; -+ -+ for (index = 0; index < maxIndex; index++) { -+ localId = &(gChipInfoArray[index].deviceId); -+ if ((localId->vendor == id->vendor) && (localId->device == id->device)) { -+ chipId = gChipInfoArray[index].chipId; -+ WMT_DETECT_INFO_FUNC -+ ("valid chipId found, index(%d), vendor id(0x%x), device id(0x%x), chip id(0x%x)\n", index, -+ localId->vendor, localId->device, chipId); -+ gComboChipId = chipId; -+ mtk_wcn_wmt_set_chipid(gComboChipId); -+ break; -+ } -+ } -+ if (0 > chipId) { -+ WMT_DETECT_ERR_FUNC("No valid chipId found, vendor id(0x%x), device id(0x%x)\n", id->vendor, -+ id->device); -+ } -+ -+ return chipId; -+} -+ -+int sdio_detect_query_chipid(int waitFlag) -+{ -+ unsigned int timeSlotMs = 200; -+ unsigned int maxTimeSlot = 15; -+ unsigned int counter = 0; -+ /* gComboChipId = 0x6628; */ -+ if (0 == waitFlag) -+ return gComboChipId; -+ if (0 <= hif_sdio_is_chipid_valid(gComboChipId)) -+ return gComboChipId; -+ -+ while (counter < maxTimeSlot) { -+ if (0 <= hif_sdio_is_chipid_valid(gComboChipId)) -+ break; -+ msleep(timeSlotMs); -+ counter++; -+ } -+ -+ return gComboChipId; -+} -+ -+int sdio_detect_do_autok(int chipId) -+{ -+ int i_ret = 0; -+ -+#if MTK_HIF_SDIO_AUTOK_ENABLED -+#if 0 -+ BOOTMODE boot_mode; -+ -+ boot_mode = get_boot_mode(); -+ -+ if (boot_mode == META_BOOT) { -+ WMT_DETECT_INFO_FUNC("omit autok in meta mode\n"); -+ return 0; -+ } -+#endif -+ if (0x6630 == chipId) { -+#ifdef CONFIG_SDIOAUTOK_SUPPORT -+ if (NULL != g_func) { -+ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready++\n"); -+ i_ret = wait_sdio_autok_ready(g_func->card->host); -+ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready--\n"); -+ if (0 == i_ret) { -+ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready return success\n"); -+ } else { -+ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready return fail, i_ret:%d\n", i_ret); -+ gComboChipId = -1; -+ } -+ } else { -+ WMT_DETECT_INFO_FUNC("g_func NULL, omit autok\n"); -+ } -+#else -+ i_ret = 0; -+ WMT_DETECT_INFO_FUNC("MTK_SDIOAUTOK_SUPPORT not defined\n"); -+#endif -+ } else { -+ WMT_DETECT_INFO_FUNC("MT%x does not support SDIO3.0 autoK is not needed\n", chipId); -+ } -+#else -+ i_ret = 0; -+ WMT_DETECT_INFO_FUNC("MTK_HIF_SDIO_AUTOK_ENABLED is not defined\n"); -+#endif -+ return i_ret; -+} -+ -+/*! -+ * \brief hif_sdio probe function -+ * -+ * hif_sdio probe function called by mmc driver when any matched SDIO function -+ * is detected by it. -+ * -+ * \param func -+ * \param id -+ * -+ * \retval 0 register successfully -+ * \retval < 0 list error code here -+ */ -+static int sdio_detect_probe(struct sdio_func *func, const struct sdio_device_id *id) -+{ -+ int chipId = 0; -+ -+ WMT_DETECT_INFO_FUNC("vendor(0x%x) device(0x%x) num(0x%x)\n", func->vendor, func->device, func->num); -+ chipId = hif_sdio_match_chipid_by_dev_id(id); -+ -+ if ((0x6630 == chipId) && (1 == func->num)) { -+ int ret = 0; -+ -+ g_func = func; -+ WMT_DETECT_INFO_FUNC("autok function detected, func:0x%p\n", g_func); -+ -+ sdio_claim_host(func); -+ ret = sdio_enable_func(func); -+ sdio_release_host(func); -+ if (ret) -+ WMT_DETECT_ERR_FUNC("sdio_enable_func failed!\n"); -+ } -+ -+ return 0; -+} -+ -+static void sdio_detect_remove(struct sdio_func *func) -+{ -+ if (g_func == func) { -+ sdio_claim_host(func); -+ sdio_disable_func(func); -+ sdio_release_host(func); -+ g_func = NULL; -+ } -+ WMT_DETECT_INFO_FUNC("do sdio remove\n"); -+} -+ -+int sdio_detect_init(void) -+{ -+ int ret = -1; -+ /* register to mmc driver */ -+ ret = sdio_register_driver(&mtk_sdio_client_drv); -+ WMT_DETECT_INFO_FUNC("sdio_register_driver() ret=%d\n", ret); -+ return 0; -+} -+ -+int sdio_detect_exit(void) -+{ -+ g_func = NULL; -+ /* register to mmc driver */ -+ sdio_unregister_driver(&mtk_sdio_client_drv); -+ WMT_DETECT_INFO_FUNC("sdio_unregister_driver\n"); -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h -new file mode 100644 -index 0000000000000..3a0bff9def1b1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h -@@ -0,0 +1,43 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef _SDIO_DETECT_H_ -+#define _SDIO_DETECT_H_ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_SDIOAUTOK_SUPPORT -+#define MTK_HIF_SDIO_AUTOK_ENABLED 1 -+extern int wait_sdio_autok_ready(void *); -+#else -+#define MTK_HIF_SDIO_AUTOK_ENABLED 0 -+#endif -+ -+typedef struct _MTK_WCN_HIF_SDIO_CHIP_INFO_ { -+ struct sdio_device_id deviceId; -+ unsigned int chipId; -+} MTK_WCN_HIF_SDIO_CHIP_INFO, *P_MTK_WCN_HIF_SDIO_CHIP_INFO; -+ -+extern int sdio_detect_exit(void); -+extern int sdio_detect_init(void); -+extern int sdio_detect_query_chipid(int waitFlag); -+extern int hif_sdio_is_chipid_valid(int chipId); -+ -+extern int sdio_detect_do_autok(int chipId); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c -new file mode 100644 -index 0000000000000..487852df8f20f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c -@@ -0,0 +1,380 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#include -+#include -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-DETECT]" -+ -+#include "wmt_detect.h" -+#include "wmt_gpio.h" -+ -+#if MTK_WCN_REMOVE_KO -+#include "conn_drv_init.h" -+#endif -+#ifdef CONFIG_COMPAT -+#include -+#endif -+ -+#define WMT_DETECT_MAJOR 154 -+#define WMT_DETECT_DEV_NUM 1 -+#define WMT_DETECT_DRVIER_NAME "mtk_wcn_detect" -+#define WMT_DETECT_DEVICE_NAME "wmtdetect" -+ -+struct class *pDetectClass = NULL; -+struct device *pDetectDev = NULL; -+static int gWmtDetectMajor = WMT_DETECT_MAJOR; -+static struct cdev gWmtDetectCdev; -+unsigned int gWmtDetectDbgLvl = WMT_DETECT_LOG_INFO; -+ -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+inline unsigned int wmt_plat_get_soc_chipid(void) -+{ -+ WMT_DETECT_INFO_FUNC("no soc chip supported, due to MTK_WCN_SOC_CHIP_SUPPORT is not set.\n"); -+ return -1; -+} -+#endif -+ -+static int wmt_detect_open(struct inode *inode, struct file *file) -+{ -+ WMT_DETECT_INFO_FUNC("open major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); -+ -+ return 0; -+} -+ -+static int wmt_detect_close(struct inode *inode, struct file *file) -+{ -+ WMT_DETECT_INFO_FUNC("close major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); -+ -+ return 0; -+} -+ -+static ssize_t wmt_detect_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ WMT_DETECT_INFO_FUNC(" ++\n"); -+ WMT_DETECT_INFO_FUNC(" --\n"); -+ -+ return 0; -+} -+ -+ssize_t wmt_detect_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ WMT_DETECT_INFO_FUNC(" ++\n"); -+ WMT_DETECT_INFO_FUNC(" --\n"); -+ -+ return 0; -+} -+ -+static long wmt_detect_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ int retval = 0; -+ -+ WMT_DETECT_INFO_FUNC("cmd (%d),arg(%ld)\n", cmd, arg); -+ -+ switch (cmd) { -+ case COMBO_IOCTL_GET_CHIP_ID: -+ /*just get chipid from sdio-detect module */ -+ /*check if external combo chip exists or not */ -+ /*if yes, just return combo chip id */ -+ /*if no, get soc chipid */ -+ retval = mtk_wcn_wmt_chipid_query(); -+ break; -+ -+ case COMBO_IOCTL_SET_CHIP_ID: -+ mtk_wcn_wmt_set_chipid(arg); -+ -+ break; -+ -+ case COMBO_IOCTL_EXT_CHIP_PWR_ON: -+ retval = wmt_detect_ext_chip_pwr_on(); -+ break; -+ -+ case COMBO_IOCTL_EXT_CHIP_DETECT: -+ retval = wmt_detect_ext_chip_detect(); -+ break; -+ -+ case COMBO_IOCTL_EXT_CHIP_PWR_OFF: -+ retval = wmt_detect_ext_chip_pwr_off(); -+ break; -+ -+ case COMBO_IOCTL_DO_SDIO_AUDOK: -+ retval = sdio_detect_do_autok(arg); -+ break; -+ -+ case COMBO_IOCTL_GET_SOC_CHIP_ID: -+ retval = wmt_plat_get_soc_chipid(); -+ /*get soc chipid by HAL interface */ -+ break; -+ -+ case COMBO_IOCTL_MODULE_CLEANUP: -+#if (MTK_WCN_REMOVE_KO) -+ /*deinit SDIO-DETECT module */ -+ retval = sdio_detect_exit(); -+#else -+ WMT_DETECT_INFO_FUNC("no MTK_WCN_REMOVE_KO defined\n"); -+#endif -+ break; -+ -+ case COMBO_IOCTL_DO_MODULE_INIT: -+#if (MTK_WCN_REMOVE_KO) -+ /*deinit SDIO-DETECT module */ -+ retval = do_connectivity_driver_init(arg); -+#else -+ WMT_DETECT_INFO_FUNC("no MTK_WCN_REMOVE_KO defined\n"); -+#endif -+ break; -+ -+ default: -+ WMT_DETECT_WARN_FUNC("unknown cmd (%d)\n", cmd); -+ retval = 0; -+ break; -+ } -+ return retval; -+} -+#ifdef CONFIG_COMPAT -+static long WMT_compat_detect_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ long ret; -+ -+ WMT_DETECT_INFO_FUNC("cmd (%d)\n", cmd); -+ ret = wmt_detect_unlocked_ioctl(filp, cmd, arg); -+ return ret; -+} -+#endif -+const struct file_operations gWmtDetectFops = { -+ .open = wmt_detect_open, -+ .release = wmt_detect_close, -+ .read = wmt_detect_read, -+ .write = wmt_detect_write, -+ .unlocked_ioctl = wmt_detect_unlocked_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = WMT_compat_detect_ioctl, -+#endif -+}; -+ -+int wmt_detect_ext_chip_pwr_on(void) -+{ -+ /*pre power on external chip */ -+ /* wmt_plat_pwr_ctrl(FUNC_ON); */ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ WMT_DETECT_INFO_FUNC("++\n"); -+ if (0 != wmt_detect_chip_pwr_ctrl(1)) -+ return -1; -+ if (0 != wmt_detect_sdio_pwr_ctrl(1)) -+ return -2; -+ return 0; -+#else -+ WMT_DETECT_INFO_FUNC("combo chip is not supported\n"); -+ return -1; -+#endif -+} -+ -+int wmt_detect_ext_chip_pwr_off(void) -+{ -+ /*pre power off external chip */ -+ /* wmt_plat_pwr_ctrl(FUNC_OFF); */ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ WMT_DETECT_INFO_FUNC("--\n"); -+ wmt_detect_sdio_pwr_ctrl(0); -+ return wmt_detect_chip_pwr_ctrl(0); -+#else -+ WMT_DETECT_INFO_FUNC("combo chip is not supported\n"); -+ return 0; -+#endif -+} -+ -+int wmt_detect_ext_chip_detect(void) -+{ -+ int iRet = -1; -+ unsigned int chipId = -1; -+ /*if there is no external combo chip, return -1 */ -+ int bgfEintStatus = -1; -+ -+ WMT_DETECT_INFO_FUNC("++\n"); -+ /*wait for a stable time */ -+ msleep(20); -+ -+ /*read BGF_EINT_PIN status */ -+ bgfEintStatus = wmt_detect_read_ext_cmb_status(); -+ -+ if (0 == bgfEintStatus) { -+ /*external chip does not exist */ -+ WMT_DETECT_INFO_FUNC("external combo chip not detected\n"); -+ } else if (1 == bgfEintStatus) { -+ /*combo chip exists */ -+ WMT_DETECT_INFO_FUNC("external combo chip detected\n"); -+ -+ /*detect chipid by sdio_detect module */ -+ chipId = sdio_detect_query_chipid(1); -+ if (0 <= hif_sdio_is_chipid_valid(chipId)) -+ WMT_DETECT_INFO_FUNC("valid external combo chip id (0x%x)\n", chipId); -+ else -+ WMT_DETECT_INFO_FUNC("invalid external combo chip id (0x%x)\n", chipId); -+ iRet = 0; -+ } else { -+ /*Error exists */ -+ WMT_DETECT_ERR_FUNC("error happens when detecting combo chip\n"); -+ } -+ WMT_DETECT_INFO_FUNC("--\n"); -+ /*return 0 */ -+ return iRet; -+ /*todo: if there is external combo chip, power on chip return 0 */ -+} -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+static int wmt_detect_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ WMT_DETECT_ERR_FUNC("platform name: %s\n", pdev->name); -+ ret = wmt_gpio_init(pdev); -+ if (-1 == ret) -+ WMT_DETECT_ERR_FUNC("gpio init fail ret:%d\n", ret); -+ return ret; -+} -+ -+static int wmt_detect_remove(struct platform_device *pdev) -+{ -+ wmt_gpio_deinit(); -+ return 0; -+} -+#endif -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+static struct of_device_id wmt_detect_match[] = { -+ { .compatible = "mediatek,connectivity-combo", }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, wmt_detect_match); -+ -+static struct platform_driver wmt_detect_driver = { -+ .probe = wmt_detect_probe, -+ .remove = wmt_detect_remove, -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "mediatek,connectivity-combo", -+ .of_match_table = wmt_detect_match, -+ }, -+}; -+#endif -+ -+/*module_platform_driver(wmt_detect_driver);*/ -+static int wmt_detect_driver_init(void) -+{ -+ dev_t devID = MKDEV(gWmtDetectMajor, 0); -+ int cdevErr = -1; -+ int ret = -1; -+ -+ ret = register_chrdev_region(devID, WMT_DETECT_DEV_NUM, WMT_DETECT_DRVIER_NAME); -+ if (ret) { -+ WMT_DETECT_ERR_FUNC("fail to register chrdev\n"); -+ return ret; -+ } -+ -+ cdev_init(&gWmtDetectCdev, &gWmtDetectFops); -+ gWmtDetectCdev.owner = THIS_MODULE; -+ -+ cdevErr = cdev_add(&gWmtDetectCdev, devID, WMT_DETECT_DEV_NUM); -+ if (cdevErr) { -+ WMT_DETECT_ERR_FUNC("cdev_add() fails (%d)\n", cdevErr); -+ goto err1; -+ } -+ -+ pDetectClass = class_create(THIS_MODULE, WMT_DETECT_DEVICE_NAME); -+ if (IS_ERR(pDetectClass)) { -+ WMT_DETECT_ERR_FUNC("class create fail, error code(%ld)\n", PTR_ERR(pDetectClass)); -+ goto err1; -+ } -+ -+ pDetectDev = device_create(pDetectClass, NULL, devID, NULL, WMT_DETECT_DEVICE_NAME); -+ if (IS_ERR(pDetectDev)) { -+ WMT_DETECT_ERR_FUNC("device create fail, error code(%ld)\n", PTR_ERR(pDetectDev)); -+ goto err2; -+ } -+ -+ WMT_DETECT_INFO_FUNC("driver(major %d) installed success\n", gWmtDetectMajor); -+ -+ /*init SDIO-DETECT module */ -+ sdio_detect_init(); -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ ret = platform_driver_register(&wmt_detect_driver); -+ if (ret) -+ WMT_DETECT_ERR_FUNC("platform driver register fail ret:%d\n", ret); -+#endif -+ -+ return 0; -+ -+err2: -+ -+ if (pDetectClass) { -+ class_destroy(pDetectClass); -+ pDetectClass = NULL; -+ } -+ -+err1: -+ -+ if (cdevErr == 0) -+ cdev_del(&gWmtDetectCdev); -+ -+ if (ret == 0) { -+ unregister_chrdev_region(devID, WMT_DETECT_DEV_NUM); -+ gWmtDetectMajor = -1; -+ } -+ -+ WMT_DETECT_ERR_FUNC("fail\n"); -+ -+ return -1; -+} -+ -+static void wmt_detect_driver_exit(void) -+{ -+ dev_t dev = MKDEV(gWmtDetectMajor, 0); -+ -+ if (pDetectDev) { -+ device_destroy(pDetectClass, dev); -+ pDetectDev = NULL; -+ } -+ -+ if (pDetectClass) { -+ class_destroy(pDetectClass); -+ pDetectClass = NULL; -+ } -+ -+ cdev_del(&gWmtDetectCdev); -+ unregister_chrdev_region(dev, WMT_DETECT_DEV_NUM); -+ -+#if !(MTK_WCN_REMOVE_KO) -+/*deinit SDIO-DETECT module*/ -+ sdio_detect_exit(); -+#endif -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ platform_driver_unregister(&wmt_detect_driver); -+#endif -+ -+ WMT_DETECT_INFO_FUNC("done\n"); -+} -+ -+module_init(wmt_detect_driver_init); -+module_exit(wmt_detect_driver_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Zhiguo.Niu & Chaozhong.Liang @ MBJ/WCNSE/SS1"); -+ -+module_param(gWmtDetectMajor, uint, 0); -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h -new file mode 100644 -index 0000000000000..7e152bfd39ec9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h -@@ -0,0 +1,114 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef _WMT_DETECT_H_ -+#define _WMT_DETECT_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#ifdef MTK_WCN_REMOVE_KERNEL_MODULE -+#define MTK_WCN_REMOVE_KO 1 -+#else -+#define MTK_WCN_REMOVE_KO 0 -+#endif -+ -+#include "sdio_detect.h" -+#include "wmt_detect_pwr.h" -+#include -+ -+#define WMT_DETECT_LOG_LOUD 4 -+#define WMT_DETECT_LOG_DBG 3 -+#define WMT_DETECT_LOG_INFO 2 -+#define WMT_DETECT_LOG_WARN 1 -+#define WMT_DETECT_LOG_ERR 0 -+ -+extern unsigned int gWmtDetectDbgLvl; -+ -+#define WMT_DETECT_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_LOUD) \ -+ pr_debug(DFT_TAG"[L]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_DETECT_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_DBG) \ -+ pr_debug(DFT_TAG"[D]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_DETECT_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_INFO) \ -+ pr_err(DFT_TAG"[I]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_DETECT_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_WARN) \ -+ pr_warn(DFT_TAG"[W]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+#define WMT_DETECT_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_ERR) \ -+ pr_err(DFT_TAG"[E]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+ -+#define WMT_IOC_MAGIC 'w' -+#define COMBO_IOCTL_GET_CHIP_ID _IOR(WMT_IOC_MAGIC, 0, int) -+#define COMBO_IOCTL_SET_CHIP_ID _IOW(WMT_IOC_MAGIC, 1, int) -+#define COMBO_IOCTL_EXT_CHIP_DETECT _IOR(WMT_IOC_MAGIC, 2, int) -+#define COMBO_IOCTL_GET_SOC_CHIP_ID _IOR(WMT_IOC_MAGIC, 3, int) -+#define COMBO_IOCTL_DO_MODULE_INIT _IOR(WMT_IOC_MAGIC, 4, int) -+#define COMBO_IOCTL_MODULE_CLEANUP _IOR(WMT_IOC_MAGIC, 5, int) -+#define COMBO_IOCTL_EXT_CHIP_PWR_ON _IOR(WMT_IOC_MAGIC, 6, int) -+#define COMBO_IOCTL_EXT_CHIP_PWR_OFF _IOR(WMT_IOC_MAGIC, 7, int) -+#define COMBO_IOCTL_DO_SDIO_AUDOK _IOR(WMT_IOC_MAGIC, 8, int) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+********************************************************************************/ -+extern int wmt_detect_ext_chip_detect(void); -+extern int wmt_detect_ext_chip_pwr_on(void); -+extern int wmt_detect_ext_chip_pwr_off(void); -+ -+#ifdef MTK_WCN_SOC_CHIP_SUPPORT -+extern unsigned int wmt_plat_get_soc_chipid(void); -+#endif -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+/* mtk_uart_pdn_enable -- request uart port enter/exit deep idle mode, this API is defined in uart driver -+ * -+ * @ port - uart port name, Eg: "ttyMT0", "ttyMT1", "ttyMT2" -+ * @ enable - "1", enable deep idle; "0", disable deep idle -+ * -+ * Return 0 if success, else -1 -+ */ -+extern unsigned int mtk_uart_pdn_enable(char *port, int enable); -+#endif -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c -new file mode 100644 -index 0000000000000..1dcb7ed358bcf ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c -@@ -0,0 +1,232 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#include -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-DETECT]" -+ -+#include "wmt_detect.h" -+#include "wmt_gpio.h" -+ -+#define INVALID_PIN_ID (0xFFFFFFFF) -+ -+/*copied form WMT module*/ -+static int wmt_detect_dump_pin_conf(void) -+{ -+ WMT_DETECT_DBG_FUNC("[WMT-DETECT]=>dump wmt pin configuration start<=\n"); -+ -+ WMT_DETECT_INFO_FUNC("LDO(GPIO%d), PMU(GPIO%d), PMUV28(GPIO%d)\n", -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num); -+ -+ WMT_DETECT_INFO_FUNC("RST(GPIO%d), BGF_EINT(GPIO%d), BGF_EINT_NUM(%d)\n", -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num, -+ gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num)); -+ -+ WMT_DETECT_INFO_FUNC("WIFI_EINT(GPIO%d), WIFI_EINT_NUM(%d)\n", -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num, -+ gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num)); -+ -+ WMT_DETECT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration ends<=\n"); -+ -+ return 0; -+} -+ -+int _wmt_detect_output_low(unsigned int id) -+{ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) { -+ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 0); -+ WMT_DETECT_DBG_FUNC("WMT-DETECT: set GPIO%d to output %d\n", -+ gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, -+ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num)); -+ } -+ -+ return 0; -+} -+ -+int _wmt_detect_output_high(unsigned int id) -+{ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) { -+ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 1); -+ WMT_DETECT_DBG_FUNC("WMT-DETECT: set GPIO%d to output %d\n", -+ gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, -+ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num)); -+ } -+ -+ return 0; -+} -+ -+int _wmt_detect_read_gpio_input(unsigned int id) -+{ -+ int retval = 0; -+ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) { -+ retval = gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num); -+ WMT_DETECT_DBG_FUNC("WMT-DETECT: get GPIO%d val%d\n", -+ gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, retval); -+ } -+ -+ return retval; -+} -+ -+/*This power on sequence must support all combo chip's basic power on sequence -+ * 1. LDO control is a must, if external LDO exist -+ * 2. PMU control is a must -+ * 3. RST control is a must -+ * 4. WIFI_EINT pin control is a must, used for GPIO mode for EINT status checkup -+ * 5. RTC32k clock control is a must -+ * */ -+static int wmt_detect_chip_pwr_on(void) -+{ -+ int retval = -1; -+ /*setting validiation check*/ -+ if ((INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) || -+ (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) || -+ (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num)) { -+ WMT_DETECT_ERR_FUNC("WMT-DETECT: either PMU(%d) or RST(%d) or WIFI_EINT(%d) is not set\n", -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num); -+ -+ return retval; -+ } -+ /*set LDO/PMU/RST to output 0, no pull*/ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) -+ _wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN); -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]); -+ WMT_DETECT_INFO_FUNC("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ WMT_DETECT_ERR_FUNC("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ _wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN); -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]); -+ WMT_DETECT_INFO_FUNC("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ WMT_DETECT_ERR_FUNC("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ _wmt_detect_output_low(GPIO_COMBO_RST_PIN); -+ -+#if 0 -+ _wmt_detect_output_high(GPIO_WIFI_EINT_PIN); -+#endif -+ -+ /*pull high LDO*/ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) -+ _wmt_detect_output_high(GPIO_COMBO_LDO_EN_PIN); -+ /*sleep for LDO stable time*/ -+ msleep(MAX_LDO_STABLE_TIME); -+ -+ /*export RTC clock, sleep for RTC stable time*/ -+ rtc_gpio_enable_32k(RTC_GPIO_USER_GPS); -+ msleep(MAX_RTC_STABLE_TIME); -+ /*PMU output low, RST output low, to make chip power off completely*/ -+ /*always done*/ -+ /*sleep for power off stable time*/ -+ msleep(MAX_OFF_STABLE_TIME); -+ /*PMU output high, and sleep for reset stable time*/ -+ _wmt_detect_output_high(GPIO_COMBO_PMU_EN_PIN); -+#ifdef CONFIG_MTK_COMBO_COMM_NPWR -+ if ((gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_DAT_PIN].gpio_num != INVALID_PIN_ID) && -+ (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_num != INVALID_PIN_ID)) { -+ msleep(20); -+ _wmt_detect_output_high(GPIO_PCM_DAISYNC_PIN); -+ -+ msleep(20); -+ _wmt_detect_output_high(GPIO_COMBO_I2S_DAT_PIN); -+ -+ msleep(20); -+ _wmt_detect_output_low(GPIO_COMBO_I2S_DAT_PIN); -+ -+ msleep(20); -+ _wmt_detect_output_low(GPIO_PCM_DAISYNC_PIN); -+ -+ msleep(20); -+ } -+#endif -+ msleep(MAX_RST_STABLE_TIME); -+ /*RST output high, and sleep for power on stable time */ -+ _wmt_detect_output_high(GPIO_COMBO_RST_PIN); -+ msleep(MAX_ON_STABLE_TIME); -+ -+ retval = 0; -+ return retval; -+} -+ -+static int wmt_detect_chip_pwr_off(void) -+{ -+ -+ /*set RST pin to input low status*/ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) -+ _wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN); -+ /*set RST pin to input low status*/ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) -+ _wmt_detect_output_low(GPIO_COMBO_RST_PIN); -+ /*set PMU pin to input low status*/ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) -+ _wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN); -+ return 0; -+} -+ -+int wmt_detect_read_ext_cmb_status(void) -+{ -+ int retval = 0; -+ /*read WIFI_EINT pin status*/ -+ if (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num) { -+ retval = 0; -+ WMT_DETECT_ERR_FUNC("WMT-DETECT: no WIFI_EINT pin set\n"); -+ } else { -+ retval = _wmt_detect_read_gpio_input(GPIO_WIFI_EINT_PIN); -+ WMT_DETECT_ERR_FUNC("WMT-DETECT: WIFI_EINT input status:%d\n", retval); -+ } -+ return retval; -+} -+ -+int wmt_detect_chip_pwr_ctrl(int on) -+{ -+ int retval = -1; -+ -+ if (0 == on) { -+ /*power off combo chip */ -+ retval = wmt_detect_chip_pwr_off(); -+ } else { -+ wmt_detect_dump_pin_conf(); -+ /*power on combo chip */ -+ retval = wmt_detect_chip_pwr_on(); -+ } -+ return retval; -+} -+ -+int wmt_detect_sdio_pwr_ctrl(int on) -+{ -+ int retval = -1; -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ if (0 == on) { -+ /*power off SDIO slot */ -+ retval = board_sdio_ctrl(1, 0); -+ } else { -+ /*power on SDIO slot */ -+ retval = board_sdio_ctrl(1, 1); -+ } -+#else -+ WMT_DETECT_WARN_FUNC("WMT-DETECT: MTK_WCN_COMBO_CHIP_SUPPORT is not set\n"); -+#endif -+ return retval; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h -new file mode 100644 -index 0000000000000..32e661520fd0d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h -@@ -0,0 +1,29 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef __WMT_DETECT_PWR_H_ -+#define __WMT_DETECT_PWR_H_ -+ -+#define MAX_RTC_STABLE_TIME 100 -+#define MAX_LDO_STABLE_TIME 100 -+#define MAX_RST_STABLE_TIME 30 -+#define MAX_OFF_STABLE_TIME 10 -+#define MAX_ON_STABLE_TIME 30 -+ -+extern int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on); -+extern int wmt_detect_chip_pwr_ctrl(int on); -+extern int wmt_detect_sdio_pwr_ctrl(int on); -+extern int wmt_detect_read_ext_cmb_status(void); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c -new file mode 100644 -index 0000000000000..3a79e1e9d15a9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c -@@ -0,0 +1,371 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#include "wmt_gpio.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+const PUINT8 gpio_state_name[GPIO_PIN_ID_MAX][GPIO_STATE_MAX] = {{"gpio_ldo_en_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_ldo_en_in_pulldown", -+ ""}, -+ {"gpio_pmuv28_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_pmuv28_in_pulldown", -+ ""}, -+ {"gpio_pmu_en_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_pmu_en_in_pulldown", -+ ""}, -+ {"gpio_rst_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_bgf_eint_in_pulldown", -+ "gpio_bgf_eint_in_pullup"}, -+ {"", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_wifi_eint_in_pull_dis", -+ "", -+ "gpio_wifi_eint_in_pullup"}, -+ {"", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_all_eint_in_pulldown", -+ "gpio_all_eint_in_pullup"}, -+ {"gpio_urxd_uart_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_urxd_gpio_in_pull_dis", -+ "", -+ "gpio_urxd_gpio_in_pullup"}, -+ {"gpio_utxd_uart_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_pcm_daiclk_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_pcm_daipcmin_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_pcm_daipcmout_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_pcm_daisync_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_i2s_ck_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_i2s_ws_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_i2s_dat_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_gps_sync_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_gps_lna_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""} -+}; -+ -+const PUINT8 gpio_pin_name[GPIO_PIN_ID_MAX] = {"gpio_combo_ldo_en_pin", -+ "gpio_combo_pmuv28_en_pin", -+ "gpio_combo_pmu_en_pin", -+ "gpio_combo_rst_pin", -+ "gpio_combo_bgf_eint_pin", -+ "gpio_wifi_eint_pin", -+ "gpio_all_eint_pin", -+ "gpio_combo_urxd_pin", -+ "gpio_combo_utxd_pin", -+ "gpio_pcm_daiclk_pin", -+ "gpio_pcm_daipcmin_pin", -+ "gpio_pcm_daipcmout_pin", -+ "gpio_pcm_daisync_pin", -+ "gpio_combo_i2s_ck_pin", -+ "gpio_combo_i2s_ws_pin", -+ "gpio_combo_i2s_dat_pin", -+ "gpio_gps_sync_pin", -+ "gpio_gps_lna_pin"}; -+ -+GPIO_CTRL_INFO gpio_ctrl_info; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+INT32 wmt_gpio_init(struct platform_device *pdev) -+{ -+ INT32 iret = 0; -+ UINT32 i, j; -+ struct device_node *node; -+ -+ node = of_find_compatible_node(NULL, NULL, "mediatek,connectivity-combo"); -+ if (!node) { -+ for (i = 0; i < GPIO_PIN_ID_MAX; i++) -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; -+ pr_err("wmt_gpio:can't find device tree node!\n"); -+ iret = -1; -+ goto err; -+ } -+ -+ gpio_ctrl_info.pinctrl_info = devm_pinctrl_get(&pdev->dev); -+ if (gpio_ctrl_info.pinctrl_info) { -+ for (i = 0; i < GPIO_PIN_ID_MAX; i++) { -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = of_get_named_gpio(node, -+ gpio_pin_name[i], 0); -+ if (gpio_ctrl_info.gpio_ctrl_state[i].gpio_num < 0) -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; -+ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[i].gpio_num) { -+ for (j = 0; j < GPIO_STATE_MAX; j++) { -+ if (0 != strlen(gpio_state_name[i][j])) { -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = -+ pinctrl_lookup_state(gpio_ctrl_info.pinctrl_info, -+ gpio_state_name[i][j]); -+ } else -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = NULL; -+ } -+ } -+ } -+ -+ pr_err("wmt_gpio: gpio init start!\n"); -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN]. -+ gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) { -+ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, -+ 0); -+ pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN out to 0: %d!\n", -+ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num)); -+ } -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) { -+ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, -+ 0); -+ pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN out to 0: %d!\n", -+ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num)); -+ } -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_state[GPIO_IN_PULLUP]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_state[GPIO_IN_PULLUP]); -+ pr_err("wmt_gpio:set GPIO_WIFI_EINT_PIN to GPIO_IN_PULLUP done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_WIFI_EINT_PIN to GPIO_IN_PULLUP fail, is NULL!\n"); -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_PCM_DAICLK_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_PCM_DAICLK_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN]. -+ gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMIN_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMIN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN]. -+ gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMOUT_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMOUT_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN]. -+ gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_PCM_DAISYNC_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_PCM_DAISYNC_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ pr_err("wmt_gpio: gpio init done!\n"); -+ } else { -+ pr_err("wmt_gpio:can't find pinctrl dev!\n"); -+ iret = -1; -+ } -+err: -+ return iret; -+} -+ -+INT32 wmt_gpio_deinit(VOID) -+{ -+ INT32 iret = 0; -+ UINT32 i; -+ UINT32 j; -+ -+ for (i = 0; i < GPIO_PIN_ID_MAX; i++) { -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; -+ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[i].gpio_num) { -+ for (j = 0; j < GPIO_STATE_MAX; j++) { -+ if (0 != strlen(gpio_state_name[i][j])) -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = NULL; -+ } -+ } -+ } -+ if (gpio_ctrl_info.pinctrl_info) { -+ devm_pinctrl_put(gpio_ctrl_info.pinctrl_info); -+ gpio_ctrl_info.pinctrl_info = NULL; -+ } -+ -+ return iret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h -new file mode 100644 -index 0000000000000..cd935bfddd994 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h -@@ -0,0 +1,103 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef _WMT_GPIO_H_ -+#define _WMT_GPIO_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "osal.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define DEFAULT_PIN_ID (0xffffffff) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_GPIO_PIN_ID { -+ GPIO_COMBO_LDO_EN_PIN = 0, -+ GPIO_COMBO_PMUV28_EN_PIN, -+ GPIO_COMBO_PMU_EN_PIN, -+ GPIO_COMBO_RST_PIN, -+ GPIO_COMBO_BGF_EINT_PIN, -+ GPIO_WIFI_EINT_PIN, -+ GPIO_COMBO_ALL_EINT_PIN, -+ GPIO_COMBO_URXD_PIN, -+ GPIO_COMBO_UTXD_PIN, -+ GPIO_PCM_DAICLK_PIN, -+ GPIO_PCM_DAIPCMIN_PIN, -+ GPIO_PCM_DAIPCMOUT_PIN, -+ GPIO_PCM_DAISYNC_PIN, -+ GPIO_COMBO_I2S_CK_PIN, -+ GPIO_COMBO_I2S_WS_PIN, -+ GPIO_COMBO_I2S_DAT_PIN, -+ GPIO_GPS_SYNC_PIN, -+ GPIO_GPS_LNA_PIN, -+ GPIO_PIN_ID_MAX -+} ENUM_GPIO_PIN_ID, *P_ENUM_GPIO_PIN_ID; -+ -+typedef enum _ENUM_GPIO_STATE_ID { -+ GPIO_PULL_DIS = 0, -+ GPIO_PULL_DOWN, -+ GPIO_PULL_UP, -+ GPIO_OUT_LOW, -+ GPIO_OUT_HIGH, -+ GPIO_IN_DIS, -+ GPIO_IN_EN, -+ GPIO_IN_PULL_DIS, -+ GPIO_IN_PULLDOWN, -+ GPIO_IN_PULLUP, -+ GPIO_STATE_MAX, -+} ENUM_GPIO_STATE_ID, *P_ENUM_GPIO_STATE_ID; -+ -+typedef struct _GPIO_CTRL_STATE { -+ INT32 gpio_num; -+ struct pinctrl_state *gpio_state[GPIO_STATE_MAX]; -+} GPIO_CTRL_STATE, *P_GPIO_CTRL_STATE; -+ -+typedef struct _GPIO_CTRL_INFO { -+ struct pinctrl *pinctrl_info; -+ GPIO_CTRL_STATE gpio_ctrl_state[GPIO_PIN_ID_MAX]; -+} GPIO_CTRL_INFO, *P_GPIO_CTRL_INFO; -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern const PUINT8 gpio_state_name[GPIO_PIN_ID_MAX][GPIO_STATE_MAX]; -+extern const PUINT8 gpio_pin_name[GPIO_PIN_ID_MAX]; -+extern GPIO_CTRL_INFO gpio_ctrl_info; -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+INT32 wmt_gpio_init(struct platform_device *pdev); -+ -+INT32 wmt_gpio_deinit(VOID); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c -new file mode 100644 -index 0000000000000..4fc3144b3ba6c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c -@@ -0,0 +1,480 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+#include "osal_typedef.h" -+#include "wmt_stp_exp.h" -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-STP-EXP]" -+ -+#define WMT_STP_EXP_INFO_FUNC(fmt, arg...) pr_debug(DFT_TAG "[I]%s: " fmt, __func__ , ##arg) -+#define WMT_STP_EXP_WARN_FUNC(fmt, arg...) pr_warn(DFT_TAG "[W]%s: " fmt, __func__ , ##arg) -+#define WMT_STP_EXP_ERR_FUNC(fmt, arg...) pr_err(DFT_TAG "[E]%s(%d):ERROR! " fmt, __func__ , __LINE__, ##arg) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+/*STP exp*/ -+MTK_WCN_STP_SEND_DATA mtk_wcn_stp_send_data_f = NULL; -+MTK_WCN_STP_SEND_DATA mtk_wcn_stp_send_data_raw_f = NULL; -+MTK_WCN_STP_PARSER_DATA mtk_wcn_stp_parser_data_f = NULL; -+MTK_WCN_STP_RECV_DATA mtk_wcn_stp_receive_data_f = NULL; -+MTK_WCN_STP_IS_RXQ_EMPTY mtk_wcn_stp_is_rxqueue_empty_f = NULL; -+MTK_WCN_STP_IS_RDY mtk_wcn_stp_is_ready_f = NULL; -+MTK_WCN_STP_SET_BLUEZ mtk_wcn_stp_set_bluez_f = NULL; -+MTK_WCN_STP_REG_IF_TX mtk_wcn_stp_if_tx_f = NULL; -+MTK_WCN_STP_REG_IF_RX mtk_wcn_stp_if_rx_f = NULL; -+MTK_WCN_STP_REG_EVENT_CB mtk_wcn_stp_reg_event_cb_f = NULL; -+MTK_WCN_STP_RGE_TX_EVENT_CB mtk_wcn_stp_reg_tx_event_cb_f = NULL; -+MTK_WCN_STP_COREDUMP_START_GET mtk_wcn_stp_coredump_start_get_f = NULL; -+ -+/*WMT exp*/ -+MTK_WCN_WMT_FUNC_CTRL mtk_wcn_wmt_func_on_f = NULL; -+MTK_WCN_WMT_FUNC_CTRL mtk_wcn_wmt_func_off_f = NULL; -+MTK_WCN_WMT_THERM_CTRL mtk_wcn_wmt_therm_ctrl_f = NULL; -+MTK_WCN_WMT_HWVER_GET mtk_wcn_wmt_hwver_get_f = NULL; -+MTK_WCN_WMT_DSNS_CTRL mtk_wcn_wmt_dsns_ctrl_f = NULL; -+MTK_WCN_WMT_MSGCB_REG mtk_wcn_wmt_msgcb_reg_f = NULL; -+MTK_WCN_WMT_MSGCB_UNREG mtk_wcn_wmt_msgcb_unreg_f = NULL; -+MTK_WCN_WMT_SDIO_OP_REG mtk_wcn_wmt_sdio_op_reg_f = NULL; -+MTK_WCN_WMT_SDIO_HOST_AWAKE mtk_wcn_wmt_sdio_host_awake_f = NULL; -+MTK_WCN_WMT_ASSERT mtk_wcn_wmt_assert_f = NULL; -+MTK_WCN_WMT_ASSERT_TIMEOUT mtk_wcn_wmt_assert_timeout_f = NULL; -+MTK_WCN_WMT_IC_INFO_GET mtk_wcn_wmt_ic_info_get_f = NULL; -+MTK_WCN_WMT_PSM_CTRL mtk_wcn_wmt_psm_ctrl_f = NULL; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+UINT32 mtk_wcn_stp_exp_cb_reg(P_MTK_WCN_STP_EXP_CB_INFO pStpExpCb) -+{ -+ WMT_STP_EXP_INFO_FUNC("call stp exp cb reg\n"); -+ -+ mtk_wcn_stp_send_data_f = pStpExpCb->stp_send_data_cb; -+ mtk_wcn_stp_send_data_raw_f = pStpExpCb->stp_send_data_raw_cb; -+ mtk_wcn_stp_parser_data_f = pStpExpCb->stp_parser_data_cb; -+ mtk_wcn_stp_receive_data_f = pStpExpCb->stp_receive_data_cb; -+ mtk_wcn_stp_is_rxqueue_empty_f = pStpExpCb->stp_is_rxqueue_empty_cb; -+ mtk_wcn_stp_is_ready_f = pStpExpCb->stp_is_ready_cb; -+ mtk_wcn_stp_set_bluez_f = pStpExpCb->stp_set_bluez_cb; -+ mtk_wcn_stp_if_tx_f = pStpExpCb->stp_if_tx_cb; -+ mtk_wcn_stp_if_rx_f = pStpExpCb->stp_if_rx_cb; -+ mtk_wcn_stp_reg_event_cb_f = pStpExpCb->stp_reg_event_cb; -+ mtk_wcn_stp_reg_tx_event_cb_f = pStpExpCb->stp_reg_tx_event_cb; -+ mtk_wcn_stp_coredump_start_get_f = pStpExpCb->stp_coredump_start_get_cb; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_exp_cb_reg); -+ -+UINT32 mtk_wcn_stp_exp_cb_unreg(VOID) -+{ -+ WMT_STP_EXP_INFO_FUNC("call stp exp cb unreg\n"); -+ -+ mtk_wcn_stp_send_data_f = NULL; -+ mtk_wcn_stp_send_data_raw_f = NULL; -+ mtk_wcn_stp_parser_data_f = NULL; -+ mtk_wcn_stp_receive_data_f = NULL; -+ mtk_wcn_stp_is_rxqueue_empty_f = NULL; -+ mtk_wcn_stp_is_ready_f = NULL; -+ mtk_wcn_stp_set_bluez_f = NULL; -+ mtk_wcn_stp_if_tx_f = NULL; -+ mtk_wcn_stp_if_rx_f = NULL; -+ mtk_wcn_stp_reg_event_cb_f = NULL; -+ mtk_wcn_stp_reg_tx_event_cb_f = NULL; -+ mtk_wcn_stp_coredump_start_get_f = NULL; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_exp_cb_unreg); -+ -+INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_send_data_f) { -+ ret = (*mtk_wcn_stp_send_data_f) (buffer, length, type); -+ /* WMT_STP_EXP_INFO_FUNC("mtk_wcn_stp_send_data_f send data(%d)\n",ret); */ -+ } else { -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_send_data_f cb is null\n"); -+ } -+ -+ return ret; -+ -+} -+EXPORT_SYMBOL(mtk_wcn_stp_send_data); -+ -+INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_send_data_raw_f) -+ ret = (*mtk_wcn_stp_send_data_raw_f) (buffer, length, type); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_send_data_raw_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_send_data_raw); -+ -+INT32 mtk_wcn_stp_parser_data(PUINT8 buffer, UINT32 length) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_parser_data_f) -+ ret = (*mtk_wcn_stp_parser_data_f) (buffer, length); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_parser_data_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_parser_data); -+ -+INT32 mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_receive_data_f) -+ ret = (*mtk_wcn_stp_receive_data_f) (buffer, length, type); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_receive_data_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_receive_data); -+ -+MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_stp_is_rxqueue_empty_f) -+ ret = (*mtk_wcn_stp_is_rxqueue_empty_f) (type); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_is_rxqueue_empty_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_is_rxqueue_empty); -+ -+MTK_WCN_BOOL mtk_wcn_stp_is_ready(void) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_stp_is_ready_f) -+ ret = (*mtk_wcn_stp_is_ready_f) (); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_is_ready_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_is_ready); -+ -+void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL flags) -+{ -+ -+ if (mtk_wcn_stp_set_bluez_f) -+ (*mtk_wcn_stp_set_bluez_f) (flags); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_set_bluez_f cb is null\n"); -+ -+} -+EXPORT_SYMBOL(mtk_wcn_stp_set_bluez); -+ -+INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_if_tx_f) -+ ret = (*mtk_wcn_stp_if_tx_f) (stp_if, func); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_if_tx_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_register_if_tx); -+ -+INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_if_rx_f) -+ ret = (*mtk_wcn_stp_if_rx_f) (func); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_if_rx_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_register_if_rx); -+ -+INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_reg_event_cb_f) -+ ret = (*mtk_wcn_stp_reg_event_cb_f) (type, func); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_reg_event_cb_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_register_event_cb); -+ -+INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_reg_tx_event_cb_f) -+ ret = (*mtk_wcn_stp_reg_tx_event_cb_f) (type, func); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_reg_tx_event_cb_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_register_tx_event_cb); -+ -+INT32 mtk_wcn_stp_coredump_start_get(VOID) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_coredump_start_get_f) -+ ret = (*mtk_wcn_stp_coredump_start_get_f) (); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_coredump_start_get_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_coredump_start_get); -+ -+UINT32 mtk_wcn_wmt_exp_cb_reg(P_MTK_WCN_WMT_EXP_CB_INFO pWmtExpCb) -+{ -+ WMT_STP_EXP_INFO_FUNC("call wmt exp cb reg\n"); -+ -+ mtk_wcn_wmt_func_on_f = pWmtExpCb->wmt_func_on_cb; -+ mtk_wcn_wmt_func_off_f = pWmtExpCb->wmt_func_off_cb; -+ mtk_wcn_wmt_therm_ctrl_f = pWmtExpCb->wmt_therm_ctrl_cb; -+ mtk_wcn_wmt_hwver_get_f = pWmtExpCb->wmt_hwver_get_cb; -+ mtk_wcn_wmt_dsns_ctrl_f = pWmtExpCb->wmt_dsns_ctrl_cb; -+ mtk_wcn_wmt_msgcb_reg_f = pWmtExpCb->wmt_msgcb_reg_cb; -+ mtk_wcn_wmt_msgcb_unreg_f = pWmtExpCb->wmt_msgcb_unreg_cb; -+ mtk_wcn_wmt_sdio_op_reg_f = pWmtExpCb->wmt_sdio_op_reg_cb; -+ mtk_wcn_wmt_sdio_host_awake_f = pWmtExpCb->wmt_sdio_host_awake_cb; -+ mtk_wcn_wmt_assert_f = pWmtExpCb->wmt_assert_cb; -+ mtk_wcn_wmt_assert_timeout_f = pWmtExpCb->wmt_assert_timeout_cb; -+ mtk_wcn_wmt_ic_info_get_f = pWmtExpCb->wmt_ic_info_get_cb; -+ mtk_wcn_wmt_psm_ctrl_f = pWmtExpCb->wmt_psm_ctrl_cb; -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_exp_cb_reg); -+ -+UINT32 mtk_wcn_wmt_exp_cb_unreg(VOID) -+{ -+ WMT_STP_EXP_INFO_FUNC("call wmt exp cb unreg\n"); -+ -+ mtk_wcn_wmt_func_on_f = NULL; -+ mtk_wcn_wmt_func_off_f = NULL; -+ mtk_wcn_wmt_therm_ctrl_f = NULL; -+ mtk_wcn_wmt_hwver_get_f = NULL; -+ mtk_wcn_wmt_dsns_ctrl_f = NULL; -+ mtk_wcn_wmt_msgcb_reg_f = NULL; -+ mtk_wcn_wmt_msgcb_unreg_f = NULL; -+ mtk_wcn_wmt_sdio_op_reg_f = NULL; -+ mtk_wcn_wmt_sdio_host_awake_f = NULL; -+ mtk_wcn_wmt_assert_f = NULL; -+ mtk_wcn_wmt_assert_timeout_f = NULL; -+ mtk_wcn_wmt_ic_info_get_f = NULL; -+ mtk_wcn_wmt_psm_ctrl_f = NULL; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_exp_cb_unreg); -+ -+MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_wmt_func_off_f) -+ ret = (*mtk_wcn_wmt_func_off_f) (type); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_func_off_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_func_off); -+ -+MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_wmt_func_on_f) { -+ ret = (*mtk_wcn_wmt_func_on_f) (type); -+ WMT_STP_EXP_INFO_FUNC("mtk_wcn_wmt_func_on_f type(%d)\n", type); -+ } else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_func_on_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_func_on); -+ -+INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_wmt_therm_ctrl_f) -+ ret = (*mtk_wcn_wmt_therm_ctrl_f) (eType); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_therm_ctrl_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_therm_ctrl); -+ -+ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID) -+{ -+ ENUM_WMTHWVER_TYPE_T ret = WMTHWVER_INVALID; -+ -+ if (mtk_wcn_wmt_hwver_get_f) -+ ret = (*mtk_wcn_wmt_hwver_get_f) (); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_hwver_get_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_hwver_get); -+ -+MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_wmt_dsns_ctrl_f) -+ ret = (*mtk_wcn_wmt_dsns_ctrl_f) (eType); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_dsns_ctrl_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_dsns_ctrl); -+ -+INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) -+{ -+ INT32 ret = 0; -+ -+ if (mtk_wcn_wmt_msgcb_reg_f) -+ ret = (*mtk_wcn_wmt_msgcb_reg_f) (eType, pCb); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_msgcb_reg_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_reg); -+ -+INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) -+{ -+ INT32 ret = 0; -+ -+ if (mtk_wcn_wmt_msgcb_unreg_f) -+ ret = (*mtk_wcn_wmt_msgcb_unreg_f) (eType); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_msgcb_unreg_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_unreg); -+ -+INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_wmt_sdio_op_reg_f) -+ ret = (*mtk_wcn_wmt_sdio_op_reg_f) (own_cb); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_sdio_op_reg_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_op_reg); -+ -+INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_wmt_sdio_host_awake_f) -+ ret = (*mtk_wcn_wmt_sdio_host_awake_f) (); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_sdio_host_awake_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_host_awake); -+ -+MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_wmt_assert_f) -+ ret = (*mtk_wcn_wmt_assert_f) (type, reason); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_assert_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_assert); -+ -+MTK_WCN_BOOL mtk_wcn_wmt_assert_timeout(ENUM_WMTDRV_TYPE_T type, UINT32 reason, INT32 timeout) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_wmt_assert_timeout_f) -+ ret = (*mtk_wcn_wmt_assert_timeout_f)(type, reason, timeout); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_assert_timeout_f cb is null\n"); -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_assert_timeout); -+ -+UINT32 mtk_wcn_wmt_ic_info_get(ENUM_WMT_CHIPINFO_TYPE_T type) -+{ -+ UINT32 ret = 0; -+ -+ if (mtk_wcn_wmt_ic_info_get_f) -+ ret = (*mtk_wcn_wmt_ic_info_get_f) (type); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_ic_info_get_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_ic_info_get); -+ -+INT32 mtk_wcn_wmt_psm_ctrl(MTK_WCN_BOOL flag) -+{ -+ UINT32 ret = 0; -+ -+ if (mtk_wcn_wmt_psm_ctrl_f) -+ ret = (*mtk_wcn_wmt_psm_ctrl_f)(flag); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_psm_ctrl_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_psm_ctrl); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h -new file mode 100644 -index 0000000000000..1c3dc89652981 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h -@@ -0,0 +1,610 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef _WMT_STP_EXP_H_ -+#define _WMT_STP_EXP_H_ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "osal_typedef.h" -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 0 -+#endif -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ -+#if (WMT_IDC_SUPPORT) -+#define CFG_WMT_LTE_COEX_HANDLING 1 -+#define CFG_WMT_LTE_ENABLE_MSGID_MAPPING 0 -+#else -+#define CFG_WMT_LTE_COEX_HANDLING 0 -+#endif -+ -+/*from stp_exp.h*/ -+#define BT_TASK_INDX (0) -+#define FM_TASK_INDX (1) -+#define GPS_TASK_INDX (2) -+#define WIFI_TASK_INDX (3) -+#define WMT_TASK_INDX (4) -+#define STP_TASK_INDX (5) -+#define INFO_TASK_INDX (6) -+#define ANT_TASK_INDX (7) -+#if CFG_WMT_LTE_COEX_HANDLING -+#define COEX_TASK_INDX (8) -+#define MTKSTP_MAX_TASK_NUM (9) -+#else -+#define MTKSTP_MAX_TASK_NUM (8) -+#endif -+ -+#define MTKSTP_BUFFER_SIZE (16384) /* Size of RX Queue */ -+/*end from stp_exp.h*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+********************************************************************************/ -+ -+/*moved from stp_exp.h*/ -+typedef void (*MTK_WCN_STP_EVENT_CB) (void); -+typedef INT32(*MTK_WCN_STP_IF_TX) (const PUINT8 data, const UINT32 size, PUINT32 written_size); -+/* export for HIF driver */ -+typedef void (*MTK_WCN_STP_IF_RX) (const PUINT8 data, INT32 size); -+ -+typedef enum { -+ STP_UART_IF_TX = 0, -+ STP_SDIO_IF_TX = 1, -+ STP_BTIF_IF_TX = 2, -+ STP_MAX_IF_TX -+} ENUM_STP_TX_IF_TYPE; -+ -+/*end moved from stp_exp.h*/ -+ -+typedef INT32(*MTK_WCN_STP_SEND_DATA) (const PUINT8 buffer, const UINT32 length, const UINT8 type); -+typedef INT32(*MTK_WCN_STP_PARSER_DATA) (PUINT8 buffer, UINT32 length); -+typedef INT32(*MTK_WCN_STP_RECV_DATA) (PUINT8 buffer, UINT32 length, UINT8 type); -+typedef MTK_WCN_BOOL(*MTK_WCN_STP_IS_RXQ_EMPTY) (UINT8 type); -+typedef MTK_WCN_BOOL(*MTK_WCN_STP_IS_RDY) (VOID); -+typedef VOID(*MTK_WCN_STP_SET_BLUEZ) (MTK_WCN_BOOL flags); -+typedef INT32(*MTK_WCN_STP_REG_IF_TX) (ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); -+typedef INT32(*MTK_WCN_STP_REG_IF_RX) (MTK_WCN_STP_IF_RX func); -+typedef INT32(*MTK_WCN_STP_REG_EVENT_CB) (INT32 type, MTK_WCN_STP_EVENT_CB func); -+typedef INT32(*MTK_WCN_STP_RGE_TX_EVENT_CB) (INT32 type, MTK_WCN_STP_EVENT_CB func); -+typedef INT32(*MTK_WCN_STP_COREDUMP_START_GET)(VOID); -+ -+typedef struct _MTK_WCN_STP_EXP_CB_INFO_ { -+ MTK_WCN_STP_SEND_DATA stp_send_data_cb; -+ MTK_WCN_STP_SEND_DATA stp_send_data_raw_cb; -+ MTK_WCN_STP_PARSER_DATA stp_parser_data_cb; -+ MTK_WCN_STP_RECV_DATA stp_receive_data_cb; -+ MTK_WCN_STP_IS_RXQ_EMPTY stp_is_rxqueue_empty_cb; -+ MTK_WCN_STP_IS_RDY stp_is_ready_cb; -+ MTK_WCN_STP_SET_BLUEZ stp_set_bluez_cb; -+ MTK_WCN_STP_REG_IF_TX stp_if_tx_cb; -+ MTK_WCN_STP_REG_IF_RX stp_if_rx_cb; -+ MTK_WCN_STP_REG_EVENT_CB stp_reg_event_cb; -+ MTK_WCN_STP_RGE_TX_EVENT_CB stp_reg_tx_event_cb; -+ MTK_WCN_STP_COREDUMP_START_GET stp_coredump_start_get_cb; -+} MTK_WCN_STP_EXP_CB_INFO, *P_MTK_WCN_STP_EXP_CB_INFO; -+ -+/*moved from wmt_exp.h*/ -+ -+typedef enum _ENUM_WMTDRV_TYPE_T { -+ WMTDRV_TYPE_BT = 0, -+ WMTDRV_TYPE_FM = 1, -+ WMTDRV_TYPE_GPS = 2, -+ WMTDRV_TYPE_WIFI = 3, -+ WMTDRV_TYPE_WMT = 4, -+ WMTDRV_TYPE_ANT = 5, -+ WMTDRV_TYPE_STP = 6, -+ WMTDRV_TYPE_SDIO1 = 7, -+ WMTDRV_TYPE_SDIO2 = 8, -+ WMTDRV_TYPE_LPBK = 9, -+ WMTDRV_TYPE_COREDUMP = 10, -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+ WMTDRV_TYPE_AUTOK = 11, -+#endif -+ WMTDRV_TYPE_MAX -+} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T; -+ -+typedef enum _ENUM_WMTDSNS_TYPE_T { -+ WMTDSNS_FM_DISABLE = 0, -+ WMTDSNS_FM_ENABLE = 1, -+ WMTDSNS_FM_GPS_DISABLE = 2, -+ WMTDSNS_FM_GPS_ENABLE = 3, -+ WMTDSNS_MAX -+} ENUM_WMTDSNS_TYPE_T, *P_ENUM_WMTDSNS_TYPE_T; -+ -+typedef enum _ENUM_WMTHWVER_TYPE_T { -+ WMTHWVER_E1 = 0x0, -+ WMTHWVER_E2 = 0x1, -+ WMTHWVER_E3 = 0x2, -+ WMTHWVER_E4 = 0x3, -+ WMTHWVER_E5 = 0x4, -+ WMTHWVER_E6 = 0x5, -+ WMTHWVER_E7 = 0x6, -+ WMTHWVER_MAX, -+ WMTHWVER_INVALID = 0xff -+} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T; -+ -+typedef enum _ENUM_WMTTHERM_TYPE_T { -+ WMTTHERM_ZERO = 0, -+ WMTTHERM_ENABLE = WMTTHERM_ZERO + 1, -+ WMTTHERM_READ = WMTTHERM_ENABLE + 1, -+ WMTTHERM_DISABLE = WMTTHERM_READ + 1, -+ WMTTHERM_MAX -+} ENUM_WMTTHERM_TYPE_T, *P_ENUM_WMTTHERM_TYPE_T; -+ -+typedef enum _ENUM_WMTMSG_TYPE_T { -+ WMTMSG_TYPE_POWER_ON = 0, -+ WMTMSG_TYPE_POWER_OFF = 1, -+ WMTMSG_TYPE_RESET = 2, -+ WMTMSG_TYPE_STP_RDY = 3, -+ WMTMSG_TYPE_HW_FUNC_ON = 4, -+ WMTMSG_TYPE_MAX -+} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T; -+ -+typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T, /* Source driver type */ -+ ENUM_WMTDRV_TYPE_T, /* Destination driver type */ -+ ENUM_WMTMSG_TYPE_T, /* Message type */ -+ VOID *, /* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client -+ can't touch this buffer after this function return. */ -+ UINT32 /* Buffer size in unit of byte */ -+); -+ -+typedef enum _SDIO_PS_OP { -+ OWN_SET = 0, -+ OWN_CLR = 1, -+ OWN_STATE = 2, -+} SDIO_PS_OP; -+ -+typedef INT32(*PF_WMT_SDIO_PSOP) (SDIO_PS_OP); -+ -+typedef enum _ENUM_WMTCHIN_TYPE_T { -+ WMTCHIN_CHIPID = 0x0, -+ WMTCHIN_HWVER = WMTCHIN_CHIPID + 1, -+ WMTCHIN_MAPPINGHWVER = WMTCHIN_HWVER + 1, -+ WMTCHIN_FWVER = WMTCHIN_MAPPINGHWVER + 1, -+ WMTCHIN_MAX, -+ -+} ENUM_WMT_CHIPINFO_TYPE_T, *P_ENUM_WMT_CHIPINFO_TYPE_T; -+ -+/*end moved from wmt_exp.h*/ -+ -+typedef MTK_WCN_BOOL(*MTK_WCN_WMT_FUNC_CTRL) (ENUM_WMTDRV_TYPE_T type); -+typedef INT8(*MTK_WCN_WMT_THERM_CTRL) (ENUM_WMTTHERM_TYPE_T eType); -+typedef ENUM_WMTHWVER_TYPE_T(*MTK_WCN_WMT_HWVER_GET) (VOID); -+typedef MTK_WCN_BOOL(*MTK_WCN_WMT_DSNS_CTRL) (ENUM_WMTDSNS_TYPE_T eType); -+typedef INT32(*MTK_WCN_WMT_MSGCB_REG) (ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); -+typedef INT32(*MTK_WCN_WMT_MSGCB_UNREG) (ENUM_WMTDRV_TYPE_T eType); -+typedef INT32(*MTK_WCN_WMT_SDIO_OP_REG) (PF_WMT_SDIO_PSOP own_cb); -+typedef INT32(*MTK_WCN_WMT_SDIO_HOST_AWAKE) (VOID); -+typedef MTK_WCN_BOOL(*MTK_WCN_WMT_ASSERT) (ENUM_WMTDRV_TYPE_T type, UINT32 reason); -+typedef MTK_WCN_BOOL(*MTK_WCN_WMT_ASSERT_TIMEOUT)(ENUM_WMTDRV_TYPE_T type, -+ UINT32 reason, INT32 timeout); -+typedef UINT32(*MTK_WCN_WMT_IC_INFO_GET) (ENUM_WMT_CHIPINFO_TYPE_T type); -+typedef INT32 (*MTK_WCN_WMT_PSM_CTRL)(MTK_WCN_BOOL flag); -+ -+typedef struct _MTK_WCN_WMT_EXP_CB_INFO_ { -+ MTK_WCN_WMT_FUNC_CTRL wmt_func_on_cb; -+ MTK_WCN_WMT_FUNC_CTRL wmt_func_off_cb; -+ MTK_WCN_WMT_THERM_CTRL wmt_therm_ctrl_cb; -+ MTK_WCN_WMT_HWVER_GET wmt_hwver_get_cb; -+ MTK_WCN_WMT_DSNS_CTRL wmt_dsns_ctrl_cb; -+ MTK_WCN_WMT_MSGCB_REG wmt_msgcb_reg_cb; -+ MTK_WCN_WMT_MSGCB_UNREG wmt_msgcb_unreg_cb; -+ MTK_WCN_WMT_SDIO_OP_REG wmt_sdio_op_reg_cb; -+ MTK_WCN_WMT_SDIO_HOST_AWAKE wmt_sdio_host_awake_cb; -+ MTK_WCN_WMT_ASSERT wmt_assert_cb; -+ MTK_WCN_WMT_ASSERT_TIMEOUT wmt_assert_timeout_cb; -+ MTK_WCN_WMT_IC_INFO_GET wmt_ic_info_get_cb; -+ MTK_WCN_WMT_PSM_CTRL wmt_psm_ctrl_cb; -+} MTK_WCN_WMT_EXP_CB_INFO, *P_MTK_WCN_WMT_EXP_CB_INFO; -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/*exp for WMT/STP register callback*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_exp_cb_reg -+* DESCRIPTION -+* stp driver reigster exp symbols -+* PARAMETERS -+* pStpExpCb [IN] stp callback structure pointer -+* RETURNS -+* UINT32 = 0: OK -+*****************************************************************************/ -+UINT32 mtk_wcn_stp_exp_cb_reg(P_MTK_WCN_STP_EXP_CB_INFO pStpExpCb); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_exp_cb_unreg -+* DESCRIPTION -+* stp driver unreigster exp symbols -+* PARAMETERS -+* VOID -+* RETURNS -+* UINT32 = 0: OK -+*****************************************************************************/ -+UINT32 mtk_wcn_stp_exp_cb_unreg(VOID); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_exp_cb_reg -+* DESCRIPTION -+* WMT driver reigster exp symbols -+* PARAMETERS -+* pStpExpCb [IN] wmt callback structure pointer -+* RETURNS -+* UINT32 = 0: OK -+*****************************************************************************/ -+UINT32 mtk_wcn_wmt_exp_cb_reg(P_MTK_WCN_WMT_EXP_CB_INFO pWmtExpCb); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_exp_cb_unreg -+* DESCRIPTION -+* wmt driver unreigster exp symbols -+* PARAMETERS -+* VOID -+* RETURNS -+* UINT32 = 0: OK -+*****************************************************************************/ -+UINT32 mtk_wcn_wmt_exp_cb_unreg(VOID); -+ -+/*stp exp symbols*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data -+* DESCRIPTION -+* subfunction send data through STP -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 >= 0: length transmitted; < 0: error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data_raw -+* DESCRIPTION -+* subfunction send data through STP without seq/ack -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 >= 0: length transmitted; < 0: error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_parser_data -+* DESCRIPTION -+* push data to serial transport protocol parser engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* void -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_parser_data(PUINT8 buffer, UINT32 length); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_receive_data -+* DESCRIPTION -+* receive data from serial protocol engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* INT32 >= 0: size of data received; < 0: error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_rxqueue_empty -+* DESCRIPTION -+* Is certain rx queue empty? -+* PARAMETERS -+* type [IN] subfunction type -+* RETURNS -+* INT32 0: queue is NOT empyt; !0: queue is empty -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_enable -+* DESCRIPTION -+* Is STP ready? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:ready, FALSE:not ready -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_ready(void); -+ -+/***************************************************************************** -+* FUNCTION -+* set_bluetooth_rx_interface -+* DESCRIPTION -+* Set bluetooth rx interface -+* PARAMETERS -+* rx interface type -+* RETURNS -+* void -+*****************************************************************************/ -+extern void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL flags); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_if_tx -+* DESCRIPTION -+* regiter Tx event callback function -+* PARAMETERS -+* stp_if: SDIO or UART, fnnc: Call back function -+* RETURNS -+* INT32: 0:successful , -1: fail -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_if_rx -+* DESCRIPTION -+* regiter Rx event callback function -+* PARAMETERS -+* stp_if: SDIO or UART, fnnc: Call back function -+* RETURNS -+* INT32: 0:successful , -1: fail -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_event_cb -+* DESCRIPTION -+* regiter Rx event callback function -+* PARAMETERS -+* func -+* RETURNS -+* INT32: 0:successful , -1: fail -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_tx_event_cb -+* DESCRIPTION -+* regiter Tx event callback function -+* PARAMETERS -+* func -+* RETURNS -+* INT32: 0:successful , -1: fail -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_coredump_start_get -+* DESCRIPTION -+* get coredump flag is set or not -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32: 0:coredump flag is not set , 1: coredump flag is set -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_coredump_start_get(VOID); -+ -+/*wmt exp symbols*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_func_off -+* DESCRIPTION -+* wmt turn off subsystem -+* PARAMETERS -+* type [IN] subsystem type -+* RETURNS -+* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_func_on -+* DESCRIPTION -+* wmt turn on subsystem -+* PARAMETERS -+* type [IN] subsystem type -+* RETURNS -+* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_therm_ctrl -+* DESCRIPTION -+* query chip temperature by WMT CMD -+* PARAMETERS -+* eType [IN] thermal ctrl type -+* RETURNS -+* >=0: chip temperature; 0xff:error -+*****************************************************************************/ -+extern INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_hwver_get -+* DESCRIPTION -+* get chip hardware version -+* PARAMETERS -+* VOID -+* RETURNS -+* >=0: chip hw version; 0xff:error -+*****************************************************************************/ -+extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_ic_info_get -+* DESCRIPTION -+* get chip hardware version or f/w version -+* PARAMETERS -+* type : which kind of information is needed -+* RETURNS -+* f/w version or hw version information -+*****************************************************************************/ -+extern UINT32 mtk_wcn_wmt_ic_info_get(ENUM_WMT_CHIPINFO_TYPE_T type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_dsns_ctrl -+* DESCRIPTION -+* fm dsns cmd ctrl -+* PARAMETERS -+* eType [IN] fm dsns ctrl type -+* RETURNS -+* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_msgcb_reg -+* DESCRIPTION -+* used for subsystem register chip reset callback for received wmt reset msg. -+* PARAMETERS -+* eType [IN] subsystem type -+* pCb [IN] rst callback -+* RETURNS -+* 1: OK; 0:error -+*****************************************************************************/ -+extern INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_msgcb_unreg -+* DESCRIPTION -+* used for subsystem unregister chip reset callback for received wmt reset msg. -+* PARAMETERS -+* eType [IN] subsystem type -+* RETURNS -+* 1: OK; 0:error -+*****************************************************************************/ -+extern INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_wmt_sdio_op_reg -+* DESCRIPTION -+* used to register callback for set sdio ownership. -+* PARAMETERS -+* own_cb [IN] set owner ship callback -+* RETURNS -+* always return 0; -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_wmt_sdio_host_awake -+* DESCRIPTION -+* handing host awake when link is stp sdio? -+* PARAMETERS -+* VOID -+* RETURNS -+* always return 0; -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_assert -+* DESCRIPTION -+* host trigger firmware assert -+* PARAMETERS -+* type [IN] subsystem driver type -+* reason [IN] trigger assert reason -+* RETURNS -+* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); -+ -+/***************************************************************************** -+ * * FUNCTION -+ * * mtk_wcn_wmt_assert_timeout -+ * * DESCRIPTION -+ * * host trigger firmware assert -+ * * PARAMETERS -+ * * type [IN] subsystem driver type -+ * * reason [IN] trigger assert reason -+ * * timeout [IN] trigger assert timeout data -+ * * RETURNS -+ * * MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error -+ * *****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_assert_timeout(ENUM_WMTDRV_TYPE_T type, -+ UINT32 reason, INT32 timeout); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_psm_ctrl -+* DESCRIPTION -+* disable/enable psm -+* PARAMETERS -+* flag [IN] disable:0, enable:1 -+* RETURNS -+* always return 0; -+*****************************************************************************/ -+extern INT32 mtk_wcn_wmt_psm_ctrl(MTK_WCN_BOOL flag); -+ -+#endif -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile -new file mode 100644 -index 0000000000000..286bfd4bfed36 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile -@@ -0,0 +1,65 @@ -+subdir-ccflags-y += \ -+ -I$(src)/linux/include \ -+ -I$(src)/linux/pri/include \ -+ -I$(src)/core/include \ -+ -I$(src)/include \ -+ -I$(src)/../common_detect \ -+ -I$(srctree)/drivers/misc/mediatek/btif/common/inc -+ -+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci/ -+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci/$(MTK_PLATFORM) -+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eemcs/ -+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/conn_md/include -+ -+EXT_FLAG=_soc -+COMMON_SRC_PATH := $(src) -+COMMON_OBJ_PATH := $(src) -+ -+ifeq ($(CONFIG_ARCH_MT6580), y) -+subdir-ccflags-y += -D CFG_WMT_READ_EFUSE_VCN33 -+endif -+ -+ifeq ($(CONFIG_MTK_COMBO), m) -+# WMT DRIVER -+obj-$(CONFIG_MTK_COMBO) += mtk_stp_wmt$(EXT_FLAG).o -+# WMT DRIVER-core part -+mtk_stp_wmt$(EXT_FLAG)-objs := core/wmt_core.o core/wmt_ctrl.o core/wmt_func.o core/wmt_ic_soc.o core/wmt_lib.o core/wmt_conf.o -+ -+ -+# WMT DRIVER-linux private part -+mtk_stp_wmt$(EXT_FLAG)-objs += linux/pri/wmt_dev.o linux/pri/wmt_exp.o -+mtk_stp_wmt$(EXT_FLAG)-objs += linux/pri/stp_btif.o -+ -+ -+# WMT DRIVER-OSAL -+mtk_stp_wmt$(EXT_FLAG)-objs += linux/pub/osal.o linux/pub/bgw_desense.o -+# WMT DRIVER-platform implementation -+# ccflags-y += -D WMT_PLAT_ALPS -+# mtk_stp_wmt$(EXT_FLAG)-objs += platform/alps/wmt_plat_alps.o -+ -+# mtk_stp_wmt$(EXT_FLAG)-objs += platform/alps/mtk_wcn_consys_hw.o -+ -+ -+mtk_stp_wmt$(EXT_FLAG)-objs += linux/pri/stp_exp.o core/stp_core.o core/psm_core.o core/btm_core.o linux/pri/stp_dbg.o -+ -+# WMT stub part (built-in kernel image) -+# obj-y += platform/alps/mtk_wcn_consys_stub_alps.o -+ -+ -+ -+obj-$(CONFIG_MTK_COMBO_BT) += mtk_stp_bt$(EXT_FLAG).o -+mtk_stp_bt$(EXT_FLAG)-objs := linux/pub/stp_chrdev_bt.o -+ -+ -+obj-$(CONFIG_MTK_COMBO_WIFI) += mtk_wmt_wifi$(EXT_FLAG).o -+mtk_wmt_wifi$(EXT_FLAG)-objs := linux/pub/wmt_chrdev_wifi.o -+ -+endif -+ -+ifeq ($(CONFIG_MTK_COMBO), y) -+# subdir-ccflags-y += -D WMT_PLAT_ALPS -+obj-y += core/ -+obj-y += linux/ -+#obj-y += $(subst ",,$(CONFIG_MTK_PLATFORM))/ -+obj-y += mt7623/ -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile -new file mode 100644 -index 0000000000000..9df71b9e163ea ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile -@@ -0,0 +1,22 @@ -+ifeq ($(CONFIG_MTK_COMBO), y) -+ -+ccflags-y += \ -+ -I$(src)/../linux/include \ -+ -I$(src)/../linux/pri/include \ -+ -I$(src)/../core/include \ -+ -I$(src)/../include \ -+ -I$(src)/../../common_detect \ -+ -I$(srctree)/drivers/misc/mediatek/btif/common/inc \ -+ -+obj-y += wmt_core.o \ -+ wmt_ctrl.o \ -+ wmt_func.o \ -+ wmt_ic_soc.o \ -+ wmt_lib.o \ -+ wmt_conf.o \ -+ btm_core.o \ -+ dbg_core.o \ -+ psm_core.o \ -+ stp_core.o -+ -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c -new file mode 100644 -index 0000000000000..4946b682d8266 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c -@@ -0,0 +1,1376 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+#include -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "stp_dbg.h" -+#include "stp_core.h" -+#include "btm_core.h" -+#include "wmt_plat.h" -+ -+#define PFX_BTM "[STP-BTM] " -+#define STP_BTM_LOG_LOUD 4 -+#define STP_BTM_LOG_DBG 3 -+#define STP_BTM_LOG_INFO 2 -+#define STP_BTM_LOG_WARN 1 -+#define STP_BTM_LOG_ERR 0 -+ -+INT32 gBtmDbgLevel = STP_BTM_LOG_INFO; -+ -+#define STP_BTM_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_LOUD) \ -+ pr_debug(PFX_BTM "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_BTM_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_DBG) \ -+ pr_debug(PFX_BTM "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_BTM_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_INFO) \ -+ pr_debug(PFX_BTM "[I]%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_BTM_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_WARN) \ -+ pr_warn(PFX_BTM "[W]%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_BTM_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_ERR) \ -+ pr_err(PFX_BTM "[E]%s(%d):ERROR! " fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+#define STP_BTM_TRC_FUNC(f) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_DBG) \ -+ pr_debug(PFX_BTM "<%s> <%d>\n", __func__, __LINE__); \ -+} while (0) -+ -+#define ASSERT(expr) -+ -+MTKSTP_BTM_T stp_btm_i; -+MTKSTP_BTM_T *stp_btm = &stp_btm_i; -+ -+const char *g_btm_op_name[] = { -+ "STP_OPID_BTM_RETRY", -+ "STP_OPID_BTM_RST", -+ "STP_OPID_BTM_DBG_DUMP", -+ "STP_OPID_BTM_DUMP_TIMEOUT", -+ "STP_OPID_BTM_POLL_CPUPCR", -+ "STP_OPID_BTM_PAGED_DUMP", -+ "STP_OPID_BTM_FULL_DUMP", -+ "STP_OPID_BTM_PAGED_TRACE", -+ "STP_OPID_BTM_FORCE_FW_ASSERT", -+#if CFG_WMT_LTE_COEX_HANDLING -+ "STP_OPID_BTM_WMT_LTE_COEX", -+#endif -+ "STP_OPID_BTM_EXIT" -+}; -+ -+#if 0 -+static char *_stp_pkt_type(int type) -+{ -+ -+ static char s[10]; -+ -+ switch (type) { -+ case WMT_TASK_INDX: -+ osal_memcpy(s, "WMT", strlen("WMT") + 1); -+ break; -+ case BT_TASK_INDX: -+ osal_memcpy(s, "BT", strlen("BT") + 1); -+ break; -+ case GPS_TASK_INDX: -+ osal_memcpy(s, "GPS", strlen("GPS") + 1); -+ break; -+ case FM_TASK_INDX: -+ osal_memcpy(s, "FM", strlen("FM") + 1); -+ break; -+ default: -+ osal_memcpy(s, "UNKNOWN", strlen("UNKNOWN") + 1); -+ break; -+ } -+ -+ return s; -+} -+#endif -+ -+static INT32 _stp_btm_put_dump_to_nl(void) -+{ -+#define NUM_FETCH_ENTRY 8 -+ -+ static UINT8 buf[2048]; -+ static UINT8 tmp[2048]; -+ -+ UINT32 buf_len; -+ STP_PACKET_T *pkt; -+ STP_DBG_HDR_T *hdr; -+ INT32 len; -+ INT32 remain = 0, index = 0; -+ INT32 retry = 0, rc = 0, nl_retry = 0; -+ -+ STP_BTM_INFO_FUNC("Enter..\n"); -+ -+ index = 0; -+ tmp[index++] = '['; -+ tmp[index++] = 'M'; -+ tmp[index++] = ']'; -+ -+ do { -+ index = 3; -+ remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len); -+ if (buf_len > 0) { -+ pkt = (STP_PACKET_T *) buf; -+ hdr = &pkt->hdr; -+ len = pkt->hdr.len; -+ osal_memcpy(&tmp[index], &len, 2); -+ index += 2; -+ if (hdr->dbg_type == STP_DBG_FW_DMP) { -+ osal_memcpy(&tmp[index], pkt->raw, len); -+ -+ if (len <= 1500) { -+ /* pr_warn("\n%s\n+++\n", tmp); */ -+ /* pr_warn("send coredump len:%d\n", len); */ -+ /* pr_warn("send coredump:%s\n", tmp); */ -+ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len+5); -+ -+ while (rc) { -+ nl_retry++; -+ if (nl_retry > 1000) -+ break; -+ STP_BTM_WARN_FUNC -+ ("**dump send fails, and retry again.**\n"); -+ osal_sleep_ms(3); -+ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len+5); -+ if (!rc) -+ STP_BTM_WARN_FUNC("****retry again ok!**\n"); -+ } -+ /* schedule(); */ -+ } else { -+ STP_BTM_INFO_FUNC("dump entry length is over long\n"); -+ BUG_ON(0); -+ } -+ retry = 0; -+ } -+ } else { -+ retry++; -+ osal_sleep_ms(100); -+ } -+ } while ((remain > 0) || (retry < 2)); -+ -+ STP_BTM_INFO_FUNC("Exit..\n"); -+ return 0; -+} -+ -+#define SUB_PKT_SIZE 1024 -+#define SUB_PKT_HEADER 5 /*'[M]',3Bytes; len,2Bytes*/ -+ -+INT32 _stp_btm_put_emi_dump_to_nl(PUINT8 data_buf, INT32 dump_len) -+{ -+ static UINT8 tmp[SUB_PKT_SIZE + SUB_PKT_HEADER]; -+ -+ INT32 remain = dump_len, index = 0; -+ INT32 rc = 0, nl_retry = 0; -+ INT32 len; -+ INT32 offset = 0; -+ -+ STP_BTM_INFO_FUNC("Enter..\n"); -+ -+ if (dump_len > 0) { -+ index = 0; -+ tmp[index++] = '['; -+ tmp[index++] = 'M'; -+ tmp[index++] = ']'; -+ -+ do { -+ index = 3; -+ if (remain >= SUB_PKT_SIZE) -+ len = SUB_PKT_SIZE; -+ else -+ len = remain; -+ remain -= len; -+ -+ osal_memcpy(&tmp[index], &len, 2); -+ index += 2; -+ osal_memcpy(&tmp[index], data_buf + offset, len); -+ offset += len; -+ STP_BTM_DBG_FUNC -+ ("send %d remain %d\n", len, remain); -+ -+ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len + SUB_PKT_HEADER); -+ while (rc) { -+ nl_retry++; -+ if (nl_retry > 1000) -+ break; -+ STP_BTM_WARN_FUNC -+ ("**dump send fails, and retry again.**\n"); -+ osal_sleep_ms(3); -+ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len + SUB_PKT_HEADER); -+ if (!rc) { -+ STP_BTM_WARN_FUNC -+ ("****retry again ok!**\n"); -+ } -+ } -+ /* schedule(); */ -+ } while (remain > 0); -+ } else -+ STP_BTM_INFO_FUNC("dump entry length is 0\n"); -+ -+ STP_BTM_INFO_FUNC("Exit..\n"); -+ return 0; -+} -+ -+static INT32 _stp_btm_put_dump_to_aee(void) -+{ -+ static UINT8 buf[2048]; -+ static UINT8 tmp[2048]; -+ -+ UINT32 buf_len; -+ STP_PACKET_T *pkt; -+ STP_DBG_HDR_T *hdr; -+ INT32 remain = 0; -+ INT32 retry = 0; -+ INT32 ret = 0; -+ -+ STP_BTM_INFO_FUNC("Enter..\n"); -+ -+ do { -+ remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len); -+ if (buf_len > 0) { -+ pkt = (STP_PACKET_T *) buf; -+ hdr = &pkt->hdr; -+ if (hdr->dbg_type == STP_DBG_FW_DMP) { -+ memcpy(&tmp[0], pkt->raw, pkt->hdr.len); -+ -+ if (pkt->hdr.len <= 1500) { -+ tmp[pkt->hdr.len] = '\n'; -+ tmp[pkt->hdr.len + 1] = '\0'; -+ -+ ret = stp_dbg_aee_send(tmp, pkt->hdr.len, 0); -+ } else { -+ STP_BTM_INFO_FUNC("dump entry length is over long\n"); -+ BUG_ON(0); -+ } -+ retry = 0; -+ } -+ } else { -+ retry++; -+ msleep(100); -+ } -+ } while ((remain > 0) || (retry < 2)); -+ -+ STP_BTM_INFO_FUNC("Exit..\n"); -+ return ret; -+} -+ -+#if 0 -+INT32 _stp_trigger_firmware_assert_via_emi(VOID) -+{ -+ PUINT8 p_virtual_addr = NULL; -+ INT32 status = -1; -+ INT32 i = 0, j = 0; -+ -+ do { -+ STP_BTM_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi -->\n"); -+ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1); -+ if (!p_virtual_addr) { -+ STP_BTM_ERR_FUNC("get virtual address fail\n"); -+ return -1; -+ } -+ -+ CONSYS_REG_WRITE(p_virtual_addr, EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1); -+ STP_BTM_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi <--\n"); -+#if 1 -+ /* wait for firmware assert */ -+ osal_sleep_ms(50); -+ /* if firmware is not assert self, host driver helps it. */ -+ do { -+ if (0 != mtk_wcn_stp_coredump_start_get()) { -+ status = 0; -+ break; -+ } -+ -+ mtk_wcn_stp_wakeup_consys(); -+ STP_BTM_INFO_FUNC("[Force Assert] wakeup consys (%d)\n", i); -+ stp_dbg_poll_cpupcr(5, 1, 1); -+ osal_sleep_ms(5); -+ -+ i++; -+ if (i > 20) { -+ i = 0; -+ break; -+ } -+ } while (1); -+#endif -+ -+ if (0 != mtk_wcn_stp_coredump_start_get()) { -+ status = 0; -+ break; -+ } -+ -+ j++; -+ if (j > 8) { -+ j = 0; -+ break; -+ } -+ } while (1); -+ -+ return status; -+} -+#else -+INT32 _stp_trigger_firmware_assert_via_emi(VOID) -+{ -+ INT32 status = -1; -+ INT32 j = 0; -+ -+ wmt_plat_force_trigger_assert(STP_FORCE_TRG_ASSERT_DEBUG_PIN); -+ -+ do { -+ if (0 != mtk_wcn_stp_coredump_start_get()) { -+ status = 0; -+ break; -+ } -+ -+ stp_dbg_poll_cpupcr(5, 1, 1); -+ stp_dbg_poll_dmaregs(5, 1); -+ j++; -+ STP_BTM_INFO_FUNC("Wait for assert message (%d)\n", j); -+ osal_sleep_ms(20); -+ if (j > 49) { /* wait for 1 second */ -+ stp_dbg_set_fw_info("host trigger fw assert timeout", -+ osal_strlen("host trigger fw assert timeout"), -+ STP_HOST_TRIGGER_ASSERT_TIMEOUT); -+ wcn_core_dump_timeout(); /* trigger collect SYS_FTRACE */ -+ break; -+ } -+ } while (1); -+ -+ return status; -+} -+#endif -+ -+#define COMBO_DUMP2AEE -+#if 1 -+#define STP_DBG_PAGED_DUMP_BUFFER_SIZE (32*1024*sizeof(char)) -+UINT8 g_paged_dump_buffer[STP_DBG_PAGED_DUMP_BUFFER_SIZE] = { 0 }; -+ -+#define STP_DBG_PAGED_TRACE_SIZE (2048*sizeof(char)) -+UINT8 g_paged_trace_buffer[STP_DBG_PAGED_TRACE_SIZE] = { 0 }; -+ -+UINT32 g_paged_dump_len = 0; -+UINT32 g_paged_trace_len = 0; -+VOID _stp_dump_emi_dump_buffer(UINT8 *buffer, UINT32 len) -+{ -+ UINT32 i = 0; -+ -+ if (len > 16) -+ len = 16; -+ for (i = 0; i < len; i++) { -+ if (i % 16 == 0 && i != 0) -+ pr_cont("\n "); -+ -+ if (buffer[i] == ']' || buffer[i] == '[' || buffer[i] == ',') -+ pr_cont("%c", buffer[i]); -+ else -+ pr_cont("0x%02x ", buffer[i]); -+ } -+} -+#endif -+static INT32 _stp_btm_handler(MTKSTP_BTM_T *stp_btm, P_STP_BTM_OP pStpOp) -+{ -+ INT32 ret = -1; -+ INT32 dump_sink = 1; /* core dump target, 0: aee; 1: netlink */ -+ INT32 Ret = 0; -+ static UINT32 counter; -+ UINT32 full_dump_left = STP_FULL_DUMP_TIME; -+ UINT32 page_counter = 0; -+ UINT32 packet_num = STP_PAGED_DUMP_TIME_LIMIT/100; -+ UINT32 dump_num = 0; -+ ENUM_STP_FW_ISSUE_TYPE issue_type; -+ P_CONSYS_EMI_ADDR_INFO p_ecsi; -+ -+ p_ecsi = wmt_plat_get_emi_phy_add(); -+ osal_assert(p_ecsi); -+ if (NULL == pStpOp) -+ return -1; -+ -+ switch (pStpOp->opId) { -+ case STP_OPID_BTM_EXIT: -+ /* TODO: clean all up? */ -+ ret = 0; -+ break; -+ -+ /*tx timeout retry */ -+ case STP_OPID_BTM_RETRY: -+ stp_do_tx_timeout(); -+ ret = 0; -+ -+ break; -+ -+ /*whole chip reset */ -+ case STP_OPID_BTM_RST: -+ STP_BTM_INFO_FUNC("whole chip reset start!\n"); -+ STP_BTM_INFO_FUNC("....+\n"); -+ if (stp_btm->wmt_notify) { -+ stp_btm->wmt_notify(BTM_RST_OP); -+ ret = 0; -+ } else { -+ STP_BTM_ERR_FUNC("stp_btm->wmt_notify is NULL."); -+ ret = -1; -+ } -+ -+ STP_BTM_INFO_FUNC("whole chip reset end!\n"); -+ -+ break; -+ -+ case STP_OPID_BTM_DBG_DUMP: -+ /*Notify the wmt to get dump data */ -+ STP_BTM_DBG_FUNC("wmt dmp notification\n"); -+ dump_sink = ((stp_btm->wmt_notify(BTM_GET_AEE_SUPPORT_FLAG) == MTK_WCN_BOOL_TRUE) ? 0 : 1); -+ -+ if (dump_sink == 0) -+ _stp_btm_put_dump_to_aee(); -+ else if (dump_sink == 1) -+ _stp_btm_put_dump_to_nl(); -+ else -+ STP_BTM_ERR_FUNC("unknown sink %d\n", dump_sink); -+ -+ break; -+ -+ case STP_OPID_BTM_DUMP_TIMEOUT: -+ /* Flush dump data, and reset compressor */ -+ STP_BTM_INFO_FUNC("Flush dump data\n"); -+ wcn_core_dump_flush(0, MTK_WCN_BOOL_TRUE); -+ break; -+ -+ case STP_OPID_BTM_POLL_CPUPCR: -+ do { -+ UINT32 times; -+ UINT32 sleep; -+ -+ times = pStpOp->au4OpData[0]; -+ sleep = pStpOp->au4OpData[1]; -+ -+ ret = stp_dbg_poll_cpupcr(times, sleep, 0); -+ ret += stp_dbg_poll_dmaregs(times, sleep); -+ } while (0); -+ break; -+ -+ case STP_OPID_BTM_PAGED_DUMP: -+ g_paged_dump_len = 0; -+ issue_type = STP_FW_ASSERT_ISSUE; -+ /*packet number depend on dump_num get from register:0xf0080044 ,support jade*/ -+ wcn_core_dump_deinit_gcoredump(); -+ dump_num = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_page_dump_num); -+ if (dump_num != 0) { -+ packet_num = dump_num; -+ STP_BTM_WARN_FUNC("get consys dump num packet_num(%d)\n", packet_num); -+ } else { -+ STP_BTM_ERR_FUNC("can not get consys dump num and default num is 35\n"); -+ } -+ Ret = wcn_core_dump_init_gcoredump(packet_num, STP_CORE_DUMP_TIMEOUT); -+ if (Ret) { -+ STP_BTM_ERR_FUNC("core dump init fail\n"); -+ break; -+ } -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+ page_counter = 0; -+ do { -+ UINT32 loop_cnt1 = 0; -+ UINT32 loop_cnt2 = 0; -+ ENUM_HOST_DUMP_STATE host_state; -+ ENUM_CHIP_DUMP_STATE chip_state; -+ UINT32 dump_phy_addr = 0; -+ UINT8 *dump_vir_addr = NULL; -+ UINT32 dump_len = 0; -+ UINT32 isEnd = 0; -+ -+ host_state = (ENUM_HOST_DUMP_STATE)wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_state); -+ if (STP_HOST_DUMP_NOT_START == host_state) { -+ counter++; -+ STP_BTM_INFO_FUNC("counter(%d)\n", counter); -+ osal_sleep_ms(100); -+ } else { -+ counter = 0; -+ } -+ while (1) { -+ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); -+ if (STP_CHIP_DUMP_PUT_DONE == chip_state) { -+ STP_BTM_INFO_FUNC("chip put done\n"); -+ break; -+ } -+ STP_BTM_INFO_FUNC("waiting chip put done\n"); -+ STP_BTM_INFO_FUNC("chip_state: %d\n", chip_state); -+ loop_cnt1++; -+ osal_sleep_ms(5); -+ -+ if (loop_cnt1 > 10) -+ goto paged_dump_end; -+ -+ } -+ -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET); -+ -+ dump_phy_addr = wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_addr); -+ -+ if (!dump_phy_addr) { -+ STP_BTM_ERR_FUNC("get paged dump phy address fail\n"); -+ ret = -1; -+ break; -+ } -+ -+ dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_ecsi->emi_phy_addr); -+ if (!dump_vir_addr) { -+ STP_BTM_ERR_FUNC("get paged dump phy address fail\n"); -+ ret = -2; -+ break; -+ } -+ dump_len = wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_len); -+ STP_BTM_INFO_FUNC("dump_phy_ddr(%08x),dump_vir_add(0x%p),dump_len(%d)\n", -+ dump_phy_addr, dump_vir_addr, dump_len); -+ -+ /*move dump info according to dump_addr & dump_len */ -+#if 1 -+ osal_memcpy(&g_paged_dump_buffer[0], dump_vir_addr, dump_len); -+ _stp_dump_emi_dump_buffer(&g_paged_dump_buffer[0], dump_len); -+ -+ if (0 == page_counter) { /* do fw assert infor paser in first paged dump */ -+ if (1 == stp_dbg_get_host_trigger_assert()) -+ issue_type = STP_HOST_TRIGGER_FW_ASSERT; -+ -+ ret = stp_dbg_set_fw_info(&g_paged_dump_buffer[0], 512, issue_type); -+ if (ret) { -+ STP_BTM_ERR_FUNC("set fw issue infor fail(%d),maybe fw warm reset...\n", ret); -+ stp_dbg_set_fw_info("Fw Warm reset", osal_strlen("Fw Warm reset"), -+ STP_FW_WARM_RST_ISSUE); -+ } -+ } -+ -+ if (dump_len <= 32 * 1024) { -+ pr_err("g_coredump_mode: %d!\n", g_coredump_mode); -+ if (1 == g_coredump_mode) -+ ret = stp_dbg_aee_send(&g_paged_dump_buffer[0], dump_len, 0); -+ else if (2 == g_coredump_mode) -+ ret = _stp_btm_put_emi_dump_to_nl(&g_paged_dump_buffer[0], dump_len); -+ else{ -+ STP_BTM_INFO_FUNC("coredump is disabled!\n"); -+ return 0; -+ } -+ if (ret == 0) -+ STP_BTM_INFO_FUNC("aee send ok!\n"); -+ else if (ret == 1) -+ STP_BTM_INFO_FUNC("aee send fisish!\n"); -+ else -+ STP_BTM_ERR_FUNC("aee send error!\n"); -+ } else -+ STP_BTM_ERR_FUNC("dump len is over than 32K(%d)\n", dump_len); -+ -+ g_paged_dump_len += dump_len; -+ STP_BTM_INFO_FUNC("dump len update(%d)\n", g_paged_dump_len); -+#endif -+ wmt_plat_update_host_sync_num(); -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE); -+ -+ STP_BTM_INFO_FUNC("host sync num(%d),chip sync num(%d)\n", -+ wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_num), -+ wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_num)); -+ -+ page_counter++; -+ STP_BTM_INFO_FUNC("\n\n++ paged dump counter(%d) ++\n\n\n", page_counter); -+ -+ while (1) { -+ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); -+ if (STP_CHIP_DUMP_END == chip_state) { -+ STP_BTM_INFO_FUNC("chip put end\n"); -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_END); -+ break; -+ } -+ STP_BTM_INFO_FUNC("waiting chip put end\n"); -+ -+ loop_cnt2++; -+ osal_sleep_ms(10); -+ -+ if (loop_cnt2 > 10) -+ goto paged_dump_end; -+ } -+ -+paged_dump_end: -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+ -+ if (counter > packet_num) { -+ isEnd = wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_paded_dump_end); -+ -+ if (isEnd) { -+ STP_BTM_INFO_FUNC("paged dump end\n"); -+ -+ STP_BTM_INFO_FUNC("\n\n paged dump print ++\n\n"); -+ _stp_dump_emi_dump_buffer(&g_paged_dump_buffer[0], g_paged_dump_len); -+ STP_BTM_INFO_FUNC("\n\n paged dump print --\n\n"); -+ STP_BTM_INFO_FUNC("\n\n paged dump size = %d, paged dump page number = %d\n\n", -+ g_paged_dump_len, page_counter); -+ counter = 0; -+ ret = 0; -+ } else { -+ STP_BTM_ERR_FUNC("paged dump fail\n"); -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+ stp_dbg_poll_cpupcr(5, 5, 0); -+ stp_dbg_poll_dmaregs(5, 1); -+ counter = 0; -+ ret = -1; -+ } -+ break; -+ } -+ -+ } while (1); -+ -+ break; -+ -+ case STP_OPID_BTM_FULL_DUMP: -+ -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+ do { -+ UINT32 loop_cnt1 = 0; -+ UINT32 loop_cnt2 = 0; -+ ENUM_CHIP_DUMP_STATE chip_state; -+ UINT32 dump_phy_addr = 0; -+ UINT8 *dump_vir_addr = NULL; -+ UINT32 dump_len = 0; -+ UINT32 isFail = 0; -+ -+ while (1) { -+ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); -+ if (STP_CHIP_DUMP_PUT_DONE == chip_state) -+ break; -+ -+ loop_cnt1++; -+ osal_sleep_ms(10); -+ -+ if (loop_cnt1 > 10) { -+ isFail = 1; -+ goto full_dump_end; -+ } -+ } -+ -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET); -+ -+ dump_phy_addr = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_addr); -+ if (!dump_phy_addr) { -+ STP_BTM_ERR_FUNC("get phy dump address fail\n"); -+ ret = -1; -+ break; -+ } -+ -+ dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_ecsi->emi_phy_addr); -+ if (!dump_vir_addr) { -+ STP_BTM_ERR_FUNC("get vir dump address fail\n"); -+ ret = -2; -+ break; -+ } -+ dump_len = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_len); -+ /*move dump info according to dump_addr & dump_len */ -+ wmt_plat_update_host_sync_num(); -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE); -+ -+ STP_BTM_INFO_FUNC("host sync num(%d),chip sync num(%d)\n", -+ wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_num), -+ wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_num)); -+ -+ while (1) { -+ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); -+ if (STP_CHIP_DUMP_END == chip_state) { -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_END); -+ break; -+ } -+ loop_cnt2++; -+ osal_sleep_ms(10); -+ -+ if (loop_cnt2 > 10) { -+ isFail = 1; -+ goto full_dump_end; -+ } -+ } -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+full_dump_end: -+ if (isFail) { -+ STP_BTM_ERR_FUNC("full dump fail\n"); -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+ ret = -1; -+ break; -+ } -+ } while (--full_dump_left > 0); -+ if (0 == full_dump_left) { -+ STP_BTM_INFO_FUNC("full dump end\n"); -+ ret = 0; -+ } -+ break; -+ case STP_OPID_BTM_PAGED_TRACE: -+ g_paged_trace_len = 0; -+ do { -+ UINT32 ctrl_val = 0; -+ UINT32 loop_cnt1 = 0; -+ UINT32 buffer_start = 0; -+ UINT32 buffer_idx = 0; -+ UINT8 *dump_vir_addr = NULL; -+ -+ while (loop_cnt1 < 10) { -+ ctrl_val = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_state); -+ if (0x8 == ctrl_val) -+ break; -+ osal_sleep_ms(10); -+ loop_cnt1++; -+ } -+ -+ if (loop_cnt1 >= 10) { -+ STP_BTM_ERR_FUNC("polling CTRL STATE fail\n"); -+ ret = -1; -+ break; -+ } -+ -+ buffer_start = wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_print_buff_start); -+ buffer_idx = wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_print_buff_idx); -+ /* buffer_len = buffer_idx - buffer_start; */ -+ g_paged_trace_len = buffer_idx; -+ STP_BTM_INFO_FUNC("paged trace buffer addr(%08x),buffer_len(%d)\n", buffer_start, buffer_idx); -+ dump_vir_addr = wmt_plat_get_emi_virt_add(buffer_start - p_ecsi->emi_phy_addr); -+ if (!dump_vir_addr) { -+ STP_BTM_ERR_FUNC("get vir dump address fail\n"); -+ ret = -2; -+ break; -+ } -+ osal_memcpy(&g_paged_trace_buffer[0], dump_vir_addr, -+ buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE); -+ /*moving paged trace according to buffer_start & buffer_len */ -+ do { -+ int i = 0; -+ int dump_len = 0; -+ -+ dump_len = -+ buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE; -+ pr_warn("\n\n -- paged trace hex output --\n\n"); -+ for (i = 0; i < dump_len; i++) { -+ if (i % 16 == 0) -+ pr_cont("\n"); -+ -+ pr_cont("%02x ", g_paged_trace_buffer[i]); -+ } -+ pr_warn("\n\n -- paged trace ascii output --\n\n"); -+ for (i = 0; i < dump_len; i++) { -+ if (i % 64 == 0) -+ pr_cont("\n"); -+ pr_cont("%c", g_paged_trace_buffer[i]); -+ } -+ } while (0); -+ /*move parser fw assert infor to paged dump in the one paged dump */ -+ /* ret = stp_dbg_set_fw_info(&g_paged_trace_buffer[0],g_paged_trace_len,issue_type); */ -+ ret = 0; -+ -+ } while (0); -+ mtk_wcn_stp_ctx_restore(); -+ break; -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ case STP_OPID_BTM_WMT_LTE_COEX: -+ ret = wmt_idc_msg_to_lte_handing(); -+ break; -+#endif -+ default: -+ ret = -1; -+ break; -+ } -+ -+ return ret; -+} -+ -+static P_OSAL_OP _stp_btm_get_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ) -+{ -+ P_OSAL_OP pOp; -+ /* INT32 ret = 0; */ -+ -+ if (!pOpQ) { -+ STP_BTM_WARN_FUNC("!pOpQ\n"); -+ return NULL; -+ } -+ -+ osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ /* acquire lock success */ -+ RB_GET(pOpQ, pOp); -+ osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ -+ if (!pOp) -+ STP_BTM_WARN_FUNC("RB_GET fail\n"); -+ -+ return pOp; -+} -+ -+static INT32 _stp_btm_put_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) -+{ -+ INT32 ret; -+ -+ if (!pOpQ || !pOp) { -+ STP_BTM_WARN_FUNC("invalid input param: 0x%p, 0x%p\n", pOpQ, pOp); -+ return 0; /* ;MTK_WCN_BOOL_FALSE; */ -+ } -+ -+ ret = 0; -+ -+ osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ /* acquire lock success */ -+ if (!RB_FULL(pOpQ)) -+ RB_PUT(pOpQ, pOp); -+ else -+ ret = -1; -+ -+ osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ -+ if (ret) { -+ STP_BTM_WARN_FUNC("RB_FULL(0x%p) %d ,rFreeOpQ = %p, rActiveOpQ = %p\n", -+ pOpQ, -+ RB_COUNT(pOpQ), -+ &stp_btm->rFreeOpQ, -+ &stp_btm->rActiveOpQ); -+ return 0; -+ } -+ /* STP_BTM_WARN_FUNC("RB_COUNT = %d\n",RB_COUNT(pOpQ)); */ -+ return 1; -+ -+} -+ -+P_OSAL_OP _stp_btm_get_free_op(MTKSTP_BTM_T *stp_btm) -+{ -+ P_OSAL_OP pOp; -+ -+ if (stp_btm) { -+ pOp = _stp_btm_get_op(stp_btm, &stp_btm->rFreeOpQ); -+ if (pOp) -+ osal_memset(&pOp->op, 0, sizeof(pOp->op)); -+ -+ return pOp; -+ } else -+ return NULL; -+} -+ -+INT32 _stp_btm_put_act_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP pOp) -+{ -+ INT32 bRet = 0; -+ INT32 bCleanup = 0; -+ long wait_ret = -1; -+ -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ if (!stp_btm || !pOp) { -+ STP_BTM_ERR_FUNC("Input NULL pointer\n"); -+ return bRet; -+ } -+ do { -+ pSignal = &pOp->signal; -+ -+ if (pSignal->timeoutValue) { -+ pOp->result = -9; -+ osal_signal_init(&pOp->signal); -+ } -+ -+ /* put to active Q */ -+ bRet = _stp_btm_put_op(stp_btm, &stp_btm->rActiveOpQ, pOp); -+ if (0 == bRet) { -+ STP_BTM_WARN_FUNC("put active queue fail\n"); -+ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ -+ break; -+ } -+ -+ /* wake up wmtd */ -+ osal_trigger_event(&stp_btm->STPd_event); -+ -+ if (pSignal->timeoutValue == 0) { -+ bRet = 1; /* MTK_WCN_BOOL_TRUE; */ -+ /* clean it in wmtd */ -+ break; -+ } -+ -+ /* wait result, clean it here */ -+ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ -+ -+ /* check result */ -+ wait_ret = osal_wait_for_signal_timeout(&pOp->signal); -+ -+ STP_BTM_DBG_FUNC("wait completion:%ld\n", wait_ret); -+ if (!wait_ret) { -+ STP_BTM_ERR_FUNC("wait completion timeout\n"); -+ /* TODO: how to handle it? retry? */ -+ } else { -+ if (pOp->result) -+ STP_BTM_WARN_FUNC("op(%d) result:%d\n", pOp->op.opId, pOp->result); -+ -+ bRet = (pOp->result) ? 0 : 1; -+ } -+ } while (0); -+ -+ if (bCleanup) { -+ /* put Op back to freeQ */ -+ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); -+ } -+ bRet = (pOp->result) ? 0 : 1; -+ return bRet; -+} -+ -+static INT32 _stp_btm_wait_for_msg(void *pvData) -+{ -+ MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData; -+ -+ return (!RB_EMPTY(&stp_btm->rActiveOpQ)) || osal_thread_should_stop(&stp_btm->BTMd); -+} -+ -+static INT32 _stp_btm_proc(void *pvData) -+{ -+ MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData; -+ P_OSAL_OP pOp; -+ INT32 id; -+ INT32 result; -+ -+ if (!stp_btm) { -+ STP_BTM_WARN_FUNC("!stp_btm\n"); -+ return -1; -+ } -+ -+ for (;;) { -+ pOp = NULL; -+ -+ osal_wait_for_event(&stp_btm->STPd_event, _stp_btm_wait_for_msg, (void *)stp_btm); -+ -+ if (osal_thread_should_stop(&stp_btm->BTMd)) { -+ STP_BTM_INFO_FUNC("should stop now...\n"); -+ /* TODO: clean up active opQ */ -+ break; -+ } -+ -+ /* get Op from activeQ */ -+ pOp = _stp_btm_get_op(stp_btm, &stp_btm->rActiveOpQ); -+ -+ if (!pOp) { -+ STP_BTM_WARN_FUNC("get_lxop activeQ fail\n"); -+ continue; -+ } -+ -+ id = osal_op_get_id(pOp); -+ -+ STP_BTM_DBG_FUNC("======> lxop_get_opid = %d, %s, remaining count = *%d*\n", -+ id, (id >= osal_array_size(g_btm_op_name)) ? ("???") : (g_btm_op_name[id]), -+ RB_COUNT(&stp_btm->rActiveOpQ)); -+ -+ if (id >= STP_OPID_BTM_NUM) { -+ STP_BTM_WARN_FUNC("abnormal opid id: 0x%x\n", id); -+ result = -1; -+ goto handler_done; -+ } -+ -+ result = _stp_btm_handler(stp_btm, &pOp->op); -+ -+handler_done: -+ -+ if (result) { -+ STP_BTM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, -+ (id >= osal_array_size(g_btm_op_name)) ? ("???") : (g_btm_op_name[id]), -+ result); -+ } -+ -+ if (osal_op_is_wait_for_signal(pOp)) { -+ osal_op_raise_signal(pOp, result); -+ } else { -+ /* put Op back to freeQ */ -+ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); -+ } -+ -+ if (STP_OPID_BTM_EXIT == id) { -+ break; -+ } else if (STP_OPID_BTM_RST == id) { -+ /* prevent multi reset case */ -+ stp_btm_reset_btm_wq(stp_btm); -+ mtk_wcn_stp_coredump_start_ctrl(0); -+ } -+ } -+ -+ STP_BTM_INFO_FUNC("exits\n"); -+ -+ return 0; -+}; -+ -+static inline INT32 _stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_RST; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_RETRY; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (!stp_btm) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_DUMP_TIMEOUT; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_dump_type(MTKSTP_BTM_T *stp_btm, ENUM_STP_BTM_OPID_T opid) -+{ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ -+ pOp->op.opId = opid; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ -+ INT32 retval; -+#if 0 -+ UINT32 dump_type; -+ UINT8 *virtual_addr = NULL; -+#endif -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+#if 1 /* Paged dump */ -+ STP_BTM_INFO_FUNC("paged dump start++\n"); -+ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_PAGED_DUMP); -+ if (retval) -+ STP_BTM_ERR_FUNC("paged dump fail\n"); -+#else -+ virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_CHIP_SYNC_ADDR); -+ if (!virtual_addr) { -+ STP_BTM_ERR_FUNC("get dump type virtual addr fail\n"); -+ return -1; -+ } -+ dump_type = CONSYS_REG_READ(virtual_addr); -+ STP_BTM_INFO_FUNC("dump type:%08x\n", dump_type); -+ -+ if ((dump_type & 0xfffff) == (CONSYS_PAGED_DUMP_START_ADDR & 0xfffff)) { -+ STP_BTM_INFO_FUNC("do paged dump\n"); -+ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_PAGED_DUMP); -+ if (retval) { -+ STP_BTM_ERR_FUNC("paged dump fail,do full dump\n"); -+ _stp_btm_dump_type(stp_btm, STP_OPID_BTM_FULL_DUMP); -+ } -+ } else if ((dump_type & 0xfffff) == (CONSYS_FULL_DUMP_START_ADDR & 0xfffff)) { -+ STP_BTM_INFO_FUNC("do full dump\n"); -+ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_FULL_DUMP); -+ } else { -+ STP_BTM_INFO_FUNC("do normal dump\n"); -+ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_DBG_DUMP); -+ } -+#endif -+ -+ return retval; -+} -+ -+static inline INT32 _stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep) -+{ -+ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ /* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */ -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_POLL_CPUPCR; -+ pOp->signal.timeoutValue = 0; -+ pOp->op.au4OpData[0] = times; -+ pOp->op.au4OpData[1] = sleep; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ /* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */ -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_PAGED_TRACE; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm) -+{ -+ INT32 ret = -1; -+ -+ ret = _stp_trigger_firmware_assert_via_emi(); -+ -+ return ret; -+ -+} -+ -+INT32 stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_btm_notify_wmt_rst_wq(stp_btm); -+} -+ -+INT32 stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_btm_notify_stp_retry_wq(stp_btm); -+} -+ -+INT32 stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_btm_notify_coredump_timeout_wq(stp_btm); -+} -+ -+INT32 stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_btm_notify_wmt_dmp_wq(stp_btm); -+} -+ -+INT32 stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_btm_notify_wmt_trace_wq(stp_btm); -+} -+ -+INT32 stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep) -+{ -+ return _stp_notify_btm_poll_cpupcr(stp_btm, times, sleep); -+} -+ -+INT32 stp_notify_btm_poll_cpupcr_ctrl(UINT32 en) -+{ -+ return stp_dbg_poll_cuppcr_ctrl(en); -+} -+ -+INT32 stp_notify_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm) -+{ -+ INT32 ret = -1; -+#if BTIF_RXD_BE_BLOCKED_DETECT -+ if (is_btif_rxd_be_blocked()) -+ ret = wcn_btif_rxd_blocked_collect_ftrace(); /* trigger collect SYS_FTRACE */ -+ else -+#endif -+ ret = _stp_btm_do_fw_assert_via_emi(stp_btm); -+ return ret; -+} -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ -+static inline INT32 _stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm) -+{ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ /* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */ -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_WMT_LTE_COEX; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+INT32 stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_notify_btm_handle_wmt_lte_coex(stp_btm); -+} -+ -+#endif -+MTKSTP_BTM_T *stp_btm_init(void) -+{ -+ INT32 i = 0x0; -+ INT32 ret = -1; -+ -+ osal_unsleepable_lock_init(&stp_btm->wq_spinlock); -+ osal_event_init(&stp_btm->STPd_event); -+ stp_btm->wmt_notify = wmt_lib_btm_cb; -+ -+ RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE); -+ RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE); -+ -+ /* Put all to free Q */ -+ for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) { -+ osal_signal_init(&(stp_btm->arQue[i].signal)); -+ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i])); -+ } -+ -+ /*Generate PSM thread, to servie STP-CORE for packet retrying and core dump receiving */ -+ stp_btm->BTMd.pThreadData = (VOID *) stp_btm; -+ stp_btm->BTMd.pThreadFunc = (VOID *) _stp_btm_proc; -+ osal_memcpy(stp_btm->BTMd.threadName, BTM_THREAD_NAME, osal_strlen(BTM_THREAD_NAME)); -+ -+ ret = osal_thread_create(&stp_btm->BTMd); -+ if (ret < 0) { -+ STP_BTM_ERR_FUNC("osal_thread_create fail...\n"); -+ goto ERR_EXIT1; -+ } -+ -+ /* Start STPd thread */ -+ ret = osal_thread_run(&stp_btm->BTMd); -+ if (ret < 0) { -+ STP_BTM_ERR_FUNC("osal_thread_run FAILS\n"); -+ goto ERR_EXIT1; -+ } -+ -+ return stp_btm; -+ -+ERR_EXIT1: -+ -+ return NULL; -+ -+} -+ -+INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm) -+{ -+ -+ INT32 ret = -1; -+ -+ STP_BTM_INFO_FUNC("btm deinit\n"); -+ -+ if (!stp_btm) -+ return STP_BTM_OPERATION_FAIL; -+ -+ ret = osal_thread_destroy(&stp_btm->BTMd); -+ if (ret < 0) { -+ STP_BTM_ERR_FUNC("osal_thread_destroy FAILS\n"); -+ return STP_BTM_OPERATION_FAIL; -+ } -+ -+ return STP_BTM_OPERATION_SUCCESS; -+} -+ -+INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ UINT32 i = 0; -+ -+ osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE); -+ RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE); -+ osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ /* Put all to free Q */ -+ for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) { -+ osal_signal_init(&(stp_btm->arQue[i].signal)); -+ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i])); -+ } -+ -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c -new file mode 100644 -index 0000000000000..246448b38b315 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c -@@ -0,0 +1,13 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h -new file mode 100644 -index 0000000000000..9a429b4af1e30 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h -@@ -0,0 +1,133 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _BTM_CORE_H -+#define _BTM_CORE_H -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "stp_wmt.h" -+#include "wmt_plat.h" -+#include "wmt_idc.h" -+#include "mtk_btif_exp.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define STP_BTM_OPERATION_FAIL (-1) -+#define STP_BTM_OPERATION_SUCCESS (0) -+ -+#define STP_BTM_OP_BUF_SIZE (64) -+ -+#define BTM_THREAD_NAME "mtk_stp_btm" -+ -+#define STP_PAGED_DUMP_TIME_LIMIT 3500 -+#define STP_FULL_DUMP_TIME 3 -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_STP_BTM_OPID_T { -+ STP_OPID_BTM_RETRY = 0x0, -+ STP_OPID_BTM_RST = 0x1, -+ STP_OPID_BTM_DBG_DUMP = 0x2, -+ STP_OPID_BTM_DUMP_TIMEOUT = 0x3, -+ STP_OPID_BTM_POLL_CPUPCR = 0x4, -+ STP_OPID_BTM_PAGED_DUMP = 0x5, -+ STP_OPID_BTM_FULL_DUMP = 0x6, -+ STP_OPID_BTM_PAGED_TRACE = 0x7, -+ STP_OPID_BTM_FORCE_FW_ASSERT = 0x8, -+#if CFG_WMT_LTE_COEX_HANDLING -+ STP_OPID_BTM_WMT_LTE_COEX = 0x9, -+#endif -+ STP_OPID_BTM_EXIT, -+ STP_OPID_BTM_NUM -+} ENUM_STP_BTM_OPID_T, *P_ENUM_STP_BTM_OPID_T; -+ -+typedef OSAL_OP_DAT STP_BTM_OP; -+typedef P_OSAL_OP_DAT P_STP_BTM_OP; -+ -+typedef struct mtk_stp_btm { -+ OSAL_THREAD BTMd; /* main thread (wmtd) handle */ -+ OSAL_EVENT STPd_event; -+ OSAL_UNSLEEPABLE_LOCK wq_spinlock; -+ -+ OSAL_OP_Q rFreeOpQ; /* free op queue */ -+ OSAL_OP_Q rActiveOpQ; /* active op queue */ -+ OSAL_OP arQue[STP_BTM_OP_BUF_SIZE]; /* real op instances */ -+ -+ /*wmt_notify */ -+ INT32 (*wmt_notify)(MTKSTP_BTM_WMT_OP_T); -+} MTKSTP_BTM_T; -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+INT32 stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm); -+INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep); -+INT32 stp_notify_btm_poll_cpupcr_ctrl(UINT32 en); -+INT32 stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_notify_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm); -+INT32 stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm); -+INT32 wcn_psm_flag_trigger_collect_ftrace(void); -+#if BTIF_RXD_BE_BLOCKED_DETECT -+INT32 wcn_btif_rxd_blocked_collect_ftrace(void); -+MTK_WCN_BOOL is_btif_rxd_be_blocked(void); -+#endif -+MTKSTP_BTM_T *stp_btm_init(void); -+extern unsigned int g_coredump_mode; -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h -new file mode 100644 -index 0000000000000..d8c6ebe9c4b06 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h -@@ -0,0 +1,69 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _DBG_CORE_H -+#define _DBG_CORE_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h -new file mode 100644 -index 0000000000000..fe92f25e92c18 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h -@@ -0,0 +1,251 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _PSM_CORE_H -+#define _PSM_CORE_H -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "stp_wmt.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define PFX_PSM "[STP-PSM] " -+#define STP_PSM_LOG_LOUD 4 -+#define STP_PSM_LOG_DBG 3 -+#define STP_PSM_LOG_INFO 2 -+#define STP_PSM_LOG_WARN 1 -+#define STP_PSM_LOG_ERR 0 -+ -+#define ASSERT(expr) -+#define STP_PSM_FIFO_SIZE 0x2000 /* 8kbytes */ -+#define STP_PSM_TX_SIZE 0x800 /* 2kbytes */ -+ -+#define STP_PSM_OPERATION_FAIL (-1) -+#define STP_PSM_OPERATION_SUCCESS (0) -+ -+#define STP_PSM_PACKET_SIZE_MAX (2000) -+ -+#define PSM_HANDLING 127 -+ -+#define STP_PSM_WMT_PS_TASK_HANDLING_TIME 30 /* 20 milli-seconds */ -+#define STP_PSM_IDLE_TIME_SLEEP 30 /* temporary for stress testing */ -+#define STP_PSM_IDLE_TIME_SLEEP_1000 1000 /* for high speed transmission e.g. BT OPP*/ -+#define STP_PSM_SDIO_IDLE_TIME_SLEEP 100 /* temporary for SDIO stress testing */ -+#define STP_PSM_WAIT_EVENT_TIMEOUT 6000 -+#if 0 -+#define STP_PSM_WMT_EVENT_SLEEP_EN (0x1UL << 0) -+#define STP_PSM_WMT_EVENT_WAKEUP_EN (0x1UL << 1) -+#define STP_PSM_BLOCK_DATA_EN (0x1UL << 2) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR (0x1UL << 3) -+#define STP_PSM_WMT_EVENT_ROLL_BACK_EN (0x1UL << 4) -+#define STP_PSM_RESET_EN (0x1UL << 5) -+#define STP_PSM_WMT_EVENT_HOST_WAKEUP_EN (0x1UL << 6) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY (0x1UL << 7) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY (0x1UL << 8) -+#endif -+ -+#define STP_PSM_WMT_EVENT_SLEEP_EN (0) -+#define STP_PSM_WMT_EVENT_WAKEUP_EN (1) -+#define STP_PSM_BLOCK_DATA_EN (2) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR (3) -+#define STP_PSM_WMT_EVENT_ROLL_BACK_EN (4) -+#define STP_PSM_RESET_EN (5) -+#define STP_PSM_WMT_EVENT_HOST_WAKEUP_EN (6) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY (7) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY (8) -+ -+#define STP_PSM_DBG_SIZE (16) -+ -+/* OP command ring buffer : must be power of 2 */ -+#define STP_OP_BUF_SIZE (16) -+ -+#define PSM_THREAD_NAME "mtk_stp_psm" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum { -+ ACT = 0, -+ ACT_INACT, -+ INACT, -+ INACT_ACT, -+ STP_PSM_MAX_STATE, -+} MTKSTP_PSM_STATE_T; -+ -+typedef enum _ENUM_STP_OPID_T { -+ STP_OPID_PSM_SLEEP = 0, -+ STP_OPID_PSM_WAKEUP, -+ STP_OPID_PSM_HOST_AWAKE, -+ STP_OPID_PSM_EXIT, -+ STP_OPID_PSM_NUM, -+ STP_OPID_PSM_INALID = STP_OPID_PSM_NUM, -+} ENUM_STP_OPID_T, *P_ENUM_STP_OPID_T; -+ -+typedef enum { -+ MON = 0, -+ UNMON, -+} MTKSTP_PSM_MONSTATE_T; -+ -+typedef INT32(*wmt_notify_t) (MTKSTP_PSM_ACTION_T action); -+typedef INT32(*stp_tx_cb_t) (unsigned char *buffer, UINT32 length, UINT8 type); -+ -+typedef OSAL_OP_DAT STP_OP; -+typedef P_OSAL_OP_DAT P_STP_OP; -+ -+typedef struct mtk_stp_psm { -+ OSAL_THREAD PSMd; /* main thread (wmtd) handle */ -+ OSAL_EVENT STPd_event; -+ -+ OSAL_OP_Q rFreeOpQ; /* free op queue */ -+ OSAL_OP_Q rActiveOpQ; /* active op queue */ -+ OSAL_OP arQue[STP_OP_BUF_SIZE]; /* real op instances */ -+ -+ /* OSAL_OP current_active_op; */ -+ /* P_OSAL_OP current_active_op; */ -+ UINT32 last_active_opId; -+ MTKSTP_PSM_STATE_T work_state; /*working state */ -+ OSAL_BIT_OP_VAR flag; -+ -+ /* in normal cases, sleep op is always enabled; -+ * but in error cases, we can't execute sleep cmd, -+ * Eg: FW assert, core dump -+ */ -+ INT32 sleep_en; -+ -+/* OSAL_UNSLEEPABLE_LOCK flagSpinlock; */ -+ INT32 idle_time_to_sleep; -+ OSAL_WAKE_LOCK wake_lock; -+ OSAL_TIMER psm_timer; /*monitor if active */ -+ OSAL_EVENT wait_wmt_q; -+ OSAL_FIFO hold_fifo; -+ OSAL_SLEEPABLE_LOCK hold_fifo_spinlock_global; -+ OSAL_UNSLEEPABLE_LOCK wq_spinlock; -+ OSAL_SLEEPABLE_LOCK stp_psm_lock; -+ INT32 (*wmt_notify)(MTKSTP_PSM_ACTION_T action); -+ INT32 (*stp_tx_cb)(unsigned char *buffer, UINT32 length, UINT8 type); -+ -+ MTK_WCN_BOOL (*is_wmt_quick_ps_support)(VOID); -+ UINT8 out_buf[STP_PSM_TX_SIZE]; -+} MTKSTP_PSM_T; -+ -+typedef struct { -+ UINT32 prev_flag; -+ UINT32 cur_flag; -+ UINT32 line_num; -+ UINT32 package_no; -+ UINT32 sec; -+ UINT32 usec; -+ UINT32 pid; -+} STP_PSM_ENTRY_T; -+ -+typedef struct stp_psm_record { -+ STP_PSM_ENTRY_T queue[STP_PSM_DBG_SIZE]; -+ UINT32 in; -+ UINT32 out; -+ UINT32 size; -+ OSAL_UNSLEEPABLE_LOCK lock; -+} STP_PSM_RECORD_T; -+ -+typedef struct stp_psm_opid_record { -+ STP_PSM_ENTRY_T queue[STP_PSM_DBG_SIZE]; -+ UINT32 in; -+ UINT32 out; -+ UINT32 size; -+ OSAL_UNSLEEPABLE_LOCK lock; -+} STP_PSM_OPID_RECORD, *P_STP_PSM_OPID_RECORD; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#define PSM_USE_COUNT_PACKAGE 0 -+ -+#if PSM_USE_COUNT_PACKAGE -+#define MTK_COMBO_PSM_RX_TH_DEFAULT (1600) -+#define MTK_COMBO_PSM_TX_TH_DEFAULT (300) -+INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir); -+#else -+#define SAMPLE_DURATION 1 /*1 second */ -+#define RTX_SPEED_THRESHOLD 50000 /*50KB/s */ -+INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir, INT32 length); -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*stp-psm external function*/ -+INT32 stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action); -+INT32 stp_psm_notify_wmt_wakeup(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_notify_wmt_sleep(MTKSTP_PSM_T *stp_psm); -+ -+INT32 stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_is_disable(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_release_data(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type); -+INT32 stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_reset(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_disable(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep); -+struct mtk_stp_psm *stp_psm_init(void); -+INT32 stp_psm_deinit(MTKSTP_PSM_T *stp_psm); -+MTK_WCN_BOOL mtk_wcn_stp_psm_dbg_level(UINT32 dbglevel); -+INT32 stp_psm_sleep_for_thermal(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_set_state(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state); -+MTK_WCN_BOOL stp_psm_is_quick_ps_support(VOID); -+ -+INT32 stp_psm_set_sleep_enable(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_set_sleep_disable(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_check_sleep_enable(MTKSTP_PSM_T *stp_psm); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h -new file mode 100644 -index 0000000000000..eaa5ce773e332 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h -@@ -0,0 +1,629 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _STP_CORE_H -+#define _STP_CORE_H -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "stp_exp.h" -+#include "psm_core.h" -+#include "btm_core.h" -+#include "stp_btif.h" -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#define CFG_STP_CORE_CTX_SPIN_LOCK (0) -+ -+#define WMT_LTE_COEX_FLAG (0x16) -+ -+/*configure using SPINLOCK or just mutex for STP-CORE tx*/ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define CONFIG_POWER_SAVING_SUPPORT -+ -+#ifdef PFX -+#undef PFX -+#endif -+#define PFX "[STP] " -+ -+#define STP_LOG_DBG 4 -+#define STP_LOG_PKHEAD 3 -+#define STP_LOG_INFO 2 -+#define STP_LOG_WARN 1 -+#define STP_LOG_ERR 0 -+ -+extern unsigned int gStpDbgLvl; -+ -+#define STP_DBG_FUNC(fmt, arg...)\ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_DBG) \ -+ osal_dbg_print(PFX "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_INFO) \ -+ osal_dbg_print(PFX "%s:[I] " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_WARN) \ -+ osal_warn_print(PFX "%s:[W] " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_ERR) \ -+ osal_err_print(PFX "%s:[E] " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_TRC_FUNC(f) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_DBG) \ -+ osal_dbg_print(PFX "<%s> <%d>\n", __func__, __LINE__); \ -+} while (0) -+ -+#define STP_DUMP_PACKET_HEAD(a, b, c) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_PKHEAD) \ -+ stp_dump_data(a, b, c); \ -+} while (0) -+#define STP_TRACE_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_DBG) \ -+ osal_dbg_print(PFX "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+ -+#define STP_MODE_BIT(x) (0x1UL << x) -+#define MTKSTP_UART_FULL_MODE STP_MODE_BIT(0) -+#define MTKSTP_UART_MAND_MODE STP_MODE_BIT(1) -+#define MTKSTP_BTIF_FULL_MODE STP_MODE_BIT(2) -+#define MTKSTP_BTIF_MAND_MODE STP_MODE_BIT(3) -+#define MTKSTP_SDIO_MODE STP_MODE_BIT(4) -+ -+#define MTKSTP_BUFFER_SIZE (16384) -+ -+/*To check function driver's status by the the interface*/ -+/*Operation definition*/ -+#define OP_FUNCTION_ACTIVE 0 -+ -+/*Driver's status*/ -+#define STATUS_OP_INVALID 0 -+#define STATUS_FUNCTION_INVALID 1 -+ -+#define STATUS_FUNCTION_ACTIVE 31 -+#define STATUS_FUNCTION_INACTIVE 32 -+ -+#define MTKSTP_CRC_SIZE (2) -+#define MTKSTP_HEADER_SIZE (4) -+#define MTKSTP_SEQ_SIZE (8) -+ -+/*#define MTKSTP_WINSIZE (4)*/ -+#define MTKSTP_WINSIZE (7) -+#define MTKSTP_TX_TIMEOUT (180) /*TODO: Baudrate to decide this */ -+#define MTKSTP_RETRY_LIMIT (10) -+ -+#define INDEX_INC(idx) \ -+{ \ -+ idx++; \ -+ idx &= 0x7; \ -+} -+ -+#define INDEX_DEC(idx) \ -+{ \ -+ idx--; \ -+ idx &= 0x7; \ -+} -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef INT32(*IF_TX) (const PUINT8 data, const UINT32 size, PUINT32 written_size); -+/* event/signal */ -+typedef INT32(*EVENT_SET) (UINT8 function_type); -+typedef INT32(*EVENT_TX_RESUME) (UINT8 winspace); -+typedef INT32(*FUNCTION_STATUS) (UINT8 type, UINT8 op); -+typedef INT32(*WMT_NOTIFY_FUNC_T) (UINT32 action); -+typedef INT32(*BTM_NOTIFY_WMT_FUNC_T) (INT32); -+ -+#if CFG_STP_CORE_CTX_SPIN_LOCK -+typedef OSAL_UNSLEEPABLE_LOCK STP_CTX_LOCK, *PSTP_CTX_LOCK; -+#else -+typedef OSAL_SLEEPABLE_LOCK STP_CTX_LOCK, *PSTP_CTX_LOCK; -+#endif -+ -+typedef struct { -+ /* common interface */ -+ IF_TX cb_if_tx; -+ /* event/signal */ -+ EVENT_SET cb_event_set; -+ EVENT_TX_RESUME cb_event_tx_resume; -+ FUNCTION_STATUS cb_check_funciton_status; -+} mtkstp_callback; -+ -+typedef enum { -+ MTKSTP_SYNC = 0, -+ MTKSTP_SEQ, -+ MTKSTP_ACK, -+ MTKSTP_NAK, -+ MTKSTP_TYPE, -+ MTKSTP_LENGTH, -+ MTKSTP_CHECKSUM, -+ MTKSTP_DATA, -+ MTKSTP_CRC1, -+ MTKSTP_CRC2, -+ MTKSTP_RESYNC1, -+ MTKSTP_RESYNC2, -+ MTKSTP_RESYNC3, -+ MTKSTP_RESYNC4, -+ MTKSTP_FW_MSG, -+} mtkstp_parser_state; -+ -+typedef struct { -+ mtkstp_parser_state state; -+ UINT8 seq; -+ UINT8 ack; -+ UINT8 nak; -+ UINT8 type; -+ UINT16 length; -+ UINT8 checksum; -+ UINT16 crc; -+#if 1 -+ UINT8 wmtsubtype; -+#endif -+} mtkstp_parser_context_struct; -+ -+typedef struct { -+ UINT8 txseq; /* last tx pkt's seq + 1 */ -+ UINT8 txack; /* last tx pkt's ack */ -+ UINT8 rxack; /* last rx pkt's ack */ -+ UINT8 winspace; /* current sliding window size */ -+ UINT8 expected_rxseq; /* last rx pkt's seq + 1 */ -+ UINT8 retry_times; -+} mtkstp_sequence_context_struct; -+ -+typedef struct { -+ /* MTK_WCN_MUTEX mtx; */ -+ OSAL_UNSLEEPABLE_LOCK mtx; -+ UINT8 buffer[MTKSTP_BUFFER_SIZE]; -+ UINT32 read_p; -+ UINT32 write_p; -+} mtkstp_ring_buffer_struct; -+ -+typedef struct { -+ UINT8 inband_rst_set; -+ UINT32 rx_counter; /* size of current processing pkt in rx_buf[] */ -+ UINT8 rx_buf[MTKSTP_BUFFER_SIZE]; /* input buffer of STP, room for current processing pkt */ -+ UINT32 tx_read; /* read ptr of tx_buf[] */ -+ UINT32 tx_write; /* write ptr of tx_buf[] */ -+ UINT8 tx_buf[MTKSTP_BUFFER_SIZE]; /* output buffer of STP */ -+ UINT32 tx_start_addr[MTKSTP_SEQ_SIZE]; /* ptr of each pkt in tx_buf[] */ -+ UINT32 tx_length[MTKSTP_SEQ_SIZE]; /* length of each pkt in tx_buf[] */ -+ mtkstp_ring_buffer_struct ring[MTKSTP_MAX_TASK_NUM]; /* ring buffers for each function driver */ -+ mtkstp_parser_context_struct parser; /* current rx pkt's content */ -+ mtkstp_sequence_context_struct sequence; /* state machine's current status */ -+ /* MTK_WCN_MUTEX stp_mutex; */ -+ /* OSAL_UNSLEEPABLE_LOCK stp_mutex; */ -+ STP_CTX_LOCK stp_mutex; -+ /* MTK_WCN_TIMER tx_timer; // timer for tx timeout handling */ -+ OSAL_TIMER tx_timer; -+ -+ MTKSTP_PSM_T *psm; -+ MTKSTP_BTM_T *btm; -+ UINT8 f_enable; /* default disabled */ -+ UINT8 f_ready; /* default non-ready */ -+ UINT8 f_pending_type; -+ UINT8 f_coredump; /*block tx flag, for now, only when f/w assert happens, we will set this bit on */ -+ UINT8 en_coredump; -+ /* Flag to identify Blueztooth is Bluez/or MTK Stack */ -+ MTK_WCN_BOOL f_bluez; -+ MTK_WCN_BOOL f_dbg_en; -+ MTK_WCN_BOOL f_autorst_en; -+ -+ /* Flag to identify STP by SDIO or UART */ -+ UINT32 f_mode; -+ -+ /* Flag to indicate the last WMT CLOSE */ -+ UINT32 f_wmt_last_close; -+ -+ /* Flag to indicate evt err has triggered assert or not */ -+ UINT32 f_evt_err_assert; -+} mtkstp_context_struct; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+INT32 stp_send_data_no_ps(UINT8 *buffer, UINT32 length, UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_init -+* DESCRIPTION -+* init STP kernel -+* PARAMETERS -+* cb_func [IN] function pointers of system APIs -+* RETURNS -+* INT32 0 = success, others = failure -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_init(const mtkstp_callback * const cb_func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_deinit -+* DESCRIPTION -+* deinit STP kernel -+* PARAMETERS -+* void -+* RETURNS -+* INT32 0 = success, others = failure -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_deinit(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_enable -+* DESCRIPTION -+* enable/disable STP -+* PARAMETERS -+* value [IN] 0 = disable, others = enable -+* RETURNS -+* INT32 0 = success, others = error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_enable(INT32 value); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_ready -+* DESCRIPTION -+* ready/non-ready STP -+* PARAMETERS -+* value [IN] 0 = non-ready, others = ready -+* RETURNS -+* INT32 0 = success, others = error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_ready(INT32 value); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_coredump_start_ctrl -+* DESCRIPTION -+* set f/w assert flag in STP context -+* PARAMETERS -+* value [IN] 0=assert end, others=assert begins -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_coredump_start_ctrl(UINT32 value); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_coredump_start_get -+* DESCRIPTION -+* get f/w assert flag in STP context -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32 0= f/w assert flag is not set, others=f/w assert flag is set -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_coredump_start_get(VOID); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data_raw -+* DESCRIPTION -+* send raw data to common interface, bypass STP -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 length transmitted -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_set_sdio_mode -+* DESCRIPTION -+* Set stp for SDIO mode -+* PARAMETERS -+* sdio_flag [IN] sdio mode flag (TRUE:SDIO mode, FALSE:UART mode) -+* RETURNS -+* void -+*****************************************************************************/ -+extern void mtk_wcn_stp_set_mode(UINT32 sdio_flag); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_uart_fullset_mode -+* DESCRIPTION -+* Is stp use UART Fullset mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:UART Fullset, FALSE:UART Fullset -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_uart_fullset_mode(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_uart_mand_mode -+* DESCRIPTION -+* Is stp use UART Mandatory mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:UART Mandatory, FALSE:UART Mandatory -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_uart_mand_mode(void); -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_btif_fullset_mode -+* DESCRIPTION -+* Is stp use BTIF Fullset mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:BTIF Fullset, FALSE:BTIF Fullset -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_btif_fullset_mode(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_btif_mand_mode -+* DESCRIPTION -+* Is stp use BTIF Mandatory mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:BTIF Mandatory, FALSE:BTIF Mandatory -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_btif_mand_mode(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_sdio_mode -+* DESCRIPTION -+* Is stp use SDIO mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:SDIO mode, FALSE:UART mode -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_sdio_mode(void); -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_inband_reset -+* DESCRIPTION -+* To sync to oringnal stp state with f/w stp -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+extern void mtk_wcn_stp_inband_reset(void); -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_inband_reset -+* DESCRIPTION -+* To send testing command to chip -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+extern void mtk_wcn_stp_test_cmd(INT32 no); -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_inband_reset -+* DESCRIPTION -+* To control STP debugging mechanism -+* PARAMETERS -+* func_no: function control, func_op: dumpping filer, func_param: dumpping parameter -+* RETURNS -+* none -+*****************************************************************************/ -+extern void mtk_wcn_stp_debug_ctrl(INT32 func_no, INT32 func_op, INT32 func_param); -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_flush -+* DESCRIPTION -+* flush all stp context -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+extern void mtk_wcn_stp_flush_context(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_rx_queue -+* DESCRIPTION -+* flush all stp rx queue -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+extern void mtk_wcn_stp_flush_rx_queue(UINT32 type); -+ -+/***************************************************************************** -+* FUNCTION -+* set stp debugging mdoe -+* DESCRIPTION -+* set stp debugging mdoe -+* PARAMETERS -+* dbg_mode: switch to dbg mode ? -+* RETURNS -+* void -+*****************************************************************************/ -+extern void mtk_wcn_stp_set_dbg_mode(MTK_WCN_BOOL dbg_mode); -+ -+/***************************************************************************** -+* FUNCTION -+* set stp auto reset mdoe -+* DESCRIPTION -+* set stp auto reset mdoe -+* PARAMETERS -+* auto_rst: switch to auto reset mode ? -+* RETURNS -+* void -+*****************************************************************************/ -+extern void mtk_wcn_stp_set_auto_rst(MTK_WCN_BOOL auto_rst); -+ -+/*stp_psm support*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_notify_stp -+* DESCRIPTION -+* WMT notification to STP that power saving job is done or not -+* PARAMETERS -+* -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_psm_notify_stp(const UINT32 action); -+ -+extern int mtk_wcn_stp_set_psm_state(MTKSTP_PSM_STATE_T state); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_enabla -+* DESCRIPTION -+* enable STP PSM -+* PARAMETERS -+* int idle_time_to_sleep: IDLE time to sleep -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_psm_enable(int idle_time_to_sleep); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_disable -+* DESCRIPTION -+* disable STP PSM -+* PARAMETERS -+* void -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_psm_disable(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_reset -+* DESCRIPTION -+* reset STP PSM (used on whole chip reset) -+* PARAMETERS -+* void -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_psm_reset(void); -+extern void stp_do_tx_timeout(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_btm_get_dmp -+* DESCRIPTION -+* get stp dump related information -+* PARAMETERS -+* buffer: dump placement, len: dump size -+* RETURNS -+* 0: Success Negative Value: Fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_btm_get_dmp(char *buf, int *len); -+ -+extern int mtk_wcn_stp_dbg_enable(void); -+ -+extern int mtk_wcn_stp_dbg_disable(void); -+ -+extern void mtk_wcn_stp_set_if_tx_type(ENUM_STP_TX_IF_TYPE stp_if_type); -+ -+extern int mtk_wcn_sys_if_rx(UINT8 *data, INT32 size); -+ -+extern MTK_WCN_BOOL mtk_wcn_stp_dbg_level(UINT32 dbglevel); -+ -+extern INT32 mtk_wcn_stp_dbg_dump_package(VOID); -+ -+extern int stp_drv_init(void); -+ -+extern void stp_drv_exit(void); -+ -+extern INT32 mtk_wcn_stp_dbg_log_ctrl(UINT32 on); -+ -+extern INT32 mtk_wcn_stp_coredump_flag_ctrl(UINT32 on); -+ -+extern INT32 mtk_wcn_stp_coredump_flag_get(VOID); -+extern INT32 mtk_wcn_stp_notify_sleep_for_thermal(void); -+ -+extern INT32 mtk_wcn_stp_set_wmt_last_close(UINT32 value); -+ -+/*stp btif API declared*/ -+extern INT32 mtk_wcn_stp_open_btif(VOID); -+extern INT32 mtk_wcn_stp_close_btif(VOID); -+extern INT32 mtk_wcn_stp_rxcb_register(MTK_WCN_BTIF_RX_CB rx_cb); -+extern INT32 mtk_wcn_stp_tx(UINT8 *pBuf, UINT32 len, UINT32 *written_len); -+extern INT32 mtk_wcn_stp_wakeup_consys(VOID); -+extern INT32 mtk_wcn_stp_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag); -+extern INT32 mtk_wcn_stp_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode); -+extern INT32 mtk_wcn_stp_logger_ctrl(ENUM_BTIF_DBG_ID flag); -+extern VOID mtk_wcn_stp_ctx_save(VOID); -+extern VOID mtk_wcn_stp_ctx_restore(VOID); -+extern INT32 mtk_wcn_stp_wmt_evt_err_trg_assert(VOID); -+extern VOID mtk_wcn_stp_set_wmt_evt_err_trg_assert(UINT32 value); -+extern UINT32 mtk_wcn_stp_get_wmt_evt_err_trg_assert(VOID); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _STP_CORE_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h -new file mode 100644 -index 0000000000000..94b3d8a597ac3 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h -@@ -0,0 +1,89 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _STP_WMT_H -+#define _STP_WMT_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum { -+ BTM_RST_OP = 0, -+ BTM_DMP_OP = 1, -+ BTM_GET_AEE_SUPPORT_FLAG = 2, -+ BTM_MAX_OP, -+} MTKSTP_BTM_WMT_OP_T; -+ -+typedef enum { -+ SLEEP = 0, -+ HOST_AWAKE, -+ WAKEUP, -+ EIRQ, -+ ROLL_BACK, -+ STP_PSM_MAX_ACTION -+} MTKSTP_PSM_ACTION_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+extern MTK_WCN_BOOL wmt_lib_btm_cb(MTKSTP_BTM_WMT_OP_T op); -+ -+extern INT32 wmt_lib_ps_stp_cb(MTKSTP_PSM_ACTION_T action); -+extern MTK_WCN_BOOL wmt_lib_is_quick_ps_support(VOID); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _STP_WMT_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h -new file mode 100644 -index 0000000000000..4c64b6b5e65bb ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h -@@ -0,0 +1,74 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_CONF_H_ -+#define _WMT_CONF_H_ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define CUST_CFG_WMT "WMT_SOC.cfg" -+#define CUST_CFG_WMT_PREFIX "/lib/firmware/mediatek/" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+INT32 wmt_conf_read_file(VOID); -+P_WMT_GEN_CONF wmt_conf_get_cfg(VOID); -+INT32 wmt_conf_set_cfg_file(const char *name); -+ -+#endif /* _WMT_CONF_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h -new file mode 100644 -index 0000000000000..cca52a15cc982 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h -@@ -0,0 +1,428 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_CORE_H_ -+#define _WMT_CORE_H_ -+ -+#include "osal.h" -+#include "wmt_ctrl.h" -+#include "wmt_exp.h" -+#include "wmt_plat.h" -+/* TODO: [GeorgeKuo][FixMe] remove temporarily */ -+/* for AIF state definition */ -+/* #include "mtk_wcn_cmb_stub.h" */ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+#define CFG_CORE_MT6620_SUPPORT 0 /* whether MT6620 is supported or not */ -+ -+#define CFG_CORE_MT6628_SUPPORT 0 /* whether MT6628 is supported or not */ -+ -+#define CFG_CORE_SOC_SUPPORT 1 -+ -+/* TODO:[ChangeFeature][George] move this definition outside so that wmt_dev can remove wmt_core.h inclusion. */ -+#define defaultPatchName "mt66xx_patch_hdr.bin" -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define BCNT_PATCH_BUF_HEADROOM (8) -+ -+#define DWCNT_HIF_CONF (4) -+#define DWCNT_STRAP_CONF (4) -+#define DWCNT_RESERVED (8) -+#define DWCNT_CTRL_DATA (16) -+ -+#if 0 /* TODO: [obsolete][GeorgeKuo]: remove ubsolete definitions */ -+#define WMT_SET (1) -+#define WMT_QUERY (0) -+#define WMT_PKT_FMT_RAW (1) -+#define WMT_PKT_FMT_STP (0) -+#endif -+ -+#define WMT_FUNC_CTRL_ON (MTK_WCN_BOOL_TRUE) -+#define WMT_FUNC_CTRL_OFF (MTK_WCN_BOOL_FALSE) -+ -+#define WMT_HDR_LEN (4) /* header length */ -+#define WMT_STS_LEN (1) /* status length */ -+#define WMT_FLAG_LEN (1) -+#define WMT_HIF_UART_INFO_LEN (4) -+#define WMT_FUNC_CTRL_PARAM_LEN (1) -+ -+#define WMT_DEFAULT_BAUD_RATE (115200) -+ -+#define INIT_CMD(c, e, s) {.cmd = c, .cmdSz = sizeof(c), .evt = e, .evtSz = sizeof(e), .str = s} -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _ENUM_WMT_FM_T { -+ WMT_FM_INVALID = 0, -+ WMT_FM_I2C = 1, -+ WMT_FM_COMM = 2, -+ WMT_FM_MAX -+} ENUM_WMT_FM_T, *P_ENUM_WMT_FM_T; -+ -+typedef enum _ENUM_WMT_HIF_T { -+ WMT_HIF_UART = 0, -+ WMT_HIF_SDIO = 1, -+ WMT_HIF_BTIF = 2, -+ WMT_HIF_MAX -+} ENUM_WMT_HIF_T, *P_ENUM_WMT_HIF_T; -+ -+#if 0 /* [George] moved to wmt_exp.h for hif_sdio's use */ -+typedef enum { -+ WMT_SDIO_SLOT_INVALID = 0, -+ WMT_SDIO_SLOT_SDIO1 = 1, /* Wi-Fi dedicated SDIO1 */ -+ WMT_SDIO_SLOT_SDIO2 = 2, -+ WMT_SDIO_SLOT_MAX -+} WMT_SDIO_SLOT_NUM; -+ -+typedef enum { -+ WMT_SDIO_FUNC_STP = 0, -+ WMT_SDIO_FUNC_WIFI = 1, -+ WMT_SDIO_FUNC_MAX -+} WMT_SDIO_FUNC_TYPE; -+#endif -+ -+typedef enum _ENUM_WMT_OPID_T { -+ WMT_OPID_HIF_CONF = 0, -+ WMT_OPID_PWR_ON = 1, -+ WMT_OPID_PWR_OFF = 2, -+ WMT_OPID_FUNC_ON = 3, -+ WMT_OPID_FUNC_OFF = 4, -+ WMT_OPID_REG_RW = 5, /* TODO:[ChangeFeature][George] is this OP obsoleted? */ -+ WMT_OPID_EXIT = 6, -+ WMT_OPID_PWR_SV = 7, -+ WMT_OPID_DSNS = 8, -+ WMT_OPID_LPBK = 9, -+ WMT_OPID_CMD_TEST = 10, -+ WMT_OPID_HW_RST = 11, -+ WMT_OPID_SW_RST = 12, -+ WMT_OPID_BAUD_RST = 13, -+ WMT_OPID_STP_RST = 14, -+ WMT_OPID_THERM_CTRL = 15, -+ WMT_OPID_EFUSE_RW = 16, -+ WMT_OPID_GPIO_CTRL = 17, -+ WMT_OPID_FW_COREDMP = 18, -+ WMT_OPID_GPIO_STATE = 19, -+ WMT_OPID_BGW_DS = 20, -+ WMT_OPID_SET_MCU_CLK = 21, -+ WMT_OPID_ADIE_LPBK_TEST = 22, -+#if CFG_WMT_LTE_COEX_HANDLING -+ WMT_OPID_IDC_MSG_HANDLING = 23, -+#endif -+#ifdef CONFIG_MTK_COMBO_ANT -+ WMT_OPID_ANT_RAM_DOWN = 24, -+ WMT_OPID_ANT_RAM_STA_GET = 25, -+#endif -+ WMT_OPID_MAX -+} ENUM_WMT_OPID_T, *P_ENUM_WMT_OPID_T; -+ -+typedef OSAL_OP_DAT WMT_OP; -+typedef P_OSAL_OP_DAT P_WMT_OP; -+ -+typedef struct _WMT_HIF_CONF { -+ UINT32 hifType; /* HIF Type */ -+ UINT32 au4HifConf[DWCNT_HIF_CONF]; /* HIF Config */ -+ UINT32 au4StrapConf[DWCNT_STRAP_CONF]; /* Strap Config */ -+} WMT_HIF_CONF, *P_WMT_HIF_CONF; -+ -+typedef INT32(*WMT_OPID_FUNC) (P_WMT_OP); -+ -+typedef struct _WMT_GEN_CONF { -+ UINT8 cfgExist; -+ -+ UINT8 coex_wmt_ant_mode; -+ UINT8 coex_wmt_ext_component; -+ UINT8 coex_wmt_wifi_time_ctl; -+ UINT8 coex_wmt_ext_pta_dev_on; -+ /*mt6592 and LTE coex filter mode setting */ -+ UINT8 coex_wmt_filter_mode; -+ -+ UINT8 coex_bt_rssi_upper_limit; -+ UINT8 coex_bt_rssi_mid_limit; -+ UINT8 coex_bt_rssi_lower_limit; -+ UINT8 coex_bt_pwr_high; -+ UINT8 coex_bt_pwr_mid; -+ UINT8 coex_bt_pwr_low; -+ -+ UINT8 coex_wifi_rssi_upper_limit; -+ UINT8 coex_wifi_rssi_mid_limit; -+ UINT8 coex_wifi_rssi_lower_limit; -+ UINT8 coex_wifi_pwr_high; -+ UINT8 coex_wifi_pwr_mid; -+ UINT8 coex_wifi_pwr_low; -+ -+ UINT8 coex_ext_pta_hi_tx_tag; -+ UINT8 coex_ext_pta_hi_rx_tag; -+ UINT8 coex_ext_pta_lo_tx_tag; -+ UINT8 coex_ext_pta_lo_rx_tag; -+ UINT16 coex_ext_pta_sample_t1; -+ UINT16 coex_ext_pta_sample_t2; -+ UINT8 coex_ext_pta_wifi_bt_con_trx; -+ -+ UINT32 coex_misc_ext_pta_on; -+ UINT32 coex_misc_ext_feature_set; -+ /*GPS LNA setting */ -+ UINT8 wmt_gps_lna_pin; -+ UINT8 wmt_gps_lna_enable; -+ /*Power on sequence */ -+ UINT8 pwr_on_rtc_slot; -+ UINT8 pwr_on_ldo_slot; -+ UINT8 pwr_on_rst_slot; -+ UINT8 pwr_on_off_slot; -+ UINT8 pwr_on_on_slot; -+ UINT8 co_clock_flag; -+ -+ /* Combo chip side SDIO driving setting */ -+ UINT32 sdio_driving_cfg; -+ -+} WMT_GEN_CONF, *P_WMT_GEN_CONF; -+ -+typedef enum _ENUM_DRV_STS_ { -+#if 0 -+ DRV_STS_INVALID = 0, -+ DRV_STS_UNREG = 1, /* Initial State */ -+#endif -+ DRV_STS_POWER_OFF = 0, /* initial state */ -+ DRV_STS_POWER_ON = 1, /* powered on, only WMT */ -+ DRV_STS_FUNC_ON = 2, /* FUNC ON */ -+ DRV_STS_MAX -+} ENUM_DRV_STS, *P_ENUM_DRV_STS; -+ -+typedef enum _WMT_IC_PIN_ID_ { -+ WMT_IC_PIN_AUDIO = 0, -+ WMT_IC_PIN_EEDI = 1, -+ WMT_IC_PIN_EEDO = 2, -+ WMT_IC_PIN_GSYNC = 3, -+ WMT_IC_PIN_MAX -+} WMT_IC_PIN_ID, *P_WMT_IC_PIN_ID; -+ -+typedef enum _WMT_IC_PIN_STATE_ { -+ WMT_IC_PIN_EN = 0, -+ WMT_IC_PIN_DIS = 1, -+ WMT_IC_AIF_0 = 2, /* = CMB_STUB_AIF_0, */ -+ WMT_IC_AIF_1 = 3, /* = CMB_STUB_AIF_1, */ -+ WMT_IC_AIF_2 = 4, /* = CMB_STUB_AIF_2, */ -+ WMT_IC_AIF_3 = 5, /* = CMB_STUB_AIF_3, */ -+ WMT_IC_PIN_MUX = 6, -+ WMT_IC_PIN_GPIO = 7, -+ WMT_IC_PIN_GPIO_HIGH = 8, -+ WMT_IC_PIN_GPIO_LOW = 9, -+ WMT_IC_PIN_STATE_MAX -+} WMT_IC_PIN_STATE, *P_WMT_IC_PIN_STATE; -+ -+typedef enum _WMT_CO_CLOCK_ { -+ WMT_CO_CLOCK_DIS = 0, -+ WMT_CO_CLOCK_EN = 1, -+ WMT_CO_CLOCK_MAX -+} WMT_CO_CLOCK, *P_WMT_CO_CLOCK; -+ -+typedef INT32(*SW_INIT) (P_WMT_HIF_CONF pWmtHifConf); -+typedef INT32(*SW_DEINIT) (P_WMT_HIF_CONF pWmtHifConf); -+typedef INT32(*IC_PIN_CTRL) (WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag); -+typedef INT32(*IC_VER_CHECK) (VOID); -+typedef INT32(*CO_CLOCK_CTRL) (WMT_CO_CLOCK on); -+typedef MTK_WCN_BOOL(*IS_QUICK_SLEEP_SUPPORT) (VOID); -+typedef MTK_WCN_BOOL(*IS_AEE_DUMP_SUPPORT) (VOID); -+ -+typedef struct _WMT_IC_OPS_ { -+ UINT32 icId; -+ SW_INIT sw_init; -+ SW_DEINIT sw_deinit; -+ IC_PIN_CTRL ic_pin_ctrl; -+ IC_VER_CHECK ic_ver_check; -+ CO_CLOCK_CTRL co_clock_ctrl; -+ IS_QUICK_SLEEP_SUPPORT is_quick_sleep; -+ IS_AEE_DUMP_SUPPORT is_aee_dump_support; -+} WMT_IC_OPS, *P_WMT_IC_OPS; -+ -+typedef struct _WMT_CTX_ { -+ ENUM_DRV_STS eDrvStatus[WMTDRV_TYPE_MAX]; /* Controlled driver status */ -+ UINT32 wmtInfoBit; /* valid info bit */ -+ WMT_HIF_CONF wmtHifConf; /* HIF information */ -+ -+ /* Pointer to WMT_IC_OPS. Shall be assigned to a correct table in stp_init -+ * if and only if getting chip id successfully. hwver and fwver are kept in -+ * WMT-IC module only. -+ */ -+ P_WMT_IC_OPS p_ic_ops; -+} WMT_CTX, *P_WMT_CTX; -+ -+/* TODO:[ChangeFeature][George] remove WMT_PKT. replace it with hardcoded arrays. */ -+/* Using this struct relies on compiler's implementation and pack() settings */ -+typedef struct _WMT_PKT_ { -+ UINT8 eType; /* PKT_TYPE_* */ -+ UINT8 eOpCode; /* OPCODE_* */ -+ UINT16 u2SduLen; /* 2 bytes length, little endian */ -+ UINT8 aucParam[32]; -+} WMT_PKT, *P_WMT_PKT; -+ -+/* WMT Packet Format */ -+typedef enum _ENUM_PKT_TYPE { -+ PKT_TYPE_INVALID = 0, -+ PKT_TYPE_CMD = 1, -+ PKT_TYPE_EVENT = 2, -+ _PKT_TYPE_MAX -+} ENUM_PKT_TYPE, *P_ENUM_PKT_TYPE; -+ -+typedef enum _ENUM_OPCODE { -+ OPCODE_INVALID = 0, -+ OPCODE_PATCH = 1, -+ OPCODE_TEST = 2, -+ OPCODE_WAKEUP = 3, -+ OPCODE_HIF = 4, -+ OPCODE_STRAP_CONF = 5, -+ OPCODE_FUNC_CTRL = 6, -+ OPCODE_RESET = 7, -+ OPCODE_INT = 8, -+ OPCODE_MAX -+} ENUM_OPCODE, *P_ENUM_OPCODE; -+ -+typedef enum { -+ WMT_STP_CONF_EN = 0, -+ WMT_STP_CONF_RDY = 1, -+ WMT_STP_CONF_MODE = 2, -+ WMT_STP_CONF_MAX -+} WMT_STP_CONF_TYPE; -+ -+struct init_script { -+ UINT8 *cmd; -+ UINT32 cmdSz; -+ UINT8 *evt; -+ UINT32 evtSz; -+ UINT8 *str; -+}; -+ -+typedef struct _WMT_PATCH { -+ UINT8 ucDateTime[16]; -+ UINT8 ucPLat[4]; -+ UINT16 u2HwVer; -+ UINT16 u2SwVer; -+ UINT32 u4PatchVer; -+} WMT_PATCH, *P_WMT_PATCH; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if CFG_CORE_MT6620_SUPPORT -+extern WMT_IC_OPS wmt_ic_ops_mt6620; -+#endif -+ -+#if CFG_CORE_MT6628_SUPPORT -+extern WMT_IC_OPS wmt_ic_ops_mt6628; -+#endif -+ -+#if CFG_CORE_SOC_SUPPORT -+extern WMT_IC_OPS wmt_ic_ops_soc; -+#endif -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+extern INT32 wmt_core_init(VOID); -+extern INT32 wmt_core_deinit(VOID); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmtd -+* DESCRIPTION -+* deinit STP kernel -+* PARAMETERS -+* void -+* RETURNS -+* INT32 0 = success, others = failure -+*****************************************************************************/ -+extern INT32 wmt_core_opid(P_WMT_OP pWmtOp); -+ -+extern INT32 wmt_core_ctrl(ENUM_WMT_CTRL_T ctrId, unsigned long *pPa1, unsigned long *pPa2); -+ -+extern INT32 wmt_core_func_ctrl_cmd(ENUM_WMTDRV_TYPE_T type, MTK_WCN_BOOL fgEn); -+ -+extern INT32 wmt_core_reg_rw_raw(UINT32 isWrite, UINT32 offset, PUINT32 pVal, UINT32 mask); -+ -+extern VOID wmt_core_dump_data(PUINT8 pData, PUINT8 pTitle, UINT32 len); -+ -+extern MTK_WCN_BOOL wmt_core_patch_check(UINT32 u4PatchVer, UINT32 u4HwVer); -+ -+extern INT32 wmt_core_init_script(struct init_script *script, INT32 count); -+ -+extern INT32 wmt_core_rx(PUINT8 pBuf, UINT32 bufLen, UINT32 *readSize); -+ -+extern INT32 wmt_core_tx(const PUINT8 pData, UINT32 size, PUINT32 writtenSize, MTK_WCN_BOOL bRawFlag); -+extern MTK_WCN_BOOL wmt_core_is_quick_ps_support(void); -+ -+extern MTK_WCN_BOOL wmt_core_get_aee_dump_flag(void); -+ -+#if CFG_CORE_INTERNAL_TXRX -+extern INT32 wmt_core_lpbk_do_stp_init(void); -+extern INT32 wmt_core_lpbk_do_stp_deinit(void); -+#endif -+ -+extern VOID wmt_core_set_coredump_state(ENUM_DRV_STS state); -+#if CFG_WMT_LTE_COEX_HANDLING -+extern VOID wmt_core_set_flag_for_test(UINT32 enable); -+extern UINT32 wmt_core_get_flag_for_test(VOID); -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static _osal_inline_ MTK_WCN_BOOL wmt_core_ic_ops_check(P_WMT_IC_OPS p_ops) -+{ -+ if (!p_ops) -+ return MTK_WCN_BOOL_FALSE; -+ -+ if ((NULL == p_ops->sw_init) -+ || (NULL == p_ops->sw_deinit) -+ || (NULL == p_ops->ic_ver_check) -+ || (NULL == p_ops->ic_pin_ctrl)) -+ return MTK_WCN_BOOL_FALSE; -+ else -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+#endif /* _WMT_CORE_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h -new file mode 100644 -index 0000000000000..0ff3d6058c394 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h -@@ -0,0 +1,120 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_CTRL_H_ -+#define _WMT_CTRL_H_ -+ -+#include "osal.h" -+#include "wmt_stp_exp.h" -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define DWCNT_CTRL_DATA (16) -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef struct _WMT_CTRL_DATA_ { -+ SIZE_T ctrlId; -+ SIZE_T au4CtrlData[DWCNT_CTRL_DATA]; -+} WMT_CTRL_DATA, *P_WMT_CTRL_DATA; -+ -+typedef enum _ENUM_WMT_CTRL_T { -+ WMT_CTRL_HW_PWR_OFF = 0, /* whole chip power off */ -+ WMT_CTRL_HW_PWR_ON = 1, /* whole chip power on */ -+ WMT_CTRL_HW_RST = 2, /* whole chip rst */ -+ WMT_CTRL_STP_CLOSE = 3, -+ WMT_CTRL_STP_OPEN = 4, -+ WMT_CTRL_STP_CONF = 5, -+ WMT_CTRL_FREE_PATCH = 6, -+ WMT_CTRL_GET_PATCH = 7, -+ WMT_CTRL_GET_PATCH_NAME = 8, -+ WMT_CTRL_HWIDVER_SET = 9, /* TODO: rename this and add chip id information in addition to chip version */ -+ WMT_CTRL_STP_RST = 10, -+ WMT_CTRL_GET_WMT_CONF = 11, -+ WMT_CTRL_TX = 12, /* [FixMe][GeorgeKuo]: to be removed by Sean's stp integration */ -+ WMT_CTRL_RX = 13, /* [FixMe][GeorgeKuo]: to be removed by Sean's stp integration */ -+ WMT_CTRL_RX_FLUSH = 14, /* [FixMe][SeanWang]: to be removed by Sean's stp integration */ -+ WMT_CTRL_GPS_SYNC_SET = 15, -+ WMT_CTRL_GPS_LNA_SET = 16, -+ WMT_CTRL_PATCH_SEARCH = 17, -+ WMT_CTRL_CRYSTAL_TRIMING_GET = 18, -+ WMT_CTRL_CRYSTAL_TRIMING_PUT = 19, -+ WMT_CTRL_HW_STATE_DUMP = 20, -+ WMT_CTRL_GET_PATCH_NUM = 21, -+ WMT_CTRL_GET_PATCH_INFO = 22, -+ WMT_CTRL_SOC_PALDO_CTRL = 23, -+ WMT_CTRL_SOC_WAKEUP_CONSYS = 24, -+ WMT_CTRL_SET_STP_DBG_INFO = 25, -+ WMT_CTRL_BGW_DESENSE_CTRL = 26, -+ WMT_CTRL_EVT_ERR_TRG_ASSERT = 27, -+#if CFG_WMT_LTE_COEX_HANDLING -+ WMT_CTRL_GET_TDM_REQ_ANTSEL = 28, -+#endif -+ WMT_CTRL_EVT_PARSER = 29, -+ WMT_CTRL_MAX -+} ENUM_WMT_CTRL_T, *P_ENUM_WMT_CTRL_T; -+ -+typedef INT32(*WMT_CTRL_FUNC) (P_WMT_CTRL_DATA); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+extern INT32 wmt_ctrl(P_WMT_CTRL_DATA pWmtCtrlData); -+ -+extern INT32 wmt_ctrl_tx_ex(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_CTRL_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h -new file mode 100644 -index 0000000000000..d586f442e7ef0 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h -@@ -0,0 +1,140 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_FUNC_H_ -+#define _WMT_FUNC_H_ -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "wmt_core.h" -+#include "wmt_plat.h" -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#if 1 /* defined(CONFIG_MTK_COMBO_HCI_DRIVER) || defined(CONFIG_MTK_COMBO_BT) */ -+#define CFG_FUNC_BT_SUPPORT 1 -+#else -+#define CFG_FUNC_BT_SUPPORT 0 -+#endif -+ -+#if 1 /* defined(CONFIG_MTK_COMBO_FM) */ -+#define CFG_FUNC_FM_SUPPORT 1 -+#else -+#define CFG_FUNC_FM_SUPPORT 0 -+#endif -+ -+#if 1 /* defined(CONFIG_MTK_COMBO_GPS) */ -+#define CFG_FUNC_GPS_SUPPORT 1 -+#else -+#define CFG_FUNC_GPS_SUPPORT 0 -+#endif -+ -+#if 1 /* defined(CONFIG_MTK_COMBO_WIFI) */ -+#define CFG_FUNC_WIFI_SUPPORT 1 -+#else -+#define CFG_FUNC_WIFI_SUPPORT 0 -+#endif -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef INT32(*SUBSYS_FUNC_ON) (P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+typedef INT32(*SUBSYS_FUNC_OFF) (P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+ -+typedef struct _WMT_FUNC_OPS_ { -+ SUBSYS_FUNC_ON func_on; -+ SUBSYS_FUNC_OFF func_off; -+} WMT_FUNC_OPS, *P_WMT_FUNC_OPS; -+ -+typedef struct _CMB_PIN_CTRL_REG_ { -+ UINT32 regAddr; -+ UINT32 regValue; -+ UINT32 regMask; -+ -+} CMB_PIN_CTRL_REG, *P_CMB_PIN_CTRL_REG; -+ -+typedef struct _CMB_PIN_CTRL_ { -+ UINT32 pinId; -+ UINT32 regNum; -+ P_CMB_PIN_CTRL_REG pFuncOnArray; -+ P_CMB_PIN_CTRL_REG pFuncOffArray; -+ -+} CMB_PIN_CTRL, *P_CMB_PIN_CTRL; -+ -+typedef enum _ENUM_CMP_PIN_ID_ { -+ CMB_PIN_EEDI_ID = 0, -+ CMB_PIN_EEDO_ID = 1, -+ CMB_PIN_GSYNC_ID = 2, -+} ENUM_CMP_PIN_ID, *P_ENUM_CMP_PIN_ID; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if CFG_FUNC_BT_SUPPORT -+extern WMT_FUNC_OPS wmt_func_bt_ops; -+#endif -+ -+#if CFG_FUNC_FM_SUPPORT -+extern WMT_FUNC_OPS wmt_func_fm_ops; -+#endif -+ -+#if CFG_FUNC_GPS_SUPPORT -+extern WMT_FUNC_OPS wmt_func_gps_ops; -+#endif -+ -+#if CFG_FUNC_WIFI_SUPPORT -+extern WMT_FUNC_OPS wmt_func_wifi_ops; -+#endif -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_FUNC_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h -new file mode 100644 -index 0000000000000..901becfdb92f0 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h -@@ -0,0 +1,122 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_IC_H_ -+#define _WMT_IC_H_ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "wmt_core.h" -+#include "wmt_exp.h" -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define WMT_IC_NAME_MT6620 "MT6620" -+#define WMT_IC_NAME_MT6628 "MT6628" -+#define WMT_IC_NAME_DEFAULT "SOC_CONSYS" -+ -+#define WMT_IC_VER_E1 "E1" -+#define WMT_IC_VER_E2 "E2" -+#define WMT_IC_VER_E3 "E3" -+#define WMT_IC_VER_E4 "E4" -+#define WMT_IC_VER_E5 "E5" -+#define WMT_IC_VER_E6 "E6" -+ -+#define WMT_IC_PATCH_DUMMY_EXT "_ex" -+#define WMT_IC_PATCH_NO_EXT "" -+#define WMT_IC_PATCH_E1_EXT "_e1" -+#define WMT_IC_PATCH_E2_EXT "_e2" -+#define WMT_IC_PATCH_E3_EXT "_e3" -+#define WMT_IC_PATCH_E4_EXT "_e4" -+#define WMT_IC_PATCH_E5_EXT "_e5" -+#define WMT_IC_PATCH_E6_EXT "_e6" -+ -+#define WMT_IC_PATCH_TAIL "_hdr.bin" -+ -+#define WMT_IC_INVALID_CHIP_ID 0xFFFF -+ -+#define MAJORNUM(x) (x & 0x00F0) -+#define MINORNUM(x) (x & 0x000F) -+ -+/******************************************************************************* -+* R E G I S T E R M A P -+******************************************************************************** -+*/ -+/* General definition used for ALL/UNKNOWN CHIPS */ -+/* Now MT6620 uses these definitions */ -+#define GEN_CONFG_BASE (0x80000000UL) -+#define GEN_HVR (GEN_CONFG_BASE + 0x0UL) /* HW_VER */ -+#define GEN_FVR (GEN_CONFG_BASE + 0x4UL) /* FW_VER */ -+#define GEN_VER_MASK (0x0000FFFFUL) /* HW_VER and FW_VER valid bits mask */ -+#define GEN_HCR (GEN_CONFG_BASE + 0x8UL) /* HW_CODE, chip id */ -+#define GEN_HCR_MASK (0x0000FFFFUL) /* HW_CODE valid bits mask */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef struct _WMT_IC_INFO_S { -+ UINT32 u4HwVer; /* u4HwId */ -+ PUINT8 cChipName; -+ PUINT8 cChipVersion; -+ PUINT8 cPatchNameExt; -+ MTK_WCN_BOOL bPsmSupport; -+ MTK_WCN_BOOL bWorkWithoutPatch; -+ ENUM_WMTHWVER_TYPE_T eWmtHwVer; -+} WMT_IC_INFO_S, *P_WMT_IC_INFO_S; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_IC_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h -new file mode 100644 -index 0000000000000..b0c05cf3a2529 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h -@@ -0,0 +1,300 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_LIB_H_ -+#define _WMT_LIB_H_ -+ -+#include "osal.h" -+#include "wmt_core.h" -+#include "wmt_exp.h" -+#include -+#include "stp_wmt.h" -+#include "wmt_plat.h" -+#include "wmt_idc.h" -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define WMT_OP_BUF_SIZE (16) -+ -+typedef enum _ENUM_WMTRSTRET_TYPE_T { -+ WMTRSTRET_SUCCESS = 0x0, -+ WMTRSTRET_FAIL = 0x1, -+ WMTRSTRET_ONGOING = 0x2, -+ WMTRSTRET_MAX -+} ENUM_WMTRSTRET_TYPE_T, *P_ENUM_WMTRSTRET_TYPE_T; -+ -+/* -+3(retry times) * 180 (STP retry time out) -++ 10 (firmware process time) + -+10 (transmit time) + -+10 (uart process -> WMT response pool) + -+230 (others) -+*/ -+#define WMT_LIB_RX_TIMEOUT 20000 /*800-->cover v1.2phone BT function on time (~830ms) */ -+/* -+open wifi during wifi power on procedure -+(because wlan is insert to system after mtk_hif_sdio module, -+so wifi card is not registered to hif module -+when mtk_wcn_wmt_func_on is called by wifi through rfkill) -+*/ -+#define MAX_WIFI_ON_TIME 55000 -+ -+#define WMT_PWRON_RTY_DFT 2 -+#define MAX_RETRY_TIME_DUE_TO_RX_TIMEOUT (WMT_PWRON_RTY_DFT * WMT_LIB_RX_TIMEOUT) -+#define MAX_EACH_FUNC_ON_WHEN_CHIP_POWER_ON_ALREADY WMT_LIB_RX_TIMEOUT /*each WMT command */ -+#define MAX_FUNC_ON_TIME \ -+ (MAX_WIFI_ON_TIME + MAX_RETRY_TIME_DUE_TO_RX_TIMEOUT + MAX_EACH_FUNC_ON_WHEN_CHIP_POWER_ON_ALREADY * 3) -+ -+#define MAX_EACH_FUNC_OFF (WMT_LIB_RX_TIMEOUT + 1000) /*1000->WMT_LIB_RX_TIMEOUT + 1000, logical judgement */ -+#define MAX_FUNC_OFF_TIME (MAX_EACH_FUNC_OFF * 4) -+ -+#define MAX_EACH_WMT_CMD (WMT_LIB_RX_TIMEOUT + 1000) /*1000->WMT_LIB_RX_TIMEOUT + 1000, logical judgement */ -+ -+#define MAX_GPIO_CTRL_TIME (2000) /* [FixMe][GeorgeKuo] a temp value */ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* AIF FLAG definition */ -+/* bit(0): share pin or not */ -+#define WMT_LIB_AIF_FLAG_MASK (0x1UL) -+#define WMT_LIB_AIF_FLAG_SHARE (0x1UL << 0) -+#define WMT_LIB_AIF_FLAG_SEPARATE (0x0UL << 0) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/* bit field offset definition */ -+typedef enum { -+ WMT_STAT_PWR = 0, /* is powered on */ -+ WMT_STAT_STP_REG = 1, /* is STP driver registered: */ -+ WMT_STAT_STP_OPEN = 2, /* is STP opened: default FALSE */ -+ WMT_STAT_STP_EN = 3, /* is STP enabled: default FALSE */ -+ WMT_STAT_STP_RDY = 4, /* is STP ready for client: default FALSE */ -+ WMT_STAT_RX = 5, /* is rx data available */ -+ WMT_STAT_CMD = 6, /* is cmd string to be read */ -+ WMT_STAT_RST_ON = 7, -+ WMT_STAT_MAX -+} WMT_STAT; -+ -+typedef enum _ENUM_WMTRSTSRC_TYPE_T { -+ WMTRSTSRC_RESET_BT = 0x0, -+ WMTRSTSRC_RESET_FM = 0x1, -+ WMTRSTSRC_RESET_GPS = 0x2, -+ WMTRSTSRC_RESET_WIFI = 0x3, -+ WMTRSTSRC_RESET_STP = 0x4, -+ WMTRSTSRC_RESET_TEST = 0x5, -+ WMTRSTSRC_RESET_MAX -+} ENUM_WMTRSTSRC_TYPE_T, *P_ENUM_WMTRSTSRC_TYPE_T; -+ -+typedef struct { -+ PF_WMT_CB fDrvRst[4]; -+} WMT_FDRV_CB, *P_WMT_FDRV_CB; -+ -+typedef struct { -+ UINT32 dowloadSeq; -+ UINT8 addRess[4]; -+ UINT8 patchName[256]; -+} WMT_PATCH_INFO, *P_WMT_PATCH_INFO; -+ -+/* OS independent wrapper for WMT_OP */ -+typedef struct _DEV_WMT_ { -+ -+ OSAL_SLEEPABLE_LOCK psm_lock; -+ OSAL_SLEEPABLE_LOCK idc_lock; -+ /* WMTd thread information */ -+ /* struct task_struct *pWmtd; */ -+ OSAL_THREAD thread; /* main thread (wmtd) handle */ -+ /* wait_queue_head_t rWmtdWq; */ -+ OSAL_EVENT rWmtdWq; /*WMTd command wait queue */ -+ /* ULONG state; */ -+ OSAL_BIT_OP_VAR state; /* bit field of WMT_STAT */ -+ -+ /* STP context information */ -+ /* wait_queue_head_t rWmtRxWq; */ -+ OSAL_EVENT rWmtRxWq; /* STP Rx wait queue */ -+ /* WMT_STP_FUNC rStpFunc; */ -+ WMT_FDRV_CB rFdrvCb; /* STP functions */ -+ -+ /* WMT Configurations */ -+ WMT_HIF_CONF rWmtHifConf; -+ WMT_GEN_CONF rWmtGenConf; -+ -+ /* Patch information */ -+ UINT8 cPatchName[NAME_MAX + 1]; -+ UINT8 cFullPatchName[NAME_MAX + 1]; -+ UINT32 patchNum; -+ -+ const osal_firmware *pPatch; -+ -+ UINT8 cWmtcfgName[NAME_MAX + 1]; -+ const osal_firmware *pWmtCfg; -+ -+ const osal_firmware *pNvram; -+ -+ /* Current used UART port description */ -+ INT8 cUartName[NAME_MAX + 1]; -+ -+ OSAL_OP_Q rFreeOpQ; /* free op queue */ -+ OSAL_OP_Q rActiveOpQ; /* active op queue */ -+ OSAL_OP arQue[WMT_OP_BUF_SIZE]; /* real op instances */ -+ P_OSAL_OP pCurOP; /* current op */ -+ -+ /* cmd str buffer */ -+ UINT8 cCmd[NAME_MAX + 1]; -+ INT32 cmdResult; -+ /* struct completion cmd_comp; */ -+ /* wait_queue_head_t cmd_wq; */ -+ OSAL_SIGNAL cmdResp; /* read command queues */ -+ OSAL_EVENT cmdReq; -+ -+ /* WMT loopback Thread Information */ -+ /* WMT_CMB_VER combo_ver; */ -+ /* P_WMT_CMB_CHIP_INFO_S pChipInfo; */ -+ UINT32 chip_id; -+ UINT32 hw_ver; -+ UINT32 fw_ver; -+ /* TODO: [FixMe][GeorgeKuo] remove this translated version code in the */ -+ /* future. Just return the above 3 info to querist */ -+ ENUM_WMTHWVER_TYPE_T eWmtHwVer; -+ -+ P_WMT_PATCH_INFO pWmtPatchInfo; -+} DEV_WMT, *P_DEV_WMT; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern DEV_WMT gDevWmt; -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+extern INT32 wmt_lib_init(VOID); -+extern INT32 wmt_lib_deinit(VOID); -+extern INT32 wmt_lib_tx(PUINT8 data, UINT32 size, PUINT32 writtenSize); -+extern INT32 wmt_lib_tx_raw(PUINT8 data, UINT32 size, PUINT32 writtenSize); -+extern INT32 wmt_lib_rx(PUINT8 buff, UINT32 buffLen, PUINT32 readSize); -+extern VOID wmt_lib_flush_rx(VOID); -+ -+#if CFG_WMT_PS_SUPPORT -+extern INT32 wmt_lib_ps_set_idle_time(UINT32 psIdleTime); -+extern INT32 wmt_lib_ps_init(VOID); -+extern INT32 wmt_lib_ps_deinit(VOID); -+extern INT32 wmt_lib_ps_enable(VOID); -+extern INT32 wmt_lib_ps_ctrl(UINT32 state); -+ -+extern INT32 wmt_lib_ps_disable(VOID); -+extern VOID wmt_lib_ps_irq_cb(VOID); -+#endif -+extern VOID wmt_lib_ps_set_sdio_psop(PF_WMT_SDIO_PSOP own_cb); -+ -+/* LXOP functions: */ -+extern P_OSAL_OP wmt_lib_get_free_op(VOID); -+extern INT32 wmt_lib_put_op_to_free_queue(P_OSAL_OP pOp); -+extern MTK_WCN_BOOL wmt_lib_put_act_op(P_OSAL_OP pOp); -+ -+/* extern ENUM_WMTHWVER_TYPE_T wmt_lib_get_hwver (VOID); */ -+extern UINT32 wmt_lib_get_icinfo(ENUM_WMT_CHIPINFO_TYPE_T type); -+ -+extern MTK_WCN_BOOL wmt_lib_is_therm_ctrl_support(VOID); -+extern MTK_WCN_BOOL wmt_lib_is_dsns_ctrl_support(VOID); -+extern INT32 wmt_lib_trigger_cmd_signal(INT32 result); -+extern PUINT8 wmt_lib_get_cmd(VOID); -+extern P_OSAL_EVENT wmt_lib_get_cmd_event(VOID); -+extern INT32 wmt_lib_set_patch_name(PUINT8 cPatchName); -+extern INT32 wmt_lib_set_hif(unsigned long hifconf); -+extern P_WMT_HIF_CONF wmt_lib_get_hif(VOID); -+extern MTK_WCN_BOOL wmt_lib_get_cmd_status(VOID); -+ -+/* GeorgeKuo: replace set_chip_gpio() with more specific ones */ -+#if 0 /* moved to wmt_exp.h */ -+extern INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); /* set AUDIO interface options */ -+#endif -+extern INT32 wmt_lib_host_awake_get(VOID); -+extern INT32 wmt_lib_host_awake_put(VOID); -+extern UINT32 wmt_lib_dbg_level_set(UINT32 level); -+ -+extern INT32 wmt_lib_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); -+ -+extern INT32 wmt_lib_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); -+ENUM_WMTRSTRET_TYPE_T wmt_lib_cmb_rst(ENUM_WMTRSTSRC_TYPE_T src); -+MTK_WCN_BOOL wmt_lib_sw_rst(INT32 baudRst); -+MTK_WCN_BOOL wmt_lib_hw_rst(VOID); -+INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask); -+INT32 wmt_lib_efuse_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask); -+ -+extern INT32 DISABLE_PSM_MONITOR(void); -+extern VOID ENABLE_PSM_MONITOR(void); -+extern INT32 wmt_lib_notify_stp_sleep(void); -+extern void wmt_lib_psm_lock_release(void); -+extern INT32 wmt_lib_psm_lock_aquire(void); -+extern VOID wmt_lib_idc_lock_release(VOID); -+extern INT32 wmt_lib_idc_lock_aquire(VOID); -+extern INT32 wmt_lib_set_stp_wmt_last_close(UINT32 value); -+ -+extern VOID wmt_lib_set_patch_num(UINT32 num); -+extern VOID wmt_lib_set_patch_info(P_WMT_PATCH_INFO pPatchinfo); -+extern INT32 wmt_lib_set_current_op(P_DEV_WMT pWmtDev, P_OSAL_OP pOp); -+extern P_OSAL_OP wmt_lib_get_current_op(P_DEV_WMT pWmtDev); -+extern PUINT8 wmt_lib_get_fwinfor_from_emi(UINT8 section, UINT32 offset, PUINT8 buff, UINT32 len); -+extern INT32 wmt_lib_poll_cpupcr(UINT32 count, UINT16 sleep, UINT16 toAee); -+extern PUINT8 wmt_lib_get_cpupcr_xml_format(PUINT32 len); -+extern INT32 wmt_lib_register_thermal_ctrl_cb(thermal_query_ctrl_cb thermal_ctrl); -+extern UINT32 wmt_lib_set_host_assert_info(UINT32 type, UINT32 reason, UINT32 en); -+extern INT8 wmt_lib_co_clock_get(VOID); -+extern UINT32 wmt_lib_soc_set_wifiver(UINT32 wifiver); -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+extern MTK_WCN_BOOL wmt_lib_handle_idc_msg(ipc_ilm_t *idc_infor); -+#endif -+#if CFG_WMT_PS_SUPPORT -+extern UINT32 wmt_lib_quick_sleep_ctrl(UINT32 en); -+#endif -+#if CONSYS_ENALBE_SET_JTAG -+extern UINT32 wmt_lib_jtag_flag_set(UINT32 en); -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_LIB_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c -new file mode 100644 -index 0000000000000..c826c513e2bd8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c -@@ -0,0 +1,1890 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "psm_core.h" -+#include "stp_core.h" -+#include -+ -+INT32 gPsmDbgLevel = STP_PSM_LOG_INFO; -+MTKSTP_PSM_T stp_psm_i; -+MTKSTP_PSM_T *stp_psm = &stp_psm_i; -+ -+STP_PSM_RECORD_T *g_stp_psm_dbg = NULL; -+static UINT32 g_record_num; -+ -+P_STP_PSM_OPID_RECORD g_stp_psm_opid_dbg = NULL; -+static UINT32 g_opid_record_num; -+ -+#define STP_PSM_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_LOUD) \ -+ pr_debug(PFX_PSM "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_PSM_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_DBG) \ -+ pr_debug(PFX_PSM "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_PSM_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_INFO) \ -+ pr_debug(PFX_PSM "[I]%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_PSM_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_WARN) \ -+ pr_warn(PFX_PSM "[W]%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_PSM_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_ERR) \ -+ pr_err(PFX_PSM "[E]%s(%d):ERROR! " fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+#define STP_PSM_TRC_FUNC(f) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_DBG) \ -+ pr_debug(PFX_PSM "<%s> <%d>\n", __func__, __LINE__); \ -+} while (0) -+ -+static inline INT32 _stp_psm_notify_wmt(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action); -+static INT32 _stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm); -+static INT32 _stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm); -+static INT32 _stp_psm_dbg_dmp_in(STP_PSM_RECORD_T *stp_psm_dbg, UINT32 flag, UINT32 line_num); -+static INT32 _stp_psm_dbg_out_printk(STP_PSM_RECORD_T *stp_psm_dbg); -+ -+static INT32 _stp_psm_opid_dbg_dmp_in(P_STP_PSM_OPID_RECORD p_opid_dbg, UINT32 opid, UINT32 line_num); -+static INT32 _stp_psm_opid_dbg_out_printk(P_STP_PSM_OPID_RECORD p_opid_dbg); -+ -+static const char *g_psm_state[STP_PSM_MAX_STATE] = { -+ "ACT", -+ "ACT_INACT", -+ "INACT", -+ "INACT_ACT" -+}; -+ -+static const char *g_psm_action[STP_PSM_MAX_ACTION] = { -+ "SLEEP", -+ "HOST_AWAKE", -+ "WAKEUP", -+ "EIRQ", -+ "ROLL_BACK" -+}; -+ -+static const char *g_psm_op_name[STP_OPID_PSM_NUM] = { -+ "STP_OPID_PSM_SLEEP", -+ "STP_OPID_PSM_WAKEUP", -+ "STP_OPID_PSM_HOST_AWAKE", -+ "STP_OPID_PSM_EXIT" -+}; -+ -+static int _stp_psm_release_data(MTKSTP_PSM_T *stp_psm); -+ -+static inline int _stp_psm_get_state(MTKSTP_PSM_T *stp_psm); -+ -+static int _stp_psm_is_redundant_active_op(P_OSAL_OP pOp, P_OSAL_OP_Q pOpQ); -+ -+static int _stp_psm_clean_up_redundant_active_op(P_OSAL_OP_Q pOpQ); -+static MTK_WCN_BOOL _stp_psm_is_quick_ps_support(VOID); -+ -+MTK_WCN_BOOL mtk_wcn_stp_psm_dbg_level(UINT32 dbglevel) -+{ -+ if (dbglevel <= 4) { -+ gPsmDbgLevel = dbglevel; -+ STP_PSM_INFO_FUNC("gPsmDbgLevel = %d\n", gPsmDbgLevel); -+ return true; -+ } -+ STP_PSM_INFO_FUNC("invalid psm debug level. gPsmDbgLevel = %d\n", gPsmDbgLevel); -+ -+ return false; -+} -+ -+static INT32 _stp_psm_handler(MTKSTP_PSM_T *stp_psm, P_STP_OP pStpOp) -+{ -+ INT32 ret = -1; -+ -+ /* if (NULL == pStpOp) */ -+ /* { */ -+ /* return -1; */ -+ /* } */ -+ ret = _stp_psm_thread_lock_aquire(stp_psm); -+ if (ret) { -+ STP_PSM_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret); -+ return ret; -+ } -+ -+ switch (pStpOp->opId) { -+ case STP_OPID_PSM_EXIT: -+ /* TODO: clean all up? */ -+ ret = 0; -+ break; -+ -+ case STP_OPID_PSM_SLEEP: -+ if (stp_psm_check_sleep_enable(stp_psm) > 0) -+ ret = _stp_psm_notify_wmt(stp_psm, SLEEP); -+ else -+ STP_PSM_INFO_FUNC("cancel sleep request\n"); -+ -+ break; -+ -+ case STP_OPID_PSM_WAKEUP: -+ ret = _stp_psm_notify_wmt(stp_psm, WAKEUP); -+ break; -+ -+ case STP_OPID_PSM_HOST_AWAKE: -+ ret = _stp_psm_notify_wmt(stp_psm, HOST_AWAKE); -+ break; -+ -+ default: -+ STP_PSM_ERR_FUNC("invalid operation id (%d)\n", pStpOp->opId); -+ ret = -1; -+ break; -+ } -+ _stp_psm_thread_lock_release(stp_psm); -+ return ret; -+} -+ -+static P_OSAL_OP _stp_psm_get_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP_Q pOpQ) -+{ -+ P_OSAL_OP pOp; -+ -+ if (!pOpQ) { -+ STP_PSM_WARN_FUNC("pOpQ == NULL\n"); -+ return NULL; -+ } -+ -+ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ /* acquire lock success */ -+ RB_GET(pOpQ, pOp); -+ -+ if ((pOpQ == &stp_psm->rActiveOpQ) && (NULL != pOp)) { -+ /* stp_psm->current_active_op = pOp; */ -+ stp_psm->last_active_opId = pOp->op.opId; -+ } -+ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ -+ if ((pOpQ == &stp_psm->rActiveOpQ) && (NULL != pOp)) -+ STP_PSM_DBG_FUNC("last_active_opId(%d)\n", stp_psm->last_active_opId); -+ -+ if (!pOp) -+ STP_PSM_WARN_FUNC("RB_GET fail\n"); -+ -+ return pOp; -+} -+ -+static INT32 _stp_psm_dump_active_q(P_OSAL_OP_Q pOpQ) -+{ -+ UINT32 read_idx; -+ UINT32 write_idx; -+ UINT32 opId; -+ -+ if (pOpQ == &stp_psm->rActiveOpQ) { -+ read_idx = stp_psm->rActiveOpQ.read; -+ write_idx = stp_psm->rActiveOpQ.write; -+ -+ STP_PSM_DBG_FUNC("Active op list:++\n"); -+ while ((read_idx & RB_MASK(pOpQ)) != (write_idx & RB_MASK(pOpQ))) { -+ opId = pOpQ->queue[read_idx & RB_MASK(pOpQ)]->op.opId; -+ if (opId < STP_OPID_PSM_NUM) -+ STP_PSM_DBG_FUNC("%s\n", g_psm_op_name[opId]); -+ else -+ STP_PSM_WARN_FUNC("Unknown OP Id\n"); -+ -+ ++read_idx; -+ } -+ STP_PSM_DBG_FUNC("Active op list:--\n"); -+ } else { -+ STP_PSM_DBG_FUNC("%s: not active queue, dont dump\n", __func__); -+ } -+ -+ return 0; -+} -+ -+static int _stp_psm_is_redundant_active_op(P_OSAL_OP pOp, P_OSAL_OP_Q pOpQ) -+{ -+ unsigned int opId = 0; -+ unsigned int prev_opId = 0; -+ -+ /* if((pOpQ == &stp_psm->rActiveOpQ) && (NULL != stp_psm->current_active_op)) */ -+ if ((pOpQ == &stp_psm->rActiveOpQ) && (STP_OPID_PSM_INALID != stp_psm->last_active_opId)) { -+ opId = pOp->op.opId; -+ -+ if (opId == STP_OPID_PSM_SLEEP) { -+ if (RB_EMPTY(pOpQ)) { -+ /* prev_opId = stp_psm->current_active_op->op.opId; */ -+ prev_opId = stp_psm->last_active_opId; -+ } else { -+ prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; -+ } -+ -+ if (prev_opId == STP_OPID_PSM_SLEEP) { -+ STP_PSM_DBG_FUNC("redundant sleep opId found\n"); -+ return 1; -+ } else { -+ return 0; -+ } -+ } else { -+ if (RB_EMPTY(pOpQ)) { -+ /* prev_opId = stp_psm->current_active_op->op.opId; */ -+ prev_opId = stp_psm->last_active_opId; -+ } else { -+ prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; -+ } -+ -+ if (((opId == STP_OPID_PSM_WAKEUP) && (prev_opId == STP_OPID_PSM_WAKEUP)) || -+ ((opId == STP_OPID_PSM_HOST_AWAKE) && (prev_opId == STP_OPID_PSM_WAKEUP)) || -+ ((opId == STP_OPID_PSM_HOST_AWAKE) && (prev_opId == STP_OPID_PSM_HOST_AWAKE)) || -+ ((opId == STP_OPID_PSM_WAKEUP) && (prev_opId == STP_OPID_PSM_HOST_AWAKE)) -+ ) { -+ STP_PSM_DBG_FUNC("redundant opId found, opId(%d), preOpid(%d)\n", opId, prev_opId); -+ return 1; -+ } else { -+ return 0; -+ } -+ } -+ } else { -+ return 0; -+ } -+ -+} -+ -+static int _stp_psm_clean_up_redundant_active_op(P_OSAL_OP_Q pOpQ) -+{ -+ unsigned int prev_opId = 0; -+ unsigned int prev_prev_opId = 0; -+ -+ P_OSAL_OP pOp; -+ P_OSAL_OP_Q pFreeOpQ = &stp_psm->rFreeOpQ; -+ -+ if (pOpQ == &stp_psm->rActiveOpQ) { -+ /* sleep , wakeup | sleep, --> null | sleep (x) */ -+ /* wakeup , sleep , wakeup | sleep --> wakeup | sleep (v) */ -+ /* sleep , wakeup , sleep | wakeup --> sleep | wakeup (v) */ -+ /* xxx, sleep | sleep --> xxx, sleep (v) */ -+ /* xxx, wakeup | wakeup --> xxx, wakeup (v) */ -+ /* xxx, awake | awake --> xxx, awake (v) --> should never happen */ -+ while (RB_COUNT(pOpQ) > 2) { -+ prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; -+ prev_prev_opId = pOpQ->queue[(pOpQ->write - 2) & RB_MASK(pOpQ)]->op.opId; -+ -+ if ((prev_opId == STP_OPID_PSM_SLEEP && prev_prev_opId == STP_OPID_PSM_WAKEUP) || -+ (prev_opId == STP_OPID_PSM_SLEEP && prev_prev_opId == STP_OPID_PSM_HOST_AWAKE) || -+ (prev_opId == STP_OPID_PSM_WAKEUP && prev_prev_opId == STP_OPID_PSM_SLEEP) || -+ (prev_opId == STP_OPID_PSM_HOST_AWAKE && prev_prev_opId == STP_OPID_PSM_SLEEP) -+ ) { -+ RB_GET(pOpQ, pOp); -+ RB_PUT(pFreeOpQ, pOp); -+ RB_GET(pOpQ, pOp); -+ RB_PUT(pFreeOpQ, pOp); -+ } else if (prev_opId == prev_prev_opId) { -+ RB_GET(pOpQ, pOp); -+ STP_PSM_DBG_FUNC("redundant opId(%d) found, remove it\n", pOp->op.opId); -+ RB_PUT(pFreeOpQ, pOp); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static INT32 _stp_psm_put_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) -+{ -+ INT32 ret; -+ -+ /* if (!pOpQ || !pOp) */ -+ /* { */ -+ /* STP_PSM_WARN_FUNC("pOpQ = 0x%p, pLxOp = 0x%p\n", pOpQ, pOp); */ -+ /* return 0; */ -+ /* } */ -+ ret = 0; -+ -+ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ /* acquire lock success */ -+ if (pOpQ == &stp_psm->rActiveOpQ) { -+ if (!_stp_psm_is_redundant_active_op(pOp, pOpQ)) { -+ /* acquire lock success */ -+ if (!RB_FULL(pOpQ)) { -+ RB_PUT(pOpQ, pOp); -+ STP_PSM_DBG_FUNC("opId(%d) enqueue\n", pOp->op.opId); -+ } else { -+ STP_PSM_INFO_FUNC("************ Active Queue Full ************\n"); -+ ret = -1; -+ } -+ -+ _stp_psm_clean_up_redundant_active_op(pOpQ); -+ } else { -+ /*redundant opId, mark ret as success */ -+ P_OSAL_OP_Q pFreeOpQ = &stp_psm->rFreeOpQ; -+ -+ if (!RB_FULL(pFreeOpQ)) -+ RB_PUT(pFreeOpQ, pOp); -+ else -+ osal_assert(!RB_FULL(pFreeOpQ)); -+ -+ ret = 0; -+ } -+ } else { -+ if (!RB_FULL(pOpQ)) -+ RB_PUT(pOpQ, pOp); -+ else -+ ret = -1; -+ -+ } -+ -+ if (pOpQ == &stp_psm->rActiveOpQ) -+ _stp_psm_dump_active_q(&stp_psm->rActiveOpQ); -+ -+ -+ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ STP_PSM_DBG_FUNC("stp_psm do unlock,active queue? (%s)\n", (pOpQ == &stp_psm->rActiveOpQ) ? "y" : "n"); -+ -+ if (ret) { -+ STP_PSM_WARN_FUNC("RB_FULL, RB_COUNT=%d , RB_SIZE=%d\n", RB_COUNT(pOpQ), RB_SIZE(pOpQ)); -+ return 0; -+ } else -+ return 1; -+ -+} -+ -+P_OSAL_OP _stp_psm_get_free_op(MTKSTP_PSM_T *stp_psm) -+{ -+ P_OSAL_OP pOp; -+ -+ if (stp_psm) { -+ pOp = _stp_psm_get_op(stp_psm, &stp_psm->rFreeOpQ); -+ if (pOp) -+ osal_memset(&pOp->op, 0, sizeof(pOp->op)); -+ -+ return pOp; -+ } else -+ return NULL; -+ -+} -+ -+INT32 _stp_psm_put_act_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP pOp) -+{ -+ INT32 bRet = 0; /* MTK_WCN_BOOL_FALSE; */ -+ INT32 bCleanup = 0; /* MTK_WCN_BOOL_FALSE; */ -+ INT32 wait_ret = -1; -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ do { -+ if (!stp_psm || !pOp) { -+ STP_PSM_ERR_FUNC("stp_psm = %p, pOp = %p\n", stp_psm, pOp); -+ break; -+ } -+ -+ pSignal = &pOp->signal; -+ -+ if (pSignal->timeoutValue) { -+ pOp->result = -9; -+ osal_signal_init(&pOp->signal); -+ } -+ -+ /* put to active Q */ -+ bRet = _stp_psm_put_op(stp_psm, &stp_psm->rActiveOpQ, pOp); -+ -+ if (0 == bRet) { -+ STP_PSM_WARN_FUNC("+++++++++++ Put op Active queue Fail\n"); -+ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ -+ break; -+ } -+ _stp_psm_opid_dbg_dmp_in(g_stp_psm_opid_dbg, pOp->op.opId, __LINE__); -+ -+ /* wake up wmtd */ -+ osal_trigger_event(&stp_psm->STPd_event); -+ -+ if (pSignal->timeoutValue == 0) { -+ bRet = 1; /* MTK_WCN_BOOL_TRUE; */ -+ /* clean it in wmtd */ -+ break; -+ } -+ -+ /* wait result, clean it here */ -+ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ -+ -+ /* check result */ -+ wait_ret = osal_wait_for_signal_timeout(&pOp->signal); -+ STP_PSM_DBG_FUNC("wait completion:%d\n", wait_ret); -+ if (!wait_ret) { -+ STP_PSM_ERR_FUNC("wait completion timeout\n"); -+ /* TODO: how to handle it? retry? */ -+ } else { -+ if (pOp->result) -+ STP_PSM_WARN_FUNC("op(%d) result:%d\n", pOp->op.opId, pOp->result); -+ /* op completes, check result */ -+ bRet = (pOp->result) ? 0 : 1; -+ } -+ } while (0); -+ -+ if (bCleanup) { -+ /* put Op back to freeQ */ -+ bRet = _stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, pOp); -+ if (bRet == 0) -+ STP_PSM_WARN_FUNC("+++++++++++ Put op active free fail, maybe disable/enable psm\n"); -+ } -+ -+ return bRet; -+} -+ -+static INT32 _stp_psm_wait_for_msg(void *pvData) -+{ -+ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; -+ -+ STP_PSM_DBG_FUNC("%s: stp_psm->rActiveOpQ = %d\n", __func__, RB_COUNT(&stp_psm->rActiveOpQ)); -+ -+ return (!RB_EMPTY(&stp_psm->rActiveOpQ)) || osal_thread_should_stop(&stp_psm->PSMd); -+} -+ -+static INT32 _stp_psm_proc(void *pvData) -+{ -+ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; -+ P_OSAL_OP pOp; -+ UINT32 id; -+ INT32 result; -+ -+ if (!stp_psm) { -+ STP_PSM_WARN_FUNC("!stp_psm\n"); -+ return -1; -+ } -+/* STP_PSM_INFO_FUNC("wmtd starts running: pWmtDev(0x%p) [pol, rt_pri, n_pri, pri]=[%d, %d, %d, %d]\n", */ -+/* stp_psm, current->policy, current->rt_priority, current->normal_prio, current->prio); */ -+ -+ for (;;) { -+ -+ pOp = NULL; -+ -+ osal_wait_for_event(&stp_psm->STPd_event, _stp_psm_wait_for_msg, (void *)stp_psm); -+ -+ /* we set reset flag when calling stp_reset after cleanup all op. */ -+ if (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)) { -+ osal_clear_bit(STP_PSM_RESET_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ } -+ if (osal_thread_should_stop(&stp_psm->PSMd)) { -+ STP_PSM_INFO_FUNC("should stop now...\n"); -+ /* TODO: clean up active opQ */ -+ break; -+ } -+ -+ /* get Op from activeQ */ -+ pOp = _stp_psm_get_op(stp_psm, &stp_psm->rActiveOpQ); -+ if (!pOp) { -+ STP_PSM_WARN_FUNC("+++++++++++ Get op from activeQ fail, maybe disable/enable psm\n"); -+ continue; -+ } -+ -+ id = osal_op_get_id(pOp); -+ -+ if (id >= STP_OPID_PSM_NUM) { -+ STP_PSM_WARN_FUNC("abnormal opid id: 0x%x\n", id); -+ result = -1; -+ goto handler_done; -+ } -+ -+ result = _stp_psm_handler(stp_psm, &pOp->op); -+ -+handler_done: -+ -+ if (result) { -+ STP_PSM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, -+ (id >= 4) ? ("???") : (g_psm_op_name[id]), result); -+ } -+ -+ if (osal_op_is_wait_for_signal(pOp)) -+ osal_op_raise_signal(pOp, result); -+ else { -+ /* put Op back to freeQ */ -+ if (_stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, pOp) == 0) -+ STP_PSM_WARN_FUNC("+++++++++++ Put op to FreeOpQ fail, maybe disable/enable psm\n"); -+ } -+ -+ if (STP_OPID_PSM_EXIT == id) -+ break; -+ } -+ STP_PSM_INFO_FUNC("exits\n"); -+ -+ return 0; -+}; -+ -+static inline INT32 _stp_psm_get_time(void) -+{ -+ if (gPsmDbgLevel >= STP_PSM_LOG_LOUD) -+ osal_printtimeofday(">>>"); -+ -+ return 0; -+} -+ -+static inline INT32 _stp_psm_get_state(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ if (stp_psm->work_state < STP_PSM_MAX_STATE) -+ return stp_psm->work_state; -+ STP_PSM_ERR_FUNC("work_state = %d, invalid\n", stp_psm->work_state); -+ -+ return STP_PSM_OPERATION_FAIL; -+} -+ -+static inline INT32 _stp_psm_set_state(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_STATE_T state) -+{ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ if (stp_psm->work_state < STP_PSM_MAX_STATE) { -+ _stp_psm_get_time(); -+ /* STP_PSM_INFO_FUNC("work_state = %s --> %s\n", -+ * g_psm_state[stp_psm->work_state], g_psm_state[state]); -+ */ -+ -+ stp_psm->work_state = state; -+ if (stp_psm->work_state != ACT) { -+ /* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ osal_set_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ } -+ } else -+ STP_PSM_ERR_FUNC("work_state = %d, invalid\n", stp_psm->work_state); -+ -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { -+ STP_PSM_DBG_FUNC("STP-PSM DISABLE, DONT restart monitor!\n\r"); -+ return STP_PSM_OPERATION_SUCCESS; -+ } -+ -+ STP_PSM_LOUD_FUNC("start monitor\n"); -+ osal_timer_modify(&stp_psm->psm_timer, stp_psm->idle_time_to_sleep); -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_stop_monitor(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ STP_PSM_DBG_FUNC("stop monitor\n"); -+ osal_timer_stop_sync(&stp_psm->psm_timer); -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+INT32 _stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type) -+{ -+ INT32 available_space = 0; -+ INT32 needed_space = 0; -+ UINT8 delimiter[] = { 0xbb, 0xbb }; -+ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ -+ available_space = STP_PSM_FIFO_SIZE - osal_fifo_len(&stp_psm->hold_fifo); -+ needed_space = len + sizeof(UINT8) + sizeof(UINT32) + 2; -+ -+ /* STP_PSM_INFO_FUNC("*******FIFO Available(%d), Need(%d)\n", available_space, needed_space); */ -+ -+ if (available_space < needed_space) { -+ STP_PSM_ERR_FUNC("FIFO Available!! Reset FIFO\n"); -+ osal_fifo_reset(&stp_psm->hold_fifo); -+ } -+ /* type */ -+ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) &type, sizeof(UINT8)); -+ /* length */ -+ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) &len, sizeof(UINT32)); -+ /* buffer */ -+ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) buffer, len); -+ /* delimiter */ -+ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) delimiter, 2); -+ -+ osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ -+ return len; -+ -+} -+ -+INT32 _stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm) -+{ -+ return osal_fifo_len(&stp_psm->hold_fifo); -+} -+ -+INT32 _stp_psm_release_data(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ INT32 i = 20; /*Max buffered packet number */ -+ INT32 ret = 0; -+ UINT8 type = 0; -+ UINT32 len = 0; -+ UINT8 delimiter[2]; -+ -+ /* STP_PSM_ERR_FUNC("++++++++++release data++len=%d\n", osal_fifo_len(&stp_psm->hold_fifo)); */ -+ while (osal_fifo_len(&stp_psm->hold_fifo) && i > 0) { -+ /* acquire spinlock */ -+ osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ -+ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) &type, sizeof(UINT8)); -+ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) &len, sizeof(UINT32)); -+ -+ if (len > STP_PSM_PACKET_SIZE_MAX) { -+ STP_PSM_ERR_FUNC("***psm packet's length too Long!****\n"); -+ STP_PSM_INFO_FUNC("***reset psm's fifo***\n"); -+ } else { -+ osal_memset(stp_psm->out_buf, 0, STP_PSM_TX_SIZE); -+ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) stp_psm->out_buf, len); -+ } -+ -+ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) delimiter, 2); -+ -+ if (delimiter[0] == 0xbb && delimiter[1] == 0xbb) { -+ /* osal_buffer_dump(stp_psm->out_buf, "psm->out_buf", len, 32); */ -+ stp_send_data_no_ps(stp_psm->out_buf, len, type); -+ } else { -+ STP_PSM_ERR_FUNC("***psm packet fifo parsing fail****\n"); -+ STP_PSM_INFO_FUNC("***reset psm's fifo***\n"); -+ -+ osal_fifo_reset(&stp_psm->hold_fifo); -+ } -+ i--; -+ osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ } -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_notify_wmt_host_awake_wq(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ pOp = _stp_psm_get_free_op(stp_psm); -+ if (!pOp) { -+ STP_PSM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ -+ pOp->op.opId = STP_OPID_PSM_HOST_AWAKE; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_psm_put_act_op(stp_psm, pOp); -+ -+ STP_PSM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ -+ retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : 0; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_psm_notify_wmt_wakeup_wq(MTKSTP_PSM_T *stp_psm) -+{ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ pOp = _stp_psm_get_free_op(stp_psm); -+ if (!pOp) { -+ STP_PSM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ -+ pOp->op.opId = STP_OPID_PSM_WAKEUP; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_psm_put_act_op(stp_psm, pOp); -+ if (0 == bRet) { -+ STP_PSM_WARN_FUNC("OPID(%d) type(%zd) bRet(%s)\n\n", -+ pOp->op.opId, pOp->op.au4OpData[0], "fail"); -+ } -+ retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : (STP_PSM_OPERATION_SUCCESS); -+ -+ return retval; -+} -+ -+static inline INT32 _stp_psm_notify_wmt_sleep_wq(MTKSTP_PSM_T *stp_psm) -+{ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag)) -+ return 0; -+#if PSM_USE_COUNT_PACKAGE -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag)) -+ return 0; -+#endif -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) -+ return 0; -+ -+ pOp = _stp_psm_get_free_op(stp_psm); -+ if (!pOp) { -+ STP_PSM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ -+ pOp->op.opId = STP_OPID_PSM_SLEEP; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_psm_put_act_op(stp_psm, pOp); -+ -+ STP_PSM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ -+ retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : 1; -+ -+ return retval; -+} -+ -+/*internal function*/ -+ -+static inline INT32 _stp_psm_reset(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 i = 0; -+ P_OSAL_OP_Q pOpQ; -+ P_OSAL_OP pOp; -+ -+ STP_PSM_DBG_FUNC("PSM MODE RESET=============================>\n\r"); -+ -+ STP_PSM_DBG_FUNC("_stp_psm_reset\n"); -+ STP_PSM_DBG_FUNC("reset-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ osal_wake_unlock(&stp_psm->wake_lock); -+ STP_PSM_DBG_FUNC("reset-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ -+ /* --> disable psm <--// */ -+ stp_psm->flag.data = 0; -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ _stp_psm_stop_monitor(stp_psm); -+ -+ /* --> prepare the op list <--// */ -+ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ RB_INIT(&stp_psm->rFreeOpQ, STP_OP_BUF_SIZE); -+ RB_INIT(&stp_psm->rActiveOpQ, STP_OP_BUF_SIZE); -+ -+ /* stp_psm->current_active_op = NULL; */ -+ stp_psm->last_active_opId = STP_OPID_PSM_INALID; -+ -+ pOpQ = &stp_psm->rFreeOpQ; -+ for (i = 0; i < STP_OP_BUF_SIZE; i++) { -+ if (!RB_FULL(pOpQ)) { -+ pOp = &stp_psm->arQue[i]; -+ RB_PUT(pOpQ, pOp); -+ } -+ } -+ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ -+ /* --> clean up interal data structure<--// */ -+ _stp_psm_set_state(stp_psm, ACT); -+ -+ osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ osal_fifo_reset(&stp_psm->hold_fifo); -+ osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ -+ /* --> stop psm thread wait <--// */ -+ osal_set_bit(STP_PSM_RESET_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ -+ STP_PSM_DBG_FUNC("PSM MODE RESET<============================\n\r"); -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static INT32 _stp_psm_wait_wmt_event(void *pvData) -+{ -+ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; -+ -+ STP_PSM_DBG_FUNC("%s, stp_psm->flag= %ld\n", __func__, stp_psm->flag.data); -+ -+ return (osal_test_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag)) || -+ (osal_test_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag)) || -+ (osal_test_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag)) || -+ (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)); -+} -+ -+static inline INT32 _stp_psm_wait_wmt_event_wq(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ INT32 retval = 0; -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ osal_wait_for_event_timeout(&stp_psm->wait_wmt_q, _stp_psm_wait_wmt_event, (void *)stp_psm); -+ -+ if (osal_test_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag)) { -+ osal_clear_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+/* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ /* STP send data here: STP enqueue data to psm buffer. */ -+ _stp_psm_release_data(stp_psm); -+ /* STP send data here: STP enqueue data to psm buffer. We release packet by the next one. */ -+ osal_clear_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* STP send data here: STP sends data directly without PSM. */ -+ _stp_psm_set_state(stp_psm, ACT); -+/* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ -+ if (stp_psm_is_quick_ps_support()) -+ stp_psm_notify_wmt_sleep(stp_psm); -+ else -+ _stp_psm_start_monitor(stp_psm); -+ } else if (osal_test_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag)) { -+ osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ _stp_psm_set_state(stp_psm, INACT); -+ -+ STP_PSM_DBG_FUNC("mt_combo_plt_enter_deep_idle++\n"); -+ mt_combo_plt_enter_deep_idle(COMBO_IF_BTIF); -+ STP_PSM_DBG_FUNC("mt_combo_plt_enter_deep_idle--\n"); -+ -+ STP_PSM_DBG_FUNC("sleep-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ osal_wake_unlock(&stp_psm->wake_lock); -+ STP_PSM_DBG_FUNC("sleep-wake_lock#(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ } else if (osal_test_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag)) { -+ osal_clear_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ if (_stp_psm_get_state(stp_psm) == ACT_INACT) { -+ /* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ _stp_psm_release_data(stp_psm); -+ osal_clear_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ _stp_psm_set_state(stp_psm, ACT); -+ /* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ } else if (_stp_psm_get_state(stp_psm) == INACT_ACT) { -+ _stp_psm_set_state(stp_psm, INACT); -+ STP_PSM_INFO_FUNC("[WARNING]PSM state rollback due too wakeup fail\n"); -+ } -+ } else if (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)) { -+ osal_clear_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ } else { -+ STP_PSM_ERR_FUNC("flag = %ld<== Abnormal flag be set!!\n\r", stp_psm->flag.data); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ wcn_psm_flag_trigger_collect_ftrace(); /* trigger collect SYS_FTRACE */ -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ } -+ retval = STP_PSM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) -+{ -+ -+ INT32 retval = 0; -+ -+ if (action == EIRQ) { -+ STP_PSM_DBG_FUNC("Call _stp_psm_notify_wmt_host_awake_wq\n\r"); -+ -+ _stp_psm_notify_wmt_host_awake_wq(stp_psm); -+ -+ return STP_PSM_OPERATION_FAIL; -+ } -+ -+ if ((_stp_psm_get_state(stp_psm) < STP_PSM_MAX_STATE) && (_stp_psm_get_state(stp_psm) >= 0)) { -+ STP_PSM_DBG_FUNC("state = %s, action=%s\n\r", g_psm_state[_stp_psm_get_state(stp_psm)], -+ g_psm_action[action]); -+ } -+ /* If STP trigger WAKEUP and SLEEP, to do the job below */ -+ switch (_stp_psm_get_state(stp_psm)) { -+ /* stp trigger */ -+ case ACT_INACT: -+ -+ if (action == SLEEP) { -+ STP_PSM_LOUD_FUNC("Action = %s, ACT_INACT state, ready to INACT\n\r", g_psm_action[action]); -+ osal_clear_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ osal_set_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* wake_up(&stp_psm->wait_wmt_q); */ -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ } else if (action == ROLL_BACK) { -+ STP_PSM_LOUD_FUNC("Action = %s, ACT_INACT state, back to ACT\n\r", g_psm_action[action]); -+ /* stp_psm->flag &= ~STP_PSM_WMT_EVENT_ROLL_BACK_EN; */ -+ osal_set_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* wake_up(&stp_psm->wait_wmt_q); */ -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ } else { -+ if (action < STP_PSM_MAX_ACTION) { -+ STP_PSM_ERR_FUNC("Action = %s, ACT_INACT state, the case should not happens\n\r", -+ g_psm_action[action]); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ } else { -+ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); -+ } -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ retval = STP_PSM_OPERATION_FAIL; -+ } -+ break; -+ /* stp trigger */ -+ -+ case INACT_ACT: -+ -+ if (action == WAKEUP) { -+ STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, ready to ACT\n\r", g_psm_action[action]); -+ osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ osal_set_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* wake_up(&stp_psm->wait_wmt_q); */ -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ } else if (action == HOST_AWAKE) { -+ STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, ready to ACT\n\r", g_psm_action[action]); -+ osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ osal_set_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* wake_up(&stp_psm->wait_wmt_q); */ -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ } else if (action == ROLL_BACK) { -+ STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, back to INACT\n\r", g_psm_action[action]); -+ osal_set_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* wake_up(&stp_psm->wait_wmt_q); */ -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ } else { -+ if (action < STP_PSM_MAX_ACTION) { -+ STP_PSM_ERR_FUNC("Action = %s, INACT_ACT state, the case should not happens\n\r", -+ g_psm_action[action]); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ } else { -+ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); -+ } -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ retval = STP_PSM_OPERATION_FAIL; -+ } -+ break; -+ -+ case INACT: -+ -+ if (action < STP_PSM_MAX_ACTION) { -+ STP_PSM_ERR_FUNC("Action = %s, INACT state, the case should not happens\n\r", -+ g_psm_action[action]); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ } else { -+ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); -+ } -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ retval = -1; -+ -+ break; -+ -+ case ACT: -+ -+ if (action < STP_PSM_MAX_ACTION) { -+ STP_PSM_ERR_FUNC("Action = %s, ACT state, the case should not happens\n\r", -+ g_psm_action[action]); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ } else { -+ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); -+ } -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ retval = STP_PSM_OPERATION_FAIL; -+ -+ break; -+ -+ default: -+ -+ /*invalid */ -+ if (action < STP_PSM_MAX_ACTION) { -+ STP_PSM_ERR_FUNC("Action = %s, Invalid state, the case should not happens\n\r", -+ g_psm_action[action]); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ } else { -+ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); -+ } -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ retval = STP_PSM_OPERATION_FAIL; -+ -+ break; -+ } -+ -+ return retval; -+ -+} -+ -+static inline INT32 _stp_psm_notify_wmt(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) -+{ -+ INT32 ret = 0; -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ switch (_stp_psm_get_state(stp_psm)) { -+ case ACT: -+ -+ if (action == SLEEP) { -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { -+ STP_PSM_ERR_FUNC("psm monitor disabled, can't do sleep op\n"); -+ return STP_PSM_OPERATION_FAIL; -+ } -+ -+ _stp_psm_set_state(stp_psm, ACT_INACT); -+ -+ _stp_psm_release_data(stp_psm); -+ -+ if (stp_psm->wmt_notify) { -+ stp_psm->wmt_notify(SLEEP); -+ _stp_psm_wait_wmt_event_wq(stp_psm); -+ } else { -+ STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n"); -+ ret = STP_PSM_OPERATION_FAIL; -+ } -+ } else if (action == WAKEUP || action == HOST_AWAKE) { -+ STP_PSM_INFO_FUNC("In ACT state, dont do WAKEUP/HOST_AWAKE again\n"); -+ _stp_psm_release_data(stp_psm); -+ } else { -+ STP_PSM_ERR_FUNC("invalid operation, the case should not happen\n"); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ ret = STP_PSM_OPERATION_FAIL; -+ -+ } -+ -+ break; -+ -+ case INACT: -+ -+ if (action == WAKEUP) { -+ _stp_psm_set_state(stp_psm, INACT_ACT); -+ -+ if (stp_psm->wmt_notify) { -+ STP_PSM_DBG_FUNC("wakeup +wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ osal_wake_lock(&stp_psm->wake_lock); -+ STP_PSM_DBG_FUNC("wakeup +wake_lock(%d)#\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ -+ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle++\n"); -+ mt_combo_plt_exit_deep_idle(COMBO_IF_BTIF); -+ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle--\n"); -+ -+ stp_psm->wmt_notify(WAKEUP); -+ _stp_psm_wait_wmt_event_wq(stp_psm); -+ } else { -+ STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n"); -+ ret = STP_PSM_OPERATION_FAIL; -+ } -+ } else if (action == HOST_AWAKE) { -+ _stp_psm_set_state(stp_psm, INACT_ACT); -+ -+ if (stp_psm->wmt_notify) { -+ STP_PSM_DBG_FUNC("host awake +wake_lock(%d)\n", -+ osal_wake_lock_count(&stp_psm->wake_lock)); -+ osal_wake_lock(&stp_psm->wake_lock); -+ STP_PSM_DBG_FUNC("host awake +wake_lock(%d)#\n", -+ osal_wake_lock_count(&stp_psm->wake_lock)); -+ -+ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle++\n"); -+ mt_combo_plt_exit_deep_idle(COMBO_IF_BTIF); -+ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle--\n"); -+ -+ stp_psm->wmt_notify(HOST_AWAKE); -+ _stp_psm_wait_wmt_event_wq(stp_psm); -+ } else { -+ STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n"); -+ ret = STP_PSM_OPERATION_FAIL; -+ } -+ } else if (action == SLEEP) { -+ STP_PSM_INFO_FUNC("In INACT state, dont do SLEEP again\n"); -+ } else { -+ STP_PSM_ERR_FUNC("invalid operation, the case should not happen\n"); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ ret = STP_PSM_OPERATION_FAIL; -+ } -+ -+ break; -+ -+ default: -+ -+ /*invalid */ -+ STP_PSM_ERR_FUNC("invalid state, the case should not happen\n"); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ ret = STP_PSM_OPERATION_FAIL; -+ -+ break; -+ } -+ return ret; -+} -+ -+static inline void _stp_psm_stp_is_idle(/*unsigned long data*/struct timer_list *t) -+{ -+ //MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) data; -+ MTKSTP_PSM_T *stp_psm = from_timer(stp_psm,t,psm_timer.timer); -+ -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { -+ STP_PSM_DBG_FUNC("STP-PSM DISABLE!\n"); -+ return; -+ } -+ -+ if (1 == _stp_psm_notify_wmt_sleep_wq(stp_psm)) -+ STP_PSM_INFO_FUNC("**IDLE is over %d msec, go to sleep!!!**\n", stp_psm->idle_time_to_sleep); -+} -+ -+static inline INT32 _stp_psm_init_monitor(MTKSTP_PSM_T *stp_psm) -+{ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ STP_PSM_INFO_FUNC("init monitor\n"); -+ -+ stp_psm->psm_timer.timeoutHandler = _stp_psm_stp_is_idle; -+ stp_psm->psm_timer.timeroutHandlerData = (unsigned long)stp_psm; -+ osal_timer_create(&stp_psm->psm_timer); -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_deinit_monitor(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ STP_PSM_INFO_FUNC("deinit monitor\n"); -+ -+ osal_timer_stop_sync(&stp_psm->psm_timer); -+ -+ return 0; -+} -+ -+static inline INT32 _stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 iRet = -1; -+ -+/* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ -+ if (osal_test_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag)) -+ iRet = 1; -+ else -+ iRet = 0; -+ -+/* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ return iRet; -+} -+ -+static inline INT32 _stp_psm_is_disable(MTKSTP_PSM_T *stp_psm) -+{ -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) -+ return 1; -+ else -+ return 0; -+} -+ -+static inline INT32 _stp_psm_do_wait(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state) -+{ -+ -+#define POLL_WAIT 20 /* 200 */ -+#define POLL_WAIT_TIME 2000 -+ -+ INT32 i = 0; -+ INT32 limit = POLL_WAIT_TIME / POLL_WAIT; -+ -+ while (_stp_psm_get_state(stp_psm) != state && i < limit) { -+ osal_sleep_ms(POLL_WAIT); -+ i++; -+ STP_PSM_INFO_FUNC("STP is waiting state for %s, i=%d, state = %d\n", g_psm_state[state], i, -+ _stp_psm_get_state(stp_psm)); -+ } -+ -+ if (i == limit) { -+ STP_PSM_WARN_FUNC("-Wait for %s takes %d msec\n", g_psm_state[state], i * POLL_WAIT); -+ _stp_psm_opid_dbg_out_printk(g_stp_psm_opid_dbg); -+ return STP_PSM_OPERATION_FAIL; -+ } -+ STP_PSM_DBG_FUNC("+Total waits for %s takes %d msec\n", g_psm_state[state], i * POLL_WAIT); -+ /* _stp_psm_dbg_out_printk(g_stp_psm_opid_dbg); */ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ INT32 ret = 0; -+ INT32 retry = 10; -+ P_OSAL_OP_Q pOpQ; -+ P_OSAL_OP pOp; -+ -+ STP_PSM_LOUD_FUNC("*** Do Force Wakeup!***\n\r"); -+ -+ /* <1>If timer is active, we will stop it. */ -+ _stp_psm_stop_monitor(stp_psm); -+ -+ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ -+ pOpQ = &stp_psm->rFreeOpQ; -+ -+ while (!RB_EMPTY(&stp_psm->rActiveOpQ)) { -+ RB_GET(&stp_psm->rActiveOpQ, pOp); -+ if (NULL != pOp && !RB_FULL(pOpQ)) { -+ STP_PSM_DBG_FUNC("opid = %d\n", pOp->op.opId); -+ RB_PUT(pOpQ, pOp); -+ } else { -+ STP_PSM_ERR_FUNC("clear up active queue fail, freeQ full\n"); -+ } -+ } -+ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ /* <5>We issue wakeup request into op queue. and wait for active. */ -+ do { -+ ret = _stp_psm_notify_wmt_wakeup_wq(stp_psm); -+ -+ if (ret == STP_PSM_OPERATION_SUCCESS) { -+ ret = _stp_psm_do_wait(stp_psm, ACT); -+ -+ /* STP_PSM_INFO_FUNC("<< wait ret = %d, num of activeQ = %d\n", -+ * ret, RB_COUNT(&stp_psm->rActiveOpQ)); -+ */ -+ if (ret == STP_PSM_OPERATION_SUCCESS) -+ break; -+ } else -+ STP_PSM_ERR_FUNC("_stp_psm_notify_wmt_wakeup_wq fail!!\n"); -+ -+ /* STP_PSM_INFO_FUNC("retry = %d\n", retry); */ -+ retry--; -+ -+ if (retry == 0) -+ break; -+ } while (1); -+ -+ if (retry == 0) -+ return STP_PSM_OPERATION_FAIL; -+ else -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_disable(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 ret = STP_PSM_OPERATION_FAIL; -+ -+ STP_PSM_DBG_FUNC("PSM Disable start\n\r"); -+ -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ ret = _stp_psm_do_wakeup(stp_psm); -+ if (ret == STP_PSM_OPERATION_SUCCESS) -+ STP_PSM_DBG_FUNC("PSM Disable Success\n"); -+ else -+ STP_PSM_ERR_FUNC("***PSM Disable Fail***\n"); -+ -+ return ret; -+} -+ -+static inline INT32 _stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep) -+{ -+ INT32 ret = STP_PSM_OPERATION_FAIL; -+ -+ STP_PSM_LOUD_FUNC("PSM Enable start\n\r"); -+ -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ -+ ret = _stp_psm_do_wakeup(stp_psm); -+ if (ret == STP_PSM_OPERATION_SUCCESS) { -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ stp_psm->idle_time_to_sleep = idle_time_to_sleep; -+ -+ if (osal_wake_lock_count(&stp_psm->wake_lock) == 0) { -+ STP_PSM_DBG_FUNC("psm_en+wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ osal_wake_lock(&stp_psm->wake_lock); -+ STP_PSM_DBG_FUNC("psm_en+wake_lock(%d)#\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ } -+ -+ _stp_psm_start_monitor(stp_psm); -+ -+ STP_PSM_DBG_FUNC("PSM Enable succeed\n\r"); -+ } else -+ STP_PSM_ERR_FUNC("***PSM Enable Fail***\n"); -+ -+ return ret; -+} -+ -+INT32 _stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm) -+{ -+ return osal_lock_sleepable_lock(&stp_psm->stp_psm_lock); -+} -+ -+INT32 _stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm) -+{ -+ osal_unlock_sleepable_lock(&stp_psm->stp_psm_lock); -+ return 0; -+} -+ -+MTK_WCN_BOOL _stp_psm_is_quick_ps_support(VOID) -+{ -+ if (stp_psm->is_wmt_quick_ps_support) -+ return (*(stp_psm->is_wmt_quick_ps_support)) (); -+ -+ STP_PSM_DBG_FUNC("stp_psm->is_wmt_quick_ps_support is NULL, return false\n\r"); -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+MTK_WCN_BOOL stp_psm_is_quick_ps_support(VOID) -+{ -+ return _stp_psm_is_quick_ps_support(); -+} -+ -+#if PSM_USE_COUNT_PACKAGE -+int stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, int dir) -+{ -+ -+ /* easy the variable maintain beween stp tx, rx thread. */ -+ /* so we create variable for tx, rx respectively. */ -+ -+ static int tx_cnt; -+ static int rx_cnt; -+ static int is_tx_first = 1; -+ static int is_rx_first = 1; -+ static unsigned long tx_end_time; -+ static unsigned long rx_end_time; -+ -+ /* */ -+ /* BT A2DP TX CNT = 220, RX CNT = 843 */ -+ /* BT FTP Transferring TX CNT = 574, RX CNT = 2233 (1228~1588) */ -+ /* BT FTP Receiving TX CNT = 204, RX CNT = 3301 (2072~2515) */ -+ /* BT OPP Tx TX_CNT= 330, RX CNT = 1300~1800 */ -+ /* BT OPP Rx TX_CNT= (109~157), RX CNT = 1681~2436 */ -+ if (dir == 0) { /* tx */ -+ -+ tx_cnt++; -+ -+ if (((long)jiffies - (long)tx_end_time >= 0) || (is_tx_first)) { -+ tx_end_time = jiffies + (3 * HZ); -+ STP_PSM_INFO_FUNC("tx cnt = %d in the previous 3 sec\n", tx_cnt); -+ /* if(tx_cnt > 400)//for high traffic , not to do sleep. */ -+ if (tx_cnt > 300) { -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ stp_psm_start_monitor(stp_psm); -+ } else { -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ } -+ tx_cnt = 0; -+ if (is_tx_first) -+ is_tx_first = 0; -+ } -+ } else { -+ rx_cnt++; -+ -+ if (((long)jiffies - (long)rx_end_time >= 0) || (is_rx_first)) { -+ rx_end_time = jiffies + (3 * HZ); -+ STP_PSM_INFO_FUNC("rx cnt = %d in the previous 3 sec\n", rx_cnt); -+ -+ /* if(rx_cnt > 2000)//for high traffic , not to do sleep. */ -+ if (rx_cnt > 1200) { /* for high traffic , not to do sleep. */ -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ stp_psm_start_monitor(stp_psm); -+ } else { -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ } -+ rx_cnt = 0; -+ if (is_rx_first) -+ is_rx_first = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+#else -+static struct timeval tv_now, tv_end; -+static INT32 sample_start; -+static INT32 tx_sum_len; -+static INT32 rx_sum_len; -+ -+INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir, INT32 length) -+{ -+ if (sample_start) { -+ if (dir) -+ rx_sum_len += length; -+ else -+ tx_sum_len += length; -+ -+ do_gettimeofday(&tv_now); -+ /* STP_PSM_INFO_FUNC("tv_now:%d.%d tv_end:%d.%d\n", -+ * tv_now.tv_sec,tv_now.tv_usec,tv_end.tv_sec,tv_end.tv_usec); -+ */ -+ if (((tv_now.tv_sec == tv_end.tv_sec) && (tv_now.tv_usec > tv_end.tv_usec)) || -+ (tv_now.tv_sec > tv_end.tv_sec)) { -+ STP_PSM_INFO_FUNC("STP speed rx:%d tx:%d\n", rx_sum_len, tx_sum_len); -+ if ((rx_sum_len + tx_sum_len) > RTX_SPEED_THRESHOLD) { -+ /* STP_PSM_INFO_FUNC("High speed,Disable monitor\n"); */ -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); -+ stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP_1000; -+ stp_psm_start_monitor(stp_psm); -+ } else { -+ /* STP_PSM_INFO_FUNC("Low speed,Enable monitor\n"); */ -+ stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP; -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); -+ } -+ sample_start = 0; -+ rx_sum_len = 0; -+ tx_sum_len = 0; -+ } -+ } else { -+ sample_start = 1; -+ do_gettimeofday(&tv_now); -+ tv_end = tv_now; -+ tv_end.tv_sec += SAMPLE_DURATION; -+ } -+ -+ return 0; -+} -+#endif -+ -+/*external function for WMT module to do sleep/wakeup*/ -+INT32 stp_psm_set_state(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state) -+{ -+ return _stp_psm_set_state(stp_psm, state); -+} -+ -+INT32 stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_thread_lock_aquire(stp_psm); -+} -+ -+INT32 stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_thread_lock_release(stp_psm); -+} -+ -+INT32 stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_do_wakeup(stp_psm); -+} -+ -+INT32 stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) -+{ -+ -+ return _stp_psm_notify_stp(stp_psm, action); -+} -+ -+INT32 stp_psm_notify_wmt_wakeup(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_notify_wmt_wakeup_wq(stp_psm); -+} -+ -+int stp_psm_notify_wmt_sleep(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ return _stp_psm_notify_wmt_sleep_wq(stp_psm); -+} -+ -+INT32 stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_start_monitor(stp_psm); -+} -+ -+INT32 stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_is_to_block_traffic(stp_psm); -+} -+ -+INT32 stp_psm_is_disable(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_is_disable(stp_psm); -+} -+ -+INT32 stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_has_pending_data(stp_psm); -+} -+ -+INT32 stp_psm_release_data(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_release_data(stp_psm); -+} -+ -+INT32 stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type) -+{ -+ return _stp_psm_hold_data(stp_psm, buffer, len, type); -+} -+ -+INT32 stp_psm_disable(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_disable(stp_psm); -+} -+ -+INT32 stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep) -+{ -+ return _stp_psm_enable(stp_psm, idle_time_to_sleep); -+} -+ -+INT32 stp_psm_reset(MTKSTP_PSM_T *stp_psm) -+{ -+ stp_psm_set_sleep_enable(stp_psm); -+ -+ return _stp_psm_reset(stp_psm); -+} -+ -+INT32 stp_psm_sleep_for_thermal(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_notify_wmt_sleep_wq(stp_psm); -+} -+ -+INT32 stp_psm_set_sleep_enable(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 ret = 0; -+ -+ if (stp_psm) { -+ stp_psm->sleep_en = 1; -+ STP_PSM_DBG_FUNC("\n"); -+ ret = 0; -+ } else { -+ STP_PSM_INFO_FUNC("Null pointer\n"); -+ ret = -1; -+ } -+ -+ return ret; -+} -+ -+INT32 stp_psm_set_sleep_disable(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 ret = 0; -+ -+ if (stp_psm) { -+ stp_psm->sleep_en = 0; -+ STP_PSM_DBG_FUNC("\n"); -+ ret = 0; -+ } else { -+ STP_PSM_INFO_FUNC("Null pointer\n"); -+ ret = -1; -+ } -+ -+ return ret; -+} -+ -+/* stp_psm_check_sleep_enable - to check if sleep cmd is enabled or not -+ * @ stp_psm - pointer of psm -+ * -+ * return 1 if sleep is enabled; else return 0 if disabled; else error code -+ */ -+INT32 stp_psm_check_sleep_enable(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 ret = 0; -+ -+ if (stp_psm) { -+ ret = stp_psm->sleep_en; -+ STP_PSM_DBG_FUNC("%s\n", ret ? "enabled" : "disabled"); -+ } else { -+ STP_PSM_INFO_FUNC("Null pointer\n"); -+ ret = -1; -+ } -+ -+ return ret; -+} -+ -+static INT32 _stp_psm_dbg_dmp_in(STP_PSM_RECORD_T *stp_psm_dbg, UINT32 flag, UINT32 line_num) -+{ -+ INT32 index = 0; -+ struct timeval now; -+ -+ if (stp_psm_dbg) { -+ osal_lock_unsleepable_lock(&stp_psm_dbg->lock); -+ do_gettimeofday(&now); -+ index = stp_psm_dbg->in - 1; -+ index = (index + STP_PSM_DBG_SIZE) % STP_PSM_DBG_SIZE; -+ STP_PSM_DBG_FUNC("index(%d)\n", index); -+ stp_psm_dbg->queue[stp_psm_dbg->in].prev_flag = stp_psm_dbg->queue[index].cur_flag; -+ stp_psm_dbg->queue[stp_psm_dbg->in].cur_flag = flag; -+ stp_psm_dbg->queue[stp_psm_dbg->in].line_num = line_num; -+ stp_psm_dbg->queue[stp_psm_dbg->in].package_no = g_record_num++; -+ stp_psm_dbg->queue[stp_psm_dbg->in].sec = now.tv_sec; -+ stp_psm_dbg->queue[stp_psm_dbg->in].usec = now.tv_usec; -+ stp_psm_dbg->size++; -+ STP_PSM_DBG_FUNC("pre_Flag = %d, cur_flag = %d\n", stp_psm_dbg->queue[stp_psm_dbg->in].prev_flag, -+ stp_psm_dbg->queue[stp_psm_dbg->in].cur_flag); -+ stp_psm_dbg->size = (stp_psm_dbg->size > STP_PSM_DBG_SIZE) ? STP_PSM_DBG_SIZE : stp_psm_dbg->size; -+ stp_psm_dbg->in = (stp_psm_dbg->in >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (stp_psm_dbg->in + 1); -+ STP_PSM_DBG_FUNC("record size = %d, in = %d num = %d\n", stp_psm_dbg->size, stp_psm_dbg->in, line_num); -+ -+ osal_unlock_unsleepable_lock(&stp_psm_dbg->lock); -+ } -+ return 0; -+} -+ -+static INT32 _stp_psm_dbg_out_printk(STP_PSM_RECORD_T *stp_psm_dbg) -+{ -+ -+ UINT32 dumpSize = 0; -+ UINT32 inIndex = 0; -+ UINT32 outIndex = 0; -+ -+ if (!stp_psm_dbg) { -+ STP_PSM_ERR_FUNC("NULL g_stp_psm_dbg reference\n"); -+ return -1; -+ } -+ osal_lock_unsleepable_lock(&stp_psm_dbg->lock); -+ -+ inIndex = stp_psm_dbg->in; -+ dumpSize = stp_psm_dbg->size; -+ if (STP_PSM_DBG_SIZE == dumpSize) -+ outIndex = inIndex; -+ else -+ outIndex = ((inIndex + STP_PSM_DBG_SIZE) - dumpSize) % STP_PSM_DBG_SIZE; -+ -+ STP_PSM_INFO_FUNC("loged record size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); -+ while (dumpSize > 0) { -+ -+ pr_debug("STP-PSM:%d.%ds, n(%d)pre_flag(%d)cur_flag(%d)line_no(%d)\n", -+ stp_psm_dbg->queue[outIndex].sec, -+ stp_psm_dbg->queue[outIndex].usec, -+ stp_psm_dbg->queue[outIndex].package_no, -+ stp_psm_dbg->queue[outIndex].prev_flag, -+ stp_psm_dbg->queue[outIndex].cur_flag, stp_psm_dbg->queue[outIndex].line_num); -+ -+ outIndex = (outIndex >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (outIndex + 1); -+ dumpSize--; -+ -+ } -+ -+ osal_unlock_unsleepable_lock(&stp_psm_dbg->lock); -+ -+ return 0; -+} -+ -+static INT32 _stp_psm_opid_dbg_dmp_in(P_STP_PSM_OPID_RECORD p_opid_dbg, UINT32 opid, UINT32 line_num) -+{ -+ INT32 index = 0; -+ struct timeval now; -+ -+ if (p_opid_dbg) { -+ osal_lock_unsleepable_lock(&p_opid_dbg->lock); -+ do_gettimeofday(&now); -+ index = p_opid_dbg->in - 1; -+ index = (index + STP_PSM_DBG_SIZE) % STP_PSM_DBG_SIZE; -+ STP_PSM_DBG_FUNC("index(%d)\n", index); -+ p_opid_dbg->queue[p_opid_dbg->in].prev_flag = p_opid_dbg->queue[index].cur_flag; -+ p_opid_dbg->queue[p_opid_dbg->in].cur_flag = opid; -+ p_opid_dbg->queue[p_opid_dbg->in].line_num = line_num; -+ p_opid_dbg->queue[p_opid_dbg->in].package_no = g_opid_record_num++; -+ p_opid_dbg->queue[p_opid_dbg->in].sec = now.tv_sec; -+ p_opid_dbg->queue[p_opid_dbg->in].usec = now.tv_usec; -+ p_opid_dbg->queue[p_opid_dbg->in].pid = current->pid; -+ p_opid_dbg->size++; -+ STP_PSM_DBG_FUNC("pre_opid = %d, cur_opid = %d\n", p_opid_dbg->queue[p_opid_dbg->in].prev_flag, -+ p_opid_dbg->queue[p_opid_dbg->in].cur_flag); -+ p_opid_dbg->size = (p_opid_dbg->size > STP_PSM_DBG_SIZE) ? STP_PSM_DBG_SIZE : p_opid_dbg->size; -+ p_opid_dbg->in = (p_opid_dbg->in >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (p_opid_dbg->in + 1); -+ STP_PSM_DBG_FUNC("opid record size = %d, in = %d num = %d\n", p_opid_dbg->size, p_opid_dbg->in, -+ line_num); -+ -+ osal_unlock_unsleepable_lock(&p_opid_dbg->lock); -+ } -+ return 0; -+ -+} -+ -+static INT32 _stp_psm_opid_dbg_out_printk(P_STP_PSM_OPID_RECORD p_opid_dbg) -+{ -+ UINT32 dumpSize = 0; -+ UINT32 inIndex = 0; -+ UINT32 outIndex = 0; -+ -+ if (!p_opid_dbg) { -+ STP_PSM_ERR_FUNC("NULL p_opid_dbg reference\n"); -+ return -1; -+ } -+ osal_lock_unsleepable_lock(&p_opid_dbg->lock); -+ -+ inIndex = p_opid_dbg->in; -+ dumpSize = p_opid_dbg->size; -+ if (STP_PSM_DBG_SIZE == dumpSize) -+ outIndex = inIndex; -+ else -+ outIndex = ((inIndex + STP_PSM_DBG_SIZE) - dumpSize) % STP_PSM_DBG_SIZE; -+ -+ STP_PSM_INFO_FUNC("loged record size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); -+ while (dumpSize > 0) { -+ -+ pr_debug("STP-PSM:%d.%ds, n(%d)pre_flag(%d)cur_flag(%d)line_no(%d) pid(%d)\n", -+ p_opid_dbg->queue[outIndex].sec, -+ p_opid_dbg->queue[outIndex].usec, -+ p_opid_dbg->queue[outIndex].package_no, -+ p_opid_dbg->queue[outIndex].prev_flag, -+ p_opid_dbg->queue[outIndex].cur_flag, -+ p_opid_dbg->queue[outIndex].line_num, p_opid_dbg->queue[outIndex].pid); -+ -+ outIndex = (outIndex >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (outIndex + 1); -+ dumpSize--; -+ -+ } -+ -+ osal_unlock_unsleepable_lock(&p_opid_dbg->lock); -+ -+ return 0; -+ -+} -+ -+MTKSTP_PSM_T *stp_psm_init(void) -+{ -+ INT32 err = 0; -+ INT32 i = 0; -+ INT32 ret = -1; -+ -+ STP_PSM_INFO_FUNC("psm init\n"); -+ -+ stp_psm->work_state = ACT; -+ stp_psm->wmt_notify = wmt_lib_ps_stp_cb; -+ stp_psm->is_wmt_quick_ps_support = wmt_lib_is_quick_ps_support; -+ stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP; -+ stp_psm->flag.data = 0; -+ stp_psm->stp_tx_cb = NULL; -+ stp_psm_set_sleep_enable(stp_psm); -+ -+ ret = osal_fifo_init(&stp_psm->hold_fifo, NULL, STP_PSM_FIFO_SIZE); -+ if (ret < 0) { -+ STP_PSM_ERR_FUNC("FIFO INIT FAILS\n"); -+ goto ERR_EXIT4; -+ } -+ -+ osal_fifo_reset(&stp_psm->hold_fifo); -+ osal_sleepable_lock_init(&stp_psm->hold_fifo_spinlock_global); -+ osal_unsleepable_lock_init(&stp_psm->wq_spinlock); -+ osal_sleepable_lock_init(&stp_psm->stp_psm_lock); -+ -+/* osal_unsleepable_lock_init(&stp_psm->flagSpinlock); */ -+ -+ osal_memcpy(stp_psm->wake_lock.name, "MT662x", 6); -+ osal_wake_lock_init(&stp_psm->wake_lock); -+ -+ osal_event_init(&stp_psm->STPd_event); -+ RB_INIT(&stp_psm->rFreeOpQ, STP_OP_BUF_SIZE); -+ RB_INIT(&stp_psm->rActiveOpQ, STP_OP_BUF_SIZE); -+ /* Put all to free Q */ -+ for (i = 0; i < STP_OP_BUF_SIZE; i++) { -+ osal_signal_init(&(stp_psm->arQue[i].signal)); -+ _stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, &(stp_psm->arQue[i])); -+ } -+ /* stp_psm->current_active_op = NULL; */ -+ stp_psm->last_active_opId = STP_OPID_PSM_INALID; -+ /*Generate BTM thread, to servie STP-CORE and WMT-CORE for sleeping, waking up and host awake */ -+ stp_psm->PSMd.pThreadData = (VOID *) stp_psm; -+ stp_psm->PSMd.pThreadFunc = (VOID *) _stp_psm_proc; -+ osal_memcpy(stp_psm->PSMd.threadName, PSM_THREAD_NAME, osal_strlen(PSM_THREAD_NAME)); -+ -+ ret = osal_thread_create(&stp_psm->PSMd); -+ if (ret < 0) { -+ STP_PSM_ERR_FUNC("osal_thread_create fail...\n"); -+ goto ERR_EXIT5; -+ } -+ /* init_waitqueue_head(&stp_psm->wait_wmt_q); */ -+ stp_psm->wait_wmt_q.timeoutValue = STP_PSM_WAIT_EVENT_TIMEOUT; -+ osal_event_init(&stp_psm->wait_wmt_q); -+ -+ err = _stp_psm_init_monitor(stp_psm); -+ if (err) { -+ STP_PSM_ERR_FUNC("__stp_psm_init ERROR\n"); -+ goto ERR_EXIT6; -+ } -+ /* Start STPd thread */ -+ ret = osal_thread_run(&stp_psm->PSMd); -+ if (ret < 0) { -+ STP_PSM_ERR_FUNC("osal_thread_run FAILS\n"); -+ goto ERR_EXIT6; -+ } -+ /* psm disable in default */ -+ _stp_psm_disable(stp_psm); -+ -+ g_stp_psm_dbg = (STP_PSM_RECORD_T *) osal_malloc(osal_sizeof(STP_PSM_RECORD_T)); -+ if (!g_stp_psm_dbg) { -+ STP_PSM_ERR_FUNC("stp psm dbg allocate memory fail!\n"); -+ return NULL; -+ } -+ osal_memset(g_stp_psm_dbg, 0, osal_sizeof(STP_PSM_RECORD_T)); -+ osal_unsleepable_lock_init(&g_stp_psm_dbg->lock); -+ -+ g_stp_psm_opid_dbg = (STP_PSM_OPID_RECORD *) osal_malloc(osal_sizeof(STP_PSM_OPID_RECORD)); -+ if (!g_stp_psm_opid_dbg) { -+ STP_PSM_ERR_FUNC("stp psm dbg allocate memory fail!\n"); -+ return NULL; -+ } -+ osal_memset(g_stp_psm_opid_dbg, 0, osal_sizeof(STP_PSM_OPID_RECORD)); -+ osal_unsleepable_lock_init(&g_stp_psm_opid_dbg->lock); -+ -+ return stp_psm; -+ -+ERR_EXIT6: -+ -+ ret = osal_thread_destroy(&stp_psm->PSMd); -+ if (ret < 0) { -+ STP_PSM_ERR_FUNC("osal_thread_destroy FAILS\n"); -+ goto ERR_EXIT5; -+ } -+ERR_EXIT5: -+ osal_fifo_deinit(&stp_psm->hold_fifo); -+ERR_EXIT4: -+ -+ return NULL; -+} -+ -+INT32 stp_psm_deinit(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 ret = -1; -+ -+ STP_PSM_INFO_FUNC("psm deinit\n"); -+ -+ if (g_stp_psm_dbg) { -+ osal_unsleepable_lock_deinit(&g_stp_psm_dbg->lock); -+ osal_free(g_stp_psm_dbg); -+ g_stp_psm_dbg = NULL; -+ } -+ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ ret = osal_thread_destroy(&stp_psm->PSMd); -+ if (ret < 0) -+ STP_PSM_ERR_FUNC("osal_thread_destroy FAILS\n"); -+ -+ ret = _stp_psm_deinit_monitor(stp_psm); -+ if (ret < 0) -+ STP_PSM_ERR_FUNC("_stp_psm_deinit_monitor ERROR\n"); -+ -+ osal_wake_lock_deinit(&stp_psm->wake_lock); -+ osal_fifo_deinit(&stp_psm->hold_fifo); -+ osal_sleepable_lock_deinit(&stp_psm->hold_fifo_spinlock_global); -+ osal_unsleepable_lock_deinit(&stp_psm->wq_spinlock); -+ osal_sleepable_lock_deinit(&stp_psm->stp_psm_lock); -+/* osal_unsleepable_lock_deinit(&stp_psm->flagSpinlock); */ -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c -new file mode 100644 -index 0000000000000..a3c24ca144411 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c -@@ -0,0 +1,3358 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#include "osal_typedef.h" -+#include "stp_core.h" -+#include "psm_core.h" -+#include "btm_core.h" -+#include "stp_dbg.h" -+#include "stp_btif.h" -+ -+#define PFX "[STP] " -+#define STP_LOG_DBG 4 -+#define STP_LOG_PKHEAD 3 -+#define STP_LOG_INFO 2 -+#define STP_LOG_WARN 1 -+#define STP_LOG_ERR 0 -+ -+#define STP_DEL_SIZE 2 /* STP delimiter length */ -+ -+UINT32 gStpDbgLvl = STP_LOG_INFO; -+unsigned int g_coredump_mode = 0; -+#define REMOVE_USELESS_LOG 1 -+ -+#define STP_POLL_CPUPCR_NUM 16 -+#define STP_POLL_CPUPCR_DELAY 10 -+#define STP_RETRY_OPTIMIZE 0 -+ -+/* global variables */ -+static const UINT8 stp_delimiter[STP_DEL_SIZE] = { 0x55, 0x55 }; -+ -+static INT32 fgEnableNak; /* 0=enable NAK; 1=disable NAK */ -+static INT32 fgEnableDelimiter; /* 0=disable Delimiter; 1=enable Delimiter */ -+#if STP_RETRY_OPTIMIZE -+static UINT32 g_retry_times; -+#endif -+/* common interface */ -+static IF_TX sys_if_tx; -+/* event/signal */ -+static EVENT_SET sys_event_set; -+static EVENT_TX_RESUME sys_event_tx_resume; -+static FUNCTION_STATUS sys_check_function_status; -+/* kernel lib */ -+/* int g_block_tx = 0; */ -+static mtkstp_context_struct stp_core_ctx = { 0 }; -+ -+#define STP_PSM_CORE(x) ((x).psm) -+#define STP_SET_PSM_CORE(x, v) ((x).psm = (v)) -+ -+#define STP_BTM_CORE(x) ((x).btm) -+#define STP_SET_BTM_CORE(x, v) ((x).btm = (v)) -+ -+#define STP_IS_ENABLE(x) ((x).f_enable != 0) -+#define STP_NOT_ENABLE(x) ((x).f_enable == 0) -+#define STP_SET_ENABLE(x, v) ((x).f_enable = (v)) -+ -+#define STP_IS_READY(x) ((x).f_ready != 0) -+#define STP_NOT_READY(x) ((x).f_ready == 0) -+#define STP_SET_READY(x, v) ((x).f_ready = (v)) -+ -+#define STP_PENDING_TYPE(x) ((x).f_pending_type) -+#define STP_SET_PENDING_TYPE(x, v) ((x).f_pending_type = (v)) -+ -+#define STP_BLUE_ANGEL (0) -+#define STP_BLUE_Z (1) -+#define STP_BT_STK(x) ((x).f_bluez) -+#define STP_BT_STK_IS_BLUEZ(x) ((x).f_bluez == (STP_BLUE_Z)) -+#define STP_SET_BT_STK(x, v) ((x).f_bluez = (v)) -+ -+#define STP_IS_ENABLE_DBG(x) ((x).f_dbg_en != 0) -+#define STP_NOT_ENABLE_DBG(x) ((x).f_dbg_en == 0) -+#define STP_SET_ENABLE_DBG(x, v) ((x).f_dbg_en = (v)) -+ -+#define STP_IS_ENABLE_RST(x) ((x).f_autorst_en != 0) -+#define STP_NOT_ENABLE_RST(x) ((x).f_autorst_en == 0) -+#define STP_SET_ENABLE_RST(x, v) ((x).f_autorst_en = (v)) -+ -+#define STP_SUPPORT_PROTOCOL(x) ((x).f_mode) -+#define STP_SET_SUPPORT_PROTOCOL(x, v) ((x).f_mode = (v)) -+ -+#define STP_FW_COREDUMP_FLAG(x) ((x).f_coredump) -+#define STP_SET_FW_COREDUMP_FLAG(x, v) ((x).f_coredump = (v)) -+#define STP_ENABLE_FW_COREDUMP(x, v) ((x).en_coredump = (v)) -+#define STP_ENABLE_FW_COREDUMP_FLAG(x) ((x).en_coredump) -+ -+#define STP_WMT_LAST_CLOSE(x) ((x).f_wmt_last_close) -+#define STP_SET_WMT_LAST_CLOSE(x, v) ((x).f_wmt_last_close = (v)) -+ -+#define STP_EVT_ERR_ASSERT(x) ((x).f_evt_err_assert) -+#define STP_SET_EVT_ERR_ASSERT(x, v) ((x).f_evt_err_assert = (v)) -+ -+/*[PatchNeed]Need to calculate the timeout value*/ -+static UINT32 mtkstp_tx_timeout = MTKSTP_TX_TIMEOUT; -+static mtkstp_parser_state prev_state = -1; -+ -+#define CONFIG_DEBUG_STP_TRAFFIC_SUPPORT -+#ifdef CONFIG_DEBUG_STP_TRAFFIC_SUPPORT -+static MTKSTP_DBG_T *g_mtkstp_dbg; -+#endif -+static VOID stp_dbg_pkt_log(INT32 type, INT32 txAck, INT32 seq, INT32 crc, INT32 dir, const UINT8 *pBuf, INT32 len); -+static MTK_WCN_BOOL stp_check_crc(UINT8 *buffer, UINT32 length, UINT16 crc); -+static VOID stp_update_tx_queue(UINT32 txseq); -+static VOID stp_rest_ctx_state(VOID); -+static VOID stp_change_rx_state(mtkstp_parser_state next); -+static void stp_tx_timeout_handler(/*unsigned long data*/ struct timer_list *t); -+static VOID stp_dump_data(const UINT8 *buf, const UINT8 *title, const UINT32 len); -+static VOID stp_dump_tx_queue(UINT32 txseq); -+static INT32 stp_is_apply_powersaving(VOID); -+/*static INT32 stp_is_privileges_cmd(const UINT8 *buffer, const UINT32 length, const UINT8 type);*/ -+static MTK_WCN_BOOL stp_is_tx_res_available(UINT32 length); -+static VOID stp_add_to_tx_queue(const UINT8 *buffer, UINT32 length); -+static INT32 stp_add_to_rx_queue(UINT8 *buffer, UINT32 length, UINT8 type); -+static VOID stp_send_tx_queue(UINT32 txseq); -+static VOID stp_send_ack(UINT8 txAck, UINT8 nak); -+static INT32 stp_process_rxack(VOID); -+static VOID stp_process_packet(VOID); -+ -+/*private functions*/ -+ -+static INT32 stp_ctx_lock_init(mtkstp_context_struct *pctx) -+{ -+#if CFG_STP_CORE_CTX_SPIN_LOCK -+ return osal_unsleepable_lock_init(&((pctx)->stp_mutex)); -+#else -+ osal_sleepable_lock_init(&((pctx)->stp_mutex)); -+ return 0; -+#endif -+} -+ -+static INT32 stp_ctx_lock_deinit(mtkstp_context_struct *pctx) -+{ -+#if CFG_STP_CORE_CTX_SPIN_LOCK -+ return osal_unsleepable_lock_deinit(&((pctx)->stp_mutex)); -+#else -+ return osal_sleepable_lock_deinit(&((pctx)->stp_mutex)); -+#endif -+} -+ -+static INT32 stp_ctx_lock(mtkstp_context_struct *pctx) -+{ -+#if CFG_STP_CORE_CTX_SPIN_LOCK -+ return osal_lock_unsleepable_lock(&((pctx)->stp_mutex)); -+#else -+ return osal_lock_sleepable_lock(&((pctx)->stp_mutex)); -+#endif -+} -+ -+static INT32 stp_ctx_unlock(mtkstp_context_struct *pctx) -+{ -+#if CFG_STP_CORE_CTX_SPIN_LOCK -+ return osal_unlock_unsleepable_lock(&((pctx)->stp_mutex)); -+#else -+ return osal_unlock_sleepable_lock(&((pctx)->stp_mutex)); -+#endif -+} -+ -+MTK_WCN_BOOL mtk_wcn_stp_dbg_level(UINT32 dbglevel) -+{ -+ if (dbglevel <= 4) { -+ gStpDbgLvl = dbglevel; -+ STP_INFO_FUNC("gStpDbgLvl = %d\n", gStpDbgLvl); -+ return MTK_WCN_BOOL_TRUE; -+ } -+ STP_INFO_FUNC("invalid stp debug level. gStpDbgLvl = %d\n", gStpDbgLvl); -+ -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+#if !(REMOVE_USELESS_LOG) -+static UINT8 *stp_type_to_dbg_string(UINT32 type) -+{ -+ UINT8 *type_name = NULL; -+ -+ if (type == BT_TASK_INDX) -+ type_name = "< BT>"; -+ else if (type == GPS_TASK_INDX) -+ type_name = ""; -+ else if (type == WMT_TASK_INDX) -+ type_name = ""; -+ else if (type == FM_TASK_INDX) -+ type_name = "< FM>"; -+ else if (type == ANT_TASK_INDX) -+ type_name = ""; -+ -+ return type_name; -+} -+#endif -+#if 0 -+/***************************************************************************** -+* FUNCTION -+* crc16 -+* DESCRIPTION -+* Compute the CRC-16 for the data buffer -+* PARAMETERS -+* crc [IN] previous CRC value -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* the updated CRC value -+*****************************************************************************/ -+static UINT16 crc16(const UINT8 *buffer, const UINT32 length) -+{ -+ UINT32 crc, i; -+ -+ /* FIXME: Add STP checksum feature */ -+ crc = 0; -+ for (i = 0; i < length; i++, buffer++) -+ crc = (crc >> 8) ^ crc16_table[(crc ^ (*buffer)) & 0xff]; -+ -+ return crc; -+} -+ -+#endif -+ -+VOID stp_dbg_pkt_log(INT32 type, INT32 txAck, INT32 seq, INT32 crc, INT32 dir, const UINT8 *pBuf, INT32 len) -+{ -+ -+#ifndef CONFIG_LOG_STP_INTERNAL -+ return; -+#endif -+ -+ if (STP_IS_ENABLE_DBG(stp_core_ctx)) { -+ stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_PKT, type, /* type */ -+ txAck, /* ack */ -+ seq, /* seq */ -+ crc, /* crc */ -+ dir, /* dir */ -+ len, /* len */ -+ pBuf); /* body */ -+ } else { -+ STP_DBG_FUNC("stp_dbg not enabled"); -+ } -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_check_crc -+* DESCRIPTION -+* check the check sum of packet payload -+* PARAMETERS -+* pdata [IN] the data want to check -+* length [IN] the length of pdata -+* crc [IN] the crc of pdata -+* RETURNS -+* KAL_TRUE crc is ok -+* KAL_FALSE crc is wrong -+*****************************************************************************/ -+static MTK_WCN_BOOL stp_check_crc(UINT8 *buffer, UINT32 length, UINT16 crc) -+{ -+ /*----------------------------------------------------------------*/ -+ /* Local Variables */ -+ /*----------------------------------------------------------------*/ -+ UINT16 checksum; -+ -+ /*----------------------------------------------------------------*/ -+ /* Code Body */ -+ /*----------------------------------------------------------------*/ -+ -+ /* FIXME: Add STP feature: check or skip crc */ -+ -+ checksum = osal_crc16(buffer, length); -+ if (checksum == crc) -+ return MTK_WCN_BOOL_TRUE; -+ -+ STP_ERR_FUNC("CRC fail, length = %d, rx = %x, calc = %x \r\n", length, crc, checksum); -+ return MTK_WCN_BOOL_FALSE; -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_update_tx_queue -+* DESCRIPTION -+* update packet's ACK field -+* PARAMETERS -+* txseq [IN] index of the tx packet which we want to update -+* RETURNS -+* void -+*****************************************************************************/ -+static void stp_update_tx_queue(UINT32 txseq) -+{ -+ INT32 tx_read, i; -+ UINT8 checksum = 0; -+ -+ tx_read = stp_core_ctx.tx_start_addr[txseq]; -+ stp_core_ctx.tx_buf[tx_read] &= 0xf8; -+ stp_core_ctx.tx_buf[tx_read] |= stp_core_ctx.sequence.txack; -+ -+ for (i = 0; i < 3; i++) { -+ checksum += stp_core_ctx.tx_buf[tx_read]; -+ tx_read++; -+ if (tx_read >= MTKSTP_BUFFER_SIZE) -+ tx_read -= MTKSTP_BUFFER_SIZE; -+ -+ } -+ -+ stp_core_ctx.tx_buf[tx_read] = checksum; -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_rest_ctx_state -+* DESCRIPTION -+* Reset stp context state variables only. Mutex and timer resources are not touched. -+* -+* PARAMETERS -+* void -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_rest_ctx_state(VOID) -+{ -+ INT32 i; -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ stp_core_ctx.rx_counter = 0; -+ -+ /*reset rx buffer pointer */ -+ for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) { -+ stp_core_ctx.ring[i].read_p = 0; -+ stp_core_ctx.ring[i].write_p = 0; -+ } -+ -+ /*reset tx buffer pointer */ -+ stp_core_ctx.tx_write = 0; -+ stp_core_ctx.tx_read = 0; -+ -+ /*reset STP protocol context */ -+ stp_core_ctx.parser.state = MTKSTP_SYNC; -+ stp_core_ctx.sequence.txseq = 0; -+ stp_core_ctx.sequence.txack = 7; -+ stp_core_ctx.sequence.rxack = 7; -+ stp_core_ctx.sequence.winspace = MTKSTP_WINSIZE; -+ stp_core_ctx.sequence.expected_rxseq = 0; -+ stp_core_ctx.sequence.retry_times = 0; -+ stp_core_ctx.inband_rst_set = 0; -+ -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_change_rx_state -+* DESCRIPTION -+* change the rx fsm of STP to "next" -+* PARAMETERS -+* next [IN] the next state of rx fsm -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_change_rx_state(mtkstp_parser_state next) -+{ -+ prev_state = stp_core_ctx.parser.state; -+ stp_core_ctx.parser.state = next; -+ -+} -+ -+/* static void stp_tx_timeout_handler(void){ */ -+static void stp_tx_timeout_handler(/*unsigned long data*/struct timer_list *t) -+{ -+ STP_WARN_FUNC("call retry btm retry wq ...\n"); -+ /*shorten the softirq lattency */ -+ stp_btm_notify_stp_retry_wq(STP_BTM_CORE(stp_core_ctx)); -+ STP_WARN_FUNC("call retry btm retry wq ...#\n"); -+} -+ -+VOID stp_do_tx_timeout(VOID) -+{ -+ UINT32 seq; -+ UINT32 ret; -+ INT32 iRet; -+ ENUM_STP_FW_ISSUE_TYPE issue_type; -+ UINT8 resync[4]; -+ -+ STP_WARN_FUNC("==============================================================================\n"); -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ -+#if STP_RETRY_OPTIMIZE -+ if ((g_retry_times != 0) && (stp_core_ctx.sequence.retry_times == 0)) { -+ STP_INFO_FUNC("STP TX timeout has been recoveryed by resend,record_retry_time(%d)\n", g_retry_times); -+ g_retry_times = 0; -+ stp_ctx_unlock(&stp_core_ctx); -+ return; -+ } -+#endif -+ if (stp_core_ctx.sequence.retry_times > (MTKSTP_RETRY_LIMIT)) { -+ STP_INFO_FUNC("STP retry times(%d) have reached retry limit,stop it\n", -+ stp_core_ctx.sequence.retry_times); -+ stp_ctx_unlock(&stp_core_ctx); -+ return; -+ } -+#if STP_RETRY_OPTIMIZE -+ else -+ STP_DBG_FUNC("current TX timeout package has not received ACK yet,retry_times(%d)\n", -+ g_retry_times); -+#endif -+ /*polling cpupcr when no ack occurs at first retry */ -+ stp_notify_btm_poll_cpupcr(STP_BTM_CORE(stp_core_ctx), STP_POLL_CPUPCR_NUM, STP_POLL_CPUPCR_DELAY); -+ -+ seq = stp_core_ctx.sequence.rxack; -+ INDEX_INC(seq); -+ -+ if (seq != stp_core_ctx.sequence.txseq) { -+ osal_memset(&resync[0], 127, 4); -+ (*sys_if_tx) (&resync[0], 4, &ret); -+ if (ret != 4) { -+ STP_ERR_FUNC("mtkstp_tx_timeout_handler: send resync fail\n"); -+ osal_assert(0); -+ } -+ -+ do { -+ STP_WARN_FUNC("[stp.ctx]*rxack (=last rx ack) = %d\n\r", stp_core_ctx.sequence.rxack); -+ STP_WARN_FUNC("[stp.ctx]txack (=last rx seq)= %d\n\r", stp_core_ctx.sequence.txack); -+ STP_WARN_FUNC("[stp.ctx]*txseq (=next tx seq)= %d\n\r", stp_core_ctx.sequence.txseq); -+ STP_WARN_FUNC("Resend STP packet from %d -> %d\n\r", seq, -+ (stp_core_ctx.sequence.txseq <= 0) ? (7) : (stp_core_ctx.sequence.txseq - 1)); -+ stp_dump_tx_queue(seq); -+ -+ stp_send_tx_queue(seq); -+ INDEX_INC(seq); -+ } while (seq != stp_core_ctx.sequence.txseq); -+ -+ } -+ -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); -+ -+ if (stp_core_ctx.sequence.winspace == MTKSTP_WINSIZE) { -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ STP_ERR_FUNC("mtkstp_tx_timeout_handler: wmt_stop_timer\n"); -+ } else { -+ stp_core_ctx.sequence.retry_times++; -+ STP_ERR_FUNC("mtkstp_tx_timeout_handler, retry = %d\n", stp_core_ctx.sequence.retry_times); -+#if STP_RETRY_OPTIMIZE -+ g_retry_times = stp_core_ctx.sequence.retry_times; -+#endif -+ /*If retry too much, try to recover STP by return back to initializatin state */ -+ /*And not to retry again */ -+ if (stp_core_ctx.sequence.retry_times > MTKSTP_RETRY_LIMIT) { -+#if STP_RETRY_OPTIMIZE -+ g_retry_times = 0; -+#endif -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ stp_ctx_unlock(&stp_core_ctx); -+ -+ STP_ERR_FUNC("mtkstp_tx_timeout_handler: wmt_stop_timer\n"); -+ -+ STP_ERR_FUNC("TX retry limit = %d\n", MTKSTP_RETRY_LIMIT); -+ osal_assert(0); -+ mtk_wcn_stp_dbg_dump_package(); -+ -+ /*Whole Chip Reset Procedure Invoke */ -+ /*if(STP_NOT_ENABLE_DBG(stp_core_ctx)) */ -+ -+ if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) { -+ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(1); -+ stp_dbg_set_host_assert_info(4, 36, 1); -+ STP_INFO_FUNC("**STP NoAck trigger firmware assert**\n"); -+ iRet = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx)); -+ -+ if (iRet) { -+ STP_ERR_FUNC("host tigger fw assert fail(%d), do noack handle flow\n", iRet); -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); -+ issue_type = STP_FW_NOACK_ISSUE; -+ iRet = stp_dbg_set_fw_info("STP NoAck", osal_strlen("STP NoAck"), issue_type); -+ -+ osal_dbg_assert_aee("[SOC_CONNSYS]NoAck", -+ "**[WCN_ISSUE_INFO]STP Tx Timeout**\n F/W has NO any RESPONSE. Please check F/W status first\n"); -+ if (STP_IS_ENABLE_RST(stp_core_ctx)) { -+ STP_SET_READY(stp_core_ctx, 0); -+ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); -+ } else { -+ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); -+ } -+ } -+ } else { -+ STP_INFO_FUNC("do trigger assert & chip reset in wmt\n"); -+ } -+ return; -+ } -+ } -+ -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+ STP_WARN_FUNC("==============================================================================#\n"); -+} -+ -+static VOID stp_dump_data(const UINT8 *buf, const UINT8 *title, const UINT32 len) -+{ -+ osal_buffer_dump(buf, title, len, 32); -+} -+ -+/***************************************************************************** -+ * FUNCTION -+ * stp_tx_timeout_handler -+ * DESCRIPTION -+ * tx timeout handler, send resync & retransmitt -+ * PARAMETERS -+ * void -+ * RETURNS -+ * void -+ *****************************************************************************/ -+static VOID stp_dump_tx_queue(UINT32 txseq) -+{ -+ INT32 tx_read, tx_length, last_len; -+ -+ tx_read = stp_core_ctx.tx_start_addr[txseq]; -+ tx_length = stp_core_ctx.tx_length[txseq]; -+ -+ STP_ERR_FUNC("tx_seq=%d ..", txseq); -+ -+ if (tx_read + tx_length < MTKSTP_BUFFER_SIZE) { -+ stp_dump_data(&stp_core_ctx.tx_buf[tx_read], "tx_q", (tx_length >= 8) ? (8) : (tx_length)); -+ } else { -+ last_len = MTKSTP_BUFFER_SIZE - tx_read; -+ stp_dump_data(&stp_core_ctx.tx_buf[tx_read], "tx_q_0", (last_len >= 8) ? (8) : (last_len)); -+ stp_dump_data(&stp_core_ctx.tx_buf[0], "tx_q_0", -+ ((tx_length - last_len) ? (8) : (tx_length - last_len))); -+ } -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_is_apply_powersaving -+* DESCRIPTION -+* Check if STP support power saving mode. -+* PARAMETERS -+* -+* RETURNS -+* True: support power saving False: not support power saving -+*****************************************************************************/ -+static INT32 stp_is_apply_powersaving(VOID) -+{ -+ -+ if (STP_IS_READY(stp_core_ctx) && !stp_psm_is_disable(STP_PSM_CORE(stp_core_ctx))) { -+ /* osal_dbg_print("apply power saving\n"); */ -+ return MTK_WCN_BOOL_TRUE; -+ } -+ if (mtk_wcn_stp_is_sdio_mode()) -+ return MTK_WCN_BOOL_FALSE; -+ -+ STP_DBG_FUNC("not apply power saving\n"); -+ return MTK_WCN_BOOL_FALSE; -+} -+#if 0 -+/***************************************************************************** -+* FUNCTION -+* stp_is_privileges_cmd -+* DESCRIPTION -+* Check if the data is privilege command -+* PARAMETERS -+* -+* RETURNS -+* True/False -+*****************************************************************************/ -+static INT32 stp_is_privileges_cmd(const UINT8 *buffer, const UINT32 length, const UINT8 type) -+{ -+ typedef struct privileges_cmd { -+ UINT32 length; -+ UINT8 type; -+ UINT8 buf[7]; /* MAX length of target command is only 5 currently */ -+ } p_cmd_t; -+ -+ p_cmd_t p_cmd_table[] = { -+ {0x05, WMT_TASK_INDX, {0x01, 0x03, 0x01, 0x00, 0x01} }, /* sleep command */ -+ {0x05, WMT_TASK_INDX, {0x01, 0x03, 0x01, 0x00, 0x02} }, /* host_awake command */ -+ }; -+ -+ UINT32 i; -+ UINT32 size = sizeof(p_cmd_table) / sizeof(p_cmd_table[0]); -+ -+ for (i = 0; i < size; i++) { -+ if (type != p_cmd_table[i].type) -+ continue; -+ -+ if (length != p_cmd_table[i].length) -+ continue; -+ -+ if (osal_memcmp(p_cmd_table[i].buf, buffer, length)) -+ continue; -+ -+ /* matched entry is found */ -+ STP_DBG_FUNC("It's p_cmd_t\n"); -+ return MTK_WCN_BOOL_TRUE; -+ } -+ -+ return MTK_WCN_BOOL_FALSE; -+} -+#endif -+/***************************************************************************** -+* FUNCTION -+* tx_queue_room_available -+* DESCRIPTION -+* check room if available, -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* void -+*****************************************************************************/ -+static MTK_WCN_BOOL stp_is_tx_res_available(UINT32 length) -+{ -+ UINT32 roomLeft; -+ -+ /* -+ Get available space of TX Queue -+ */ -+ if (stp_core_ctx.tx_read <= stp_core_ctx.tx_write) -+ roomLeft = MTKSTP_BUFFER_SIZE - stp_core_ctx.tx_write + stp_core_ctx.tx_read - 1; -+ else -+ roomLeft = stp_core_ctx.tx_read - stp_core_ctx.tx_write - 1; -+ -+ if (roomLeft < length) { -+ STP_ERR_FUNC("%s: tx queue room shortage\n", __func__); -+ return MTK_WCN_BOOL_FALSE; -+ } else -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_add_to_tx_queue -+* DESCRIPTION -+* put data to tx queue -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_add_to_tx_queue(const UINT8 *buffer, UINT32 length) -+{ -+ UINT32 last_len; -+ -+ /* Get available space of TX Queue */ -+ if (length + stp_core_ctx.tx_write < MTKSTP_BUFFER_SIZE) { -+ osal_memcpy(stp_core_ctx.tx_buf + stp_core_ctx.tx_write, buffer, length); -+ stp_core_ctx.tx_write += length; -+ } else { -+ last_len = MTKSTP_BUFFER_SIZE - stp_core_ctx.tx_write; -+ osal_memcpy(stp_core_ctx.tx_buf + stp_core_ctx.tx_write, buffer, last_len); -+ osal_memcpy(stp_core_ctx.tx_buf, buffer + last_len, length - last_len); -+ -+ stp_core_ctx.tx_write = length - last_len; -+ } -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_add_to_rx_queue -+* DESCRIPTION -+* put data to corresponding task's rx queue and notify corresponding task -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] corresponding task index -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+static INT32 stp_add_to_rx_queue(UINT8 *buffer, UINT32 length, UINT8 type) -+{ -+ UINT32 roomLeft, last_len; -+ -+ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ if (stp_core_ctx.ring[type].read_p <= stp_core_ctx.ring[type].write_p) -+ roomLeft = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].write_p + stp_core_ctx.ring[type].read_p - 1; -+ else -+ roomLeft = stp_core_ctx.ring[type].read_p - stp_core_ctx.ring[type].write_p - 1; -+ -+ if (roomLeft < length) { -+ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ STP_ERR_FUNC("Queue is full !!!, type = %d\n", type); -+ osal_assert(0); -+ return -1; -+ } -+ -+ if (length + stp_core_ctx.ring[type].write_p < MTKSTP_BUFFER_SIZE) { -+ osal_memcpy(stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].write_p, buffer, length); -+ stp_core_ctx.ring[type].write_p += length; -+ } else { -+ last_len = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].write_p; -+ osal_memcpy(stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].write_p, buffer, last_len); -+ osal_memcpy(stp_core_ctx.ring[type].buffer, buffer + last_len, length - last_len); -+ stp_core_ctx.ring[type].write_p = length - last_len; -+ } -+ -+ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_tx_queue -+* DESCRIPTION -+* send data in tx buffer to common interface -+* PARAMETERS -+* txseq [IN] sequence number of outgoing packet in tx buffer -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_send_tx_queue(UINT32 txseq) -+{ -+ UINT32 ret; -+ INT32 tx_read, tx_length, last_len; -+ -+ tx_read = stp_core_ctx.tx_start_addr[txseq]; -+ tx_length = stp_core_ctx.tx_length[txseq]; -+ -+ stp_update_tx_queue(txseq); -+ -+ if (tx_read + tx_length < MTKSTP_BUFFER_SIZE) { -+ -+ (*sys_if_tx) (&stp_core_ctx.tx_buf[tx_read], tx_length, &ret); -+ -+ if (ret != tx_length) { -+ STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", tx_length, ret); -+ osal_assert(0); -+ } -+ } else { -+ last_len = MTKSTP_BUFFER_SIZE - tx_read; -+ (*sys_if_tx) (&stp_core_ctx.tx_buf[tx_read], last_len, &ret); -+ -+ if (ret != last_len) { -+ STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", last_len, ret); -+ osal_assert(0); -+ } -+ -+ (*sys_if_tx) (&stp_core_ctx.tx_buf[0], tx_length - last_len, &ret); -+ -+ if (ret != tx_length - last_len) { -+ STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", tx_length - last_len, ret); -+ osal_assert(0); -+ } -+ } -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_ack -+* DESCRIPTION -+* send ack packet to the peer -+* PARAMETERS -+* txAck [IN] Ack number -+* nak [IN] 0 = ack; !0 = NAK -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_send_ack(UINT8 txAck, UINT8 nak) -+{ -+ UINT8 mtkstp_header[MTKSTP_HEADER_SIZE]; -+ UINT32 ret; -+ INT32 iStatus; -+ -+ mtkstp_header[0] = 0x80 + (0 << 3) + txAck; /* stp_core_ctx.sequence.txack; */ -+ -+ if (fgEnableNak == 0) -+ mtkstp_header[1] = 0x00; /* disable NAK */ -+ else -+ mtkstp_header[1] = ((nak == 0) ? 0x00 : 0x80); -+ -+ mtkstp_header[2] = 0; -+ mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; -+ -+ stp_dbg_pkt_log(STP_TASK_INDX, txAck, 0, 0, PKT_DIR_TX, NULL, 0); -+ -+ if (fgEnableDelimiter == 1) { -+ iStatus = (*sys_if_tx) ((PUINT8) &stp_delimiter[0], STP_DEL_SIZE, &ret); -+ STP_DUMP_PACKET_HEAD((PUINT8) &stp_delimiter[0], "tx del", STP_DEL_SIZE); -+ if (ret != STP_DEL_SIZE) { -+ STP_ERR_FUNC("stp_send_ack, %d/%d status %d\n", STP_DEL_SIZE, ret, iStatus); -+ osal_assert(0); -+ } -+ } -+ -+ iStatus = (*sys_if_tx) (&mtkstp_header[0], MTKSTP_HEADER_SIZE, &ret); -+ -+ if (ret != MTKSTP_HEADER_SIZE) { -+ STP_ERR_FUNC("stp_send_ack, %d/%d status %d\n", MTKSTP_HEADER_SIZE, ret, iStatus); -+ osal_assert(0); -+ } -+ -+} -+ -+INT32 stp_send_data_no_ps(UINT8 *buffer, UINT32 length, UINT8 type) -+{ -+ UINT8 mtkstp_header[MTKSTP_HEADER_SIZE], temp[2]; -+ UINT8 *p_tx_buf = NULL; -+ UINT16 crc; -+ INT32 ret = 0; -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ -+ /*Only WMT can set raw data */ -+ if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX != type) { -+ /* no op */ -+ /* NULL; */ -+ } else if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == type) { -+ /* ret = mtk_wcn_stp_send_data_raw(buffer, length, type); */ -+ /* NULL; */ -+ } -+ /* STP over SDIO */ -+ else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { -+ osal_printtimeofday("[ STP][SDIO][ B][W]"); -+ -+ mtkstp_header[0] = 0x80; -+ mtkstp_header[1] = (type << 4) + (((length) >> 8) & 0x0f); -+ mtkstp_header[2] = (length) & 0xff; -+ mtkstp_header[3] = 0x00; -+ -+ p_tx_buf = &stp_core_ctx.tx_buf[0]; -+ osal_memcpy(p_tx_buf, mtkstp_header, MTKSTP_HEADER_SIZE); -+ p_tx_buf += MTKSTP_HEADER_SIZE; -+ -+ osal_memcpy(p_tx_buf, buffer, length); -+ p_tx_buf += length; -+ -+ temp[0] = 0x00; -+ temp[1] = 0x00; -+ osal_memcpy(p_tx_buf, temp, 2); -+ stp_dbg_pkt_log(type, -+ stp_core_ctx.sequence.txack, -+ stp_core_ctx.sequence.txseq, 0, PKT_DIR_TX, buffer, length); -+ (*sys_if_tx) (&stp_core_ctx.tx_buf[0], (MTKSTP_HEADER_SIZE + length + 2), &ret); -+ if ((MTKSTP_HEADER_SIZE + length + 2) != ret) { -+ STP_ERR_FUNC("stp send tx packet: %d, maybe stp_if_tx == NULL\n", ret); -+ osal_assert(0); -+ ret = 0; -+ } else { -+ ret = (INT32) length; -+ } -+ -+ osal_printtimeofday("[ STP][SDIO][ E][W]"); -+ } -+ /* STP over BTIF OR UART */ -+ else if ((mtk_wcn_stp_is_btif_fullset_mode()) && STP_IS_ENABLE(stp_core_ctx)) { -+ -+ if ((stp_core_ctx.sequence.winspace > 0) && -+ (stp_is_tx_res_available(MTKSTP_HEADER_SIZE + length + MTKSTP_CRC_SIZE))) { -+ mtkstp_header[0] = 0x80 + (stp_core_ctx.sequence.txseq << 3) + stp_core_ctx.sequence.txack; -+ mtkstp_header[1] = (type << 4) + ((length & 0xf00) >> 8); -+ mtkstp_header[2] = length & 0xff; -+ mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; -+ -+ stp_core_ctx.tx_start_addr[stp_core_ctx.sequence.txseq] = stp_core_ctx.tx_write; -+ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] = MTKSTP_HEADER_SIZE + length + 2; -+ -+ if (fgEnableDelimiter == 1) { -+ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] += STP_DEL_SIZE; -+ stp_add_to_tx_queue(&stp_delimiter[0], STP_DEL_SIZE); -+ } -+ -+ stp_add_to_tx_queue(mtkstp_header, MTKSTP_HEADER_SIZE); -+ -+ /*Make Payload */ -+ stp_add_to_tx_queue(buffer, length); -+ -+ /*Make CRC */ -+ crc = osal_crc16(buffer, length); -+ temp[0] = crc & 0xff; -+ temp[1] = (crc & 0xff00) >> 8; -+ stp_add_to_tx_queue(temp, 2); -+ -+ stp_dbg_pkt_log(type, -+ stp_core_ctx.sequence.txack, -+ stp_core_ctx.sequence.txseq, crc, PKT_DIR_TX, buffer, length); -+ -+ /*Kick to UART */ -+ stp_send_tx_queue(stp_core_ctx.sequence.txseq); -+ INDEX_INC(stp_core_ctx.sequence.txseq); -+ stp_core_ctx.sequence.winspace--; -+ -+ /*Setup the Retry Timer */ -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) -+ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); -+ else -+ STP_ERR_FUNC("mtk_wcn_stp_send_data: wmt_stop_timer\n"); -+ -+ ret = (INT32) length; -+ } else { -+ /* No winspace to send. Let caller retry */ -+ STP_ERR_FUNC("%s: There is no winspace/txqueue to send !!!\n", __func__); -+ ret = 0; -+ } -+ } -+ -+ stp_ctx_unlock(&stp_core_ctx); -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ -+ return ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_process_rxack -+* DESCRIPTION -+* process ack packet -+* PARAMETERS -+* void -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+static INT32 stp_process_rxack(VOID) -+{ -+ INT32 j, k; -+ UINT8 rxack; -+ INT32 fgResult = (-1); -+ -+ if (stp_core_ctx.sequence.rxack != stp_core_ctx.parser.ack) { -+ j = k = 0; -+ rxack = stp_core_ctx.sequence.rxack; -+ INDEX_INC(rxack); -+ while (rxack != stp_core_ctx.sequence.txseq) { -+ j++; -+ if (rxack == stp_core_ctx.parser.ack) { -+ k = 1; -+ break; -+ } -+ INDEX_INC(rxack); -+ } -+ if (k == 1) { -+ stp_core_ctx.sequence.rxack = stp_core_ctx.parser.ack; -+ stp_core_ctx.tx_read = stp_core_ctx.tx_start_addr[rxack] + stp_core_ctx.tx_length[rxack]; -+ if (stp_core_ctx.tx_read >= MTKSTP_BUFFER_SIZE) -+ stp_core_ctx.tx_read -= MTKSTP_BUFFER_SIZE; -+ -+ stp_core_ctx.sequence.winspace += j; -+ stp_core_ctx.sequence.retry_times = 0; -+ -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) -+ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); -+ -+ fgResult = 0; -+ } -+ } -+ -+ return fgResult; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_process_packet -+* DESCRIPTION -+* process STP packet -+* PARAMETERS -+* void -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_process_packet(VOID) -+{ -+ INT32 fgTriggerResume = (-1); -+ UINT8 txAck = 0; -+ static INT32 fgRxOk; -+ MTK_WCN_BOOL b; -+ MTK_WCN_BOOL is_function_active = 0; -+ static INT32 stp_process_packet_fail_count; -+ INT32 iRet = -1; -+ -+ stp_dbg_pkt_log(stp_core_ctx.parser.type, -+ stp_core_ctx.parser.ack, -+ stp_core_ctx.parser.seq, -+ stp_core_ctx.parser.crc, PKT_DIR_RX, stp_core_ctx.rx_buf, stp_core_ctx.parser.length); -+ /*Optimization */ -+ /*If bluez, direct send packet to hci_core not through RX buffer! */ -+ if ((stp_core_ctx.sequence.expected_rxseq == stp_core_ctx.parser.seq) && -+ (stp_core_ctx.parser.type == BT_TASK_INDX) && STP_BT_STK_IS_BLUEZ(stp_core_ctx)) { -+ /*Indicate packet to hci_stp */ -+ STP_DBG_FUNC("Send Packet to BT_SUBFUCTION, len = %d\n", stp_core_ctx.rx_counter); -+ -+ b = mtk_wcn_sys_if_rx(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); -+ if (b) -+ STP_ERR_FUNC("mtk_wcn_sys_if_rx is NULL\n"); -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ /*Process rx ack */ -+ fgTriggerResume = stp_process_rxack(); -+ stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; -+ INDEX_INC(stp_core_ctx.sequence.expected_rxseq); -+ txAck = stp_core_ctx.sequence.txack; -+ -+ /*Send ack back */ -+ stp_send_ack(txAck, 0); -+ -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+ fgRxOk = 0; -+ } -+ /* sequence matches expected, enqueue packet */ -+ else if (stp_core_ctx.sequence.expected_rxseq == stp_core_ctx.parser.seq) { -+ is_function_active = -+ ((*sys_check_function_status) (stp_core_ctx.parser.type, OP_FUNCTION_ACTIVE) == -+ STATUS_FUNCTION_ACTIVE); -+ /*If type is valid and function works, then try to enqueue */ -+ if ((stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) && (is_function_active == MTK_WCN_BOOL_TRUE)) { -+ if (stp_core_ctx.parser.type == BT_TASK_INDX) { -+ static const UINT8 rst_buf[7] = { 0x04, 0x0e, 0x04, 0x01, 0x3, 0xc, 0x00 }; -+ -+ if (!osal_strncmp(stp_core_ctx.rx_buf, rst_buf, 7)) -+ osal_printtimeofday("############ BT Rest end <--"); -+ } -+ -+ stp_ctx_lock(&stp_core_ctx); -+ -+ fgTriggerResume = stp_process_rxack(); -+ stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; -+ INDEX_INC(stp_core_ctx.sequence.expected_rxseq); -+ -+ /*Send tx ack */ -+ txAck = stp_core_ctx.sequence.txack; -+ stp_send_ack(txAck, 0); -+ -+ stp_ctx_unlock(&stp_core_ctx); -+#if CFG_WMT_LTE_COEX_HANDLING -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && -+ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { -+ fgRxOk = -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, COEX_TASK_INDX); -+ } else { -+ fgRxOk = -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type); -+ } -+#else -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && -+ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { -+ STP_WARN_FUNC("BT/WIFI & LTE coex in non-LTE projects,drop it...\n"); -+ } else { -+ fgRxOk = -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type); -+ } -+#endif -+ } else { -+ if (is_function_active == MTK_WCN_BOOL_FALSE) { -+ STP_ERR_FUNC("function type = %d is inactive, so no en-queue to rx\n", -+ stp_core_ctx.parser.type); -+ fgRxOk = 0; /*drop packet */ -+ } else { -+ STP_ERR_FUNC("mtkstp_process_packet: type = %x, the type is invalid\n", -+ stp_core_ctx.parser.type); -+ fgRxOk = 0; /*drop packet */ -+ } -+ stp_ctx_lock(&stp_core_ctx); -+ -+ fgTriggerResume = stp_process_rxack(); -+ stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; -+ INDEX_INC(stp_core_ctx.sequence.expected_rxseq); -+ -+ /*Send tx ack */ -+ txAck = stp_core_ctx.sequence.txack; -+ stp_send_ack(txAck, 0); -+ -+ stp_ctx_unlock(&stp_core_ctx); -+ } -+ -+ /* enqueue successfully */ -+ if (fgRxOk == 0) { -+ stp_process_packet_fail_count = 0; -+ /*notify corresponding subfunction of incoming data */ -+#if CFG_WMT_LTE_COEX_HANDLING -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && -+ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { -+#if 1 -+ STP_DBG_FUNC -+ ("WMT/LTE package:[0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x]\n", -+ stp_core_ctx.rx_buf[0], stp_core_ctx.rx_buf[1], stp_core_ctx.rx_buf[2], -+ stp_core_ctx.rx_buf[3], stp_core_ctx.rx_buf[4], stp_core_ctx.rx_buf[5], -+ stp_core_ctx.rx_buf[6], stp_core_ctx.rx_buf[7]); -+#endif -+ stp_notify_btm_handle_wmt_lte_coex(STP_BTM_CORE(stp_core_ctx)); -+ } else { -+ (*sys_event_set) (stp_core_ctx.parser.type); -+ } -+#else -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && -+ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { -+ STP_WARN_FUNC("omit BT/WIFI & LTE coex msg handling in non-LTE projects\n"); -+ } else { -+ (*sys_event_set) (stp_core_ctx.parser.type); -+ } -+#endif -+ } else { -+ stp_process_packet_fail_count++; -+ /*Queue is full */ -+ if (stp_core_ctx.parser.type == GPS_TASK_INDX) { -+ /*Clear Rx Queue if GPS */ -+ mtk_wcn_stp_flush_rx_queue(GPS_TASK_INDX); -+ } else { -+ /*notify corresponding subfunction of incoming data */ -+ (*sys_event_set) (stp_core_ctx.parser.type); -+ } -+ /*enqueue fail, don't send ack and wait for peer retry */ -+ STP_ERR_FUNC("Enqueue to Rx queue fail, maybe function %d queue is full\n", -+ stp_core_ctx.parser.type); -+ } -+ } -+ /*sequence not match && previous packet enqueue successfully, send the previous ACK */ -+ else if (fgRxOk == 0) { -+ STP_ERR_FUNC("mtkstp_process_packet: expected_rxseq = %d, parser.seq = %d\n", -+ stp_core_ctx.sequence.expected_rxseq, stp_core_ctx.parser.seq); -+ stp_process_packet_fail_count++; -+ -+ stp_ctx_lock(&stp_core_ctx); -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ txAck = stp_core_ctx.sequence.txack; -+ stp_send_ack(txAck, 1); -+ stp_ctx_unlock(&stp_core_ctx); -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ STP_ERR_FUNC -+ ("sequence not match && previous packet enqueue successfully, send the previous ACK (ack no =%d)\n", -+ txAck); -+ } -+ /*sequence not match && previous packet enqueue failed, do nothing, make the other side timeout */ -+ else { -+ stp_process_packet_fail_count++; -+ STP_ERR_FUNC -+ ("sequence not match && previous packet enqueue failed, do nothing, make the other side timeout\n"); -+ } -+ -+ if (fgTriggerResume == 0) { -+ /*[PatchNeed]Just Notificaiton, not blocking call */ -+ /* notify adaptation layer for possible tx resume mechanism */ -+ (*sys_event_tx_resume) (stp_core_ctx.sequence.winspace); -+ } -+ -+ if (stp_process_packet_fail_count > MTKSTP_RETRY_LIMIT) { -+ stp_process_packet_fail_count = 0; -+ STP_ERR_FUNC("The process packet fail count > 10 lastly\n\r, whole chip reset\n\r"); -+ mtk_wcn_stp_dbg_dump_package(); -+ /*Whole Chip Reset Procedure Invoke */ -+ /*if(STP_NOT_ENABLE_DBG(stp_core_ctx)) */ -+ if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) { -+ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(1); -+ stp_dbg_set_host_assert_info(4, 37, 1); -+ STP_INFO_FUNC("**Ack Miss trigger firmware assert**\n"); -+ iRet = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx)); -+ if (iRet) { -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); -+ /* (*sys_dbg_assert_aee)("[MT662x]Ack Miss", "**STP Ack Miss**\n Ack Miss.\n"); */ -+ osal_dbg_assert_aee("[SOC_CONSYS]Ack Miss", -+ "**[WCN_ISSUE_INFO]STP Ack Miss**\n Ack Miss.\n"); -+ -+ if (STP_IS_ENABLE_RST(stp_core_ctx)) { -+ STP_SET_READY(stp_core_ctx, 0); -+ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); -+ } else { -+ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); -+ } -+ } -+ } -+ } -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_init -+* DESCRIPTION -+* init STP kernel -+* PARAMETERS -+* cb_func [IN] function pointers of system APIs -+* RETURNS -+* INT32 0 = success, others = failure -+*****************************************************************************/ -+INT32 mtk_wcn_stp_init(const mtkstp_callback * const cb_func) -+{ -+ INT32 ret = 0; -+ INT32 i = 0; -+ -+ /* Function pointer to point to the currently used transmission interface -+ */ -+ sys_if_tx = cb_func->cb_if_tx; -+ -+ /* Used to inform the function driver has received the corresponding type of information */ -+ sys_event_set = cb_func->cb_event_set; -+ -+ /* Used to inform the function driver can continue to send information and -+ STP has resources to deal with -+ */ -+ sys_event_tx_resume = cb_func->cb_event_tx_resume; -+ -+ /* STP driver determines whether the function is enable. If not enable and -+ STP has received the kind of information, and STP have the right to put it away. -+ */ -+ sys_check_function_status = cb_func->cb_check_funciton_status; -+ -+ /* osal_unsleepable_lock_init(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock_init(&stp_core_ctx); -+ /* Setup timer to be used to check if f/w receive the data in the specific time -+ interval after being sent -+ */ -+ for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) -+ osal_unsleepable_lock_init(&stp_core_ctx.ring[i].mtx); -+ -+ stp_core_ctx.tx_timer.timeoutHandler = stp_tx_timeout_handler; -+ stp_core_ctx.tx_timer.timeroutHandlerData = 0; -+ osal_timer_create(&stp_core_ctx.tx_timer); -+ -+ STP_SET_BT_STK(stp_core_ctx, 0); -+ STP_SET_ENABLE(stp_core_ctx, 0); -+ STP_SET_ENABLE_DBG(stp_core_ctx, 0); -+ STP_SET_ENABLE_RST(stp_core_ctx, 0); -+ STP_SET_PENDING_TYPE(stp_core_ctx, 0); -+ STP_SET_READY(stp_core_ctx, 0); -+ STP_SET_SUPPORT_PROTOCOL(stp_core_ctx, 0); -+ STP_SET_PSM_CORE(stp_core_ctx, stp_psm_init()); -+ STP_SET_FW_COREDUMP_FLAG(stp_core_ctx, 0); -+ STP_ENABLE_FW_COREDUMP(stp_core_ctx, 0); -+ STP_SET_WMT_LAST_CLOSE(stp_core_ctx, 0); -+ STP_SET_EVT_ERR_ASSERT(stp_core_ctx, 0); -+ -+ if (!STP_PSM_CORE(stp_core_ctx)) { -+ ret = (-3); -+ goto ERROR; -+ } -+ -+ STP_SET_BTM_CORE(stp_core_ctx, stp_btm_init()); -+ if (!STP_BTM_CORE(stp_core_ctx)) { -+ STP_ERR_FUNC("STP_BTM_CORE(stp_core_ctx) initialization fail!\n"); -+ ret = (-3); -+ goto ERROR; -+ } -+ -+ if (STP_BTM_CORE(stp_core_ctx) != NULL) -+ g_mtkstp_dbg = stp_dbg_init(STP_BTM_CORE(stp_core_ctx)); -+ else -+ g_mtkstp_dbg = stp_dbg_init(NULL); -+ -+ if (!g_mtkstp_dbg) { -+ STP_ERR_FUNC("g_mtkstp_dbg initialization fail!\n"); -+ ret = (-3); -+ goto ERROR; -+ } -+ STP_SET_ENABLE_RST(stp_core_ctx, 1); -+#ifdef CONFIG_LOG_STP_INTERNAL -+ mtk_wcn_stp_dbg_enable(); -+#else -+ mtk_wcn_stp_dbg_enable(); -+#endif -+ goto RETURN; -+ -+ERROR: -+ stp_psm_deinit(STP_PSM_CORE(stp_core_ctx)); -+ -+RETURN: -+ return ret; -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_deinit -+* DESCRIPTION -+* deinit STP kernel -+* PARAMETERS -+* void -+* RETURNS -+* INT32 0 = success, others = failure -+*****************************************************************************/ -+INT32 mtk_wcn_stp_deinit(void) -+{ -+ UINT32 i = 0; -+ -+ sys_if_tx = NULL; -+ sys_event_set = NULL; -+ sys_event_tx_resume = NULL; -+ sys_check_function_status = NULL; -+ -+ stp_dbg_deinit(g_mtkstp_dbg); -+ stp_btm_deinit(STP_BTM_CORE(stp_core_ctx)); -+ stp_psm_deinit(STP_PSM_CORE(stp_core_ctx)); -+ -+ for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) -+ osal_unsleepable_lock_deinit(&stp_core_ctx.ring[i].mtx); -+ -+ stp_ctx_lock_deinit(&stp_core_ctx); -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_btm_get_dmp -+* DESCRIPTION -+* get stp dump related information -+* PARAMETERS -+* buffer: dump placement, len: dump size -+* RETURNS -+* 0: Success Negative Value: Fail -+*****************************************************************************/ -+ -+int mtk_wcn_stp_btm_get_dmp(char *buf, int *len) -+{ -+ return stp_dbg_dmp_out(g_mtkstp_dbg, buf, len); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_notify_stp -+* DESCRIPTION -+* WMT notification to STP that power saving job is done or not -+* PARAMETERS -+* -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+int mtk_wcn_stp_psm_notify_stp(const MTKSTP_PSM_ACTION_T action) -+{ -+ return stp_psm_notify_stp(STP_PSM_CORE(stp_core_ctx), action); -+} -+ -+int mtk_wcn_stp_set_psm_state(MTKSTP_PSM_STATE_T state) -+{ -+ return stp_psm_set_state(STP_PSM_CORE(stp_core_ctx), state); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_enable -+* DESCRIPTION -+* enable STP sleep/wakeup support -+* PARAMETERS -+* void -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+INT32 mtk_wcn_stp_psm_enable(INT32 idle_time_to_sleep) -+{ -+#if 0 -+ if (MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) { -+ if (mtk_wcn_stp_is_ready()) -+ return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); -+ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return -1; -+ } -+ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { -+ return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); -+ } else if (mtk_wcn_stp_is_sdio_mode()) { -+ stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); -+ STP_DBG_FUNC("PSM is not support under SDIO mode\n"); -+ return 0; -+ } -+ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return -1; -+ -+#else -+ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { -+ return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); -+ } else if (mtk_wcn_stp_is_sdio_mode()) { -+ stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); -+ STP_DBG_FUNC("PSM is not support under SDIO mode\n"); -+ return 0; -+ } -+ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return -1; -+#endif -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_disable -+* DESCRIPTION -+* disable STP sleep/wakeup support -+* PARAMETERS -+* void -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_psm_disable(VOID) -+{ -+#if 0 -+ if (MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) { -+ if (mtk_wcn_stp_is_ready()) -+ return stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return -1; -+ } -+ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { -+ return stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ } else if (mtk_wcn_stp_is_sdio_mode()) { -+ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ return 0; -+ } -+ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return -1; -+ -+#else -+ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { -+ return stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ } else if (mtk_wcn_stp_is_sdio_mode()) { -+ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ return 0; -+ } -+ STP_DBG_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return 0; -+ -+#endif -+} -+ -+extern INT32 mtk_wcn_stp_psm_reset(VOID) -+{ -+ return stp_psm_reset(STP_PSM_CORE(stp_core_ctx)); -+} -+ -+extern INT32 mtk_wcn_stp_dbg_disable(VOID) -+{ -+ if (STP_IS_ENABLE_DBG(stp_core_ctx)) { -+ STP_DBG_FUNC("STP dbg mode is turned off\n"); -+ STP_SET_ENABLE_DBG(stp_core_ctx, 0); -+ stp_dbg_disable(g_mtkstp_dbg); -+ } else { -+ STP_WARN_FUNC("STP dbg mode has been turned off\n"); -+ } -+ -+ return 0; -+} -+ -+extern INT32 mtk_wcn_stp_dbg_enable(VOID) -+{ -+ if (STP_NOT_ENABLE_DBG(stp_core_ctx)) { -+ STP_DBG_FUNC("STP dbg mode is turned on\n"); -+ STP_SET_ENABLE_DBG(stp_core_ctx, 1); -+ stp_dbg_enable(g_mtkstp_dbg); -+ } else { -+ STP_WARN_FUNC("STP dbg mode has been turned on\n"); -+ } -+ -+ return 0; -+} -+ -+INT32 mtk_wcn_stp_dbg_log_ctrl(UINT32 on) -+{ -+ stp_dbg_log_ctrl(on); -+ return 0; -+} -+ -+INT32 mtk_wcn_stp_coredump_flag_ctrl(UINT32 on) -+{ -+ STP_ENABLE_FW_COREDUMP(stp_core_ctx, on); -+ STP_INFO_FUNC("coredump function mode: %d.\n", on); -+ g_coredump_mode = on; -+ return 0; -+} -+ -+INT32 mtk_wcn_stp_coredump_flag_get(VOID) -+{ -+ return STP_ENABLE_FW_COREDUMP_FLAG(stp_core_ctx); -+} -+ -+static INT32 stp_parser_data_in_mand_mode(UINT32 length, UINT8 *p_data) -+{ -+ UINT8 padding_len = 0; -+ INT32 remain_length; /* GeorgeKuo: sync from MAUI, change to unsigned */ -+ MTK_WCN_BOOL is_function_active = 0; -+ INT32 i = length; -+ -+ while (i > 0) { -+ switch (stp_core_ctx.parser.state) { -+ case MTKSTP_SYNC: /* b'10 */ -+ /* if (((*p_data & 0x80) == 0x80) && ((*p_data & 0x40) == 0x00)) */ -+ /* if(*p_data == 0x80) */ -+ if ((*p_data & 0x80) == 0x80) { -+ /* STP_DBG_FUNC("[STP] STP Packet Start =========>\n"); */ -+ if (*p_data != 0x80) -+ STP_WARN_FUNC("SDIO not 0x80!!(0x%x)\n", *p_data); -+ -+ if (i >= 4) { -+#if !(REMOVE_USELESS_LOG) -+ /*print header, when get the full STP header */ -+ UINT32 type = (*(p_data + 1) & 0x70) >> 4; -+ UINT8 *type_name = ""; -+ -+ type_name = stp_type_to_dbg_string(type); -+ STP_DBG_FUNC( -+ "STP Rx Header: [%02x %02x %02x %02x] type=%s, len=%d, seq=%d, ack=%d\n", -+ *p_data, *(p_data + 1), *(p_data + 2), *(p_data + 3), -+ type_name, ((*(p_data + 1) & 0x0f) << 8) + *(p_data + 2), -+ (*p_data & 0x38) >> 3, *p_data & 0x07); -+#endif -+ } else { -+ STP_WARN_FUNC("STP Rx: discard due to i < 4 (%d)\n", i); -+ } -+ -+ /* STP_DBG_FUNC("[STP] sync->nak\n"); */ -+ stp_change_rx_state(MTKSTP_NAK); -+ stp_core_ctx.rx_counter++; -+ } else { -+ STP_WARN_FUNC("sync to sync!!(0x%x)\n", *p_data); -+ stp_change_rx_state(MTKSTP_SYNC); -+ } -+ break; -+ -+ case MTKSTP_NAK: -+ /* STP_DBG_FUNC("[STP] nak->length\n"); */ -+ stp_change_rx_state(MTKSTP_LENGTH); -+ stp_core_ctx.parser.type = (*p_data & 0x70) >> 4; -+ if (stp_core_ctx.parser.type <= MTKSTP_MAX_TASK_NUM) { -+ stp_core_ctx.parser.length = (*p_data & 0x0f) << 8; -+ stp_core_ctx.rx_counter++; -+ } else { -+ STP_WARN_FUNC("nak to sync\n"); -+ stp_change_rx_state(MTKSTP_SYNC); -+ } -+ break; -+ -+ case MTKSTP_LENGTH: -+ /* STP_DBG_FUNC("[STP] length -> checksum\n"); */ -+ stp_change_rx_state(MTKSTP_CHECKSUM); -+ stp_core_ctx.parser.length += *p_data; -+ -+ /*Valid length checking */ -+ if (stp_core_ctx.parser.length < 2000) { -+ stp_core_ctx.rx_counter++; -+ } else { -+ STP_WARN_FUNC("The length of STP packet is not valid !!! length = %d\n", -+ stp_core_ctx.parser.length); -+ stp_change_rx_state(MTKSTP_SYNC); -+ stp_core_ctx.rx_counter = 0; -+ /* return -1; */ -+ } -+ -+ break; -+ -+ case MTKSTP_CHECKSUM: -+ -+ if ((stp_core_ctx.parser.type == STP_TASK_INDX) || -+ (stp_core_ctx.parser.type == INFO_TASK_INDX)) { -+ stp_change_rx_state(MTKSTP_FW_MSG); -+ stp_core_ctx.rx_counter = 0; -+ i -= 1; -+ if (i != 0) -+ p_data += 1; -+ -+ continue; -+ } -+ -+ if (stp_core_ctx.parser.length == 0) { -+ STP_WARN_FUNC("checksum to sync\n"); -+ stp_change_rx_state(MTKSTP_SYNC); -+ stp_core_ctx.rx_counter = 0; -+ } else { -+ /* STP_DBG_FUNC("[STP] checksum->data\n"); */ -+ stp_change_rx_state(MTKSTP_DATA); -+ stp_core_ctx.rx_counter = 0; -+ } -+ break; -+ -+ case MTKSTP_DATA: -+ -+ /* block copy instead of byte copy */ -+ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { -+ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", -+ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); -+ osal_assert(0); -+ } -+ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; -+ if (i >= remain_length) { -+ /*boundary checking */ -+ if (stp_core_ctx.rx_counter + remain_length >= MTKSTP_BUFFER_SIZE) { -+ STP_ERR_FUNC("Abnormal!! Memory operation over boundary!!\n"); -+ stp_change_rx_state(MTKSTP_SYNC); -+ stp_core_ctx.rx_counter = 0; -+ return -1; -+ } -+ -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, -+ remain_length); -+ i -= remain_length; -+ p_data += remain_length; -+ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; -+ stp_core_ctx.parser.state = MTKSTP_CRC1; -+ continue; -+ -+ } else { /* only copy by data length */ -+ -+ /*fixed klocwork insight issue */ -+ /*boundary checking */ -+ if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { -+ STP_ERR_FUNC("Abnormal!! Memory operation over boundary 2!!\n"); -+ stp_core_ctx.rx_counter = 0; -+ return -1; -+ } -+ -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); -+ stp_core_ctx.rx_counter += i; /* all remain buffer are data */ -+ i = 0; -+ p_data += i; -+ continue; -+ } -+ break; -+ -+ case MTKSTP_CRC1: -+ stp_change_rx_state(MTKSTP_CRC2); -+ break; -+ -+ case MTKSTP_CRC2: -+#if 1 -+ if (stp_core_ctx.parser.type == WMT_TASK_INDX) { -+ stp_core_ctx.parser.wmtsubtype = stp_core_ctx.rx_buf[1]; -+ STP_DBG_FUNC("wmt sub type (0x%x)\n", stp_core_ctx.parser.wmtsubtype); -+ } -+#endif -+ /*SDIO mode do it. */ -+ if (mtk_wcn_stp_is_sdio_mode()) { -+ /*STP packet 4-bytes alignment */ -+ /*Discard padding bytes , otherwise make parser state machine disorder */ -+ if (i <= 4) { -+ /*STP_DBG_FUNC("STP last block padding %d bytes\n", i-1); */ -+ p_data += (i - 1); -+ i -= (i - 1); -+ } else { -+ padding_len = (0x04 - ((stp_core_ctx.parser.length + 6) & 0x03)) & 0x03; -+ p_data += padding_len; -+ i -= padding_len; -+ /*STP_DBG_FUNC("STP Agg padding %d bytes\n", padding_len); */ -+ } -+ } -+ stp_dbg_pkt_log(stp_core_ctx.parser.type, -+ 0, 0, 0, PKT_DIR_RX, stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); -+ if ((stp_core_ctx.parser.type == BT_TASK_INDX) && STP_BT_STK_IS_BLUEZ(stp_core_ctx)) { -+ int b; -+ -+ /*Indicate packet to hci_stp */ -+ if (gStpDbgLvl >= STP_LOG_DBG) { -+ stp_dump_data(stp_core_ctx.rx_buf, "indicate_to_bt_core", -+ stp_core_ctx.rx_counter); -+ } -+ -+ b = mtk_wcn_sys_if_rx(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); -+ if (b) -+ STP_ERR_FUNC("mtk_wcn_sys_if_rx is NULL\n"); -+ -+ } else { -+ -+ is_function_active = ( -+ (*sys_check_function_status)(stp_core_ctx.parser.type, OP_FUNCTION_ACTIVE) -+ == STATUS_FUNCTION_ACTIVE); -+ -+ /*check type and function if active? */ -+ if ((stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) -+ && (is_function_active == MTK_WCN_BOOL_TRUE)) { -+#if CFG_WMT_LTE_COEX_HANDLING -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) -+ && stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG) { -+ STP_INFO_FUNC("wmt/lte coex package!\n"); -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, -+ stp_core_ctx.rx_counter, COEX_TASK_INDX); -+ stp_notify_btm_handle_wmt_lte_coex(STP_BTM_CORE(stp_core_ctx)); -+ } else { -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, -+ stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type); -+ -+ /*notify corresponding subfunction of incoming data */ -+ (*sys_event_set) (stp_core_ctx.parser.type); -+ } -+#else -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) -+ && stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG) { -+ STP_WARN_FUNC -+ ("omit BT/WIFI & LTE coex msg handling in non-LTE projects\n"); -+ } else { -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, -+ stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type); -+ -+ /*notify corresponding subfunction of incoming data */ -+ (*sys_event_set) (stp_core_ctx.parser.type); -+ } -+#endif -+ } else { -+ if (is_function_active == MTK_WCN_BOOL_FALSE) { -+ STP_ERR_FUNC -+ ("function type = %d is inactive, so no en-queue to rx\n", -+ stp_core_ctx.parser.type); -+ } else { -+ STP_ERR_FUNC -+ ("mtkstp_process_packet: type = %x, the type is invalid\n", -+ stp_core_ctx.parser.type); -+ } -+ } -+ } -+ -+ /* STP_DBG_FUNC("[STP] crc2->sync\n"); */ -+ /* STP_DBG_FUNC("[STP] STP Packet End <=========\n"); */ -+ stp_core_ctx.rx_counter = 0; -+ stp_change_rx_state(MTKSTP_SYNC); -+ -+ break; -+ -+ case MTKSTP_FW_MSG: -+ -+ /*f/w assert and exception information */ -+ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { -+ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", -+ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); -+ } -+ -+ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; -+ -+ if (i >= remain_length) { -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, -+ remain_length); -+ i -= remain_length; -+ p_data += remain_length; -+ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; -+ *(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter) = '\0'; -+ /*Trace32 Dump */ -+ if (stp_core_ctx.parser.type == STP_TASK_INDX) { -+ /* g_block_tx = 1; */ -+ mtk_wcn_stp_coredump_start_ctrl(1); -+ pr_debug("[len=%d][type=%d]\n%s\n", stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type, stp_core_ctx.rx_buf); -+ /*use paged dump or full dump */ -+ stp_btm_notify_wmt_dmp_wq(stp_core_ctx.btm); -+#if 0 -+ stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_FW_DMP /*STP_DBG_FW_ASSERT */ , 5, -+ 0, 0, 0, 0, -+ (stp_core_ctx.rx_counter + 1), stp_core_ctx.rx_buf); -+#endif -+ } -+ -+ /*discard CRC */ -+ /* we will discard antoher CRC on the outer switch procedure. */ -+ if (i >= 1) { -+ STP_INFO_FUNC("crc discard.. i = %d\n", i); -+ i -= 1; -+ if (i > 0) -+ p_data += 1; -+ -+ } -+ -+ /*STP packet 4-bytes alignment */ -+ /*Discard padding bytes , otherwise make parser state machine disorder */ -+ if (i <= 4) { -+ STP_INFO_FUNC -+ ("\n[STP]FW_EVENT========= block padding %d bytes =========\n", -+ i - 1); -+ p_data += (i - 1); -+ i -= (i - 1); -+ } else { -+ padding_len = (0x04 - ((stp_core_ctx.parser.length + 6) & 0x03)) & 0x03; -+ p_data += padding_len; -+ i -= padding_len; -+ STP_INFO_FUNC -+ ("\n[STP]FW_EVENT========= STP Agg padding %d bytes =========\n", -+ padding_len); -+ } -+ stp_change_rx_state(MTKSTP_SYNC); -+ -+ } else { /* only copy by data length */ -+ -+ STP_ERR_FUNC("raw data doesn't contain full stp packet!!\n"); -+ } -+ break; -+ default: -+ break; -+ } -+ p_data++; -+ i--; -+ } -+ -+ return 0; -+} -+ -+static INT32 stp_parser_data_in_full_mode(UINT32 length, UINT8 *p_data) -+{ -+ INT32 remain_length; /* GeorgeKuo: sync from MAUI, change to unsigned */ -+ INT32 i = length; -+ -+ while (i > 0) { -+ switch (stp_core_ctx.parser.state) { -+ -+ case MTKSTP_RESYNC1: /* RESYNC must be 4 _continuous_ 0x7f */ -+ if (*p_data == 0x7f) -+ stp_change_rx_state(MTKSTP_RESYNC2); -+ else -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ break; -+ case MTKSTP_RESYNC2: -+ if (*p_data == 0x7f) -+ stp_change_rx_state(MTKSTP_RESYNC3); -+ else -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ break; -+ case MTKSTP_RESYNC3: -+ if (*p_data == 0x7f) -+ stp_change_rx_state(MTKSTP_RESYNC4); -+ else -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ break; -+ case MTKSTP_RESYNC4: -+ if (*p_data == 0x7f) -+ stp_change_rx_state(MTKSTP_SYNC); -+ else -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ break; -+ case MTKSTP_SYNC: /* b'10 */ -+ STP_DUMP_PACKET_HEAD(p_data, "rx (uart):", length > 4 ? 4 : length); -+ if (((*p_data & 0x80) == 0x80) && ((*p_data & 0x40) == 0x00)) { -+ stp_change_rx_state(MTKSTP_NAK); -+ stp_core_ctx.parser.seq = (*p_data & 0x38) >> 3; -+ stp_core_ctx.parser.ack = *p_data & 0x07; -+ stp_core_ctx.rx_buf[0] = *p_data; -+ /* Geoge FIXME: WHY comment the following line? */ -+ /* stp_core_ctx.rx_counter++; */ -+ -+ if (i >= 4 && gStpDbgLvl >= STP_LOG_DBG) { -+ /*print header, when get the full STP header */ -+#if !(REMOVE_USELESS_LOG) -+ int type = (*(p_data + 1) & 0x70) >> 4; -+ char *type_name = ""; -+ -+ type_name = stp_type_to_dbg_string(type); -+ -+ STP_DBG_FUNC -+ ("STP Rx Header: [%02x %02x %02x %02x] type=%s, len=%d, seq=%d, ack=%d\n", -+ *p_data, *(p_data + 1), *(p_data + 2), *(p_data + 3), type_name, -+ ((*(p_data + 1) & 0x0f) << 8) + *(p_data + 2), -+ (*p_data & 0x38) >> 3, *p_data & 0x07); -+#endif -+ } else { -+ STP_DBG_FUNC("STP Rx: discard due to i < 4\n"); -+ } -+ } else if ((*p_data == 0x7f) && (prev_state == MTKSTP_RESYNC4)) { -+ /* if this 0x7f is continuous to resync pattern */ -+ /* skip this continuous 0x7f, remain current & prev state */ -+ osal_assert(0); -+ STP_ERR_FUNC("MTKSTP_SYNC: continuous resync pattern, buff = %x\n", *p_data); -+ } else if (*p_data == 0x7f) { /* a start of 0x7f, maybe this is resync pattern */ -+ stp_change_rx_state(MTKSTP_RESYNC2); -+ osal_assert(0); -+ STP_ERR_FUNC("MTKSTP_SYNC: go to MTKSTP_RESYNC2, buff = %x\n", *p_data); -+ } else if (*p_data == 0x55) { /* STP delimiter */ -+ /* do nothing for delimiter */ -+ } else { /* unexpected, go to resync1 */ -+ osal_assert(0); -+ STP_ERR_FUNC("MTKSTP_SYNC: unexpected data, buff = %x\n", *p_data); -+ } -+ break; -+ -+ case MTKSTP_NAK: -+ /* (*sys_dbg_print)("MTKSTP_NAK : mtk_wcn_stp_parser_data, buff = %x", *p_data); */ -+ if (fgEnableNak == 0) -+ stp_core_ctx.parser.nak = 0; /* disable NAK */ -+ else -+ stp_core_ctx.parser.nak = (*p_data & 0x80) >> 7; -+ -+ stp_core_ctx.parser.type = (*p_data & 0x70) >> 4; -+ stp_core_ctx.parser.length = (*p_data & 0x0f) << 8; -+ stp_core_ctx.rx_buf[1] = *p_data; -+ /* Geoge FIXME: WHY comment the following line? */ -+ /*stp_core_ctx.rx_counter++; */ -+ if (stp_core_ctx.parser.nak) -+ STP_ERR_FUNC("MTKSTP_NAK TRUE: mtk_wcn_stp_parser_data, buff = %x\n", *p_data); -+ -+ if (stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) -+ stp_change_rx_state(MTKSTP_LENGTH); -+ else -+ stp_change_rx_state(MTKSTP_SYNC); -+ break; -+ -+ case MTKSTP_LENGTH: -+ /* (*sys_dbg_print)("MTKSTP_LENGTH : mtk_wcn_stp_parser_data, buff = %x", *p_data); */ -+ stp_change_rx_state(MTKSTP_CHECKSUM); -+ stp_core_ctx.parser.length += *p_data; -+ -+ /*Valid length checking */ -+ if (stp_core_ctx.parser.length > 2048) { -+ STP_ERR_FUNC("The length of STP packet is not valid !!! length = %d\n", -+ stp_core_ctx.parser.length); -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.rx_counter = 0; -+ STP_TRACE_FUNC("--\n"); -+ return -1; -+ } -+ -+ stp_core_ctx.rx_buf[2] = *p_data; -+ /* Geoge FIXME: WHY comment the following line? */ -+ /*stp_core_ctx.rx_counter++; */ -+ break; -+ -+ case MTKSTP_CHECKSUM: -+ /* (*sys_dbg_print)("MTKSTP_CHECKSUM : mtk_wcn_stp_parser_data, buff = %x", *p_data); */ -+ if ((stp_core_ctx.parser.type == STP_TASK_INDX) || -+ (stp_core_ctx.parser.type == INFO_TASK_INDX)) { -+ stp_change_rx_state(MTKSTP_FW_MSG); -+ stp_core_ctx.rx_counter = 0; -+ i -= 1; -+ if (i != 0) -+ p_data += 1; -+ -+ continue; -+ } -+ -+ if (((stp_core_ctx.rx_buf[0] + -+ stp_core_ctx.rx_buf[1] + stp_core_ctx.rx_buf[2]) & 0xff) == *p_data) { -+ /* header only packet */ -+ if (stp_core_ctx.parser.length == 0) { -+ INT32 fgTriggerResume = (-1); -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ if (stp_core_ctx.inband_rst_set == 0) { -+ stp_dbg_pkt_log(STP_TASK_INDX, -+ stp_core_ctx.parser.ack, -+ stp_core_ctx.parser.seq, -+ 5, /* STP type id */ -+ PKT_DIR_RX, -+ NULL, -+ 0); -+ fgTriggerResume = stp_process_rxack(); -+ } else { -+ STP_WARN_FUNC -+ ("Now it's inband reset process and drop ACK packet.\n"); -+ } -+ -+ if (fgTriggerResume == 0) { -+ /* notify adaptation layer for -+ * possible tx resume mechanism -+ */ -+ (*sys_event_tx_resume) (stp_core_ctx.sequence.winspace); -+ } -+ stp_ctx_unlock(&stp_core_ctx); -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_change_rx_state(MTKSTP_SYNC); -+ stp_core_ctx.rx_counter = 0; -+ } else { -+ stp_change_rx_state(MTKSTP_DATA); -+ stp_core_ctx.rx_counter = 0; -+ } -+ } else { -+ STP_ERR_FUNC("The checksum of header is error !!! %02x %02x %02x %02x\n", -+ stp_core_ctx.rx_buf[0], stp_core_ctx.rx_buf[1], -+ stp_core_ctx.rx_buf[2], *p_data); -+ /* George FIXME: error handling mechanism shall be refined */ -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.rx_counter = 0; -+ -+ /* since checksum error is usually related to interface -+ * buffer overflow, so we just let timeout mechanism to -+ * handle such error. -+ */ -+ STP_TRACE_FUNC("--\n"); -+ /* return and purge COMM port */ -+ return -1; -+ /*stp_send_ack(1); NAK mechanism is removed */ -+ } -+ break; -+ -+ case MTKSTP_DATA: -+#if 0 -+ if (stp_core_ctx.rx_counter < stp_core_ctx.parser.length) { -+ stp_core_ctx.rx_buf[stp_core_ctx.rx_counter] = *p_data; -+ stp_core_ctx.rx_counter++; -+ } -+ if (stp_core_ctx.rx_counter == stp_core_ctx.parser.length) -+ stp_change_rx_state(MTKSTP_CRC1); -+#else -+ /* block copy instead of byte copy */ -+ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { -+ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", -+ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); -+ osal_assert(0); -+ } -+ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; -+ if (i >= remain_length) { -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, -+ remain_length); -+ -+ i -= remain_length; -+ p_data += remain_length; -+ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; -+ stp_core_ctx.parser.state = MTKSTP_CRC1; -+ continue; -+ } else { /* only copy by data length */ -+ -+ /*fixed klocwork insight issue */ -+ if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { -+ STP_ERR_FUNC -+ ("Fail to handle Packet, maybe it doesn't follow STP protocol.\n"); -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.rx_counter = 0; -+ STP_TRACE_FUNC("--\n"); -+ return -1; -+ } -+ -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); -+ stp_core_ctx.rx_counter += i; /* all remain buffer are data */ -+ i = 0; -+ p_data += i; -+ continue; -+ } -+#endif -+ break; -+ -+ case MTKSTP_CRC1: -+ stp_change_rx_state(MTKSTP_CRC2); -+ stp_core_ctx.parser.crc = *p_data; -+ break; -+ case MTKSTP_CRC2: -+ stp_change_rx_state(MTKSTP_SYNC); -+ stp_core_ctx.parser.crc += (*p_data) << 8; -+#if 1 -+ if (stp_core_ctx.parser.type == WMT_TASK_INDX) { -+ stp_core_ctx.parser.wmtsubtype = stp_core_ctx.rx_buf[1]; -+ STP_DBG_FUNC("wmt sub type is (0x%x)\n", stp_core_ctx.parser.wmtsubtype); -+ } -+#endif -+ if (stp_check_crc(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, stp_core_ctx.parser.crc) -+ == MTK_WCN_BOOL_TRUE) { -+ if (stp_core_ctx.inband_rst_set == 0) -+ stp_process_packet(); -+ else -+ STP_WARN_FUNC("Now it's inband reset process and drop packet.\n"); -+ } else { -+ STP_ERR_FUNC("The CRC of packet is error !!!\n"); -+ /* George FIXME: error handling mechanism shall be refined */ -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.rx_counter = 0; -+ -+ /* since checksum error is usually related to interface -+ * buffer overflow, so we just let timeout mechanism to -+ * handle such error. -+ */ -+ STP_TRACE_FUNC("--\n"); -+ /* return and purge COMM port */ -+ return -1; -+ /*stp_send_ack(1); NAK mechanism is removed */ -+ } -+ break; -+ -+ case MTKSTP_FW_MSG: -+#if CFG_WMT_DUMP_INT_STATUS -+ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) -+ wmt_plat_BGF_irq_dump_status(); -+#endif -+ if (STP_IS_READY(stp_core_ctx)) -+ mtk_wcn_stp_dbg_dump_package(); -+ -+ STP_SET_READY(stp_core_ctx, 0); -+ /*stp inband reset */ -+ if (stp_core_ctx.parser.type == STP_TASK_INDX && -+ stp_core_ctx.parser.seq == 0 && -+ stp_core_ctx.parser.ack == 0 && -+ stp_core_ctx.parser.length == 0 && stp_core_ctx.inband_rst_set == 1) { -+ STP_INFO_FUNC("Inband reset event get! Resync STP with firmware!\n\r"); -+ stp_rest_ctx_state(); -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.inband_rst_set = 0; -+ /* STP_INFO_FUNC("Restart STP Timer\n\r"); */ -+ /* (*sys_timer_start)(stp_core_ctx.tx_timer, -+ * mtkstp_tx_timeout, -+ * (MTK_WCN_TIMER_CB)stp_tx_timeout_handler, -+ * NULL); -+ */ -+ STP_TRACE_FUNC("--\n"); -+ return 0; -+ } -+ -+ /*f/w assert and exception information */ -+ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { -+ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", -+ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); -+ osal_assert(0); -+ } -+ -+ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; -+ if (i >= remain_length) { -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, -+ remain_length); -+ i -= remain_length; -+ p_data += remain_length; -+ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; -+ stp_change_rx_state(MTKSTP_SYNC); -+ *(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter) = '\0'; -+ /* STP_ERR_FUNC("%s [%d]\n", stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); */ -+#if 0 -+ if ((stp_core_ctx.rx_counter == 1) && (stp_core_ctx.rx_buf[0] == 0xFF)) { -+ /* For MT6620, enable/disable coredump function is controlled by -+ * firmware for the moment, we need to set coredump enable flag -+ * to be 1 after see firmware send a pariticallar character(0xff) -+ * before any coredump packet is sent -+ */ -+ mtk_wcn_stp_coredump_flag_ctrl(1); -+ } -+#endif -+ /*Trace32 Dump */ -+ if (STP_IS_ENABLE_DBG(stp_core_ctx) && -+ (stp_core_ctx.parser.type == STP_TASK_INDX)) { -+ if (0 != stp_core_ctx.rx_counter) { -+ STP_SET_READY(stp_core_ctx, 0); -+ mtk_wcn_stp_ctx_save(); -+ STP_INFO_FUNC("++ start to read paged dump and paged trace ++\n"); -+ stp_btm_notify_wmt_dmp_wq(stp_core_ctx.btm); -+ stp_btm_notify_wmt_trace_wq(stp_core_ctx.btm); -+ STP_INFO_FUNC("++ start to read paged dump and paged trace --\n"); -+ -+ } -+ STP_INFO_FUNC("[len=%d][type=%d]\n%s\n", stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type, stp_core_ctx.rx_buf); -+ } -+ -+ /*Runtime FW Log */ -+ else if (STP_IS_ENABLE_DBG(stp_core_ctx) -+ && (stp_core_ctx.parser.type == INFO_TASK_INDX)) { -+ stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_FW_LOG, STP_TASK_INDX, 5, 0, 0, 0, -+ (stp_core_ctx.rx_counter + 1), stp_core_ctx.rx_buf); -+ mtk_wcn_stp_dbg_dump_package(); -+ } -+ /*Normal mode: whole chip reset */ -+ else { -+ /*Aee Kernel Warning Message Shown First */ -+ /* (*sys_dbg_assert_aee)("[MT662x]f/w Assert", stp_core_ctx.rx_buf); */ -+ mtk_wcn_stp_coredump_start_ctrl(0); -+ mtk_wcn_stp_dbg_dump_package(); -+ -+ osal_dbg_assert_aee(stp_core_ctx.rx_buf, stp_core_ctx.rx_buf); -+ /*Whole Chip Reset Procedure Invoke */ -+ if (STP_IS_ENABLE_RST(stp_core_ctx)) { -+ STP_SET_READY(stp_core_ctx, 0); -+ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); -+ } else { -+ STP_INFO_FUNC -+ ("No to launch whole chip reset! for debugging purpose\n"); -+ } -+ } -+ /*discard CRC */ -+ if (i >= 2) { -+ STP_DBG_FUNC("crc discard.. i = %d\n", i); -+ i -= 2; -+ if (i > 0) -+ p_data += 2; -+ } -+ continue; -+ } else { /* only copy by data length */ -+ -+ /*fixed klocwork insight issue */ -+ if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { -+ STP_ERR_FUNC -+ ("Fail to handle Packet, maybe it doesn't follow STP protocol.\n"); -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.rx_counter = 0; -+ return -1; -+ } -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); -+ stp_core_ctx.rx_counter += i; /* all remain buffer are data */ -+ i = 0; -+ p_data += i; -+ continue; -+ } -+ -+ break; -+ default: -+ break; -+ } -+ p_data++; -+ i--; -+ } -+ -+ return 0; -+} -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_parser_data -+* DESCRIPTION -+* push data to serial transport protocol parser engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* int 0 = success; -1 = crc/checksum error -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+int _mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length) -+#else -+int mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length) -+#endif -+{ -+ /*----------------------------------------------------------------*/ -+ /* Local Variables */ -+ /*----------------------------------------------------------------*/ -+ INT32 i; -+ UINT8 *p_data; -+ INT32 ret = 0; -+#ifdef DEBUG_DUMP_PACKET_HEAD -+ static UINT32 counter; -+ -+ STP_TRACE_FUNC("++, rx (cnt=%d,len=%d)\n", ++counter, length); -+#endif -+ -+#if 0 -+#ifdef CONFIG_POWER_SAVING_SUPPORT -+ if (stp_is_apply_powersaving()) { -+ /* If now chip is awake, to restart monitor! */ -+ if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) { -+ STP_DBG_FUNC("To restart moinotr when rx\n\r"); -+ stp_psm_start_monitor(STP_PSM_CORE(stp_core_ctx)); -+ } -+ } -+#endif -+#endif -+ -+ /*----------------------------------------------------------------*/ -+ /* Code Body */ -+ /*----------------------------------------------------------------*/ -+ /* George FIXME: WHY or HOW can we reduct the locked region? */ -+ /*flags = (*sys_mutex_lock)(stp_core_ctx.stp_mutex); */ -+ i = length; -+ p_data = (UINT8 *) buffer; -+ -+/* stp_dump_data(buffer, "rx queue", length); */ -+ -+ /*STP is not enabled and only WMT can use Raw data path */ -+ if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == STP_PENDING_TYPE(stp_core_ctx)) { -+ /* route to task who send command */ -+ stp_add_to_rx_queue(buffer, length, STP_PENDING_TYPE(stp_core_ctx)); -+ -+ /* mike: notify corresponding subfunction of incoming data */ -+ (*sys_event_set) (STP_PENDING_TYPE(stp_core_ctx)); -+ } -+ /* STP over SDIO */ -+ else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { -+#if !(REMOVE_USELESS_LOG) -+ if (gStpDbgLvl >= STP_LOG_DBG) -+ stp_dump_data(buffer, "sdio parser_in", length); -+#endif -+ /* STP_DBG_FUNC("sdio stp parser data length = %d\n", length); */ -+ ret = stp_parser_data_in_mand_mode(i, p_data); -+ } -+ /* STP over UART */ -+ else if (mtk_wcn_stp_is_btif_fullset_mode() && STP_IS_ENABLE(stp_core_ctx)) -+ ret = stp_parser_data_in_full_mode(i, p_data); -+ -+ /* George FIXME: WHY or HOW can we reduct the locked region? */ -+ /*(*sys_mutex_unlock)(stp_core_ctx.stp_mutex, flags); */ -+ STP_TRACE_FUNC("--\n"); -+ return ret; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_parser_data); -+#endif -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_enable -+* DESCRIPTION -+* enable/disable STP -+* PARAMETERS -+* value [IN] 0=disable, others=enable -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+INT32 mtk_wcn_stp_enable(INT32 value) -+{ -+ STP_DBG_FUNC("%s: set the current enable = (%d)\n", __func__, value); -+ -+ stp_rest_ctx_state(); -+ STP_SET_ENABLE(stp_core_ctx, value); -+ if (!value) { -+ mtk_wcn_stp_psm_reset(); -+ } else { -+/* g_block_tx = 0; */ -+ mtk_wcn_stp_coredump_start_ctrl(0); -+ } -+ return 0; -+} -+ -+INT32 mtk_wcn_stp_dbg_dump_package(VOID) -+{ -+ if (STP_NOT_ENABLE(stp_core_ctx)) { -+ STP_INFO_FUNC("STP dbg mode is off\n"); -+ -+ } else { -+ STP_INFO_FUNC("STP dbg mode is on\n"); -+ /* if (0 == g_block_tx) */ -+ if (0 == mtk_wcn_stp_coredump_start_get()) { -+ mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_LOG); -+ mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_BTIF_REG); -+ stp_dbg_dmp_printk(g_mtkstp_dbg); -+ } else { -+ STP_INFO_FUNC("assert start flag is set, disable packet dump function\n"); -+ } -+ } -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_ready -+* DESCRIPTION -+* ready/un-ready STP -+* PARAMETERS -+* value [IN] 0=un-ready, others=ready -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+INT32 mtk_wcn_stp_ready(INT32 value) -+{ -+ STP_DBG_FUNC("set ready (%d)\n", value); -+ -+ STP_SET_READY(stp_core_ctx, value); -+ /*if whole chip reset, reset the debuggine mode */ -+#ifndef CONFIG_LOG_STP_INTERNAL -+ /* mtk_wcn_stp_dbg_disable(); */ -+#endif -+ -+ if (stp_is_apply_powersaving()) { -+ STP_INFO_FUNC("Restart the stp-psm monitor !!\n"); -+ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ } -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_coredump_start_ctrl -+* DESCRIPTION -+* set f/w assert flag in STP context -+* PARAMETERS -+* value [IN] 0=assert end, others=assert begins -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+INT32 mtk_wcn_stp_coredump_start_ctrl(UINT32 value) -+{ -+ STP_DBG_FUNC("set f/w assert (%d)\n", value); -+ -+ STP_SET_FW_COREDUMP_FLAG(stp_core_ctx, value); -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_coredump_start_get -+* DESCRIPTION -+* get f/w assert flag in STP context -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32 0= f/w assert flag is not set, others=f/w assert flag is set -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_coredump_start_get(VOID) -+#else -+INT32 mtk_wcn_stp_coredump_start_get(VOID) -+#endif -+{ -+ return STP_FW_COREDUMP_FLAG(stp_core_ctx); -+} -+ -+/* mtk_wcn_stp_set_wmt_last_close -- set the state of link(UART or SDIO) -+ * @ value - 1, link already be closed; 0, link is open -+ * -+ * Return 0 if success; else error code -+ */ -+INT32 mtk_wcn_stp_set_wmt_last_close(UINT32 value) -+{ -+ STP_INFO_FUNC("set wmt_last_close flag (%d)\n", value); -+ -+ STP_SET_WMT_LAST_CLOSE(stp_core_ctx, value); -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data -+* DESCRIPTION -+* subfunction send data through STP -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 > 0: length transmitted; = 0: error -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+#else -+INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+#endif -+{ -+ UINT8 mtkstp_header[MTKSTP_HEADER_SIZE], temp[2]; -+ UINT8 *p_tx_buf = NULL; -+ UINT16 crc; -+ INT32 ret = 0; -+ MTK_WCN_BOOL is_quick_enable = MTK_WCN_BOOL_TRUE; -+ -+ /* osal_buffer_dump(buffer,"tx", length, 32); */ -+ -+ if (0 != STP_WMT_LAST_CLOSE(stp_core_ctx)) { -+ STP_ERR_FUNC("WMT lats close,should not have tx request!\n"); -+ return length; -+ } -+ /* if(g_block_tx) */ -+ if (0 != mtk_wcn_stp_coredump_start_get()) { -+ STP_ERR_FUNC("STP fw coredump start flag set...\n"); -+ return length; -+ } -+#ifdef CONFIG_POWER_SAVING_SUPPORT -+ is_quick_enable = stp_psm_is_quick_ps_support(); -+ STP_DBG_FUNC("is quick sleep enable:%s\n", is_quick_enable ? "yes" : "no"); -+ if (MTK_WCN_BOOL_TRUE == is_quick_enable) { -+ if (type != WMT_TASK_INDX) { -+#if PSM_USE_COUNT_PACKAGE -+ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 0); -+#else -+ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 0, length); -+#endif -+ } -+ /* if(stp_is_apply_powersaving()) */ -+ { -+ if (type == WMT_TASK_INDX) -+ goto DONT_MONITOR; -+ /*-----------------------------STP_PSM_Lock----------------------------------------*/ -+ ret = stp_psm_thread_lock_aquire(STP_PSM_CORE(stp_core_ctx)); -+ if (ret) { -+ STP_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret); -+ return ret; -+ } -+ -+ if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) { -+ if (stp_psm_has_pending_data(STP_PSM_CORE(stp_core_ctx))) { -+ STP_WARN_FUNC("***** Release psm hold data before send normal data *****\n"); -+ stp_psm_release_data(STP_PSM_CORE(stp_core_ctx)); -+ } -+ } else { -+ ret = stp_psm_hold_data(STP_PSM_CORE(stp_core_ctx), buffer, length, type); -+ stp_psm_notify_wmt_wakeup(STP_PSM_CORE(stp_core_ctx)); -+ /*-----------------------------STP_PSM_UnLock----------------------------------------*/ -+ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); -+ return ret; -+ } -+ } -+ } else { -+ /* if(stp_is_apply_powersaving()) */ -+ { -+ if (type == WMT_TASK_INDX) -+ goto DONT_MONITOR; -+ /* If now chip is awake, to restart monitor! */ -+ /* STP_INFO_FUNC("check if block traffic !!\n"); */ -+ /*-----------------------------STP_PSM_Lock----------------------------------------*/ -+ ret = stp_psm_thread_lock_aquire(STP_PSM_CORE(stp_core_ctx)); -+ if (ret) { -+ STP_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret); -+ return ret; -+ } -+ -+ if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) { -+ /* STP_INFO_FUNC("not to block !!\n"); */ -+ if (stp_psm_has_pending_data(STP_PSM_CORE(stp_core_ctx))) { -+ STP_WARN_FUNC("***** Release psm hold data before send normal data *****\n"); -+ stp_psm_release_data(STP_PSM_CORE(stp_core_ctx)); -+ } -+ stp_psm_start_monitor(STP_PSM_CORE(stp_core_ctx)); -+ } else { -+ /* STP_INFO_FUNC("to block !!\n"); */ -+ -+ /* STP_INFO_FUNC("*****hold data in psm queue data length = %d\n", -+ * length); -+ */ -+ /* stp_dump_data(buffer, "Hold in psm queue", length); */ -+ /* hold datas */ -+ ret = stp_psm_hold_data(STP_PSM_CORE(stp_core_ctx), buffer, length, type); -+ /* wmt notification */ -+ STP_INFO_FUNC("#####Type = %d, to inform WMT to wakeup chip, ret = %d:0x%2x,0x%2x\n", -+ type, ret, *buffer, *(buffer + 1)); -+ stp_psm_notify_wmt_wakeup(STP_PSM_CORE(stp_core_ctx)); -+ /* STP_INFO_FUNC("*********Type = %d, to inform WMT to wakeup chip>end\n", type); */ -+ /*-----------------------------STP_PSM_UnLock----------------------------------------*/ -+ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); -+ return ret; -+ } -+ } -+ } -+DONT_MONITOR: -+#endif -+ if (type == BT_TASK_INDX) { -+ static const UINT8 rst_buf[4] = { 0x01, 0x03, 0x0c, 0x00 }; -+ -+ if (!osal_strncmp(buffer, rst_buf, 4)) -+ osal_printtimeofday("############ BT Rest start -->"); -+ } -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ /*Only WMT can set raw data */ -+ if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX != type) { -+ /* no-op */ -+ /* NULL; */ -+ } else if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == type) { -+ /* ret = mtk_wcn_stp_send_data_raw(buffer, length, type); */ -+ /* NULL; */ -+ } -+ /* STP over SDIO */ -+ else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { -+ -+ /* osal_printtimeofday("[ STP][SDIO][ B][W]"); */ -+ -+ mtkstp_header[0] = 0x80; -+ mtkstp_header[1] = (type << 4) + (((length) >> 8) & 0x0f); -+ mtkstp_header[2] = (length) & 0xff; -+ mtkstp_header[3] = 0x00; -+ -+ /* HEADER */ -+ p_tx_buf = &stp_core_ctx.tx_buf[0]; -+ osal_memcpy(p_tx_buf, mtkstp_header, MTKSTP_HEADER_SIZE); -+ p_tx_buf += MTKSTP_HEADER_SIZE; -+ -+ /* PAYLOAD */ -+ osal_memcpy(p_tx_buf, buffer, length); -+ p_tx_buf += length; -+ -+ /* CRC */ -+ temp[0] = 0x00; -+ temp[1] = 0x00; -+ osal_memcpy(p_tx_buf, temp, 2); -+ stp_dbg_pkt_log(type, 0, 0, 0, PKT_DIR_TX, buffer, length); -+ (*sys_if_tx) (&stp_core_ctx.tx_buf[0], (MTKSTP_HEADER_SIZE + length + 2), &ret); -+ -+ if ((MTKSTP_HEADER_SIZE + length + 2) != ret) { -+ STP_ERR_FUNC("stp send tx packet: %d, maybe stp_if_tx == NULL\n", ret); -+ osal_assert(0); -+ ret = 0; -+ } else { -+ ret = (INT32) length; -+ } -+ -+ /* osal_printtimeofday("[ STP][SDIO][ E][W]"); */ -+ } -+ /* STP over UART */ -+ else if (mtk_wcn_stp_is_btif_fullset_mode() && STP_IS_ENABLE(stp_core_ctx)) { -+ -+ /* osal_printtimeofday("[ STP][UART][ B][W]"); */ -+ /* STP_INFO_FUNC("Write byte %d\n", length); */ -+ -+ if ((stp_core_ctx.sequence.winspace > 0) && -+ (stp_core_ctx.inband_rst_set == 0) && -+ (stp_is_tx_res_available(MTKSTP_HEADER_SIZE + length + MTKSTP_CRC_SIZE))) { -+ /*Make Header */ -+ /* (*sys_dbg_print)("mtk_wcn_stp_send_data 1, txseq = %d, winspace = %d", -+ * stp_core_ctx.sequence.txseq, stp_core_ctx.sequence.winspace); -+ */ -+ mtkstp_header[0] = 0x80 + (stp_core_ctx.sequence.txseq << 3) + stp_core_ctx.sequence.txack; -+ mtkstp_header[1] = (type << 4) + ((length & 0xf00) >> 8); -+ mtkstp_header[2] = length & 0xff; -+ mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; -+ stp_core_ctx.tx_start_addr[stp_core_ctx.sequence.txseq] = stp_core_ctx.tx_write; -+ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] = MTKSTP_HEADER_SIZE + length + 2; -+ if (fgEnableDelimiter == 1) { -+ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] += STP_DEL_SIZE; -+ stp_add_to_tx_queue(&stp_delimiter[0], STP_DEL_SIZE); -+ } -+ stp_add_to_tx_queue(mtkstp_header, MTKSTP_HEADER_SIZE); -+ -+ /*Make Payload */ -+ stp_add_to_tx_queue(buffer, length); -+ -+ /*Make CRC */ -+ crc = osal_crc16(buffer, length); -+ temp[0] = crc & 0xff; -+ temp[1] = (crc & 0xff00) >> 8; -+ stp_add_to_tx_queue(temp, 2); -+ stp_dbg_pkt_log(type, -+ stp_core_ctx.sequence.txack, -+ stp_core_ctx.sequence.txseq, crc, PKT_DIR_TX, buffer, length); -+ -+ /*Kick to UART */ -+ stp_send_tx_queue(stp_core_ctx.sequence.txseq); -+ -+ INDEX_INC(stp_core_ctx.sequence.txseq); -+ stp_core_ctx.sequence.winspace--; -+ -+ /*Setup the Retry Timer */ -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) -+ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); -+ else -+ STP_ERR_FUNC("mtk_wcn_stp_send_data: wmt_stop_timer\n"); -+ -+ ret = (INT32) length; -+ } else { -+ /* -+ No winspace to send. Let caller retry -+ */ -+ if (stp_core_ctx.inband_rst_set == 1) -+ STP_WARN_FUNC("Now it's inband reset process and drop sent packet.\n"); -+ else -+ STP_ERR_FUNC("There is no winspace/txqueue to send !!!\n"); -+ -+ ret = 0; -+ } -+ -+ /* osal_printtimeofday("[ STP][UART][ E][W]"); */ -+ } -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+ -+#ifdef CONFIG_POWER_SAVING_SUPPORT -+ -+ if (MTK_WCN_BOOL_TRUE == is_quick_enable) { -+ if (type != WMT_TASK_INDX) { -+ stp_psm_notify_wmt_sleep(STP_PSM_CORE(stp_core_ctx)); -+ /*-----------------------STP_PSM_UnLock-------------------------*/ -+ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); -+ } -+ } else { -+ /* if(stp_is_apply_powersaving()) */ -+ /* { */ -+ if (type != WMT_TASK_INDX) { -+ -+ /*--------------------STP_PSM_UnLock--------------------------*/ -+ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); -+ } -+ /* } */ -+ } -+#endif -+ -+ return ret; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_send_data); -+#endif -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data_raw -+* DESCRIPTION -+* send raw data to common interface, bypass STP -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 >= 0: length transmitted; < 0: error -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+#else -+INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+#endif -+{ -+ UINT32 written = 0; -+ INT32 ret = 0; -+ -+ if (0 != STP_WMT_LAST_CLOSE(stp_core_ctx)) { -+ STP_ERR_FUNC("WMT lats close,should not have tx request!"); -+ return length; -+ } -+ -+ STP_DBG_FUNC("mtk_wcn_stp_send_data_raw, type = %d, data = %x %x %x %x %x %x ", type, buffer[0], buffer[1], -+ buffer[2], buffer[3], buffer[4], buffer[5]); -+ STP_SET_PENDING_TYPE(stp_core_ctx, type); /* remember tx type, forward following rx to this type */ -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ stp_dbg_pkt_log(type, 0, 0, 0, PKT_DIR_TX, buffer, 1); -+ (*sys_if_tx) (&buffer[0], length, &written); -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+ -+ if (written == 0) -+ stp_dump_data(&buffer[0], "tx raw failed:", length); -+ -+ if (written == length) -+ ret = (INT32) written; -+ else -+ ret = (-1); -+ -+ return ret; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_send_data_raw); -+#endif -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_receive_data -+* DESCRIPTION -+* receive data from serial protocol engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 >= 0: size of data received; < 0: error -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type) -+#else -+INT32 mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type) -+#endif -+{ -+ /* GeorgeKuo modify: reduce "if" branch */ -+ UINT16 copyLen = 0; -+ UINT16 tailLen = 0; -+ -+ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ while (stp_core_ctx.ring[type].read_p != stp_core_ctx.ring[type].write_p) { -+ /* GeorgeKuo modify: reduce if branch */ -+ if (stp_core_ctx.ring[type].write_p > stp_core_ctx.ring[type].read_p) { -+ copyLen = stp_core_ctx.ring[type].write_p - stp_core_ctx.ring[type].read_p; -+ if (copyLen > length) -+ copyLen = length; -+ -+ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, copyLen); -+ stp_core_ctx.ring[type].read_p += copyLen; -+ } else { -+ tailLen = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].read_p; -+ if (tailLen > length) { /* exclude equal case to skip wrap check */ -+ copyLen = length; -+ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, -+ copyLen); -+ stp_core_ctx.ring[type].read_p += copyLen; -+ } else { -+ /* part 1: copy tailLen */ -+ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, -+ tailLen); -+ -+ buffer += tailLen; /* update buffer offset */ -+ -+ /* part 2: check if head length is enough */ -+ copyLen = length - tailLen; -+ copyLen = -+ (stp_core_ctx.ring[type].write_p < -+ copyLen) ? stp_core_ctx.ring[type].write_p : copyLen; -+ -+ if (copyLen) -+ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + 0, copyLen); -+ -+ /* Update read_p final position */ -+ stp_core_ctx.ring[type].read_p = copyLen; -+ -+ /* update return length: head + tail */ -+ copyLen += tailLen; -+ } -+ } -+ break; -+ } -+ -+ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ if ((MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) && (type != WMT_TASK_INDX)) { -+#if PSM_USE_COUNT_PACKAGE -+ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 1); -+#else -+ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 1, copyLen); -+#endif -+ } -+ -+ return copyLen; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_receive_data); -+#endif -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_rxqueue_empty -+* DESCRIPTION -+* Is certain rx queue empty? -+* PARAMETERS -+* type [IN] subfunction type -+* RETURNS -+* INT32 0: queue is NOT empyt; !0: queue is empty -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_is_rxqueue_empty(UINT8 type) -+#else -+INT32 mtk_wcn_stp_is_rxqueue_empty(UINT8 type) -+#endif -+{ -+ INT32 ret; -+ -+ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ if (stp_core_ctx.ring[type].read_p == stp_core_ctx.ring[type].write_p) -+ ret = 1; /* queue is empty */ -+ else -+ ret = 0; /* queue is not empty */ -+ -+ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ return ret; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_is_rxqueue_empty); -+#endif -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_set_sdio_mode -+* DESCRIPTION -+* Set stp for SDIO mode -+* PARAMETERS -+* sdio_flag [IN] sdio mode flag (TRUE:SDIO mode, FALSE:UART mode) -+* RETURNS -+* void -+*****************************************************************************/ -+ -+void mtk_wcn_stp_set_mode(UINT32 mode) -+{ -+ STP_SET_SUPPORT_PROTOCOL(stp_core_ctx, mode); -+ -+ STP_DBG_FUNC("STP_SUPPORT_PROTOCOL = %08x\n", STP_SUPPORT_PROTOCOL(stp_core_ctx)); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_uart_fullset_mode -+* DESCRIPTION -+* Is stp use UART fullset mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:Uart Fullset mode, FALSE:Not UART Fullset mode -+*****************************************************************************/ -+MTK_WCN_BOOL mtk_wcn_stp_is_uart_fullset_mode(void) -+{ -+ /* -+ bit 0: uart fullset mode -+ bit 1: uart mandatory mode -+ bit 2: sdio mode -+ */ -+ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_UART_FULL_MODE) -+ return MTK_WCN_BOOL_TRUE; -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_uart_mand_mode -+* DESCRIPTION -+* Is stp use UART mandatory mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:Uart Mandatory mode, FALSE:Not UART Mandotary mode -+*****************************************************************************/ -+MTK_WCN_BOOL mtk_wcn_stp_is_uart_mand_mode(void) -+{ -+ /* -+ bit 0: uart fullset mode -+ bit 1: uart mandatory mode -+ bit 2: sdio mode -+ */ -+ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_UART_MAND_MODE) -+ return MTK_WCN_BOOL_TRUE; -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_btif_fullset_mode -+* DESCRIPTION -+* Is stp use BTIF fullset mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:BTIF Fullset mode, FALSE:Not BTIF Fullset mode -+*****************************************************************************/ -+MTK_WCN_BOOL mtk_wcn_stp_is_btif_fullset_mode(void) -+{ -+ -+ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_BTIF_FULL_MODE) -+ return MTK_WCN_BOOL_TRUE; -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_btif_mand_mode -+* DESCRIPTION -+* Is stp use BTIF mandatory mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:BTIF Mandatory mode, FALSE:Not BTIF Mandotary mode -+*****************************************************************************/ -+ -+MTK_WCN_BOOL mtk_wcn_stp_is_btif_mand_mode(void) -+{ -+ -+ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_BTIF_MAND_MODE) -+ return MTK_WCN_BOOL_TRUE; -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_sdio_mode -+* DESCRIPTION -+* Is stp use SDIO mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:SDIO mode, FALSE:UART mode -+*****************************************************************************/ -+MTK_WCN_BOOL mtk_wcn_stp_is_sdio_mode(void) -+{ -+ /* -+ bit 0: uart fullset mode -+ bit 1: uart mandatory mode -+ bit 2: sdio mode -+ */ -+ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_SDIO_MODE) -+ return MTK_WCN_BOOL_TRUE; -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_inband_reset -+* DESCRIPTION -+* To sync to oringnal stp state with f/w stp -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+void mtk_wcn_stp_inband_reset(void) -+{ -+ UINT8 inband_reset_packet[64]; -+ UINT32 txseq = 0; -+ UINT32 txack = 0; -+ UINT32 crc = 0; -+ UINT32 ret = 0; -+ UINT32 reset_payload_len = 0; -+ -+ /*512 bytes */ -+ UINT8 reset_payload[] = { -+ 0xc0, 0x01, 0xc0, 0xde, 0x3e, 0xd1, 0xa7, 0xef -+ }; -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ -+ /*RESYNC*/ inband_reset_packet[0] = 0x7f; -+ inband_reset_packet[1] = 0x7f; -+ inband_reset_packet[2] = 0x7f; -+ inband_reset_packet[3] = 0x7f; -+ inband_reset_packet[4] = 0x7f; -+ inband_reset_packet[5] = 0x7f; -+ inband_reset_packet[6] = 0x7f; -+ inband_reset_packet[7] = 0x7f; -+ -+ /*header */ -+ reset_payload_len = sizeof(reset_payload) / sizeof(reset_payload[0]); -+ inband_reset_packet[8] = 0x80 + (txseq << 3) + txack; -+ inband_reset_packet[9] = (STP_TASK_INDX << 4) + ((reset_payload_len & 0xf00) >> 8); -+ inband_reset_packet[10] = reset_payload_len & 0xff; -+ inband_reset_packet[11] = (inband_reset_packet[8] + inband_reset_packet[9] + inband_reset_packet[10]) & 0xff; -+ -+ /*payload */ -+ osal_memcpy(&inband_reset_packet[12], reset_payload, reset_payload_len); -+ -+ /*crc */ -+ crc = osal_crc16(&reset_payload[0], reset_payload_len); -+ inband_reset_packet[12 + reset_payload_len] = crc & 0xff; -+ inband_reset_packet[12 + reset_payload_len + 1] = (crc & 0xff00) >> 8; -+ -+ (*sys_if_tx) (&inband_reset_packet[0], 14 + reset_payload_len, &ret); -+ -+ if (ret != (14 + reset_payload_len)) -+ STP_ERR_FUNC("Inband sending error, sending %d , but ret = %d\n", 10 + reset_payload_len, ret); -+ -+ stp_core_ctx.inband_rst_set = 1; -+ stp_ctx_unlock(&stp_core_ctx); -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+} -+ -+void mtk_wcn_stp_debug_ctrl(INT32 op, INT32 filter, INT32 filter_param) -+{ -+ /*nothing at now*/ -+} -+ -+void mtk_wcn_stp_test_cmd(INT32 cmd_no) -+{ -+ UINT8 test_packet[64]; -+ UINT32 txseq = 0; -+ UINT32 txack = 0; -+ UINT32 crc = 0; -+ UINT32 ret = 0; -+ UINT32 reset_payload_len = 0; -+ -+ UINT8 test_payload[] = { -+ 0xAA, 0xAA, 0xC0, 0xDE, 0x3E, 0xD1, 0xA7, 0xEF -+ }; -+/* */ -+/* select your test command by cmd_no */ -+/* */ -+ if (cmd_no == 0) { -+ /* to test new command to chip */ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ -+ /*RESYNC*/ test_packet[0] = 0x7f; -+ test_packet[1] = 0x7f; -+ test_packet[2] = 0x7f; -+ test_packet[3] = 0x7f; -+ test_packet[4] = 0x7f; -+ test_packet[5] = 0x7f; -+ test_packet[6] = 0x7f; -+ test_packet[7] = 0x7f; -+ -+ /*header */ -+ reset_payload_len = sizeof(test_payload) / sizeof(test_payload[0]); -+ test_packet[8] = 0x80 + (txseq << 3) + txack; -+ test_packet[9] = (STP_TASK_INDX << 4) + ((reset_payload_len & 0xf00) >> 8); -+ test_packet[10] = reset_payload_len & 0xff; -+ test_packet[11] = (test_packet[8] + test_packet[9] + test_packet[10]) & 0xff; -+ -+ /*payload */ -+ osal_memcpy(&test_packet[12], test_payload, reset_payload_len); -+ -+ /*crc */ -+ crc = osal_crc16(&test_payload[0], reset_payload_len); -+ test_packet[12 + reset_payload_len] = crc & 0xff; -+ test_packet[12 + reset_payload_len + 1] = (crc & 0xff00) >> 8; -+ -+ (*sys_if_tx) (&test_packet[0], 14 + reset_payload_len, &ret); -+ if (ret != (14 + reset_payload_len)) { -+ STP_ERR_FUNC("stp test sending error, sending %d , but ret = %d\n", 10 + reset_payload_len, -+ ret); -+ } -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+ } -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_flush_context -+* DESCRIPTION -+* Flush STP Context -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+void mtk_wcn_stp_flush_context(void) -+{ -+ stp_rest_ctx_state(); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_flush_rx_queue -+* DESCRIPTION -+* Flush STP Rx Queue -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+ -+void mtk_wcn_stp_flush_rx_queue(UINT32 type) -+{ -+ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ if (type < MTKSTP_MAX_TASK_NUM) { -+ stp_core_ctx.ring[type].read_p = 0; -+ stp_core_ctx.ring[type].write_p = 0; -+ } -+ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_enable -+* DESCRIPTION -+* STP is ready? -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+MTK_WCN_BOOL _mtk_wcn_stp_is_ready(void) -+#else -+MTK_WCN_BOOL mtk_wcn_stp_is_ready(void) -+#endif -+{ -+ return STP_IS_READY(stp_core_ctx); -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_is_ready); -+#endif -+/***************************************************************************** -+* FUNCTION -+* set_bluetooth_rx_interface -+* DESCRIPTION -+* Set bluetooth rx interface -+* PARAMETERS -+* rx interface type -+* RETURNS -+* void -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+void _mtk_wcn_stp_set_bluez(MTK_WCN_BOOL bluez_flag) -+#else -+void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL bluez_flag) -+#endif -+{ -+ /* g_mtkstp_bluez_flag = bluez_flag; */ -+ STP_SET_BT_STK(stp_core_ctx, bluez_flag); -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_set_bluez); -+#endif -+/***************************************************************************** -+* FUNCTION -+* set stp debugging mdoe -+* DESCRIPTION -+* set stp debugging mdoe -+* PARAMETERS -+* dbg_mode: switch to dbg mode ? -+* RETURNS -+* void -+*****************************************************************************/ -+void mtk_wcn_stp_set_dbg_mode(MTK_WCN_BOOL dbg_mode) -+{ -+ STP_SET_ENABLE_DBG(stp_core_ctx, dbg_mode); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* set stp auto reset mdoe -+* DESCRIPTION -+* set stp auto reset mdoe -+* PARAMETERS -+* auto_rst: switch to auto reset mode ? -+* RETURNS -+* void -+*****************************************************************************/ -+void mtk_wcn_stp_set_auto_rst(MTK_WCN_BOOL auto_rst) -+{ -+ STP_SET_ENABLE_RST(stp_core_ctx, auto_rst); -+} -+ -+INT32 mtk_wcn_stp_notify_sleep_for_thermal(void) -+{ -+ return stp_psm_sleep_for_thermal(STP_PSM_CORE(stp_core_ctx)); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_open_btif -+* DESCRIPTION -+* init btif hw & sw by owner stp -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_open_btif(VOID) -+{ -+ return mtk_wcn_consys_stp_btif_open(); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_open_close -+* DESCRIPTION -+* close btif hw & sw by owner stp -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_close_btif(VOID) -+{ -+ return mtk_wcn_consys_stp_btif_close(); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_rx_cb_register -+* DESCRIPTION -+* register stp rx cb to btif -+* PARAMETERS -+* MTK_WCN_BTIF_RX_CB stp rx handle function -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_rxcb_register(MTK_WCN_BTIF_RX_CB rx_cb) -+{ -+ return mtk_wcn_consys_stp_btif_rx_cb_register(rx_cb); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_tx -+* DESCRIPTION -+* send stp package by btif -+* PARAMETERS -+* pBuf:package buffer pointer,len:package length -+* written_len:package written length -+* RETURNS -+* INT32 package length-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_tx(UINT8 *pBuf, UINT32 len, UINT32 *written_len) -+{ -+ INT32 iRet = -1; -+ -+ iRet = mtk_wcn_consys_stp_btif_tx(pBuf, len, written_len); -+ return iRet; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_wakeup_consys -+* DESCRIPTION -+* STP wakeup consys by btif -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_wakeup_consys(VOID) -+{ -+ /*log wakeup int for debug */ -+ stp_dbg_pkt_log(7, 0, 0, 0, PKT_DIR_TX, NULL, 0); -+ return mtk_wcn_consys_stp_btif_wakeup(); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_dpidle_ctrl -+* DESCRIPTION -+* decide AP enter or exit deep idle -+* PARAMETERS -+* en_flag:1,enter,0,exit -+* RETURNS -+* always 0 -+*****************************************************************************/ -+INT32 mtk_wcn_stp_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag) -+{ -+ mtk_wcn_consys_stp_btif_dpidle_ctrl(en_flag); -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_lpbk_ctrl -+* DESCRIPTION -+* enable stp internal lpbk test or not -+* PARAMETERS -+* mode:1,enable,0,disabel -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode) -+{ -+ return mtk_wcn_consys_stp_btif_lpbk_ctrl(mode); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_logger_ctrl -+* DESCRIPTION -+* dump btif buffer or register status when No ACK or assert occurs -+* PARAMETERS -+* flag:see enum value in ENUM_BTIF_DBG_ID -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_logger_ctrl(ENUM_BTIF_DBG_ID flag) -+{ -+ return mtk_wcn_consys_stp_btif_logger_ctrl(flag); -+} -+ -+VOID mtk_wcn_stp_ctx_save(void) -+{ -+ STP_INFO_FUNC("start ++\n"); -+ mtk_wcn_stp_coredump_start_ctrl(1); -+ stp_psm_set_sleep_disable(stp_core_ctx.psm); -+ STP_INFO_FUNC("exit --\n"); -+} -+ -+VOID mtk_wcn_stp_ctx_restore(void) -+{ -+ STP_INFO_FUNC("start ++\n"); -+ stp_psm_set_sleep_enable(stp_core_ctx.psm); -+ stp_btm_reset_btm_wq(STP_BTM_CORE(stp_core_ctx)); -+ -+ if (STP_IS_ENABLE_RST(stp_core_ctx)) -+ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); -+ else -+ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); -+#if STP_RETRY_OPTIMIZE -+ g_retry_times = 0; -+#endif -+ STP_INFO_FUNC("exit --\n"); -+} -+ -+INT32 mtk_wcn_stp_wmt_evt_err_trg_assert(void) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_coredump_start_get() != 0) { -+ STP_INFO_FUNC("firmware assert has been triggered\n"); -+ return 0; -+ } -+ -+ ret = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx)); -+ if (ret) { -+ STP_ERR_FUNC("evt err trigger assert fail,do chip reset to recovery\n"); -+ -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); -+ if (STP_IS_ENABLE_RST(stp_core_ctx)) -+ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); -+ else -+ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); -+ } -+ -+ return ret; -+} -+ -+VOID mtk_wcn_stp_set_wmt_evt_err_trg_assert(UINT32 value) -+{ -+ STP_INFO_FUNC("set evt err tigger assert flag to %d\n", value); -+ STP_SET_EVT_ERR_ASSERT(stp_core_ctx, value); -+} -+ -+UINT32 mtk_wcn_stp_get_wmt_evt_err_trg_assert(void) -+{ -+ return STP_EVT_ERR_ASSERT(stp_core_ctx); -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c -new file mode 100644 -index 0000000000000..3009bd26df41a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c -@@ -0,0 +1,529 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-CONF]" -+ -+#include "osal_typedef.h" -+/* #include "osal.h" */ -+#include "wmt_lib.h" -+#include "wmt_dev.h" -+#include "wmt_conf.h" -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+struct parse_data { -+ PINT8 name; -+ INT32 (*parser)(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 value); -+ PINT8 (*writer)(P_DEV_WMT pWmtDev, const struct parse_data *data); -+ /*PINT8 param1, *param2, *param3; */ -+ /* TODO:[FixMe][George] CLARIFY WHAT SHOULD BE USED HERE!!! */ -+ PINT8 param1; -+ PINT8 param2; -+ PINT8 param3; -+}; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************* -+*/ -+static INT32 wmt_conf_parse_char(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); -+ -+static PINT8 wmt_conf_write_char(P_DEV_WMT pWmtDev, const struct parse_data *data); -+ -+static INT32 wmt_conf_parse_short(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); -+ -+static PINT8 wmt_conf_write_short(P_DEV_WMT pWmtDev, const struct parse_data *data); -+ -+static INT32 wmt_conf_parse_int(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); -+ -+static PINT8 wmt_conf_write_int(P_DEV_WMT pWmtDev, const struct parse_data *data); -+ -+static INT32 wmt_conf_parse_pair(P_DEV_WMT pWmtDev, const PINT8 pKey, const PINT8 pVal); -+ -+static INT32 wmt_conf_parse(P_DEV_WMT pWmtDev, const PINT8 pInBuf, UINT32 size); -+ -+#define OFFSET(v) ((void *) &((P_DEV_WMT) 0)->v) -+ -+#define CHAR(f) \ -+{ \ -+ #f, \ -+ wmt_conf_parse_char, \ -+ wmt_conf_write_char, \ -+ OFFSET(rWmtGenConf.f), \ -+ NULL, \ -+ NULL \ -+} -+/* #define CHAR(f) _CHAR(f), NULL, NULL} */ -+ -+#define SHORT(f) \ -+{ \ -+ #f, \ -+ wmt_conf_parse_short, \ -+ wmt_conf_write_short, \ -+ OFFSET(rWmtGenConf.f), \ -+ NULL, \ -+ NULL \ -+} -+/* #define SHORT(f) _SHORT(f), NULL, NULL */ -+ -+#define INT(f) \ -+{ \ -+ #f, \ -+ wmt_conf_parse_int, \ -+ wmt_conf_write_int, \ -+ OFFSET(rWmtGenConf.f), \ -+ NULL, \ -+ NULL \ -+} -+/* #define INT(f) _INT(f), NULL, NULL */ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static const struct parse_data wmtcfg_fields[] = { -+ CHAR(coex_wmt_ant_mode), -+ CHAR(coex_wmt_ext_component), -+ CHAR(coex_wmt_wifi_time_ctl), -+ CHAR(coex_wmt_ext_pta_dev_on), -+ CHAR(coex_wmt_filter_mode), -+ -+ CHAR(coex_bt_rssi_upper_limit), -+ CHAR(coex_bt_rssi_mid_limit), -+ CHAR(coex_bt_rssi_lower_limit), -+ CHAR(coex_bt_pwr_high), -+ CHAR(coex_bt_pwr_mid), -+ CHAR(coex_bt_pwr_low), -+ -+ CHAR(coex_wifi_rssi_upper_limit), -+ CHAR(coex_wifi_rssi_mid_limit), -+ CHAR(coex_wifi_rssi_lower_limit), -+ CHAR(coex_wifi_pwr_high), -+ CHAR(coex_wifi_pwr_mid), -+ CHAR(coex_wifi_pwr_low), -+ -+ CHAR(coex_ext_pta_hi_tx_tag), -+ CHAR(coex_ext_pta_hi_rx_tag), -+ CHAR(coex_ext_pta_lo_tx_tag), -+ CHAR(coex_ext_pta_lo_rx_tag), -+ SHORT(coex_ext_pta_sample_t1), -+ SHORT(coex_ext_pta_sample_t2), -+ CHAR(coex_ext_pta_wifi_bt_con_trx), -+ -+ INT(coex_misc_ext_pta_on), -+ INT(coex_misc_ext_feature_set), -+ -+ CHAR(wmt_gps_lna_pin), -+ CHAR(wmt_gps_lna_enable), -+ -+ CHAR(pwr_on_rtc_slot), -+ CHAR(pwr_on_ldo_slot), -+ CHAR(pwr_on_rst_slot), -+ CHAR(pwr_on_off_slot), -+ CHAR(pwr_on_on_slot), -+ CHAR(co_clock_flag), -+ -+ INT(sdio_driving_cfg), -+ -+}; -+ -+#define NUM_WMTCFG_FIELDS (osal_sizeof(wmtcfg_fields) / osal_sizeof(wmtcfg_fields[0])) -+ -+static int wmt_conf_parse_char(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) -+{ -+ PINT8 dst; -+ long res; -+ int ret; -+ -+ dst = (PINT8) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { -+ ret = osal_strtol(pos + 2, 16, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); -+ } else { -+ ret = osal_strtol(pos, 10, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); -+ } -+ return 0; -+} -+ -+static PINT8 wmt_conf_write_char(P_DEV_WMT pWmtDev, const struct parse_data *data) -+{ -+ PINT8 src; -+ INT32 res; -+ PINT8 value; -+ -+ src = (PINT8) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ value = osal_malloc(20); -+ if (value == NULL) -+ return NULL; -+ res = osal_snprintf(value, 20, "0x%x", *src); -+ if (res < 0 || res >= 20) { -+ osal_free(value); -+ return NULL; -+ } -+ value[20 - 1] = '\0'; -+ return value; -+} -+ -+static int wmt_conf_parse_short(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) -+{ -+ PUINT16 dst; -+ long res; -+ int ret; -+ -+ dst = (PINT16) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ /* WMT_INFO_FUNC(">strlen(pos)=%d\n", strlen(pos)); */ -+ -+ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { -+ ret = osal_strtol(pos + 2, 16, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); -+ } else { -+ ret = osal_strtol(pos, 10, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); -+ } -+ -+ return 0; -+} -+ -+static PINT8 wmt_conf_write_short(P_DEV_WMT pWmtDev, const struct parse_data *data) -+{ -+ PINT16 src; -+ INT32 res; -+ PINT8 value; -+ -+ /* TODO: [FixMe][George] FIX COMPILE WARNING HERE! */ -+ src = (PINT16) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ value = osal_malloc(20); -+ if (value == NULL) -+ return NULL; -+ res = osal_snprintf(value, 20, "0x%x", *src); -+ if (res < 0 || res >= 20) { -+ osal_free(value); -+ return NULL; -+ } -+ value[20 - 1] = '\0'; -+ return value; -+} -+ -+static int wmt_conf_parse_int(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) -+{ -+ PUINT32 dst; -+ long res; -+ int ret; -+ -+ dst = (PINT32) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ /* WMT_INFO_FUNC(">strlen(pos)=%d\n", strlen(pos)); */ -+ -+ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { -+ ret = osal_strtol(pos + 2, 16, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); -+ } else { -+ ret = osal_strtol(pos, 10, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); -+ } -+ -+ return 0; -+} -+ -+static PINT8 wmt_conf_write_int(P_DEV_WMT pWmtDev, const struct parse_data *data) -+{ -+ PINT32 src; -+ INT32 res; -+ PINT8 value; -+ -+ src = (PUINT32) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ value = osal_malloc(20); -+ if (value == NULL) -+ return NULL; -+ res = osal_snprintf(value, 20, "0x%x", *src); -+ if (res < 0 || res >= 20) { -+ osal_free(value); -+ return NULL; -+ } -+ value[20 - 1] = '\0'; -+ return value; -+} -+ -+static INT32 wmt_conf_parse_pair(P_DEV_WMT pWmtDev, const PINT8 pKey, const PINT8 pVal) -+{ -+ int i = 0; -+ int ret = 0; -+ -+ /* WMT_INFO_FUNC( DBG_NAME "cfg(%s) val(%s)\n", pKey, pVal); */ -+ -+ for (i = 0; i < NUM_WMTCFG_FIELDS; i++) { -+ const struct parse_data *field = &wmtcfg_fields[i]; -+ -+ if (osal_strcmp(pKey, field->name) != 0) -+ continue; -+ if (field->parser(pWmtDev, field, pVal)) { -+ WMT_ERR_FUNC("failed to parse %s '%s'.\n", pKey, pVal); -+ ret = -1; -+ } -+ break; -+ } -+ if (i == NUM_WMTCFG_FIELDS) { -+ WMT_ERR_FUNC("unknown field '%s'.\n", pKey); -+ ret = -1; -+ } -+ -+ return ret; -+} -+ -+static INT32 wmt_conf_parse(P_DEV_WMT pWmtDev, const PINT8 pInBuf, UINT32 size) -+{ -+ PINT8 pch; -+ PINT8 pBuf; -+ PINT8 pLine; -+ PINT8 pKey; -+ PINT8 pVal; -+ PINT8 pPos; -+ INT32 ret = 0; -+ INT32 i = 0; -+ PINT8 pa = NULL; -+ -+ pBuf = osal_malloc(size); -+ if (!pBuf) -+ return -1; -+ -+ osal_memcpy(pBuf, pInBuf, size); -+ pBuf[size] = '\0'; -+ -+ pch = pBuf; -+ /* pch is to be updated by strsep(). Keep pBuf unchanged!! */ -+ -+#if 0 -+ { -+ PINT8 buf_ptr = pBuf; -+ INT32 k = 0; -+ -+ WMT_INFO_FUNC("%s len=%d", "wmcfg.content:", size); -+ for (k = 0; k < size; k++) { -+ /* if(k%16 == 0) WMT_INFO_FUNC("\n"); */ -+ WMT_INFO_FUNC("%c", buf_ptr[k]); -+ } -+ WMT_INFO_FUNC("--end\n"); -+ } -+#endif -+ -+ while ((pLine = osal_strsep(&pch, "\r\n")) != NULL) { -+ /* pch is updated to the end of pLine by strsep() and updated to '\0' */ -+ /*WMT_INFO_FUNC("strsep offset(%d), char(%d, '%c' )\n", pLine-pBuf, *pLine, *pLine); */ -+ /* parse each line */ -+ -+ /* WMT_INFO_FUNC("==> Line = (%s)\n", pLine); */ -+ -+ if (!*pLine) -+ continue; -+ -+ pVal = osal_strchr(pLine, '='); -+ if (!pVal) { -+ WMT_WARN_FUNC("mal-format cfg string(%s)\n", pLine); -+ continue; -+ } -+ -+ /* |<-pLine->|'='<-pVal->|'\n' ('\0')| */ -+ *pVal = '\0'; /* replace '=' with '\0' to get key */ -+ /* |<-pKey->|'\0'|<-pVal->|'\n' ('\0')| */ -+ pKey = pLine; -+ -+ if ((pVal - pBuf) < size) -+ pVal++; -+ -+ /*key handling */ -+ pPos = pKey; -+ /*skip space characeter */ -+ while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) { -+ if ((pPos - pBuf) >= size) -+ break; -+ pPos++; -+ } -+ /*key head */ -+ pKey = pPos; -+ while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0') && ((*pPos) != '\n')) { -+ if ((pPos - pBuf) >= size) -+ break; -+ pPos++; -+ } -+ /*key tail */ -+ (*pPos) = '\0'; -+ -+ /*value handling */ -+ pPos = pVal; -+ /*skip space characeter */ -+ while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) { -+ if ((pPos - pBuf) >= size) -+ break; -+ pPos++; -+ } -+ /*value head */ -+ pVal = pPos; -+ while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0') && ((*pPos) != '\n')) { -+ if ((pPos - pBuf) >= size) -+ break; -+ pPos++; -+ } -+ /*value tail */ -+ (*pPos) = '\0'; -+ -+ /* WMT_DBG_FUNC("parse (key: #%s#, value: #%s#)\n", pKey, pVal); */ -+ ret = wmt_conf_parse_pair(pWmtDev, pKey, pVal); -+ WMT_DBG_FUNC("parse (%s, %s, %d)\n", pKey, pVal, ret); -+ if (ret) -+ WMT_WARN_FUNC("parse fail (%s, %s, %d)\n", pKey, pVal, ret); -+ } -+ -+ for (i = 0; i < NUM_WMTCFG_FIELDS; i++) { -+ const struct parse_data *field = &wmtcfg_fields[i]; -+ -+ pa = field->writer(pWmtDev, field); -+ if (pa) { -+ WMT_DBG_FUNC("#%d(%s)=>%s\n", i, field->name, pa); -+ osal_free(pa); -+ } else { -+ WMT_ERR_FUNC("failed to parse '%s'.\n", field->name); -+ } -+ } -+ osal_free(pBuf); -+ return 0; -+} -+ -+INT32 wmt_conf_set_cfg_file(const char *name) -+{ -+ if (NULL == name) { -+ WMT_ERR_FUNC("name is NULL\n"); -+ return -1; -+ } -+ if (osal_strlen(name) >= osal_sizeof(gDevWmt.cWmtcfgName)) { -+ WMT_ERR_FUNC("name is too long, length=%d, expect to < %d\n", osal_strlen(name), -+ osal_sizeof(gDevWmt.cWmtcfgName)); -+ return -2; -+ } -+ osal_memset(&gDevWmt.cWmtcfgName[0], 0, osal_sizeof(gDevWmt.cWmtcfgName)); -+ osal_strcpy(&(gDevWmt.cWmtcfgName[0]), name); -+ WMT_ERR_FUNC("WMT config file is set to (%s)\n", &(gDevWmt.cWmtcfgName[0])); -+ -+ return 0; -+} -+ -+INT32 wmt_conf_read_file(VOID) -+{ -+ INT32 ret = -1; -+ -+ osal_memset(&gDevWmt.rWmtGenConf, 0, osal_sizeof(gDevWmt.rWmtGenConf)); -+ osal_memset(&gDevWmt.pWmtCfg, 0, osal_sizeof(gDevWmt.pWmtCfg)); -+ -+#if 1 -+ osal_memset(&gDevWmt.cWmtcfgName[0], 0, osal_sizeof(gDevWmt.cWmtcfgName)); -+ -+ osal_strncat(&(gDevWmt.cWmtcfgName[0]), CUST_CFG_WMT_PREFIX, osal_sizeof(CUST_CFG_WMT_PREFIX)); -+ osal_strncat(&(gDevWmt.cWmtcfgName[0]), CUST_CFG_WMT, osal_sizeof(CUST_CFG_WMT)); -+#endif -+ -+ if (!osal_strlen(&(gDevWmt.cWmtcfgName[0]))) { -+ WMT_ERR_FUNC("empty Wmtcfg name\n"); -+ osal_assert(0); -+ return ret; -+ } -+ WMT_DBG_FUNC("WMT config file:%s\n", &(gDevWmt.cWmtcfgName[0])); -+ if (0 == wmt_dev_patch_get(&gDevWmt.cWmtcfgName[0], (osal_firmware **) &gDevWmt.pWmtCfg, 0)) { -+ /*get full name patch success */ -+ WMT_DBG_FUNC("get full file name(%s) buf(0x%p) size(%d)\n", -+ &gDevWmt.cWmtcfgName[0], gDevWmt.pWmtCfg->data, gDevWmt.pWmtCfg->size); -+ -+ if (0 == wmt_conf_parse(&gDevWmt, (const PINT8)gDevWmt.pWmtCfg->data, gDevWmt.pWmtCfg->size)) { -+ /*config file exists */ -+ gDevWmt.rWmtGenConf.cfgExist = 1; -+ -+ WMT_DBG_FUNC("&gDevWmt.rWmtGenConf=%p\n", &gDevWmt.rWmtGenConf); -+ ret = 0; -+ } else { -+ WMT_ERR_FUNC("wmt conf parsing fail\n"); -+ osal_assert(0); -+ ret = -1; -+ } -+ wmt_dev_patch_put((osal_firmware **) &gDevWmt.pWmtCfg); -+/* -+ if (gDevWmt.pWmtCfg) -+ { -+ if (gDevWmt.pWmtCfg->data) -+ { -+ osal_free(gDevWmt.pWmtCfg->data); -+ } -+ osal_free(gDevWmt.pWmtCfg); -+ gDevWmt.pWmtCfg = 0; -+ } -+*/ -+ return ret; -+ } -+ WMT_ERR_FUNC("read %s file fails\n", &(gDevWmt.cWmtcfgName[0])); -+ osal_assert(0); -+ -+ gDevWmt.rWmtGenConf.cfgExist = 0; -+ return ret; -+} -+ -+P_WMT_GEN_CONF wmt_conf_get_cfg(VOID) -+{ -+ if (0 == gDevWmt.rWmtGenConf.cfgExist) -+ return NULL; -+ -+ return &gDevWmt.rWmtGenConf; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c -new file mode 100644 -index 0000000000000..cca6729d53a07 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c -@@ -0,0 +1,2521 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-CORE]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+ -+#include "wmt_lib.h" -+#include "wmt_core.h" -+#include "wmt_ctrl.h" -+#include "wmt_ic.h" -+#include "wmt_conf.h" -+ -+#include "wmt_func.h" -+#include "stp_core.h" -+#include "psm_core.h" -+ -+ -+P_WMT_FUNC_OPS gpWmtFuncOps[4] = { -+#if CFG_FUNC_BT_SUPPORT -+ [0] = &wmt_func_bt_ops, -+#else -+ [0] = NULL, -+#endif -+ -+#if CFG_FUNC_FM_SUPPORT -+ [1] = &wmt_func_fm_ops, -+#else -+ [1] = NULL, -+#endif -+ -+#if CFG_FUNC_GPS_SUPPORT -+ [2] = &wmt_func_gps_ops, -+#else -+ [2] = NULL, -+#endif -+ -+#if CFG_FUNC_WIFI_SUPPORT -+ [3] = &wmt_func_wifi_ops, -+#else -+ [3] = NULL, -+#endif -+ -+}; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* TODO:[FixMe][GeorgeKuo]: is it an MT6620 only or general general setting? -+*move to wmt_ic_6620 temporarily. -+*/ -+/* BT Port 2 Feature. */ -+/* #define CFG_WMT_BT_PORT2 (1) */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+static WMT_CTX gMtkWmtCtx; -+static UINT8 gLpbkBuf[1024+5] = { 0 }; -+#ifdef CONFIG_MTK_COMBO_ANT -+static UINT8 gAntBuf[1024] = { 0 }; -+#define CFG_CHECK_WMT_RESULT (1) -+#endif -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static INT32 opfunc_hif_conf(P_WMT_OP pWmtOp); -+static INT32 opfunc_pwr_on(P_WMT_OP pWmtOp); -+static INT32 opfunc_pwr_off(P_WMT_OP pWmtOp); -+static INT32 opfunc_func_on(P_WMT_OP pWmtOp); -+static INT32 opfunc_func_off(P_WMT_OP pWmtOp); -+static INT32 opfunc_reg_rw(P_WMT_OP pWmtOp); -+static INT32 opfunc_exit(P_WMT_OP pWmtOp); -+static INT32 opfunc_pwr_sv(P_WMT_OP pWmtOp); -+static INT32 opfunc_dsns(P_WMT_OP pWmtOp); -+static INT32 opfunc_lpbk(P_WMT_OP pWmtOp); -+static INT32 opfunc_cmd_test(P_WMT_OP pWmtOp); -+static INT32 opfunc_hw_rst(P_WMT_OP pWmtOp); -+static INT32 opfunc_sw_rst(P_WMT_OP pWmtOp); -+static INT32 opfunc_stp_rst(P_WMT_OP pWmtOp); -+static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp); -+static INT32 opfunc_efuse_rw(P_WMT_OP pWmtOp); -+static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp); -+static INT32 opfunc_gpio_ctrl(P_WMT_OP pWmtOp); -+static INT32 opfunc_pin_state(P_WMT_OP pWmtOp); -+static INT32 opfunc_bgw_ds(P_WMT_OP pWmtOp); -+static INT32 opfunc_set_mcu_clk(P_WMT_OP pWmtOp); -+static INT32 opfunc_adie_lpbk_test(P_WMT_OP pWmtOp); -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 opfunc_idc_msg_handling(P_WMT_OP pWmtOp); -+#endif -+#ifdef CONFIG_MTK_COMBO_ANT -+static INT32 opfunc_ant_ram_down(P_WMT_OP pWmtOp); -+static INT32 opfunc_ant_ram_stat_get(P_WMT_OP pWmtOp); -+#endif -+static VOID wmt_core_dump_func_state(PINT8 pSource); -+static INT32 wmt_core_stp_init(VOID); -+static INT32 wmt_core_stp_deinit(VOID); -+static INT32 wmt_core_hw_check(VOID); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+static const UINT8 WMT_SLEEP_CMD[] = { 0x01, 0x03, 0x01, 0x00, 0x01 }; -+static const UINT8 WMT_SLEEP_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x01 }; -+ -+static const UINT8 WMT_HOST_AWAKE_CMD[] = { 0x01, 0x03, 0x01, 0x00, 0x02 }; -+static const UINT8 WMT_HOST_AWAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x02 }; -+ -+static const UINT8 WMT_WAKEUP_CMD[] = { 0xFF }; -+static const UINT8 WMT_WAKEUP_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; -+ -+static UINT8 WMT_THERM_CMD[] = { 0x01, 0x11, 0x01, 0x00, -+ 0x00 /*thermal sensor operation */ -+}; -+static UINT8 WMT_THERM_CTRL_EVT[] = { 0x02, 0x11, 0x01, 0x00, 0x00 }; -+static UINT8 WMT_THERM_READ_EVT[] = { 0x02, 0x11, 0x02, 0x00, 0x00, 0x00 }; -+ -+static UINT8 WMT_EFUSE_CMD[] = { 0x01, 0x0D, 0x08, 0x00, -+ 0x01, /*[4]operation, 0:init, 1:write 2:read */ -+ 0x01, /*[5]Number of register setting */ -+ 0xAA, 0xAA, /*[6-7]Address */ -+ 0xBB, 0xBB, 0xBB, 0xBB /*[8-11] Value */ -+}; -+ -+static UINT8 WMT_EFUSE_EVT[] = { 0x02, 0x0D, 0x08, 0x00, -+ 0xAA, /*[4]operation, 0:init, 1:write 2:read */ -+ 0xBB, /*[5]Number of register setting */ -+ 0xCC, 0xCC, /*[6-7]Address */ -+ 0xDD, 0xDD, 0xDD, 0xDD /*[8-11] Value */ -+}; -+ -+static UINT8 WMT_DSNS_CMD[] = { 0x01, 0x0E, 0x02, 0x00, 0x01, -+ 0x00 /*desnse type */ -+}; -+static UINT8 WMT_DSNS_EVT[] = { 0x02, 0x0E, 0x01, 0x00, 0x00 }; -+ -+/* TODO:[NewFeature][GeorgeKuo] Update register group in ONE CMD/EVT */ -+static UINT8 WMT_SET_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x00 /*op: w(1) & r(2) */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*res */ -+ , 0x01 /*1 register */ -+ , 0x00, 0x00, 0x00, 0x00 /* addr */ -+ , 0x00, 0x00, 0x00, 0x00 /* value */ -+ , 0xFF, 0xFF, 0xFF, 0xFF /*mask */ -+}; -+ -+static UINT8 WMT_SET_REG_WR_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 register */ -+ /* , 0x00, 0x00, 0x00, 0x00 */ /* addr */ -+ /* , 0x00, 0x00, 0x00, 0x00 */ /* value */ -+}; -+ -+static UINT8 WMT_SET_REG_RD_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 register */ -+ , 0x00, 0x00, 0x00, 0x00 /* addr */ -+ , 0x00, 0x00, 0x00, 0x00 /* value */ -+}; -+ -+#ifdef CONFIG_MTK_COMBO_ANT -+static UINT8 WMT_ANT_RAM_STA_GET_CMD[] = { 0x01, 0x06, 0x02, 0x00, 0x05, 0x02 -+}; -+ -+static UINT8 WMT_ANT_RAM_STA_GET_EVT[] = { 0x02, 0x06, 0x03, 0x00 /*length */ -+ , 0x05, 0x02, 0x00 /*S: result */ -+}; -+ -+static UINT8 WMT_ANT_RAM_DWN_CMD[] = { 0x01, 0x15, 0x00, 0x00, 0x01 -+}; -+ -+static UINT8 WMT_ANT_RAM_DWN_EVT[] = { 0x02, 0x15, 0x01, 0x00 /*length */ -+ , 0x00 -+}; -+#endif -+ -+/* GeorgeKuo: Use designated initializers described in -+ * http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Designated-Inits.html -+ */ -+ -+static const WMT_OPID_FUNC wmt_core_opfunc[] = { -+ [WMT_OPID_HIF_CONF] = opfunc_hif_conf, -+ [WMT_OPID_PWR_ON] = opfunc_pwr_on, -+ [WMT_OPID_PWR_OFF] = opfunc_pwr_off, -+ [WMT_OPID_FUNC_ON] = opfunc_func_on, -+ [WMT_OPID_FUNC_OFF] = opfunc_func_off, -+ [WMT_OPID_REG_RW] = opfunc_reg_rw, /* TODO:[ChangeFeature][George] is this OP obsoleted? */ -+ [WMT_OPID_EXIT] = opfunc_exit, -+ [WMT_OPID_PWR_SV] = opfunc_pwr_sv, -+ [WMT_OPID_DSNS] = opfunc_dsns, -+ [WMT_OPID_LPBK] = opfunc_lpbk, -+ [WMT_OPID_CMD_TEST] = opfunc_cmd_test, -+ [WMT_OPID_HW_RST] = opfunc_hw_rst, -+ [WMT_OPID_SW_RST] = opfunc_sw_rst, -+ [WMT_OPID_STP_RST] = opfunc_stp_rst, -+ [WMT_OPID_THERM_CTRL] = opfunc_therm_ctrl, -+ [WMT_OPID_EFUSE_RW] = opfunc_efuse_rw, -+ [WMT_OPID_GPIO_CTRL] = opfunc_gpio_ctrl, -+ [WMT_OPID_GPIO_STATE] = opfunc_pin_state, -+ [WMT_OPID_BGW_DS] = opfunc_bgw_ds, -+ [WMT_OPID_SET_MCU_CLK] = opfunc_set_mcu_clk, -+ [WMT_OPID_ADIE_LPBK_TEST] = opfunc_adie_lpbk_test, -+#if CFG_WMT_LTE_COEX_HANDLING -+ [WMT_OPID_IDC_MSG_HANDLING] = opfunc_idc_msg_handling, -+#endif -+#ifdef CONFIG_MTK_COMBO_ANT -+ [WMT_OPID_ANT_RAM_DOWN] = opfunc_ant_ram_down, -+ [WMT_OPID_ANT_RAM_STA_GET] = opfunc_ant_ram_stat_get, -+#endif -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+INT32 wmt_core_init(VOID) -+{ -+ INT32 i = 0; -+ -+ osal_memset(&gMtkWmtCtx, 0, osal_sizeof(gMtkWmtCtx)); -+ /* gMtkWmtCtx.p_ops is cleared to NULL */ -+ -+ /* default FUNC_OFF state */ -+ for (i = 0; i < WMTDRV_TYPE_MAX; ++i) { -+ /* WinMo is default to DRV_STS_UNREG; */ -+ gMtkWmtCtx.eDrvStatus[i] = DRV_STS_POWER_OFF; -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_core_deinit(VOID) -+{ -+ /* return to init state */ -+ osal_memset(&gMtkWmtCtx, 0, osal_sizeof(gMtkWmtCtx)); -+ /* gMtkWmtCtx.p_ops is cleared to NULL */ -+ return 0; -+} -+ -+/* TODO: [ChangeFeature][George] Is wmt_ctrl a good interface? maybe not...... */ -+/* parameters shall be copied in/from ctrl buffer, which is also a size-wasting buffer. */ -+INT32 wmt_core_tx(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag) -+{ -+ INT32 iRet; -+#if 0 /* Test using direct function call instead of wmt_ctrl() interface */ -+ WMT_CTRL_DATA ctrlData; -+ -+ ctrlData.ctrlId = WMT_CTRL_TX; -+ ctrlData.au4CtrlData[0] = (UINT32) pData; -+ ctrlData.au4CtrlData[1] = size; -+ ctrlData.au4CtrlData[2] = (UINT32) writtenSize; -+ ctrlData.au4CtrlData[3] = bRawFlag; -+ -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /* ERROR */ -+ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_TX, iRet:%d\n", iRet); -+ /* (*sys_dbg_assert)(0, __FILE__, __LINE__); */ -+ osal_assert(0); -+ } -+#endif -+ iRet = wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); -+ if (0 == *writtenSize) { -+ INT32 retry_times = 0; -+ INT32 max_retry_times = 3; -+ INT32 retry_delay_ms = 360; -+ -+ WMT_WARN_FUNC("WMT-CORE: wmt_ctrl_tx_ex failed and written ret:%d, maybe no winspace in STP layer\n", -+ *writtenSize); -+ while ((0 == *writtenSize) && (retry_times < max_retry_times)) { -+ WMT_ERR_FUNC("WMT-CORE: retrying, wait for %d ms\n", retry_delay_ms); -+ osal_sleep_ms(retry_delay_ms); -+ -+ iRet = wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); -+ retry_times++; -+ } -+ } -+ return iRet; -+} -+ -+INT32 wmt_core_rx(PUINT8 pBuf, UINT32 bufLen, UINT32 *readSize) -+{ -+ INT32 iRet; -+ WMT_CTRL_DATA ctrlData; -+ -+ ctrlData.ctrlId = WMT_CTRL_RX; -+ ctrlData.au4CtrlData[0] = (SIZE_T) pBuf; -+ ctrlData.au4CtrlData[1] = bufLen; -+ ctrlData.au4CtrlData[2] = (SIZE_T) readSize; -+ -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /* ERROR */ -+ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_RX, iRet:%d\n", iRet); -+ mtk_wcn_stp_dbg_dump_package(); -+ osal_assert(0); -+ } -+ return iRet; -+} -+ -+INT32 wmt_core_rx_flush(UINT32 type) -+{ -+ INT32 iRet; -+ WMT_CTRL_DATA ctrlData; -+ -+ ctrlData.ctrlId = WMT_CTRL_RX_FLUSH; -+ ctrlData.au4CtrlData[0] = (UINT32) type; -+ -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /* ERROR */ -+ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_RX_FLUSH, iRet:%d\n", iRet); -+ osal_assert(0); -+ } -+ return iRet; -+} -+ -+INT32 wmt_core_func_ctrl_cmd(ENUM_WMTDRV_TYPE_T type, MTK_WCN_BOOL fgEn) -+{ -+ INT32 iRet = 0; -+ UINT32 u4WmtCmdPduLen; -+ UINT32 u4WmtEventPduLen; -+ UINT32 u4ReadSize; -+ UINT32 u4WrittenSize; -+ WMT_PKT rWmtPktCmd; -+ WMT_PKT rWmtPktEvent; -+ MTK_WCN_BOOL fgFail; -+ -+ /* TODO:[ChangeFeature][George] remove WMT_PKT. replace it with hardcoded arrays. */ -+ /* Using this struct relies on compiler's implementation and pack() settings */ -+ osal_memset(&rWmtPktCmd, 0, osal_sizeof(rWmtPktCmd)); -+ osal_memset(&rWmtPktEvent, 0, osal_sizeof(rWmtPktEvent)); -+ -+ rWmtPktCmd.eType = (UINT8) PKT_TYPE_CMD; -+ rWmtPktCmd.eOpCode = (UINT8) OPCODE_FUNC_CTRL; -+ -+ /* Flag field: driver type */ -+ rWmtPktCmd.aucParam[0] = (UINT8) type; -+ /* Parameter field: ON/OFF */ -+ rWmtPktCmd.aucParam[1] = (fgEn == WMT_FUNC_CTRL_ON) ? 1 : 0; -+ rWmtPktCmd.u2SduLen = WMT_FLAG_LEN + WMT_FUNC_CTRL_PARAM_LEN; /* (2) */ -+ -+ /* WMT Header + WMT SDU */ -+ u4WmtCmdPduLen = WMT_HDR_LEN + rWmtPktCmd.u2SduLen; /* (6) */ -+ u4WmtEventPduLen = WMT_HDR_LEN + WMT_STS_LEN; /* (5) */ -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+/* iRet = (*kal_stp_tx)((PUINT8)&rWmtPktCmd, u4WmtCmdPduLen, &u4WrittenSize); */ -+ iRet = wmt_core_tx((PUINT8) &rWmtPktCmd, u4WmtCmdPduLen, &u4WrittenSize, MTK_WCN_BOOL_FALSE); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd kal_stp_tx failed\n"); -+ break; -+ } -+ -+ iRet = wmt_core_rx((PUINT8) &rWmtPktEvent, u4WmtEventPduLen, &u4ReadSize); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd kal_stp_rx failed\n"); -+ break; -+ } -+ -+ /* Error Checking */ -+ if (PKT_TYPE_EVENT != rWmtPktEvent.eType) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd PKT_TYPE_EVENT != rWmtPktEvent.eType %d\n", -+ rWmtPktEvent.eType); -+ break; -+ } -+ -+ if (rWmtPktCmd.eOpCode != rWmtPktEvent.eOpCode) { -+ WMT_ERR_FUNC -+ ("WMT-CORE: wmt_func_ctrl_cmd rWmtPktCmd.eOpCode(0x%x) != rWmtPktEvent.eType(0x%x)\n", -+ rWmtPktCmd.eOpCode, rWmtPktEvent.eOpCode); -+ break; -+ } -+ -+ if (u4WmtEventPduLen != (rWmtPktEvent.u2SduLen + WMT_HDR_LEN)) { -+ WMT_ERR_FUNC -+ ("WMT-CORE: wmt_func_ctrl_cmd u4WmtEventPduLen(0x%x) != rWmtPktEvent.u2SduLen(0x%x)+4\n", -+ u4WmtEventPduLen, rWmtPktEvent.u2SduLen); -+ break; -+ } -+ /* Status field of event check */ -+ if (0 != rWmtPktEvent.aucParam[0]) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd, 0 != status(%d)\n", rWmtPktEvent.aucParam[0]); -+ break; -+ } -+ -+ fgFail = MTK_WCN_BOOL_FALSE; -+ } while (0); -+ -+ if (MTK_WCN_BOOL_FALSE == fgFail) { -+ /* WMT_INFO_FUNC("WMT-CORE: wmt_func_ctrl_cmd OK!\n"); */ -+ return 0; -+ } -+ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd 0x%x FAIL\n", rWmtPktCmd.aucParam[0]); -+ return -3; -+} -+ -+INT32 wmt_core_opid_handler(P_WMT_OP pWmtOp) -+{ -+ UINT32 opId; -+ INT32 ret; -+ -+ opId = pWmtOp->opId; -+ -+ if (wmt_core_opfunc[opId]) { -+ ret = (*(wmt_core_opfunc[opId])) (pWmtOp); /*wmtCoreOpidHandlerPack[].opHandler */ -+ return ret; -+ } -+ WMT_ERR_FUNC("WMT-CORE: null handler (%d)\n", pWmtOp->opId); -+ return -2; -+ -+} -+ -+INT32 wmt_core_opid(P_WMT_OP pWmtOp) -+{ -+ -+ /*sanity check */ -+ if (NULL == pWmtOp) { -+ WMT_ERR_FUNC("null pWmtOP\n"); -+ /*print some message with error info */ -+ return -1; -+ } -+ -+ if (WMT_OPID_MAX <= pWmtOp->opId) { -+ WMT_ERR_FUNC("WMT-CORE: invalid OPID(%d)\n", pWmtOp->opId); -+ return -2; -+ } -+ /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ -+ return wmt_core_opid_handler(pWmtOp); -+} -+ -+INT32 wmt_core_ctrl(ENUM_WMT_CTRL_T ctrId, unsigned long *pPa1, unsigned long *pPa2) -+{ -+ INT32 iRet = -1; -+ WMT_CTRL_DATA ctrlData; -+ SIZE_T val1 = (pPa1) ? *pPa1 : 0; -+ SIZE_T val2 = (pPa2) ? *pPa2 : 0; -+ -+ ctrlData.ctrlId = (SIZE_T) ctrId; -+ ctrlData.au4CtrlData[0] = val1; -+ ctrlData.au4CtrlData[1] = val2; -+ -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /* ERROR */ -+ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: id(%d), type(%d), value(%d) iRet:(%d)\n", ctrId, val1, -+ val2, iRet); -+ osal_assert(0); -+ } else { -+ if (pPa1) -+ *pPa1 = ctrlData.au4CtrlData[0]; -+ if (pPa2) -+ *pPa2 = ctrlData.au4CtrlData[1]; -+ } -+ return iRet; -+} -+ -+VOID wmt_core_dump_data(PUINT8 pData, PUINT8 pTitle, UINT32 len) -+{ -+ PUINT8 ptr = pData; -+ INT32 k = 0; -+ -+ WMT_INFO_FUNC("%s len=%d\n", pTitle, len); -+ for (k = 0; k < len; k++) { -+ if (k % 16 == 0) -+ WMT_INFO_FUNC("\n"); -+ WMT_INFO_FUNC("0x%02x ", *ptr); -+ ptr++; -+ } -+ WMT_INFO_FUNC("--end\n"); -+} -+ -+/*! -+ * \brief An WMT-CORE function to support read, write, and read after write to -+ * an internal register. -+ * -+ * Detailed description. -+ * -+ * \param isWrite 1 for write, 0 for read -+ * \param offset of register to be written or read -+ * \param pVal a pointer to the 32-bit value to be writtern or read -+ * \param mask a 32-bit mask to be applied for the read or write operation -+ * -+ * \retval 0 operation success -+ * \retval -1 invalid parameters -+ * \retval -2 tx cmd fail -+ * \retval -3 rx event fail -+ * \retval -4 read check error -+ */ -+INT32 wmt_core_reg_rw_raw(UINT32 isWrite, UINT32 offset, PUINT32 pVal, UINT32 mask) -+{ -+ INT32 iRet; -+ UINT32 u4Res; -+ UINT32 evtLen; -+ UINT8 evtBuf[16] = { 0 }; -+ -+ WMT_SET_REG_CMD[4] = (isWrite) ? 0x1 : 0x2; /* w:1, r:2 */ -+ osal_memcpy(&WMT_SET_REG_CMD[8], &offset, 4); /* offset */ -+ osal_memcpy(&WMT_SET_REG_CMD[12], pVal, 4); /* [2] is var addr */ -+ osal_memcpy(&WMT_SET_REG_CMD[16], &mask, 4); /* mask */ -+ -+ /* send command */ -+ iRet = wmt_core_tx(WMT_SET_REG_CMD, sizeof(WMT_SET_REG_CMD), &u4Res, MTK_WCN_BOOL_FALSE); -+ if ((iRet) || (u4Res != sizeof(WMT_SET_REG_CMD))) { -+ WMT_ERR_FUNC("Tx REG_CMD fail!(%d) len (%d, %d)\n", iRet, u4Res, sizeof(WMT_SET_REG_CMD)); -+ return -2; -+ } -+ -+ /* receive event */ -+ evtLen = (isWrite) ? sizeof(WMT_SET_REG_WR_EVT) : sizeof(WMT_SET_REG_RD_EVT); -+ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); -+ if ((iRet) || (u4Res != evtLen)) { -+ WMT_ERR_FUNC("Rx REG_EVT fail!(%d) len(%d, %d)\n", iRet, u4Res, evtLen); -+ return -3; -+ } -+ -+ if (!isWrite) { -+ UINT32 rxEvtAddr; -+ UINT32 txCmdAddr; -+ -+ osal_memcpy(&txCmdAddr, &WMT_SET_REG_CMD[8], 4); -+ osal_memcpy(&rxEvtAddr, &evtBuf[8], 4); -+ -+ /* check read result */ -+ if (txCmdAddr != rxEvtAddr) { -+ WMT_ERR_FUNC("Check read addr fail (0x%08x, 0x%08x)\n", rxEvtAddr, txCmdAddr); -+ return -4; -+ } -+ WMT_DBG_FUNC("Check read addr(0x%08x) ok\n", rxEvtAddr); -+ -+ osal_memcpy(pVal, &evtBuf[12], 4); -+ } -+ -+ /* no error here just return 0 */ -+ return 0; -+} -+ -+INT32 wmt_core_init_script(struct init_script *script, INT32 count) -+{ -+ UINT8 evtBuf[256]; -+ UINT32 u4Res; -+ INT32 i = 0; -+ INT32 iRet; -+ -+ for (i = 0; i < count; i++) { -+ WMT_DBG_FUNC("WMT-CORE: init_script operation %s start\n", script[i].str); -+ /* CMD */ -+ /* iRet = (*kal_stp_tx)(script[i].cmd, script[i].cmdSz, &u4Res); */ -+ iRet = wmt_core_tx(script[i].cmd, script[i].cmdSz, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != script[i].cmdSz)) { -+ WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", script[i].str, iRet, u4Res, -+ script[i].cmdSz); -+ break; -+ } -+ /* EVENT BUF */ -+ osal_memset(evtBuf, 0, sizeof(evtBuf)); -+ iRet = wmt_core_rx(evtBuf, script[i].evtSz, &u4Res); -+ if (iRet || (u4Res != script[i].evtSz)) { -+ WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", script[i].str, iRet, -+ u4Res, script[i].evtSz); -+ mtk_wcn_stp_dbg_dump_package(); -+ break; -+ } -+ /* RESULT */ -+ if (0x14 != evtBuf[1]) { /* workaround RF calibration data EVT,do not care this EVT */ -+ if (osal_memcmp(evtBuf, script[i].evt, script[i].evtSz) != 0) { -+ WMT_ERR_FUNC("WMT-CORE:compare %s result error\n", script[i].str); -+ WMT_ERR_FUNC -+ ("WMT-CORE:rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], script[i].evtSz, -+ script[i].evt[0], script[i].evt[1], script[i].evt[2], script[i].evt[3], -+ script[i].evt[4]); -+ mtk_wcn_stp_dbg_dump_package(); -+ break; -+ } -+ } -+ WMT_DBG_FUNC("init_script operation %s ok\n", script[i].str); -+ } -+ -+ return (i == count) ? 0 : -1; -+} -+ -+static INT32 wmt_core_stp_init(VOID) -+{ -+ INT32 iRet = -1; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ UINT8 co_clock_type; -+ P_WMT_CTX pctx = &gMtkWmtCtx; -+ P_WMT_GEN_CONF pWmtGenConf = NULL; -+ -+ wmt_conf_read_file(); -+ pWmtGenConf = wmt_conf_get_cfg(); -+ if (!(pctx->wmtInfoBit & WMT_OP_HIF_BIT)) { -+ WMT_ERR_FUNC("WMT-CORE: no hif info!\n"); -+ osal_assert(0); -+ return -1; -+ } -+ /* 4 <1> open stp */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_OPEN, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); -+ return -2; -+ } -+ /* 4 <1.5> disable and un-ready stp */ -+ ctrlPa1 = WMT_STP_CONF_EN; -+ ctrlPa2 = 0; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = WMT_STP_CONF_RDY; -+ ctrlPa2 = 0; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ -+ /* 4 <2> set mode and enable */ -+ if (WMT_HIF_BTIF == pctx->wmtHifConf.hifType) { -+ ctrlPa1 = WMT_STP_CONF_MODE; -+ ctrlPa2 = MTKSTP_BTIF_MAND_MODE; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ } -+ -+ ctrlPa1 = WMT_STP_CONF_EN; -+ ctrlPa2 = 1; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: stp_init <1><2> fail:%d\n", iRet); -+ return -3; -+ } -+ /* TODO: [ChangeFeature][GeorgeKuo] can we apply raise UART baud rate firstly for ALL supported chips??? */ -+ -+ iRet = wmt_core_hw_check(); -+ if (iRet) { -+ WMT_ERR_FUNC("hw_check fail:%d\n", iRet); -+ return -4; -+ } -+ /* mtkWmtCtx.p_ic_ops is identified and checked ok */ -+ if ((NULL != pctx->p_ic_ops->co_clock_ctrl) && (pWmtGenConf != NULL)) { -+ co_clock_type = (pWmtGenConf->co_clock_flag & 0x0f); -+ (*(pctx->p_ic_ops->co_clock_ctrl)) (co_clock_type == 0 ? WMT_CO_CLOCK_DIS : WMT_CO_CLOCK_EN); -+ } else { -+ WMT_WARN_FUNC("pctx->p_ic_ops->co_clock_ctrl(0x%x), pWmtGenConf(0x%x)\n", pctx->p_ic_ops->co_clock_ctrl, -+ pWmtGenConf); -+ } -+ osal_assert(NULL != pctx->p_ic_ops->sw_init); -+ if (NULL != pctx->p_ic_ops->sw_init) { -+ iRet = (*(pctx->p_ic_ops->sw_init)) (&pctx->wmtHifConf); -+ } else { -+ WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init is NULL\n"); -+ return -5; -+ } -+ if (iRet) { -+ WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init fail:%d\n", iRet); -+ return -6; -+ } -+ /* 4 <10> set stp ready */ -+ ctrlPa1 = WMT_STP_CONF_RDY; -+ ctrlPa2 = 1; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ -+ return iRet; -+} -+ -+static INT32 wmt_core_stp_deinit(VOID) -+{ -+ INT32 iRet; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ WMT_DBG_FUNC(" start\n"); -+ -+ if (NULL == gMtkWmtCtx.p_ic_ops) { -+ WMT_WARN_FUNC("gMtkWmtCtx.p_ic_ops is NULL\n"); -+ goto deinit_ic_ops_done; -+ } -+ if (NULL != gMtkWmtCtx.p_ic_ops->sw_deinit) { -+ iRet = (*(gMtkWmtCtx.p_ic_ops->sw_deinit)) (&gMtkWmtCtx.wmtHifConf); -+ /* unbind WMT-IC */ -+ gMtkWmtCtx.p_ic_ops = NULL; -+ } else { -+ WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init is NULL\n"); -+ } -+ -+deinit_ic_ops_done: -+ -+ /* 4 <1> un-ready, disable, and close stp. */ -+ ctrlPa1 = WMT_STP_CONF_RDY; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = WMT_STP_CONF_EN; -+ ctrlPa2 = 0; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); -+ -+ if (iRet) -+ WMT_WARN_FUNC("end with fail:%d\n", iRet); -+ -+ return iRet; -+} -+ -+static VOID wmt_core_dump_func_state(PINT8 pSource) -+{ -+ WMT_WARN_FUNC("[%s]status(b:%d f:%d g:%d w:%d lpbk:%d coredump:%d wmt:%d stp:%d)\n", -+ (pSource == NULL ? (PINT8) "CORE" : pSource), -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT], gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_STP] -+ ); -+ return; -+ -+} -+ -+MTK_WCN_BOOL wmt_core_patch_check(UINT32 u4PatchVer, UINT32 u4HwVer) -+{ -+ if (MAJORNUM(u4HwVer) != MAJORNUM(u4PatchVer)) { -+ /*major no. does not match */ -+ WMT_ERR_FUNC("WMT-CORE: chip version(0x%d) does not match patch version(0x%d)\n", u4HwVer, u4PatchVer); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+static INT32 wmt_core_hw_check(VOID) -+{ -+ UINT32 chipid; -+ P_WMT_IC_OPS p_ops; -+ INT32 iret; -+ -+ /* 1. get chip id */ -+ chipid = 0; -+ WMT_LOUD_FUNC("before read hwcode (chip id)\n"); -+ iret = wmt_core_reg_rw_raw(0, GEN_HCR, &chipid, GEN_HCR_MASK); /* read 0x80000008 */ -+ if (iret) { -+ WMT_ERR_FUNC("get hwcode (chip id) fail (%d)\n", iret); -+ return -2; -+ } -+ WMT_DBG_FUNC("get hwcode (chip id) (0x%x)\n", chipid); -+ -+ /* TODO:[ChangeFeature][George]: use a better way to select a correct ops table based on chip id */ -+ switch (chipid) { -+#if CFG_CORE_MT6620_SUPPORT -+ case 0x6620: -+ p_ops = &wmt_ic_ops_mt6620; -+ break; -+#endif -+#if CFG_CORE_MT6628_SUPPORT -+ case 0x6628: -+ p_ops = &wmt_ic_ops_mt6628; -+ break; -+#endif -+#if CFG_CORE_SOC_SUPPORT -+ case 0x6572: -+ case 0x6582: -+ case 0x6592: -+ case 0x8127: -+ case 0x6571: -+ case 0x6752: -+ case 0x0279: -+ case 0x0326: -+ case 0x0321: -+ case 0x0335: -+ case 0x0337: -+ case 0x8163: -+ case 0x6580: -+ p_ops = &wmt_ic_ops_soc; -+ break; -+#endif -+ default: -+ p_ops = (P_WMT_IC_OPS) NULL; -+#if CFG_CORE_SOC_SUPPORT -+ if (0x7f90 == chipid - 0x600) { -+ p_ops = &wmt_ic_ops_soc; -+ chipid -= 0xf6d; -+ } -+#endif -+ break; -+ } -+ -+ if (NULL == p_ops) { -+ WMT_ERR_FUNC("unsupported chip id (hw_code): 0x%x\n", chipid); -+ return -3; -+ } else if (MTK_WCN_BOOL_FALSE == wmt_core_ic_ops_check(p_ops)) { -+ WMT_ERR_FUNC -+ ("chip id(0x%x) with null operation fp: init(0x%p), deinit(0x%p), pin_ctrl(0x%p), ver_chk(0x%p)\n", -+ chipid, p_ops->sw_init, p_ops->sw_deinit, p_ops->ic_pin_ctrl, p_ops->ic_ver_check); -+ return -4; -+ } -+ WMT_DBG_FUNC("chip id(0x%x) fp: init(0x%p), deinit(0x%p), pin_ctrl(0x%p), ver_chk(0x%p)\n", -+ chipid, p_ops->sw_init, p_ops->sw_deinit, p_ops->ic_pin_ctrl, p_ops->ic_ver_check); -+ -+ wmt_ic_ops_soc.icId = chipid; -+ WMT_DBG_FUNC("wmt_ic_ops_soc.icId(0x%x)\n", wmt_ic_ops_soc.icId); -+ iret = p_ops->ic_ver_check(); -+ if (iret) { -+ WMT_ERR_FUNC("chip id(0x%x) ver_check error:%d\n", chipid, iret); -+ return -5; -+ } -+ -+ WMT_DBG_FUNC("chip id(0x%x) ver_check ok\n", chipid); -+ gMtkWmtCtx.p_ic_ops = p_ops; -+ return 0; -+} -+ -+static INT32 opfunc_hif_conf(P_WMT_OP pWmtOp) -+{ -+ if (!(pWmtOp->u4InfoBit & WMT_OP_HIF_BIT)) { -+ WMT_ERR_FUNC("WMT-CORE: no HIF_BIT in WMT_OP!\n"); -+ return -1; -+ } -+ -+ if (gMtkWmtCtx.wmtInfoBit & WMT_OP_HIF_BIT) { -+ WMT_ERR_FUNC("WMT-CORE: WMT HIF already exist. overwrite! old (%d), new(%d))\n", -+ gMtkWmtCtx.wmtHifConf.hifType, pWmtOp->au4OpData[0]); -+ } else { -+ gMtkWmtCtx.wmtInfoBit |= WMT_OP_HIF_BIT; -+ WMT_ERR_FUNC("WMT-CORE: WMT HIF info added\n"); -+ } -+ -+ osal_memcpy(&gMtkWmtCtx.wmtHifConf, &pWmtOp->au4OpData[0], osal_sizeof(gMtkWmtCtx.wmtHifConf)); -+ return 0; -+ -+} -+ -+static INT32 opfunc_pwr_on(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ INT32 retry = WMT_PWRON_RTY_DFT; -+ -+ if (DRV_STS_POWER_OFF != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_ERR_FUNC("WMT-CORE: already powered on, WMT DRV_STS_[0x%x]\n", -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]); -+ osal_assert(0); -+ return -1; -+ } -+ /* TODO: [FixMe][GeorgeKuo]: clarify the following is reqiured or not! */ -+ if (pWmtOp->u4InfoBit & WMT_OP_HIF_BIT) -+ opfunc_hif_conf(pWmtOp); -+ -+pwr_on_rty: -+ /* power on control */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_ON, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: WMT_CTRL_HW_PWR_ON fail iRet(%d)\n", iRet); -+ if (0 == retry--) { -+ WMT_INFO_FUNC("WMT-CORE: retry (%d)\n", retry); -+ goto pwr_on_rty; -+ } -+ return -1; -+ } -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; -+ -+ /* init stp */ -+ iRet = wmt_core_stp_init(); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_core_stp_init fail (%d)\n", iRet); -+ osal_assert(0); -+ -+ /* deinit stp */ -+ iRet = wmt_core_stp_deinit(); -+ iRet = opfunc_pwr_off(pWmtOp); -+ if (iRet) -+ WMT_ERR_FUNC("WMT-CORE: opfunc_pwr_off fail during pwr_on retry\n"); -+ -+ if (0 < retry--) { -+ WMT_INFO_FUNC("WMT-CORE: retry (%d)\n", retry); -+ goto pwr_on_rty; -+ } -+ iRet = -2; -+ return iRet; -+ } -+ -+ WMT_DBG_FUNC("WMT-CORE: WMT [FUNC_ON]\n"); -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_FUNC_ON; -+ -+ /* What to do when state is changed from POWER_OFF to POWER_ON? -+ * 1. STP driver does s/w reset -+ * 2. UART does 0xFF wake up -+ * 3. SDIO does re-init command(changed to trigger by host) -+ */ -+ return iRet; -+ -+} -+ -+static INT32 opfunc_pwr_off(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ if (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_WARN_FUNC("WMT-CORE: WMT already off, WMT DRV_STS_[0x%x]\n", -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]); -+ osal_assert(0); -+ return -1; -+ } -+ if (MTK_WCN_BOOL_FALSE == g_pwr_off_flag) { -+ WMT_WARN_FUNC("CONNSYS power off be disabled, maybe need trigger core dump!\n"); -+ osal_assert(0); -+ return -2; -+ } -+ -+ /* wmt and stp are initialized successfully */ -+ if (DRV_STS_FUNC_ON == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ iRet = wmt_core_stp_deinit(); -+ if (iRet) { -+ WMT_WARN_FUNC("wmt_core_stp_deinit fail (%d)\n", iRet); -+ /*should let run to power down chip */ -+ } -+ } -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; -+ -+ /* power off control */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_OFF, &ctrlPa1, &ctrlPa2); -+ if (iRet) -+ WMT_WARN_FUNC("HW_PWR_OFF fail (%d)\n", iRet); -+ WMT_WARN_FUNC("HW_PWR_OFF ok\n"); -+ -+ /*anyway, set to POWER_OFF state */ -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF; -+ return iRet; -+ -+} -+ -+static INT32 opfunc_func_on(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = -1; -+ INT32 iPwrOffRet = -1; -+ UINT32 drvType; -+ -+ drvType = pWmtOp->au4OpData[0]; -+ -+ /* Check abnormal type */ -+ if (WMTDRV_TYPE_COREDUMP < drvType) { -+ WMT_ERR_FUNC("abnormal Fun(%d)\n", drvType); -+ osal_assert(0); -+ return -1; -+ } -+ -+ /* Check abnormal state */ -+ if ((DRV_STS_POWER_OFF > gMtkWmtCtx.eDrvStatus[drvType]) -+ || (DRV_STS_MAX <= gMtkWmtCtx.eDrvStatus[drvType])) { -+ WMT_ERR_FUNC("func(%d) status[0x%x] abnormal\n", drvType, gMtkWmtCtx.eDrvStatus[drvType]); -+ osal_assert(0); -+ return -2; -+ } -+ -+ /* check if func already on */ -+ if (DRV_STS_FUNC_ON == gMtkWmtCtx.eDrvStatus[drvType]) { -+ WMT_WARN_FUNC("func(%d) already on\n", drvType); -+ return 0; -+ } -+ /*enable power off flag, if flag=0, power off connsys will not be executed */ -+ mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL_TRUE); -+ /* check if chip power on is needed */ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ iRet = opfunc_pwr_on(pWmtOp); -+ -+ if (iRet) { -+ WMT_ERR_FUNC("func(%d) pwr_on fail(%d)\n", drvType, iRet); -+ osal_assert(0); -+ -+ /* check all sub-func and do power off */ -+ return -3; -+ } -+ } -+ -+ if (WMTDRV_TYPE_WMT > drvType) { -+ if (NULL != gpWmtFuncOps[drvType] && NULL != gpWmtFuncOps[drvType]->func_on) { -+ iRet = (*(gpWmtFuncOps[drvType]->func_on)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); -+ if (0 != iRet) -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; -+ else -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; -+ } else { -+ WMT_WARN_FUNC("WMT-CORE: ops for type(%d) not found\n", drvType); -+ iRet = -5; -+ } -+ } else { -+ if (WMTDRV_TYPE_LPBK == drvType) -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; -+ else if (WMTDRV_TYPE_COREDUMP == drvType) -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; -+ iRet = 0; -+ } -+ -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE:type(0x%x) function on failed, ret(%d)\n", drvType, iRet); -+ osal_assert(0); -+ /* FIX-ME:[Chaozhong Liang], Error handling? check subsystem state and do pwr off if necessary? */ -+ /* check all sub-func and do power off */ -+ if ((DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP])) { -+ WMT_INFO_FUNC("WMT-CORE:Fun(%d) [POWER_OFF] and power down chip\n", drvType); -+ mtk_wcn_wmt_system_state_reset(); -+ -+ iPwrOffRet = opfunc_pwr_off(pWmtOp); -+ if (iPwrOffRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_pwr_off fail(%d) when turn off func(%d)\n", iPwrOffRet, -+ drvType); -+ osal_assert(0); -+ } -+ } -+ return iRet; -+ } -+ -+ wmt_core_dump_func_state("AF FUNC ON"); -+ -+ return 0; -+} -+ -+static INT32 opfunc_func_off(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = -1; -+ UINT32 drvType; -+ -+ drvType = pWmtOp->au4OpData[0]; -+ /* Check abnormal type */ -+ if (WMTDRV_TYPE_COREDUMP < drvType) { -+ WMT_ERR_FUNC("WMT-CORE: abnormal Fun(%d) in wmt_func_off\n", drvType); -+ osal_assert(0); -+ return -1; -+ } -+ -+ /* Check abnormal state */ -+ if (DRV_STS_MAX <= gMtkWmtCtx.eDrvStatus[drvType]) { -+ WMT_ERR_FUNC("WMT-CORE: Fun(%d) DRV_STS_[0x%x] abnormal in wmt_func_off\n", -+ drvType, gMtkWmtCtx.eDrvStatus[drvType]); -+ osal_assert(0); -+ return -2; -+ } -+ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[drvType]) { -+ WMT_WARN_FUNC("WMT-CORE: Fun(%d) DRV_STS_[0x%x] already non-FUN_ON in wmt_func_off\n", -+ drvType, gMtkWmtCtx.eDrvStatus[drvType]); -+ /* needs to check 4 subsystem's state? */ -+ return 0; -+ } else if (WMTDRV_TYPE_WMT > drvType) { -+ if (NULL != gpWmtFuncOps[drvType] && NULL != gpWmtFuncOps[drvType]->func_off) { -+ iRet = (*(gpWmtFuncOps[drvType]->func_off)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); -+ } else { -+ WMT_WARN_FUNC("WMT-CORE: ops for type(%d) not found\n", drvType); -+ iRet = -3; -+ } -+ } else { -+ if (WMTDRV_TYPE_LPBK == drvType) -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; -+ else if (WMTDRV_TYPE_COREDUMP == drvType) -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; -+ iRet = 0; -+ } -+ -+ /* shall we put device state to POWER_OFF state when fail? */ -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; -+ -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: type(0x%x) function off failed, ret(%d)\n", drvType, iRet); -+ osal_assert(0); -+ /* no matter subsystem function control fail or not, -+ *chip should be powered off when no subsystem is active -+ */ -+ /* return iRet; */ -+ } -+ -+ /* check all sub-func and do power off */ -+ if ((DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP])) { -+ WMT_INFO_FUNC("WMT-CORE:Fun(%d) [POWER_OFF] and power down chip\n", drvType); -+ -+ iRet = opfunc_pwr_off(pWmtOp); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_pwr_off fail(%d) when turn off func(%d)\n", iRet, drvType); -+ osal_assert(0); -+ } -+ } -+ -+ wmt_core_dump_func_state("AF FUNC OFF"); -+ return iRet; -+} -+ -+/* TODO:[ChangeFeature][George] is this OP obsoleted? */ -+static INT32 opfunc_reg_rw(P_WMT_OP pWmtOp) -+{ -+ INT32 iret; -+ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_ERR_FUNC("reg_rw when WMT is powered off\n"); -+ return -1; -+ } -+ iret = wmt_core_reg_rw_raw(pWmtOp->au4OpData[0], -+ pWmtOp->au4OpData[1], (PUINT32) pWmtOp->au4OpData[2], pWmtOp->au4OpData[3]); -+ -+ return iret; -+} -+ -+static INT32 opfunc_exit(P_WMT_OP pWmtOp) -+{ -+ /* TODO: [FixMe][George] is ok to leave this function empty??? */ -+ WMT_WARN_FUNC("EMPTY FUNCTION\n"); -+ return 0; -+} -+ -+static INT32 opfunc_pwr_sv(P_WMT_OP pWmtOp) -+{ -+ INT32 ret = -1; -+ UINT32 u4_result = 0; -+ UINT32 evt_len; -+ UINT8 evt_buf[16] = { 0 }; -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ -+ typedef INT32(*STP_PSM_CB) (INT32); -+ STP_PSM_CB psm_cb = NULL; -+ -+ if (SLEEP == pWmtOp->au4OpData[0]) { -+ WMT_DBG_FUNC("**** Send sleep command\n"); -+ /* mtk_wcn_stp_set_psm_state(ACT_INACT); */ -+ /* (*kal_stp_flush_rx)(WMT_TASK_INDX); */ -+ ret = wmt_core_tx((PUINT8) &WMT_SLEEP_CMD[0], sizeof(WMT_SLEEP_CMD), &u4_result, 0); -+ if (ret || (u4_result != sizeof(WMT_SLEEP_CMD))) { -+ WMT_ERR_FUNC("wmt_core: SLEEP_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, -+ sizeof(WMT_SLEEP_CMD)); -+ goto pwr_sv_done; -+ } -+ -+ evt_len = sizeof(WMT_SLEEP_EVT); -+ ret = wmt_core_rx(evt_buf, evt_len, &u4_result); -+ if (ret || (u4_result != evt_len)) { -+ unsigned long type = WMTDRV_TYPE_WMT; -+ unsigned long reason = 33; -+ unsigned long ctrlpa = 1; -+ -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: read SLEEP_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len); -+ mtk_wcn_stp_dbg_dump_package(); -+ ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0); -+ if (!ret) { /* parser ok */ -+ reason = 38; /* host schedule issue reason code */ -+ WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n"); -+ } -+ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason); -+ goto pwr_sv_done; -+ } -+ -+ if (osal_memcmp(evt_buf, WMT_SLEEP_EVT, sizeof(WMT_SLEEP_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_SLEEP_EVT error\n"); -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ u4_result, -+ evt_buf[0], -+ evt_buf[1], -+ evt_buf[2], -+ evt_buf[3], -+ evt_buf[4], -+ evt_buf[5]); -+ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ sizeof(WMT_SLEEP_EVT), -+ WMT_SLEEP_EVT[0], -+ WMT_SLEEP_EVT[1], -+ WMT_SLEEP_EVT[2], -+ WMT_SLEEP_EVT[3], -+ WMT_SLEEP_EVT[4], -+ WMT_SLEEP_EVT[5]); -+ mtk_wcn_stp_dbg_dump_package(); -+ goto pwr_sv_done; -+ } else { -+ WMT_DBG_FUNC("Send sleep command OK!\n"); -+ } -+ } else if (pWmtOp->au4OpData[0] == WAKEUP) { -+ WMT_DBG_FUNC("wakeup connsys by btif"); -+ -+ ret = wmt_core_ctrl(WMT_CTRL_SOC_WAKEUP_CONSYS, &ctrlPa1, &ctrlPa2); -+ if (ret) { -+ WMT_ERR_FUNC("wmt-core:WAKEUP_CONSYS by BTIF fail(%d)", ret); -+ goto pwr_sv_done; -+ } -+#if 0 -+ WMT_DBG_FUNC("**** Send wakeup command\n"); -+ ret = wmt_core_tx(WMT_WAKEUP_CMD, sizeof(WMT_WAKEUP_CMD), &u4_result, 1); -+ -+ if (ret || (u4_result != sizeof(WMT_WAKEUP_CMD))) { -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: WAKEUP_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, -+ sizeof(WMT_WAKEUP_CMD)); -+ goto pwr_sv_done; -+ } -+#endif -+ evt_len = sizeof(WMT_WAKEUP_EVT); -+ ret = wmt_core_rx(evt_buf, evt_len, &u4_result); -+ if (ret || (u4_result != evt_len)) { -+ unsigned long type = WMTDRV_TYPE_WMT; -+ unsigned long reason = 34; -+ unsigned long ctrlpa = 2; -+ -+ WMT_ERR_FUNC("wmt_core: read WAKEUP_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len); -+ mtk_wcn_stp_dbg_dump_package(); -+ ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0); -+ if (!ret) { /* parser ok */ -+ reason = 39; /* host schedule issue reason code */ -+ WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n"); -+ } -+ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason); -+ goto pwr_sv_done; -+ } -+ -+ if (osal_memcmp(evt_buf, WMT_WAKEUP_EVT, sizeof(WMT_WAKEUP_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_WAKEUP_EVT error\n"); -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ u4_result, -+ evt_buf[0], -+ evt_buf[1], -+ evt_buf[2], -+ evt_buf[3], -+ evt_buf[4], -+ evt_buf[5]); -+ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ sizeof(WMT_WAKEUP_EVT), -+ WMT_WAKEUP_EVT[0], -+ WMT_WAKEUP_EVT[1], -+ WMT_WAKEUP_EVT[2], -+ WMT_WAKEUP_EVT[3], -+ WMT_WAKEUP_EVT[4], -+ WMT_WAKEUP_EVT[5]); -+ mtk_wcn_stp_dbg_dump_package(); -+ goto pwr_sv_done; -+ } else { -+ WMT_DBG_FUNC("Send wakeup command OK!\n"); -+ } -+ } else if (pWmtOp->au4OpData[0] == HOST_AWAKE) { -+ -+ WMT_DBG_FUNC("**** Send host awake command\n"); -+ -+ psm_cb = (STP_PSM_CB) pWmtOp->au4OpData[1]; -+ /* (*kal_stp_flush_rx)(WMT_TASK_INDX); */ -+ ret = wmt_core_tx((PUINT8) WMT_HOST_AWAKE_CMD, sizeof(WMT_HOST_AWAKE_CMD), &u4_result, 0); -+ if (ret || (u4_result != sizeof(WMT_HOST_AWAKE_CMD))) { -+ WMT_ERR_FUNC("wmt_core: HOST_AWAKE_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, -+ sizeof(WMT_HOST_AWAKE_CMD)); -+ goto pwr_sv_done; -+ } -+ -+ evt_len = sizeof(WMT_HOST_AWAKE_EVT); -+ ret = wmt_core_rx(evt_buf, evt_len, &u4_result); -+ if (ret || (u4_result != evt_len)) { -+ unsigned long type = WMTDRV_TYPE_WMT; -+ unsigned long reason = 35; -+ unsigned long ctrlpa = 3; -+ -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: read HOST_AWAKE_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len); -+ mtk_wcn_stp_dbg_dump_package(); -+ ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0); -+ if (!ret) { /* parser ok */ -+ reason = 40; /* host schedule issue reason code */ -+ WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n"); -+ } -+ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason); -+ goto pwr_sv_done; -+ } -+ -+ if (osal_memcmp(evt_buf, WMT_HOST_AWAKE_EVT, sizeof(WMT_HOST_AWAKE_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_HOST_AWAKE_EVT error\n"); -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ u4_result, -+ evt_buf[0], -+ evt_buf[1], -+ evt_buf[2], -+ evt_buf[3], -+ evt_buf[4], -+ evt_buf[5]); -+ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ sizeof(WMT_HOST_AWAKE_EVT), -+ WMT_HOST_AWAKE_EVT[0], -+ WMT_HOST_AWAKE_EVT[1], -+ WMT_HOST_AWAKE_EVT[2], -+ WMT_HOST_AWAKE_EVT[3], -+ WMT_HOST_AWAKE_EVT[4], -+ WMT_HOST_AWAKE_EVT[5]); -+ mtk_wcn_stp_dbg_dump_package(); -+ /* goto pwr_sv_done; */ -+ } else { -+ WMT_DBG_FUNC("Send host awake command OK!\n"); -+ } -+ } -+pwr_sv_done: -+ -+ if (pWmtOp->au4OpData[0] < STP_PSM_MAX_ACTION) { -+ psm_cb = (STP_PSM_CB) pWmtOp->au4OpData[1]; -+ WMT_DBG_FUNC("Do STP-CB! %d %p / %p\n", pWmtOp->au4OpData[0], (PVOID) pWmtOp->au4OpData[1], -+ (PVOID) psm_cb); -+ if (NULL != psm_cb) { -+ psm_cb(pWmtOp->au4OpData[0]); -+ } else { -+ WMT_ERR_FUNC("fatal error !!!, psm_cb = %p, god, someone must have corrupted our memory.\n", -+ psm_cb); -+ } -+ } -+ -+ return ret; -+} -+ -+static INT32 opfunc_dsns(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = -1; -+ UINT32 u4Res; -+ UINT32 evtLen; -+ UINT8 evtBuf[16] = { 0 }; -+ -+ WMT_DSNS_CMD[4] = (UINT8) pWmtOp->au4OpData[0]; -+ WMT_DSNS_CMD[5] = (UINT8) pWmtOp->au4OpData[1]; -+ -+ /* send command */ -+ /* iRet = (*kal_stp_tx)(WMT_DSNS_CMD, osal_sizeof(WMT_DSNS_CMD), &u4Res); */ -+ iRet = wmt_core_tx((PUINT8) WMT_DSNS_CMD, osal_sizeof(WMT_DSNS_CMD), &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != osal_sizeof(WMT_DSNS_CMD))) { -+ WMT_ERR_FUNC("WMT-CORE: DSNS_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, -+ osal_sizeof(WMT_DSNS_CMD)); -+ return iRet; -+ } -+ -+ evtLen = osal_sizeof(WMT_DSNS_EVT); -+ -+ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); -+ if (iRet || (u4Res != evtLen)) { -+ WMT_ERR_FUNC("WMT-CORE: read DSNS_EVT fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen); -+ mtk_wcn_stp_dbg_dump_package(); -+ return iRet; -+ } -+ -+ if (osal_memcmp(evtBuf, WMT_DSNS_EVT, osal_sizeof(WMT_DSNS_EVT)) != 0) { -+ WMT_ERR_FUNC("WMT-CORE: compare WMT_DSNS_EVT error\n"); -+ WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], -+ osal_sizeof(WMT_DSNS_EVT), WMT_DSNS_EVT[0], WMT_DSNS_EVT[1], WMT_DSNS_EVT[2], -+ WMT_DSNS_EVT[3], WMT_DSNS_EVT[4]); -+ } else { -+ WMT_INFO_FUNC("Send WMT_DSNS_CMD command OK!\n"); -+ } -+ -+ return iRet; -+} -+ -+#if CFG_CORE_INTERNAL_TXRX -+INT32 wmt_core_lpbk_do_stp_init(void) -+{ -+ INT32 iRet = 0; -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_OPEN, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); -+ return -1; -+ } -+ -+ ctrlPa1 = WMT_STP_CONF_MODE; -+ ctrlPa2 = MTKSTP_BTIF_MAND_MODE; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ -+ ctrlPa1 = WMT_STP_CONF_EN; -+ ctrlPa2 = 1; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: stp_init <1><2> fail:%d\n", iRet); -+ return -2; -+ } -+} -+ -+INT32 wmt_core_lpbk_do_stp_deinit(void) -+{ -+ INT32 iRet = 0; -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+#endif -+static INT32 opfunc_lpbk(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet; -+ UINT32 u4WrittenSize = 0; -+ UINT32 u4ReadSize = 0; -+ UINT32 buf_length = 0; -+ UINT32 *pbuffer = NULL; -+ UINT16 len_in_cmd; -+ -+ /* UINT32 offset; */ -+ UINT8 WMT_TEST_LPBK_CMD[] = { 0x1, 0x2, 0x0, 0x0, 0x7 }; -+ UINT8 WMT_TEST_LPBK_EVT[] = { 0x2, 0x2, 0x0, 0x0, 0x0 }; -+ -+ /* UINT8 lpbk_buf[1024 + 5] = {0}; */ -+ MTK_WCN_BOOL fgFail; -+ -+ buf_length = pWmtOp->au4OpData[0]; /* packet length */ -+ pbuffer = (VOID *) pWmtOp->au4OpData[1]; /* packet buffer pointer */ -+ WMT_DBG_FUNC("WMT-CORE: -->wmt_do_lpbk\n"); -+ -+#if 0 -+ osal_memcpy(&WMT_TEST_LPBK_EVT[0], &WMT_TEST_LPBK_CMD[0], osal_sizeof(WMT_TEST_LPBK_CMD)); -+#endif -+#if !CFG_CORE_INTERNAL_TXRX -+ /*check if WMTDRV_TYPE_LPBK function is already on */ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK] -+ || buf_length + osal_sizeof(WMT_TEST_LPBK_CMD) > osal_sizeof(gLpbkBuf)) { -+ WMT_ERR_FUNC("WMT-CORE: abnormal LPBK in wmt_do_lpbk\n"); -+ osal_assert(0); -+ return -2; -+ } -+#endif -+ /*package loopback for STP */ -+ -+ /* init buffer */ -+ osal_memset(gLpbkBuf, 0, osal_sizeof(gLpbkBuf)); -+ -+ len_in_cmd = buf_length + 1; /* add flag field */ -+ -+ osal_memcpy(&WMT_TEST_LPBK_CMD[2], &len_in_cmd, 2); -+ osal_memcpy(&WMT_TEST_LPBK_EVT[2], &len_in_cmd, 2); -+ -+ /* wmt cmd */ -+ osal_memcpy(gLpbkBuf, WMT_TEST_LPBK_CMD, osal_sizeof(WMT_TEST_LPBK_CMD)); -+ osal_memcpy(gLpbkBuf + osal_sizeof(WMT_TEST_LPBK_CMD), pbuffer, buf_length); -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+ /*send packet through STP */ -+ -+ /* iRet = (*kal_stp_tx)( -+ *(PUINT8)gLpbkBuf, -+ *osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length, -+ *&u4WrittenSize); -+ */ -+ iRet = wmt_core_tx((PUINT8) gLpbkBuf, -+ (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length), -+ &u4WrittenSize, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet) { -+ WMT_ERR_FUNC("opfunc_lpbk wmt_core_tx failed\n"); -+ break; -+ } -+ WMT_INFO_FUNC("opfunc_lpbk wmt_core_tx OK\n"); -+ -+ /*receive firmware response from STP */ -+ iRet = wmt_core_rx((PUINT8) gLpbkBuf, (osal_sizeof(WMT_TEST_LPBK_EVT) + buf_length), &u4ReadSize); -+ if (iRet) { -+ WMT_ERR_FUNC("opfunc_lpbk wmt_core_rx failed\n"); -+ break; -+ } -+ WMT_INFO_FUNC("opfunc_lpbk wmt_core_rx OK\n"); -+ /*check if loopback response ok or not */ -+ if (u4ReadSize != (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)) { -+ WMT_ERR_FUNC("lpbk event read size wrong(%d, %d)\n", u4ReadSize, -+ (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)); -+ break; -+ } -+ WMT_INFO_FUNC("lpbk event read size right(%d, %d)\n", u4ReadSize, -+ (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)); -+ -+ if (osal_memcmp(WMT_TEST_LPBK_EVT, gLpbkBuf, osal_sizeof(WMT_TEST_LPBK_EVT))) { -+ WMT_ERR_FUNC("WMT-CORE WMT_TEST_LPBK_EVT error! read len %d [%02x,%02x,%02x,%02x,%02x]\n", -+ (INT32) u4ReadSize, gLpbkBuf[0], gLpbkBuf[1], gLpbkBuf[2], gLpbkBuf[3], gLpbkBuf[4] -+ ); -+ break; -+ } -+ pWmtOp->au4OpData[0] = u4ReadSize - osal_sizeof(WMT_TEST_LPBK_EVT); -+ osal_memcpy((VOID *) pWmtOp->au4OpData[1], gLpbkBuf + osal_sizeof(WMT_TEST_LPBK_CMD), buf_length); -+ fgFail = MTK_WCN_BOOL_FALSE; -+ } while (0); -+ /*return result */ -+ /* WMT_DBG_FUNC("WMT-CORE: <--wmt_do_lpbk, fgFail = %d\n", fgFail); */ -+ return fgFail; -+ -+} -+ -+static INT32 opfunc_cmd_test(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = 0; -+ UINT32 cmdNo = 0; -+ UINT32 cmdNoPa = 0; -+ -+ UINT8 tstCmd[64]; -+ UINT8 tstEvt[64]; -+ UINT8 tstEvtTmp[64]; -+ UINT32 u4Res; -+ SIZE_T tstCmdSz = 0; -+ SIZE_T tstEvtSz = 0; -+ -+ UINT8 *pRes = NULL; -+ UINT32 resBufRoom = 0; -+ /*test command list */ -+ /*1 */ -+ UINT8 WMT_ASSERT_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x08 }; -+ UINT8 WMT_ASSERT_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; -+ UINT8 WMT_NOACK_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0A }; -+ UINT8 WMT_NOACK_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; -+ UINT8 WMT_WARNRST_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0B }; -+ UINT8 WMT_WARNRST_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; -+ UINT8 WMT_FWLOGTST_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0C }; -+ UINT8 WMT_FWLOGTST_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; -+ -+ UINT8 WMT_EXCEPTION_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x09 }; -+ UINT8 WMT_EXCEPTION_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; -+ /*2 */ -+ UINT8 WMT_COEXDBG_CMD[] = { 0x01, 0x10, 0x02, 0x00, -+ 0x08, -+ 0xAA /*Debugging Parameter */ -+ }; -+ UINT8 WMT_COEXDBG_1_EVT[] = { 0x02, 0x10, 0x05, 0x00, -+ 0x00, -+ 0xAA, 0xAA, 0xAA, 0xAA /*event content */ -+ }; -+ UINT8 WMT_COEXDBG_2_EVT[] = { 0x02, 0x10, 0x07, 0x00, -+ 0x00, -+ 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB /*event content */ -+ }; -+ UINT8 WMT_COEXDBG_3_EVT[] = { 0x02, 0x10, 0x0B, 0x00, -+ 0x00, -+ 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB /*event content */ -+ }; -+ /*test command list -end */ -+ -+ cmdNo = pWmtOp->au4OpData[0]; -+ -+ WMT_INFO_FUNC("Send Test command %d!\n", cmdNo); -+ if (cmdNo == 0) { -+ /*dead command */ -+ WMT_INFO_FUNC("Send Assert command !\n"); -+ tstCmdSz = osal_sizeof(WMT_ASSERT_CMD); -+ tstEvtSz = osal_sizeof(WMT_ASSERT_EVT); -+ osal_memcpy(tstCmd, WMT_ASSERT_CMD, tstCmdSz); -+ osal_memcpy(tstEvt, WMT_ASSERT_EVT, tstEvtSz); -+ } else if (cmdNo == 1) { -+ /*dead command */ -+ WMT_INFO_FUNC("Send Exception command !\n"); -+ tstCmdSz = osal_sizeof(WMT_EXCEPTION_CMD); -+ tstEvtSz = osal_sizeof(WMT_EXCEPTION_EVT); -+ osal_memcpy(tstCmd, WMT_EXCEPTION_CMD, tstCmdSz); -+ osal_memcpy(tstEvt, WMT_EXCEPTION_EVT, tstEvtSz); -+ } else if (cmdNo == 2) { -+ cmdNoPa = pWmtOp->au4OpData[1]; -+ pRes = (PUINT8) pWmtOp->au4OpData[2]; -+ resBufRoom = pWmtOp->au4OpData[3]; -+ if (cmdNoPa <= 0xf) { -+ WMT_INFO_FUNC("Send Coexistence Debug command [0x%x]!\n", cmdNoPa); -+ tstCmdSz = osal_sizeof(WMT_COEXDBG_CMD); -+ osal_memcpy(tstCmd, WMT_COEXDBG_CMD, tstCmdSz); -+ if (tstCmdSz > 5) -+ tstCmd[5] = cmdNoPa; -+ -+ /*setup the expected event length */ -+ if (cmdNoPa <= 0x4) { -+ tstEvtSz = osal_sizeof(WMT_COEXDBG_1_EVT); -+ osal_memcpy(tstEvt, WMT_COEXDBG_1_EVT, tstEvtSz); -+ } else if (cmdNoPa == 0x5) { -+ tstEvtSz = osal_sizeof(WMT_COEXDBG_2_EVT); -+ osal_memcpy(tstEvt, WMT_COEXDBG_2_EVT, tstEvtSz); -+ } else if (cmdNoPa >= 0x6 && cmdNoPa <= 0xf) { -+ tstEvtSz = osal_sizeof(WMT_COEXDBG_3_EVT); -+ osal_memcpy(tstEvt, WMT_COEXDBG_3_EVT, tstEvtSz); -+ } else { -+ -+ } -+ } else { -+ WMT_ERR_FUNC("cmdNoPa is wrong\n"); -+ return iRet; -+ } -+ } else if (cmdNo == 3) { -+ /*dead command */ -+ WMT_INFO_FUNC("Send No Ack command !\n"); -+ tstCmdSz = osal_sizeof(WMT_NOACK_CMD); -+ tstEvtSz = osal_sizeof(WMT_NOACK_EVT); -+ osal_memcpy(tstCmd, WMT_NOACK_CMD, tstCmdSz); -+ osal_memcpy(tstEvt, WMT_NOACK_EVT, tstEvtSz); -+ } else if (cmdNo == 4) { -+ /*dead command */ -+ WMT_INFO_FUNC("Send Warm reset command !\n"); -+ tstCmdSz = osal_sizeof(WMT_WARNRST_CMD); -+ tstEvtSz = osal_sizeof(WMT_WARNRST_EVT); -+ osal_memcpy(tstCmd, WMT_WARNRST_CMD, tstCmdSz); -+ osal_memcpy(tstEvt, WMT_WARNRST_EVT, tstEvtSz); -+ } else if (cmdNo == 5) { -+ /*dead command */ -+ WMT_INFO_FUNC("Send f/w log test command !\n"); -+ tstCmdSz = osal_sizeof(WMT_FWLOGTST_CMD); -+ tstEvtSz = osal_sizeof(WMT_FWLOGTST_EVT); -+ osal_memcpy(tstCmd, WMT_FWLOGTST_CMD, tstCmdSz); -+ osal_memcpy(tstEvt, WMT_FWLOGTST_EVT, tstEvtSz); -+ } -+ -+ else { -+ /*Placed youer test WMT command here, easiler to integrate and test with F/W side */ -+ } -+ -+ /* send command */ -+ /* iRet = (*kal_stp_tx)(tstCmd, tstCmdSz, &u4Res); */ -+ iRet = wmt_core_tx((PUINT8) tstCmd, tstCmdSz, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != tstCmdSz)) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_cmd_test iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, tstCmdSz); -+ return -1; -+ } -+ -+ if ((cmdNo == 0) || (cmdNo == 1) || cmdNo == 3) { -+ WMT_INFO_FUNC("WMT-CORE: not to rx event for assert command\n"); -+ return 0; -+ } -+ -+ iRet = wmt_core_rx(tstEvtTmp, tstEvtSz, &u4Res); -+ -+ /*Event Post Handling */ -+ if (cmdNo == 2) { -+ WMT_INFO_FUNC("#=========================================================#\n"); -+ WMT_INFO_FUNC("coext debugging id = %d", cmdNoPa); -+ if (tstEvtSz > 5) { -+ wmt_core_dump_data(&tstEvtTmp[5], "coex debugging ", tstEvtSz - 5); -+ } else { -+ /* error log */ -+ WMT_ERR_FUNC("error coex debugging event\n"); -+ } -+ /*put response to buffer for shell to read */ -+ if (pRes != NULL && resBufRoom > 0) { -+ pWmtOp->au4OpData[3] = resBufRoom < tstEvtSz - 5 ? resBufRoom : tstEvtSz - 5; -+ osal_memcpy(pRes, &tstEvtTmp[5], pWmtOp->au4OpData[3]); -+ } else -+ pWmtOp->au4OpData[3] = 0; -+ WMT_INFO_FUNC("#=========================================================#\n"); -+ } -+ -+ return iRet; -+ -+} -+ -+static INT32 opfunc_hw_rst(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = -1; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ wmt_core_dump_func_state("BE HW RST"); -+ /*-->Reset WMT data structure*/ -+ /* gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] = DRV_STS_POWER_OFF; */ -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM] = DRV_STS_POWER_OFF; -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS] = DRV_STS_POWER_OFF; -+ /* gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] = DRV_STS_POWER_OFF; */ -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK] = DRV_STS_POWER_OFF; -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_STP] = DRV_STS_POWER_OFF; -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] = DRV_STS_POWER_OFF; -+ /*enable power off flag, if flag=0, power off connsys will not be executed */ -+ mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL_TRUE); -+ /* if wmt is poweroff, we need poweron chip first */ -+ /* Zhiguo : this action also needed in BTIF interface to avoid KE */ -+#if 1 -+ if (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_WARN_FUNC("WMT-CORE: WMT is off, need re-poweron\n"); -+ /* power on control */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_ON, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: WMT_CTRL_HW_PWR_ON fail iRet(%d)\n", iRet); -+ return -1; -+ } -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; -+ } -+#endif -+ if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] == DRV_STS_FUNC_ON) { -+ -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ if (iRet) -+ WMT_ERR_FUNC("WMT-CORE: wmt_ctrl_soc_paldo_ctrl failed(%d)(%d)(%d)\n", iRet, ctrlPa1, ctrlPa2); -+ -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] = DRV_STS_POWER_OFF; -+ } -+ -+ if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] == DRV_STS_FUNC_ON) { -+ -+ if (NULL != gpWmtFuncOps[WMTDRV_TYPE_WIFI] && NULL != gpWmtFuncOps[WMTDRV_TYPE_WIFI]->func_off) { -+ iRet = gpWmtFuncOps[WMTDRV_TYPE_WIFI]->func_off(gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: turn off WIFI func fail (%d)\n", iRet); -+ -+ /* check all sub-func and do power off */ -+ } else { -+ WMT_INFO_FUNC("wmt core: turn off WIFI func ok!!\n"); -+ } -+ } -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] = DRV_STS_POWER_OFF; -+ } -+#if 0 -+ /*<4>Power off Combo chip */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_RST, &ctrlPa1, &ctrlPa2); -+ if (iRet) -+ WMT_ERR_FUNC("WMT-CORE: [HW RST] WMT_CTRL_POWER_OFF fail (%d)", iRet); -+ WMT_INFO_FUNC("WMT-CORE: [HW RST] WMT_CTRL_POWER_OFF ok (%d)", iRet); -+#endif -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF; -+ -+ /*-->PesetCombo chip*/ -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_RST, &ctrlPa1, &ctrlPa2); -+ if (iRet) -+ WMT_ERR_FUNC("WMT-CORE: -->[HW RST] fail iRet(%d)\n", iRet); -+ WMT_WARN_FUNC("WMT-CORE: -->[HW RST] ok\n"); -+ -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; -+ -+ /* 4 close stp */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ if (iRet == -2) { -+ WMT_INFO_FUNC("WMT-CORE:stp should have be closed\n"); -+ return 0; -+ } -+ WMT_ERR_FUNC("WMT-CORE: wmt close stp failed\n"); -+ return -1; -+ } -+ -+ wmt_core_dump_func_state("AF HW RST"); -+ return iRet; -+ -+} -+ -+static INT32 opfunc_sw_rst(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = 0; -+ -+ iRet = wmt_core_stp_init(); -+ if (!iRet) -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_FUNC_ON; -+ return iRet; -+} -+ -+static INT32 opfunc_stp_rst(P_WMT_OP pWmtOp) -+{ -+ -+ return 0; -+} -+ -+static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = -1; -+ UINT32 u4Res; -+ UINT32 evtLen; -+ UINT8 evtBuf[16] = { 0 }; -+ -+ WMT_THERM_CMD[4] = pWmtOp->au4OpData[0]; /*CMD type, refer to ENUM_WMTTHERM_TYPE_T */ -+ -+ /* send command */ -+ /* iRet = (*kal_stp_tx)(WMT_THERM_CMD, osal_sizeof(WMT_THERM_CMD), &u4Res); */ -+ iRet = wmt_core_tx((PUINT8) WMT_THERM_CMD, osal_sizeof(WMT_THERM_CMD), &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != osal_sizeof(WMT_THERM_CMD))) { -+ WMT_ERR_FUNC("WMT-CORE: THERM_CTRL_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, -+ osal_sizeof(WMT_THERM_CMD)); -+ return iRet; -+ } -+ -+ evtLen = 16; -+ -+ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); -+ if (iRet || ((u4Res != osal_sizeof(WMT_THERM_CTRL_EVT)) && (u4Res != osal_sizeof(WMT_THERM_READ_EVT)))) { -+ WMT_ERR_FUNC("WMT-CORE: read THERM_CTRL_EVT/THERM_READ_EVENT fail(%d) len(%d, %d)\n", iRet, u4Res, -+ evtLen); -+ mtk_wcn_stp_dbg_dump_package(); -+ return iRet; -+ } -+ if (u4Res == osal_sizeof(WMT_THERM_CTRL_EVT)) { -+ if (osal_memcmp(evtBuf, WMT_THERM_CTRL_EVT, osal_sizeof(WMT_THERM_CTRL_EVT)) != 0) { -+ WMT_ERR_FUNC("WMT-CORE: compare WMT_THERM_CTRL_EVT error\n"); -+ WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], -+ osal_sizeof(WMT_THERM_CTRL_EVT), WMT_THERM_CTRL_EVT[0], WMT_THERM_CTRL_EVT[1], -+ WMT_THERM_CTRL_EVT[2], WMT_THERM_CTRL_EVT[3], WMT_THERM_CTRL_EVT[4]); -+ pWmtOp->au4OpData[1] = MTK_WCN_BOOL_FALSE; /*will return to function driver */ -+ mtk_wcn_stp_dbg_dump_package(); -+ } else { -+ WMT_DBG_FUNC("Send WMT_THERM_CTRL_CMD command OK!\n"); -+ pWmtOp->au4OpData[1] = MTK_WCN_BOOL_TRUE; /*will return to function driver */ -+ } -+ } else { -+ /*no need to judge the real thermal value */ -+ if (osal_memcmp(evtBuf, WMT_THERM_READ_EVT, osal_sizeof(WMT_THERM_READ_EVT) - 1) != 0) { -+ WMT_ERR_FUNC("WMT-CORE: compare WMT_THERM_READ_EVT error\n"); -+ WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X]\n", -+ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], evtBuf[5], -+ osal_sizeof(WMT_THERM_READ_EVT), WMT_THERM_READ_EVT[0], WMT_THERM_READ_EVT[1], -+ WMT_THERM_READ_EVT[2], WMT_THERM_READ_EVT[3]); -+ pWmtOp->au4OpData[1] = 0xFF; /*will return to function driver */ -+ mtk_wcn_stp_dbg_dump_package(); -+ } else { -+ WMT_DBG_FUNC("Send WMT_THERM_READ_CMD command OK!\n"); -+ pWmtOp->au4OpData[1] = evtBuf[5]; /*will return to function driver */ -+ } -+ } -+ -+ return iRet; -+ -+} -+ -+static INT32 opfunc_efuse_rw(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = -1; -+ UINT32 u4Res; -+ UINT32 evtLen; -+ UINT8 evtBuf[16] = { 0 }; -+ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_efuse_rw fail: chip is powered off\n"); -+ return -1; -+ } -+ -+ WMT_EFUSE_CMD[4] = (pWmtOp->au4OpData[0]) ? 0x1 : 0x2; /* w:2, r:1 */ -+ osal_memcpy(&WMT_EFUSE_CMD[6], (PUINT8) &pWmtOp->au4OpData[1], 2); /* address */ -+ osal_memcpy(&WMT_EFUSE_CMD[8], (PUINT32) pWmtOp->au4OpData[2], 4); /* value */ -+ -+ wmt_core_dump_data(&WMT_EFUSE_CMD[0], "efuse_cmd", osal_sizeof(WMT_EFUSE_CMD)); -+ -+ /* send command */ -+ /* iRet = (*kal_stp_tx)(WMT_EFUSE_CMD, osal_sizeof(WMT_EFUSE_CMD), &u4Res); */ -+ iRet = wmt_core_tx((PUINT8) WMT_EFUSE_CMD, osal_sizeof(WMT_EFUSE_CMD), &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != osal_sizeof(WMT_EFUSE_CMD))) { -+ WMT_ERR_FUNC("WMT-CORE: EFUSE_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, -+ osal_sizeof(WMT_EFUSE_CMD)); -+ return iRet; -+ } -+ -+ evtLen = (pWmtOp->au4OpData[0]) ? osal_sizeof(WMT_EFUSE_EVT) : osal_sizeof(WMT_EFUSE_EVT); -+ -+ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); -+ if (iRet || (u4Res != evtLen)) -+ WMT_ERR_FUNC("WMT-CORE: read REG_EVB fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen); -+ wmt_core_dump_data(&evtBuf[0], "efuse_evt", osal_sizeof(evtBuf)); -+ -+ return iRet; -+ -+} -+ -+static INT32 opfunc_gpio_ctrl(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = -1; -+ WMT_IC_PIN_ID id; -+ WMT_IC_PIN_STATE stat; -+ UINT32 flag; -+ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_gpio_ctrl fail: chip is powered off\n"); -+ return -1; -+ } -+ -+ if (!gMtkWmtCtx.p_ic_ops->ic_pin_ctrl) { -+ WMT_ERR_FUNC("WMT-CORE: error, gMtkWmtCtx.p_ic_ops->ic_pin_ctrl(NULL)\n"); -+ return -1; -+ } -+ -+ id = pWmtOp->au4OpData[0]; -+ stat = pWmtOp->au4OpData[1]; -+ flag = pWmtOp->au4OpData[2]; -+ -+ WMT_INFO_FUNC("ic pin id:%d, stat:%d, flag:0x%x\n", id, stat, flag); -+ -+ iRet = (*(gMtkWmtCtx.p_ic_ops->ic_pin_ctrl)) (id, stat, flag); -+ -+ return iRet; -+} -+ -+MTK_WCN_BOOL wmt_core_is_quick_ps_support(void) -+{ -+ P_WMT_CTX pctx = &gMtkWmtCtx; -+ -+ if ((NULL != pctx->p_ic_ops) && (NULL != pctx->p_ic_ops->is_quick_sleep)) -+ return (*(pctx->p_ic_ops->is_quick_sleep)) (); -+ -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+MTK_WCN_BOOL wmt_core_get_aee_dump_flag(void) -+{ -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_WMT_CTX pctx = &gMtkWmtCtx; -+ -+ if ((NULL != pctx->p_ic_ops) && (NULL != pctx->p_ic_ops->is_aee_dump_support)) -+ bRet = (*(pctx->p_ic_ops->is_aee_dump_support)) (); -+ else -+ bRet = MTK_WCN_BOOL_FALSE; -+ -+ return bRet; -+} -+ -+INT32 opfunc_pin_state(P_WMT_OP pWmtOp) -+{ -+ -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ UINT32 iRet = 0; -+ -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_STATE_DUMP, &ctrlPa1, &ctrlPa2); -+ return iRet; -+} -+ -+static INT32 opfunc_bgw_ds(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = -1; -+ UINT32 u4WrittenSize = 0; -+ UINT32 u4ReadSize = 0; -+ UINT32 buf_len = 0; -+ UINT8 *buffer = NULL; -+ UINT8 evt_buffer[8] = { 0 }; -+ MTK_WCN_BOOL fgFail; -+ -+ UINT8 WMT_BGW_DESENSE_CMD[] = { -+ 0x01, 0x0e, 0x0f, 0x00, -+ 0x02, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00 -+ }; -+ UINT8 WMT_BGW_DESENSE_EVT[] = { 0x02, 0x0e, 0x01, 0x00, 0x00 }; -+ -+ buf_len = pWmtOp->au4OpData[0]; -+ buffer = (PUINT8) pWmtOp->au4OpData[1]; -+ -+ osal_memcpy(&WMT_BGW_DESENSE_CMD[5], buffer, buf_len); -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+ -+ iRet = -+ wmt_core_tx(&WMT_BGW_DESENSE_CMD[0], osal_sizeof(WMT_BGW_DESENSE_CMD), &u4WrittenSize, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4WrittenSize != osal_sizeof(WMT_BGW_DESENSE_CMD))) { -+ WMT_ERR_FUNC("bgw desense tx CMD fail(%d),size(%d)\n", iRet, u4WrittenSize); -+ break; -+ } -+ -+ iRet = wmt_core_rx(evt_buffer, osal_sizeof(WMT_BGW_DESENSE_EVT), &u4ReadSize); -+ if (iRet || (u4ReadSize != osal_sizeof(WMT_BGW_DESENSE_EVT))) { -+ WMT_ERR_FUNC("bgw desense rx EVT fail(%d),size(%d)\n", iRet, u4ReadSize); -+ break; -+ } -+ -+ if (osal_memcmp(evt_buffer, WMT_BGW_DESENSE_EVT, osal_sizeof(WMT_BGW_DESENSE_EVT)) != 0) { -+ WMT_ERR_FUNC -+ ("bgw desense WMT_BGW_DESENSE_EVT compare fail:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", -+ evt_buffer[0], evt_buffer[1], evt_buffer[2], evt_buffer[3], evt_buffer[4]); -+ break; -+ } -+ -+ fgFail = MTK_WCN_BOOL_FALSE; -+ -+ } while (0); -+ -+ return fgFail; -+} -+ -+static INT32 opfunc_set_mcu_clk(P_WMT_OP pWmtOp) -+{ -+ UINT32 kind = 0; -+ INT32 iRet = -1; -+ UINT32 u4WrittenSize = 0; -+ UINT32 u4ReadSize = 0; -+ UINT8 evt_buffer[12] = { 0 }; -+ MTK_WCN_BOOL fgFail; -+ PUINT8 set_mcu_clk_str[] = { -+ "Enable MCU PLL", -+ "SET MCU CLK to 26M", -+ "SET MCU CLK to 37M", -+ "SET MCU CLK to 64M", -+ "SET MCU CLK to 69M", -+ "SET MCU CLK to 104M", -+ "SET MCU CLK to 118.857M", -+ "SET MCU CLK to 138.67M", -+ "Disable MCU PLL" -+ }; -+ UINT8 WMT_SET_MCU_CLK_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+ }; -+ UINT8 WMT_SET_MCU_CLK_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+ UINT8 WMT_EN_MCU_CLK_CMD[] = { 0x34, 0x03, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00 }; /* enable pll clk */ -+ UINT8 WMT_26_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x00, 0x4d, 0x84, 0x00 }; /* set 26M */ -+ UINT8 WMT_37_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1e, 0x4d, 0x84, 0x00 }; /* set 37.8M */ -+ UINT8 WMT_64_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1d, 0x4d, 0x84, 0x00 }; /* set 64M */ -+ UINT8 WMT_69_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1c, 0x4d, 0x84, 0x00 }; /* set 69M */ -+ UINT8 WMT_104_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x5b, 0x4d, 0x84, 0x00 }; /* set 104M */ -+ UINT8 WMT_108_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x5a, 0x4d, 0x84, 0x00 }; /* set 118.857M */ -+ UINT8 WMT_138_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x59, 0x4d, 0x84, 0x00 }; /* set 138.67M */ -+ UINT8 WMT_DIS_MCU_CLK_CMD[] = { 0x34, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 }; /* disable pll clk */ -+ -+ kind = pWmtOp->au4OpData[0]; -+ WMT_INFO_FUNC("do %s\n", set_mcu_clk_str[kind]); -+ -+ switch (kind) { -+ case 0: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_EN_MCU_CLK_CMD[0], osal_sizeof(WMT_EN_MCU_CLK_CMD)); -+ break; -+ case 1: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_26_MCU_CLK_CMD[0], osal_sizeof(WMT_26_MCU_CLK_CMD)); -+ break; -+ case 2: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_37_MCU_CLK_CMD[0], osal_sizeof(WMT_37_MCU_CLK_CMD)); -+ break; -+ case 3: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_64_MCU_CLK_CMD[0], osal_sizeof(WMT_64_MCU_CLK_CMD)); -+ break; -+ case 4: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_69_MCU_CLK_CMD[0], osal_sizeof(WMT_69_MCU_CLK_CMD)); -+ break; -+ case 5: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_104_MCU_CLK_CMD[0], osal_sizeof(WMT_104_MCU_CLK_CMD)); -+ break; -+ case 6: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_108_MCU_CLK_CMD[0], osal_sizeof(WMT_108_MCU_CLK_CMD)); -+ break; -+ case 7: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_138_MCU_CLK_CMD[0], osal_sizeof(WMT_138_MCU_CLK_CMD)); -+ break; -+ case 8: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_DIS_MCU_CLK_CMD[0], osal_sizeof(WMT_DIS_MCU_CLK_CMD)); -+ break; -+ default: -+ WMT_ERR_FUNC("unknown kind\n"); -+ break; -+ } -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+ -+ iRet = -+ wmt_core_tx(&WMT_SET_MCU_CLK_CMD[0], osal_sizeof(WMT_SET_MCU_CLK_CMD), &u4WrittenSize, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4WrittenSize != osal_sizeof(WMT_SET_MCU_CLK_CMD))) { -+ WMT_ERR_FUNC("WMT_SET_MCU_CLK_CMD fail(%d),size(%d)\n", iRet, u4WrittenSize); -+ break; -+ } -+ -+ iRet = wmt_core_rx(evt_buffer, osal_sizeof(WMT_SET_MCU_CLK_EVT), &u4ReadSize); -+ if (iRet || (u4ReadSize != osal_sizeof(WMT_SET_MCU_CLK_EVT))) { -+ WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT fail(%d),size(%d)\n", iRet, u4ReadSize); -+ break; -+ } -+ -+ if (osal_memcmp(evt_buffer, WMT_SET_MCU_CLK_EVT, osal_sizeof(WMT_SET_MCU_CLK_EVT)) != 0) { -+ WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT compare fail:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", -+ evt_buffer[0], evt_buffer[1], evt_buffer[2], evt_buffer[3], evt_buffer[4], -+ evt_buffer[5], evt_buffer[6], evt_buffer[7]); -+ break; -+ } -+ -+ fgFail = MTK_WCN_BOOL_FALSE; -+ -+ } while (0); -+ -+ if (MTK_WCN_BOOL_FALSE == fgFail) -+ WMT_INFO_FUNC("wmt-core:%s: ok!\n", set_mcu_clk_str[kind]); -+ -+ WMT_INFO_FUNC("wmt-core:%s: fail!\n", set_mcu_clk_str[kind]); -+ -+ return fgFail; -+} -+ -+static INT32 opfunc_adie_lpbk_test(P_WMT_OP pWmtOp) -+{ -+ UINT8 *buffer = NULL; -+ MTK_WCN_BOOL fgFail; -+ UINT32 u4Res; -+ UINT32 aDieChipid = 0; -+ UINT8 soc_adie_chipid_cmd[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x24, 0x00 }; -+ UINT8 soc_adie_chipid_evt[] = { 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00 }; -+ UINT8 evtbuf[20]; -+ INT32 iRet = -1; -+ -+ buffer = (PUINT8) pWmtOp->au4OpData[1]; -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+ -+ /* read A die chipid by wmt cmd */ -+ iRet = -+ wmt_core_tx((PUINT8) &soc_adie_chipid_cmd[0], osal_sizeof(soc_adie_chipid_cmd), &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != osal_sizeof(soc_adie_chipid_cmd))) { -+ WMT_ERR_FUNC("wmt_core:read A die chipid CMD fail(%d),size(%d)\n", iRet, u4Res); -+ break; -+ } -+ osal_memset(evtbuf, 0, osal_sizeof(evtbuf)); -+ iRet = wmt_core_rx(evtbuf, osal_sizeof(soc_adie_chipid_evt), &u4Res); -+ if (iRet || (u4Res != osal_sizeof(soc_adie_chipid_evt))) { -+ WMT_ERR_FUNC("wmt_core:read A die chipid EVT fail(%d),size(%d)\n", iRet, u4Res); -+ break; -+ } -+ osal_memcpy(&aDieChipid, &evtbuf[u4Res - 2], 2); -+ osal_memcpy(buffer, &evtbuf[u4Res - 2], 2); -+ pWmtOp->au4OpData[0] = 2; -+ WMT_INFO_FUNC("get SOC A die chipid(0x%x)\n", aDieChipid); -+ -+ fgFail = MTK_WCN_BOOL_FALSE; -+ -+ } while (0); -+ -+ return fgFail; -+} -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 opfunc_idc_msg_handling(P_WMT_OP pWmtOp) -+{ -+ MTK_WCN_BOOL fgFail; -+ UINT32 u4Res; -+ UINT8 host_lte_btwf_coex_cmd[] = { 0x01, 0x10, 0x00, 0x00, 0x00 }; -+ UINT8 host_lte_btwf_coex_evt[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ UINT8 *pTxBuf = NULL; -+ UINT8 evtbuf[8] = { 0 }; -+ INT32 iRet = -1; -+ UINT16 msg_len = 0; -+ UINT32 total_len = 0; -+ UINT32 index = 0; -+ UINT8 *msg_local_buffer = NULL; -+ -+ msg_local_buffer = kmalloc(1300, GFP_KERNEL); -+ if (!msg_local_buffer) { -+ WMT_ERR_FUNC("msg_local_buffer kmalloc memory fail\n"); -+ return 0; -+ } -+ -+ pTxBuf = (UINT8 *) pWmtOp->au4OpData[0]; -+ if (NULL == pTxBuf) { -+ WMT_ERR_FUNC("idc msg buffer is NULL\n"); -+ return -1; -+ } -+ iRet = wmt_lib_idc_lock_aquire(); -+ if (iRet) { -+ WMT_ERR_FUNC("--->lock idc_lock failed, ret=%d\n", iRet); -+ return iRet; -+ } -+ osal_memcpy(&msg_len, &pTxBuf[0], osal_sizeof(msg_len)); -+ if (msg_len > 1200) { -+ wmt_lib_idc_lock_release(); -+ WMT_ERR_FUNC("abnormal idc msg len:%d\n", msg_len); -+ return -2; -+ } -+ msg_len += 1; /*flag byte */ -+ -+ osal_memcpy(&host_lte_btwf_coex_cmd[2], &msg_len, 2); -+ host_lte_btwf_coex_cmd[4] = (pWmtOp->au4OpData[1] & 0x00ff); -+ osal_memcpy(&msg_local_buffer[0], &host_lte_btwf_coex_cmd[0], osal_sizeof(host_lte_btwf_coex_cmd)); -+ osal_memcpy(&msg_local_buffer[osal_sizeof(host_lte_btwf_coex_cmd)], -+ &pTxBuf[osal_sizeof(msg_len)], msg_len - 1); -+ -+ wmt_lib_idc_lock_release(); -+ total_len = osal_sizeof(host_lte_btwf_coex_cmd) + msg_len - 1; -+ -+ WMT_DBG_FUNC("wmt_core:idc msg payload len form lte(%d),wmt msg total len(%d)\n", msg_len - 1, -+ total_len); -+ WMT_DBG_FUNC("wmt_core:idc msg payload:\n"); -+ -+ for (index = 0; index < total_len; index++) -+ WMT_DBG_FUNC("0x%02x ", msg_local_buffer[index]); -+ -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+ -+ /* read A die chipid by wmt cmd */ -+ iRet = wmt_core_tx((PUINT8) &msg_local_buffer[0], total_len, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != total_len)) { -+ WMT_ERR_FUNC("wmt_core:send lte idc msg to connsys fail(%d),size(%d)\n", iRet, u4Res); -+ break; -+ } -+ osal_memset(evtbuf, 0, osal_sizeof(evtbuf)); -+ iRet = wmt_core_rx(evtbuf, osal_sizeof(host_lte_btwf_coex_evt), &u4Res); -+ if (iRet || (u4Res != osal_sizeof(host_lte_btwf_coex_evt))) { -+ WMT_ERR_FUNC("wmt_core:recv host_lte_btwf_coex_evt fail(%d),size(%d)\n", iRet, u4Res); -+ break; -+ } -+ -+ fgFail = MTK_WCN_BOOL_FALSE; -+ -+ } while (0); -+ kfree(msg_local_buffer); -+ return fgFail; -+} -+#endif -+ -+VOID wmt_core_set_coredump_state(ENUM_DRV_STS state) -+{ -+ WMT_INFO_FUNC("wmt-core: set coredump state(%d)\n", state); -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] = state; -+} -+#ifdef CONFIG_MTK_COMBO_ANT -+INT32 opfunc_ant_ram_down(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = 0; -+ size_t ctrlPa1 = pWmtOp->au4OpData[0]; -+ UINT32 ctrlPa2 = pWmtOp->au4OpData[1]; -+ PUINT8 pbuf = (PUINT8) ctrlPa1; -+ UINT32 fragSeq = 0; -+ UINT16 fragSize = 0; -+ UINT16 wmtCmdLen; -+ UINT16 wmtPktLen; -+ UINT32 u4Res = 0; -+ UINT8 antEvtBuf[osal_sizeof(WMT_ANT_RAM_DWN_EVT)]; -+#if 1 -+ UINT32 ctrlPa3 = pWmtOp->au4OpData[2]; -+ -+ do { -+ fragSize = ctrlPa2; -+ fragSeq = ctrlPa3; -+ gAntBuf[5] = fragSeq; -+ -+ -+ wmtPktLen = fragSize + sizeof(WMT_ANT_RAM_DWN_CMD) + 1; -+ -+ /*WMT command length cal */ -+ wmtCmdLen = wmtPktLen - 4; -+#if 0 -+ WMT_ANT_RAM_DWN_CMD[2] = wmtCmdLen & 0xFF; -+ WMT_ANT_RAM_DWN_CMD[3] = (wmtCmdLen & 0xFF00) >> 16; -+#else -+ osal_memcpy(&WMT_ANT_RAM_DWN_CMD[2], &wmtCmdLen, 2); -+#endif -+ -+ -+ -+ WMT_ANT_RAM_DWN_CMD[4] = 1; /*RAM CODE download */ -+ -+ osal_memcpy(gAntBuf, WMT_ANT_RAM_DWN_CMD, sizeof(WMT_ANT_RAM_DWN_CMD)); -+ -+ /*copy ram code content to global buffer */ -+ osal_memcpy(&gAntBuf[osal_sizeof(WMT_ANT_RAM_DWN_CMD) + 1], pbuf, fragSize); -+ -+ iRet = wmt_core_tx(gAntBuf, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != wmtPktLen)) { -+ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, -+ wmtPktLen, u4Res, iRet); -+ iRet = -4; -+ break; -+ } -+ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", -+ fragSeq, wmtPktLen, u4Res); -+ -+ osal_memset(antEvtBuf, 0, sizeof(antEvtBuf)); -+ -+ WMT_ANT_RAM_DWN_EVT[4] = 0; /*download result; 0 */ -+ -+ iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_ANT_RAM_DWN_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_ANT_RAM_DWN_EVT))) { -+ WMT_ERR_FUNC("wmt_core: read WMT_ANT_RAM_DWN_EVT length(%zu, %d) fail(%d)\n", -+ sizeof(WMT_ANT_RAM_DWN_EVT), u4Res, iRet); -+ iRet = -5; -+ break; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(antEvtBuf, WMT_ANT_RAM_DWN_EVT, sizeof(WMT_ANT_RAM_DWN_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_ANT_RAM_DWN_EVT result error\n"); -+ WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], -+ antEvtBuf[4], sizeof(WMT_ANT_RAM_DWN_EVT), WMT_ANT_RAM_DWN_EVT[0], -+ WMT_ANT_RAM_DWN_EVT[1], WMT_ANT_RAM_DWN_EVT[2], WMT_ANT_RAM_DWN_EVT[3], -+ WMT_ANT_RAM_DWN_EVT[4]); -+ iRet = -6; -+ break; -+ } -+#endif -+ WMT_DBG_FUNC("wmt_core: read WMT_ANT_RAM_DWN_EVT length(%zu, %d) ok\n", -+ sizeof(WMT_ANT_RAM_DWN_EVT), u4Res); -+ -+ } while (0); -+#else -+ UINT32 patchSize = ctrlPa2; -+ UINT32 patchSizePerFrag = 1000; -+ UINT32 offset; -+ UINT32 fragNum = 0; -+ /*cal patch fragNum */ -+ fragNum = (patchSize + patchSizePerFrag - 1) / patchSizePerFrag; -+ if (2 >= fragNum) { -+ WMT_WARN_FUNC("ANT ramcode size(%d) too short\n", patchSize); -+ return -1; -+ } -+ -+ while (fragSeq < fragNum) { -+ /*update fragNum */ -+ fragSeq++; -+ -+ if (1 == fragSeq) { -+ fragSize = patchSizePerFrag; -+ /*first package */ -+ gAntBuf[5] = 1; /*RAM CODE start */ -+ } else if (fragNum == fragSeq) { -+ /*last package */ -+ fragSize = patchSizePerFrag; -+ gAntBuf[5] = 3; /*RAM CODE end */ -+ } else { -+ /*middle package */ -+ fragSize = patchSize - ((fragNum - 1) * patchSizePerFrag); -+ gAntBuf[5] = 2; /*RAM CODE confinue */ -+ } -+ wmtPktLen = fragSize + sizeof(WMT_ANT_RAM_OP_CMD) + 1; -+ -+ /*WMT command length cal */ -+ wmtCmdLen = wmtPktLen - 4; -+ -+ WMT_ANT_RAM_OP_CMD[2] = wmtCmdLen & 0xFF; -+ WMT_ANT_RAM_OP_CMD[3] = (wmtCmdLen & 0xFF00) >> 16; -+ -+ WMT_ANT_RAM_OP_CMD[4] = 1; /*RAM CODE download */ -+ -+ osal_memcpy(gAntBuf, WMT_ANT_RAM_OP_CMD, sizeof(WMT_ANT_RAM_OP_CMD)); -+ -+ /*copy ram code content to global buffer */ -+ osal_memcpy(&gAntBuf[6], pbuf, fragSize); -+ -+ /*update offset */ -+ offset += fragSize; -+ pbuf += offset; -+ -+ iRet = wmt_core_tx(gAntBuf, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != wmtPktLen)) { -+ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, -+ wmtPktLen, u4Res, iRet); -+ iRet = -4; -+ break; -+ } -+ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", -+ fragSeq, wmtPktLen, u4Res); -+ -+ osal_memset(antEvtBuf, 0, sizeof(antEvtBuf)); -+ -+ WMT_SET_RAM_OP_EVT[4] = 0; /*download result; 0 */ -+ -+ iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_SET_RAM_OP_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_SET_RAM_OP_EVT))) { -+ WMT_ERR_FUNC("wmt_core: read WMT_SET_RAM_OP_EVT length(%d, %d) fail(%d)\n", -+ sizeof(WMT_SET_RAM_OP_EVT), u4Res, iRet); -+ iRet = -5; -+ break; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(antEvtBuf, WMT_SET_RAM_OP_EVT, sizeof(WMT_SET_RAM_OP_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_SET_RAM_OP_EVT result error\n"); -+ WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], -+ antEvtBuf[4], sizeof(WMT_SET_RAM_OP_EVT), WMT_SET_RAM_OP_EVT[0], -+ WMT_SET_RAM_OP_EVT[1], WMT_SET_RAM_OP_EVT[2], WMT_SET_RAM_OP_EVT[3], -+ WMT_SET_RAM_OP_EVT[4]); -+ iRet = -6; -+ break; -+ } -+#endif -+ WMT_DBG_FUNC("wmt_core: read WMT_SET_RAM_OP_EVT length(%d, %d) ok\n", -+ sizeof(WMT_SET_RAM_OP_EVT), u4Res); -+ -+ -+ } -+ if (fragSeq != fragNum) -+ iRet = -7; -+#endif -+ return iRet; -+} -+ -+ -+INT32 opfunc_ant_ram_stat_get(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = 0; -+ UINT32 u4Res = 0; -+ UINT32 wmtPktLen = osal_sizeof(WMT_ANT_RAM_STA_GET_CMD); -+ UINT32 u4AntRamStatus = 0; -+ UINT8 antEvtBuf[osal_sizeof(WMT_ANT_RAM_STA_GET_EVT)]; -+ -+ -+ iRet = wmt_core_tx(WMT_ANT_RAM_STA_GET_CMD, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != wmtPktLen)) { -+ WMT_ERR_FUNC -+ ("wmt_core: write wmt and ramcode status query command failed, (%d, %d), iRet(%d)\n", -+ wmtPktLen, u4Res, iRet); -+ iRet = -4; -+ return iRet; -+ } -+ -+ -+ iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_ANT_RAM_STA_GET_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_ANT_RAM_STA_GET_EVT))) { -+ WMT_ERR_FUNC("wmt_core: read WMT_ANT_RAM_STA_GET_EVT length(%zu, %d) fail(%d)\n", -+ sizeof(WMT_ANT_RAM_STA_GET_EVT), u4Res, iRet); -+ iRet = -5; -+ return iRet; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(antEvtBuf, WMT_ANT_RAM_STA_GET_EVT, sizeof(WMT_ANT_RAM_STA_GET_EVT) - 1) != -+ 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_ANT_RAM_STA_GET_EVT result error\n"); -+ WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], antEvtBuf[4], -+ sizeof(WMT_ANT_RAM_STA_GET_EVT), WMT_ANT_RAM_STA_GET_EVT[0], -+ WMT_ANT_RAM_STA_GET_EVT[1], WMT_ANT_RAM_STA_GET_EVT[2], -+ WMT_ANT_RAM_STA_GET_EVT[3], WMT_ANT_RAM_STA_GET_EVT[4]); -+ iRet = -6; -+ return iRet; -+ } -+#endif -+ if (0 == iRet) { -+ u4AntRamStatus = antEvtBuf[sizeof(WMT_ANT_RAM_STA_GET_EVT) - 1]; -+ pWmtOp->au4OpData[2] = u4AntRamStatus; -+ WMT_INFO_FUNC("ANT ram code %s\n", -+ 1 == u4AntRamStatus ? "exist already" : "not exist"); -+ } -+ return iRet; -+} -+#endif -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+/*TEST CODE*/ -+static UINT32 g_open_wmt_lte_flag; -+VOID wmt_core_set_flag_for_test(UINT32 enable) -+{ -+ WMT_INFO_FUNC("%s wmt_lte_flag\n", enable ? "enable" : "disable"); -+ g_open_wmt_lte_flag = enable; -+} -+ -+UINT32 wmt_core_get_flag_for_test(VOID) -+{ -+ return g_open_wmt_lte_flag; -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c -new file mode 100644 -index 0000000000000..fa603c208e59b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c -@@ -0,0 +1,1019 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-CTRL]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+#include "osal.h" -+ -+#include "wmt_ctrl.h" -+#include "wmt_core.h" -+#include "wmt_ic.h" -+#include "wmt_lib.h" -+#include "wmt_dev.h" -+#include "wmt_plat.h" -+#include "stp_core.h" -+#include "stp_dbg.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* moved to wmt_ctrl.h */ -+/*static INT32 wmt_ctrl_tx_ex (UINT8 *pData, UINT32 size, UINT32 *writtenSize, MTK_WCN_BOOL bRawFlag);*/ -+ -+static INT32 wmt_ctrl_stp_conf_ex(WMT_STP_CONF_TYPE type, UINT32 value); -+ -+static INT32 wmt_ctrl_hw_pwr_off(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_hw_pwr_on(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_hw_rst(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_stp_close(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_stp_open(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_stp_conf(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_free_patch(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_get_patch(P_WMT_CTRL_DATA); -+#if 0 -+static INT32 wmt_ctrl_host_baudrate_set(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_sdio_hw(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA); -+#endif -+static INT32 wmt_ctrl_hwidver_set(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_stp_rst(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_get_wmt_conf(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_others(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_tx(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_patch_search(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_crystal_triming_put(P_WMT_CTRL_DATA pWmtCtrlData); -+static INT32 wmt_ctrl_crystal_triming_get(P_WMT_CTRL_DATA pWmtCtrlData); -+static INT32 wmt_ctrl_hw_state_show(P_WMT_CTRL_DATA pWmtCtrlData); -+static INT32 wmt_ctrl_get_patch_num(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_soc_paldo_ctrl(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_soc_wakeup_consys(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_set_stp_dbg_info(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_bgw_desense_ctrl(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_evt_err_trg_assert(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_evt_parser(P_WMT_CTRL_DATA pWmtCtrlData); -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 wmt_ctrl_get_tdm_req_antsel(P_WMT_CTRL_DATA); -+#endif -+ -+static INT32 wmt_ctrl_rx_flush(P_WMT_CTRL_DATA); -+ -+static INT32 wmt_ctrl_gps_sync_set(P_WMT_CTRL_DATA pData); -+ -+static INT32 wmt_ctrl_gps_lna_set(P_WMT_CTRL_DATA pData); -+ -+static INT32 wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData); -+ -+/* TODO: [FixMe][GeorgeKuo]: remove unused function */ -+/*static INT32 wmt_ctrl_hwver_get(P_WMT_CTRL_DATA);*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* GeorgeKuo: Use designated initializers described in -+ * http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Designated-Inits.html -+ */ -+static const WMT_CTRL_FUNC wmt_ctrl_func[] = { -+ [WMT_CTRL_HW_PWR_OFF] = wmt_ctrl_hw_pwr_off, -+ [WMT_CTRL_HW_PWR_ON] = wmt_ctrl_hw_pwr_on, -+ [WMT_CTRL_HW_RST] = wmt_ctrl_hw_rst, -+ [WMT_CTRL_STP_CLOSE] = wmt_ctrl_stp_close, -+ [WMT_CTRL_STP_OPEN] = wmt_ctrl_stp_open, -+ [WMT_CTRL_STP_CONF] = wmt_ctrl_stp_conf, -+ [WMT_CTRL_FREE_PATCH] = wmt_ctrl_free_patch, -+ [WMT_CTRL_GET_PATCH] = wmt_ctrl_get_patch, -+ [WMT_CTRL_GET_PATCH_NAME] = wmt_ctrl_get_patch_name, -+ [WMT_CTRL_HWIDVER_SET] = wmt_ctrl_hwidver_set, -+ [WMT_CTRL_STP_RST] = wmt_ctrl_stp_rst, -+ [WMT_CTRL_GET_WMT_CONF] = wmt_ctrl_get_wmt_conf, -+ [WMT_CTRL_TX] = wmt_ctrl_tx, -+ [WMT_CTRL_RX] = wmt_ctrl_rx, -+ [WMT_CTRL_RX_FLUSH] = wmt_ctrl_rx_flush, -+ [WMT_CTRL_GPS_SYNC_SET] = wmt_ctrl_gps_sync_set, -+ [WMT_CTRL_GPS_LNA_SET] = wmt_ctrl_gps_lna_set, -+ [WMT_CTRL_PATCH_SEARCH] = wmt_ctrl_patch_search, -+ [WMT_CTRL_CRYSTAL_TRIMING_GET] = wmt_ctrl_crystal_triming_get, -+ [WMT_CTRL_CRYSTAL_TRIMING_PUT] = wmt_ctrl_crystal_triming_put, -+ [WMT_CTRL_HW_STATE_DUMP] = wmt_ctrl_hw_state_show, -+ [WMT_CTRL_GET_PATCH_NUM] = wmt_ctrl_get_patch_num, -+ [WMT_CTRL_GET_PATCH_INFO] = wmt_ctrl_get_patch_info, -+ [WMT_CTRL_SOC_PALDO_CTRL] = wmt_ctrl_soc_paldo_ctrl, -+ [WMT_CTRL_SOC_WAKEUP_CONSYS] = wmt_ctrl_soc_wakeup_consys, -+ [WMT_CTRL_SET_STP_DBG_INFO] = wmt_ctrl_set_stp_dbg_info, -+ [WMT_CTRL_BGW_DESENSE_CTRL] = wmt_ctrl_bgw_desense_ctrl, -+ [WMT_CTRL_EVT_ERR_TRG_ASSERT] = wmt_ctrl_evt_err_trg_assert, -+#if CFG_WMT_LTE_COEX_HANDLING -+ [WMT_CTRL_GET_TDM_REQ_ANTSEL] = wmt_ctrl_get_tdm_req_antsel, -+#endif -+ [WMT_CTRL_EVT_PARSER] = wmt_ctrl_evt_parser, -+ [WMT_CTRL_MAX] = wmt_ctrl_others, -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+INT32 wmt_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT32 ctrlId; -+ -+ if (NULL == pWmtCtrlData) { -+ osal_assert(0); -+ return -1; -+ } -+ -+ ctrlId = pWmtCtrlData->ctrlId; -+ /*1sanity check, including wmtCtrlId */ -+ if ((NULL == pWmtCtrlData) -+ || (WMT_CTRL_MAX <= ctrlId)) -+ /* || (ctrlId < WMT_CTRL_HW_PWR_OFF) ) [FixMe][GeorgeKuo]: useless comparison */ -+ { -+ osal_assert(NULL != pWmtCtrlData); -+ osal_assert(WMT_CTRL_MAX > ctrlId); -+ /* osal_assert(ctrlId >= WMT_CTRL_HW_PWR_OFF); [FixMe][GeorgeKuo]: useless comparison */ -+ return -2; -+ } -+ /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ -+ if (wmt_ctrl_func[ctrlId]) { -+ /*call servicd handling API */ -+ return (*(wmt_ctrl_func[ctrlId])) (pWmtCtrlData); /* serviceHandlerPack[ctrlId].serviceHandler */ -+ } -+ osal_assert(NULL != wmt_ctrl_func[ctrlId]); -+ return -3; -+ -+} -+ -+INT32 wmt_ctrl_tx(P_WMT_CTRL_DATA pWmtCtrlData /*UINT8 *pData, UINT32 size, UINT32 *writtenSize */) -+{ -+ UINT8 *pData = (PUINT8) pWmtCtrlData->au4CtrlData[0]; -+ UINT32 size = pWmtCtrlData->au4CtrlData[1]; -+ PUINT32 writtenSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; -+ MTK_WCN_BOOL bRawFlag = pWmtCtrlData->au4CtrlData[3]; -+ -+ return wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); -+} -+ -+INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA pWmtCtrlData /*UINT8 *pBuff, UINT32 buffLen, UINT32 *readSize */) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ INT32 readLen; -+ long waitRet = -1; -+ PUINT8 pBuff = (PUINT8) pWmtCtrlData->au4CtrlData[0]; -+ UINT32 buffLen = pWmtCtrlData->au4CtrlData[1]; -+ PUINT32 readSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; -+ -+ if (readSize) -+ *readSize = 0; -+ -+ /* sanity check */ -+ if (!buffLen) { -+ WMT_WARN_FUNC("buffLen = 0\n"); -+ osal_assert(buffLen); -+ return 0; -+ } -+#if 0 -+ if (!pDev) { -+ WMT_WARN_FUNC("gpDevWmt = NULL\n"); -+ osal_assert(pDev); -+ return -1; -+ } -+#endif -+ -+ if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) { -+ WMT_WARN_FUNC("state(0x%lx)\n", pDev->state); -+ osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)); -+ return -2; -+ } -+ -+ /* sanity ok, proceeding rx operation */ -+ /* read_len = mtk_wcn_stp_receive_data(data, size, WMT_TASK_INDX); */ -+ readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX); -+ -+ while (readLen == 0) { /* got nothing, wait for STP's signal */ -+ WMT_LOUD_FUNC("before wmt_dev_rx_timeout\n"); -+ /* iRet = wait_event_interruptible(pdev->rWmtRxWq, osal_test_bit(WMT_STAT_RX, &pdev->state)); */ -+ /* waitRet = wait_event_interruptible_timeout( -+ * pDev->rWmtRxWq, -+ * osal_test_bit(WMT_STAT_RX, &pdev->state), -+ * msecs_to_jiffies(WMT_LIB_RX_TIMEOUT)); -+ */ -+ pDev->rWmtRxWq.timeoutValue = WMT_LIB_RX_TIMEOUT; -+ /* waitRet = osal_wait_for_event_bit_timeout(&pDev->rWmtRxWq, &pDev->state, WMT_STAT_RX); */ -+ waitRet = wmt_dev_rx_timeout(&pDev->rWmtRxWq); -+ -+ WMT_LOUD_FUNC("wmt_dev_rx_timeout returned\n"); -+ -+ if (0 == waitRet) { -+ WMT_ERR_FUNC("wmt_dev_rx_timeout: timeout,jiffies(%lu),timeoutvalue(%d)\n", -+ jiffies, pDev->rWmtRxWq.timeoutValue); -+ return -1; -+ } else if (waitRet < 0) { -+ WMT_WARN_FUNC("wmt_dev_rx_timeout: interrupted by signal (%ld)\n", waitRet); -+ return waitRet; -+ } -+ WMT_DBG_FUNC("wmt_dev_rx_timeout, iRet(%ld)\n", waitRet); -+ /* read_len = mtk_wcn_stp_receive_data(data, size, WMT_TASK_INDX); */ -+ readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX); -+ -+ if (0 == readLen) -+ WMT_WARN_FUNC("wmt_ctrl_rx be signaled, but no rx data(%ld)\n", waitRet); -+ -+ } -+ -+ if (readSize) -+ *readSize = readLen; -+ -+ return 0; -+ -+} -+ -+INT32 wmt_ctrl_tx_ex(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ INT32 iRet; -+ -+ if (NULL != writtenSize) -+ *writtenSize = 0; -+ -+ /* sanity check */ -+ if (0 == size) { -+ WMT_WARN_FUNC("size to tx is 0\n"); -+ osal_assert(size); -+ return -1; -+ } -+ -+ /* if STP is not enabled yet, can't use this function. Use tx_raw instead */ -+ if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state) || !osal_test_bit(WMT_STAT_STP_EN, &pDev->state)) { -+ WMT_ERR_FUNC("wmt state(0x%lx)\n", pDev->state); -+ osal_assert(osal_test_bit(WMT_STAT_STP_EN, &pDev->state)); -+ osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)); -+ return -2; -+ } -+ -+ /* sanity ok, proceeding tx operation */ -+ /*retval = mtk_wcn_stp_send_data(data, size, WMTDRV_TYPE_WMT); */ -+ mtk_wcn_stp_flush_rx_queue(WMT_TASK_INDX); -+ if (bRawFlag) -+ iRet = mtk_wcn_stp_send_data_raw(pData, size, WMT_TASK_INDX); -+ else -+ iRet = mtk_wcn_stp_send_data(pData, size, WMT_TASK_INDX); -+ -+ if (iRet != size) { -+ WMT_WARN_FUNC("write(%d) written(%d)\n", size, iRet); -+ osal_assert(iRet == size); -+ } -+ -+ if (writtenSize) -+ *writtenSize = iRet; -+ -+ return 0; -+ -+} -+ -+INT32 wmt_ctrl_rx_flush(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT32 type = pWmtCtrlData->au4CtrlData[0]; -+ -+ WMT_INFO_FUNC("flush rx %d queue\n", type); -+ mtk_wcn_stp_flush_rx_queue(type); -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_hw_pwr_off(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iret; -+ -+/*psm should be disabled before wmt_ic_deinit*/ -+ P_DEV_WMT pDev = &gDevWmt; -+ -+ if (osal_test_and_clear_bit(WMT_STAT_PWR, &pDev->state)) { -+ WMT_DBG_FUNC("on->off\n"); -+ iret = wmt_plat_pwr_ctrl(FUNC_OFF); -+ } else { -+ WMT_WARN_FUNC("already off\n"); -+ iret = 0; -+ } -+ -+ return iret; -+} -+ -+INT32 wmt_ctrl_hw_pwr_on(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iret; -+ /*psm should be enabled right after wmt_ic_init */ -+ P_DEV_WMT pDev = &gDevWmt; -+ if (osal_test_and_set_bit(WMT_STAT_PWR, &pDev->state)) { -+ WMT_WARN_FUNC("already on\n"); -+ iret = 0; -+ } else { -+ WMT_DBG_FUNC("off->on\n"); -+ iret = wmt_plat_pwr_ctrl(FUNC_ON); -+ } -+ -+ return iret; -+} -+ -+INT32 wmt_ctrl_ul_cmd(P_DEV_WMT pWmtDev, const UINT8 *pCmdStr) -+{ -+ INT32 waitRet = -1; -+ P_OSAL_SIGNAL pCmdSignal; -+ P_OSAL_EVENT pCmdReq; -+ -+ if (osal_test_and_set_bit(WMT_STAT_CMD, &pWmtDev->state)) { -+ WMT_WARN_FUNC("cmd buf is occupied by (%s)\n", pWmtDev->cCmd); -+ return -1; -+ } -+ -+ /* indicate baud rate change to user space app */ -+#if 0 -+ INIT_COMPLETION(pWmtDev->cmd_comp); -+ pWmtDev->cmd_result = -1; -+ strncpy(pWmtDev->cCmd, pCmdStr, NAME_MAX); -+ pWmtDev->cCmd[NAME_MAX] = '\0'; -+ wake_up_interruptible(&pWmtDev->cmd_wq); -+#endif -+ -+ pCmdSignal = &pWmtDev->cmdResp; -+ osal_signal_init(pCmdSignal); -+ pCmdSignal->timeoutValue = 2000; -+ osal_strncpy(pWmtDev->cCmd, pCmdStr, NAME_MAX); -+ pWmtDev->cCmd[NAME_MAX] = '\0'; -+ -+ pCmdReq = &pWmtDev->cmdReq; -+ -+ osal_trigger_event(&pWmtDev->cmdReq); -+ WMT_DBG_FUNC("str(%s) request ok\n", pCmdStr); -+ -+/* waitRet = wait_for_completion_interruptible_timeout(&pWmtDev->cmd_comp, msecs_to_jiffies(2000)); */ -+ waitRet = osal_wait_for_signal_timeout(pCmdSignal); -+ WMT_LOUD_FUNC("wait signal iRet:%d\n", waitRet); -+ if (0 == waitRet) { -+ WMT_ERR_FUNC("wait signal timeout\n"); -+ return -2; -+ } -+ -+ WMT_DBG_FUNC("str(%s) result(%d)\n", pCmdStr, pWmtDev->cmdResult); -+ -+ return pWmtDev->cmdResult; -+} -+ -+INT32 wmt_ctrl_hw_rst(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ wmt_plat_pwr_ctrl(FUNC_RST); -+ return 0; -+} -+ -+INT32 wmt_ctrl_hw_state_show(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ wmt_plat_pwr_ctrl(FUNC_STAT); -+ return 0; -+} -+ -+INT32 wmt_ctrl_stp_close(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ INT32 iRet = 0; -+ /* un-register to STP-core for rx */ -+ iRet = mtk_wcn_stp_register_event_cb(WMT_TASK_INDX, NULL); /* mtk_wcn_stp_register_event_cb */ -+ if (iRet) { -+ WMT_WARN_FUNC("stp_reg cb unregister fail(%d)\n", iRet); -+ return -1; -+ } -+ -+ /*un-register rxcb to btif */ -+ iRet = mtk_wcn_stp_rxcb_register(NULL); -+ if (iRet) { -+ WMT_WARN_FUNC("mtk_wcn_stp_rxcb_unregister fail(%d)\n", iRet); -+ return -2; -+ } -+ -+ iRet = mtk_wcn_stp_close_btif(); -+ if (iRet) { -+ WMT_WARN_FUNC("mtk_wcn_stp_close_btif fail(%d)\n", iRet); -+ return -3; -+ } -+ osal_clear_bit(WMT_STAT_STP_OPEN, &pDev->state); -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_stp_open(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ INT32 iRet; -+ -+ iRet = mtk_wcn_stp_open_btif(); -+ if (iRet) { -+ WMT_WARN_FUNC("mtk_wcn_stp_open_btif fail(%d)\n", iRet); -+ return -1; -+ } -+ -+ /*register stp rx call back to btif */ -+ iRet = mtk_wcn_stp_rxcb_register((MTK_WCN_BTIF_RX_CB) mtk_wcn_stp_parser_data); -+ if (iRet) { -+ WMT_WARN_FUNC("mtk_wcn_stp_rxcb_register fail(%d)\n", iRet); -+ return -2; -+ } -+ /* register to STP-core for rx */ -+ iRet = mtk_wcn_stp_register_event_cb(WMT_TASK_INDX, wmt_dev_rx_event_cb); -+ if (iRet) { -+ WMT_WARN_FUNC("stp_reg cb fail(%d)\n", iRet); -+ return -3; -+ } -+ -+ osal_set_bit(WMT_STAT_STP_OPEN, &pDev->state); -+ -+#if 0 -+ iRet = mtk_wcn_stp_lpbk_ctrl(1); -+#endif -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_patch_search(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ INT32 iRet; -+ UINT8 cmdStr[NAME_MAX + 1] = { 0 }; -+ -+ osal_snprintf(cmdStr, NAME_MAX, "srh_patch"); -+ iRet = wmt_ctrl_ul_cmd(pDev, cmdStr); -+ if (iRet) { -+ WMT_WARN_FUNC("wmt_ctrl_ul_cmd fail(%d)\n", iRet); -+ return -1; -+ } -+ return 0; -+} -+ -+INT32 wmt_ctrl_get_patch_num(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ -+ pWmtCtrlData->au4CtrlData[0] = pDev->patchNum; -+ return 0; -+} -+ -+INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ UINT32 downLoadSeq = 0; -+ P_WMT_PATCH_INFO pPatchinfo = NULL; -+ PUINT8 pNbuf = NULL; -+ PUINT8 pAbuf = NULL; -+ -+ downLoadSeq = pWmtCtrlData->au4CtrlData[0]; -+ WMT_DBG_FUNC("download seq is %d\n", downLoadSeq); -+ -+ pPatchinfo = pDev->pWmtPatchInfo + downLoadSeq - 1; -+ pNbuf = (PUINT8) pWmtCtrlData->au4CtrlData[1]; -+ pAbuf = (PUINT8) pWmtCtrlData->au4CtrlData[2]; -+ if (pPatchinfo) { -+ osal_memcpy(pNbuf, pPatchinfo->patchName, osal_sizeof(pPatchinfo->patchName)); -+ osal_memcpy(pAbuf, pPatchinfo->addRess, osal_sizeof(pPatchinfo->addRess)); -+ WMT_DBG_FUNC("get 4 address bytes is 0x%2x,0x%2x,0x%2x,0x%2x", pAbuf[0], pAbuf[1], pAbuf[2], pAbuf[3]); -+ } else { -+ WMT_ERR_FUNC("NULL patchinfo pointer\n"); -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_soc_paldo_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = 0; -+ ENUM_PALDO_TYPE ept = pWmtCtrlData->au4CtrlData[0]; -+ ENUM_PALDO_OP epo = pWmtCtrlData->au4CtrlData[1]; -+ -+ WMT_DBG_FUNC("ept(%d),epo(%d)\n", ept, epo); -+ iRet = wmt_plat_soc_paldo_ctrl(ept, epo); -+ if (iRet) { -+ if (PMIC_CHIPID_PALDO == ept) { -+ /* special handling for PMIC CHIPID */ -+ pWmtCtrlData->au4CtrlData[2] = iRet; -+ } else { -+ /* for other PA handling */ -+ WMT_ERR_FUNC("soc palod ctrl fail(%d)\n", iRet); -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 wmt_ctrl_soc_wakeup_consys(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = 0; -+ -+ iRet = mtk_wcn_stp_wakeup_consys(); -+ if (iRet) -+ WMT_ERR_FUNC("soc palod ctrl fail(%d)\n", iRet); -+ -+ return iRet; -+} -+ -+INT32 wmt_ctrl_stp_conf_ex(WMT_STP_CONF_TYPE type, UINT32 value) -+{ -+ INT32 iRet = -1; -+ -+ switch (type) { -+ case WMT_STP_CONF_EN: -+ iRet = mtk_wcn_stp_enable(value); -+ break; -+ -+ case WMT_STP_CONF_RDY: -+ iRet = mtk_wcn_stp_ready(value); -+ break; -+ -+ case WMT_STP_CONF_MODE: -+ mtk_wcn_stp_set_mode(value); -+ iRet = 0; -+ break; -+ -+ default: -+ WMT_WARN_FUNC("invalid type(%d) value(%d)\n", type, value); -+ break; -+ } -+ return iRet; -+} -+ -+INT32 wmt_ctrl_stp_conf(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = -1; -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ UINT32 type; -+ UINT32 value; -+ -+ if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) { -+ WMT_WARN_FUNC("CTRL_STP_ENABLE but invalid Handle of WmtStp\n"); -+ return -1; -+ } -+ -+ type = pWmtCtrlData->au4CtrlData[0]; -+ value = pWmtCtrlData->au4CtrlData[1]; -+ iRet = wmt_ctrl_stp_conf_ex(type, value); -+ -+ if (!iRet) { -+ if (WMT_STP_CONF_EN == type) { -+ if (value) { -+ osal_set_bit(WMT_STAT_STP_EN, &pDev->state); -+ WMT_DBG_FUNC("enable STP\n"); -+ } else { -+ osal_clear_bit(WMT_STAT_STP_EN, &pDev->state); -+ WMT_DBG_FUNC("disable STP\n"); -+ } -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 wmt_ctrl_free_patch(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT32 patchSeq = pWmtCtrlData->au4CtrlData[0]; -+ -+ WMT_DBG_FUNC("BF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch); -+ if (NULL != gDevWmt.pPatch) -+ wmt_dev_patch_put((osal_firmware **) &(gDevWmt.pPatch)); -+ -+ WMT_DBG_FUNC("AF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch); -+ if (patchSeq == gDevWmt.patchNum) { -+ WMT_DBG_FUNC("the %d patch has been download\n", patchSeq); -+ wmt_dev_patch_info_free(); -+ } -+ return 0; -+} -+ -+INT32 wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ PUINT8 pBuf = (PUINT8) pWmtCtrlData->au4CtrlData[0]; -+ -+ osal_memcpy(pBuf, gDevWmt.cPatchName, osal_sizeof(gDevWmt.cPatchName)); -+ return 0; -+} -+ -+INT32 wmt_ctrl_crystal_triming_put(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ WMT_DBG_FUNC("BF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch); -+ if (NULL != gDevWmt.pNvram) -+ wmt_dev_patch_put((osal_firmware **) &(gDevWmt.pNvram)); -+ -+ WMT_DBG_FUNC("AF free patch, gDevWmt.pNvram(0x%08x)\n", gDevWmt.pNvram); -+ return 0; -+} -+ -+INT32 wmt_ctrl_crystal_triming_get(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = 0x0; -+ PUINT8 pFileName = (PUINT8) pWmtCtrlData->au4CtrlData[0]; -+ PPUINT8 ppBuf = (PPUINT8) pWmtCtrlData->au4CtrlData[1]; -+ PUINT32 pSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; -+ -+ osal_firmware *pNvram = NULL; -+ -+ if ((NULL == pFileName) || (NULL == pSize)) { -+ WMT_ERR_FUNC("parameter error, pFileName(0x%08x), pSize(0x%08x)\n", pFileName, pSize); -+ iRet = -1; -+ return iRet; -+ } -+ if (0 == wmt_dev_patch_get(pFileName, &pNvram, 0)) { -+ *ppBuf = (PUINT8) (pNvram)->data; -+ *pSize = (pNvram)->size; -+ gDevWmt.pNvram = pNvram; -+ return 0; -+ } -+ return -1; -+ -+} -+ -+INT32 wmt_ctrl_get_patch(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT8 *pFullPatchName = NULL; -+ UINT8 *pDefPatchName = NULL; -+ PUINT8 *ppBuf = (PUINT8 *) pWmtCtrlData->au4CtrlData[2]; -+ PUINT32 pSize = (PUINT32) pWmtCtrlData->au4CtrlData[3]; -+ -+ osal_firmware *pPatch = NULL; -+ -+ pFullPatchName = (PUINT8) pWmtCtrlData->au4CtrlData[1]; -+ WMT_DBG_FUNC("BF get patch, pPatch(0x%08x)\n", pPatch); -+ if ((NULL != pFullPatchName) -+ && (0 == wmt_dev_patch_get(pFullPatchName, &pPatch, BCNT_PATCH_BUF_HEADROOM))) { -+ /*get full name patch success */ -+ WMT_DBG_FUNC("get full patch name(%s) buf(0x%p) size(%d)\n", -+ pFullPatchName, (pPatch)->data, (pPatch)->size); -+ WMT_DBG_FUNC("AF get patch, pPatch(0x%08x)\n", pPatch); -+ *ppBuf = (PUINT8) (pPatch)->data; -+ *pSize = (pPatch)->size; -+ gDevWmt.pPatch = pPatch; -+ return 0; -+ } -+ -+ pDefPatchName = (PUINT8) pWmtCtrlData->au4CtrlData[0]; -+ if ((NULL != pDefPatchName) -+ && (0 == wmt_dev_patch_get(pDefPatchName, &pPatch, BCNT_PATCH_BUF_HEADROOM))) { -+ WMT_DBG_FUNC("get def patch name(%s) buf(0x%p) size(%d)\n", -+ pDefPatchName, (pPatch)->data, (pPatch)->size); -+ WMT_DBG_FUNC("AF get patch, pPatch(0x%08x)\n", pPatch); -+ /*get full name patch success */ -+ *ppBuf = (PUINT8) (pPatch)->data; -+ *pSize = (pPatch)->size; -+ gDevWmt.pPatch = pPatch; -+ return 0; -+ } -+ return -1; -+ -+} -+ -+/*do not need contol uart because B/G/F send/receive data by BTIF*/ -+#if 0 -+INT32 wmt_ctrl_host_baudrate_set(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = -1; -+ char cmdStr[NAME_MAX + 1] = { 0 }; -+ UINT32 u4Baudrate = pWmtCtrlData->au4CtrlData[0]; -+ UINT32 u4FlowCtrl = pWmtCtrlData->au4CtrlData[1]; -+ -+ WMT_DBG_FUNC("baud(%d), flowctrl(%d)\n", u4Baudrate, u4FlowCtrl); -+ -+ if (osal_test_bit(WMT_STAT_STP_OPEN, &gDevWmt.state)) { -+ osal_snprintf(cmdStr, NAME_MAX, "baud_%d_%d", u4Baudrate, u4FlowCtrl); -+ iRet = wmt_ctrl_ul_cmd(&gDevWmt, cmdStr); -+ if (iRet) { -+ WMT_WARN_FUNC("CTRL_BAUDRATE baud(%d), flowctrl(%d) fail(%d)\n", -+ u4Baudrate, pWmtCtrlData->au4CtrlData[1], iRet); -+ } else { -+ WMT_DBG_FUNC("CTRL_BAUDRATE baud(%d), flowctrl(%d) ok\n", u4Baudrate, u4FlowCtrl); -+ } -+ } else { -+ WMT_INFO_FUNC("CTRL_BAUDRATE but invalid Handle of WmtStp\n"); -+ } -+ return iRet; -+} -+#endif -+/*do not need control SDIO because wifi send/receive data by sdio*/ -+#if 0 -+INT32 wmt_ctrl_sdio_hw(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = 0; -+ UINT32 statBit = WMT_STAT_SDIO1_ON; -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ -+ WMT_SDIO_SLOT_NUM sdioSlotNum = pWmtCtrlData->au4CtrlData[0]; -+ ENUM_FUNC_STATE funcState = pWmtCtrlData->au4CtrlData[1]; -+ -+ if ((WMT_SDIO_SLOT_INVALID == sdioSlotNum) -+ || (WMT_SDIO_SLOT_MAX <= sdioSlotNum)) { -+ WMT_WARN_FUNC("CTRL_SDIO_SLOT(%d) but invalid slot num\n", sdioSlotNum); -+ return -1; -+ } -+ -+ WMT_DBG_FUNC("WMT_CTRL_SDIO_HW (0x%x, %d)\n", sdioSlotNum, funcState); -+ -+ if (WMT_SDIO_SLOT_SDIO2 == sdioSlotNum) -+ statBit = WMT_STAT_SDIO2_ON; -+ -+ if (funcState) { -+ if (osal_test_and_set_bit(statBit, &pDev->state)) { -+ WMT_WARN_FUNC("CTRL_SDIO_SLOT slotNum(%d) already ON\n", sdioSlotNum); -+ /* still return 0 */ -+ iRet = 0; -+ } else { -+ iRet = wmt_plat_sdio_ctrl(sdioSlotNum, FUNC_ON); -+ } -+ } else { -+ if (osal_test_and_clear_bit(statBit, &pDev->state)) { -+ iRet = wmt_plat_sdio_ctrl(sdioSlotNum, FUNC_OFF); -+ } else { -+ WMT_WARN_FUNC("CTRL_SDIO_SLOT slotNum(%d) already OFF\n", sdioSlotNum); -+ /* still return 0 */ -+ iRet = 0; -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = -1; -+ UINT32 statBit = WMT_STAT_SDIO_WIFI_ON; -+ INT32 retry = 10; -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ WMT_SDIO_FUNC_TYPE sdioFuncType = pWmtCtrlData->au4CtrlData[0]; -+ UINT32 u4On = pWmtCtrlData->au4CtrlData[1]; -+ -+ if (WMT_SDIO_FUNC_MAX <= sdioFuncType) { -+ WMT_ERR_FUNC("CTRL_SDIO_FUNC, invalid func type (%d)\n", sdioFuncType); -+ return -1; -+ } -+ -+ if (WMT_SDIO_FUNC_STP == sdioFuncType) -+ statBit = WMT_STAT_SDIO_STP_ON; -+ -+ if (u4On) { -+ if (osal_test_bit(statBit, &pDev->state)) { -+ WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already ON\n", sdioFuncType); -+ iRet = 0; -+ } else { -+ while (retry-- > 0 && iRet != 0) { -+ if (iRet) { -+ /* sleep 150ms before sdio slot ON ready */ -+ osal_sleep_ms(150); -+ } -+ iRet = mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_TRUE); -+ if (HIF_SDIO_ERR_NOT_PROBED == iRet) { -+ /* not probed case, retry */ -+ continue; -+ } else if (HIF_SDIO_ERR_CLT_NOT_REG == iRet) { -+ /* For WiFi, client not reg yet, no need to retry, -+ *WiFi function can work any time when wlan.ko -+ *is insert into system -+ */ -+ iRet = 0; -+ } else { -+ /* other fail cases, stop */ -+ break; -+ } -+ } -+ if (!retry || iRet) { -+ WMT_ERR_FUNC("mtk_wcn_hif_sdio_wmt_control(%d, TRUE) fail(%d) retry(%d)\n", -+ sdioFuncType, iRet, retry); -+ } else { -+ osal_set_bit(statBit, &pDev->state); -+ } -+ } -+ } else { -+ if (osal_test_bit(statBit, &pDev->state)) { -+ iRet = mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_FALSE); -+ if (iRet) -+ WMT_ERR_FUNC("mtk_wcn_hif_sdio_wmt_control(%d, FALSE) fail(%d)\n", sdioFuncType, iRet); -+ /*any way, set to OFF state */ -+ osal_clear_bit(statBit, &pDev->state); -+ } else { -+ WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already OFF\n", sdioFuncType); -+ iRet = 0; -+ } -+ } -+ -+ return iRet; -+} -+#endif -+ -+ -+INT32 wmt_ctrl_hwidver_set(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ -+ /* input sanity check is done in wmt_ctrl() */ -+ pDev->chip_id = (pWmtCtrlData->au4CtrlData[0] & 0xFFFF0000) >> 16; -+ pDev->hw_ver = pWmtCtrlData->au4CtrlData[0] & 0x0000FFFF; -+ pDev->fw_ver = pWmtCtrlData->au4CtrlData[1] & 0x0000FFFF; -+ -+ /* TODO: [FixMe][GeorgeKuo] remove translated ENUM_WMTHWVER_TYPE_T in the future!!! */ -+ /* Only use hw_ver read from hw. */ -+ pDev->eWmtHwVer = (ENUM_WMTHWVER_TYPE_T) (pWmtCtrlData->au4CtrlData[1] & 0xFFFF0000) >> 16; -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_set_stp_dbg_info(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT8 *pRomVer = NULL; -+ P_WMT_PATCH pPatch = NULL; -+ UINT32 chipID = 0; -+ -+ chipID = pWmtCtrlData->au4CtrlData[0]; -+ pRomVer = (PUINT8) (pWmtCtrlData->au4CtrlData[1]); -+ pPatch = (P_WMT_PATCH) (pWmtCtrlData->au4CtrlData[2]); -+ if (!pRomVer) { -+ WMT_ERR_FUNC("pRomVer null pointer\n"); -+ return -1; -+ } -+ if (!pPatch) { -+ WMT_ERR_FUNC("pPatch null pointer\n"); -+ return -2; -+ } -+ WMT_DBG_FUNC("chipid(0x%x),rom(%s),patch date(%s),patch plat(%s)\n", chipID, pRomVer, pPatch->ucDateTime, -+ pPatch->ucPLat); -+ return stp_dbg_set_version_info(chipID, pRomVer, &(pPatch->ucDateTime[0]), &(pPatch->ucPLat[0])); -+} -+ -+static INT32 wmt_ctrl_bgw_desense_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT32 cmd = pWmtCtrlData->au4CtrlData[0]; -+ -+ WMT_INFO_FUNC("wmt-ctrl:send native cmd(%d)\n", cmd); -+ wmt_dev_send_cmd_to_daemon(cmd); -+ -+ return 0; -+} -+ -+static INT32 wmt_ctrl_evt_err_trg_assert(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = -1; -+ -+ ENUM_WMTDRV_TYPE_T drv_type; -+ UINT32 reason = 0; -+ -+ drv_type = pWmtCtrlData->au4CtrlData[0]; -+ reason = pWmtCtrlData->au4CtrlData[1]; -+ WMT_WARN_FUNC("wmt-ctrl:drv_type(%d),reason(%d)\n", drv_type, reason); -+ -+ if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) { -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(1); -+ wmt_lib_set_host_assert_info(drv_type, reason, 1); -+ -+ iRet = mtk_wcn_stp_wmt_evt_err_trg_assert(); -+ if (iRet) -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); -+ } else { -+ /* maybe assert triggered by stp noack*/ -+ WMT_INFO_FUNC("do trigger assert & chip reset in stp noack\n"); -+ } -+ return 0; -+} -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 wmt_ctrl_get_tdm_req_antsel(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 antsel_index = wmt_plat_get_tdm_antsel_index(); -+ -+ if (0 <= antsel_index) -+ pWmtCtrlData->au4CtrlData[0] = antsel_index; -+ else -+ pWmtCtrlData->au4CtrlData[0] = 0xff; -+ -+ WMT_INFO_FUNC("get tdm req antsel index is %d\n", antsel_index); -+ -+ return 0; -+} -+#endif -+ -+static INT32 wmt_ctrl_evt_parser(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 ret = -1; -+ UINT32 evt_idx = (UINT32) pWmtCtrlData->au4CtrlData[0]; -+ UINT8 *p_buf = NULL; -+ -+ static UINT8 sleep_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x01 }; -+ static UINT8 wakeup_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; -+ static UINT8 hostawake_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x02 }; -+ static UINT8 *evt_array[] = { sleep_evt, wakeup_evt, hostawake_evt }; -+ -+ p_buf = evt_array[evt_idx - 1]; -+ -+ WMT_INFO_FUNC("evt index:%d,p_buf:%p\n", evt_idx, p_buf); -+ -+ ret = mtk_wcn_consys_stp_btif_parser_wmt_evt(p_buf, 6); -+ if (ret == 1) { -+ WMT_INFO_FUNC("parser wmt evt from BTIF buf is OK\n"); -+ return 0; -+ } -+ WMT_ERR_FUNC("parser wmt evt from BTIF buf fail(%d)\n", ret); -+ return -1; -+} -+ -+static INT32 wmt_ctrl_gps_sync_set(P_WMT_CTRL_DATA pData) -+{ -+ INT32 iret; -+ -+ WMT_INFO_FUNC("ctrl GPS_SYNC(%d)\n", (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX); -+ iret = wmt_plat_gpio_ctrl(PIN_GPS_SYNC, (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX); -+ -+ if (iret) { -+ WMT_WARN_FUNC("ctrl GPS_SYNC(%d) fail!(%d) ignore it...\n", -+ (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX, iret); -+ } -+ -+ return 0; -+} -+ -+static INT32 wmt_ctrl_gps_lna_set(P_WMT_CTRL_DATA pData) -+{ -+ INT32 iret; -+ -+ WMT_INFO_FUNC("ctrl GPS_LNA(%d)\n", (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H); -+ iret = wmt_plat_gpio_ctrl(PIN_GPS_LNA, (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H); -+ -+ if (iret) { -+ WMT_WARN_FUNC("ctrl GPS_SYNC(%d) fail!(%d) ignore it...\n", -+ (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H, iret); -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_stp_rst(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ return 0; -+} -+ -+INT32 wmt_ctrl_get_wmt_conf(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ -+ pWmtCtrlData->au4CtrlData[0] = (SIZE_T) &pDev->rWmtGenConf; -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_others(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ WMT_ERR_FUNC("wmt_ctrl_others, invalid CTRL ID (%d)\n", pWmtCtrlData->ctrlId); -+ return -1; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c -new file mode 100644 -index 0000000000000..d42d572c92922 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c -@@ -0,0 +1,713 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-FUNC]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+ -+#include "wmt_func.h" -+#include "wmt_lib.h" -+#include "wmt_core.h" -+#include "wmt_exp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if CFG_FUNC_BT_SUPPORT -+ -+static INT32 wmt_func_bt_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+static INT32 wmt_func_bt_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+ -+WMT_FUNC_OPS wmt_func_bt_ops = { -+ /* BT subsystem function on/off */ -+ .func_on = wmt_func_bt_on, -+ .func_off = wmt_func_bt_off -+}; -+#endif -+ -+#if CFG_FUNC_FM_SUPPORT -+ -+static INT32 wmt_func_fm_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+static INT32 wmt_func_fm_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+ -+WMT_FUNC_OPS wmt_func_fm_ops = { -+ /* FM subsystem function on/off */ -+ .func_on = wmt_func_fm_on, -+ .func_off = wmt_func_fm_off -+}; -+#endif -+ -+#if CFG_FUNC_GPS_SUPPORT -+ -+static INT32 wmt_func_gps_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+static INT32 wmt_func_gps_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+ -+WMT_FUNC_OPS wmt_func_gps_ops = { -+ /* GPS subsystem function on/off */ -+ .func_on = wmt_func_gps_on, -+ .func_off = wmt_func_gps_off -+}; -+ -+#endif -+ -+#if CFG_FUNC_WIFI_SUPPORT -+static INT32 wmt_func_wifi_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+static INT32 wmt_func_wifi_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+ -+WMT_FUNC_OPS wmt_func_wifi_ops = { -+ /* Wi-Fi subsystem function on/off */ -+ .func_on = wmt_func_wifi_on, -+ .func_off = wmt_func_wifi_off -+}; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if CFG_FUNC_GPS_SUPPORT -+CMB_PIN_CTRL_REG eediPinOhRegs[] = { -+ { -+ /* pull down ctrl register */ -+ .regAddr = 0x80050020, -+ .regValue = ~(0x1 << 5), -+ .regMask = 0x00000020, -+ }, -+ { -+ /* pull up ctrl register */ -+ .regAddr = 0x80050000, -+ .regValue = 0x1 << 5, -+ .regMask = 0x00000020, -+ }, -+ { -+ /* iomode ctrl register */ -+ .regAddr = 0x80050110, -+ .regValue = 0x1 << 0, -+ .regMask = 0x00000007, -+ }, -+ { -+ /* output high/low ctrl register */ -+ .regAddr = 0x80050040, -+ .regValue = 0x1 << 5, -+ .regMask = 0x00000020, -+ } -+ -+}; -+ -+CMB_PIN_CTRL_REG eediPinOlRegs[] = { -+ { -+ .regAddr = 0x80050020, -+ .regValue = 0x1 << 5, -+ .regMask = 0x00000020UL, -+ }, -+ { -+ .regAddr = 0x80050000, -+ .regValue = ~(0x1 << 5), -+ .regMask = 0x00000020, -+ }, -+ { -+ .regAddr = 0x80050110, -+ .regValue = 0x1 << 0, -+ .regMask = 0x00000007, -+ }, -+ { -+ .regAddr = 0x80050040, -+ .regValue = ~(0x1 << 5), -+ .regMask = 0x00000020, -+ } -+}; -+ -+CMB_PIN_CTRL_REG eedoPinOhRegs[] = { -+ { -+ .regAddr = 0x80050020, -+ .regValue = ~(0x1 << 7), -+ .regMask = 0x00000080UL, -+ }, -+ { -+ .regAddr = 0x80050000, -+ .regValue = 0x1 << 7, -+ .regMask = 0x00000080UL, -+ }, -+ { -+ .regAddr = 0x80050110, -+ .regValue = 0x1 << 12, -+ .regMask = 0x00007000UL, -+ }, -+ { -+ .regAddr = 0x80050040, -+ .regValue = 0x1 << 7, -+ .regMask = 0x00000080, -+ } -+}; -+ -+CMB_PIN_CTRL_REG eedoPinOlRegs[] = { -+ { -+ .regAddr = 0x80050020, -+ .regValue = 0x1 << 7, -+ .regMask = 0x00000080, -+ }, -+ { -+ .regAddr = 0x80050000, -+ .regValue = ~(0x1 << 7), -+ .regMask = 0x00000080, -+ }, -+ { -+ .regAddr = 0x80050110, -+ .regValue = 0x1 << 12, -+ .regMask = 0x00007000, -+ }, -+ { -+ .regAddr = 0x80050040, -+ .regValue = ~(0x1 << 7), -+ .regMask = 0x00000080, -+ } -+ -+}; -+ -+CMB_PIN_CTRL_REG gsyncPinOnRegs[] = { -+ { -+ .regAddr = 0x80050110, -+ .regValue = 0x3 << 20, -+ .regMask = 0x7 << 20, -+ } -+ -+}; -+ -+CMB_PIN_CTRL_REG gsyncPinOffRegs[] = { -+ { -+ .regAddr = 0x80050110, -+ .regValue = 0x0 << 20, -+ .regMask = 0x7 << 20, -+ } -+}; -+ -+/* templete usage for GPIO control */ -+CMB_PIN_CTRL gCmbPinCtrl[3] = { -+ { -+ .pinId = CMB_PIN_EEDI_ID, -+ .regNum = 4, -+ .pFuncOnArray = eediPinOhRegs, -+ .pFuncOffArray = eediPinOlRegs, -+ }, -+ { -+ .pinId = CMB_PIN_EEDO_ID, -+ .regNum = 4, -+ .pFuncOnArray = eedoPinOhRegs, -+ .pFuncOffArray = eedoPinOlRegs, -+ }, -+ { -+ .pinId = CMB_PIN_GSYNC_ID, -+ .regNum = 1, -+ .pFuncOnArray = gsyncPinOnRegs, -+ .pFuncOffArray = gsyncPinOffRegs, -+ } -+}; -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#if CFG_FUNC_BT_SUPPORT -+ -+INT32 _osal_inline_ wmt_func_bt_ctrl(ENUM_FUNC_STATE funcState) -+{ -+ /*only need to send turn BT subsystem wmt command */ -+ return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); -+} -+ -+INT32 wmt_func_bt_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ /* return wmt_func_bt_ctrl(FUNC_ON); */ -+ INT32 iRet = -1; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_ON; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt-func: wmt_ctrl_soc_paldo_ctrl failed(%d)(%d)(%d)\n", iRet, ctrlPa1, ctrlPa2); -+ return -1; -+ } -+ iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, MTK_WCN_BOOL_TRUE); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt-func: wmt_core_func_ctrl_cmd(bt_on) failed(%d)\n", iRet); -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ -+ /*do coredump when bt on fail */ -+ wmt_core_set_coredump_state(DRV_STS_FUNC_ON); -+ ctrlPa1 = WMTDRV_TYPE_BT; -+ ctrlPa2 = 32; -+ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &ctrlPa1, &ctrlPa2); -+ return -2; -+ } -+ osal_set_bit(WMT_BT_ON, &gBtWifiGpsState); -+ if (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState)) { -+ /* send msg to GPS native for sending de-sense CMD */ -+ ctrlPa1 = 1; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ return 0; -+} -+ -+INT32 wmt_func_bt_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ /* return wmt_func_bt_ctrl(FUNC_OFF); */ -+ INT32 iRet1 = -1; -+ INT32 iRet2 = -1; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ iRet1 = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, MTK_WCN_BOOL_FALSE); -+ if (iRet1) -+ WMT_ERR_FUNC("wmt-func: wmt_core_func_ctrl_cmd(bt_off) failed(%d)\n", iRet1); -+ -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ iRet2 = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ if (iRet2) -+ WMT_ERR_FUNC("wmt-func: wmt_ctrl_soc_paldo_ctrl(bt_off) failed(%d)\n", iRet2); -+ -+ if (iRet1 + iRet2) { -+ /*do coredump when bt off fail */ -+ wmt_core_set_coredump_state(DRV_STS_FUNC_ON); -+ ctrlPa1 = WMTDRV_TYPE_BT; -+ ctrlPa2 = 32; -+ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &ctrlPa1, &ctrlPa2); -+ return -1; -+ } -+ -+ osal_clear_bit(WMT_BT_ON, &gBtWifiGpsState); -+ if ((!osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState)) && (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState))) { -+ /* send msg to GPS native for stopping send de-sense CMD */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ return 0; -+} -+ -+#endif -+ -+#if CFG_FUNC_GPS_SUPPORT -+ -+INT32 _osal_inline_ wmt_func_gps_ctrl(ENUM_FUNC_STATE funcState) -+{ -+ /*send turn GPS subsystem wmt command */ -+ return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_GPS, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); -+} -+ -+INT32 wmt_func_gps_pre_ctrl(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf, ENUM_FUNC_STATE funcStatus) -+{ -+ UINT32 i = 0; -+ INT32 iRet = 0; -+ UINT32 regAddr = 0; -+ UINT32 regValue = 0; -+ UINT32 regMask = 0; -+ UINT32 regNum = 0; -+ P_CMB_PIN_CTRL_REG pReg; -+ P_CMB_PIN_CTRL pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_GSYNC_ID]; -+ WMT_CTRL_DATA ctrlData; -+ WMT_IC_PIN_ID wmtIcPinId = WMT_IC_PIN_MAX; -+ /* sanity check */ -+ if (FUNC_ON != funcStatus && FUNC_OFF != funcStatus) { -+ WMT_ERR_FUNC("invalid funcStatus(%d)\n", funcStatus); -+ return -1; -+ } -+ /* turn on GPS sync function on both side */ -+ ctrlData.ctrlId = WMT_CTRL_GPS_SYNC_SET; -+ ctrlData.au4CtrlData[0] = (FUNC_ON == funcStatus) ? 1 : 0; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /*we suppose this would never print */ -+ WMT_ERR_FUNC("ctrl GPS_SYNC_SET(%d) fail, ret(%d)\n", funcStatus, iRet); -+ /* TODO:[FixMe][George] error handling? */ -+ return -2; -+ } -+ WMT_INFO_FUNC("ctrl GPS_SYNC_SET(%d) ok\n", funcStatus); -+ -+ -+ if ((NULL == pOps->ic_pin_ctrl) || -+ (0 > pOps->ic_pin_ctrl( -+ WMT_IC_PIN_GSYNC, -+ FUNC_ON == funcStatus ? WMT_IC_PIN_MUX : WMT_IC_PIN_GPIO, -+ 1))) { /*WMT_IC_PIN_GSYNC */ -+ pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_GSYNC_ID]; -+ regNum = pCmbPinCtrl->regNum; -+ for (i = 0; i < regNum; i++) { -+ if (FUNC_ON == funcStatus) -+ pReg = &pCmbPinCtrl->pFuncOnArray[i]; -+ else -+ pReg = &pCmbPinCtrl->pFuncOffArray[i]; -+ -+ regAddr = pReg->regAddr; -+ regValue = pReg->regValue; -+ regMask = pReg->regMask; -+ -+ iRet = wmt_core_reg_rw_raw(1, regAddr, ®Value, regMask); -+ if (iRet) { -+ WMT_ERR_FUNC("set reg for GPS_SYNC function fail(%d)\n", iRet); -+ /* TODO:[FixMe][Chaozhong] error handling? */ -+ return -2; -+ } -+ -+ } -+ } else { -+ WMT_INFO_FUNC("set reg for GPS_SYNC function okay by chip ic_pin_ctrl\n"); -+ } -+ WMT_INFO_FUNC("ctrl combo chip gps sync function succeed\n"); -+ /* turn on GPS lna ctrl function */ -+ if (NULL != pConf) { -+ if (0 == pConf->wmt_gps_lna_enable) { -+ -+ WMT_INFO_FUNC("host pin used for gps lna\n"); -+ /* host LNA ctrl pin needed */ -+ ctrlData.ctrlId = WMT_CTRL_GPS_LNA_SET; -+ ctrlData.au4CtrlData[0] = FUNC_ON == funcStatus ? 1 : 0; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /*we suppose this would never print */ -+ WMT_ERR_FUNC("ctrl host GPS_LNA output high fail, ret(%d)\n", iRet); -+ /* TODO:[FixMe][Chaozhong] error handling? */ -+ return -3; -+ } -+ WMT_INFO_FUNC("ctrl host gps lna function succeed\n"); -+ } else { -+ WMT_INFO_FUNC("combo chip pin(%s) used for gps lna\n", -+ 0 == pConf->wmt_gps_lna_pin ? "EEDI" : "EEDO"); -+ wmtIcPinId = 0 == pConf->wmt_gps_lna_pin ? WMT_IC_PIN_EEDI : WMT_IC_PIN_EEDO; -+ if ((NULL == pOps->ic_pin_ctrl) || -+ (0 > pOps->ic_pin_ctrl( -+ wmtIcPinId, -+ FUNC_ON == funcStatus ? WMT_IC_PIN_GPIO_HIGH : WMT_IC_PIN_GPIO_LOW, -+ 1))) { /*WMT_IC_PIN_GSYNC */ -+ if (0 == pConf->wmt_gps_lna_pin) { -+ /* EEDI needed */ -+ pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_EEDI_ID]; -+ } else if (1 == pConf->wmt_gps_lna_pin) { -+ /* EEDO needed */ -+ pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_EEDO_ID]; -+ } -+ regNum = pCmbPinCtrl->regNum; -+ for (i = 0; i < regNum; i++) { -+ if (FUNC_ON == funcStatus) -+ pReg = &pCmbPinCtrl->pFuncOnArray[i]; -+ else -+ pReg = &pCmbPinCtrl->pFuncOffArray[i]; -+ regAddr = pReg->regAddr; -+ regValue = pReg->regValue; -+ regMask = pReg->regMask; -+ -+ iRet = wmt_core_reg_rw_raw(1, regAddr, ®Value, regMask); -+ if (iRet) { -+ WMT_ERR_FUNC("set reg for GPS_LNA function fail(%d)\n", iRet); -+ /* TODO:[FixMe][Chaozhong] error handling? */ -+ return -3; -+ } -+ } -+ WMT_INFO_FUNC("ctrl combo chip gps lna succeed\n"); -+ } else { -+ WMT_INFO_FUNC("set reg for GPS_LNA function okay by chip ic_pin_ctrl\n"); -+ } -+ } -+ } -+ return 0; -+ -+} -+ -+INT32 wmt_func_gps_pre_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ return wmt_func_gps_pre_ctrl(pOps, pConf, FUNC_ON); -+} -+ -+INT32 wmt_func_gps_pre_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ -+ return wmt_func_gps_pre_ctrl(pOps, pConf, FUNC_OFF); -+} -+ -+INT32 wmt_func_gps_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ INT32 iRet = 0; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); -+ -+ if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) { /* use SOC external LNA */ -+ if (!osal_test_bit(WMT_FM_ON, &gGpsFmState)) { -+ ctrlPa1 = GPS_PALDO; -+ ctrlPa2 = PALDO_ON; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } else { -+ WMT_INFO_FUNC("LDO VCN28 has been turn on by FM\n"); -+ } -+ } -+ -+ iRet = wmt_func_gps_pre_on(pOps, pConf); -+ if (0 == iRet) { -+ iRet = wmt_func_gps_ctrl(FUNC_ON); -+ if (!iRet) { -+ osal_set_bit(WMT_GPS_ON, &gBtWifiGpsState); -+ if ((osal_test_bit(WMT_BT_ON, &gBtWifiGpsState)) -+ || (osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState))) { -+ /* send msg to GPS native for sending de-sense CMD */ -+ ctrlPa1 = 1; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ -+ if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) /* use SOC external LNA */ -+ osal_set_bit(WMT_GPS_ON, &gGpsFmState); -+ } -+ } -+ return iRet; -+} -+ -+INT32 wmt_func_gps_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ INT32 iRet = 0; -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); -+ -+ iRet = wmt_func_gps_pre_off(pOps, pConf); -+ if (0 == iRet) { -+ iRet = wmt_func_gps_ctrl(FUNC_OFF); -+ if (!iRet) { -+ osal_clear_bit(WMT_GPS_ON, &gBtWifiGpsState); -+ if ((osal_test_bit(WMT_BT_ON, &gBtWifiGpsState)) -+ || (osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState))) { -+ /* send msg to GPS native for stop sending de-sense CMD */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ } -+ } -+ -+ if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) { /* use SOC external LNA */ -+ if (osal_test_bit(WMT_FM_ON, &gGpsFmState)) -+ WMT_INFO_FUNC("FM is still on, do not turn off LDO VCN28\n"); -+ else { -+ ctrlPa1 = GPS_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ -+ osal_clear_bit(WMT_GPS_ON, &gGpsFmState); -+ } -+ -+ return iRet; -+ -+} -+#endif -+ -+#if CFG_FUNC_FM_SUPPORT -+ -+INT32 _osal_inline_ wmt_func_fm_ctrl(ENUM_FUNC_STATE funcState) -+{ -+ /*only need to send turn FM subsystem wmt command */ -+ return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); -+} -+ -+INT32 wmt_func_fm_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ /* return wmt_func_fm_ctrl(FUNC_ON); */ -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ INT32 iRet = -1; -+ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); -+ -+ if (co_clock_type) { -+ if (!osal_test_bit(WMT_GPS_ON, &gGpsFmState)) { -+ ctrlPa1 = FM_PALDO; -+ ctrlPa2 = PALDO_ON; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } else { -+ WMT_INFO_FUNC("LDO VCN28 has been turn on by GPS\n"); -+ } -+ } -+ -+ iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, MTK_WCN_BOOL_TRUE); -+ if (!iRet) { -+ if (co_clock_type) -+ osal_set_bit(WMT_FM_ON, &gGpsFmState); -+ } -+ -+ return iRet; -+} -+ -+INT32 wmt_func_fm_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ /* return wmt_func_fm_ctrl(FUNC_OFF); */ -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ INT32 iRet = -1; -+ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); -+ -+ iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, MTK_WCN_BOOL_FALSE); -+ -+ if (co_clock_type) { -+ if (osal_test_bit(WMT_GPS_ON, &gGpsFmState)) { -+ WMT_INFO_FUNC("GPS is still on, do not turn off LDO VCN28\n"); -+ } else { -+ ctrlPa1 = FM_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ -+ osal_clear_bit(WMT_FM_ON, &gGpsFmState); -+ } -+ -+ return iRet; -+} -+ -+#endif -+ -+#if CFG_FUNC_WIFI_SUPPORT -+ -+/*in soc, wmt turn on wifi directly, no not need operate SDIO*/ -+#if 0 -+INT32 wmt_func_wifi_ctrl(ENUM_FUNC_STATE funcState) -+{ -+ INT32 iRet = 0; -+ unsigned long ctrlPa1 = WMT_SDIO_FUNC_WIFI; -+ unsigned long ctrlPa2 = (FUNC_ON == funcState) ? 1 : 0; /* turn on Wi-Fi driver */ -+ -+ iRet = wmt_core_ctrl(WMT_CTRL_SDIO_FUNC, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-FUNC: turn on WIFI function fail (%d)", iRet); -+ return -1; -+ } -+ return 0; -+} -+#endif -+ -+INT32 wmt_func_wifi_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ int iRet = 0; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ if (NULL != mtk_wcn_wlan_probe) { -+ -+ WMT_WARN_FUNC("WMT-FUNC: wmt wlan func on before wlan probe\n"); -+ iRet = (*mtk_wcn_wlan_probe) (); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-FUNC: wmt call wlan probe fail(%d)\n", iRet); -+ iRet = -1; -+ } else { -+ WMT_WARN_FUNC("WMT-FUNC: wmt call wlan probe ok\n"); -+ } -+ } else { -+ WMT_ERR_FUNC("WMT-FUNC: null pointer mtk_wcn_wlan_probe\n"); -+ gWifiProbed = 1; -+ iRet = -2; -+ } -+ -+ if (!iRet) { -+ osal_set_bit(WMT_WIFI_ON, &gBtWifiGpsState); -+ if (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState)) { -+ /* send msg to GPS native for sending de-sense CMD */ -+ ctrlPa1 = 1; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ } -+ return iRet; -+#if 0 -+ return wmt_func_wifi_ctrl(FUNC_ON); -+#endif -+} -+ -+INT32 wmt_func_wifi_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ int iRet = 0; -+ -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ -+ if (NULL != mtk_wcn_wlan_remove) { -+ -+ WMT_WARN_FUNC("WMT-FUNC: wmt wlan func on before wlan remove\n"); -+ iRet = (*mtk_wcn_wlan_remove) (); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-FUNC: wmt call wlan remove fail(%d)\n", iRet); -+ iRet = -1; -+ } else { -+ WMT_WARN_FUNC("WMT-FUNC: wmt call wlan remove ok\n"); -+ } -+ } else { -+ WMT_ERR_FUNC("WMT-FUNC: null pointer mtk_wcn_wlan_remove\n"); -+ iRet = -2; -+ } -+ -+ if (!iRet) { -+ osal_clear_bit(WMT_WIFI_ON, &gBtWifiGpsState); -+ if ((!osal_test_bit(WMT_BT_ON, &gBtWifiGpsState)) && (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState))) { -+ /* send msg to GPS native for stopping send de-sense CMD */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ } -+ return iRet; -+#if 0 -+ return wmt_func_wifi_ctrl(FUNC_OFF); -+#endif -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c -new file mode 100644 -index 0000000000000..c07052bce8e6d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c -@@ -0,0 +1,2452 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-IC]" -+#define CFG_IC_SOC 1 -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+#include "wmt_ic.h" -+#include "wmt_core.h" -+#include "wmt_lib.h" -+#include "stp_core.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define DEFAULT_PATCH_FRAG_SIZE (1000) -+#define WMT_PATCH_FRAG_1ST (0x1) -+#define WMT_PATCH_FRAG_MID (0x2) -+#define WMT_PATCH_FRAG_LAST (0x3) -+ -+#define CFG_CHECK_WMT_RESULT (1) -+/* BT Port 2 Feature. this command does not need -+ * after coex command is downconfirmed by LC, -+ */ -+#define CFG_WMT_BT_PORT2 (0) -+ -+#define CFG_SET_OPT_REG (0) -+#define CFG_WMT_I2S_DBGUART_SUPPORT (0) -+#define CFG_SET_OPT_REG_SWLA (0) -+#define CFG_SET_OPT_REG_MCUCLK (0) -+#define CFG_SET_OPT_REG_MCUIRQ (0) -+ -+#define CFG_SUBSYS_COEX_NEED 0 -+ -+#define CFG_WMT_COREDUMP_ENABLE 0 -+ -+#define CFG_WMT_MULTI_PATCH (1) -+ -+#define CFG_WMT_CRYSTAL_TIMING_SET (0) -+ -+#define CFG_WMT_SDIO_DRIVING_SET (0) -+ -+#define CFG_WMT_UART_HIF_USE (0) -+ -+#define CFG_WMT_WIFI_5G_SUPPORT (1) -+ -+#define CFG_WMT_PATCH_DL_OPTM (1) -+#if CFG_WMT_LTE_COEX_HANDLING -+#define CFG_WMT_FILTER_MODE_SETTING (1) -+#else -+#define CFG_WMT_FILTER_MODE_SETTING (0) -+#endif -+#define MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT (0) -+ -+#define CFG_WMT_POWER_ON_DLM (1) -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+static UINT8 gFullPatchName[NAME_MAX + 1]; -+static const WMT_IC_INFO_S *gp_soc_info; -+static WMT_PATCH gp_soc_patch_info; -+static WMT_CO_CLOCK gCoClockEn = WMT_CO_CLOCK_DIS; -+#if 0 -+static UINT8 WMT_WAKEUP_DIS_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x04 }; -+static UINT8 WMT_WAKEUP_DIS_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x04 }; -+ -+static UINT8 WMT_WAKEUP_EN_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x05 }; -+static UINT8 WMT_WAKEUP_EN_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x05 }; -+#endif -+ -+#if CFG_WMT_UART_HIF_USE -+static UINT8 WMT_QUERY_BAUD_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x02 }; -+static UINT8 WMT_QUERY_BAUD_EVT_115200[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0x00, 0xC2, 0x01, 0x00 }; -+static UINT8 WMT_QUERY_BAUD_EVT_X[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xBB }; -+static UINT8 WMT_SET_BAUD_CMD_X[] = { 0x01, 0x04, 0x05, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xBB }; -+static UINT8 WMT_SET_BAUD_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x01 }; -+static UINT8 WMT_SET_WAKEUP_WAKE_CMD_RAW[] = { 0xFF }; -+static UINT8 WMT_SET_WAKEUP_WAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; -+#endif -+static UINT8 WMT_QUERY_STP_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x04 }; -+static UINT8 WMT_QUERY_STP_EVT_DEFAULT[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_QUERY_STP_EVT[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0xDF, 0x0E, 0x68, 0x01 }; -+static UINT8 WMT_PATCH_CMD[] = { 0x01, 0x01, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_PATCH_EVT[] = { 0x02, 0x01, 0x01, 0x00, 0x00 }; -+static UINT8 WMT_RESET_CMD[] = { 0x01, 0x07, 0x01, 0x00, 0x04 }; -+static UINT8 WMT_RESET_EVT[] = { 0x02, 0x07, 0x01, 0x00, 0x00 }; -+ -+#if CFG_WMT_BT_PORT2 -+static UINT8 WMT_BTP2_CMD[] = { 0x01, 0x10, 0x03, 0x00, 0x01, 0x03, 0x01 }; -+static UINT8 WMT_BTP2_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+#endif -+ -+/*soc patial patch address cmd & evt need firmware owner provide*/ -+#if CFG_WMT_MULTI_PATCH -+static UINT8 WMT_PATCH_ADDRESS_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x3c, 0x02, 0x09, 0x02, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_PATCH_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+static UINT8 WMT_PATCH_P_ADDRESS_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0xc4, 0x04, 0x09, 0x02, -+ 0x00, 0x3f, 0x00, 0x01, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_PATCH_P_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+#endif -+ -+/*coex cmd/evt++*/ -+static UINT8 WMT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x01, 0x00 }; -+static UINT8 WMT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ -+#if CFG_SUBSYS_COEX_NEED -+static UINT8 WMT_BT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0B, -+ 0x00, 0x02, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA -+}; -+static UINT8 WMT_BT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0C, -+ 0x00, 0x03, -+ 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA -+}; -+static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_PTA_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0A, -+ 0x00, 0x04, -+ 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF, 0xFE -+}; -+static UINT8 WMT_PTA_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_MISC_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x09, -+ 0x00, 0x05, -+ 0xAA, 0xAA, 0xAA, 0xAA, -+ 0xBB, 0xBB, 0xBB, 0xBB -+}; -+static UINT8 WMT_MISC_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+#endif -+ -+/*coex cmd/evt--*/ -+static UINT8 WMT_SET_STP_CMD[] = { 0x01, 0x04, 0x05, 0x00, 0x03, 0xDF, 0x0E, 0x68, 0x01 }; -+static UINT8 WMT_SET_STP_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x03 }; -+static UINT8 WMT_STRAP_CONF_CMD_FM_COMM[] = { 0x01, 0x05, 0x02, 0x00, 0x02, 0x02 }; -+static UINT8 WMT_STRAP_CONF_EVT[] = { 0x02, 0x05, 0x02, 0x00, 0x00, 0x02 }; -+ -+#if 0 -+static UINT8 WMT_SET_OSC32K_BYPASS_CMD[] = { 0x01, 0x0A, 0x01, 0x00, 0x05 }; -+static UINT8 WMT_SET_OSC32K_BYPASS_EVT[] = { 0x02, 0x0A, 0x01, 0x00, 0x00 }; -+#endif -+ -+#if 0 -+/* to enable dump feature */ -+static UINT8 WMT_CORE_DUMP_EN_CMD[] = { 0x01, 0x0F, 0x02, 0x00, 0x03, 0x01 }; -+static UINT8 WMT_CORE_DUMP_EN_EVT[] = { 0x02, 0x0F, 0x01, 0x00, 0x00 }; -+ -+/* to get system stack dump when f/w assert */ -+static UINT8 WMT_CORE_DUMP_LEVEL_01_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_CORE_DUMP_LEVEL_01_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; -+ -+/* to get task and system stack dump when f/w assert */ -+static UINT8 WMT_CORE_DUMP_LEVEL_02_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_CORE_DUMP_LEVEL_02_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; -+ -+/* to get bt related memory dump when f/w assert */ -+static UINT8 WMT_CORE_DUMP_LEVEL_03_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x03, 0x00, 0x00, 0x09, 0xF0, 0x00, 0x0A }; -+static UINT8 WMT_CORE_DUMP_LEVEL_03_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; -+#endif -+/* to get full dump when f/w assert */ -+static UINT8 WMT_CORE_DUMP_LEVEL_04_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_CORE_DUMP_LEVEL_04_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_CORE_CO_CLOCK_CMD[] = { 0x1, 0x0A, 0x02, 0x00, 0x08, 0x03 }; -+static UINT8 WMT_CORE_CO_CLOCK_EVT[] = { 0x2, 0x0A, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_CORE_START_RF_CALIBRATION_CMD[] = { 0x1, 0x14, 0x1, 0x00, 0x01 }; -+static UINT8 WMT_CORE_START_RF_CALIBRATION_EVT[] = { 0x2, 0x14, 0x02, 0x00, 0x00, 0x01 }; -+ -+#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) -+static UINT8 WMT_SET_I2S_SLAVE_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+ , 0x78, 0x00, 0x05, 0x80 /*addr:0x80050078 */ -+ , 0x00, 0x00, 0x11, 0x01 /*value:0x11010000 */ -+ , 0x00, 0x00, 0x77, 0x07 /*mask:0x07770000 */ -+}; -+ -+static UINT8 WMT_SET_I2S_SLAVE_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+}; -+ -+static UINT8 WMT_SET_DAI_TO_PAD_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+ , 0x74, 0x00, 0x05, 0x80 /*addr:0x80050074 */ -+ , 0x44, 0x44, 0x00, 0x00 /*value:0x11010000 */ -+ , 0x77, 0x77, 0x00, 0x00 /*mask:0x07770000 */ -+}; -+ -+static UINT8 WMT_SET_DAI_TO_PAD_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+}; -+ -+static UINT8 WMT_SET_DAI_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+ , 0xA0, 0x00, 0x05, 0x80 /*addr:0x80050074 */ -+ , 0x04, 0x00, 0x00, 0x00 /*value:0x11010000 */ -+ , 0x04, 0x00, 0x00, 0x00 /*mask:0x07770000 */ -+}; -+ -+static UINT8 WMT_SET_DAI_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+}; -+#endif -+ -+#if !(CFG_IC_SOC) /* For MT6628 no need to set ALLEINT registers, done in f/w */ -+/* enable all interrupt */ -+static UINT8 WMT_SET_ALLINT_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+ , 0x00, 0x03, 0x05, 0x80 /*addr:0x80050300 */ -+ , 0x00, 0xC4, 0x00, 0x00 /*value:0x0000C400 */ -+ , 0x00, 0xC4, 0x00, 0x00 /*mask:0x0000C400 */ -+}; -+ -+static UINT8 WMT_SET_ALLINT_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+}; -+ -+#endif -+ -+#if CFG_SET_OPT_REG_SWLA /* enable swla: eesk(7) eecs(8) oscen(19) sck0(24) scs0(25) */ -+static UINT8 WMT_SET_SWLA_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x02 /*2 registers */ -+ , 0x10, 0x01, 0x05, 0x80 /*addr:0x80050110 */ -+ , 0x10, 0x10, 0x01, 0x00 /*value:0x00011010 */ -+ , 0xF0, 0xF0, 0x0F, 0x00 /*mask:0x000FF0F0 */ -+ , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ -+ , 0x00, 0x10, 0x01, 0x00 /*value:0x00011000 */ -+ , 0x00, 0xF0, 0x0F, 0x00 /*mask:0x000FF000 */ -+}; -+ -+static UINT8 WMT_SET_SWLA_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x02 /*2 registers */ -+}; -+#endif -+ -+#if CFG_SET_OPT_REG_MCUCLK /* enable mcu clk: antsel_4, eedi */ -+static UINT8 WMT_SET_MCUCLK_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x04 /* 4 registers */ -+ , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000 0400 */ -+ , 0x00, 0x14, 0x00, 0x00 /* value:0x0000 1400(osc, hclk), 0x0000 1501(PLL, en) */ -+ , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ -+ , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005 0180 */ -+ , 0x12, 0x13, 0x00, 0x00 /* value:0x0000 1312(osc, hclk), 0x0000 1a19(PLL, en) */ -+ , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ -+ , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005 0100 */ -+ , 0x00, 0x00, 0x02, 0x00 /* value:0x0002 0000 */ -+ , 0x00, 0x00, 0x0F, 0x00 /* mask:0x000F 0000 */ -+ , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005 0110 */ -+ , 0x02, 0x00, 0x00, 0x00 /* value:0x0000 0002 */ -+ , 0x0F, 0x00, 0x00, 0x00 /* mask:0x0000 000F */ -+}; -+ -+static UINT8 WMT_SET_MCUCLK_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /* S: 0 */ -+ , 0x00 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x04 /* 4 registers */ -+}; -+#endif -+ -+#if CFG_WMT_I2S_DBGUART_SUPPORT /* register write for debug uart */ -+static UINT8 WMT_SET_DBGUART_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x02 /*2 registers */ -+ , 0x30, 0x01, 0x05, 0x80 /*addr:0x80050130 */ -+ , 0x00, 0x00, 0x00, 0x00 /*value:0x00000000 */ -+ , 0xF0, 0x0F, 0x00, 0x00 /*mask:0x00000FF0 */ -+ , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ -+ , 0x00, 0x01, 0x00, 0x00 /*value:0x00000100 */ -+ , 0x00, 0x01, 0x00, 0x00 /*mask:0x00000100 */ -+}; -+ -+static UINT8 WMT_SET_DBGUART_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x02 /*2 registers */ -+}; -+#endif -+ -+#if CFG_SET_OPT_REG_MCUIRQ /* enable mcu irq: antsel_4, wlan_act */ -+#if 1 /* Ray */ -+static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x04 /* 4 registers */ -+ , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ -+ , 0x03, 0x14, 0x00, 0x00 /* value:0x0000_1403 check confg debug flag 3 low word */ -+ , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000_FFFF */ -+ /* cirq_int_n */ -+ , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005_0110 */ -+ , 0x02, 0x00, 0x00, 0x00 /* value:0x0000_0002 set EEDI as cirq_int_n debug flag (monitor flag2) */ -+ , 0x07, 0x00, 0x00, 0x00 /* mask:0x0000_0007 */ -+ , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ -+ , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0, ahb_x2_gt_ck debug flag) */ -+ , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ -+ /* 1. ARM irq_b, monitor flag 0 */ -+ , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ -+ , 0x1F, 0x1E, 0x00, 0x00 /* value:0x0000_1E1F check mcusys debug flag */ -+ , 0x7F, 0x7F, 0x00, 0x00 /* mask:0x0000_7F7F */ -+}; -+ -+static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /* S: 0 */ -+ , 0x00 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x04 /* 5 registers */ -+}; -+#elif 0 /* KC */ -+static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 5), 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x05 /* 5 registers */ -+ , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ -+ , 0x00, 0x02, 0x00, 0x00 /* value:0x0000_0200 [15:8]=0x2 arm irq_b, 0xA irq_bus[5] bt_timcon_irq_b */ -+ , 0x00, 0xFF, 0x00, 0x00 /* mask:0x0000_FF00 */ -+ /* 1. ARM irq_b, monitor flag 0 */ -+ , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ -+ , 0x18, 0x00, 0x00, 0x00 /* value:0x0000_0018 [6:0]=001_1000 (monitor flag 0 select, MCUSYS, SEL:8) */ -+ , 0x7F, 0x00, 0x00, 0x00 /* mask:0x0000_007F */ -+ , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ -+ , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0) */ -+ , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ -+ /* 2. irq_bus[5] bt_timcon_irq_b monitor flag 15 */ -+ , 0xB0, 0x01, 0x05, 0x80 /* addr:0x8005_01B0 */ -+ , 0x00, 0x00, 0x00, 0x16 /* value:0x1600_0000 [30:24]=001_0110 (monitor flag 15 select, MCUSYS, SEL:6) */ -+ , 0x00, 0x00, 0x00, 0x7F /* mask:0x7F00_0000 */ -+ , 0x30, 0x01, 0x05, 0x80 /* addr:0x8005_0130 */ -+ , 0x00, 0x20, 0x00, 0x00 /* value:0x0000_2000 (WLAN_ACT=>monitor flag 15) */ -+ , 0x00, 0x70, 0x00, 0x00 /* mask:0x0000_7000 */ -+}; -+ -+static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /* S: 0 */ -+ , 0x00 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x05 /* 5 registers */ -+}; -+#endif -+#endif -+ -+#if CFG_WMT_CRYSTAL_TIMING_SET -+static UINT8 WMT_SET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x01, 0x00 }; -+static UINT8 WMT_SET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x01, 0x00 }; -+ -+static UINT8 WMT_GET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_GET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x00, 0x00 }; -+#endif -+ -+#ifdef CFG_WMT_READ_EFUSE_VCN33 -+static UINT8 WMT_GET_EFUSE_VCN33_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x04, 0x00 }; -+static UINT8 WMT_GET_EFUSE_VCN33_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x04, 0x00 }; -+#endif -+ -+/* set sdio driving */ -+#if CFG_WMT_SDIO_DRIVING_SET -+static UINT8 WMT_SET_SDIO_DRV_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+ , 0x50, 0x00, 0x05, 0x80 /*addr:0x80050050 */ -+ , 0x44, 0x44, 0x04, 0x00 /*value:0x00044444 */ -+ , 0x77, 0x77, 0x07, 0x00 /*mask:0x00077777 */ -+}; -+ -+static UINT8 WMT_SET_SDIO_DRV_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+}; -+#endif -+ -+#if CFG_WMT_WIFI_5G_SUPPORT -+static UINT8 WMT_GET_SOC_ADIE_CHIPID_CMD[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x24, 0x00 }; -+static UINT8 WMT_GET_SOC_ADIE_CHIPID_EVT[] = { -+ 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x24, -+ 0x00, 0x00, 0x00, 0x00, 0x00 -+}; -+static UINT8 WMT_GET_SOC_6625_L_CMD[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x20, 0x01 }; -+static UINT8 WMT_GET_SOC_6625_L_EVT[] = { -+ 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x20, -+ 0x01, 0x00, 0x00, 0x00, 0x00 -+}; -+#endif -+ -+#if CFG_WMT_PATCH_DL_OPTM -+static UINT8 WMT_SET_MCU_CLK_EN_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x34, 0x03, 0x00, 0x80, -+ 0x00, 0x00, 0x01, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_SET_MCU_CLK_EN_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+static UINT8 WMT_SET_MCU_CLK_138_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x0c, 0x01, 0x00, 0x80, -+ 0x59, 0x4d, 0x84, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_SET_MCU_CLK_138_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+static UINT8 WMT_SET_MCU_CLK_26_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x0c, 0x01, 0x00, 0x80, -+ 0x00, 0x4d, 0x84, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_SET_MCU_CLK_26_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+static UINT8 WMT_SET_MCU_CLK_DIS_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x34, 0x03, 0x00, 0x80, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_SET_MCU_CLK_DIS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+/*only for 6797,enable high clock frequency*/ -+/*CLK EN*/ -+static UINT8 WMT_SET_MCU_CLK_EN_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x10, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x10, -+ 0x00, 0x00, 0x00, 0x10 -+}; -+/*RATIO SET*/ -+static UINT8 WMT_SET_MCU_RATIO_SET_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x0c, 0x01, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, -+ 0xc0, 0x00, 0x00, 0x00 -+}; -+/*DIV SET*/ -+static UINT8 WMT_SET_MCU_DIV_SET_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x18, 0x11, 0x02, 0x80, 0x07, 0x00, 0x00, 0x00, -+ 0x3f, 0x00, 0x00, 0x00 -+}; -+/*HCLK SET*/ -+static UINT8 WMT_SET_MCU_HCLK_SET_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x00, 0x11, 0x02, 0x81, 0x04, 0x00, 0x00, 0x00, -+ 0x07, 0x00, 0x00, 0x00 -+}; -+ -+/*Change clock to 26MHz*/ -+/*HCLK DIS*/ -+static UINT8 WMT_SET_MCU_HCLK_DIS_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x00, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x00, -+ 0x07, 0x00, 0x00, 0x00 -+}; -+/*RATIO DIS*/ -+static UINT8 WMT_SET_MCU_RATIO_DIS_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x0c, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, -+ 0xc0, 0x00, 0x00, 0x00 -+}; -+/*CLK DIS*/ -+static UINT8 WMT_SET_MCU_CLK_DIS_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x10, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x10 -+}; -+ -+static UINT8 WMT_SET_MCU_CLK_EVT_6797[] = { -+ 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 -+}; -+ -+#endif -+ -+#if CFG_WMT_FILTER_MODE_SETTING -+static UINT8 WMT_COEX_EXT_COMPONENT_CMD[] = {0x01, 0x10, 0x03, 0x00, 0x0d, 0x00, 0x00}; -+static UINT8 WMT_COEX_FILTER_SPEC_CMD_TEST[] = { -+ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, -+ 0x00, 0x11, 0x11, 0x16, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x63, 0x63, 0x63, 0x00, 0x39, 0x43, 0x63, -+ 0x63, 0x02, 0x02, 0x03, 0x00, 0x01, 0x01, 0x01, -+ 0x01, 0x0e, 0x0e, 0x0e, 0x00, 0x0a, 0x0c, 0x0e, -+ 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -+static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD[] = { -+ 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, -+ 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xd4, -+ 0x09, 0xe3, 0x09, 0x5a, 0x0a, 0x14, 0x09, 0x2d, -+ 0x09, 0x46, 0x09, 0x60, 0x09, 0xd3, 0x09, 0xe2, -+ 0x09, 0x59, 0x0a, 0x8B, 0x0a}; -+static UINT8 WMT_COEX_LTE_CHAN_UNSAFE_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x13, 0x00 }; -+static UINT8 WMT_COEX_IS_LTE_L_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x21, 0x01 }; -+ -+#if 0 -+static UINT8 WMT_COEX_SPLIT_FILTER_CMD_TEST[] = { -+ 0x01, 0x10, 0x19, 0x00, 0x0F, 0x00, 0x00, 0x00, -+ 0x00, 0x6c, 0x09, 0x8a, 0x09, 0x8a, 0x09, 0x9e, -+ 0x09, 0x01, 0x07, 0x07, 0x0b, 0x07, 0x07, 0x00, -+ 0x32, 0x27, 0x4e, 0x27, 0x32 -+}; -+ -+static UINT8 WMT_COEX_FILTER_SPEC_CMD_TEST[] = { -+ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, -+ 0x00, 0x07, 0x07, 0x07, 0x54, 0x54, 0x00, 0x00, -+ 0x00, 0x50, 0x50, 0x50, 0x54, 0x54, 0x39, 0x39, -+ 0x39, 0x02, 0x02, 0x02, 0x0e, 0x0e, 0x01, 0x01, -+ 0x01, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0a, 0x0a, -+ 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00 -+}; -+ -+static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_TEST[] = { -+ 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, -+ 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xdd, -+ 0x09, 0xf6, 0x09, 0x0f, 0xaf, 0x14, 0x09, 0x2d, -+ 0x09, 0x46, 0x09, 0x5f, 0x09, 0xdd, 0x09, 0xf5, -+ 0x09, 0x0d, 0x0a, 0x27, 0x0a -+}; -+static UINT8 WMT_COEX_LTE_CHAN_UNSAFE_CMD_TEST[] = { 0x01, 0x10, 0x02, 0x00, 0x13, 0x00 }; -+static UINT8 WMT_COEX_EXT_COMPONENT_CMD_TEST[] = { 0x01, 0x10, 0x03, 0x00, 0x0d, 0x7f, 0x03 }; -+#endif -+ -+static UINT8 WMT_COEX_FILTER_SPEC_CMD_0[] = { -+ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, -+ 0x00, 0x16, 0x16, 0x16, 0x16, 0x00, 0x00, 0x00, -+ 0x00, 0x63, 0x63, 0x63, 0x63, 0x3c, 0x3c, 0x3c, -+ 0x3c, 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, 0x01, -+ 0x01, 0x0e, 0x0e, 0x0e, 0x0e, 0x0b, 0x0b, 0x0b, -+ 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00 -+}; -+ -+static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_0[] = { -+ 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, -+ 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xdd, -+ 0x09, 0xf6, 0x09, 0x0f, 0x0a, 0x14, 0x09, 0x2d, -+ 0x09, 0x46, 0x09, 0x5f, 0x09, 0xdd, 0x09, 0xf5, -+ 0x09, 0x0d, 0x0a, 0x27, 0x0a -+}; -+static UINT8 WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x14, 0x00 }; -+static UINT8 WMT_COEX_IS_LTE_PROJ_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x15, 0x01 }; -+static UINT8 WMT_COEX_SPLIT_MODE_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_COEX_FILTER_SPEC_CMD_6752[] = { -+ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, -+ 0x00, 0x11, 0x11, 0x16, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x63, 0x63, 0x63, 0x00, 0x39, 0x43, 0x63, -+ 0x63, 0x02, 0x02, 0x03, 0x00, 0x01, 0x01, 0x01, -+ 0x01, 0x0E, 0x0E, 0x0E, 0x00, 0x0A, 0x0C, 0x0E, -+ 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00 -+}; -+ -+static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_6752[] = { -+ 0x01, 0x10, 0x21, 0x00, 0x12, 0xFC, 0x08, 0x15, -+ 0x09, 0x2E, 0x09, 0x47, 0x09, 0xC4, 0x09, 0xD4, -+ 0x09, 0xE3, 0x09, 0x5A, 0x0A, 0x14, 0x09, 0x2D, -+ 0x09, 0x46, 0x09, 0x60, 0x09, 0xD3, 0x09, 0xE2, -+ 0x09, 0x59, 0x0A, 0x8B, 0x0A -+}; -+#endif -+ -+#if CFG_WMT_POWER_ON_DLM -+static UINT8 WMT_POWER_CTRL_DLM_CMD1[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x60, 0x00, 0x10, 0x80, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x0f, 0x00, 0x00 -+}; -+ -+static UINT8 WMT_POWER_CTRL_DLM_CMD2[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x60, 0x00, 0x10, 0x80, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xf0, 0x00, 0x00, 0x00 -+}; -+ -+static UINT8 WMT_POWER_CTRL_DLM_CMD3[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x60, 0x00, 0x10, 0x80, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x08, 0x00, 0x00, 0x00 -+}; -+static UINT8 WMT_POWER_CTRL_DLM_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+#endif -+ -+#if (!CFG_IC_SOC) -+ -+/* stp sdio init scripts */ -+static struct init_script init_table_1_1[] = { -+ /* table_1_1 is only applied to common SDIO interface */ -+ INIT_CMD(WMT_SET_ALLINT_REG_CMD, WMT_SET_ALLINT_REG_EVT, "enable all interrupt"), -+ /* applied to MT6628 ? */ -+ INIT_CMD(WMT_WAKEUP_DIS_GATE_CMD, WMT_WAKEUP_DIS_GATE_EVT, "disable gating"), -+}; -+ -+#endif -+ -+static struct init_script init_table_1_2[] = { -+ INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT_DEFAULT, "query stp default"), -+}; -+ -+#if CFG_WMT_UART_HIF_USE -+static struct init_script init_table_2[] = { -+ INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_X, "query baud X"), -+}; -+#endif -+ -+static struct init_script init_table_3[] = { -+ INIT_CMD(WMT_RESET_CMD, WMT_RESET_EVT, "wmt reset"), -+#if CFG_WMT_BT_PORT2 -+ INIT_CMD(WMT_BTP2_CMD, WMT_BTP2_EVT, "set bt port2"), -+#endif -+}; -+ -+#if CFG_WMT_CRYSTAL_TIMING_SET -+static struct init_script set_crystal_timing_script[] = { -+ INIT_CMD(WMT_SET_CRYSTAL_TRIMING_CMD, WMT_SET_CRYSTAL_TRIMING_EVT, "set crystal trim value"), -+}; -+ -+static struct init_script get_crystal_timing_script[] = { -+ INIT_CMD(WMT_GET_CRYSTAL_TRIMING_CMD, WMT_GET_CRYSTAL_TRIMING_EVT, "get crystal trim value"), -+}; -+#endif -+#ifdef CFG_WMT_READ_EFUSE_VCN33 -+static struct init_script get_efuse_vcn33_script[] = { -+ INIT_CMD(WMT_GET_EFUSE_VCN33_CMD, WMT_GET_EFUSE_VCN33_EVT, "get efuse vcn33 value"), -+}; -+#endif -+ -+static struct init_script init_table_4[] = { -+ INIT_CMD(WMT_SET_STP_CMD, WMT_SET_STP_EVT, "set stp"), -+}; -+ -+static struct init_script init_table_5[] = { -+ INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT, "query stp"), -+}; -+ -+static struct init_script init_table_5_1[] = { -+ INIT_CMD(WMT_STRAP_CONF_CMD_FM_COMM, WMT_STRAP_CONF_EVT, "configure FM comm"), -+}; -+ -+static struct init_script init_table_6[] = { -+ INIT_CMD(WMT_CORE_DUMP_LEVEL_04_CMD, WMT_CORE_DUMP_LEVEL_04_EVT, "setup core dump level"), -+}; -+ -+static struct init_script calibration_table[] = { -+ INIT_CMD(WMT_CORE_START_RF_CALIBRATION_CMD, WMT_CORE_START_RF_CALIBRATION_EVT, "start RF calibration data"), -+}; -+ -+#if CFG_WMT_PATCH_DL_OPTM -+static struct init_script set_mcuclk_table_1[] = { -+ INIT_CMD(WMT_SET_MCU_CLK_EN_CMD, WMT_SET_MCU_CLK_EN_EVT, "enable set mcu clk"), -+ INIT_CMD(WMT_SET_MCU_CLK_138_CMD, WMT_SET_MCU_CLK_138_EVT, "set mcu clk to 138.67MH"), -+}; -+ -+static struct init_script set_mcuclk_table_2[] = { -+ INIT_CMD(WMT_SET_MCU_CLK_26_CMD, WMT_SET_MCU_CLK_26_EVT, "set mcu clk to 26MH"), -+ INIT_CMD(WMT_SET_MCU_CLK_DIS_CMD, WMT_SET_MCU_CLK_DIS_EVT, "disable set mcu clk"), -+}; -+ -+static struct init_script set_mcuclk_table_3[] = { -+ INIT_CMD(WMT_SET_MCU_CLK_EN_6797, WMT_SET_MCU_CLK_EVT_6797, "enable set mcu clk"), -+ INIT_CMD(WMT_SET_MCU_RATIO_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "mcu ratio set"), -+ INIT_CMD(WMT_SET_MCU_DIV_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "mcu div set"), -+ INIT_CMD(WMT_SET_MCU_HCLK_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "set mcu clk to hclk"), -+}; -+static struct init_script set_mcuclk_table_4[] = { -+ INIT_CMD(WMT_SET_MCU_HCLK_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu hclk"), -+ INIT_CMD(WMT_SET_MCU_RATIO_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu ratio set"), -+ INIT_CMD(WMT_SET_MCU_CLK_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu clk set"), -+}; -+ -+#endif -+ -+#if CFG_WMT_FILTER_MODE_SETTING -+static struct init_script set_wifi_lte_coex_table_1[] = { -+ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_6752, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter spec"), -+ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_6752, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq idx"), -+ INIT_CMD(WMT_COEX_IS_LTE_PROJ_CMD, WMT_COEX_SPLIT_MODE_EVT, "set LTE project"), -+}; -+ -+static struct init_script set_wifi_lte_coex_table_2[] = { -+ INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte ext component"), -+ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter"), -+ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq id table"), -+ INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte unsafe channel"), -+ INIT_CMD(WMT_COEX_IS_LTE_L_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi coex is L branch"), -+}; -+ -+static struct init_script set_wifi_lte_coex_table_0[] = { -+#if 0 -+ INIT_CMD(WMT_COEX_SPLIT_FILTER_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex split filter"), -+ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter spec"), -+ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq idx"), -+ INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte channel unsafe"), -+ INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi coex ext component"), -+#endif -+ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_0, WMT_COEX_SPLIT_MODE_EVT, "def wifi lte coex filter spec"), -+ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_0, WMT_COEX_SPLIT_MODE_EVT, "def wifi lte freq idx"), -+}; -+ -+static struct init_script get_tdm_req_antsel_num_table[] = { -+ INIT_CMD(WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD, WMT_COEX_SPLIT_MODE_EVT, "get tdm req antsel num"), -+}; -+#endif -+ -+#if CFG_SET_OPT_REG -+static struct init_script set_registers[] = { -+ /* INIT_CMD(WMT_SET_GPS_REG_CMD, WMT_SET_GPS_REG_EVT, "set wmt registers"), */ -+ /* INIT_CMD(WMT_SET_SDIODRV_REG_CMD, WMT_SET_SDIODRV_REG_EVT, "set SDIO driving registers") */ -+#if CFG_WMT_I2S_DBGUART_SUPPORT -+ INIT_CMD(WMT_SET_DBGUART_REG_CMD, WMT_SET_DBGUART_REG_EVT, "set debug uart registers"), -+#endif -+#if CFG_SET_OPT_REG_SWLA -+ INIT_CMD(WMT_SET_SWLA_REG_CMD, WMT_SET_SWLA_REG_EVT, "set swla registers"), -+#endif -+#if CFG_SET_OPT_REG_MCUCLK -+ INIT_CMD(WMT_SET_MCUCLK_REG_CMD, WMT_SET_MCUCLK_REG_EVT, "set mcuclk dbg registers"), -+#endif -+#if CFG_SET_OPT_REG_MCUIRQ -+ INIT_CMD(WMT_SET_MCUIRQ_REG_CMD, WMT_SET_MCUIRQ_REG_EVT, "set mcu irq dbg registers"), -+#endif -+}; -+#endif -+ -+static struct init_script coex_table[] = { -+ INIT_CMD(WMT_COEX_SETTING_CONFIG_CMD, WMT_COEX_SETTING_CONFIG_EVT, "coex_wmt"), -+ -+#if CFG_SUBSYS_COEX_NEED -+/* no need in MT6628 */ -+ INIT_CMD(WMT_BT_COEX_SETTING_CONFIG_CMD, WMT_BT_COEX_SETTING_CONFIG_EVT, "coex_bt"), -+ INIT_CMD(WMT_WIFI_COEX_SETTING_CONFIG_CMD, WMT_WIFI_COEX_SETTING_CONFIG_EVT, "coex_wifi"), -+ INIT_CMD(WMT_PTA_COEX_SETTING_CONFIG_CMD, WMT_PTA_COEX_SETTING_CONFIG_EVT, "coex_ext_pta"), -+ INIT_CMD(WMT_MISC_COEX_SETTING_CONFIG_CMD, WMT_MISC_COEX_SETTING_CONFIG_EVT, "coex_misc"), -+#endif -+}; -+ -+static struct init_script osc_type_table[] = { -+ INIT_CMD(WMT_CORE_CO_CLOCK_CMD, WMT_CORE_CO_CLOCK_EVT, "osc_type"), -+}; -+ -+#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) -+static struct init_script merge_pcm_table[] = { -+ INIT_CMD(WMT_SET_I2S_SLAVE_REG_CMD, WMT_SET_I2S_SLAVE_REG_EVT, "I2S_Slave"), -+ INIT_CMD(WMT_SET_DAI_TO_PAD_REG_CMD, WMT_SET_DAI_TO_PAD_REG_EVT, "DAI_PAD"), -+ INIT_CMD(WMT_SET_DAI_REG_CMD, WMT_SET_DAI_REG_EVT, "DAI_EVT"), -+}; -+#endif -+ -+#if CFG_WMT_SDIO_DRIVING_SET -+static struct init_script sdio_driving_table[] = { -+ INIT_CMD(WMT_SET_SDIO_DRV_REG_CMD, WMT_SET_SDIO_DRV_REG_EVT, "sdio_driving"), -+}; -+#endif -+ -+#if CFG_WMT_POWER_ON_DLM -+static struct init_script wmt_power_on_dlm_table[] = { -+ INIT_CMD(WMT_POWER_CTRL_DLM_CMD1, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd1"), -+ INIT_CMD(WMT_POWER_CTRL_DLM_CMD2, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd2"), -+ INIT_CMD(WMT_POWER_CTRL_DLM_CMD3, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd3") -+}; -+#endif -+ -+/* SOC Chip Version and Info Table */ -+static const WMT_IC_INFO_S mtk_wcn_soc_info_table[] = { -+ { -+ .u4HwVer = 0x8A00, -+ .cChipName = WMT_IC_NAME_DEFAULT, -+ .cChipVersion = WMT_IC_VER_E1, -+ .cPatchNameExt = WMT_IC_PATCH_E1_EXT, -+ /* need to refine? */ -+ .eWmtHwVer = WMTHWVER_E1, -+ .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, -+ .bPsmSupport = MTK_WCN_BOOL_TRUE, -+ }, -+ { -+ .u4HwVer = 0x8A01, -+ .cChipName = WMT_IC_NAME_DEFAULT, -+ .cChipVersion = WMT_IC_VER_E2, -+ .cPatchNameExt = WMT_IC_PATCH_E1_EXT, -+ .eWmtHwVer = WMTHWVER_E2, -+ .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, -+ .bPsmSupport = MTK_WCN_BOOL_TRUE, -+ }, -+ { -+ .u4HwVer = 0x8B01, -+ .cChipName = WMT_IC_NAME_DEFAULT, -+ .cChipVersion = WMT_IC_VER_E3, -+ .cPatchNameExt = WMT_IC_PATCH_E1_EXT, -+ .eWmtHwVer = WMTHWVER_E3, -+ .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, -+ .bPsmSupport = MTK_WCN_BOOL_TRUE, -+ } -+}; -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static INT32 mtk_wcn_soc_sw_init(P_WMT_HIF_CONF pWmtHifConf); -+ -+static INT32 mtk_wcn_soc_sw_deinit(P_WMT_HIF_CONF pWmtHifConf); -+ -+static INT32 mtk_wcn_soc_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag); -+ -+static INT32 mtk_wcn_soc_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag); -+ -+static INT32 mtk_wcn_soc_ver_check(VOID); -+ -+static const WMT_IC_INFO_S *mtk_wcn_soc_find_wmt_ic_info(const UINT32 hw_ver); -+ -+static INT32 wmt_stp_init_coex(VOID); -+ -+#if CFG_WMT_FILTER_MODE_SETTING -+static INT32 wmt_stp_wifi_lte_coex(VOID); -+#endif -+ -+#if CFG_WMT_MULTI_PATCH -+static INT32 mtk_wcn_soc_patch_dwn(UINT32 index); -+static INT32 mtk_wcn_soc_patch_info_prepare(VOID); -+#else -+static INT32 mtk_wcn_soc_patch_dwn(VOID); -+#endif -+ -+static INT32 mtk_wcn_soc_co_clock_ctrl(WMT_CO_CLOCK on); -+static WMT_CO_CLOCK mtk_wcn_soc_co_clock_get(VOID); -+ -+#if CFG_WMT_CRYSTAL_TIMING_SET -+static INT32 mtk_wcn_soc_crystal_triming_set(VOID); -+#endif -+ -+static MTK_WCN_BOOL mtk_wcn_soc_quick_sleep_flag_get(VOID); -+ -+static MTK_WCN_BOOL mtk_wcn_soc_aee_dump_flag_get(VOID); -+ -+#if CFG_WMT_SDIO_DRIVING_SET -+static INT32 mtk_wcn_soc_set_sdio_driving(void); -+#endif -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/* SOC Operation Function Table */ -+WMT_IC_OPS wmt_ic_ops_soc = { -+ .icId = 0x0000, /* soc may have mt6572/82/71/83,but they have the same sw init flow */ -+ .sw_init = mtk_wcn_soc_sw_init, -+ .sw_deinit = mtk_wcn_soc_sw_deinit, -+ .ic_pin_ctrl = mtk_wcn_soc_pin_ctrl, -+ .ic_ver_check = mtk_wcn_soc_ver_check, -+ .co_clock_ctrl = mtk_wcn_soc_co_clock_ctrl, -+ .is_quick_sleep = mtk_wcn_soc_quick_sleep_flag_get, -+ .is_aee_dump_support = mtk_wcn_soc_aee_dump_flag_get, -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static INT32 mtk_wcn_soc_sw_init(P_WMT_HIF_CONF pWmtHifConf) -+{ -+ INT32 iRet = -1; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ UINT32 hw_ver; -+ WMT_CTRL_DATA ctrlData; -+#ifdef CFG_WMT_READ_EFUSE_VCN33 -+ UINT32 efuse_d3_vcn33 = 2; /*default voltage is 3.5V*/ -+#endif -+#if CFG_WMT_MULTI_PATCH -+ UINT32 patch_num = 0; -+ UINT32 patch_index = 0; -+#endif -+#if CFG_WMT_WIFI_5G_SUPPORT -+ UINT32 dDieChipid = 0; -+ UINT32 aDieChipid = 0; -+ UINT8 evtbuf[20]; -+ UINT32 u4Res; -+ UINT32 pmicChipid = 0; -+#endif -+ WMT_DBG_FUNC(" start\n"); -+ -+ osal_assert(NULL != gp_soc_info); -+ if ((NULL == gp_soc_info) -+ || (NULL == pWmtHifConf) -+ ) { -+ WMT_ERR_FUNC("null pointers: gp_soc_info(0x%p), pWmtHifConf(0x%p)\n", gp_soc_info, pWmtHifConf); -+ return -1; -+ } -+ -+ hw_ver = gp_soc_info->u4HwVer; -+ -+ /* 4 <3.2> start init for BTIF */ -+ if (WMT_HIF_BTIF == pWmtHifConf->hifType) { -+ /* 1. Query chip STP default options (TEST-ONLY) */ -+ /* WMT_DBG_FUNC("WMT-CORE: init_table_1_2 set chip baud:%d", pWmtHifConf->au4HifConf[0]); */ -+ iRet = wmt_core_init_script(init_table_1_2, osal_array_size(init_table_1_2)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_1_2 fail(%d)\n", iRet); -+ osal_assert(0); -+ return -2; -+ } -+ /* 2. Set chip STP options */ -+ iRet = wmt_core_init_script(init_table_4, osal_array_size(init_table_4)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_4 fail(%d)\n", iRet); -+ return -3; -+ } -+ -+ /* 3. Enable host full mode */ -+ ctrlPa1 = WMT_STP_CONF_MODE; -+ ctrlPa2 = MTKSTP_BTIF_FULL_MODE; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = WMT_STP_CONF_EN; -+ ctrlPa2 = 1; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("enable host STP-BTIF-FULL mode fail(%d)\n", iRet); -+ return -4; -+ } -+ WMT_DBG_FUNC("enable host STP-BTIF-FULL mode\n"); -+ /*4. wait for 10ms, enough for chip do mechanism switch.(at least 2ms is needed) */ -+ osal_sleep_ms(10); -+ /* 5. Query chip STP options (TEST-ONLY) */ -+ iRet = wmt_core_init_script(init_table_5, osal_array_size(init_table_5)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_5 fail(%d)\n", iRet); -+ return -5; -+ } -+ } -+#if CFG_WMT_POWER_ON_DLM -+ iRet = wmt_core_init_script(wmt_power_on_dlm_table, osal_array_size(wmt_power_on_dlm_table)); -+ if (iRet) -+ WMT_ERR_FUNC("wmt_power_on_dlm_table fail(%d)\n", iRet); -+ WMT_DBG_FUNC("wmt_power_on_dlm_table ok\n"); -+#endif -+ /* 6. download patch */ -+#if CFG_WMT_MULTI_PATCH -+ /* 6.1 Let launcher to search patch info */ -+ iRet = mtk_wcn_soc_patch_info_prepare(); -+ if (iRet) { -+ WMT_ERR_FUNC("patch info perpare fail(%d)\n", iRet); -+ return -6; -+ } -+ -+ /* 6.2 Read patch number */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_GET_PATCH_NUM, &ctrlPa1, &ctrlPa2); -+ patch_num = ctrlPa1; -+ WMT_DBG_FUNC("patch total num = [%d]\n", patch_num); -+ -+#if CFG_WMT_PATCH_DL_OPTM -+ if (0x0279 == wmt_ic_ops_soc.icId) { -+ iRet = wmt_core_init_script(set_mcuclk_table_3, osal_array_size(set_mcuclk_table_3)); -+ if (iRet) -+ WMT_ERR_FUNC("set_mcuclk_table_3 fail(%d)\n", iRet); -+ } else { -+ iRet = wmt_core_init_script(set_mcuclk_table_1, osal_array_size(set_mcuclk_table_1)); -+ if (iRet) -+ WMT_ERR_FUNC("set_mcuclk_table_1 fail(%d)\n", iRet); -+ } -+#endif -+ /* 6.3 Multi-patch Patch download */ -+ for (patch_index = 0; patch_index < patch_num; patch_index++) { -+ iRet = mtk_wcn_soc_patch_dwn(patch_index); -+ if (iRet) { -+ WMT_ERR_FUNC("patch dwn fail (%d),patch_index(%d)\n", iRet, patch_index); -+ return -7; -+ } -+ iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); -+ return -8; -+ } -+ } -+ -+#if CFG_WMT_PATCH_DL_OPTM -+ if (0x0279 == wmt_ic_ops_soc.icId) { -+ iRet = wmt_core_init_script(set_mcuclk_table_4, osal_array_size(set_mcuclk_table_4)); -+ if (iRet) -+ WMT_ERR_FUNC("set_mcuclk_table_4 fail(%d)\n", iRet); -+ } else { -+ iRet = wmt_core_init_script(set_mcuclk_table_2, osal_array_size(set_mcuclk_table_2)); -+ if (iRet) -+ WMT_ERR_FUNC("set_mcuclk_table_2 fail(%d)\n", iRet); -+ } -+#endif -+ -+#else -+ /* 6.3 Patch download */ -+ iRet = mtk_wcn_soc_patch_dwn(); -+ /* If patch download fail, we just ignore this error and let chip init process goes on */ -+ if (iRet) -+ WMT_ERR_FUNC("patch dwn fail (%d), just omit\n", iRet); -+ -+ /* 6.4. WMT Reset command */ -+ iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); -+ return -8; -+ } -+#endif -+ -+#ifdef CFG_WMT_READ_EFUSE_VCN33 -+ /*get CrystalTiming value before set it */ -+ iRet = wmt_core_tx(get_efuse_vcn33_script[0].cmd, get_efuse_vcn33_script[0].cmdSz, &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != get_efuse_vcn33_script[0].cmdSz)) { -+ WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", -+ get_efuse_vcn33_script[0].str, iRet, u4Res, get_efuse_vcn33_script[0].cmdSz); -+ } -+ /* EVENT BUF */ -+ osal_memset(get_efuse_vcn33_script[0].evt, 0, get_efuse_vcn33_script[0].evtSz); -+ iRet = wmt_core_rx(get_efuse_vcn33_script[0].evt, get_efuse_vcn33_script[0].evtSz, &u4Res); -+ if (iRet || (u4Res != get_efuse_vcn33_script[0].evtSz)) { -+ WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", -+ get_efuse_vcn33_script[0].str, iRet, u4Res, get_efuse_vcn33_script[0].evtSz); -+ mtk_wcn_stp_dbg_dump_package(); -+ } -+ efuse_d3_vcn33 = WMT_GET_EFUSE_VCN33_EVT[5] & 0x03; -+ WMT_INFO_FUNC("Read efuse to set PMIC voltage:(%d)\n", efuse_d3_vcn33); -+ wmt_set_pmic_voltage(efuse_d3_vcn33); -+#endif -+ -+#if CFG_WMT_FILTER_MODE_SETTING -+ if ((0x6580 == wmt_ic_ops_soc.icId) || -+ (0x8163 == wmt_ic_ops_soc.icId) || -+ (0x6752 == wmt_ic_ops_soc.icId) || -+ (0x6582 == wmt_ic_ops_soc.icId) || -+ (0x6592 == wmt_ic_ops_soc.icId) || -+ (0x0279 == wmt_ic_ops_soc.icId) || -+ (0x0326 == wmt_ic_ops_soc.icId) || -+ (0x0321 == wmt_ic_ops_soc.icId) || (0x0335 == wmt_ic_ops_soc.icId) || (0x0337 == wmt_ic_ops_soc.icId)) { -+ wmt_stp_wifi_lte_coex(); -+ WMT_DBG_FUNC("wmt_stp_wifi_lte_coex done!\n"); -+ } -+ if ((0x6582 == wmt_ic_ops_soc.icId) || (0x6592 == wmt_ic_ops_soc.icId)) { -+ /*get gpio tdm req antsel number */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_GET_TDM_REQ_ANTSEL, &ctrlPa1, &ctrlPa2); -+ WMT_INFO_FUNC("get GPIO TDM REQ ANTSEL number(%d)\n", ctrlPa1); -+ /*set gpio tdm req antsel number to firmware */ -+ WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD[5] = ctrlPa1; -+ iRet = wmt_core_init_script(get_tdm_req_antsel_num_table, -+ osal_array_size(get_tdm_req_antsel_num_table)); -+ if (iRet) -+ WMT_ERR_FUNC("get_tdm_req_antsel_num_table fail(%d)\n", iRet); -+ } -+#endif -+ /* 7. start RF calibration data */ -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_ON; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = WIFI_PALDO; -+ ctrlPa2 = PALDO_ON; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ -+ iRet = wmt_core_init_script(calibration_table, osal_array_size(calibration_table)); -+ if (iRet) { -+ /* pwrap_read(0x0210,&ctrlPa1); */ -+ /* pwrap_read(0x0212,&ctrlPa2); */ -+ WMT_ERR_FUNC("power status: 210:(%d),212:(%d)!\n", ctrlPa1, ctrlPa2); -+ WMT_ERR_FUNC("calibration_table fail(%d)\n", iRet); -+ return -9; -+ } -+ -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = WIFI_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ -+ iRet = wmt_stp_init_coex(); -+ if (iRet) { -+ WMT_ERR_FUNC("init_coex fail(%d)\n", iRet); -+ return -10; -+ } -+ WMT_DBG_FUNC("init_coex ok\n"); -+ -+#if CFG_WMT_CRYSTAL_TIMING_SET -+ mtk_wcn_soc_crystal_triming_set(); -+#endif -+ -+#if CFG_WMT_SDIO_DRIVING_SET -+ mtk_wcn_soc_set_sdio_driving(); -+#endif -+ -+ if (WMT_CO_CLOCK_EN == mtk_wcn_soc_co_clock_get()) { -+ WMT_INFO_FUNC("co-clock enabled.\n"); -+ -+ iRet = wmt_core_init_script(osc_type_table, osal_array_size(osc_type_table)); -+ if (iRet) { -+ WMT_ERR_FUNC("osc_type_table fail(%d), goes on\n", iRet); -+ return -11; -+ } -+ } else { -+ WMT_WARN_FUNC("co-clock disabled.\n"); -+ } -+#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) -+ iRet = wmt_core_init_script(merge_pcm_table, osal_array_size(merge_pcm_table)); -+ if (iRet) { -+ WMT_ERR_FUNC("merge_pcm_table fail(%d), goes on\n", iRet); -+ return -12; -+ } -+#endif -+ -+ /* 15. Set FM strap */ -+ WMT_STRAP_CONF_CMD_FM_COMM[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; -+ WMT_STRAP_CONF_EVT[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; -+ iRet = wmt_core_init_script(init_table_5_1, osal_array_size(init_table_5_1)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_5_1 fm mode(%d) fail(%d)\n", pWmtHifConf->au4StrapConf[0], iRet); -+ return -13; -+ } -+ WMT_DBG_FUNC("set fm mode (%d) ok\n", pWmtHifConf->au4StrapConf[0]); -+ -+#if CFG_SET_OPT_REG /*set registers */ -+ iRet = wmt_core_init_script(set_registers, osal_array_size(set_registers)); -+ if (iRet) { -+ WMT_ERR_FUNC("set_registers fail(%d)", iRet); -+ return -14; -+ } -+#endif -+ -+#if CFG_WMT_COREDUMP_ENABLE -+ /*Open Core Dump Function @QC begin */ -+ mtk_wcn_stp_coredump_flag_ctrl(1); -+#endif -+ if (0 != mtk_wcn_stp_coredump_flag_get()) { -+ iRet = wmt_core_init_script(init_table_6, osal_array_size(init_table_6)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_6 core dump setting fail(%d)\n", iRet); -+ return -15; -+ } -+ WMT_DBG_FUNC("enable soc_consys firmware coredump\n"); -+ } else { -+ WMT_DBG_FUNC("disable soc_consys firmware coredump\n"); -+ } -+ -+#if CFG_WMT_WIFI_5G_SUPPORT -+ dDieChipid = wmt_ic_ops_soc.icId; -+ WMT_DBG_FUNC("current SOC chipid is 0x%x\n", dDieChipid); -+ if (0x6592 == dDieChipid) { -+ /* read A die chipid by wmt cmd */ -+ iRet = -+ wmt_core_tx((PUINT8) &WMT_GET_SOC_ADIE_CHIPID_CMD[0], sizeof(WMT_GET_SOC_ADIE_CHIPID_CMD), &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != sizeof(WMT_GET_SOC_ADIE_CHIPID_CMD))) { -+ WMT_ERR_FUNC("wmt_core:read A die chipid CMD fail(%d),size(%d)\n", iRet, u4Res); -+ return -16; -+ } -+ osal_memset(evtbuf, 0, sizeof(evtbuf)); -+ iRet = wmt_core_rx(evtbuf, sizeof(WMT_GET_SOC_ADIE_CHIPID_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_GET_SOC_ADIE_CHIPID_EVT))) { -+ WMT_ERR_FUNC("wmt_core:read A die chipid EVT fail(%d),size(%d)\n", iRet, u4Res); -+ return -17; -+ } -+ -+ osal_memcpy(&aDieChipid, &evtbuf[u4Res - 2], 2); -+ WMT_INFO_FUNC("get SOC A die chipid(0x%x)\n", aDieChipid); -+ -+ if (0x6625 == aDieChipid) { -+ iRet = -+ wmt_core_tx((PUINT8) &WMT_GET_SOC_6625_L_CMD[0], sizeof(WMT_GET_SOC_6625_L_CMD), &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != sizeof(WMT_GET_SOC_6625_L_CMD))) -+ WMT_ERR_FUNC("wmt_core:read A die efuse CMD fail(%d),size(%d)\n", iRet, u4Res); -+ osal_memset(evtbuf, 0, sizeof(evtbuf)); -+ iRet = wmt_core_rx(evtbuf, sizeof(WMT_GET_SOC_6625_L_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_GET_SOC_6625_L_EVT))) -+ WMT_ERR_FUNC("wmt_core:read A die efuse EVT fail(%d),size(%d)\n", iRet, u4Res); -+ -+ WMT_INFO_FUNC("read SOC Adie Efuse(0x120) value:0x%2x,0x%2x,0x%2x,0x%2x -> %s\n", -+ evtbuf[u4Res - 4], evtbuf[u4Res - 3], evtbuf[u4Res - 2], evtbuf[u4Res - 1], -+ evtbuf[u4Res - 2] == 0x31 ? "MT6625L" : "MT6625"); -+ } -+ /* get PMIC chipid */ -+ -+ ctrlData.ctrlId = WMT_CTRL_SOC_PALDO_CTRL; -+ ctrlData.au4CtrlData[0] = PMIC_CHIPID_PALDO; -+ ctrlData.au4CtrlData[1] = 0; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet < 0) { -+ WMT_ERR_FUNC("wmt_core: read PMIC chipid fail(%d)\n", iRet); -+ return -18; -+ } -+ pmicChipid = ctrlData.au4CtrlData[2]; -+ WMT_INFO_FUNC("current PMIC chipid(0x%x)\n", pmicChipid); -+ -+ /* MT6625 & MT6322, write 1 to 0x0414[12] */ -+ /* MT6625 & MT6323, assert */ -+ /* MT6627 & (MT6322 or MT6323),write 0 to 0x0414[12] */ -+ -+ switch (aDieChipid) { -+ case 0x6625: -+ if (0x6322 == pmicChipid) { -+ WMT_INFO_FUNC("wmt-core:enable wifi 5G support\n"); -+ ctrlPa1 = WIFI_5G_PALDO; -+ ctrlPa2 = PALDO_ON; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } else if (0x6323 == pmicChipid) { -+ osal_assert(0); -+ } else { -+ WMT_WARN_FUNC("wmt-core: unknown PMIC chipid\n"); -+ } -+ break; -+ case 0x6627: -+ if ((0x6322 == pmicChipid) || (0x6323 == pmicChipid)) { -+ WMT_INFO_FUNC("wmt-core: disable wifi 5G support\n"); -+ ctrlPa1 = WIFI_5G_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } else { -+ WMT_WARN_FUNC("wmt-core: unknown PMIC chipid\n"); -+ } -+ break; -+ default: -+ WMT_WARN_FUNC("wmt-core: unknown A die chipid(0x%x)\n", aDieChipid); -+ break; -+ } -+ } -+#endif -+ -+#if 1 -+ ctrlData.ctrlId = WMT_CTRL_SET_STP_DBG_INFO; -+ ctrlData.au4CtrlData[0] = wmt_ic_ops_soc.icId; -+ ctrlData.au4CtrlData[1] = (SIZE_T) gp_soc_info->cChipVersion; -+ ctrlData.au4CtrlData[2] = (SIZE_T) &gp_soc_patch_info; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ WMT_ERR_FUNC("set dump info fail(%d)\n", iRet); -+ return -19; -+ } -+#endif -+ -+#if CFG_WMT_PS_SUPPORT -+ osal_assert(NULL != gp_soc_info); -+ if (NULL != gp_soc_info) { -+ if (MTK_WCN_BOOL_FALSE != gp_soc_info->bPsmSupport) -+ wmt_lib_ps_enable(); -+ else -+ wmt_lib_ps_disable(); -+ } -+#endif -+ -+ return 0; -+} -+ -+static INT32 mtk_wcn_soc_sw_deinit(P_WMT_HIF_CONF pWmtHifConf) -+{ -+ WMT_DBG_FUNC(" start\n"); -+ -+#if CFG_WMT_PS_SUPPORT -+ osal_assert(NULL != gp_soc_info); -+ if ((NULL != gp_soc_info) -+ && (MTK_WCN_BOOL_FALSE != gp_soc_info->bPsmSupport)) { -+ wmt_lib_ps_disable(); -+ } -+#endif -+ -+ gp_soc_info = NULL; -+ -+ return 0; -+} -+ -+static INT32 mtk_wcn_soc_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) -+{ -+ INT32 ret = -1; -+ UINT32 val; -+ -+ if ((flag & WMT_LIB_AIF_FLAG_MASK) == WMT_LIB_AIF_FLAG_SHARE) { -+ WMT_INFO_FUNC("PCM & I2S PIN SHARE\n"); -+#if 0 -+ switch (state) { -+ case WMT_IC_AIF_0: -+ /* BT_PCM_OFF & FM line in/out */ -+ val = 0x00000770; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000000; -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ break; -+ -+ case WMT_IC_AIF_1: -+ /* BT_PCM_ON & FM line in/out */ -+ val = 0x00000700; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000000; -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ break; -+ -+ case WMT_IC_AIF_2: -+ /* BT_PCM_OFF & FM I2S */ -+ val = 0x00000710; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000800; /* 800:3-wire, 000: 4-wire */ -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ break; -+ default: -+ WMT_ERR_FUNC("unsupported state (%d)\n", state); -+ ret = -1; -+ break; -+ } -+#else -+ WMT_WARN_FUNC("TBD!!"); -+ ret = 0; -+#endif -+ } else { -+ /*PCM & I2S separate */ -+ WMT_INFO_FUNC("PCM & I2S PIN SEPARATE\n"); -+#if 0 -+ switch (state) { -+ case WMT_IC_AIF_0: -+ /* BT_PCM_OFF & FM line in/out */ -+ val = 0x00000770; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000000; -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ break; -+ -+ case WMT_IC_AIF_1: -+ /* BT_PCM_ON & FM line in/out */ -+ val = 0x00000700; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000000; -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ break; -+ -+ case WMT_IC_AIF_2: -+ /* BT_PCM_OFF & FM I2S */ -+ val = 0x00000070; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000800; /* 800:3-wire, 000: 4-wire */ -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ -+ break; -+ case WMT_IC_AIF_3: -+ val = 0x00000000; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000800; /* 800:3-wire, 000: 4-wire */ -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ -+ break; -+ default: -+ WMT_ERR_FUNC("unsupported state (%d)\n", state); -+ ret = -1; -+ break; -+ } -+#else -+ switch (state) { -+ case WMT_IC_AIF_0: -+ /* BT_PCM_OFF & FM line in/out */ -+ ret = 0; -+ break; -+ case WMT_IC_AIF_1: -+ /* BT_PCM_ON & FM line in/out */ -+ ret = 0; -+ break; -+ -+ case WMT_IC_AIF_2: -+ /* BT_PCM_OFF & FM I2S */ -+ val = 0x01110000; -+ ret = wmt_core_reg_rw_raw(1, 0x80050078, &val, 0x0FFF0000); -+ -+ break; -+ case WMT_IC_AIF_3: -+ ret = 0; -+ break; -+ -+ default: -+ WMT_ERR_FUNC("unsupported state (%d)\n", state); -+ ret = -1; -+ break; -+ } -+#endif -+ } -+ -+ if (!ret) -+ WMT_WARN_FUNC("new state(%d) fail(%d)\n", state, ret); -+ WMT_INFO_FUNC("new state(%d) ok\n", state); -+ -+ return ret; -+} -+ -+static INT32 mtk_wcn_soc_gps_sync_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) -+{ -+ INT32 iRet = -1; -+ UINT32 uVal = 0; -+ -+ /* mt6797 can not access reg:0x80050078 and no need to do GPS SYNC */ -+ if (0x0279 != wmt_ic_ops_soc.icId) { -+ if (WMT_IC_PIN_MUX == state) -+ uVal = 0x1 << 28; -+ else -+ uVal = 0x5 << 28; -+ iRet = wmt_core_reg_rw_raw(1, 0x80050078, &uVal, 0x7 << 28); -+ if (iRet) -+ WMT_ERR_FUNC("gps_sync pin ctrl failed, iRet(%d)\n", iRet); -+ } else -+ WMT_INFO_FUNC("This chip no need to sync GPS and MODEM!\n"); -+ -+ /* anyway, we return 0 */ -+ return 0; -+} -+ -+static INT32 mtk_wcn_soc_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag) -+{ -+ INT32 ret; -+ -+ WMT_DBG_FUNC("ic pin id:%d, state:%d, flag:0x%x\n", id, state, flag); -+ -+ ret = -1; -+ switch (id) { -+ case WMT_IC_PIN_AUDIO: -+ ret = mtk_wcn_soc_aif_ctrl(state, flag); -+ break; -+ -+ case WMT_IC_PIN_EEDI: -+ WMT_WARN_FUNC("TBD!!"); -+ /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ -+ ret = 0; -+ break; -+ -+ case WMT_IC_PIN_EEDO: -+ WMT_WARN_FUNC("TBD!!"); -+ /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ -+ ret = 0; -+ break; -+ case WMT_IC_PIN_GSYNC: -+ ret = mtk_wcn_soc_gps_sync_ctrl(state, flag); -+ break; -+ default: -+ break; -+ } -+ WMT_INFO_FUNC("ret = (%d)\n", ret); -+ -+ return ret; -+} -+ -+INT32 mtk_wcn_soc_co_clock_ctrl(WMT_CO_CLOCK on) -+{ -+ INT32 iRet = 0; -+ -+ if ((WMT_CO_CLOCK_DIS <= on) && (WMT_CO_CLOCK_MAX > on)) { -+ gCoClockEn = on; -+ } else { -+ WMT_DBG_FUNC("0x%x: error parameter:%d\n", wmt_ic_ops_soc.icId, on); -+ iRet = -1; -+ } -+ WMT_DBG_FUNC("0x%x: Co-clock %s\n", wmt_ic_ops_soc.icId, -+ (gCoClockEn == WMT_CO_CLOCK_DIS) ? "disabled" : "enabled"); -+ -+ return iRet; -+} -+ -+static MTK_WCN_BOOL mtk_wcn_soc_quick_sleep_flag_get(VOID) -+{ -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+static MTK_WCN_BOOL mtk_wcn_soc_aee_dump_flag_get(VOID) -+{ -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+WMT_CO_CLOCK mtk_wcn_soc_co_clock_get(VOID) -+{ -+ return gCoClockEn; -+} -+ -+static INT32 mtk_wcn_soc_ver_check(VOID) -+{ -+ UINT32 hw_ver; -+ UINT32 fw_ver; -+ INT32 iret; -+ const WMT_IC_INFO_S *p_info; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ /* 1. identify chip versions: HVR(HW_VER) and FVR(FW_VER) */ -+ WMT_LOUD_FUNC("0x%x: before read hw_ver (hw version)\n", wmt_ic_ops_soc.icId); -+ iret = wmt_core_reg_rw_raw(0, GEN_HVR, &hw_ver, GEN_VER_MASK); -+ if (iret) { -+ WMT_ERR_FUNC("0x%x: read hw_ver fail:%d\n", wmt_ic_ops_soc.icId, iret); -+ return -2; -+ } -+ WMT_WARN_FUNC("0x%x: read hw_ver (hw version) (0x%x)\n", wmt_ic_ops_soc.icId, hw_ver); -+ -+ WMT_LOUD_FUNC("0x%x: before fw_ver (rom version)\n", wmt_ic_ops_soc.icId); -+ wmt_core_reg_rw_raw(0, GEN_FVR, &fw_ver, GEN_VER_MASK); -+ if (iret) { -+ WMT_ERR_FUNC("0x%x: read fw_ver fail:%d\n", wmt_ic_ops_soc.icId, iret); -+ return -2; -+ } -+ WMT_WARN_FUNC("0x%x: read fw_ver (rom version) (0x%x)\n", wmt_ic_ops_soc.icId, fw_ver); -+ -+ p_info = mtk_wcn_soc_find_wmt_ic_info(hw_ver); -+ if (NULL == p_info) { -+ WMT_ERR_FUNC("0x%x: hw_ver(0x%x) find wmt ic info fail\n", wmt_ic_ops_soc.icId); -+ return -3; -+ } -+ WMT_WARN_FUNC("0x%x: ic info: %s.%s (0x%x/0x%x, WMTHWVER:%d, patch_ext:%s)\n", -+ wmt_ic_ops_soc.icId, p_info->cChipName, p_info->cChipVersion, -+ hw_ver, fw_ver, p_info->eWmtHwVer, p_info->cPatchNameExt); -+ -+ /* hw id & version */ -+ ctrlPa1 = (wmt_ic_ops_soc.icId << 16) | (hw_ver & 0x0000FFFF); -+ /* translated hw version & fw rom version */ -+ ctrlPa2 = ((UINT32) (p_info->eWmtHwVer) << 16) | (fw_ver & 0x0000FFFF); -+ -+ iret = wmt_core_ctrl(WMT_CTRL_HWIDVER_SET, &ctrlPa1, &ctrlPa2); -+ if (iret) -+ WMT_WARN_FUNC("0x%x: WMT_CTRL_HWIDVER_SET fail(%d)\n", wmt_ic_ops_soc.icId, iret); -+ -+ gp_soc_info = p_info; -+ return 0; -+} -+ -+static const WMT_IC_INFO_S *mtk_wcn_soc_find_wmt_ic_info(const UINT32 hw_ver) -+{ -+ /* match chipversion with u4HwVer item in mtk_wcn_soc_info_table */ -+ const UINT32 size = osal_array_size(mtk_wcn_soc_info_table); -+ INT32 index = 0; -+ -+ /* George: reverse the search order to favor newer version products -+ * TODO:[FixMe][GeorgeKuo] Remove full match once API wmt_lib_get_hwver() -+ * is changed correctly in the future!! -+ * Leave full match here is a workaround for GPS to distinguish E3/E4 ICs. -+ */ -+ index = size - 1; -+ /* full match */ -+ while ((0 <= index) && (hw_ver != mtk_wcn_soc_info_table[index].u4HwVer)) -+ --index; -+ if (0 <= index) { -+ WMT_DBG_FUNC("found ic info(0x%x) by full match! index:%d\n", hw_ver, index); -+ return &mtk_wcn_soc_info_table[index]; -+ } -+ -+ WMT_WARN_FUNC("find no ic info for (0x%x) by full match!try major num match!\n", hw_ver); -+ -+ /* George: The ONLY CORRECT method to find supported hw table. Match MAJOR -+ * NUM only can help us support future minor hw ECO, or fab switch, etc. -+ * FULL matching eliminate such flexibility and software package have to be -+ * updated EACH TIME even when minor hw ECO or fab switch!!! -+ */ -+ /* George: reverse the search order to favor newer version products */ -+ index = size - 1; -+ /* major num match */ -+ while ((0 <= index) && -+ (MAJORNUM(hw_ver) != MAJORNUM(mtk_wcn_soc_info_table[index].u4HwVer))) { -+ --index; -+ } -+ if (0 <= index) { -+ WMT_DBG_FUNC("0x%x: found ic info for hw_ver(0x%x) by major num! index:%d\n", -+ wmt_ic_ops_soc.icId, hw_ver, index); -+ return &mtk_wcn_soc_info_table[index]; -+ } -+ -+ WMT_ERR_FUNC("0x%x: find no ic info for hw_ver(0x%x) by full match nor major num match!\n", -+ wmt_ic_ops_soc.icId, hw_ver); -+ WMT_ERR_FUNC("Set default chip version: E1!\n"); -+ return &mtk_wcn_soc_info_table[0]; -+} -+ -+#if CFG_WMT_FILTER_MODE_SETTING -+static INT32 wmt_stp_wifi_lte_coex(VOID) -+{ -+ INT32 iRet; -+ unsigned long addr; -+ WMT_GEN_CONF *pWmtGenConf; -+ -+ /*Get wmt config */ -+ iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); -+ if (iRet) { -+ WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); -+ return -2; -+ } -+ WMT_DBG_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); -+ -+ pWmtGenConf = (P_WMT_GEN_CONF) addr; -+ -+ /*Check if WMT.cfg exists */ -+ if (pWmtGenConf->cfgExist == 0) { -+ WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); -+ /*if WMT.cfg not existed, still return success and adopt the default value */ -+ return 0; -+ } -+ -+ osal_sleep_ms(5); -+ -+ if (pWmtGenConf->coex_wmt_filter_mode == 0) { -+ if ((0x6752 == wmt_ic_ops_soc.icId) || -+ (0x6580 == wmt_ic_ops_soc.icId) || -+ (0x8163 == wmt_ic_ops_soc.icId) || -+ (0x0326 == wmt_ic_ops_soc.icId) || -+ (0x0321 == wmt_ic_ops_soc.icId) || -+ (0x0335 == wmt_ic_ops_soc.icId) || (0x0337 == wmt_ic_ops_soc.icId)) { -+ iRet = -+ wmt_core_init_script(set_wifi_lte_coex_table_1, osal_array_size(set_wifi_lte_coex_table_1)); -+ WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_1 %s(%d)\n", iRet ? "fail" : "ok", iRet); -+ } else if (0x0279 == wmt_ic_ops_soc.icId) { -+ /* add WMT_COXE_CONFIG_EXT_COMPONENT_OPCODE command for 2G4 eLNA demand*/ -+ if (pWmtGenConf->coex_wmt_ext_component) { -+ WMT_INFO_FUNC("coex_wmt_ext_component:0x%x\n", pWmtGenConf->coex_wmt_ext_component); -+ set_wifi_lte_coex_table_2[0].cmd[5] = pWmtGenConf->coex_wmt_ext_component; -+ } -+ iRet = -+ wmt_core_init_script(set_wifi_lte_coex_table_2, osal_array_size(set_wifi_lte_coex_table_2)); -+ WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_2 %s(%d)\n", iRet ? "fail" : "ok", iRet); -+ } else { -+ iRet = -+ wmt_core_init_script(set_wifi_lte_coex_table_0, osal_array_size(set_wifi_lte_coex_table_0)); -+ WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_0 %s(%d)\n", iRet ? "fail" : "ok", iRet); -+ } -+ } -+ -+ return iRet; -+} -+#endif -+ -+static INT32 wmt_stp_init_coex(VOID) -+{ -+ INT32 iRet; -+ unsigned long addr; -+ WMT_GEN_CONF *pWmtGenConf; -+ -+#define COEX_WMT 0 -+ -+#if CFG_SUBSYS_COEX_NEED -+ /* no need for MT6628 */ -+#define COEX_BT 1 -+#define COEX_WIFI 2 -+#define COEX_PTA 3 -+#define COEX_MISC 4 -+#endif -+ /*Get wmt config */ -+ iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); -+ if (iRet) { -+ WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); -+ return -2; -+ } -+ WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); -+ -+ pWmtGenConf = (P_WMT_GEN_CONF) addr; -+ -+ /*Check if WMT.cfg exists */ -+ if (pWmtGenConf->cfgExist == 0) { -+ WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); -+ /*if WMT.cfg not existed, still return success and adopt the default value */ -+ return 0; -+ } -+ -+ /*Dump the coex-related info */ -+ WMT_DBG_FUNC("coex_wmt:0x%x\n", pWmtGenConf->coex_wmt_ant_mode); -+#if CFG_SUBSYS_COEX_NEED -+ WMT_DBG_FUNC("coex_bt:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ pWmtGenConf->coex_bt_rssi_upper_limit, -+ pWmtGenConf->coex_bt_rssi_mid_limit, -+ pWmtGenConf->coex_bt_rssi_lower_limit, -+ pWmtGenConf->coex_bt_pwr_high, pWmtGenConf->coex_bt_pwr_mid, pWmtGenConf->coex_bt_pwr_low); -+ WMT_DBG_FUNC("coex_wifi:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ pWmtGenConf->coex_wifi_rssi_upper_limit, -+ pWmtGenConf->coex_wifi_rssi_mid_limit, -+ pWmtGenConf->coex_wifi_rssi_lower_limit, -+ pWmtGenConf->coex_wifi_pwr_high, pWmtGenConf->coex_wifi_pwr_mid, pWmtGenConf->coex_wifi_pwr_low); -+ WMT_DBG_FUNC("coex_ext_pta:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ pWmtGenConf->coex_ext_pta_hi_tx_tag, -+ pWmtGenConf->coex_ext_pta_hi_rx_tag, -+ pWmtGenConf->coex_ext_pta_lo_tx_tag, -+ pWmtGenConf->coex_ext_pta_lo_rx_tag, -+ pWmtGenConf->coex_ext_pta_sample_t1, -+ pWmtGenConf->coex_ext_pta_sample_t2, pWmtGenConf->coex_ext_pta_wifi_bt_con_trx); -+ WMT_DBG_FUNC("coex_misc:0x%x 0x%x 0x%x\n", -+ pWmtGenConf->coex_misc_ext_pta_on, pWmtGenConf->coex_misc_ext_feature_set); -+#endif -+ -+ /*command adjustion due to WMT.cfg */ -+ coex_table[COEX_WMT].cmd[5] = pWmtGenConf->coex_wmt_ant_mode; -+ if (gWmtDbgLvl >= WMT_LOG_DBG) -+ wmt_core_dump_data(&coex_table[COEX_WMT].cmd[0], coex_table[COEX_WMT].str, coex_table[COEX_WMT].cmdSz); -+ -+#if CFG_SUBSYS_COEX_NEED -+ coex_table[COEX_BT].cmd[9] = pWmtGenConf->coex_bt_rssi_upper_limit; -+ coex_table[COEX_BT].cmd[10] = pWmtGenConf->coex_bt_rssi_mid_limit; -+ coex_table[COEX_BT].cmd[11] = pWmtGenConf->coex_bt_rssi_lower_limit; -+ coex_table[COEX_BT].cmd[12] = pWmtGenConf->coex_bt_pwr_high; -+ coex_table[COEX_BT].cmd[13] = pWmtGenConf->coex_bt_pwr_mid; -+ coex_table[COEX_BT].cmd[14] = pWmtGenConf->coex_bt_pwr_low; -+ if (gWmtDbgLvl >= WMT_LOG_DBG) -+ wmt_core_dump_data(&coex_table[COEX_BT].cmd[0], coex_table[COEX_BT].str, coex_table[COEX_BT].cmdSz); -+ -+ coex_table[COEX_WIFI].cmd[10] = pWmtGenConf->coex_wifi_rssi_upper_limit; -+ coex_table[COEX_WIFI].cmd[11] = pWmtGenConf->coex_wifi_rssi_mid_limit; -+ coex_table[COEX_WIFI].cmd[12] = pWmtGenConf->coex_wifi_rssi_lower_limit; -+ coex_table[COEX_WIFI].cmd[13] = pWmtGenConf->coex_wifi_pwr_high; -+ coex_table[COEX_WIFI].cmd[14] = pWmtGenConf->coex_wifi_pwr_mid; -+ coex_table[COEX_WIFI].cmd[15] = pWmtGenConf->coex_wifi_pwr_low; -+ if (gWmtDbgLvl >= WMT_LOG_DBG) -+ wmt_core_dump_data(&coex_table[COEX_WIFI].cmd[0], -+ coex_table[COEX_WIFI].str, coex_table[COEX_WIFI].cmdSz); -+ -+ coex_table[COEX_PTA].cmd[5] = pWmtGenConf->coex_ext_pta_hi_tx_tag; -+ coex_table[COEX_PTA].cmd[6] = pWmtGenConf->coex_ext_pta_hi_rx_tag; -+ coex_table[COEX_PTA].cmd[7] = pWmtGenConf->coex_ext_pta_lo_tx_tag; -+ coex_table[COEX_PTA].cmd[8] = pWmtGenConf->coex_ext_pta_lo_rx_tag; -+ coex_table[COEX_PTA].cmd[9] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0xff00) >> 8); -+ coex_table[COEX_PTA].cmd[10] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0x00ff) >> 0); -+ coex_table[COEX_PTA].cmd[11] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0xff00) >> 8); -+ coex_table[COEX_PTA].cmd[12] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0x00ff) >> 0); -+ coex_table[COEX_PTA].cmd[13] = pWmtGenConf->coex_ext_pta_wifi_bt_con_trx; -+ if (gWmtDbgLvl >= WMT_LOG_DBG) -+ wmt_core_dump_data(&coex_table[COEX_PTA].cmd[0], coex_table[COEX_PTA].str, coex_table[COEX_PTA].cmdSz); -+ -+ osal_memcpy(&coex_table[COEX_MISC].cmd[5], &pWmtGenConf->coex_misc_ext_pta_on, -+ sizeof(pWmtGenConf->coex_misc_ext_pta_on)); -+ osal_memcpy(&coex_table[COEX_MISC].cmd[9], &pWmtGenConf->coex_misc_ext_feature_set, -+ sizeof(pWmtGenConf->coex_misc_ext_feature_set)); -+ -+ wmt_core_dump_data(&coex_table[COEX_MISC].cmd[0], coex_table[COEX_MISC].str, coex_table[COEX_MISC].cmdSz); -+#endif -+ -+ iRet = wmt_core_init_script(coex_table, sizeof(coex_table) / sizeof(coex_table[0])); -+ -+ return iRet; -+} -+ -+#if CFG_WMT_SDIO_DRIVING_SET -+static INT32 mtk_wcn_soc_set_sdio_driving(void) -+{ -+ INT32 ret = 0; -+ -+ unsigned long addr; -+ WMT_GEN_CONF *pWmtGenConf; -+ UINT32 drv_val = 0; -+ -+ /*Get wmt config */ -+ ret = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); -+ if (ret) { -+ WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", ret); -+ return -1; -+ } -+ WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); -+ -+ pWmtGenConf = (P_WMT_GEN_CONF) addr; -+ -+ /*Check if WMT.cfg exists */ -+ if (pWmtGenConf->cfgExist == 0) { -+ WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); -+ /*if WMT.cfg not existed, still return success and adopt the default value */ -+ return 0; -+ } -+ -+ drv_val = pWmtGenConf->sdio_driving_cfg; -+ -+ /*Dump the sdio driving related info */ -+ WMT_INFO_FUNC("sdio driving:0x%x\n", drv_val); -+ -+ sdio_driving_table[0].cmd[12] = (UINT8) ((drv_val & 0x00000077UL) >> 0); /* DAT0 and DAT1 */ -+ sdio_driving_table[0].cmd[13] = (UINT8) ((drv_val & 0x00007700UL) >> 8); /* DAT2 and DAT3 */ -+ sdio_driving_table[0].cmd[14] = (UINT8) ((drv_val & 0x00070000UL) >> 16); /* CMD */ -+ -+ ret = wmt_core_init_script(sdio_driving_table, sizeof(sdio_driving_table) / sizeof(sdio_driving_table[0])); -+ -+ return ret; -+} -+#endif -+ -+#if CFG_WMT_CRYSTAL_TIMING_SET -+static INT32 mtk_wcn_soc_crystal_triming_set(VOID) -+{ -+ INT32 iRet = 0; -+ PUINT8 pbuf = NULL; -+ UINT32 bufLen = 0; -+ WMT_CTRL_DATA ctrlData; -+ UINT32 uCryTimOffset = 0x6D; -+ MTK_WCN_BOOL bIsNvramExist = MTK_WCN_BOOL_FALSE; -+ INT8 cCrystalTimingOffset = 0x0; -+ UINT8 cCrystalTiming = 0x0; -+ INT32 iCrystalTiming = 0x0; -+ MTK_WCN_BOOL bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; -+ UINT32 u4Res; -+ -+ bIsNvramExist = MTK_WCN_BOOL_FALSE; -+ /**/ ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_GET; -+ ctrlData.au4CtrlData[0] = (UINT32) "/data/nvram/APCFG/APRDEB/WIFI"; -+ ctrlData.au4CtrlData[1] = (UINT32) &pbuf; -+ ctrlData.au4CtrlData[2] = (UINT32) &bufLen; -+ -+ iRet = wmt_ctrl(&ctrlData); -+ if (0 != iRet) { -+ WMT_ERR_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_GET fail:%d\n", wmt_ic_ops_soc.icId, iRet); -+ bIsNvramExist = MTK_WCN_BOOL_FALSE; -+ bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; -+ cCrystalTimingOffset = 0x0; -+ cCrystalTiming = 0x0; -+ iRet = -1; -+ } else { -+ WMT_DBG_FUNC("0x%x: nvram pBuf(0x%08x), bufLen(%d)\n", wmt_ic_ops_soc.icId, pbuf, bufLen); -+ if (bufLen < (uCryTimOffset + 1)) { -+ WMT_ERR_FUNC("0x%x: nvram len(%d) too short, crystalTimging value offset(%d)\n", -+ wmt_ic_ops_soc.icId, bufLen, uCryTimOffset); -+ bIsNvramExist = MTK_WCN_BOOL_FALSE; -+ bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; -+ cCrystalTimingOffset = 0x0; -+ cCrystalTiming = 0x0; -+ } else { -+ bIsNvramExist = MTK_WCN_BOOL_TRUE; -+ cCrystalTimingOffset = *(pbuf + uCryTimOffset); -+ if (cCrystalTimingOffset & 0x80) { -+ bIsCrysTrimEnabled = MTK_WCN_BOOL_TRUE; -+ cCrystalTimingOffset = (UINT8) cCrystalTimingOffset & 0x7f; -+ } -+ WMT_DBG_FUNC("cCrystalTimingOffset (%d), bIsCrysTrimEnabled(%d)\n", cCrystalTimingOffset, -+ bIsCrysTrimEnabled); -+ } -+ ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_PUT; -+ ctrlData.au4CtrlData[0] = (UINT32) "/data/nvram/APCFG/APRDEB/WIFI"; -+ iRet = wmt_ctrl(&ctrlData); -+ if (0 != iRet) { -+ WMT_ERR_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_PUT fail:%d\n", wmt_ic_ops_soc.icId, iRet); -+ iRet = -2; -+ } else { -+ WMT_DBG_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_PUT succeed\n", wmt_ic_ops_soc.icId); -+ } -+ } -+ if ((MTK_WCN_BOOL_TRUE == bIsNvramExist) && (MTK_WCN_BOOL_TRUE == bIsCrysTrimEnabled)) { -+ /*get CrystalTiming value before set it */ -+ iRet = -+ wmt_core_tx(get_crystal_timing_script[0].cmd, get_crystal_timing_script[0].cmdSz, &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != get_crystal_timing_script[0].cmdSz)) { -+ WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", -+ get_crystal_timing_script[0].str, iRet, u4Res, get_crystal_timing_script[0].cmdSz); -+ iRet = -3; -+ goto done; -+ } -+ /* EVENT BUF */ -+ osal_memset(get_crystal_timing_script[0].evt, 0, get_crystal_timing_script[0].evtSz); -+ iRet = wmt_core_rx(get_crystal_timing_script[0].evt, get_crystal_timing_script[0].evtSz, &u4Res); -+ if (iRet || (u4Res != get_crystal_timing_script[0].evtSz)) { -+ WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", -+ get_crystal_timing_script[0].str, iRet, u4Res, get_crystal_timing_script[0].evtSz); -+ mtk_wcn_stp_dbg_dump_package(); -+ iRet = -4; -+ goto done; -+ } -+ -+ iCrystalTiming = WMT_GET_CRYSTAL_TRIMING_EVT[5] & 0x7f; -+ if (cCrystalTimingOffset & 0x40) { -+ /*nagative offset value */ -+ iCrystalTiming = iCrystalTiming + cCrystalTimingOffset - 128; -+ } else { -+ iCrystalTiming += cCrystalTimingOffset; -+ } -+ WMT_DBG_FUNC("iCrystalTiming (0x%x)\n", iCrystalTiming); -+ cCrystalTiming = iCrystalTiming > 0x7f ? 0x7f : iCrystalTiming; -+ cCrystalTiming = iCrystalTiming < 0 ? 0 : iCrystalTiming; -+ WMT_DBG_FUNC("cCrystalTiming (0x%x)\n", cCrystalTiming); -+ /* set_crystal_timing_script */ -+ WMT_SET_CRYSTAL_TRIMING_CMD[5] = cCrystalTiming; -+ WMT_GET_CRYSTAL_TRIMING_EVT[5] = cCrystalTiming; -+ -+ iRet = wmt_core_init_script(set_crystal_timing_script, osal_array_size(set_crystal_timing_script)); -+ if (iRet) { -+ WMT_ERR_FUNC("set_crystal_timing_script fail(%d)\n", iRet); -+ iRet = -5; -+ } else { -+ WMT_DBG_FUNC("set crystal timing value (0x%x) succeed\n", WMT_SET_CRYSTAL_TRIMING_CMD[5]); -+ iRet = -+ wmt_core_init_script(get_crystal_timing_script, osal_array_size(get_crystal_timing_script)); -+ if (iRet) { -+ WMT_ERR_FUNC("get_crystal_timing_script fail(%d)\n", iRet); -+ iRet = -6; -+ } else { -+ WMT_INFO_FUNC("succeed, updated crystal timing value (0x%x)\n", -+ WMT_GET_CRYSTAL_TRIMING_EVT[5]); -+ iRet = 0x0; -+ } -+ } -+ } -+done: -+ return iRet; -+} -+#endif -+ -+#if CFG_WMT_MULTI_PATCH -+static INT32 mtk_wcn_soc_patch_info_prepare(VOID) -+{ -+ INT32 iRet = -1; -+ WMT_CTRL_DATA ctrlData; -+ -+ ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; -+ iRet = wmt_ctrl(&ctrlData); -+ -+ return iRet; -+} -+ -+static INT32 mtk_wcn_soc_patch_dwn(UINT32 index) -+{ -+ INT32 iRet = -1; -+ P_WMT_PATCH patchHdr; -+ PUINT8 pbuf; -+ UINT32 patchSize; -+ UINT32 fragSeq; -+ UINT32 fragNum; -+ UINT16 fragSize = 0; -+ UINT16 cmdLen; -+ UINT32 offset; -+ UINT32 u4Res; -+ UINT8 evtBuf[8]; -+ UINT8 addressevtBuf[12]; -+ UINT8 addressByte[4]; -+ PINT8 cDataTime = NULL; -+ /*PINT8 cPlat = NULL; */ -+ UINT16 u2HwVer = 0; -+ UINT16 u2SwVer = 0; -+ UINT32 u4PatchVer = 0; -+ UINT32 patchSizePerFrag = 0; -+ WMT_CTRL_DATA ctrlData; -+ -+ /*1.check hardware information */ -+ if (NULL == gp_soc_info) { -+ WMT_ERR_FUNC("null gp_soc_info!\n"); -+ return -1; -+ } -+ -+ osal_memset(gFullPatchName, 0, osal_sizeof(gFullPatchName)); -+ -+ ctrlData.ctrlId = WMT_CTRL_GET_PATCH_INFO; -+ ctrlData.au4CtrlData[0] = index + 1; -+ ctrlData.au4CtrlData[1] = (SIZE_T) &gFullPatchName; -+ ctrlData.au4CtrlData[2] = (SIZE_T) &addressByte; -+ iRet = wmt_ctrl(&ctrlData); -+ WMT_DBG_FUNC("the %d time valid patch found: (%s)\n", index + 1, gFullPatchName); -+ -+ /* <2.2> read patch content */ -+ ctrlData.ctrlId = WMT_CTRL_GET_PATCH; -+ ctrlData.au4CtrlData[0] = (SIZE_T) NULL; -+ ctrlData.au4CtrlData[1] = (SIZE_T) &gFullPatchName; -+ ctrlData.au4CtrlData[2] = (SIZE_T) &pbuf; -+ ctrlData.au4CtrlData[3] = (SIZE_T) &patchSize; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); -+ iRet -= 1; -+ goto done; -+ } -+ -+ /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ -+ pbuf += BCNT_PATCH_BUF_HEADROOM; -+ /* patch file with header: -+ * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| -+ */ -+ patchHdr = (P_WMT_PATCH) pbuf; -+ /* check patch file information */ -+ -+ cDataTime = patchHdr->ucDateTime; -+ u2HwVer = patchHdr->u2HwVer; -+ u2SwVer = patchHdr->u2SwVer; -+ u4PatchVer = patchHdr->u4PatchVer; -+ /*cPlat = &patchHdr->ucPLat[0]; */ -+ -+ cDataTime[15] = '\0'; -+ if (index == 0) { -+ WMT_DBG_FUNC("===========================================\n"); -+ WMT_INFO_FUNC("[Patch]BuiltTime = %s, HVer = 0x%x, SVer = 0x%x, PhVer = 0x%04x,Platform = %c%c%c%c\n", -+ cDataTime, ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8), -+ ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8), -+ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16), -+ patchHdr->ucPLat[0], patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); -+ WMT_DBG_FUNC("[Consys Patch] Hw Ver = 0x%x\n", ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8)); -+ WMT_DBG_FUNC("[Consys Patch] Sw Ver = 0x%x\n", ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8)); -+ WMT_DBG_FUNC("[Consys Patch] Ph Ver = 0x%04x\n", -+ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16)); -+ WMT_DBG_FUNC("[Consys Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], patchHdr->ucPLat[1], -+ patchHdr->ucPLat[2], patchHdr->ucPLat[3]); -+ WMT_DBG_FUNC("===========================================\n"); -+ } -+ -+ /* remove patch header: -+ * |<-patch body: X Bytes (X=patchSize)--->| -+ */ -+ patchSize -= sizeof(WMT_PATCH); -+ pbuf += sizeof(WMT_PATCH); -+ patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; -+ /* reserve 1st patch cmd space before patch body -+ * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| -+ */ -+ /* gp_soc_patch_info = patchHdr; */ -+ osal_memcpy(&gp_soc_patch_info, patchHdr, osal_sizeof(WMT_PATCH)); -+ pbuf -= sizeof(WMT_PATCH_CMD); -+ -+ fragNum = patchSize / patchSizePerFrag; -+ fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; -+ -+ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); -+ -+ /*send wmt part patch address command */ -+ if (0x6752 == wmt_ic_ops_soc.icId || -+ 0x8127 == wmt_ic_ops_soc.icId || -+ 0x7623 == wmt_ic_ops_soc.icId || -+ 0x6571 == wmt_ic_ops_soc.icId || -+ 0x0326 == wmt_ic_ops_soc.icId || -+ 0x0321 == wmt_ic_ops_soc.icId || -+ 0x0335 == wmt_ic_ops_soc.icId || -+ 0x0337 == wmt_ic_ops_soc.icId || 0x8163 == wmt_ic_ops_soc.icId || 0x6580 == wmt_ic_ops_soc.icId) { -+ /* MT6571 patch RAM base */ -+ WMT_PATCH_ADDRESS_CMD[8] = 0x40; -+ WMT_PATCH_P_ADDRESS_CMD[8] = 0xc8; -+ } -+ /*send wmt part patch address command */ -+ if (0x0279 == wmt_ic_ops_soc.icId) { -+ /* MT6797 patch RAM base */ -+ WMT_PATCH_ADDRESS_CMD[8] = 0x08; -+ WMT_PATCH_ADDRESS_CMD[9] = 0x05; -+ WMT_PATCH_P_ADDRESS_CMD[8] = 0x2c; -+ WMT_PATCH_P_ADDRESS_CMD[9] = 0x0b; -+ } -+ -+ /*send wmt part patch address command */ -+ iRet = -+ wmt_core_tx((PUINT8) &WMT_PATCH_ADDRESS_CMD[0], sizeof(WMT_PATCH_ADDRESS_CMD), &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_CMD))) { -+ WMT_ERR_FUNC("wmt_core:wmt patch address CMD fail(%d),size(%d)\n", iRet, u4Res); -+ iRet -= 1; -+ goto done; -+ } -+ osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); -+ iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_ADDRESS_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_EVT))) { -+ WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d)\n", iRet, u4Res); -+ iRet -= 1; -+ goto done; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(addressevtBuf, WMT_PATCH_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail\n"); -+ iRet -= 1; -+ goto done; -+ } -+#endif -+ -+ /*send part patch address command */ -+ osal_memcpy(&WMT_PATCH_P_ADDRESS_CMD[12], addressByte, osal_sizeof(addressByte)); -+ WMT_DBG_FUNC("4 bytes address command:0x%02x,0x%02x,0x%02x,0x%02x", -+ WMT_PATCH_P_ADDRESS_CMD[12], -+ WMT_PATCH_P_ADDRESS_CMD[13], WMT_PATCH_P_ADDRESS_CMD[14], WMT_PATCH_P_ADDRESS_CMD[15]); -+ iRet = -+ wmt_core_tx((PUINT8) &WMT_PATCH_P_ADDRESS_CMD[0], sizeof(WMT_PATCH_P_ADDRESS_CMD), &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_CMD))) { -+ WMT_ERR_FUNC("wmt_core:wmt part patch address CMD fail(%d),size(%d),index(%d)\n", iRet, u4Res, index); -+ iRet -= 1; -+ goto done; -+ } -+ osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); -+ iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_P_ADDRESS_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_EVT))) { -+ WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d),index(%d)\n", iRet, u4Res, index); -+ iRet -= 1; -+ goto done; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(addressevtBuf, WMT_PATCH_P_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail,index(%d)\n", index); -+ iRet -= 1; -+ goto done; -+ } -+#endif -+ -+ /* send all fragments */ -+ offset = sizeof(WMT_PATCH_CMD); -+ fragSeq = 0; -+ while (fragSeq < fragNum) { -+ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); -+ if (fragSeq == (fragNum - 1)) { -+ /* last fragment */ -+ fragSize = patchSize - fragSeq * patchSizePerFrag; -+ WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; -+ } else { -+ fragSize = patchSizePerFrag; -+ WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; -+ } -+ /* update length field in CMD:flag+frag */ -+ cmdLen = 1 + fragSize; -+ osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); -+ /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ -+ osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, sizeof(WMT_PATCH_CMD)); -+ -+ /* iRet = -+ *(*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), -+ *&u4Res); -+ */ -+ iRet = -+ wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), -+ &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { -+ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, -+ fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); -+ iRet -= 1; -+ break; -+ } -+ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", -+ fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); -+ -+ osal_memset(evtBuf, 0, sizeof(evtBuf)); -+ /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ -+ iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { -+ WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) fail(%d)\n", sizeof(WMT_PATCH_EVT), -+ u4Res, iRet); -+ iRet -= 1; -+ break; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_PATCH_EVT error rx(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, -+ evtBuf[0], -+ evtBuf[1], -+ evtBuf[2], -+ evtBuf[3], -+ evtBuf[4]); -+ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ sizeof(WMT_PATCH_EVT), -+ WMT_PATCH_EVT[0], -+ WMT_PATCH_EVT[1], -+ WMT_PATCH_EVT[2], -+ WMT_PATCH_EVT[3], -+ WMT_PATCH_EVT[4]); -+ iRet -= 1; -+ break; -+ } -+#endif -+ WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) ok\n", sizeof(WMT_PATCH_EVT), u4Res); -+ offset += patchSizePerFrag; -+ ++fragSeq; -+ } -+ -+ WMT_WARN_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", -+ iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); -+ -+ if (fragSeq != fragNum) -+ iRet -= 1; -+done: -+ /* WMT_CTRL_FREE_PATCH always return 0 */ -+ /* wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); */ -+ ctrlData.ctrlId = WMT_CTRL_FREE_PATCH; -+ ctrlData.au4CtrlData[0] = index + 1; -+ wmt_ctrl(&ctrlData); -+ -+ return iRet; -+} -+ -+#else -+static INT32 mtk_wcn_soc_patch_dwn(VOID) -+{ -+ INT32 iRet = -1; -+ P_WMT_PATCH patchHdr; -+ PUINT8 pbuf; -+ UINT32 patchSize; -+ UINT32 fragSeq; -+ UINT32 fragNum; -+ UINT16 fragSize = 0; -+ UINT16 cmdLen; -+ UINT32 offset; -+ UINT32 u4Res; -+ UINT8 evtBuf[8]; -+ PINT8 cDataTime = NULL; -+ /*PINT8 cPlat = NULL; */ -+ UINT16 u2HwVer = 0; -+ UINT16 u2SwVer = 0; -+ UINT32 u4PatchVer = 0; -+ UINT32 patchSizePerFrag = 0; -+ WMT_CTRL_DATA ctrlData; -+ -+ /*1.check hardware information */ -+ if (NULL == gp_soc_info) { -+ WMT_ERR_FUNC("null gp_soc_info!\n"); -+ return -1; -+ } -+ /* <2> search patch and read patch content */ -+ /* <2.1> search patch */ -+ ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; -+ iRet = wmt_ctrl(&ctrlData); -+ if (0 == iRet) { -+ /* patch with correct Hw Ver Major Num found */ -+ ctrlData.ctrlId = WMT_CTRL_GET_PATCH_NAME; -+ ctrlData.au4CtrlData[0] = (UINT32) &gFullPatchName; -+ iRet = wmt_ctrl(&ctrlData); -+ -+ WMT_INFO_FUNC("valid patch found: (%s)\n", gFullPatchName); -+ /* <2.2> read patch content */ -+ ctrlData.ctrlId = WMT_CTRL_GET_PATCH; -+ ctrlData.au4CtrlData[0] = (UINT32) NULL; -+ ctrlData.au4CtrlData[1] = (UINT32) &gFullPatchName; -+ -+ } else { -+ iRet -= 1; -+ return iRet; -+ } -+ ctrlData.au4CtrlData[2] = (UINT32) &pbuf; -+ ctrlData.au4CtrlData[3] = (UINT32) &patchSize; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); -+ iRet -= 1; -+ goto done; -+ } -+ -+ /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ -+ pbuf += BCNT_PATCH_BUF_HEADROOM; -+ /* patch file with header: -+ * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| -+ */ -+ patchHdr = (P_WMT_PATCH) pbuf; -+ /* check patch file information */ -+ -+ cDataTime = patchHdr->ucDateTime; -+ u2HwVer = patchHdr->u2HwVer; -+ u2SwVer = patchHdr->u2SwVer; -+ u4PatchVer = patchHdr->u4PatchVer; -+ /*cPlat = &patchHdr->ucPLat[0]; */ -+ -+ cDataTime[15] = '\0'; -+ WMT_DBG_FUNC("===========================================\n"); -+ WMT_INFO_FUNC("[ConsysPatch]BuiltTime = %s, HVer = 0x%x, SVer = 0x%x, PhVer = 0x%04x,Platform = %c%c%c%c\n", -+ cDataTime, ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8), -+ ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8), -+ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16), -+ patchHdr->ucPLat[0], patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); -+ WMT_DBG_FUNC("[Consys Patch] Hw Ver = 0x%x\n", ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8)); -+ WMT_DBG_FUNC("[Consys Patch] Sw Ver = 0x%x\n", ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8)); -+ WMT_DBG_FUNC("[Consys Patch] Ph Ver = 0x%04x\n", -+ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16)); -+ WMT_DBG_FUNC("[Consys Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], patchHdr->ucPLat[1], -+ patchHdr->ucPLat[2], patchHdr->ucPLat[3]); -+ WMT_DBG_FUNC("===========================================\n"); -+ -+ /* remove patch header: -+ * |<-patch body: X Bytes (X=patchSize)--->| -+ */ -+ patchSize -= sizeof(WMT_PATCH); -+ pbuf += sizeof(WMT_PATCH); -+ patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; -+ /* reserve 1st patch cmd space before patch body -+ * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| -+ */ -+ pbuf -= sizeof(WMT_PATCH_CMD); -+ -+ fragNum = patchSize / patchSizePerFrag; -+ fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; -+ -+ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); -+ -+ /* send all fragments */ -+ offset = sizeof(WMT_PATCH_CMD); -+ fragSeq = 0; -+ while (fragSeq < fragNum) { -+ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); -+ if (fragSeq == (fragNum - 1)) { -+ /* last fragment */ -+ fragSize = patchSize - fragSeq * patchSizePerFrag; -+ WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; -+ } else { -+ fragSize = patchSizePerFrag; -+ WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; -+ } -+ /* update length field in CMD:flag+frag */ -+ cmdLen = 1 + fragSize; -+ osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); -+ /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ -+ osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, sizeof(WMT_PATCH_CMD)); -+ -+ /* iRet = -+ * (*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), -+ * &u4Res); -+ */ -+ iRet = -+ wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { -+ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, -+ fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); -+ iRet -= 1; -+ break; -+ } -+ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", -+ fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); -+ -+ osal_memset(evtBuf, 0, sizeof(evtBuf)); -+ /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ -+ iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { -+ WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) fail(%d)\n", sizeof(WMT_PATCH_EVT), -+ u4Res, iRet); -+ iRet -= 1; -+ break; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_PATCH_EVT error rx(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, -+ evtBuf[0], -+ evtBuf[1], -+ evtBuf[2], -+ evtBuf[3], -+ evtBuf[4]); -+ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ sizeof(WMT_PATCH_EVT), -+ WMT_PATCH_EVT[0], -+ WMT_PATCH_EVT[1], -+ WMT_PATCH_EVT[2], -+ WMT_PATCH_EVT[3], -+ WMT_PATCH_EVT[4]); -+ iRet -= 1; -+ break; -+ } -+#endif -+ WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) ok\n", sizeof(WMT_PATCH_EVT), u4Res); -+ offset += patchSizePerFrag; -+ ++fragSeq; -+ } -+ -+ WMT_WARN_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", -+ iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); -+ -+ if (fragSeq != fragNum) -+ iRet -= 1; -+done: -+ /* WMT_CTRL_FREE_PATCH always return 0 */ -+ wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); -+ -+ return iRet; -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c -new file mode 100644 -index 0000000000000..747ed64af2d2d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c -@@ -0,0 +1,1938 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-LIB]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+ -+#include "wmt_dev.h" -+#include "wmt_lib.h" -+#include "wmt_conf.h" -+#include "wmt_core.h" -+#include "wmt_plat.h" -+ -+#include "stp_core.h" -+#include "btm_core.h" -+#include "psm_core.h" -+#include "stp_dbg.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* A table for translation: CMB_STUB_AIF_X=>WMT_IC_PIN_STATE */ -+static const WMT_IC_PIN_STATE cmb_aif2pin_stat[] = { -+ [CMB_STUB_AIF_0] = WMT_IC_AIF_0, -+ [CMB_STUB_AIF_1] = WMT_IC_AIF_1, -+ [CMB_STUB_AIF_2] = WMT_IC_AIF_2, -+ [CMB_STUB_AIF_3] = WMT_IC_AIF_3, -+}; -+ -+#if CFG_WMT_PS_SUPPORT -+static UINT32 gPsIdleTime = STP_PSM_IDLE_TIME_SLEEP; -+static UINT32 gPsEnable = 1; -+static PF_WMT_SDIO_PSOP sdio_own_ctrl; -+#endif -+ -+#define WMT_STP_CPUPCR_BUF_SIZE 6144 -+static UINT8 g_cpupcr_buf[WMT_STP_CPUPCR_BUF_SIZE] = { 0 }; -+ -+static UINT32 g_quick_sleep_ctrl = 1; -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+DEV_WMT gDevWmt; -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#if CFG_WMT_PS_SUPPORT -+static MTK_WCN_BOOL wmt_lib_ps_action(MTKSTP_PSM_ACTION_T action); -+static MTK_WCN_BOOL wmt_lib_ps_do_sleep(VOID); -+static MTK_WCN_BOOL wmt_lib_ps_do_wakeup(VOID); -+static MTK_WCN_BOOL wmt_lib_ps_do_host_awake(VOID); -+static INT32 wmt_lib_ps_handler(MTKSTP_PSM_ACTION_T action); -+#endif -+ -+static MTK_WCN_BOOL wmt_lib_put_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pLxOp); -+ -+static P_OSAL_OP wmt_lib_get_op(P_OSAL_OP_Q pOpQ); -+ -+static INT32 wmtd_thread(PVOID pvData); -+ -+static INT32 wmt_lib_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE stat, UINT32 flag); -+static MTK_WCN_BOOL wmt_lib_hw_state_show(VOID); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+INT32 wmt_lib_idc_lock_aquire(VOID) -+{ -+ return osal_lock_sleepable_lock(&gDevWmt.idc_lock); -+} -+ -+VOID wmt_lib_idc_lock_release(VOID) -+{ -+ osal_unlock_sleepable_lock(&gDevWmt.idc_lock); -+} -+INT32 wmt_lib_psm_lock_aquire(void) -+{ -+ return osal_lock_sleepable_lock(&gDevWmt.psm_lock); -+} -+ -+void wmt_lib_psm_lock_release(void) -+{ -+ osal_unlock_sleepable_lock(&gDevWmt.psm_lock); -+} -+ -+INT32 DISABLE_PSM_MONITOR(void) -+{ -+ INT32 ret = 0; -+ -+ /* osal_lock_sleepable_lock(&gDevWmt.psm_lock); */ -+ ret = wmt_lib_psm_lock_aquire(); -+ if (ret) { -+ WMT_ERR_FUNC("--->lock psm_lock failed, ret=%d\n", ret); -+ return ret; -+ } -+#if CFG_WMT_PS_SUPPORT -+ ret = wmt_lib_ps_disable(); -+ if (ret) { -+ WMT_ERR_FUNC("wmt_lib_ps_disable fail, ret=%d\n", ret); -+ wmt_lib_psm_lock_release(); -+ } -+#endif -+ -+ return ret; -+} -+ -+void ENABLE_PSM_MONITOR(void) -+{ -+#if CFG_WMT_PS_SUPPORT -+ wmt_lib_ps_enable(); -+#endif -+ /* osal_unlock_sleepable_lock(&gDevWmt.psm_lock); */ -+ wmt_lib_psm_lock_release(); -+} -+ -+INT32 wmt_lib_init(VOID) -+{ -+ INT32 iRet; -+ UINT32 i; -+ P_DEV_WMT pDevWmt; -+ P_OSAL_THREAD pThraed; -+ -+ /* create->init->start */ -+ /* 1. create: static allocation with zero initialization */ -+ pDevWmt = &gDevWmt; -+ osal_memset(&gDevWmt, 0, sizeof(gDevWmt)); -+ -+ iRet = wmt_conf_read_file(); -+ if (iRet) { -+ WMT_ERR_FUNC("read wmt config file fail(%d)\n", iRet); -+ return -1; -+ } -+ -+ pThraed = &gDevWmt.thread; -+ -+ /* Create mtk_wmtd thread */ -+ osal_strncpy(pThraed->threadName, "mtk_wmtd", sizeof(pThraed->threadName)); -+ pThraed->pThreadData = (VOID *) pDevWmt; -+ pThraed->pThreadFunc = (VOID *) wmtd_thread; -+ iRet = osal_thread_create(pThraed); -+ if (iRet) { -+ WMT_ERR_FUNC("osal_thread_create(0x%p) fail(%d)\n", pThraed, iRet); -+ return -2; -+ } -+ -+ /* 2. initialize */ -+ /* Initialize wmt_core */ -+ -+ iRet = wmt_core_init(); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_core_init() fail(%d)\n", iRet); -+ return -1; -+ } -+ -+ /* Initialize WMTd Thread Information: Thread */ -+ osal_event_init(&pDevWmt->rWmtdWq); -+ osal_sleepable_lock_init(&pDevWmt->psm_lock); -+ osal_sleepable_lock_init(&pDevWmt->idc_lock); -+ osal_sleepable_lock_init(&pDevWmt->rActiveOpQ.sLock); -+ osal_sleepable_lock_init(&pDevWmt->rFreeOpQ.sLock); -+ pDevWmt->state.data = 0; -+ -+ /* Initialize op queue */ -+ RB_INIT(&pDevWmt->rFreeOpQ, WMT_OP_BUF_SIZE); -+ RB_INIT(&pDevWmt->rActiveOpQ, WMT_OP_BUF_SIZE); -+ /* Put all to free Q */ -+ for (i = 0; i < WMT_OP_BUF_SIZE; i++) { -+ osal_signal_init(&(pDevWmt->arQue[i].signal)); -+ wmt_lib_put_op(&pDevWmt->rFreeOpQ, &(pDevWmt->arQue[i])); -+ } -+ -+ /* initialize stp resources */ -+ osal_event_init(&pDevWmt->rWmtRxWq); -+ -+ /*function driver callback */ -+ for (i = 0; i < WMTDRV_TYPE_WIFI; i++) -+ pDevWmt->rFdrvCb.fDrvRst[i] = NULL; -+ -+ pDevWmt->hw_ver = WMTHWVER_MAX; -+ WMT_INFO_FUNC("***********Init, hw->ver = %x\n", pDevWmt->hw_ver); -+ -+ /* TODO:[FixMe][GeorgeKuo]: wmt_lib_conf_init */ -+ /* initialize default configurations */ -+ /* i4Result = wmt_lib_conf_init(VOID); */ -+ /* WMT_WARN_FUNC("wmt_drv_conf_init(%d)\n", i4Result); */ -+ -+ osal_signal_init(&pDevWmt->cmdResp); -+ osal_event_init(&pDevWmt->cmdReq); -+ -+ /* initialize platform resources */ -+ if (0 != gDevWmt.rWmtGenConf.cfgExist) -+ iRet = wmt_plat_init(gDevWmt.rWmtGenConf.co_clock_flag & 0x0f); -+ else -+ iRet = wmt_plat_init(0); -+ -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_plat_init() fail(%d)\n", iRet); -+ return -3; -+ } -+#if CFG_WMT_PS_SUPPORT -+ iRet = wmt_lib_ps_init(); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_lib_ps_init() fail(%d)\n", iRet); -+ return -4; -+ } -+#endif -+ -+ /* 3. start: start running mtk_wmtd */ -+ iRet = osal_thread_run(pThraed); -+ if (iRet) { -+ WMT_ERR_FUNC("osal_thread_run(0x%p) fail(%d)\n", pThraed, iRet); -+ return -5; -+ } -+ -+ /*4. register irq callback to WMT-PLAT */ -+ wmt_plat_irq_cb_reg(wmt_lib_ps_irq_cb); -+ -+ /*5. register audio if control callback to WMT-PLAT */ -+ wmt_plat_aif_cb_reg(wmt_lib_set_aif); -+ -+ /*6. register function control callback to WMT-PLAT */ -+ wmt_plat_func_ctrl_cb_reg(mtk_wcn_wmt_func_ctrl_for_plat); -+ -+ wmt_plat_deep_idle_ctrl_cb_reg(mtk_wcn_consys_stp_btif_dpidle_ctrl); -+ /*7 reset gps/bt state */ -+ -+ mtk_wcn_wmt_system_state_reset(); -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ mtk_wcn_wmt_exp_init(); -+#endif -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ wmt_idc_init(); -+#endif -+ WMT_DBG_FUNC("init success\n"); -+ return 0; -+} -+ -+INT32 wmt_lib_deinit(VOID) -+{ -+ INT32 iRet; -+ P_DEV_WMT pDevWmt; -+ P_OSAL_THREAD pThraed; -+ INT32 i; -+ INT32 iResult; -+ -+ pDevWmt = &gDevWmt; -+ pThraed = &gDevWmt.thread; -+ iResult = 0; -+ -+ /* stop->deinit->destroy */ -+ -+ /* 1. stop: stop running mtk_wmtd */ -+ iRet = osal_thread_stop(pThraed); -+ if (iRet) { -+ WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", pThraed, iRet); -+ iResult += 1; -+ } -+ -+ /* 2. deinit: */ -+ -+#if CFG_WMT_PS_SUPPORT -+ iRet = wmt_lib_ps_deinit(); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_lib_ps_deinit fail(%d)\n", iRet); -+ iResult += 2; -+ } -+#endif -+ -+ iRet = wmt_plat_deinit(); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_plat_deinit fail(%d)\n", iRet); -+ iResult += 4; -+ } -+ -+ osal_event_deinit(&pDevWmt->cmdReq); -+ osal_signal_deinit(&pDevWmt->cmdResp); -+ -+ /* de-initialize stp resources */ -+ osal_event_deinit(&pDevWmt->rWmtRxWq); -+ -+ for (i = 0; i < WMT_OP_BUF_SIZE; i++) -+ osal_signal_deinit(&(pDevWmt->arQue[i].signal)); -+ -+ -+ osal_sleepable_lock_deinit(&pDevWmt->rFreeOpQ.sLock); -+ osal_sleepable_lock_deinit(&pDevWmt->rActiveOpQ.sLock); -+ osal_sleepable_lock_deinit(&pDevWmt->idc_lock); -+ osal_sleepable_lock_deinit(&pDevWmt->psm_lock); -+ osal_event_deinit(&pDevWmt->rWmtdWq); -+ -+ iRet = wmt_core_deinit(); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_core_deinit fail(%d)\n", iRet); -+ iResult += 8; -+ } -+ -+ /* 3. destroy */ -+ iRet = osal_thread_destroy(pThraed); -+ if (iRet) { -+ WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", pThraed, iRet); -+ iResult += 16; -+ } -+ osal_memset(&gDevWmt, 0, sizeof(gDevWmt)); -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ mtk_wcn_wmt_exp_deinit(); -+#endif -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ wmt_idc_deinit(); -+#endif -+ -+ return iResult; -+} -+ -+VOID wmt_lib_flush_rx(VOID) -+{ -+ mtk_wcn_stp_flush_rx_queue(WMT_TASK_INDX); -+} -+ -+INT32 wmt_lib_trigger_cmd_signal(INT32 result) -+{ -+ P_OSAL_SIGNAL pSignal = &gDevWmt.cmdResp; -+ -+ gDevWmt.cmdResult = result; -+ osal_raise_signal(pSignal); -+ WMT_DBG_FUNC("wakeup cmdResp\n"); -+ return 0; -+} -+ -+P_OSAL_EVENT wmt_lib_get_cmd_event(VOID) -+{ -+ return &gDevWmt.cmdReq; -+} -+ -+INT32 wmt_lib_set_patch_name(PUINT8 cPatchName) -+{ -+ osal_strncpy(gDevWmt.cPatchName, cPatchName, NAME_MAX); -+ return 0; -+} -+ -+INT32 wmt_lib_set_hif(unsigned long hifconf) -+{ -+ UINT32 val; -+ P_WMT_HIF_CONF pHif = &gDevWmt.rWmtHifConf; -+ -+ val = hifconf & 0xF; -+ if (STP_UART_FULL == val) { -+ pHif->hifType = WMT_HIF_UART; -+ val = (hifconf >> 8); -+ pHif->au4HifConf[0] = val; -+ pHif->au4HifConf[1] = val; -+ mtk_wcn_stp_set_if_tx_type(STP_UART_IF_TX); -+ } else if (STP_SDIO == val) { -+ pHif->hifType = WMT_HIF_SDIO; -+ mtk_wcn_stp_set_if_tx_type(STP_SDIO_IF_TX); -+ } else if (STP_BTIF_FULL == val) { -+ pHif->hifType = WMT_HIF_BTIF; -+ mtk_wcn_stp_set_if_tx_type(STP_BTIF_IF_TX); -+ } else { -+ WMT_WARN_FUNC("invalid stp mode: %u\n", val); -+ mtk_wcn_stp_set_if_tx_type(STP_MAX_IF_TX); -+ return -1; -+ } -+ -+ val = (hifconf & 0xF0) >> 4; -+ if (WMT_FM_COMM == val) { -+ pHif->au4StrapConf[0] = WMT_FM_COMM; -+ } else if (WMT_FM_I2C == val) { -+ pHif->au4StrapConf[0] = WMT_FM_I2C; -+ } else { -+ WMT_WARN_FUNC("invalid fm mode: %u\n", val); -+ return -2; -+ } -+ -+ WMT_WARN_FUNC("new hifType: %d, fm:%d\n", pHif->hifType, pHif->au4StrapConf[0]); -+ return 0; -+} -+ -+P_WMT_HIF_CONF wmt_lib_get_hif(VOID) -+{ -+ return &gDevWmt.rWmtHifConf; -+} -+ -+PUINT8 wmt_lib_get_cmd(VOID) -+{ -+ if (osal_test_and_clear_bit(WMT_STAT_CMD, &gDevWmt.state)) -+ return gDevWmt.cCmd; -+ -+ return NULL; -+} -+ -+MTK_WCN_BOOL wmt_lib_get_cmd_status(VOID) -+{ -+ return osal_test_bit(WMT_STAT_CMD, &gDevWmt.state) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; -+} -+ -+#if CFG_WMT_PS_SUPPORT -+INT32 wmt_lib_ps_set_idle_time(UINT32 psIdleTime) -+{ -+ gPsIdleTime = psIdleTime; -+ return gPsIdleTime; -+} -+ -+INT32 wmt_lib_ps_ctrl(UINT32 state) -+{ -+ if (0 == state) { -+ wmt_lib_ps_disable(); -+ gPsEnable = 0; -+ } else { -+ gPsEnable = 1; -+ wmt_lib_ps_enable(); -+ } -+ return 0; -+} -+ -+INT32 wmt_lib_ps_enable(VOID) -+{ -+ if (gPsEnable) -+ mtk_wcn_stp_psm_enable(gPsIdleTime); -+ -+ return 0; -+} -+ -+INT32 wmt_lib_ps_disable(VOID) -+{ -+ if (gPsEnable) -+ return mtk_wcn_stp_psm_disable(); -+ -+ return 0; -+} -+ -+INT32 wmt_lib_ps_init(VOID) -+{ -+ /* mtk_wcn_stp_psm_register_wmt_cb(wmt_lib_ps_stp_cb); */ -+ return 0; -+} -+ -+INT32 wmt_lib_ps_deinit(VOID) -+{ -+ /* mtk_wcn_stp_psm_unregister_wmt_cb(); */ -+ return 0; -+} -+ -+static MTK_WCN_BOOL wmt_lib_ps_action(MTKSTP_PSM_ACTION_T action) -+{ -+ P_OSAL_OP lxop; -+ MTK_WCN_BOOL bRet; -+ UINT32 u4Wait; -+ P_OSAL_SIGNAL pSignal; -+ -+ lxop = wmt_lib_get_free_op(); -+ if (!lxop) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ pSignal = &lxop->signal; -+ pSignal->timeoutValue = 0; -+ lxop->op.opId = WMT_OPID_PWR_SV; -+ lxop->op.au4OpData[0] = action; -+ lxop->op.au4OpData[1] = (SIZE_T) mtk_wcn_stp_psm_notify_stp; -+ u4Wait = 0; -+ bRet = wmt_lib_put_act_op(lxop); -+ return bRet; -+} -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+MTK_WCN_BOOL wmt_lib_handle_idc_msg(ipc_ilm_t *idc_infor) -+{ -+ P_OSAL_OP lxop; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_OSAL_SIGNAL pSignal; -+ INT32 ret = 0; -+ UINT16 msg_len = 0; -+ static UINT8 msg_local_buffer[1300]; -+#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING -+ MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; -+#endif -+ WMT_DBG_FUNC("idc_infor from conn_md is 0x%p\n", idc_infor); -+ ret = wmt_lib_idc_lock_aquire(); -+ if (ret) { -+ WMT_ERR_FUNC("--->lock idc_lock failed, ret=%d\n", ret); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ msg_len = idc_infor->local_para_ptr->msg_len - osal_sizeof(local_para_struct); -+ osal_memcpy(&msg_local_buffer[0], &msg_len, osal_sizeof(msg_len)); -+ osal_memcpy(&msg_local_buffer[osal_sizeof(msg_len)], -+ &(idc_infor->local_para_ptr->data[0]), msg_len - 1); -+ wmt_lib_idc_lock_release(); -+ lxop = wmt_lib_get_free_op(); -+ if (!lxop) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ pSignal = &lxop->signal; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ lxop->op.opId = WMT_OPID_IDC_MSG_HANDLING; -+ lxop->op.au4OpData[0] = (size_t) msg_local_buffer; -+ /*msg opcode fill rule is still not clrear,need scott comment */ -+ /***********************************************************/ -+ WMT_DBG_FUNC("ilm msg id is (0x%08x)\n", idc_infor->msg_id); -+ -+#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING -+ switch (idc_infor->msg_id) { -+ case IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND: -+ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_PARA; -+ break; -+ case IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND: -+ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_FREQ; -+ break; -+ case IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND: -+ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_WIFI_MAX_POWER; -+ break; -+ case IPC_MSG_ID_EL1_LTE_TX_IND: -+ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_INDICATION; -+ break; -+ case IPC_MSG_ID_EL1_LTE_CONNECTION_STATUS_IND: -+ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_CONNECTION_STAS; -+ break; -+ default: -+ unknown_msgid = MTK_WCN_BOOL_TRUE; -+ break; -+ } -+ -+ if (MTK_WCN_BOOL_FALSE == unknown_msgid) { -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(lxop); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ bRet = wmt_lib_put_act_op(lxop); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) -+ WMT_WARN_FUNC("WMT_OPID_IDC_MSG_HANDLING fail(%d)\n", bRet); -+ else -+ WMT_DBG_FUNC("OPID(%d) type(%d) ok\n", lxop->op.opId, lxop->op.au4OpData[1]); -+ } else { -+ bRet = MTK_WCN_BOOL_FALSE; -+ wmt_lib_put_op_to_free_queue(lxop); -+ WMT_ERR_FUNC("unknown msgid from LTE(%d)\n", idc_infor->msg_id); -+ } -+#else -+ if ((idc_infor->msg_id >= IPC_EL1_MSG_ID_BEGIN) -+ && (idc_infor->msg_id <= IPC_EL1_MSG_ID_BEGIN + IPC_EL1_MSG_ID_RANGE)) { -+ lxop->op.au4OpData[1] = idc_infor->msg_id - IPC_EL1_MSG_ID_BEGIN + LTE_MSG_ID_OFFSET - 1; -+ -+ WMT_DBG_FUNC("LTE->CONN:(0x%x->0x%zx)\n", idc_infor->msg_id, lxop->op.au4OpData[1]); -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(lxop); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ bRet = wmt_lib_put_act_op(lxop); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("WMT_OPID_IDC_MSG_HANDLING fail(%d)\n", bRet); -+ } else { -+ WMT_DBG_FUNC("wmt_lib_handle_idc_msg OPID(%d) type(%d) ok\n", -+ lxop->op.opId, lxop->op.au4OpData[1]); -+ } -+ } else { -+ wmt_lib_put_op_to_free_queue(lxop); -+ WMT_ERR_FUNC("msgid(%d) out of range,wmt drop it!\n", idc_infor->msg_id); -+ } -+#endif -+ -+ return bRet; -+} -+#endif -+ -+static MTK_WCN_BOOL wmt_lib_ps_do_sleep(VOID) -+{ -+ return wmt_lib_ps_action(SLEEP); -+} -+ -+static MTK_WCN_BOOL wmt_lib_ps_do_wakeup(VOID) -+{ -+ return wmt_lib_ps_action(WAKEUP); -+} -+ -+static MTK_WCN_BOOL wmt_lib_ps_do_host_awake(VOID) -+{ -+#if 1 -+ return wmt_lib_ps_action(WAKEUP); -+#else -+ return wmt_lib_ps_action(HOST_AWAKE); -+#endif -+} -+ -+/* extern int g_block_tx; */ -+static INT32 wmt_lib_ps_handler(MTKSTP_PSM_ACTION_T action) -+{ -+ INT32 ret; -+ -+ ret = 0; /* TODO:[FixMe][George] initial value or compile warning? */ -+ /* if(g_block_tx && (action == SLEEP)) */ -+ if ((0 != mtk_wcn_stp_coredump_start_get()) && (action == SLEEP)) { -+ mtk_wcn_stp_psm_notify_stp(SLEEP); -+ return ret; -+ } -+ -+ /*MT662x Not Ready */ -+ if (!mtk_wcn_stp_is_ready()) { -+ WMT_DBG_FUNC("MT662x Not Ready, Dont Send Sleep/Wakeup Command\n"); -+ mtk_wcn_stp_psm_notify_stp(ROLL_BACK); -+ return 0; -+ } -+ -+ if (SLEEP == action) { -+ WMT_DBG_FUNC("send op-----------> sleep job\n"); -+ -+ if (!mtk_wcn_stp_is_sdio_mode()) { -+ ret = wmt_lib_ps_do_sleep(); -+ WMT_DBG_FUNC("enable host eirq\n"); -+ wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_EN); -+#if CFG_WMT_DUMP_INT_STATUS -+ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) -+ wmt_plat_BGF_irq_dump_status(); -+#endif -+ } else { -+ /* ret = mtk_wcn_stp_sdio_do_own_set(); */ -+ if (sdio_own_ctrl) { -+ ret = (*sdio_own_ctrl) (OWN_SET); -+ } else { -+ WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); -+ ret = -1; -+ } -+ -+ if (!ret) { -+ mtk_wcn_stp_psm_notify_stp(SLEEP); -+ } else if (ret == -2) { -+ mtk_wcn_stp_psm_notify_stp(ROLL_BACK); -+ WMT_WARN_FUNC("===[SDIO-PS] rollback due to tx busy===%%\n"); -+ } else { -+ mtk_wcn_stp_psm_notify_stp(SLEEP); -+ WMT_ERR_FUNC("===[SDIO-PS] set own fails!===%%\n"); -+ } -+ } -+ -+ WMT_DBG_FUNC("send op<---------- sleep job\n"); -+ } else if (WAKEUP == action) { -+ WMT_DBG_FUNC("send op --------> wake job\n"); -+ -+ if (!mtk_wcn_stp_is_sdio_mode()) { -+ WMT_DBG_FUNC("disable host eirq\n"); -+#if CFG_WMT_DUMP_INT_STATUS -+ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) -+ wmt_plat_BGF_irq_dump_status(); -+#endif -+ wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); -+ ret = wmt_lib_ps_do_wakeup(); -+ } else { -+ /* ret = mtk_wcn_stp_sdio_do_own_clr(); */ -+ -+ if (sdio_own_ctrl) { -+ ret = (*sdio_own_ctrl) (OWN_CLR); -+ } else { -+ WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); -+ ret = -1; -+ } -+ -+ if (!ret) { -+ mtk_wcn_stp_psm_notify_stp(WAKEUP); -+ } else { -+ mtk_wcn_stp_psm_notify_stp(WAKEUP); -+ WMT_ERR_FUNC("===[SDIO-PS] set own back fails!===%%\n"); -+ } -+ } -+ -+ WMT_DBG_FUNC("send op<---------- wake job\n"); -+ } else if (HOST_AWAKE == action) { -+ WMT_DBG_FUNC("send op-----------> host awake job\n"); -+ -+ if (!mtk_wcn_stp_is_sdio_mode()) { -+ WMT_DBG_FUNC("disable host eirq\n"); -+ /* IRQ already disabled */ -+ /* wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); */ -+#if 0 -+ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) -+ wmt_plat_BGF_irq_dump_status(); -+#endif -+ ret = wmt_lib_ps_do_host_awake(); -+ } else { -+ WMT_DBG_FUNC("[SDIO-PS] SDIO host awake! ####\n"); -+ -+ /* ret = mtk_wcn_stp_sdio_do_own_clr(); */ -+ -+ if (sdio_own_ctrl) { -+ ret = (*sdio_own_ctrl) (OWN_CLR); -+ } else { -+ WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); -+ ret = -1; -+ } -+ -+ /* Here we set ret to 0 directly */ -+ ret = 0; -+ if (!ret) { -+ mtk_wcn_stp_psm_notify_stp(HOST_AWAKE); -+ } else { -+ mtk_wcn_stp_psm_notify_stp(HOST_AWAKE); -+ WMT_ERR_FUNC("===[SDIO-PS]set own back fails!===%%\n"); -+ } -+ } -+ -+ WMT_DBG_FUNC("send op<----------- host awake job\n"); -+ } else if (EIRQ == action) { -+ WMT_DBG_FUNC("send op -------------> eirq job\n"); -+ -+ if (!mtk_wcn_stp_is_sdio_mode()) { -+ WMT_DBG_FUNC("disable host eirq\n"); -+ /* Disable interrupt */ -+ /* wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); */ -+ ret = mtk_wcn_stp_psm_notify_stp(EIRQ); -+ } else { -+ WMT_ERR_FUNC("[SDIO-PS]sdio own-back eirq!######\n"); -+ ret = mtk_wcn_stp_psm_notify_stp(EIRQ); -+ } -+ -+ WMT_DBG_FUNC("send op<----------- eirq job\n"); -+ } -+ -+ return ret; -+} -+#endif /* end of CFG_WMT_PS_SUPPORT */ -+ -+INT32 wmt_lib_ps_stp_cb(MTKSTP_PSM_ACTION_T action) -+{ -+#if CFG_WMT_PS_SUPPORT -+ return wmt_lib_ps_handler(action); -+#else -+ WMT_WARN_FUNC("CFG_WMT_PS_SUPPORT is not set\n"); -+ return 0; -+#endif -+} -+ -+MTK_WCN_BOOL wmt_lib_is_quick_ps_support(VOID) -+{ -+ if ((g_quick_sleep_ctrl) && (wmt_dev_get_early_suspend_state() == MTK_WCN_BOOL_TRUE)) -+ return wmt_core_is_quick_ps_support(); -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+VOID wmt_lib_ps_irq_cb(VOID) -+{ -+#if CFG_WMT_PS_SUPPORT -+ wmt_lib_ps_handler(EIRQ); -+#else -+ WMT_DBG_FUNC("CFG_WMT_PS_SUPPORT is not set\n"); -+ return; -+#endif -+} -+ -+VOID wmt_lib_ps_set_sdio_psop(PF_WMT_SDIO_PSOP own_cb) -+{ -+#if CFG_WMT_PS_SUPPORT -+ sdio_own_ctrl = own_cb; -+#endif -+} -+ -+UINT32 wmt_lib_wait_event_checker(P_OSAL_THREAD pThread) -+{ -+ P_DEV_WMT pDevWmt; -+ -+ if (pThread) { -+ pDevWmt = (P_DEV_WMT) (pThread->pThreadData); -+ return !RB_EMPTY(&pDevWmt->rActiveOpQ); -+ } -+ WMT_ERR_FUNC("pThread(NULL)\n"); -+ return 0; -+} -+ -+static INT32 wmtd_thread(void *pvData) -+{ -+ P_DEV_WMT pWmtDev = (P_DEV_WMT) pvData; -+ P_OSAL_EVENT pEvent = NULL; -+ P_OSAL_OP pOp; -+ INT32 iResult; -+ -+ if (NULL == pWmtDev) { -+ WMT_ERR_FUNC("pWmtDev(NULL)\n"); -+ return -1; -+ } -+ WMT_INFO_FUNC("wmtd thread starts\n"); -+ -+ pEvent = &(pWmtDev->rWmtdWq); -+ -+ for (;;) { -+ pOp = NULL; -+ pEvent->timeoutValue = 0; -+/* osal_thread_wait_for_event(&pWmtDev->thread, pEvent);*/ -+ osal_thread_wait_for_event(&pWmtDev->thread, pEvent, wmt_lib_wait_event_checker); -+ -+ if (osal_thread_should_stop(&pWmtDev->thread)) { -+ WMT_INFO_FUNC("wmtd thread should stop now...\n"); -+ /* TODO: clean up active opQ */ -+ break; -+ } -+ -+ /* get Op from activeQ */ -+ pOp = wmt_lib_get_op(&pWmtDev->rActiveOpQ); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_lxop activeQ fail\n"); -+ continue; -+ } -+#if 0 /* wmt_core_opid_handler will do sanity check on opId, so no usage here */ -+ id = lxop_get_opid(pLxOp); -+ if (id >= WMT_OPID_MAX) { -+ WMT_WARN_FUNC("abnormal opid id: 0x%x\n", id); -+ iResult = -1; -+ goto handlerDone; -+ } -+#endif -+ -+ if (osal_test_bit(WMT_STAT_RST_ON, &pWmtDev->state)) { -+ /* when whole chip reset, only HW RST and SW RST cmd can execute */ -+ if ((pOp->op.opId == WMT_OPID_HW_RST) || (pOp->op.opId == WMT_OPID_SW_RST) -+ || (pOp->op.opId == WMT_OPID_GPIO_STATE)) { -+ iResult = wmt_core_opid(&pOp->op); -+ } else { -+ iResult = -2; -+ WMT_WARN_FUNC("Whole chip resetting, opid (%d) failed, iRet(%d)\n", pOp->op.opId, -+ iResult); -+ } -+ } else { -+ wmt_lib_set_current_op(pWmtDev, pOp); -+ iResult = wmt_core_opid(&pOp->op); -+ wmt_lib_set_current_op(pWmtDev, NULL); -+ } -+ -+ if (iResult) -+ WMT_WARN_FUNC("opid (%d) failed, iRet(%d)\n", pOp->op.opId, iResult); -+ -+ if (osal_op_is_wait_for_signal(pOp)) { -+ osal_op_raise_signal(pOp, iResult); -+ } else { -+ /* put Op back to freeQ */ -+ wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp); -+ } -+ -+ if (WMT_OPID_EXIT == pOp->op.opId) { -+ WMT_INFO_FUNC("wmtd thread received exit signal\n"); -+ break; -+ } -+ } -+ -+ WMT_INFO_FUNC("wmtd thread exits succeed\n"); -+ -+ return 0; -+}; -+ -+static MTK_WCN_BOOL wmt_lib_put_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) -+{ -+ INT32 iRet; -+ -+ if (!pOpQ || !pOp) { -+ WMT_WARN_FUNC("invalid input param: pOpQ(0x%p), pLxOp(0x%p)\n", pOpQ, pOp); -+ osal_assert(pOpQ); -+ osal_assert(pOp); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ iRet = osal_lock_sleepable_lock(&pOpQ->sLock); -+ if (iRet) { -+ WMT_WARN_FUNC("osal_lock_sleepable_lock iRet(%d)\n", iRet); -+ return MTK_WCN_BOOL_FALSE; -+ } -+#if 0 -+ if (pOpQ == &gDevWmt.rFreeOpQ) -+ WMT_INFO_FUNC("current wmt free queue count is(%d),opid(%d)\n", RB_COUNT(pOpQ), pOp->op.opId); -+#endif -+ /* acquire lock success */ -+ if (!RB_FULL(pOpQ)) -+ RB_PUT(pOpQ, pOp); -+ else -+ iRet = -1; -+ -+ osal_unlock_sleepable_lock(&pOpQ->sLock); -+ -+ if (iRet) { -+ WMT_WARN_FUNC("RB_FULL(0x%p)\n", pOpQ); -+ return MTK_WCN_BOOL_FALSE; -+ } else { -+ return MTK_WCN_BOOL_TRUE; -+ } -+} -+ -+static P_OSAL_OP wmt_lib_get_op(P_OSAL_OP_Q pOpQ) -+{ -+ P_OSAL_OP pOp; -+ INT32 iRet; -+ -+ if (NULL == pOpQ) { -+ WMT_ERR_FUNC("pOpQ = NULL\n"); -+ osal_assert(pOpQ); -+ return NULL; -+ } -+ -+ iRet = osal_lock_sleepable_lock(&pOpQ->sLock); -+ if (iRet) { -+ WMT_ERR_FUNC("osal_lock_sleepable_lock iRet(%d)\n", iRet); -+ return NULL; -+ } -+ -+ /* acquire lock success */ -+ RB_GET(pOpQ, pOp); -+ osal_unlock_sleepable_lock(&pOpQ->sLock); -+ -+ if (NULL == pOp) { -+ WMT_WARN_FUNC("RB_GET return NULL\n"); -+ osal_assert(pOp); -+ } -+ -+ return pOp; -+} -+ -+INT32 wmt_lib_put_op_to_free_queue(P_OSAL_OP pOp) -+{ -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ -+ if (MTK_WCN_BOOL_FALSE == wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp)) -+ return -1; -+ else -+ return 0; -+} -+ -+P_OSAL_OP wmt_lib_get_free_op(VOID) -+{ -+ P_OSAL_OP pOp = NULL; -+ P_DEV_WMT pDevWmt = &gDevWmt; -+ -+ osal_assert(pDevWmt); -+ -+ pOp = wmt_lib_get_op(&pDevWmt->rFreeOpQ); -+ if (pOp) -+ osal_memset(&pOp->op, 0, osal_sizeof(pOp->op)); -+ return pOp; -+} -+ -+MTK_WCN_BOOL wmt_lib_put_act_op(P_OSAL_OP pOp) -+{ -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ MTK_WCN_BOOL bCleanup = MTK_WCN_BOOL_FALSE; -+ P_OSAL_SIGNAL pSignal = NULL; -+ long waitRet = -1; -+ P_OSAL_THREAD pThread; -+ -+ osal_assert(pWmtDev); -+ osal_assert(pOp); -+ -+ do { -+ if (!pWmtDev || !pOp) { -+ WMT_ERR_FUNC("pWmtDev(0x%p), pOp(0x%p)\n", pWmtDev, pOp); -+ break; -+ } -+ if ((0 != mtk_wcn_stp_coredump_start_get()) && -+ (WMT_OPID_HW_RST != pOp->op.opId) && -+ (WMT_OPID_SW_RST != pOp->op.opId) && (WMT_OPID_GPIO_STATE != pOp->op.opId)) { -+ bCleanup = MTK_WCN_BOOL_TRUE; -+ WMT_WARN_FUNC("block tx flag is set\n"); -+ break; -+ } -+ pSignal = &pOp->signal; -+/* pOp->u4WaitMs = u4WaitMs; */ -+ if (pSignal->timeoutValue) { -+ pOp->result = -9; -+ osal_signal_init(pSignal); -+ } -+ -+ /* put to active Q */ -+ bRet = wmt_lib_put_op(&pWmtDev->rActiveOpQ, pOp); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("put to active queue fail\n"); -+ bCleanup = MTK_WCN_BOOL_TRUE; -+ break; -+ } -+ -+ /* wake up wmtd */ -+ /* wake_up_interruptible(&pWmtDev->rWmtdWq); */ -+ osal_trigger_event(&pWmtDev->rWmtdWq); -+ -+ if (0 == pSignal->timeoutValue) { -+ bRet = MTK_WCN_BOOL_TRUE; -+ /* clean it in wmtd */ -+ break; -+ } -+ /* wait result, clean it here */ -+ bCleanup = MTK_WCN_BOOL_TRUE; -+ -+ /* check result */ -+ /* wait_ret = wait_for_completion_interruptible_timeout(&pOp->comp, msecs_to_jiffies(u4WaitMs)); */ -+ /* wait_ret = wait_for_completion_timeout(&pOp->comp, msecs_to_jiffies(u4WaitMs)); */ -+ waitRet = osal_wait_for_signal_timeout(pSignal); -+ WMT_DBG_FUNC("osal_wait_for_signal_timeout:%ld\n", waitRet); -+ -+ /* if (unlikely(!wait_ret)) { */ -+ if (0 == waitRet) { -+ pThread = &gDevWmt.thread; -+ WMT_ERR_FUNC -+ ("wait completion timeout, opId(%d), show wmtd_thread stack!\n", pOp->op.opId); -+ /* TODO: how to handle it? retry? */ -+ wcn_wmtd_timeout_collect_ftrace(); /* trigger collect SYS_FTRACE */ -+ osal_thread_show_stack(pThread); -+ } else { -+ if (pOp->result) -+ WMT_WARN_FUNC("opId(%d) result:%d\n", pOp->op.opId, pOp->result); -+ } -+ /* op completes, check result */ -+ bRet = (pOp->result) ? MTK_WCN_BOOL_FALSE : MTK_WCN_BOOL_TRUE; -+ } while (0); -+ -+ if (bCleanup) { -+ /* put Op back to freeQ */ -+ wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp); -+ } -+ -+ return bRet; -+} -+ -+/* TODO:[ChangeFeature][George] is this function obsoleted? */ -+#if 0 -+INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) -+{ -+ P_WMT_LXOP lxop; -+ MTK_WCN_BOOL bRet; -+ PUINT32 plv = NULL; -+ UINT32 pbuf[2]; -+ P_OSAL_EVENT pSignal = NULL; -+ -+ if (!pvalue) { -+ WMT_WARN_FUNC("!pvalue\n"); -+ return -1; -+ } -+ lxop = wmt_lib_get_free_lxop(); -+ if (!lxop) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ -+ return -1; -+ } -+ -+ plv = (PUINT32) (((UINT32) pbuf + 0x3) & ~0x3UL); -+ *plv = *pvalue; -+ pSignal = &lxop->signal; -+ WMT_DBG_FUNC("OPID_REG_RW isWrite(%d) offset(0x%x) value(0x%x) mask(0x%x)\n", isWrite, offset, *pvalue, mask); -+ -+ lxop->op.opId = WMT_OPID_REG_RW; -+ lxop->op.au4OpData[0] = isWrite; -+ lxop->op.au4OpData[1] = offset; -+ lxop->op.au4OpData[2] = (UINT32) plv; -+ lxop->op.au4OpData[3] = mask; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ -+ DISABLE_PSM_MONITOR(); -+ bRet = wmt_lib_put_act_lxop(lxop); -+ ENABLE_PSM_MONITOR(); -+ -+ if (MTK_WCN_BOOL_FALSE != bRet) { -+ WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", -+ isWrite, offset, *plv, mask); -+ if (!isWrite) -+ *pvalue = *plv; -+ } else { -+ WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", -+ isWrite, offset, *plv, mask, bRet); -+ } -+ -+ return bRet; -+} -+#endif -+ -+/* TODO:[ChangeFeature][George] is this function obsoleted? */ -+#if 0 -+static VOID wmt_lib_clear_chip_id(VOID) -+{ -+/* -+ gDevWmt.pChipInfo = NULL; -+*/ -+ gDevWmt.hw_ver = WMTHWVER_INVALID; -+} -+#endif -+ -+/* TODO: [FixMe][GeorgeKuo]: change this API to report real chip id, hw_ver, and */ -+/* fw_ver instead of WMT-translated WMTHWVER */ -+ENUM_WMTHWVER_TYPE_T wmt_lib_get_hwver(VOID) -+{ -+/* -+ P_WMT_CMB_CHIP_INFO_S pChipInfo = NULL; -+ P_DEV_WMT pWmtDev = gpDevWmt; -+ pChipInfo = wmt_lib_get_chip_info(pWmtDev); -+ return pChipInfo != NULL ? pChipInfo->eHwVersion : WMTHWVER_INVALID; -+ */ -+ return gDevWmt.eWmtHwVer; -+} -+ -+UINT32 wmt_lib_get_icinfo(ENUM_WMT_CHIPINFO_TYPE_T index) -+{ -+ if (WMTCHIN_CHIPID == index) -+ return gDevWmt.chip_id; -+ else if (WMTCHIN_HWVER == index) -+ return gDevWmt.hw_ver; -+ else if (WMTCHIN_MAPPINGHWVER == index) -+ return gDevWmt.eWmtHwVer; -+ else if (WMTCHIN_FWVER == index) -+ return gDevWmt.fw_ver; -+ -+ return 0; -+ -+} -+ -+PUINT8 wmt_lib_def_patch_name(VOID) -+{ -+ WMT_INFO_FUNC("wmt-lib: use default patch name (%s)\n", gDevWmt.cPatchName); -+ return gDevWmt.cPatchName; -+} -+ -+MTK_WCN_BOOL wmt_lib_is_therm_ctrl_support(VOID) -+{ -+ MTK_WCN_BOOL bIsSupportTherm = MTK_WCN_BOOL_TRUE; -+ /* TODO:[FixMe][GeorgeKuo]: move IC-dependent checking to ic-implementation file */ -+ if (((0x6620 == gDevWmt.chip_id) && (WMTHWVER_E3 > gDevWmt.eWmtHwVer)) -+ || (WMTHWVER_INVALID == gDevWmt.eWmtHwVer)) { -+ WMT_ERR_FUNC("thermal command fail: chip version(WMTHWVER_TYPE:%d) is not valid\n", gDevWmt.eWmtHwVer); -+ bIsSupportTherm = MTK_WCN_BOOL_FALSE; -+ } -+ if (!mtk_wcn_stp_is_ready()) { -+ WMT_ERR_FUNC("thermal command can not be send: STP is not ready\n"); -+ bIsSupportTherm = MTK_WCN_BOOL_FALSE; -+ } -+ -+ return bIsSupportTherm; -+} -+ -+MTK_WCN_BOOL wmt_lib_is_dsns_ctrl_support(VOID) -+{ -+ /* TODO:[FixMe][GeorgeKuo]: move IC-dependent checking to ic-implementation file */ -+ if (((0x6620 == gDevWmt.chip_id) && (WMTHWVER_E3 > gDevWmt.eWmtHwVer)) -+ || (WMTHWVER_INVALID == gDevWmt.eWmtHwVer)) { -+ WMT_ERR_FUNC("thermal command fail: chip version(WMTHWVER_TYPE:%d) is not valid\n", gDevWmt.eWmtHwVer); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+/*! -+ * \brief Update combo chip pin settings (GPIO) -+ * -+ * An internal library function to support various settings for chip GPIO. It is -+ * updated in a grouping way: configure all required pins in a single call. -+ * -+ * \param id desired pin ID to be controlled -+ * \param stat desired pin states to be set -+ * \param flag supplementary options for this operation -+ * -+ * \retval 0 operation success -+ * \retval -1 invalid id -+ * \retval -2 invalid stat -+ * \retval < 0 error for operation fail -+ */ -+static INT32 wmt_lib_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE stat, UINT32 flag) -+{ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ /* input sanity check */ -+ if (WMT_IC_PIN_MAX <= id) { -+ WMT_ERR_FUNC("invalid ic pin id(%d)\n", id); -+ return -1; -+ } -+ if (WMT_IC_PIN_STATE_MAX <= stat) { -+ WMT_ERR_FUNC("invalid ic pin state (%d)\n", stat); -+ return -2; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ WMT_DBG_FUNC("call WMT_OPID_GPIO_CTRL (ic pin id:%d, stat:%d, flag:0x%x)\n", id, stat, flag); -+ -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_GPIO_CTRL; -+ pOp->op.au4OpData[0] = id; -+ pOp->op.au4OpData[1] = stat; -+ pOp->op.au4OpData[2] = flag; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) -+ WMT_WARN_FUNC("PIN_ID(%d) PIN_STATE(%d) flag(%d) fail\n", id, stat, flag); -+ else -+ WMT_DBG_FUNC("OPID(%d) type(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ return 0; -+} -+ -+INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) -+{ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ UINT32 value; -+ P_OSAL_SIGNAL pSignal; -+ -+ if (!pvalue) { -+ WMT_WARN_FUNC("!pvalue\n"); -+ return -1; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; -+ } -+ -+ pSignal = &pOp->signal; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ value = *pvalue; -+ WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x)\n\n", isWrite, offset, *pvalue, mask); -+ pOp->op.opId = WMT_OPID_REG_RW; -+ pOp->op.au4OpData[0] = isWrite; -+ pOp->op.au4OpData[1] = offset; -+ pOp->op.au4OpData[2] = (SIZE_T)&value; -+ pOp->op.au4OpData[3] = mask; -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ -+ if (MTK_WCN_BOOL_FALSE != bRet) { -+ WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", -+ isWrite, offset, value, mask); -+ if (!isWrite) -+ *pvalue = value; -+ -+ return 0; -+ } -+ WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", -+ isWrite, offset, value, mask, bRet); -+ return -1; -+} -+ -+INT32 wmt_lib_efuse_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) -+{ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ UINT32 value; -+ P_OSAL_SIGNAL pSignal; -+ -+ if (!pvalue) { -+ WMT_WARN_FUNC("!pvalue\n"); -+ return -1; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; -+ } -+ -+ pSignal = &pOp->signal; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ value = *pvalue; -+ WMT_DBG_FUNC("OPID_EFUSE_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x)\n\n", -+ isWrite, offset, *pvalue, mask); -+ pOp->op.opId = WMT_OPID_EFUSE_RW; -+ pOp->op.au4OpData[0] = isWrite; -+ pOp->op.au4OpData[1] = offset; -+ pOp->op.au4OpData[2] = (SIZE_T)&value; -+ pOp->op.au4OpData[3] = mask; -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ -+ if (MTK_WCN_BOOL_FALSE != bRet) { -+ WMT_DBG_FUNC("OPID_EFUSE_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", -+ isWrite, offset, value, mask); -+ if (!isWrite) -+ *pvalue = value; -+ -+ return 0; -+ } -+ WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", -+ isWrite, offset, value, mask, bRet); -+ return -1; -+ -+} -+ -+/*! -+ * \brief update combo chip AUDIO Interface (AIF) settings -+ * -+ * A library function to support updating chip AUDIO pin settings. A group of -+ * pins is updated as a whole. -+ * -+ * \param aif desired audio interface state to use -+ * \param flag whether audio pin is shared or not -+ * -+ * \retval 0 operation success -+ * \retval -1 invalid aif -+ * \retval < 0 error for invalid parameters or operation fail -+ */ -+INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share) -+{ -+ if (CMB_STUB_AIF_MAX <= aif) { -+ WMT_ERR_FUNC("invalid aif (%d)\n", aif); -+ return -1; -+ } -+ WMT_DBG_FUNC("call pin_ctrl for aif:%d, share:%d\n", aif, (MTK_WCN_BOOL_TRUE == share) ? 1 : 0); -+ /* Translate CMB_STUB_AIF_X into WMT_IC_PIN_STATE by array */ -+ return wmt_lib_pin_ctrl(WMT_IC_PIN_AUDIO, -+ cmb_aif2pin_stat[aif], -+ (MTK_WCN_BOOL_TRUE == share) ? WMT_LIB_AIF_FLAG_SHARE : WMT_LIB_AIF_FLAG_SEPARATE); -+} -+ -+INT32 wmt_lib_host_awake_get(VOID) -+{ -+ return wmt_plat_wake_lock_ctrl(WL_OP_GET); -+} -+ -+INT32 wmt_lib_host_awake_put(VOID) -+{ -+ return wmt_plat_wake_lock_ctrl(WL_OP_PUT); -+} -+ -+MTK_WCN_BOOL wmt_lib_btm_cb(MTKSTP_BTM_WMT_OP_T op) -+{ -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ -+ if (op == BTM_RST_OP) { -+ /* high priority, not to enqueue into the queue of wmtd */ -+ WMT_INFO_FUNC("Invoke whole chip reset from stp_btm!!!\n"); -+ wmt_lib_cmb_rst(WMTRSTSRC_RESET_STP); -+ bRet = MTK_WCN_BOOL_TRUE; -+ } else if (op == BTM_DMP_OP) { -+ -+ WMT_WARN_FUNC("TBD!!!\n"); -+ } else if (op == BTM_GET_AEE_SUPPORT_FLAG) { -+ bRet = wmt_core_get_aee_dump_flag(); -+ } -+ return bRet; -+} -+ -+MTK_WCN_BOOL wmt_cdev_rstmsg_snd(ENUM_WMTRSTMSG_TYPE_T msg) -+{ -+ -+ INT32 i = 0; -+ P_DEV_WMT pDevWmt = &gDevWmt; -+ PUINT8 drv_name[] = { -+ "DRV_TYPE_BT", -+ "DRV_TYPE_FM", -+ "DRV_TYPE_GPS", -+ "DRV_TYPE_WIFI" -+ }; -+ -+ for (i = 0; i <= WMTDRV_TYPE_WIFI; i++) { -+ /* <1> check if reset callback is registered */ -+ if (pDevWmt->rFdrvCb.fDrvRst[i]) { -+ /* <2> send the msg to this subfucntion */ -+ /*src, dst, msg_type, msg_data, msg_size */ -+ pDevWmt->rFdrvCb.fDrvRst[i] (WMTDRV_TYPE_WMT, i, WMTMSG_TYPE_RESET, &msg, -+ sizeof(ENUM_WMTRSTMSG_TYPE_T)); -+ WMT_INFO_FUNC("type = %s, msg sent\n", drv_name[i]); -+ } else { -+ WMT_DBG_FUNC("type = %s, unregistered\n", drv_name[i]); -+ } -+ } -+ -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+VOID wmt_lib_state_init(VOID) -+{ -+ /* UINT32 i = 0; */ -+ P_DEV_WMT pDevWmt = &gDevWmt; -+ P_OSAL_OP pOp; -+ -+ /* Initialize op queue */ -+ /* RB_INIT(&pDevWmt->rFreeOpQ, WMT_OP_BUF_SIZE); */ -+ /* RB_INIT(&pDevWmt->rActiveOpQ, WMT_OP_BUF_SIZE); */ -+ -+ while (!RB_EMPTY(&pDevWmt->rActiveOpQ)) { -+#if 0 -+ osal_signal_init(&(pOp->signal)); -+ wmt_lib_put_op(&pDevWmt->rFreeOpQ, pOp); -+#endif -+ pOp = wmt_lib_get_op(&pDevWmt->rActiveOpQ); -+ if (pOp) { -+ if (osal_op_is_wait_for_signal(pOp)) -+ osal_op_raise_signal(pOp, -1); -+ else -+ wmt_lib_put_op(&pDevWmt->rFreeOpQ, pOp); -+ } -+ } -+ -+ /* Put all to free Q */ -+ /* -+ for (i = 0; i < WMT_OP_BUF_SIZE; i++) { -+ osal_signal_init(&(pDevWmt->arQue[i].signal)); -+ wmt_lib_put_op(&pDevWmt->rFreeOpQ, &(pDevWmt->arQue[i])); -+ } */ -+} -+ -+#if 0 -+INT32 wmt_lib_sdio_ctrl(UINT32 on) -+{ -+ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ WMT_DBG_FUNC("call WMT_OPID_SDIO_CTRL\n"); -+ -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_SDIO_CTRL; -+ pOp->op.au4OpData[0] = on; -+ pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("WMT_OPID_SDIO_CTRL failed\n"); -+ return -1; -+ } -+ WMT_DBG_FUNC("OPID(WMT_OPID_SDIO_CTRL)ok\n"); -+ -+ return 0; -+} -+#endif -+ -+MTK_WCN_BOOL wmt_lib_hw_state_show(VOID) -+{ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ WMT_DBG_FUNC("call WMT_OPID_HW_STATE_SHOW\n"); -+ -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_GPIO_STATE; -+ pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("WMT_OPID_HW_STATE_SHOW failed\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ WMT_DBG_FUNC("OPID(WMT_OPID_HW_STATE_SHOW)ok\n"); -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+MTK_WCN_BOOL wmt_lib_hw_rst(VOID) -+{ -+ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ P_DEV_WMT pDevWmt = &gDevWmt; -+ -+ wmt_lib_state_init(); -+ -+ osal_clear_bit(WMT_STAT_STP_REG, &pDevWmt->state); -+ osal_clear_bit(WMT_STAT_STP_OPEN, &pDevWmt->state); -+ osal_clear_bit(WMT_STAT_STP_EN, &pDevWmt->state); -+ osal_clear_bit(WMT_STAT_STP_RDY, &pDevWmt->state); -+ osal_clear_bit(WMT_STAT_RX, &pDevWmt->state); -+ osal_clear_bit(WMT_STAT_CMD, &pDevWmt->state); -+ -+ /*Before do hardware reset, we show GPIO state to check if others modified our pin state accidentially */ -+ wmt_lib_hw_state_show(); -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ WMT_DBG_FUNC("call WMT_OPID_HW_RST\n"); -+ -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_HW_RST; -+ pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("WMT_OPID_HW_RST failed\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ WMT_DBG_FUNC("OPID(WMT_OPID_HW_RST)ok\n"); -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+MTK_WCN_BOOL wmt_lib_sw_rst(INT32 baudRst) -+{ -+ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ /* <1> wmt state reset */ -+ wmt_lib_state_init(); -+ -+ /* <2> Reset STP data structure */ -+ WMT_DBG_FUNC("Cleanup STP context\n"); -+ mtk_wcn_stp_flush_context(); -+ /* <3> Reset STP-PSM data structure */ -+ WMT_DBG_FUNC("Cleanup STP-PSM context\n"); -+ mtk_wcn_stp_psm_reset(); -+ -+ /* <4> do sw reset in wmt-core */ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ WMT_DBG_FUNC("call WMT_OPID_SW_RST\n"); -+ -+ pSignal = &pOp->signal; -+ pSignal->timeoutValue = MAX_FUNC_ON_TIME; -+ -+ pOp->op.opId = WMT_OPID_SW_RST; -+ pOp->op.au4OpData[0] = baudRst; -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("WMT_OPID_SW_RST failed\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ WMT_DBG_FUNC("OPID(WMT_OPID_SW_RST)ok\n"); -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+ENUM_WMTRSTRET_TYPE_T wmt_lib_cmb_rst(ENUM_WMTRSTSRC_TYPE_T src) -+{ -+#define RETRYTIMES 10 -+ MTK_WCN_BOOL bRet; -+ ENUM_WMTRSTRET_TYPE_T retval = WMTRSTRET_MAX; -+ ENUM_WMTRSTMSG_TYPE_T rstMsg = WMTRSTMSG_RESET_MAX; -+ INT32 retries = RETRYTIMES; -+ P_DEV_WMT pDevWmt = &gDevWmt; -+ P_OSAL_OP pOp; -+ PUINT8 srcName[] = { "WMTRSTSRC_RESET_BT", -+ "WMTRSTSRC_RESET_FM", -+ "WMTRSTSRC_RESET_GPS", -+ "WMTRSTSRC_RESET_WIFI", -+ "WMTRSTSRC_RESET_STP", -+ "WMTRSTSRC_RESET_TEST" -+ }; -+ -+ if (src < WMTRSTSRC_RESET_MAX) -+ WMT_INFO_FUNC("reset source = %s\n", srcName[src]); -+ -+ if (WMTRSTSRC_RESET_TEST == src) { -+ pOp = wmt_lib_get_current_op(pDevWmt); -+ if (pOp && ((WMT_OPID_FUNC_ON == pOp->op.opId) -+ || (WMT_OPID_FUNC_OFF == pOp->op.opId))) { -+ WMT_INFO_FUNC("can't do reset by test src when func on/off\n"); -+ return -1; -+ } -+ } -+ /* <1> Consider the multi-context combo_rst case. */ -+ if (osal_test_and_set_bit(WMT_STAT_RST_ON, &pDevWmt->state)) { -+ retval = WMTRSTRET_ONGOING; -+ goto rstDone; -+ } -+ /* <2> Block all STP request */ -+ mtk_wcn_stp_enable(0); -+ -+ /* <3> RESET_START notification */ -+ bRet = wmt_cdev_rstmsg_snd(WMTRSTMSG_RESET_START); -+ if (bRet == MTK_WCN_BOOL_FALSE) { -+ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_rstmsg_snd!\n"); -+ retval = WMTRSTRET_FAIL; -+ goto rstDone; -+ } -+ /* wakeup blocked opid */ -+ pOp = wmt_lib_get_current_op(pDevWmt); -+ if (osal_op_is_wait_for_signal(pOp)) -+ osal_op_raise_signal(pOp, -1); -+ -+ /* wakeup blocked cmd */ -+ wmt_dev_rx_event_cb(); -+ -+ /* <4> retry until reset flow successful */ -+ while (retries > 0) { -+ /* <4.1> reset combo hw */ -+ bRet = wmt_lib_hw_rst(); -+ if (bRet == MTK_WCN_BOOL_FALSE) { -+ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_hw_rst!\n"); -+ retries--; -+ continue; -+ } -+ /* <4.2> reset driver/combo sw */ -+ bRet = wmt_lib_sw_rst(1); -+ if (bRet == MTK_WCN_BOOL_FALSE) { -+ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_sw_rst!\n"); -+ retries--; -+ continue; -+ } -+ break; -+ } -+ -+ osal_clear_bit(WMT_STAT_RST_ON, &pDevWmt->state); -+ -+ if (bRet == MTK_WCN_BOOL_FALSE) { -+ rstMsg = WMTRSTMSG_RESET_END_FAIL; -+ WMT_WARN_FUNC("[whole chip reset] fail! retries = %d\n", RETRYTIMES - retries); -+ } else { -+ rstMsg = WMTRSTMSG_RESET_END; -+ WMT_INFO_FUNC("[whole chip reset] ok! retries = %d\n", RETRYTIMES - retries); -+ } -+ -+ /* <5> RESET_END notification */ -+ bRet = wmt_cdev_rstmsg_snd(rstMsg); -+ if (bRet == MTK_WCN_BOOL_FALSE) { -+ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_rstmsg_snd!\n"); -+ retval = WMTRSTRET_FAIL; -+ } else { -+ retval = WMTRSTMSG_RESET_END == rstMsg ? WMTRSTRET_SUCCESS : WMTRSTRET_FAIL; -+ } -+ mtk_wcn_stp_coredump_start_ctrl(0); -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); -+rstDone: -+ if (osal_test_and_clear_bit(WMT_STAT_RST_ON, &pDevWmt->state)) -+ WMT_WARN_FUNC("[whole chip reset] retval = %d\n", retval); -+ -+ return retval; -+} -+ -+MTK_WCN_BOOL wmt_lib_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) -+{ -+ -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ -+ if (eType >= 0 && eType <= WMTDRV_TYPE_WIFI) { -+ WMT_DBG_FUNC("reg ok!\n"); -+ pWmtDev->rFdrvCb.fDrvRst[eType] = pCb; -+ bRet = MTK_WCN_BOOL_TRUE; -+ } else { -+ WMT_WARN_FUNC("reg fail!\n"); -+ } -+ -+ return bRet; -+} -+ -+MTK_WCN_BOOL wmt_lib_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) -+{ -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ -+ if (eType >= 0 && eType <= WMTDRV_TYPE_WIFI) { -+ WMT_DBG_FUNC("unreg ok!\n"); -+ pWmtDev->rFdrvCb.fDrvRst[eType] = NULL; -+ bRet = MTK_WCN_BOOL_TRUE; -+ } else { -+ WMT_WARN_FUNC("unreg fail!\n"); -+ } -+ -+ return bRet; -+} -+ -+UINT32 wmt_lib_dbg_level_set(UINT32 level) -+{ -+ gWmtDbgLvl = level > WMT_LOG_LOUD ? WMT_LOG_LOUD : level; -+ return 0; -+} -+ -+INT32 wmt_lib_set_stp_wmt_last_close(UINT32 value) -+{ -+ return mtk_wcn_stp_set_wmt_last_close(value); -+} -+ -+INT32 wmt_lib_notify_stp_sleep(void) -+{ -+ INT32 iRet = 0x0; -+ -+ iRet = wmt_lib_psm_lock_aquire(); -+ if (iRet) { -+ WMT_ERR_FUNC("--->lock psm_lock failed, iRet=%d\n", iRet); -+ return iRet; -+ } -+ -+ iRet = mtk_wcn_stp_notify_sleep_for_thermal(); -+ wmt_lib_psm_lock_release(); -+ -+ return iRet; -+} -+ -+VOID wmt_lib_set_patch_num(UINT32 num) -+{ -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ -+ pWmtDev->patchNum = num; -+} -+ -+VOID wmt_lib_set_patch_info(P_WMT_PATCH_INFO pPatchinfo) -+{ -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ -+ if (pPatchinfo) -+ pWmtDev->pWmtPatchInfo = pPatchinfo; -+ -+} -+ -+INT32 wmt_lib_set_current_op(P_DEV_WMT pWmtDev, P_OSAL_OP pOp) -+{ -+ if (pWmtDev) { -+ pWmtDev->pCurOP = pOp; -+ WMT_DBG_FUNC("pOp=0x%p\n", pOp); -+ return 0; -+ } -+ WMT_ERR_FUNC("Invalid pointer\n"); -+ return -1; -+} -+ -+P_OSAL_OP wmt_lib_get_current_op(P_DEV_WMT pWmtDev) -+{ -+ if (pWmtDev) -+ return pWmtDev->pCurOP; -+ -+ WMT_ERR_FUNC("Invalid pointer\n"); -+ return NULL; -+} -+ -+UINT8 *wmt_lib_get_fwinfor_from_emi(UINT8 section, UINT32 offset, UINT8 *buf, UINT32 len) -+{ -+ UINT8 *pAddr = NULL; -+ UINT32 sublen1 = 0; -+ UINT32 sublen2 = 0; -+ P_CONSYS_EMI_ADDR_INFO p_consys_info; -+ -+ p_consys_info = wmt_plat_get_emi_phy_add(); -+ osal_assert(p_consys_info); -+ -+ if (section == 0) { -+ pAddr = wmt_plat_get_emi_virt_add(0x0); -+ if (len > 1024) -+ len = 1024; -+ if (!pAddr) { -+ WMT_ERR_FUNC("wmt-lib: get EMI virtual base address fail\n"); -+ } else { -+ WMT_INFO_FUNC("vir addr(0x%p)\n", pAddr); -+ osal_memcpy(&buf[0], pAddr, len); -+ } -+ } else { -+ if (offset >= 0x7fff) -+ offset = 0x0; -+ -+ if (offset + len > 32768) { -+ pAddr = wmt_plat_get_emi_virt_add(offset + p_consys_info->paged_trace_off); -+ if (!pAddr) { -+ WMT_ERR_FUNC("wmt-lib: get part1 EMI virtual base address fail\n"); -+ } else { -+ WMT_INFO_FUNC("part1 vir addr(0x%p)\n", pAddr); -+ sublen1 = 0x7fff - offset; -+ osal_memcpy(&buf[0], pAddr, sublen1); -+ } -+ pAddr = wmt_plat_get_emi_virt_add(p_consys_info->paged_trace_off); -+ if (!pAddr) { -+ WMT_ERR_FUNC("wmt-lib: get part2 EMI virtual base address fail\n"); -+ } else { -+ WMT_INFO_FUNC("part2 vir addr(0x%p)\n", pAddr); -+ sublen2 = len - sublen1; -+ osal_memcpy(&buf[sublen1], pAddr, sublen2); -+ } -+ } else { -+ pAddr = wmt_plat_get_emi_virt_add(offset + p_consys_info->paged_trace_off); -+ if (!pAddr) { -+ WMT_ERR_FUNC("wmt-lib: get EMI virtual base address fail\n"); -+ } else { -+ WMT_INFO_FUNC("vir addr(0x%p)\n", pAddr); -+ osal_memcpy(&buf[0], pAddr, len); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_lib_poll_cpupcr(UINT32 count, UINT16 sleep, UINT16 toAee) -+{ -+ ENUM_STP_FW_ISSUE_TYPE issue_type; -+ -+ issue_type = STP_DBG_PROC_TEST; -+ -+ stp_dbg_poll_cpupcr(count, sleep, 1); -+ -+ if (toAee) { -+ stp_dbg_set_fw_info("STP ProcTest", osal_strlen("STP ProcTest"), issue_type); -+ osal_dbg_assert_aee("[SOC_CONSYS]ProcTest", -+ "**[WCN_ISSUE_INFO]STP Tx Timeout**\n Polling CPUPCR for FW debug usage\n"); -+ } else { -+ WMT_INFO_FUNC("wmt_lib:do not pass cpupcr to AEE\n"); -+ } -+ return 0; -+} -+ -+UINT8 *wmt_lib_get_cpupcr_xml_format(UINT32 *len) -+{ -+ PUINT8 temp; -+ UINT32 i = 0; -+ -+ osal_memset(&g_cpupcr_buf[0], 0, WMT_STP_CPUPCR_BUF_SIZE); -+ temp = g_cpupcr_buf; -+ stp_dbg_cpupcr_infor_format(&temp, len); -+ -+ pr_debug("print xml buffer,len(%d):\n\n", *len); -+ for (i = 0; i < *len; i++) -+ pr_cont("%c", g_cpupcr_buf[i]); -+ -+ return &g_cpupcr_buf[0]; -+} -+ -+UINT32 wmt_lib_set_host_assert_info(UINT32 type, UINT32 reason, UINT32 en) -+{ -+ return stp_dbg_set_host_assert_info(type, reason, en); -+} -+ -+INT32 wmt_lib_register_thermal_ctrl_cb(thermal_query_ctrl_cb thermal_ctrl) -+{ -+ wmt_plat_thermal_ctrl_cb_reg(thermal_ctrl); -+ return 0; -+} -+ -+INT8 wmt_lib_co_clock_get(void) -+{ -+ if (gDevWmt.rWmtGenConf.cfgExist) -+ return gDevWmt.rWmtGenConf.co_clock_flag; -+ else -+ return -1; -+} -+ -+#if CFG_WMT_PS_SUPPORT -+UINT32 wmt_lib_quick_sleep_ctrl(UINT32 en) -+{ -+ WMT_WARN_FUNC("%s quick sleep mode\n", en ? "enable" : "disable"); -+ g_quick_sleep_ctrl = en; -+ return 0; -+} -+#endif -+ -+#if CONSYS_ENALBE_SET_JTAG -+UINT32 wmt_lib_jtag_flag_set(UINT32 en) -+{ -+ return wmt_plat_jtag_flag_ctrl(en); -+} -+#endif -+ -+UINT32 wmt_lib_soc_set_wifiver(UINT32 wifiver) -+{ -+ return stp_dbg_set_wifiver(wifiver); -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h -new file mode 100644 -index 0000000000000..b1b5285638f96 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h -@@ -0,0 +1,252 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _STP_EXP_H_ -+#define _STP_EXP_H_ -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "wmt_stp_exp.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ -+#define BT_TASK_INDX (0) -+#define FM_TASK_INDX (1) -+#define GPS_TASK_INDX (2) -+#define WIFI_TASK_INDX (3) -+#define WMT_TASK_INDX (4) -+#define STP_TASK_INDX (5) -+#define INFO_TASK_INDX (6) -+#define ANT_TASK_INDX (7) -+#if CFG_WMT_LTE_COEX_HANDLING -+#define COEX_TASK_INDX (8) -+#define MTKSTP_MAX_TASK_NUM (9) -+#else -+#define MTKSTP_MAX_TASK_NUM (8) -+#endif -+ -+#define MTKSTP_BUFFER_SIZE (16384) /* Size of RX Queue */ -+ -+#define STP_EXP_HID_API_EXPORT 0 -+ -+#else -+ -+#define STP_EXP_HID_API_EXPORT 1 -+ -+#endif -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+typedef void (*MTK_WCN_STP_EVENT_CB) (void); -+typedef INT32 (*MTK_WCN_STP_IF_TX) (const UINT8 *data, const UINT32 size, UINT32 *written_size); -+/* export for HIF driver */ -+typedef void (*MTK_WCN_STP_IF_RX) (const UINT8 *data, INT32 size); -+ -+typedef enum { -+ STP_UART_IF_TX = 0, -+ STP_SDIO_IF_TX = 1, -+ STP_BTIF_IF_TX = 2, -+ STP_MAX_IF_TX -+} ENUM_STP_TX_IF_TYPE; -+#endif -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_receive_data -+* DESCRIPTION -+* receive data from serial protocol engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* INT32 >= 0: size of data received; < 0: error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data -+* DESCRIPTION -+* subfunction send data through STP -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 >= 0: length transmitted; < 0: error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_rxqueue_empty -+* DESCRIPTION -+* Is certain rx queue empty? -+* PARAMETERS -+* type [IN] subfunction type -+* RETURNS -+* INT32 0: queue is NOT empyt; !0: queue is empty -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_enable -+* DESCRIPTION -+* Is STP ready? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:ready, FALSE:not ready -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_ready(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_parser_data -+* DESCRIPTION -+* push data to serial transport protocol parser engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* void -+*****************************************************************************/ -+extern int mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length); -+ -+/***************************************************************************** -+* FUNCTION -+* set_bluetooth_rx_interface -+* DESCRIPTION -+* Set bluetooth rx interface -+* PARAMETERS -+* rx interface type -+* RETURNS -+* void -+*****************************************************************************/ -+extern void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL sdio_flag); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_tx_event_cb -+* DESCRIPTION -+* regiter Tx event callback function -+* PARAMETERS -+* func -+* RETURNS -+* int: 0:successful , -1: fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_register_tx_event_cb(int type, MTK_WCN_STP_EVENT_CB func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_event_cb -+* DESCRIPTION -+* regiter Rx event callback function -+* PARAMETERS -+* func -+* RETURNS -+* int: 0:successful , -1: fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_register_event_cb(int type, MTK_WCN_STP_EVENT_CB func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_if_tx -+* DESCRIPTION -+* regiter Tx event callback function -+* PARAMETERS -+* stp_if: SDIO or UART, fnnc: Call back function -+* RETURNS -+* int: 0:successful , -1: fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_if_rx -+* DESCRIPTION -+* regiter Rx event callback function -+* PARAMETERS -+* stp_if: SDIO or UART, fnnc: Call back function -+* RETURNS -+* int: 0:successful , -1: fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#else -+extern INT32 _mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type); -+extern INT32 _mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+extern INT32 _mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+extern MTK_WCN_BOOL _mtk_wcn_stp_is_rxqueue_empty(UINT8 type); -+extern MTK_WCN_BOOL _mtk_wcn_stp_is_ready(void); -+extern INT32 _mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length); -+extern void _mtk_wcn_stp_set_bluez(MTK_WCN_BOOL sdio_flag); -+extern INT32 _mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); -+extern INT32 _mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); -+extern INT32 _mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); -+extern INT32 _mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); -+extern INT32 _mtk_wcn_stp_coredump_start_get(VOID); -+ -+#endif -+ -+#endif /* _WMT_EXP_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h -new file mode 100644 -index 0000000000000..6d10c3ff26590 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h -@@ -0,0 +1,19 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef _MTKWMT_H_ -+#define _MTKWMT_H_ -+#include "wmt_core.h" -+ -+#endif /*_MTKWMT_H_*/ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h -new file mode 100644 -index 0000000000000..06238e07879fe ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h -@@ -0,0 +1,329 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_EXP_H_ -+#define _WMT_EXP_H_ -+ -+#include -+#include "osal.h" -+#include "wmt_plat.h" -+#include "wmt_stp_exp.h" -+/* not to reference to internal wmt */ -+/* #include "wmt_core.h" */ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#if 1 /* moved from wmt_lib.h */ -+#ifndef DFT_TAG -+#define DFT_TAG "[WMT-DFT]" -+#endif -+ -+#define WMT_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_LOUD) \ -+ osal_dbg_print(DFT_TAG "[L]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_INFO) \ -+ osal_dbg_print(DFT_TAG "[I]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_WARN) \ -+ osal_warn_print(DFT_TAG "[W]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_ERR) \ -+ osal_err_print(DFT_TAG "[E]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+#define WMT_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_DBG) \ -+ osal_dbg_print(DFT_TAG "[D]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_TRC_FUNC(f) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_DBG) \ -+ osal_dbg_print(DFT_TAG "<%s> <%d>\n", __func__, __LINE__); \ -+} while (0) -+ -+#endif -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#if 1 /* moved from wmt_lib.h */ -+extern UINT32 gWmtDbgLvl; -+#endif -+extern OSAL_BIT_OP_VAR gBtWifiGpsState; -+extern OSAL_BIT_OP_VAR gGpsFmState; -+extern UINT32 gWifiProbed; -+extern MTK_WCN_BOOL g_pwr_off_flag; -+extern UINT32 g_IsNeedDoChipReset; -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#if 1 /* moved from wmt_lib.h */ -+#define WMT_LOG_LOUD 4 -+#define WMT_LOG_DBG 3 -+#define WMT_LOG_INFO 2 -+#define WMT_LOG_WARN 1 -+#define WMT_LOG_ERR 0 -+#endif -+#define CFG_CORE_INTERNAL_TXRX 0 /*just do TX/RX in host side */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+typedef enum _ENUM_WMTDRV_TYPE_T { -+ WMTDRV_TYPE_BT = 0, -+ WMTDRV_TYPE_FM = 1, -+ WMTDRV_TYPE_GPS = 2, -+ WMTDRV_TYPE_WIFI = 3, -+ WMTDRV_TYPE_WMT = 4, -+ WMTDRV_TYPE_STP = 5, -+ WMTDRV_TYPE_LPBK = 6, -+ WMTDRV_TYPE_COREDUMP = 7, -+ WMTDRV_TYPE_MAX -+} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T; -+ -+/* TODO: [ChangeFeature][GeorgeKuo] Reconsider usage of this type */ -+/* TODO: how do we extend for new chip and newer revision? */ -+/* TODO: This way is hard to extend */ -+typedef enum _ENUM_WMTHWVER_TYPE_T { -+ WMTHWVER_E1 = 0x0, -+ WMTHWVER_E2 = 0x1, -+ WMTHWVER_E3 = 0x2, -+ WMTHWVER_E4 = 0x3, -+ WMTHWVER_E5 = 0x4, -+ WMTHWVER_E6 = 0x5, -+ WMTHWVER_MAX, -+ WMTHWVER_INVALID = 0xff -+} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T; -+ -+typedef enum _ENUM_WMTDSNS_TYPE_T { -+ WMTDSNS_FM_DISABLE = 0, -+ WMTDSNS_FM_ENABLE = 1, -+ WMTDSNS_FM_GPS_DISABLE = 2, -+ WMTDSNS_FM_GPS_ENABLE = 3, -+ WMTDSNS_MAX -+} ENUM_WMTDSNS_TYPE_T, *P_ENUM_WMTDSNS_TYPE_T; -+ -+typedef enum _ENUM_WMTTHERM_TYPE_T { -+ WMTTHERM_ZERO = 0, -+ WMTTHERM_ENABLE = WMTTHERM_ZERO + 1, -+ WMTTHERM_READ = WMTTHERM_ENABLE + 1, -+ WMTTHERM_DISABLE = WMTTHERM_READ + 1, -+ WMTTHERM_MAX -+} ENUM_WMTTHERM_TYPE_T, *P_ENUM_WMTTHERM_TYPE_T; -+ -+typedef enum _ENUM_WMTMSG_TYPE_T { -+ WMTMSG_TYPE_POWER_ON = 0, -+ WMTMSG_TYPE_POWER_OFF = 1, -+ WMTMSG_TYPE_RESET = 2, -+ WMTMSG_TYPE_STP_RDY = 3, -+ WMTMSG_TYPE_HW_FUNC_ON = 4, -+ WMTMSG_TYPE_MAX -+} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T; -+ -+typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T, /* Source driver type */ -+ ENUM_WMTDRV_TYPE_T, /* Destination driver type */ -+ ENUM_WMTMSG_TYPE_T, /* Message type */ -+ VOID *, /* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client -+ can't touch this buffer after this function return. */ -+ UINT32 /* Buffer size in unit of byte */ -+); -+ -+typedef enum _SDIO_PS_OP { -+ OWN_SET = 0, -+ OWN_CLR = 1, -+ OWN_STATE = 2, -+} SDIO_PS_OP; -+ -+typedef INT32(*PF_WMT_SDIO_PSOP) (SDIO_PS_OP); -+ -+typedef enum _ENUM_WMTCHIN_TYPE_T { -+ WMTCHIN_CHIPID = 0x0, -+ WMTCHIN_HWVER = WMTCHIN_CHIPID + 1, -+ WMTCHIN_MAPPINGHWVER = WMTCHIN_HWVER + 1, -+ WMTCHIN_FWVER = WMTCHIN_MAPPINGHWVER + 1, -+ WMTCHIN_MAX, -+ -+} ENUM_WMT_CHIPINFO_TYPE_T, *P_ENUM_WMT_CHIPINFO_TYPE_T; -+ -+#endif -+ -+typedef enum _ENUM_WMTRSTMSG_TYPE_T { -+ WMTRSTMSG_RESET_START = 0x0, -+ WMTRSTMSG_RESET_END = 0x1, -+ WMTRSTMSG_RESET_END_FAIL = 0x2, -+ WMTRSTMSG_RESET_MAX, -+ WMTRSTMSG_RESET_INVALID = 0xff -+} ENUM_WMTRSTMSG_TYPE_T, *P_ENUM_WMTRSTMSG_TYPE_T; -+ -+typedef enum _ENUM_BT_GPS_ONOFF_STATE_T { -+ WMT_BT_ON = 0, -+ WMT_GPS_ON = 1, -+ WMT_WIFI_ON = 2, -+ WMT_FM_ON = 3, -+ WMT_BT_GPS_STATE_MAX, -+ WMT_BT_GPS_STATE_INVALID = 0xff -+} ENUM_BT_GPS_ONOFF_STATE_T, *P_ENUM_BT_GPS_ONOFF_STATE_T; -+ -+#if 1 /* moved from wmt_core.h */ -+typedef enum { -+ WMT_SDIO_SLOT_INVALID = 0, -+ WMT_SDIO_SLOT_SDIO1 = 1, /* Wi-Fi dedicated SDIO1 */ -+ WMT_SDIO_SLOT_SDIO2 = 2, -+ WMT_SDIO_SLOT_MAX -+} WMT_SDIO_SLOT_NUM; -+ -+typedef enum { -+ WMT_SDIO_FUNC_STP = 0, -+ WMT_SDIO_FUNC_WIFI = 1, -+ WMT_SDIO_FUNC_MAX -+} WMT_SDIO_FUNC_TYPE; -+#endif -+ -+typedef INT32(*wmt_wlan_probe_cb) (VOID); -+typedef INT32(*wmt_wlan_remove_cb) (VOID); -+typedef INT32(*wmt_wlan_bus_cnt_get_cb) (VOID); -+typedef INT32(*wmt_wlan_bus_cnt_clr_cb) (VOID); -+ -+typedef struct _MTK_WCN_WMT_WLAN_CB_INFO { -+ wmt_wlan_probe_cb wlan_probe_cb; -+ wmt_wlan_remove_cb wlan_remove_cb; -+ wmt_wlan_bus_cnt_get_cb wlan_bus_cnt_get_cb; -+ wmt_wlan_bus_cnt_clr_cb wlan_bus_cnt_clr_cb; -+} MTK_WCN_WMT_WLAN_CB_INFO, *P_MTK_WCN_WMT_WLAN_CB_INFO; -+ -+#ifdef CONFIG_MTK_COMBO_ANT -+typedef enum _ENUM_WMT_ANT_RAM_CTRL_T { -+ WMT_ANT_RAM_GET_STATUS = 0, -+ WMT_ANT_RAM_DOWNLOAD = WMT_ANT_RAM_GET_STATUS + 1, -+ WMT_ANT_RAM_CTRL_MAX -+} ENUM_WMT_ANT_RAM_CTRL, *P_ENUM_WMT_ANT_RAM_CTRL; -+ -+typedef enum _ENUM_WMT_ANT_RAM_SEQ_T { -+ WMT_ANT_RAM_START_PKT = 1, -+ WMT_ANT_RAM_CONTINUE_PKT = WMT_ANT_RAM_START_PKT + 1, -+ WMT_ANT_RAM_END_PKT = WMT_ANT_RAM_CONTINUE_PKT + 1, -+ WMT_ANT_RAM_SEQ_MAX -+} ENUM_WMT_ANT_RAM_SEQ, *P_ENUM_WMT_ANT_RAM_SEQ; -+ -+typedef enum _ENUM_WMT_ANT_RAM_STATUS_T { -+ WMT_ANT_RAM_NOT_EXIST = 0, -+ WMT_ANT_RAM_EXIST = WMT_ANT_RAM_NOT_EXIST + 1, -+ WMT_ANT_RAM_DOWN_OK = WMT_ANT_RAM_EXIST + 1, -+ WMT_ANT_RAM_DOWN_FAIL = WMT_ANT_RAM_DOWN_OK + 1, -+ WMT_ANT_RAM_PARA_ERR = WMT_ANT_RAM_DOWN_FAIL + 1, -+ WMT_ANT_RAM_OP_ERR = WMT_ANT_RAM_PARA_ERR + 1, -+ WMT_ANT_RAM_MAX -+} ENUM_WMT_ANT_RAM_STATUS, *P_ENUM_WMT_ANT_RAM_STATUS; -+#endif -+ -+extern INT32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo); -+extern INT32 mtk_wcn_wmt_wlan_unreg(VOID); -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern wmt_wlan_probe_cb mtk_wcn_wlan_probe; -+extern wmt_wlan_remove_cb mtk_wcn_wlan_remove; -+extern wmt_wlan_bus_cnt_get_cb mtk_wcn_wlan_bus_tx_cnt; -+extern wmt_wlan_bus_cnt_clr_cb mtk_wcn_wlan_bus_tx_cnt_clr; -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*subsystem function ctrl APIs*/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); -+ -+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+#define WMT_EXP_HID_API_EXPORT 0 -+ -+extern MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type); -+ -+extern MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type); -+ -+extern MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType); -+ -+extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); -+ -+extern INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); -+ -+extern INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); -+ -+extern INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb); -+ -+extern INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID); -+/* -+return value: -+enable/disable thermal sensor function: true(1)/false(0) -+read thermal sensor function: thermal value -+ -+*/ -+extern INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType); -+ -+extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID); -+ -+#else -+#define WMT_EXP_HID_API_EXPORT 1 -+#endif -+ -+#ifdef CONFIG_MTK_COMBO_ANT -+extern ENUM_WMT_ANT_RAM_STATUS mtk_wcn_wmt_ant_ram_ctrl(ENUM_WMT_ANT_RAM_CTRL ctrlId, PUINT8 pBuf, -+ UINT32 length, ENUM_WMT_ANT_RAM_SEQ seq); -+#endif -+extern INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); /* set AUDIO interface options */ -+extern VOID wmt_lib_ps_irq_cb(VOID); -+ -+extern VOID mtk_wcn_wmt_func_ctrl_for_plat(UINT32 on, ENUM_WMTDRV_TYPE_T type); -+ -+extern INT32 mtk_wcn_wmt_system_state_reset(VOID); -+extern MTK_WCN_BOOL mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL value); -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+extern VOID mtk_wcn_wmt_exp_init(VOID); -+extern VOID mtk_wcn_wmt_exp_deinit(VOID); -+#endif -+extern INT8 mtk_wcn_wmt_co_clock_flag_get(VOID); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_EXP_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h -new file mode 100644 -index 0000000000000..075496cac54f9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h -@@ -0,0 +1,295 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_PLAT_H_ -+#define _WMT_PLAT_H_ -+#include "osal_typedef.h" -+#include "stp_exp.h" -+#include -+ -+/* #include "mtk_wcn_consys_hw.h" */ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#if 1 /* moved from wmt_exp.h */ -+#ifndef DFT_TAG -+#define DFT_TAG "[WMT-DFT]" -+#endif -+ -+#define WMT_PLAT_LOG_LOUD 4 -+#define WMT_PLAT_LOG_DBG 3 -+#define WMT_PLAT_LOG_INFO 2 -+#define WMT_PLAT_LOG_WARN 1 -+#define WMT_PLAT_LOG_ERR 0 -+ -+extern UINT32 wmtPlatLogLvl; -+ -+#define WMT_PLAT_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (wmtPlatLogLvl >= WMT_PLAT_LOG_LOUD) \ -+ pr_debug(DFT_TAG "[L]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_PLAT_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (wmtPlatLogLvl >= WMT_PLAT_LOG_INFO) \ -+ pr_debug(DFT_TAG "[I]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_PLAT_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (wmtPlatLogLvl >= WMT_PLAT_LOG_WARN) \ -+ pr_warn(DFT_TAG "[W]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_PLAT_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (wmtPlatLogLvl >= WMT_PLAT_LOG_ERR) \ -+ pr_err(DFT_TAG "[E]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+#define WMT_PLAT_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (wmtPlatLogLvl >= WMT_PLAT_LOG_DBG) \ -+ pr_debug(DFT_TAG "[D]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+ -+#endif -+ -+#define CFG_WMT_PS_SUPPORT 1 /* moved from wmt_exp.h */ -+ -+#define CFG_WMT_DUMP_INT_STATUS 0 -+#define CONSYS_ENALBE_SET_JTAG 1 -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _ENUM_FUNC_STATE_ { -+ FUNC_ON = 0, -+ FUNC_OFF = 1, -+ FUNC_RST = 2, -+ FUNC_STAT = 3, -+ FUNC_CTRL_MAX, -+} ENUM_FUNC_STATE, *P_ENUM_FUNC_STATE; -+ -+typedef enum _ENUM_PIN_ID_ { -+ PIN_BGF_EINT = 0, -+ PIN_I2S_GRP = 1, -+ PIN_GPS_SYNC = 2, -+ PIN_GPS_LNA = 3, -+#if CFG_WMT_LTE_COEX_HANDLING -+ PIN_TDM_REQ = 4, -+#endif -+ PIN_ID_MAX -+} ENUM_PIN_ID, *P_ENUM_PIN_ID; -+ -+typedef enum _ENUM_PIN_STATE_ { -+ PIN_STA_INIT = 0, -+ PIN_STA_OUT_L = 1, -+ PIN_STA_OUT_H = 2, -+ PIN_STA_IN_L = 3, -+ PIN_STA_MUX = 4, -+ PIN_STA_EINT_EN = 5, -+ PIN_STA_EINT_DIS = 6, -+ PIN_STA_DEINIT = 7, -+ PIN_STA_SHOW = 8, -+ PIN_STA_MAX -+} ENUM_PIN_STATE, *P_ENUM_PIN_STATE; -+ -+typedef enum _CMB_IF_TYPE_ { -+ CMB_IF_UART = 0, -+ CMB_IF_WIFI_SDIO = 1, -+ CMB_IF_BGF_SDIO = 2, -+ CMB_IF_BGWF_SDIO = 3, -+ CMB_IF_TYPE_MAX -+} CMB_IF_TYPE, *P_CMB_IF_TYPE; -+ -+typedef INT32(*fp_set_pin) (ENUM_PIN_STATE); -+ -+typedef enum _ENUM_WL_OP_ { -+ WL_OP_GET = 0, -+ WL_OP_PUT = 1, -+ WL_OP_MAX -+} ENUM_WL_OP, *P_ENUM_WL_OP; -+ -+typedef enum _ENUM_PALDO_TYPE_ { -+ BT_PALDO = 0, -+ WIFI_PALDO = 1, -+ FM_PALDO = 2, -+ GPS_PALDO = 3, -+ PMIC_CHIPID_PALDO = 4, -+ WIFI_5G_PALDO = 5, -+ PALDO_TYPE_MAX -+} ENUM_PALDO_TYPE, *P_ENUM_PALDO_TYPE; -+ -+typedef enum _ENUM_PALDO_OP_ { -+ PALDO_OFF = 0, -+ PALDO_ON = 1, -+ PALDO_OP_MAX -+} ENUM_PALDO_OP, *P_ENUM_PALDO_OP; -+ -+typedef enum _ENUM_HOST_DUMP_STATE_T { -+ STP_HOST_DUMP_NOT_START = 0, -+ STP_HOST_DUMP_GET = 1, -+ STP_HOST_DUMP_GET_DONE = 2, -+ STP_HOST_DUMP_END = 3, -+ STP_HOST_DUMP_MAX -+} ENUM_HOST_DUMP_STATE, *P_ENUM_HOST_DUMP_STATE_T; -+ -+typedef enum _ENUM_FORCE_TRG_ASSERT_T { -+ STP_FORCE_TRG_ASSERT_EMI = 0, -+ STP_FORCE_TRG_ASSERT_DEBUG_PIN = 1, -+ STP_FORCE_TRG_ASSERT_MAX = 2 -+} ENUM_FORCE_TRG_ASSERT_T, *P_ENUM_FORCE_TRG_ASSERT_T; -+ -+typedef enum _ENUM_CHIP_DUMP_STATE_T { -+ STP_CHIP_DUMP_NOT_START = 0, -+ STP_CHIP_DUMP_PUT = 1, -+ STP_CHIP_DUMP_PUT_DONE = 2, -+ STP_CHIP_DUMP_END = 3, -+ STP_CHIP_DUMP_MAX -+} ENUM_CHIP_DUMP_STATE, *P_ENUM_CHIP_DUMP_STATE_T; -+ -+typedef struct _EMI_CTRL_STATE_OFFSET_ { -+ UINT32 emi_apmem_ctrl_state; -+ UINT32 emi_apmem_ctrl_host_sync_state; -+ UINT32 emi_apmem_ctrl_host_sync_num; -+ UINT32 emi_apmem_ctrl_chip_sync_state; -+ UINT32 emi_apmem_ctrl_chip_sync_num; -+ UINT32 emi_apmem_ctrl_chip_sync_addr; -+ UINT32 emi_apmem_ctrl_chip_sync_len; -+ UINT32 emi_apmem_ctrl_chip_print_buff_start; -+ UINT32 emi_apmem_ctrl_chip_print_buff_len; -+ UINT32 emi_apmem_ctrl_chip_print_buff_idx; -+ UINT32 emi_apmem_ctrl_chip_int_status; -+ UINT32 emi_apmem_ctrl_chip_paded_dump_end; -+ UINT32 emi_apmem_ctrl_host_outband_assert_w1; -+ UINT32 emi_apmem_ctrl_chip_page_dump_num; -+} EMI_CTRL_STATE_OFFSET, *P_EMI_CTRL_STATE_OFFSET; -+ -+typedef struct _BGF_IRQ_BALANCE_ { -+ UINT32 counter; -+ unsigned long flags; -+ spinlock_t lock; -+} BGF_IRQ_BALANCE, *P_BGF_IRQ_BALANCE; -+ -+typedef struct _CONSYS_EMI_ADDR_INFO_ { -+ UINT32 emi_phy_addr; -+ UINT32 paged_trace_off; -+ UINT32 paged_dump_off; -+ UINT32 full_dump_off; -+ P_EMI_CTRL_STATE_OFFSET p_ecso; -+} CONSYS_EMI_ADDR_INFO, *P_CONSYS_EMI_ADDR_INFO; -+ -+typedef struct _GPIO_TDM_REQ_INFO_ { -+ UINT32 ant_sel_index; -+ UINT32 gpio_number; -+ UINT32 cr_address; -+} GPIO_TDM_REQ_INFO, *P_GPIO_TDM_REQ_INFO; -+ -+typedef VOID(*irq_cb) (VOID); -+typedef INT32(*device_audio_if_cb) (CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); -+typedef VOID(*func_ctrl_cb) (UINT32 on, UINT32 type); -+typedef long (*thermal_query_ctrl_cb) (VOID); -+typedef INT32(*deep_idle_ctrl_cb) (UINT32); -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern UINT32 gWmtDbgLvl; -+extern struct device *wmt_dev; -+#ifdef CFG_WMT_READ_EFUSE_VCN33 -+extern INT32 wmt_set_pmic_voltage(UINT32 level); -+#endif -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+INT32 wmt_plat_init(UINT32 co_clock_type); -+ -+INT32 wmt_plat_deinit(VOID); -+ -+INT32 wmt_plat_pwr_ctrl(ENUM_FUNC_STATE state); -+ -+INT32 wmt_plat_gpio_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state); -+ -+INT32 wmt_plat_eirq_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state); -+ -+INT32 wmt_plat_wake_lock_ctrl(ENUM_WL_OP opId); -+ -+INT32 wmt_plat_audio_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl); -+ -+VOID wmt_plat_irq_cb_reg(irq_cb bgf_irq_cb); -+VOID wmt_plat_aif_cb_reg(device_audio_if_cb aif_ctrl_cb); -+VOID wmt_plat_func_ctrl_cb_reg(func_ctrl_cb subsys_func_ctrl); -+VOID wmt_plat_thermal_ctrl_cb_reg(thermal_query_ctrl_cb thermal_query_ctrl); -+VOID wmt_plat_deep_idle_ctrl_cb_reg(deep_idle_ctrl_cb deep_idle_ctrl); -+ -+INT32 wmt_plat_soc_paldo_ctrl(ENUM_PALDO_TYPE ePt, ENUM_PALDO_OP ePo); -+UINT8 *wmt_plat_get_emi_virt_add(UINT32 offset); -+#if CONSYS_ENALBE_SET_JTAG -+UINT32 wmt_plat_jtag_flag_ctrl(UINT32 en); -+#endif -+#if CFG_WMT_DUMP_INT_STATUS -+VOID wmt_plat_BGF_irq_dump_status(VOID); -+MTK_WCN_BOOL wmt_plat_dump_BGF_irq_status(VOID); -+#endif -+P_CONSYS_EMI_ADDR_INFO wmt_plat_get_emi_phy_add(VOID); -+UINT32 wmt_plat_read_cpupcr(VOID); -+UINT32 wmt_plat_read_dmaregs(UINT32); -+INT32 wmt_plat_set_host_dump_state(ENUM_HOST_DUMP_STATE state); -+UINT32 wmt_plat_force_trigger_assert(ENUM_FORCE_TRG_ASSERT_T type); -+INT32 wmt_plat_update_host_sync_num(VOID); -+INT32 wmt_plat_get_dump_info(UINT32 offset); -+UINT32 wmt_plat_get_soc_chipid(VOID); -+INT32 wmt_plat_set_dbg_mode(UINT32 flag); -+VOID wmt_plat_set_dynamic_dumpmem(UINT32 *buf); -+#if CFG_WMT_LTE_COEX_HANDLING -+INT32 wmt_plat_get_tdm_antsel_index(VOID); -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_PLAT_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile -new file mode 100644 -index 0000000000000..9052071189386 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile -@@ -0,0 +1,6 @@ -+ifeq ($(CONFIG_MTK_COMBO), y) -+ -+obj-y += pub/ -+obj-y += pri/ -+ -+endif -\ No newline at end of file -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h -new file mode 100644 -index 0000000000000..95d1ab02a9fa4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h -@@ -0,0 +1,74 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef __BGW_DESENSE_H_ -+#define __BGW_DESENSE_H_ -+ -+#ifdef MSG -+#undef MSG -+#endif -+ -+#ifdef ERR -+#undef ERR -+#endif -+ -+#define PFX1 "[BWG] " -+#define MSG(fmt, arg ...) pr_debug(PFX1 "[D]%s: " fmt, __func__ , ##arg) -+#define ERR(fmt, arg ...) pr_debug(PFX1 "[D]%s: " fmt, __func__ , ##arg) -+ -+#ifdef NETLINK_TEST -+#undef NETLINK_TEST -+#endif -+ -+#define NETLINK_TEST 17 -+ -+#ifdef MAX_NL_MSG_LEN -+#undef MAX_NL_MSG_LEN -+#endif -+ -+#define MAX_NL_MSG_LEN 1024 -+ -+ -+#ifdef ON -+#undef ON -+#endif -+#ifdef OFF -+#undef OFF -+#endif -+#ifdef ACK -+#undef ACK -+#endif -+ -+#define ON 1 -+#define OFF 0 -+#define ACK 2 -+ -+/* -+used send command to native process -+ -+parameter: command could be macro ON: enable co-exist; OFF: disable co-exist; -+ACK: after get native process init message send ACK -+ -+*/ -+extern void send_command_to_daemon(const int command); -+ -+/* -+before use kernel socket, please call init socket first -+return value: 0: ok; -1: fail -+*/ -+extern int bgw_init_socket(void); -+ -+extern void bgw_destroy_netlink_kernel(void); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h -new file mode 100644 -index 0000000000000..cf3e830003ac8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h -@@ -0,0 +1,349 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _OSAL_H_ -+#define _OSAL_H_ -+ -+#include -+#include -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define OS_BIT_OPS_SUPPORT 1 -+ -+#define _osal_inline_ inline -+ -+#define MAX_THREAD_NAME_LEN 16 -+#define MAX_WAKE_LOCK_NAME_LEN 16 -+#define OSAL_OP_BUF_SIZE 64 -+ -+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MT_ENG_BUILD)) -+#define OSAL_OP_DATA_SIZE 8 -+#else -+#define OSAL_OP_DATA_SIZE 32 -+#endif -+ -+#define DBG_LOG_STR_SIZE 256 -+ -+#define osal_sizeof(x) sizeof(x) -+ -+#define osal_array_size(x) (sizeof(x)/sizeof(x[0])) -+ -+#ifndef NAME_MAX -+#define NAME_MAX 256 -+#endif -+ -+#define WMT_OP_BIT(x) (0x1UL << x) -+#define WMT_OP_HIF_BIT WMT_OP_BIT(0) -+ -+#define RB_SIZE(prb) ((prb)->size) -+#define RB_MASK(prb) (RB_SIZE(prb) - 1) -+#define RB_COUNT(prb) ((prb)->write - (prb)->read) -+#define RB_FULL(prb) (RB_COUNT(prb) >= RB_SIZE(prb)) -+#define RB_EMPTY(prb) ((prb)->write == (prb)->read) -+ -+#define RB_INIT(prb, qsize) \ -+do { \ -+ (prb)->read = (prb)->write = 0; \ -+ (prb)->size = (qsize); \ -+} while (0) -+ -+#define RB_PUT(prb, value) \ -+do { \ -+ if (!RB_FULL(prb)) { \ -+ (prb)->queue[(prb)->write & RB_MASK(prb)] = value; \ -+ ++((prb)->write); \ -+ } \ -+ else { \ -+ osal_assert(!RB_FULL(prb)); \ -+ } \ -+} while (0) -+ -+#define RB_GET(prb, value) \ -+do { \ -+ if (!RB_EMPTY(prb)) { \ -+ value = (prb)->queue[(prb)->read & RB_MASK(prb)]; \ -+ ++((prb)->read); \ -+ if (RB_EMPTY(prb)) { \ -+ (prb)->read = (prb)->write = 0; \ -+ } \ -+ } \ -+ else { \ -+ value = NULL; \ -+ osal_assert(!RB_EMPTY(prb)); \ -+ } \ -+} while (0) -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+//typedef VOID(*P_TIMEOUT_HANDLER) (unsigned long); -+typedef VOID(*P_TIMEOUT_HANDLER) (struct timer_list *t); -+typedef INT32(*P_COND) (VOID *); -+ -+typedef struct _OSAL_TIMER_ { -+ struct timer_list timer; -+ P_TIMEOUT_HANDLER timeoutHandler; -+ unsigned long timeroutHandlerData; -+} OSAL_TIMER, *P_OSAL_TIMER; -+ -+typedef struct _OSAL_UNSLEEPABLE_LOCK_ { -+ spinlock_t lock; -+ unsigned long flag; -+} OSAL_UNSLEEPABLE_LOCK, *P_OSAL_UNSLEEPABLE_LOCK; -+ -+typedef struct _OSAL_SLEEPABLE_LOCK_ { -+ struct mutex lock; -+} OSAL_SLEEPABLE_LOCK, *P_OSAL_SLEEPABLE_LOCK; -+ -+typedef struct _OSAL_SIGNAL_ { -+ struct completion comp; -+ UINT32 timeoutValue; -+} OSAL_SIGNAL, *P_OSAL_SIGNAL; -+ -+typedef struct _OSAL_EVENT_ { -+ wait_queue_head_t waitQueue; -+/* VOID *pWaitQueueData; */ -+ UINT32 timeoutValue; -+ INT32 waitFlag; -+ -+} OSAL_EVENT, *P_OSAL_EVENT; -+ -+typedef struct _OSAL_THREAD_ { -+ struct task_struct *pThread; -+ VOID *pThreadFunc; -+ VOID *pThreadData; -+ char threadName[MAX_THREAD_NAME_LEN]; -+} OSAL_THREAD, *P_OSAL_THREAD; -+ -+typedef struct _OSAL_FIFO_ { -+ /*fifo definition */ -+ VOID *pFifoBody; -+ spinlock_t fifoSpinlock; -+ /*fifo operations */ -+ INT32 (*FifoInit)(struct _OSAL_FIFO_ *pFifo, UINT8 *buf, UINT32); -+ INT32 (*FifoDeInit)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoReset)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoSz)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoAvailSz)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoLen)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoIsEmpty)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoIsFull)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoDataIn)(struct _OSAL_FIFO_ *pFifo, const VOID *buf, UINT32 len); -+ INT32 (*FifoDataOut)(struct _OSAL_FIFO_ *pFifo, void *buf, UINT32 len); -+} OSAL_FIFO, *P_OSAL_FIFO; -+ -+typedef struct firmware osal_firmware; -+ -+typedef struct _OSAL_OP_DAT { -+ UINT32 opId; /* Event ID */ -+ UINT32 u4InfoBit; /* Reserved */ -+ SIZE_T au4OpData[OSAL_OP_DATA_SIZE]; /* OP Data */ -+} OSAL_OP_DAT, *P_OSAL_OP_DAT; -+ -+typedef struct _OSAL_LXOP_ { -+ OSAL_OP_DAT op; -+ OSAL_SIGNAL signal; -+ INT32 result; -+} OSAL_OP, *P_OSAL_OP; -+ -+typedef struct _OSAL_LXOP_Q { -+ OSAL_SLEEPABLE_LOCK sLock; -+ UINT32 write; -+ UINT32 read; -+ UINT32 size; -+ P_OSAL_OP queue[OSAL_OP_BUF_SIZE]; -+} OSAL_OP_Q, *P_OSAL_OP_Q; -+ -+typedef struct _OSAL_WAKE_LOCK_ { -+ #ifdef CONFIG_PM_WAKELOCKS -+ struct wakeup_source wake_lock; -+ #else -+ struct wake_lock wake_lock; -+ #endif -+ UINT8 name[MAX_WAKE_LOCK_NAME_LEN]; -+} OSAL_WAKE_LOCK, *P_OSAL_WAKE_LOCK; -+#if 1 -+typedef struct _OSAL_BIT_OP_VAR_ { -+ unsigned long data; -+ OSAL_UNSLEEPABLE_LOCK opLock; -+} OSAL_BIT_OP_VAR, *P_OSAL_BIT_OP_VAR; -+#else -+#define OSAL_BIT_OP_VAR unsigned long -+#define P_OSAL_BIT_OP_VAR unsigned long * -+ -+#endif -+typedef UINT32(*P_OSAL_EVENT_CHECKER) (P_OSAL_THREAD pThread); -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+extern UINT32 osal_strlen(const char *str); -+extern INT32 osal_strcmp(const char *dst, const char *src); -+extern INT32 osal_strncmp(const char *dst, const char *src, UINT32 len); -+extern char *osal_strcpy(char *dst, const char *src); -+extern char *osal_strncpy(char *dst, const char *src, UINT32 len); -+extern char *osal_strcat(char *dst, const char *src); -+extern char *osal_strncat(char *dst, const char *src, UINT32 len); -+extern char *osal_strchr(const char *str, UINT8 c); -+extern char *osal_strsep(char **str, const char *c); -+extern int osal_strtol(const char *str, UINT32 adecimal, long *res); -+extern INT32 osal_snprintf(char *buf, UINT32 len, const char *fmt, ...); -+extern char *osal_strstr(char *str1, const char *str2); -+ -+extern INT32 osal_err_print(const char *str, ...); -+extern INT32 osal_dbg_print(const char *str, ...); -+extern INT32 osal_warn_print(const char *str, ...); -+ -+extern INT32 osal_dbg_assert(INT32 expr, const char *file, INT32 line); -+extern INT32 osal_sprintf(char *str, const char *format, ...); -+extern VOID *osal_malloc(UINT32 size); -+extern VOID osal_free(const VOID *dst); -+extern VOID *osal_memset(VOID *buf, INT32 i, UINT32 len); -+extern VOID *osal_memcpy(VOID *dst, const VOID *src, UINT32 len); -+extern INT32 osal_memcmp(const VOID *buf1, const VOID *buf2, UINT32 len); -+ -+extern INT32 osal_sleep_ms(UINT32 ms); -+extern INT32 osal_udelay(UINT32 us); -+extern INT32 osal_timer_create(P_OSAL_TIMER); -+extern INT32 osal_timer_start(P_OSAL_TIMER, UINT32); -+extern INT32 osal_timer_stop(P_OSAL_TIMER); -+extern INT32 osal_timer_stop_sync(P_OSAL_TIMER pTimer); -+extern INT32 osal_timer_modify(P_OSAL_TIMER, UINT32); -+extern INT32 osal_timer_delete(P_OSAL_TIMER); -+ -+extern INT32 osal_fifo_init(P_OSAL_FIFO pFifo, UINT8 *buffer, UINT32 size); -+extern VOID osal_fifo_deinit(P_OSAL_FIFO pFifo); -+extern INT32 osal_fifo_reset(P_OSAL_FIFO pFifo); -+extern UINT32 osal_fifo_in(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size); -+extern UINT32 osal_fifo_out(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size); -+extern UINT32 osal_fifo_len(P_OSAL_FIFO pFifo); -+extern UINT32 osal_fifo_sz(P_OSAL_FIFO pFifo); -+extern UINT32 osal_fifo_avail(P_OSAL_FIFO pFifo); -+extern UINT32 osal_fifo_is_empty(P_OSAL_FIFO pFifo); -+extern UINT32 osal_fifo_is_full(P_OSAL_FIFO pFifo); -+ -+extern INT32 osal_wake_lock_init(P_OSAL_WAKE_LOCK plock); -+extern INT32 osal_wake_lock(P_OSAL_WAKE_LOCK plock); -+extern INT32 osal_wake_unlock(P_OSAL_WAKE_LOCK plock); -+extern INT32 osal_wake_lock_count(P_OSAL_WAKE_LOCK plock); -+extern INT32 osal_wake_lock_deinit(P_OSAL_WAKE_LOCK plock); -+ -+#if defined(CONFIG_PROVE_LOCKING) -+#define osal_unsleepable_lock_init(l) { spin_lock_init(&((l)->lock)); } -+#else -+extern INT32 osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK); -+#endif -+extern INT32 osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK); -+extern INT32 osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK); -+extern INT32 osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK); -+ -+#if defined(CONFIG_PROVE_LOCKING) -+#define osal_sleepable_lock_init(l) { mutex_init(&((l)->lock)); } -+#else -+extern INT32 osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK); -+#endif -+extern INT32 osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK); -+extern INT32 osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK); -+extern INT32 osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK); -+ -+extern INT32 osal_signal_init(P_OSAL_SIGNAL); -+extern INT32 osal_wait_for_signal(P_OSAL_SIGNAL); -+extern INT32 osal_wait_for_signal_timeout(P_OSAL_SIGNAL); -+extern INT32 osal_raise_signal(P_OSAL_SIGNAL); -+extern INT32 osal_signal_deinit(P_OSAL_SIGNAL); -+ -+extern INT32 osal_event_init(P_OSAL_EVENT); -+extern INT32 osal_wait_for_event(P_OSAL_EVENT, P_COND, void *); -+extern INT32 osal_wait_for_event_timeout(P_OSAL_EVENT, P_COND, void *); -+extern INT32 osal_trigger_event(P_OSAL_EVENT); -+ -+extern INT32 osal_event_deinit(P_OSAL_EVENT); -+ -+extern INT32 osal_thread_create(P_OSAL_THREAD); -+extern INT32 osal_thread_run(P_OSAL_THREAD); -+extern INT32 osal_thread_should_stop(P_OSAL_THREAD); -+extern INT32 osal_thread_stop(P_OSAL_THREAD); -+/*extern INT32 osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT);*/ -+extern INT32 osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT, P_OSAL_EVENT_CHECKER); -+/*check pOsalLxOp and OSAL_THREAD_SHOULD_STOP*/ -+extern INT32 osal_thread_destroy(P_OSAL_THREAD); -+ -+extern INT32 osal_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); -+extern INT32 osal_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); -+extern INT32 osal_test_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); -+extern INT32 osal_test_and_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); -+extern INT32 osal_test_and_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); -+ -+extern INT32 osal_dbg_assert_aee(const char *module, const char *detail_description); -+extern INT32 osal_gettimeofday(PINT32 sec, PINT32 usec); -+extern INT32 osal_printtimeofday(const PUINT8 prefix); -+ -+extern VOID osal_buffer_dump(const UINT8 *buf, const UINT8 *title, UINT32 len, UINT32 limit); -+ -+extern UINT32 osal_op_get_id(P_OSAL_OP pOp); -+extern MTK_WCN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp); -+extern VOID osal_op_raise_signal(P_OSAL_OP pOp, INT32 result); -+extern VOID osal_set_op_result(P_OSAL_OP pOp, INT32 result); -+extern UINT16 osal_crc16(const UINT8 *buffer, const UINT32 length); -+extern VOID osal_thread_show_stack(P_OSAL_THREAD pThread); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#define osal_assert(condition) \ -+do { \ -+ if (!(condition)) \ -+ osal_err_print("%s, %d, (%s)\n", __FILE__, __LINE__, #condition); \ -+} while (0) -+ -+#endif /* _OSAL_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h -new file mode 100644 -index 0000000000000..b3a9c57e062dd ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h -@@ -0,0 +1,90 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _OSAL_TYPEDEF_H_ -+#define _OSAL_TYPEDEF_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_EARLYSUSPEND -+#include -+#else -+#include -+#endif -+#include -+#include -+#ifdef WMT_PLAT_ALPS -+#include -+#endif -+#include -+#ifdef CONFIG_PM_WAKELOCKS -+#include -+#else -+#include -+#endif -+#include -+ -+#ifndef _TYPEDEFS_H /*fix redifine */ -+typedef char INT8; -+#endif -+ -+typedef void VOID, *PVOID, **PPVOID; -+typedef char *PINT8, **PPINT8; -+typedef short INT16, *PINT16, **PPINT16; -+typedef int INT32, *PINT32, **PPINT32; -+typedef long long INT64, *PINT64, **PPINT64; -+ -+typedef unsigned char UINT8, *PUINT8, **PPUINT8; -+typedef unsigned short UINT16, *PUINT16, **PPUINT16; -+typedef unsigned int UINT32, *PUINT32, **PPUINT32; -+typedef unsigned long long UINT64, *PUINT64, **PPUINT64; -+ -+typedef size_t SIZE_T; -+ -+typedef int MTK_WCN_BOOL; -+#ifndef MTK_WCN_BOOL_TRUE -+#define MTK_WCN_BOOL_FALSE ((MTK_WCN_BOOL) 0) -+#define MTK_WCN_BOOL_TRUE ((MTK_WCN_BOOL) 1) -+#endif -+ -+#endif /*_OSAL_TYPEDEF_H_*/ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h -new file mode 100644 -index 0000000000000..17be778484c17 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h -@@ -0,0 +1,97 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef _WMT_IDC_H_ -+#define _WMT_IDC_H_ -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "wmt_stp_exp.h" -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ -+#include "wmt_stp_exp.h" -+#include "conn_md_exp.h" -+ -+#define LTE_IDC_BUFFER_MAX_SIZE 1024 -+/*comment from firmware owner,max pckage num is 5,but should not happened*/ -+#define WMT_IDC_RX_MAX_LEN 384 -+#define LTE_MSG_ID_OFFSET 0x30 -+ -+typedef enum { -+ WMT_IDC_TX_OPCODE_MIN = 0, -+ WMT_IDC_TX_OPCODE_LTE_PARA = 0x0a, -+ WMT_IDC_TX_OPCODE_LTE_FREQ = 0x0b, -+ WMT_IDC_TX_OPCODE_WIFI_MAX_POWER = 0x0c, -+ WMT_IDC_TX_OPCODE_DEBUG_MONITOR = 0x0e, -+ WMT_IDC_TX_OPCODE_SPLIT_FILTER = 0x0f, -+ WMT_IDC_TX_OPCODE_LTE_CONNECTION_STAS = 0x16, -+ WMT_IDC_TX_OPCODE_LTE_HW_IF_INDICATION = 0x17, -+ WMT_IDC_TX_OPCODE_LTE_INDICATION = 0x20, -+ WMT_IDC_TX_OPCODE_MAX -+} WMT_IDC_TX_OPCODE; -+ -+typedef enum { -+ WMT_IDC_RX_OPCODE_BTWF_DEF_PARA = 0x0, -+ WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN = 0x1, -+ /* WMT_IDC_RX_OPCODE_TDM_REQ = 0x10, */ -+ WMT_IDC_RX_OPCODE_DEBUG_MONITOR = 0x02, -+ WMT_IDC_RX_OPCODE_LTE_FREQ_IDX_TABLE = 0x03, -+ WMT_IDC_RX_OPCODE_BTWF_PROFILE_IND = 0x04, -+ WMT_IDC_RX_OPCODE_UART_PIN_SEL = 0x05, -+ WMT_IDC_RX_OPCODE_MAX -+} WMT_IDC_RX_OPCODE; -+ -+#if (CFG_WMT_LTE_ENABLE_MSGID_MAPPING == 0) -+typedef enum { -+ IPC_L4C_MSG_ID_INVALID = IPC_L4C_MSG_ID_BEGIN, -+ IPC_L4C_MSG_ID_END, -+ IPC_EL1_MSG_ID_INVALID = IPC_EL1_MSG_ID_BEGIN, -+ /* below are EL1 IPC messages sent from AP */ -+ IPC_MSG_ID_EL1_LTE_TX_ALLOW_IND, -+ IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND, -+ IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND, -+ IPC_MSG_ID_EL1_WIFIBT_FREQ_IDX_TABLE_IND, -+ IPC_MSG_ID_EL1_WIFIBT_PROFILE_IND, -+ -+ /* below are EL1 messages sent to AP */ -+ IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND, -+ IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND, -+ IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND, -+ IPC_MSG_ID_EL1_LTE_TX_IND, -+ IPC_MSG_ID_EL1_LTE_CONNECTION_STATUS_IND, -+ IPC_MSG_ID_EL1_PIN_TYPE_IND, -+ IPC_MSG_ID_EL1_LTE_HW_INTERFACE_IND, -+ IPC_MSG_ID_EL1_DUMMY13_IND, -+ IPC_MSG_ID_EL1_DUMMY14_IND, -+ IPC_MSG_ID_EL1_DUMMY15_IND, -+ IPC_EL1_MSG_ID_END, -+} IPC_MSG_ID_CODE; -+#endif -+ -+typedef struct _MTK_WCN_WMT_IDC_INFO_ { -+ ipc_ilm_t iit; -+ CONN_MD_BRIDGE_OPS ops; -+ UINT8 buffer[LTE_IDC_BUFFER_MAX_SIZE]; -+} MTK_WCN_WMT_IDC_INFO, *P_MTK_WCN_WMT_IDC_INFO; -+ -+extern INT32 wmt_idc_init(VOID); -+extern INT32 wmt_idc_deinit(VOID); -+extern INT32 wmt_idc_msg_from_lte_handing(ipc_ilm_t *ilm); -+extern INT32 wmt_idc_msg_to_lte_handing(VOID); -+extern UINT32 wmt_idc_msg_to_lte_handing_for_test(UINT8 *p_buf, UINT32 len); -+ -+#endif /* endif CFG_WMT_LTE_COEX_HANDLING */ -+ -+#endif /* _WMT_IDC_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile -new file mode 100644 -index 0000000000000..ff0f0b0aefda7 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile -@@ -0,0 +1,21 @@ -+ifeq ($(CONFIG_MTK_COMBO), y) -+ -+ccflags-y += \ -+ -I$(src)/../../linux/include \ -+ -I$(src)/../../linux/pri/include \ -+ -I$(src)/../../core/include \ -+ -I$(src)/../../include \ -+ -I$(src)/../include \ -+ -I$(src)/../../../common_detect \ -+ -I$(srctree)/drivers/misc/mediatek/btif/common/inc \ -+ -I$(srctree)/drivers/misc/mediatek/mach/$(MTK_PLATFORM)/include/mach -+ -+ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1 -+ -+obj-y += stp_btif.o \ -+ stp_dbg.o \ -+ stp_exp.o \ -+ wmt_dev.o \ -+ wmt_exp.o -+ -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h -new file mode 100644 -index 0000000000000..3730fbba69289 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h -@@ -0,0 +1,31 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef _STP_BTIF_H_ -+#define _STP_BTIF_H_ -+ -+#include "osal_typedef.h" -+#include "mtk_btif_exp.h" -+ -+extern INT32 mtk_wcn_consys_stp_btif_open(VOID); -+extern INT32 mtk_wcn_consys_stp_btif_close(VOID); -+extern INT32 mtk_wcn_consys_stp_btif_rx_cb_register(MTK_WCN_BTIF_RX_CB rx_cb); -+extern INT32 mtk_wcn_consys_stp_btif_tx(const UINT8 *pBuf, const UINT32 len, UINT32 *written_len); -+extern INT32 mtk_wcn_consys_stp_btif_wakeup(VOID); -+extern INT32 mtk_wcn_consys_stp_btif_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag); -+extern INT32 mtk_wcn_consys_stp_btif_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode); -+extern INT32 mtk_wcn_consys_stp_btif_logger_ctrl(ENUM_BTIF_DBG_ID flag); -+extern MTK_WCN_BOOL mtk_wcn_consys_stp_btif_parser_wmt_evt(const UINT8 *str, UINT32 len); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h -new file mode 100644 -index 0000000000000..de5684a168537 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h -@@ -0,0 +1,316 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef _STP_DEBUG_H_ -+#define _STP_DEBUG_H_ -+ -+#include -+#include "osal.h" -+ -+#define CONFIG_LOG_STP_INTERNAL -+ -+#if 1 /* #ifndef CONFIG_LOG_STP_INTERNAL */ -+#define STP_PKT_SZ 16 -+#define STP_DMP_SZ 2048 -+#define STP_PKT_NO 2048 -+ -+#define STP_DBG_LOG_ENTRY_NUM 60 -+#define STP_DBG_LOG_ENTRY_SZ 64 -+ -+#else -+ -+#define STP_PKT_SZ 16 -+#define STP_DMP_SZ 16 -+#define STP_PKT_NO 16 -+ -+#define STP_DBG_LOG_ENTRY_NUM 28 -+#define STP_DBG_LOG_ENTRY_SZ 64 -+ -+#endif -+ -+typedef enum { -+ STP_DBG_EN = 0, -+ STP_DBG_PKT = 1, -+ STP_DBG_DR = 2, -+ STP_DBG_FW_ASSERT = 3, -+ STP_DBG_FW_LOG = 4, -+ STP_DBG_FW_DMP = 5, -+ STP_DBG_MAX -+} STP_DBG_OP_T; -+ -+typedef enum { -+ STP_DBG_PKT_FIL_ALL = 0, -+ STP_DBG_PKT_FIL_BT = 1, -+ STP_DBG_PKT_FIL_GPS = 2, -+ STP_DBG_PKT_FIL_FM = 3, -+ STP_DBG_PKT_FIL_WMT = 4, -+ STP_DBG_PKT_FIL_MAX -+} STP_DBG_PKT_FIL_T; -+ -+static char *const gStpDbgType[] = { -+ "< BT>", -+ "< FM>", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "" -+}; -+ -+typedef enum { -+ STP_DBG_DR_MAX = 0, -+} STP_DBG_DR_FIL_T; -+ -+typedef enum { -+ STP_DBG_FW_MAX = 0, -+} STP_DBG_FW_FIL_T; -+ -+typedef enum { -+ PKT_DIR_RX = 0, -+ PKT_DIR_TX -+} STP_DBG_PKT_DIR_T; -+ -+/*simple log system ++*/ -+ -+typedef struct { -+ /*type: 0. pkt trace 1. fw info -+ * 2. assert info 3. trace32 dump . -+ * -1. linked to the the previous -+ */ -+ int id; -+ int len; -+ char buffer[STP_DBG_LOG_ENTRY_SZ]; -+} MTKSTP_LOG_ENTRY_T; -+ -+typedef struct log_sys { -+ MTKSTP_LOG_ENTRY_T queue[STP_DBG_LOG_ENTRY_NUM]; -+ unsigned int size; -+ unsigned int in; -+ unsigned int out; -+ spinlock_t lock; -+} MTKSTP_LOG_SYS_T; -+/*--*/ -+ -+typedef struct stp_dbg_pkt_hdr { -+ /* packet information */ -+ unsigned int sec; -+ unsigned int usec; -+ unsigned int dbg_type; -+ unsigned int dmy; -+ unsigned int no; -+ unsigned int dir; -+ -+ /* packet content */ -+ unsigned int type; -+ unsigned int len; -+ unsigned int ack; -+ unsigned int seq; -+ unsigned int chs; -+ unsigned int crc; -+} STP_DBG_HDR_T; -+ -+typedef struct stp_dbg_pkt { -+ struct stp_dbg_pkt_hdr hdr; -+ unsigned char raw[STP_DMP_SZ]; -+} STP_PACKET_T; -+ -+typedef struct mtkstp_dbg_t { -+ /*log_sys */ -+ int pkt_trace_no; -+ void *btm; -+ int is_enable; -+ MTKSTP_LOG_SYS_T *logsys; -+} MTKSTP_DBG_T; -+ -+/* extern void aed_combo_exception(const int *, int, const int *, int, const char *); */ -+ -+#define STP_CORE_DUMP_TIMEOUT (5*60*1000) /* default 5minutes */ -+#define STP_OJB_NAME_SZ 20 -+#define STP_CORE_DUMP_INFO_SZ 500 -+#define STP_CORE_DUMP_INIT_SIZE 1 -+typedef enum wcn_compress_algorithm_t { -+ GZIP = 0, -+ BZIP2 = 1, -+ RAR = 2, -+ LMA = 3, -+ MAX -+} WCN_COMPRESS_ALG_T; -+ -+typedef INT32 (*COMPRESS_HANDLER) (void *worker, UINT8 *in_buf, INT32 in_sz, UINT8 *out_buf, INT32 *out_sz, -+ INT32 finish); -+typedef struct wcn_compressor_t { -+ /* current object name */ -+ UINT8 name[STP_OJB_NAME_SZ + 1]; -+ -+ /* buffer for raw data, named L1 */ -+ PUINT8 L1_buf; -+ INT32 L1_buf_sz; -+ INT32 L1_pos; -+ -+ /* target buffer, named L2 */ -+ PUINT8 L2_buf; -+ INT32 L2_buf_sz; -+ INT32 L2_pos; -+ -+ /* compress state */ -+ UINT8 f_done; -+ UINT16 reserved; -+ UINT32 uncomp_size; -+ UINT32 crc32; -+ -+ /* compress algorithm */ -+ UINT8 f_compress_en; -+ WCN_COMPRESS_ALG_T compress_type; -+ void *worker; -+ COMPRESS_HANDLER handler; -+} WCN_COMPRESSOR_T, *P_WCN_COMPRESSOR_T; -+ -+P_WCN_COMPRESSOR_T wcn_compressor_init(PUINT8 name, INT32 L1_buf_sz, INT32 L2_buf_sz); -+INT32 wcn_compressor_deinit(P_WCN_COMPRESSOR_T compressor); -+INT32 wcn_compressor_in(P_WCN_COMPRESSOR_T compressor, PUINT8 buf, INT32 len, INT32 finish); -+INT32 wcn_compressor_out(P_WCN_COMPRESSOR_T compressor, PUINT8 *pbuf, PINT32 len); -+INT32 wcn_compressor_reset(P_WCN_COMPRESSOR_T compressor, UINT8 enable, WCN_COMPRESS_ALG_T type); -+ -+typedef enum core_dump_state_t { -+ CORE_DUMP_INIT = 0, -+ CORE_DUMP_DOING, -+ CORE_DUMP_TIMEOUT, -+ CORE_DUMP_DONE, -+ CORE_DUMP_MAX -+} CORE_DUMP_STA; -+ -+typedef struct core_dump_t { -+ /* compress dump data and buffered */ -+ P_WCN_COMPRESSOR_T compressor; -+ -+ /* timer for monitor timeout */ -+ OSAL_TIMER dmp_timer; -+ UINT32 timeout; -+ -+ OSAL_SLEEPABLE_LOCK dmp_lock; -+ -+ /* state machine for core dump flow */ -+ CORE_DUMP_STA sm; -+ -+ /* dump info */ -+ INT8 info[STP_CORE_DUMP_INFO_SZ + 1]; -+} WCN_CORE_DUMP_T, *P_WCN_CORE_DUMP_T; -+ -+typedef enum _ENUM_STP_FW_ISSUE_TYPE_ { -+ STP_FW_ISSUE_TYPE_INVALID = 0x0, -+ STP_FW_ASSERT_ISSUE = 0x1, -+ STP_FW_NOACK_ISSUE = 0x2, -+ STP_FW_WARM_RST_ISSUE = 0x3, -+ STP_DBG_PROC_TEST = 0x4, -+ STP_HOST_TRIGGER_FW_ASSERT = 0x5, -+ STP_HOST_TRIGGER_ASSERT_TIMEOUT = 0x6, -+ STP_FW_ISSUE_TYPE_MAX -+} ENUM_STP_FW_ISSUE_TYPE, *P_ENUM_STP_FW_ISSUE_TYPE; -+ -+/* this was added for support dmareg's issue */ -+typedef enum _ENUM_DMA_ISSUE_TYPE_ { -+ CONNSYS_CLK_GATE_STATUS = 0x00, -+ CONSYS_EMI_STATUS, -+ SYSRAM1, -+ SYSRAM2, -+ SYSRAM3, -+ DMA_REGS_MAX -+} ENUM_DMA_ISSUE_TYPE; -+#define STP_PATCH_TIME_SIZE 12 -+#define STP_DBG_CPUPCR_NUM 512 -+#define STP_DBG_DMAREGS_NUM 16 -+#define STP_PATCH_BRANCH_SZIE 8 -+#define STP_ASSERT_INFO_SIZE 64 -+#define STP_DBG_ROM_VER_SIZE 4 -+#define STP_ASSERT_TYPE_SIZE 32 -+ -+typedef struct stp_dbg_host_assert_t { -+ UINT32 drv_type; -+ UINT32 reason; -+ UINT32 assert_from_host; -+} STP_DBG_HOST_ASSERT_T, *P_STP_DBG_HOST_ASSERT_T; -+ -+typedef struct stp_dbg_cpupcr_t { -+ UINT32 chipId; -+ UINT8 romVer[STP_DBG_ROM_VER_SIZE]; -+ UINT8 patchVer[STP_PATCH_TIME_SIZE]; -+ UINT8 branchVer[STP_PATCH_BRANCH_SZIE]; -+ UINT32 wifiVer; -+ UINT32 count; -+ UINT32 stop_flag; -+ UINT32 buffer[STP_DBG_CPUPCR_NUM]; -+ UINT8 assert_info[STP_ASSERT_INFO_SIZE]; -+ UINT32 fwTaskId; -+ UINT32 fwRrq; -+ UINT32 fwIsr; -+ STP_DBG_HOST_ASSERT_T host_assert_info; -+ UINT8 assert_type[STP_ASSERT_TYPE_SIZE]; -+ ENUM_STP_FW_ISSUE_TYPE issue_type; -+ OSAL_SLEEPABLE_LOCK lock; -+} STP_DBG_CPUPCR_T, *P_STP_DBG_CPUPCR_T; -+ -+typedef struct stp_dbg_dmaregs_t { -+ UINT32 count; -+ UINT32 dmaIssue[DMA_REGS_MAX][STP_DBG_DMAREGS_NUM]; -+ OSAL_SLEEPABLE_LOCK lock; -+} STP_DBG_DMAREGS_T, *P_STP_DBG_DMAREGS_T; -+ -+typedef enum _ENUM_ASSERT_INFO_PARSER_TYPE_ { -+ STP_DBG_ASSERT_INFO = 0x0, -+ STP_DBG_FW_TASK_ID = 0x1, -+ STP_DBG_FW_ISR = 0x2, -+ STP_DBG_FW_IRQ = 0x3, -+ STP_DBG_ASSERT_TYPE = 0x4, -+ STP_DBG_PARSER_TYPE_MAX -+} ENUM_ASSERT_INFO_PARSER_TYPE, *P_ENUM_ASSERT_INFO_PARSER_TYPE; -+ -+P_WCN_CORE_DUMP_T wcn_core_dump_init(UINT32 packet_num, UINT32 timeout); -+INT32 wcn_core_dump_deinit(P_WCN_CORE_DUMP_T dmp); -+INT32 wcn_core_dump_in(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len); -+INT32 wcn_core_dump_out(P_WCN_CORE_DUMP_T dmp, PUINT8 *pbuf, PINT32 len); -+INT32 wcn_core_dump_reset(P_WCN_CORE_DUMP_T dmp, UINT32 timeout); -+INT32 wcn_core_dump_timeout(void); -+INT32 wcn_wmtd_timeout_collect_ftrace(void); -+ -+extern INT32 wcn_core_dump_init_gcoredump(UINT32 packet_num, UINT32 timeout); -+extern INT32 wcn_core_dump_deinit_gcoredump(VOID); -+extern INT32 wcn_core_dump_flush(INT32 rst, MTK_WCN_BOOL is_coredump_timeout); -+extern int stp_dbg_enable(MTKSTP_DBG_T *stp_dbg); -+extern int stp_dbg_disable(MTKSTP_DBG_T *stp_dbg); -+extern MTKSTP_DBG_T *stp_dbg_init(void *); -+extern int stp_dbg_deinit(MTKSTP_DBG_T *stp_dbg); -+extern int stp_dbg_dmp_out_ex(char *buf, int *len); -+extern int stp_dbg_dmp_out(MTKSTP_DBG_T *stp_dbg, char *buf, int *len); -+extern int stp_dbg_dmp_printk(MTKSTP_DBG_T *stp_dbg); -+extern char stp_dbg_nl_send(PINT8 aucMsg, UINT8 cmd, INT32 len); -+ -+extern INT32 stp_dbg_aee_send(unsigned char *aucMsg, INT32 len, INT32 cmd); -+extern INT32 _stp_btm_put_emi_dump_to_nl(PUINT8 data_buf, INT32 dump_len); -+extern int -+stp_dbg_log_pkt(MTKSTP_DBG_T *stp_dbg, -+ int dbg_type, int type, int ack_no, int seq_no, int crc, int dir, int len, const unsigned char *body); -+extern int stp_dbg_log_ctrl(unsigned int on); -+extern INT32 stp_dbg_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd); -+extern INT32 stp_dbg_poll_dmaregs(UINT32 times, UINT32 sleep); -+extern INT32 stp_dbg_poll_cuppcr_ctrl(UINT32 en); -+extern INT32 stp_dbg_set_version_info(UINT32 chipid, PUINT8 pRomVer, PUINT8 pPatchVer, -+ PUINT8 pPatchBrh); -+extern INT32 stp_dbg_set_wifiver(UINT32 wifiver); -+extern INT32 stp_dbg_cpupcr_infor_format(PPUINT8 buf, PUINT32 len); -+extern INT32 stp_dbg_set_fw_info(PUINT8 assert_info, UINT32 len, ENUM_STP_FW_ISSUE_TYPE issue_type); -+extern INT32 stp_dbg_set_host_assert_info(UINT32 drv_type, UINT32 reason, UINT32 en); -+extern UINT32 stp_dbg_get_host_trigger_assert(VOID); -+#endif /* end of _STP_DEBUG_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h -new file mode 100644 -index 0000000000000..5788eb355549a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h -@@ -0,0 +1,71 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#ifndef _WMT_DEV_H_ -+#define _WMT_DEV_H_ -+ -+#include "osal.h" -+ -+#define STP_UART_FULL 0x01 -+#define STP_UART_MAND 0x02 -+#define STP_BTIF_FULL 0x03 -+#define STP_SDIO 0x04 -+ -+#define CFG_WMT_DBG_SUPPORT 1 /* support wmt_dbg or not */ -+#define CFG_WMT_PROC_FOR_AEE 1 -+ -+extern VOID wmt_dev_rx_event_cb(VOID); -+extern INT32 wmt_dev_rx_timeout(P_OSAL_EVENT pEvent); -+extern INT32 wmt_dev_patch_get(PUINT8 pPatchName, osal_firmware **ppPatch, INT32 padSzBuf); -+extern INT32 wmt_dev_patch_put(osal_firmware **ppPatch); -+extern VOID wmt_dev_patch_info_free(VOID); -+extern VOID wmt_dev_send_cmd_to_daemon(UINT32 cmd); -+extern MTK_WCN_BOOL wmt_dev_get_early_suspend_state(VOID); -+ -+#if CFG_WMT_DBG_SUPPORT -+typedef struct _COEX_BUF { -+ UINT8 buffer[128]; -+ INT32 availSize; -+} COEX_BUF, *P_COEX_BUF; -+ -+typedef enum _ENUM_CMD_TYPE_T { -+ WMTDRV_CMD_ASSERT = 0, -+ WMTDRV_CMD_EXCEPTION = 1, -+ WMTDRV_CMD_COEXDBG_00 = 2, -+ WMTDRV_CMD_COEXDBG_01 = 3, -+ WMTDRV_CMD_COEXDBG_02 = 4, -+ WMTDRV_CMD_COEXDBG_03 = 5, -+ WMTDRV_CMD_COEXDBG_04 = 6, -+ WMTDRV_CMD_COEXDBG_05 = 7, -+ WMTDRV_CMD_COEXDBG_06 = 8, -+ WMTDRV_CMD_COEXDBG_07 = 9, -+ WMTDRV_CMD_COEXDBG_08 = 10, -+ WMTDRV_CMD_COEXDBG_09 = 11, -+ WMTDRV_CMD_COEXDBG_10 = 12, -+ WMTDRV_CMD_COEXDBG_11 = 13, -+ WMTDRV_CMD_COEXDBG_12 = 14, -+ WMTDRV_CMD_COEXDBG_13 = 15, -+ WMTDRV_CMD_COEXDBG_14 = 16, -+ WMTDRV_CMD_COEXDBG_15 = 17, -+ WMTDRV_CMD_NOACK_TEST = 18, -+ WMTDRV_CMD_WARNRST_TEST = 19, -+ WMTDRV_CMD_FWTRACE_TEST = 20, -+ WMTDRV_CMD_MAX -+} ENUM_WMTDRV_CMD_T, *P_ENUM_WMTDRV_CMD_T; -+ -+#endif -+ -+typedef INT32(*WMT_DEV_DBG_FUNC) (INT32 par1, INT32 par2, INT32 par3); -+ -+#endif /*_WMT_DEV_H_*/ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c -new file mode 100644 -index 0000000000000..76debb4674f9c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c -@@ -0,0 +1,279 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*file: stp_btif, mainly control stp & btif interaction*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[STP-BTIF]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+#include "wmt_exp.h" -+#include "stp_exp.h" -+#include "stp_btif.h" -+ -+#include -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define BTIF_OWNER_NAME "CONSYS_STP" -+ -+#define STP_MAX_PACKAGE_ALLOWED (2000) -+ -+#define STP_BTIF_TX_RTY_LMT (10) -+#define STP_BTIF_TX_RTY_DLY (5) -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+unsigned long stpBtifId = 0; -+unsigned long *pBtifRef = &stpBtifId; -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+INT32 mtk_wcn_consys_stp_btif_open(VOID) -+{ -+ INT32 iRet = -1; -+ -+ iRet = mtk_wcn_btif_open(BTIF_OWNER_NAME, pBtifRef); -+ if (iRet) { -+ WMT_WARN_FUNC("STP open btif fail(%d)\n", iRet); -+ return -1; -+ } -+ WMT_DBG_FUNC("STP open bitf OK\n"); -+ -+ mtk_wcn_stp_register_if_tx(STP_BTIF_IF_TX, (MTK_WCN_STP_IF_TX) mtk_wcn_consys_stp_btif_tx); -+ -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_close(VOID) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ iRet = -1; -+ } else { -+ iRet = mtk_wcn_btif_close(stpBtifId); -+ if (iRet) { -+ WMT_WARN_FUNC("STP close btif fail(%d)\n", iRet); -+ iRet = -2; -+ } else { -+ stpBtifId = 0; -+ WMT_DBG_FUNC("STP close btif OK\n"); -+ } -+ } -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_rx_cb_register(MTK_WCN_BTIF_RX_CB rx_cb) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference\n!"); -+ iRet = -1; -+ } else { -+ iRet = mtk_wcn_btif_rx_cb_register(stpBtifId, rx_cb); -+ if (iRet) { -+ WMT_WARN_FUNC("STP register rxcb to btif fail(%d)\n", iRet); -+ iRet = -2; -+ } else { -+ WMT_DBG_FUNC("STP register rxcb to btif OK\n"); -+ } -+ } -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_tx(const UINT8 *pBuf, const UINT32 len, UINT32 *written_len) -+{ -+ INT32 retry_left = STP_BTIF_TX_RTY_LMT; -+ INT32 wr_count = 0; -+ INT32 written = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ return -1; -+ } -+ -+ if (len == 0) { -+ *written_len = 0; -+ WMT_INFO_FUNC("special case for STP-CORE,pbuf(%p)\n", pBuf); -+ return 0; -+ } -+ -+ *written_len = 0; -+ -+ if (len > STP_MAX_PACKAGE_ALLOWED) { -+ WMT_WARN_FUNC("abnormal pacage length,len(%d),pid[%d/%s]\n", len, current->pid, current->comm); -+ return -2; -+ } -+ wr_count = mtk_wcn_btif_write(stpBtifId, pBuf, len); -+ -+ if (wr_count < 0) { -+ WMT_ERR_FUNC("mtk_wcn_btif_write err(%d)\n", wr_count); -+ *written_len = 0; -+ return -3; -+ } -+ if (wr_count == len) { -+ /*perfect case */ -+ *written_len = wr_count; -+ return wr_count; -+ } -+ -+ while ((retry_left--) && (wr_count < len)) { -+ osal_sleep_ms(STP_BTIF_TX_RTY_DLY); -+ written = mtk_wcn_btif_write(stpBtifId, pBuf + wr_count, len - wr_count); -+ if (written < 0) { -+ WMT_ERR_FUNC("mtk_wcn_btif_write err(%d)when do recovered\n", written); -+ break; -+ } -+ wr_count += written; -+ } -+ -+ if (wr_count == len) { -+ WMT_INFO_FUNC("recovered,len(%d),retry_left(%d)\n", len, retry_left); -+ /*recovered case */ -+ *written_len = wr_count; -+ return wr_count; -+ } -+ -+ WMT_ERR_FUNC("stp btif write fail,len(%d),written(%d),retry_left(%d),pid[%d/%s]\n", -+ len, wr_count, retry_left, current->pid, current->comm); -+ *written_len = 0; -+ return -wr_count; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_rx(UINT8 *pBuf, UINT32 len) -+{ -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_wakeup(VOID) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ iRet = -1; -+ } else { -+ iRet = mtk_wcn_btif_wakeup_consys(stpBtifId); -+ if (iRet) { -+ WMT_WARN_FUNC("STP btif wakeup consys fail(%d)\n", iRet); -+ iRet = -2; -+ } else { -+ WMT_DBG_FUNC("STP btif wakeup consys ok\n"); -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ iRet = -1; -+ } else { -+ mtk_wcn_btif_dpidle_ctrl(stpBtifId, en_flag); -+ WMT_DBG_FUNC("stp btif dpidle ctrl done,en_flag(%d)\n", en_flag); -+ } -+ -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ iRet = -1; -+ } else { -+ iRet = mtk_wcn_btif_loopback_ctrl(stpBtifId, mode); -+ if (iRet) { -+ WMT_WARN_FUNC("STP btif lpbk ctrl fail(%d)\n", iRet); -+ iRet = -2; -+ } else { -+ WMT_INFO_FUNC("stp btif lpbk ctrl ok,mode(%d)\n", mode); -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_logger_ctrl(ENUM_BTIF_DBG_ID flag) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ iRet = -1; -+ } else { -+ iRet = mtk_wcn_btif_dbg_ctrl(stpBtifId, flag); -+ if (iRet) { -+ WMT_WARN_FUNC("STP btif log dbg ctrl fail(%d)\n", iRet); -+ iRet = -2; -+ } else { -+ WMT_INFO_FUNC("stp btif log dbg ctrl ok,flag(%d)\n", flag); -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_parser_wmt_evt(const UINT8 *str, UINT32 len) -+{ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ return -1; -+ } else { -+ return (INT32) mtk_wcn_btif_parser_wmt_evt(stpBtifId, str, len); -+ } -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c -new file mode 100644 -index 0000000000000..fdb610cc3897d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c -@@ -0,0 +1,2061 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+#include /* GFP_KERNEL */ -+#include /* init_timer, add_time, del_timer_sync */ -+#include /* gettimeofday */ -+#include -+#include /* kzalloc */ -+#include /* task's status */ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "osal_typedef.h" -+#include "stp_dbg.h" -+/* #include "stp_btm.h" */ -+#include "btm_core.h" -+#include "wmt_plat.h" -+ -+#define PFX_STP_DBG "[STPDbg]" -+#define STP_DBG_LOG_LOUD 4 -+#define STP_DBG_LOG_DBG 3 -+#define STP_DBG_LOG_INFO 2 -+#define STP_DBG_LOG_WARN 1 -+#define STP_DBG_LOG_ERR 0 -+ -+unsigned int gStpDbgDbgLevel = STP_DBG_LOG_INFO; -+unsigned int gStpDbgLogOut = 0; -+ -+#define STP_DBG_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_LOUD) \ -+ pr_debug(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_DBG_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_DBG) \ -+ pr_debug(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_DBG_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_INFO) \ -+ pr_debug(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_DBG_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_WARN) \ -+ pr_warn(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_DBG_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_ERR) \ -+ pr_err(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_DBG_TRC_FUNC(f) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_DBG) \ -+ pr_debug(PFX_STP_DBG "<%s> <%d>\n", __func__, __LINE__); \ -+} while (0) -+ -+MTKSTP_DBG_T *g_stp_dbg = NULL; -+ -+#define STP_DBG_FAMILY_NAME "STP_DBG" -+#define MAX_BIND_PROCESS (4) -+#ifdef WMT_PLAT_ALPS -+#define STP_DBG_AEE_EXP_API (1) -+#else -+#define STP_DBG_AEE_EXP_API (0) -+#endif -+enum { -+ __STP_DBG_ATTR_INVALID, -+ STP_DBG_ATTR_MSG, -+ __STP_DBG_ATTR_MAX, -+}; -+#define STP_DBG_ATTR_MAX (__STP_DBG_ATTR_MAX - 1) -+ -+enum { -+ __STP_DBG_COMMAND_INVALID, -+ STP_DBG_COMMAND_BIND, -+ STP_DBG_COMMAND_RESET, -+ __STP_DBG_COMMAND_MAX, -+}; -+#define MTK_WIFI_COMMAND_MAX (__STP_DBG_COMMAND_MAX - 1) -+ -+static struct genl_family stp_dbg_gnl_family = { -+ .id = GENL_ID_GENERATE, -+ .hdrsize = 0, -+ .name = STP_DBG_FAMILY_NAME, -+ .version = 1, -+ .maxattr = STP_DBG_ATTR_MAX, -+}; -+ -+static void stp_dbg_nl_init(void); -+static void stp_dbg_nl_deinit(void); -+static int stp_dbg_nl_bind(struct sk_buff *skb, struct genl_info *info); -+static int stp_dbg_nl_reset(struct sk_buff *skb, struct genl_info *info); -+ -+/* attribute policy */ -+static struct nla_policy stp_dbg_genl_policy[STP_DBG_ATTR_MAX + 1] = { -+ [STP_DBG_ATTR_MSG] = {.type = NLA_NUL_STRING}, -+}; -+ -+/* operation definition */ -+#if 0 -+static struct genl_ops stp_dbg_gnl_ops_bind = { -+ .cmd = STP_DBG_COMMAND_BIND, -+ .flags = 0, -+ .policy = stp_dbg_genl_policy, -+ .doit = stp_dbg_nl_bind, -+ .dumpit = NULL, -+}; -+ -+static struct genl_ops stp_dbg_gnl_ops_reset = { -+ .cmd = STP_DBG_COMMAND_RESET, -+ .flags = 0, -+ .policy = stp_dbg_genl_policy, -+ .doit = stp_dbg_nl_reset, -+ .dumpit = NULL, -+}; -+#endif -+static struct genl_ops stp_dbg_gnl_ops_array[] = { -+ { -+ .cmd = STP_DBG_COMMAND_BIND, -+ .flags = 0, -+ .policy = stp_dbg_genl_policy, -+ .doit = stp_dbg_nl_bind, -+ .dumpit = NULL, -+ }, -+ { -+ .cmd = STP_DBG_COMMAND_RESET, -+ .flags = 0, -+ .policy = stp_dbg_genl_policy, -+ .doit = stp_dbg_nl_reset, -+ .dumpit = NULL, -+ }, -+}; -+ -+#if 0 -+#define E2S(x) #x -+static char *dmaRegsStr[] = { -+ E2S(CONNSYS_CLK_GATE_STATUS), -+ E2S(CONSYS_EMI_STATUS), -+ E2S(SYSRAM1), -+ E2S(SYSRAM2), -+ E2S(SYSRAM3) -+}; -+#endif -+static unsigned int stp_dbg_seqnum; -+static int num_bind_process; -+static pid_t bind_pid[MAX_BIND_PROCESS]; -+ -+static P_WCN_CORE_DUMP_T g_core_dump; -+ -+static P_STP_DBG_CPUPCR_T g_stp_dbg_cpupcr; -+ -+/* just show in log at present */ -+static P_STP_DBG_DMAREGS_T g_stp_dbg_dmaregs; -+ -+/* core_dump_timeout_handler - handler of coredump timeout -+ * @ data - core dump object's pointer -+ * -+ * No return value -+ */ -+static void core_dump_timeout_handler(/*unsigned long data*/struct timer_list *t) -+{ -+ //P_WCN_CORE_DUMP_T dmp = (P_WCN_CORE_DUMP_T) data; -+ P_WCN_CORE_DUMP_T dmp = from_timer(dmp,t,dmp_timer.timer); -+ -+ STP_DBG_INFO_FUNC(" start\n"); -+ -+ stp_btm_notify_coredump_timeout_wq(g_stp_dbg->btm); -+ -+ STP_DBG_INFO_FUNC(" end\n"); -+ -+ if (dmp) -+ dmp->sm = CORE_DUMP_TIMEOUT; -+} -+ -+/* wcn_core_dump_init - create core dump sys -+ * @ timeout - core dump time out value -+ * -+ * Return object pointer if success, else NULL -+ */ -+P_WCN_CORE_DUMP_T wcn_core_dump_init(UINT32 packet_num, UINT32 timeout) -+{ -+#define KBYTES (1024*sizeof(char)) -+#define L1_BUF_SIZE (32*KBYTES) -+ -+ P_WCN_CORE_DUMP_T core_dmp = NULL; -+ -+ core_dmp = (P_WCN_CORE_DUMP_T) osal_malloc(sizeof(WCN_CORE_DUMP_T)); -+ if (!core_dmp) { -+ STP_DBG_ERR_FUNC("alloc mem failed!\n"); -+ goto fail; -+ } -+ -+ osal_memset(core_dmp, 0, sizeof(WCN_CORE_DUMP_T)); -+ -+ core_dmp->compressor = wcn_compressor_init("core_dump_compressor", L1_BUF_SIZE, 18*packet_num*KBYTES); -+ if (!core_dmp->compressor) { -+ STP_DBG_ERR_FUNC("create compressor failed!\n"); -+ goto fail; -+ } -+ wcn_compressor_reset(core_dmp->compressor, 1, GZIP); -+ -+ core_dmp->dmp_timer.timeoutHandler = core_dump_timeout_handler; -+ core_dmp->dmp_timer.timeroutHandlerData = (unsigned long)core_dmp; -+ osal_timer_create(&core_dmp->dmp_timer); -+ core_dmp->timeout = timeout; -+ -+ osal_sleepable_lock_init(&core_dmp->dmp_lock); -+ -+ core_dmp->sm = CORE_DUMP_INIT; -+ STP_DBG_INFO_FUNC("create coredump object OK!\n"); -+ -+ return core_dmp; -+ -+fail: -+ if (core_dmp && core_dmp->compressor) { -+ wcn_compressor_deinit(core_dmp->compressor); -+ core_dmp->compressor = NULL; -+ } -+ if (core_dmp) -+ osal_free(core_dmp); -+ -+ return NULL; -+} -+INT32 wcn_core_dump_init_gcoredump(UINT32 packet_num, UINT32 timeout) -+{ -+ INT32 Ret = 0; -+ -+ g_core_dump = wcn_core_dump_init(packet_num, timeout); -+ if (g_core_dump == NULL) -+ Ret = -1; -+ return Ret; -+} -+ -+/* wcn_core_dump_deinit - destroy core dump object -+ * @ dmp - pointer of object -+ * -+ * Retunr 0 if success, else error code -+ */ -+INT32 wcn_core_dump_deinit(P_WCN_CORE_DUMP_T dmp) -+{ -+ if (dmp && dmp->compressor) { -+ wcn_compressor_deinit(dmp->compressor); -+ dmp->compressor = NULL; -+ } -+ -+ if (dmp) { -+ osal_sleepable_lock_deinit(&dmp->dmp_lock); -+ osal_timer_stop(&dmp->dmp_timer); -+ osal_free(dmp); -+ } -+ -+ return 0; -+} -+ -+INT32 wcn_core_dump_deinit_gcoredump(VOID) -+{ -+ wcn_core_dump_deinit(g_core_dump); -+ return 0; -+} -+ -+static INT32 wcn_core_dump_check_end(PUINT8 buf, INT32 len) -+{ -+ if (strnstr(buf, "coredump end", len)) -+ return 1; -+ else -+ return 0; -+} -+ -+/* wcn_core_dump_in - add a packet to compressor buffer -+ * @ dmp - pointer of object -+ * @ buf - input buffer -+ * @ len - data length -+ * -+ * Retunr 0 if success; return 1 if find end string; else error code -+ */ -+INT32 wcn_core_dump_in(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len) -+{ -+ INT32 ret = 0; -+ INT32 tmp; -+ -+#define INFO_HEAD ";SOC_CONSYS FW CORE, " -+ -+ if ((!dmp) || (!buf)) { -+ STP_DBG_ERR_FUNC("invalid pointer!\n"); -+ return -1; -+ } -+ -+ ret = osal_lock_sleepable_lock(&dmp->dmp_lock); -+ if (ret) { -+ STP_DBG_ERR_FUNC("--->lock dmp->dmp_lock failed, ret=%d\n", ret); -+ return ret; -+ } -+ -+ switch (dmp->sm) { -+ case CORE_DUMP_INIT: -+ wcn_compressor_reset(dmp->compressor, 1, GZIP); -+ osal_timer_start(&dmp->dmp_timer, STP_CORE_DUMP_TIMEOUT); -+ -+ /* first package, copy to info buffer */ -+ osal_strcpy(&dmp->info[0], INFO_HEAD); -+ -+ if (NULL == (strnstr(buf, "", 32))) { -+ osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], "Fw warm reset exception...", -+ osal_strlen("Fw warm reset exception...")); -+ dmp->info[osal_strlen(INFO_HEAD) + osal_strlen("Fw warm reset exception...") + 1] = '\0'; -+ } else { -+ char *pStr = buf; -+ char *pDtr = NULL; -+ -+ pDtr = osal_strchr(pStr, '-'); -+ if (NULL != pDtr) { -+ tmp = pDtr - pStr; -+ osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], buf, tmp); -+ dmp->info[osal_strlen(dmp->info) + 1] = '\0'; -+ } else { -+ tmp = STP_CORE_DUMP_INFO_SZ - osal_strlen(INFO_HEAD); -+ tmp = (len > tmp) ? tmp : len; -+ osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], buf, tmp); -+ dmp->info[STP_CORE_DUMP_INFO_SZ] = '\0'; -+ } -+ -+ } -+ /* show coredump start info on UI */ -+ /* osal_dbg_assert_aee("MT662x f/w coredump start", "MT662x firmware coredump start"); */ -+#if STP_DBG_AEE_EXP_API -+ aee_kernel_dal_show("SOC_CONSYS coredump start ....\n"); -+#endif -+ /* parsing data, and check end srting */ -+ ret = wcn_core_dump_check_end(buf, len); -+ if (ret == 1) { -+ STP_DBG_INFO_FUNC("core dump end!\n"); -+ dmp->sm = CORE_DUMP_DONE; -+ wcn_compressor_in(dmp->compressor, buf, len, 0); -+ } else { -+ dmp->sm = CORE_DUMP_DOING; -+ wcn_compressor_in(dmp->compressor, buf, len, 0); -+ } -+ break; -+ -+ case CORE_DUMP_DOING: -+ /* parsing data, and check end srting */ -+ ret = wcn_core_dump_check_end(buf, len); -+ if (ret == 1) { -+ STP_DBG_INFO_FUNC("core dump end!\n"); -+ dmp->sm = CORE_DUMP_DONE; -+ wcn_compressor_in(dmp->compressor, buf, len, 0); -+ } else { -+ dmp->sm = CORE_DUMP_DOING; -+ wcn_compressor_in(dmp->compressor, buf, len, 0); -+ } -+ break; -+ -+ case CORE_DUMP_DONE: -+ wcn_compressor_reset(dmp->compressor, 1, GZIP); -+ osal_timer_start(&dmp->dmp_timer, STP_CORE_DUMP_TIMEOUT); -+ wcn_compressor_in(dmp->compressor, buf, len, 0); -+ dmp->sm = CORE_DUMP_DOING; -+ break; -+ -+ case CORE_DUMP_TIMEOUT: -+ break; -+ default: -+ break; -+ } -+ -+ osal_unlock_sleepable_lock(&dmp->dmp_lock); -+ -+ return ret; -+} -+ -+/* wcn_core_dump_out - get compressed data from compressor buffer -+ * @ dmp - pointer of object -+ * @ pbuf - target buffer's pointer -+ * @ len - data length -+ * -+ * Retunr 0 if success; else error code -+ */ -+INT32 wcn_core_dump_out(P_WCN_CORE_DUMP_T dmp, PUINT8 *pbuf, PINT32 plen) -+{ -+ INT32 ret = 0; -+ -+ if ((!dmp) || (!pbuf) || (!plen)) { -+ STP_DBG_ERR_FUNC("invalid pointer!\n"); -+ return -1; -+ } -+ -+ ret = osal_lock_sleepable_lock(&dmp->dmp_lock); -+ if (ret) { -+ STP_DBG_ERR_FUNC("--->lock dmp->dmp_lock failed, ret=%d\n", ret); -+ return ret; -+ } -+ -+ ret = wcn_compressor_out(dmp->compressor, pbuf, plen); -+ -+ osal_unlock_sleepable_lock(&dmp->dmp_lock); -+ -+ return ret; -+} -+ -+/* wcn_core_dump_reset - reset core dump sys -+ * @ dmp - pointer of object -+ * @ timeout - core dump time out value -+ * -+ * Retunr 0 if success, else error code -+ */ -+INT32 wcn_core_dump_reset(P_WCN_CORE_DUMP_T dmp, UINT32 timeout) -+{ -+ if (!dmp) { -+ STP_DBG_ERR_FUNC("invalid pointer!\n"); -+ return -1; -+ } -+ -+ dmp->sm = CORE_DUMP_INIT; -+ dmp->timeout = timeout; -+ osal_timer_stop(&dmp->dmp_timer); -+ wcn_compressor_reset(dmp->compressor, 1, GZIP); -+ osal_memset(dmp->info, 0, STP_CORE_DUMP_INFO_SZ + 1); -+ -+ wcn_core_dump_deinit(dmp); -+ g_core_dump = wcn_core_dump_init(STP_CORE_DUMP_INIT_SIZE, STP_CORE_DUMP_TIMEOUT); -+ -+ return 0; -+} -+ -+/* wcn_wmtd_timeout_collect_ftrace - wmtd timeout ,this func can collect SYS_FTRACE -+ * -+ * Retunr 0 if success -+ */ -+#define WMTD_TIMEOUT_INFO_HEAD "Wait wmtd complation timeout ,just collect SYS_FTRACE to DB" -+INT32 wcn_wmtd_timeout_collect_ftrace(void) -+{ -+ PUINT8 pbuf; -+ INT32 len; -+ -+ pbuf = "Wait wmtd complation timeout"; -+ len = osal_strlen("Wait wmtd complation timeout"); -+ osal_strcpy(&g_core_dump->info[0], WMTD_TIMEOUT_INFO_HEAD); -+#ifdef WMT_PLAT_ALPS -+ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); -+#endif -+ return 0; -+} -+/* wcn_psm_flag_trigger_collect_ftrace - wmtd timeout ,this func can collect SYS_FTRACE -+ * -+ * Retunr 0 if success -+ */ -+#define PSM_ABNORMAL_FLAG_INFO_HEAD "Abnormal PSM flag be set ,just collect SYS_FTRACE to DB" -+INT32 wcn_psm_flag_trigger_collect_ftrace(void) -+{ -+ PUINT8 pbuf; -+ INT32 len; -+ -+ pbuf = "Abnormal PSM flag be set"; -+ len = osal_strlen("Abnormal PSM flag be set"); -+ osal_strcpy(&g_core_dump->info[0], PSM_ABNORMAL_FLAG_INFO_HEAD); -+#ifdef WMT_PLAT_ALPS -+ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); -+#endif -+ return 0; -+} -+#if BTIF_RXD_BE_BLOCKED_DETECT -+MTK_WCN_BOOL is_btif_rxd_be_blocked(void) -+{ -+ MTK_WCN_BOOL flag = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_btif_rxd_be_blocked_flag_get()) -+ flag = MTK_WCN_BOOL_TRUE; -+ return flag; -+} -+/* wcn_btif_rxd_blocked_collect_ftrace - btif rxd be blocked,this func can collect SYS_FTRACE -+ * -+ * Retunr 0 if success -+ */ -+#define BTIF_RXD_BLOCKED_INFO_HEAD "Btif_rxd thread be blocked too long,just collect SYS_FTRACE to DB" -+INT32 wcn_btif_rxd_blocked_collect_ftrace(void) -+{ -+ PUINT8 pbuf; -+ INT32 len; -+ -+ pbuf = "Btif_rxd thread be blocked too long"; -+ len = osal_strlen("Btif_rxd thread be blocked too long"); -+ osal_strcpy(&g_core_dump->info[0], BTIF_RXD_BLOCKED_INFO_HEAD); -+#ifdef WMT_PLAT_ALPS -+ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); -+#endif -+ return 0; -+} -+#endif -+/* wcn_core_dump_timeout - wait for FW assert info timeout ,this func can collect SYS_FTRACE -+ * -+ * Retunr 0 if success -+ */ -+#define TIMEOUT_INFO_HEAD "Trigger assert timeout ,just collect SYS_FTRACE to DB" -+INT32 wcn_core_dump_timeout(void) -+{ -+ PUINT8 pbuf; -+ INT32 len; -+ -+ pbuf = "Trigger assert timeout"; -+ len = osal_strlen("Trigger assert timeout"); -+ osal_strcpy(&g_core_dump->info[0], TIMEOUT_INFO_HEAD); -+#ifdef WMT_PLAT_ALPS -+ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); -+#endif -+ return 0; -+} -+ -+#define ENABLE_F_TRACE 0 -+/* wcn_core_dump_flush - Fulsh dump data and reset core dump sys -+ * -+ * Retunr 0 if success, else error code -+ */ -+INT32 wcn_core_dump_flush(INT32 rst, MTK_WCN_BOOL coredump_is_timeout) -+{ -+ PUINT8 pbuf = NULL; -+ INT32 len = 0; -+ -+ if (!g_core_dump) { -+ STP_DBG_ERR_FUNC("invalid pointer!\n"); -+ return -1; -+ } -+ -+ wcn_core_dump_out(g_core_dump, &pbuf, &len); -+ STP_DBG_INFO_FUNC("buf 0x%zx, len %d\n", (SIZE_T) pbuf, len); -+#ifdef WMT_PLAT_ALPS -+ /* show coredump end info on UI */ -+ /* osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends"); */ -+#if STP_DBG_AEE_EXP_API -+ if (coredump_is_timeout) -+ aee_kernel_dal_show("++ SOC_CONSYS coredump tiemout ,pass received coredump to AEE ++\n"); -+ else -+ aee_kernel_dal_show("++ SOC_CONSYS coredump get successfully ++\n"); -+ /* call AEE driver API */ -+#if ENABLE_F_TRACE -+ aed_combo_exception_api(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info, DB_OPT_FTRACE); -+#else -+ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); -+#endif -+ -+#endif -+ -+#endif // WMT_PLAT_ALPS -+ -+ /* reset */ -+ wcn_core_dump_reset(g_core_dump, STP_CORE_DUMP_TIMEOUT); -+ -+ return 0; -+} -+ -+static INT32 wcn_gzip_compressor(void *worker, UINT8 *in_buf, INT32 in_sz, UINT8 *out_buf, INT32 *out_sz, -+ INT32 finish) -+{ -+ INT32 ret = 0; -+ z_stream *stream = NULL; -+ INT32 tmp = *out_sz; -+ -+ STP_DBG_INFO_FUNC("need to compressor :buf 0x%zx, size %d\n", (SIZE_T) in_buf, in_sz); -+ STP_DBG_INFO_FUNC("before compressor,avalible buf: 0x%zx, size %d\n", (SIZE_T) out_buf, tmp); -+ -+ stream = (z_stream *) worker; -+ if (!stream) { -+ STP_DBG_ERR_FUNC("invalid workspace!\n"); -+ return -1; -+ } -+ -+ if (in_sz > 0) { -+#if 0 -+ ret = zlib_deflateReset(stream); -+ if (ret != Z_OK) { -+ STP_DBG_ERR_FUNC("reset failed!\n"); -+ return -2; -+ } -+#endif -+ -+ stream->next_in = in_buf; -+ stream->avail_in = in_sz; -+ stream->next_out = out_buf; -+ stream->avail_out = tmp; -+ -+ zlib_deflate(stream, Z_FULL_FLUSH); -+ -+ if (finish) { -+ while (1) { -+ int val = zlib_deflate(stream, Z_FINISH); -+ -+ if (val == Z_OK) -+ continue; -+ else if (val == Z_STREAM_END) -+ break; -+ STP_DBG_ERR_FUNC("finish operation failed %d\n", val); -+ return -3; -+ } -+ } -+ -+ *out_sz = tmp - stream->avail_out; -+ } -+ -+ STP_DBG_INFO_FUNC("after compressor,avalible buf: 0x%zx, compress rate %d -> %d\n", (SIZE_T) out_buf, in_sz, -+ *out_sz); -+ -+ return ret; -+} -+ -+/* wcn_compressor_init - create a compressor and do init -+ * @ name - compressor's name -+ * @ L1_buf_sz - L1 buffer size -+ * @ L2_buf_sz - L2 buffer size -+ * -+ * Retunr object's pointer if success, else NULL -+ */ -+P_WCN_COMPRESSOR_T wcn_compressor_init(PUINT8 name, INT32 L1_buf_sz, INT32 L2_buf_sz) -+{ -+ z_stream *pstream = NULL; -+ P_WCN_COMPRESSOR_T compress = NULL; -+ -+ compress = (P_WCN_COMPRESSOR_T) osal_malloc(sizeof(WCN_COMPRESSOR_T)); -+ if (!compress) { -+ STP_DBG_ERR_FUNC("alloc compressor failed!\n"); -+ goto fail; -+ } -+ -+ osal_memset(compress, 0, sizeof(WCN_COMPRESSOR_T)); -+ osal_memcpy(compress->name, name, STP_OJB_NAME_SZ); -+ -+ compress->f_compress_en = 0; -+ compress->compress_type = GZIP; -+ -+ if (compress->compress_type == GZIP) { -+ compress->worker = osal_malloc(sizeof(z_stream)); -+ if (!compress->worker) { -+ STP_DBG_ERR_FUNC("alloc stream failed!\n"); -+ goto fail; -+ } -+ pstream = (z_stream *) compress->worker; -+ -+ pstream->workspace = osal_malloc(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL)); -+ if (!pstream->workspace) { -+ STP_DBG_ERR_FUNC("alloc workspace failed!\n"); -+ goto fail; -+ } -+ zlib_deflateInit2(pstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, -+ DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); -+ } -+ -+ compress->handler = wcn_gzip_compressor; -+ compress->L1_buf_sz = L1_buf_sz; -+ compress->L2_buf_sz = L2_buf_sz; -+ compress->L1_pos = 0; -+ compress->L2_pos = 0; -+ compress->uncomp_size = 0; -+ compress->crc32 = 0xffffffffUL; -+ -+ compress->L1_buf = osal_malloc(compress->L1_buf_sz); -+ if (!compress->L1_buf) { -+ STP_DBG_ERR_FUNC("alloc %d bytes for L1 buf failed!\n", compress->L1_buf_sz); -+ goto fail; -+ } -+ -+ compress->L2_buf = osal_malloc(compress->L2_buf_sz); -+ if (!compress->L2_buf) { -+ STP_DBG_ERR_FUNC("alloc %d bytes for L2 buf failed!\n", compress->L2_buf_sz); -+ goto fail; -+ } -+ -+ STP_DBG_INFO_FUNC("create compressor OK! L1 %d bytes, L2 %d bytes\n", L1_buf_sz, L2_buf_sz); -+ return compress; -+ -+fail: -+ if (compress) { -+ if (compress->L2_buf) { -+ osal_free(compress->L2_buf); -+ compress->L2_buf = NULL; -+ } -+ -+ if (compress->L1_buf) { -+ osal_free(compress->L1_buf); -+ compress->L1_buf = NULL; -+ } -+ -+ if (compress->worker) { -+ pstream = (z_stream *) compress->worker; -+ if ((compress->compress_type == GZIP) && pstream->workspace) { -+ zlib_deflateEnd(pstream); -+ osal_free(pstream->workspace); -+ } -+ osal_free(compress->worker); -+ compress->worker = NULL; -+ } -+ -+ if (compress->worker) { -+ osal_free(compress->worker); -+ compress->worker = NULL; -+ } -+ -+ osal_free(compress); -+ compress = NULL; -+ } -+ -+ STP_DBG_ERR_FUNC("init failed!\n"); -+ -+ return NULL; -+} -+ -+/* wcn_compressor_deinit - distroy a compressor -+ * @ cprs - compressor's pointer -+ * -+ * Retunr 0 if success, else NULL -+ */ -+INT32 wcn_compressor_deinit(P_WCN_COMPRESSOR_T cprs) -+{ -+ z_stream *pstream = NULL; -+ -+ if (cprs) { -+ if (cprs->L2_buf) { -+ osal_free(cprs->L2_buf); -+ cprs->L2_buf = NULL; -+ } -+ -+ if (cprs->L1_buf) { -+ osal_free(cprs->L1_buf); -+ cprs->L1_buf = NULL; -+ } -+ -+ if (cprs->worker) { -+ pstream = (z_stream *) cprs->worker; -+ if ((cprs->compress_type == GZIP) && pstream->workspace) { -+ zlib_deflateEnd(pstream); -+ osal_free(pstream->workspace); -+ } -+ osal_free(cprs->worker); -+ cprs->worker = NULL; -+ } -+ -+ cprs->handler = NULL; -+ -+ osal_free(cprs); -+ } -+ -+ STP_DBG_INFO_FUNC("destroy OK\n"); -+ -+ return 0; -+} -+ -+/* wcn_compressor_in - put in a raw data, and compress L1 buffer if need -+ * @ cprs - compressor's pointer -+ * @ buf - raw data buffer -+ * @ len - raw data length -+ * @ finish - core dump finish or not, 1: finished; 0: not finish -+ * -+ * Retunr 0 if success, else NULL -+ */ -+INT32 wcn_compressor_in(P_WCN_COMPRESSOR_T cprs, PUINT8 buf, INT32 len, INT32 finish) -+{ -+ INT32 tmp_len = 0; -+ INT32 ret = 0; -+ -+ if (!cprs) { -+ STP_DBG_ERR_FUNC("invalid para!\n"); -+ return -1; -+ } -+ -+ cprs->uncomp_size += len; -+ -+ /* check L1 buf valid space */ -+ if (len > (cprs->L1_buf_sz - cprs->L1_pos)) { -+ STP_DBG_INFO_FUNC("L1 buffer full\n"); -+ -+ if (cprs->f_compress_en && cprs->handler) { -+ /* need compress */ -+ /* compress L1 buffer, and put result to L2 buffer */ -+ tmp_len = cprs->L2_buf_sz - cprs->L2_pos; -+ ret = -+ cprs->handler(cprs->worker, cprs->L1_buf, cprs->L1_pos, &cprs->L2_buf[cprs->L2_pos], -+ &tmp_len, finish); -+ if (!ret) { -+ cprs->crc32 = (crc32(cprs->crc32, cprs->L1_buf, cprs->L1_pos)); -+ cprs->L2_pos += tmp_len; -+ if (cprs->L2_pos > cprs->L2_buf_sz) -+ STP_DBG_ERR_FUNC("coredump size too large(%d), L2 buf overflow\n", -+ cprs->L2_pos); -+ -+ if (finish) { -+ /* Add 8 byte suffix -+ === -+ 32 bits UNCOMPRESS SIZE -+ 32 bits CRC -+ */ -+ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos]) = (cprs->crc32 ^ 0xffffffffUL); -+ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos + 4]) = cprs->uncomp_size; -+ cprs->L2_pos += 8; -+ } -+ STP_DBG_INFO_FUNC("compress OK!\n"); -+ } else -+ STP_DBG_ERR_FUNC("compress error!\n"); -+ } else { -+ /* no need compress */ -+ /* Flush L1 buffer to L2 buffer */ -+ STP_DBG_INFO_FUNC("No need do compress, Put to L2 buf\n"); -+ -+ tmp_len = cprs->L2_buf_sz - cprs->L2_pos; -+ tmp_len = (cprs->L1_pos > tmp_len) ? tmp_len : cprs->L1_pos; -+ osal_memcpy(&cprs->L2_buf[cprs->L2_pos], cprs->L1_buf, tmp_len); -+ cprs->L2_pos += tmp_len; -+ } -+ -+ /* reset L1 buf pos */ -+ cprs->L1_pos = 0; -+ -+ /* put curren data to L1 buf */ -+ if (len > cprs->L1_buf_sz) { -+ STP_DBG_ERR_FUNC("len=%d, too long err!\n", len); -+ } else { -+ STP_DBG_INFO_FUNC("L1 Flushed, and Put %d bytes to L1 buf\n", len); -+ osal_memcpy(&cprs->L1_buf[cprs->L1_pos], buf, len); -+ cprs->L1_pos += len; -+ } -+ } else { -+ /* put to L1 buffer */ -+ STP_DBG_INFO_FUNC("Put %d bytes to L1 buf\n", len); -+ -+ osal_memcpy(&cprs->L1_buf[cprs->L1_pos], buf, len); -+ cprs->L1_pos += len; -+ } -+ -+ return ret; -+} -+ -+/* wcn_compressor_out - get the result data from L2 buffer -+ * @ cprs - compressor's pointer -+ * @ pbuf - point to L2 buffer -+ * @ plen - out len -+ * -+ * Retunr 0 if success, else NULL -+ */ -+INT32 wcn_compressor_out(P_WCN_COMPRESSOR_T cprs, PUINT8 *pbuf, PINT32 plen) -+{ -+ INT32 ret = 0; -+ INT32 tmp_len = 0; -+ -+ if ((!cprs) || (!pbuf) || (!plen)) { -+ STP_DBG_ERR_FUNC("invalid para!\n"); -+ return -1; -+ } -+ /* check if there's L1 data need flush to L2 buffer */ -+ if (cprs->L1_pos > 0) { -+ tmp_len = cprs->L2_buf_sz - cprs->L2_pos; -+ -+ if (cprs->f_compress_en && cprs->handler) { -+ /* need compress */ -+ ret = -+ cprs->handler(cprs->worker, cprs->L1_buf, cprs->L1_pos, &cprs->L2_buf[cprs->L2_pos], -+ &tmp_len, 1); -+ -+ if (!ret) { -+ cprs->crc32 = (crc32(cprs->crc32, cprs->L1_buf, cprs->L1_pos)); -+ cprs->L2_pos += tmp_len; -+ -+ /* Add 8 byte suffix -+ === -+ 32 bits UNCOMPRESS SIZE -+ 32 bits CRC -+ */ -+ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos]) = (cprs->crc32 ^ 0xffffffffUL); -+ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos + 4]) = cprs->uncomp_size; -+ cprs->L2_pos += 8; -+ -+ STP_DBG_INFO_FUNC("compress OK!\n"); -+ } else { -+ STP_DBG_ERR_FUNC("compress error!\n"); -+ } -+ } else { -+ /* no need compress */ -+ tmp_len = (cprs->L1_pos > tmp_len) ? tmp_len : cprs->L1_pos; -+ osal_memcpy(&cprs->L2_buf[cprs->L2_pos], cprs->L1_buf, tmp_len); -+ cprs->L2_pos += tmp_len; -+ } -+ -+ cprs->L1_pos = 0; -+ } -+ -+ *pbuf = cprs->L2_buf; -+ *plen = cprs->L2_pos; -+ -+ STP_DBG_INFO_FUNC("0x%zx, len %d\n", (SIZE_T)*pbuf, *plen); -+ -+ return 0; -+} -+ -+/* wcn_compressor_reset - reset compressor -+ * @ cprs - compressor's pointer -+ * @ enable - enable/disable compress -+ * @ type - compress algorithm -+ * -+ * Retunr 0 if success, else NULL -+ */ -+INT32 wcn_compressor_reset(P_WCN_COMPRESSOR_T cprs, UINT8 enable, WCN_COMPRESS_ALG_T type) -+{ -+ if (!cprs) { -+ STP_DBG_ERR_FUNC("invalid para!\n"); -+ return -1; -+ } -+ -+ cprs->f_compress_en = enable; -+ /* cprs->f_compress_en = 0; // disable compress for test */ -+ cprs->compress_type = type; -+ cprs->L1_pos = 0; -+ cprs->L2_pos = 0; -+ cprs->uncomp_size = 0; -+ cprs->crc32 = 0xffffffffUL; -+ -+ /* zlib_deflateEnd((z_stream*)cprs->worker); */ -+ -+ STP_DBG_INFO_FUNC("OK! compress algorithm %d\n", type); -+ -+ return 0; -+} -+ -+static void stp_dbg_dump_data(unsigned char *pBuf, char *title, int len) -+{ -+ int k = 0; -+ -+ pr_debug(" %s-len:%d\n", title, len); -+ -+ for (k = 0; k < len; k++) { -+ if (k % 16 == 0 && k != 0) -+ pr_cont("\n "); -+ pr_cont("0x%02x ", pBuf[k]); -+ } -+ pr_debug("--end\n"); -+} -+ -+static int _stp_dbg_enable(MTKSTP_DBG_T *stp_dbg) -+{ -+ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); -+ stp_dbg->pkt_trace_no = 0; -+ stp_dbg->is_enable = 1; -+ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); -+ -+ return 0; -+} -+ -+static int _stp_dbg_disable(MTKSTP_DBG_T *stp_dbg) -+{ -+ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); -+ stp_dbg->pkt_trace_no = 0; -+ memset(stp_dbg->logsys, 0, sizeof(MTKSTP_LOG_SYS_T)); -+ stp_dbg->is_enable = 0; -+ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); -+ -+ return 0; -+} -+ -+static int _stp_dbg_dmp_in(MTKSTP_DBG_T *stp_dbg, char *buf, int len) -+{ -+ unsigned long flags; -+ STP_DBG_HDR_T *pHdr = NULL; -+ char *pBuf = NULL; -+ unsigned int length = 0; -+ unsigned int internalFlag = stp_dbg->logsys->size < STP_DBG_LOG_ENTRY_NUM; -+ /* #ifdef CONFIG_LOG_STP_INTERNAL */ -+ /* Here we record log in this circle buffer, if buffer is full , -+ select to overlap earlier log, logic should be okay */ -+ internalFlag = 1; -+ /* #endif */ -+ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); -+ -+ if (internalFlag) { -+ stp_dbg->logsys->queue[stp_dbg->logsys->in].id = 0; -+ stp_dbg->logsys->queue[stp_dbg->logsys->in].len = len; -+ memset(&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]), -+ 0, ((len >= STP_DBG_LOG_ENTRY_SZ) ? (STP_DBG_LOG_ENTRY_SZ) : (len))); -+ memcpy(&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]), -+ buf, ((len >= STP_DBG_LOG_ENTRY_SZ) ? (STP_DBG_LOG_ENTRY_SZ) : (len))); -+ -+ stp_dbg->logsys->size++; -+ stp_dbg->logsys->size = -+ (stp_dbg->logsys->size > STP_DBG_LOG_ENTRY_NUM) ? STP_DBG_LOG_ENTRY_NUM : stp_dbg->logsys->size; -+ -+ if (0 != gStpDbgLogOut) { -+ pHdr = (STP_DBG_HDR_T *) &(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]); -+ pBuf = (char *)&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]) + sizeof(STP_DBG_HDR_T); -+ length = stp_dbg->logsys->queue[stp_dbg->logsys->in].len - sizeof(STP_DBG_HDR_T); -+ pr_debug("STP-DBG:%d.%ds, %s:pT%sn(%d)l(%d)s(%d)a(%d)\n", -+ pHdr->sec, -+ pHdr->usec, -+ pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", -+ gStpDbgType[pHdr->type], pHdr->no, pHdr->len, pHdr->seq, pHdr->ack); -+ if (0 < length) -+ stp_dbg_dump_data(pBuf, pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", length); -+ } -+ stp_dbg->logsys->in = -+ (stp_dbg->logsys->in >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (stp_dbg->logsys->in + 1); -+ STP_DBG_DBG_FUNC("logsys size = %d, in = %d\n", stp_dbg->logsys->size, stp_dbg->logsys->in); -+ } else { -+ STP_DBG_WARN_FUNC("logsys FULL!\n"); -+ } -+ -+ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); -+ -+ return 0; -+} -+ -+int stp_gdb_notify_btm_dmp_wq(MTKSTP_DBG_T *stp_dbg) -+{ -+ int retval = 0; -+/* #ifndef CONFIG_LOG_STP_INTERNAL */ -+ -+ if (stp_dbg->btm != NULL) -+ retval += stp_btm_notify_wmt_dmp_wq((MTKSTP_BTM_T *) stp_dbg->btm); -+/* #endif */ -+ -+ return retval; -+} -+ -+int stp_dbg_log_ctrl(unsigned int on) -+{ -+ if (on != 0) { -+ gStpDbgLogOut = 1; -+ pr_debug("STP-DBG: enable pkt log dump out.\n"); -+ } else { -+ gStpDbgLogOut = 0; -+ pr_debug("STP-DBG: disable pkt log dump out.\n"); -+ } -+ return 0; -+} -+ -+int stp_dbg_dmp_in(MTKSTP_DBG_T *stp_dbg, char *buf, int len) -+{ -+ return _stp_dbg_dmp_in(stp_dbg, buf, len); -+} -+ -+int stp_dbg_dmp_printk(MTKSTP_DBG_T *stp_dbg) -+{ -+#define MAX_DMP_NUM 80 -+ unsigned long flags; -+ char *pBuf = NULL; -+ int len = 0; -+ STP_DBG_HDR_T *pHdr = NULL; -+ UINT32 dumpSize = 0; -+ UINT32 inIndex = 0; -+ UINT32 outIndex = 0; -+ -+ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); -+ /* Not to dequeue from loging system */ -+ inIndex = stp_dbg->logsys->in; -+ dumpSize = stp_dbg->logsys->size; -+ if (STP_DBG_LOG_ENTRY_NUM == dumpSize) -+ outIndex = inIndex; -+ else -+ outIndex = ((inIndex + STP_DBG_LOG_ENTRY_NUM) - dumpSize) % STP_DBG_LOG_ENTRY_NUM; -+ -+ if (dumpSize > MAX_DMP_NUM) { -+ -+ outIndex += (dumpSize - MAX_DMP_NUM); -+ outIndex %= STP_DBG_LOG_ENTRY_NUM; -+ dumpSize = MAX_DMP_NUM; -+ -+ } -+ STP_DBG_INFO_FUNC("loged packet size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); -+ while (dumpSize > 0) { -+ pHdr = (STP_DBG_HDR_T *) &(stp_dbg->logsys->queue[outIndex].buffer[0]); -+ pBuf = &(stp_dbg->logsys->queue[outIndex].buffer[0]) + sizeof(STP_DBG_HDR_T); -+ len = stp_dbg->logsys->queue[outIndex].len - sizeof(STP_DBG_HDR_T); -+ len = len > STP_PKT_SZ ? STP_PKT_SZ : len; -+ pr_debug("STP-DBG:%d.%ds, %s:pT%sn(%d)l(%d)s(%d)a(%d)\n", -+ pHdr->sec, -+ pHdr->usec, -+ pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", -+ gStpDbgType[pHdr->type], pHdr->no, pHdr->len, pHdr->seq, pHdr->ack); -+ -+ if (0 < len) -+ stp_dbg_dump_data(pBuf, pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", len); -+ outIndex = (outIndex >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (outIndex + 1); -+ dumpSize--; -+ -+ } -+ -+ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); -+ -+ return 0; -+} -+ -+int stp_dbg_dmp_out_ex(char *buf, int *len) -+{ -+ return stp_dbg_dmp_out(g_stp_dbg, buf, len); -+} -+ -+int stp_dbg_dmp_out(MTKSTP_DBG_T *stp_dbg, char *buf, int *len) -+{ -+ -+ unsigned long flags; -+ int remaining = 0; -+ *len = 0; -+ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); -+ -+ if (stp_dbg->logsys->size > 0) { -+ memcpy(buf, &(stp_dbg->logsys->queue[stp_dbg->logsys->out].buffer[0]), -+ stp_dbg->logsys->queue[stp_dbg->logsys->out].len); -+ -+ (*len) = stp_dbg->logsys->queue[stp_dbg->logsys->out].len; -+ stp_dbg->logsys->out = -+ (stp_dbg->logsys->out >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (stp_dbg->logsys->out + 1); -+ stp_dbg->logsys->size--; -+ -+ STP_DBG_DBG_FUNC("logsys size = %d, out = %d\n", stp_dbg->logsys->size, stp_dbg->logsys->out); -+ } else { -+ STP_DBG_LOUD_FUNC("logsys EMPTY!\n"); -+ } -+ -+ remaining = (stp_dbg->logsys->size == 0) ? (0) : (1); -+ -+ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); -+ -+ return remaining; -+} -+ -+static int stp_dbg_fill_hdr(struct stp_dbg_pkt_hdr *hdr, int type, int ack, int seq, int crc, int dir, int len, -+ int dbg_type) -+{ -+ -+ struct timeval now; -+ -+ if (!hdr) { -+ STP_DBG_ERR_FUNC("function invalid\n"); -+ return -EINVAL; -+ } -+ do_gettimeofday(&now); -+ hdr->dbg_type = dbg_type; -+ hdr->ack = ack; -+ hdr->seq = seq; -+ hdr->sec = now.tv_sec; -+ hdr->usec = now.tv_usec; -+ hdr->crc = crc; -+ hdr->dir = dir; /* rx */ -+ hdr->dmy = 0xffffffff; -+ hdr->len = len; -+ hdr->type = type; -+ return 0; -+ -+} -+ -+static int stp_dbg_add_pkt(MTKSTP_DBG_T *stp_dbg, struct stp_dbg_pkt_hdr *hdr, const unsigned char *body) -+{ -+ /* fix the frame size large issues. */ -+ static struct stp_dbg_pkt stp_pkt; -+ uint32_t hdr_sz = sizeof(struct stp_dbg_pkt_hdr); -+ uint32_t body_sz = 0; -+ -+ BUG_ON(!stp_dbg); -+ -+ if (hdr->dbg_type == STP_DBG_PKT) -+ body_sz = (hdr->len <= STP_PKT_SZ) ? (hdr->len) : (STP_PKT_SZ); -+ else -+ body_sz = (hdr->len <= STP_DMP_SZ) ? (hdr->len) : (STP_DMP_SZ); -+ -+ hdr->no = stp_dbg->pkt_trace_no++; -+ memcpy((uint8_t *) &stp_pkt.hdr, (uint8_t *) hdr, hdr_sz); -+ if (body != NULL) -+ memcpy((uint8_t *) &stp_pkt.raw[0], body, body_sz); -+ -+ _stp_dbg_dmp_in(stp_dbg, (char *)&stp_pkt, hdr_sz + body_sz); -+ /* Only FW DMP MSG should inform BTM-CORE to dump packet to native process */ -+ if (hdr->dbg_type == STP_DBG_FW_DMP) -+ stp_gdb_notify_btm_dmp_wq(stp_dbg); -+ -+ return 0; -+} -+ -+int stp_dbg_log_pkt(MTKSTP_DBG_T *stp_dbg, int dbg_type, -+ int type, int ack_no, int seq_no, int crc, int dir, int len, const unsigned char *body) -+{ -+ -+ struct stp_dbg_pkt_hdr hdr; -+ -+ if (stp_dbg->is_enable == 0) { -+ /*dbg is disable,and not to log */ -+ } else { -+ hdr.no = 0; -+ hdr.chs = 0; -+ stp_dbg_fill_hdr(&hdr, -+ (int)type, (int)ack_no, (int)seq_no, (int)crc, (int)dir, (int)len, (int)dbg_type); -+ -+ stp_dbg_add_pkt(stp_dbg, &hdr, body); -+ } -+ -+ return 0; -+} -+ -+int stp_dbg_enable(MTKSTP_DBG_T *stp_dbg) -+{ -+ return _stp_dbg_enable(stp_dbg); -+} -+ -+int stp_dbg_disable(MTKSTP_DBG_T *stp_dbg) -+{ -+ return _stp_dbg_disable(stp_dbg); -+} -+ -+static void stp_dbg_nl_init(void) -+{ -+#if 0 -+ if (genl_register_family(&stp_dbg_gnl_family) != 0) { -+ STP_DBG_ERR_FUNC("%s(): GE_NELINK family registration fail\n", __func__); -+ } else { -+ if (genl_register_ops(&stp_dbg_gnl_family, &stp_dbg_gnl_ops_bind) != 0) -+ STP_DBG_ERR_FUNC("%s(): BIND operation registration fail\n", __func__); -+ -+ if (genl_register_ops(&stp_dbg_gnl_family, &stp_dbg_gnl_ops_reset) != 0) -+ STP_DBG_ERR_FUNC("%s(): RESET operation registration fail\n", __func__); -+ -+ } -+#endif -+ if (genl_register_family_with_ops(&stp_dbg_gnl_family, stp_dbg_gnl_ops_array) != 0) -+ STP_DBG_ERR_FUNC("%s(): GE_NELINK family registration fail\n", __func__); -+} -+ -+static void stp_dbg_nl_deinit(void) -+{ -+ genl_unregister_family(&stp_dbg_gnl_family); -+} -+ -+static int stp_dbg_nl_bind(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr *na; -+ char *mydata; -+ -+ if (info == NULL) -+ goto out; -+ -+ STP_DBG_INFO_FUNC("%s():->\n", __func__); -+ -+ na = info->attrs[STP_DBG_ATTR_MSG]; -+ -+ if (na) -+ mydata = (char *)nla_data(na); -+ -+ if (num_bind_process < MAX_BIND_PROCESS) { -+ bind_pid[num_bind_process] = info->snd_portid; -+ num_bind_process++; -+ STP_DBG_INFO_FUNC("%s():-> pid = %d\n", __func__, info->snd_portid); -+ } else { -+ STP_DBG_ERR_FUNC("%s(): exceeding binding limit %d\n", __func__, MAX_BIND_PROCESS); -+ } -+ -+out: -+ return 0; -+} -+ -+static int stp_dbg_nl_reset(struct sk_buff *skb, struct genl_info *info) -+{ -+ STP_DBG_ERR_FUNC("%s(): should not be invoked\n", __func__); -+ -+ return 0; -+} -+ -+INT8 stp_dbg_nl_send(PINT8 aucMsg, UINT8 cmd, INT32 len) -+{ -+ struct sk_buff *skb = NULL; -+ void *msg_head = NULL; -+ int rc = -1; -+ int i; -+ -+ if (num_bind_process == 0) { -+ /* no listening process */ -+ STP_DBG_ERR_FUNC("%s(): the process is not invoked\n", __func__); -+ return 0; -+ } -+ -+ for (i = 0; i < num_bind_process; i++) { -+ skb = genlmsg_new(2048, GFP_KERNEL); -+ -+ if (skb) { -+ msg_head = genlmsg_put(skb, 0, stp_dbg_seqnum++, &stp_dbg_gnl_family, 0, cmd); -+ if (msg_head == NULL) { -+ nlmsg_free(skb); -+ STP_DBG_ERR_FUNC("%s(): genlmsg_put fail...\n", __func__); -+ return -1; -+ } -+ -+ rc = nla_put(skb, STP_DBG_ATTR_MSG, len, aucMsg); -+ if (rc != 0) { -+ nlmsg_free(skb); -+ STP_DBG_ERR_FUNC("%s(): nla_put_string fail...%d\n", __func__, rc); -+ return -1; -+ } -+ -+ /* finalize the message */ -+ genlmsg_end(skb, msg_head); -+ -+ /* sending message */ -+ rc = genlmsg_unicast(&init_net, skb, bind_pid[i]); -+ if (rc != 0) { -+ STP_DBG_ERR_FUNC("%s(): genlmsg_unicast fail...\n", __func__); -+ return -1; -+ } -+ } else { -+ STP_DBG_ERR_FUNC("%s(): genlmsg_new fail...\n", __func__); -+ return -1; -+ } -+ } -+ -+ return 0; -+} -+ -+INT32 stp_dbg_aee_send(unsigned char *aucMsg, INT32 len, INT32 cmd) -+{ -+ INT32 ret = 0; -+ -+ /* buffered to compressor */ -+ ret = wcn_core_dump_in(g_core_dump, aucMsg, len); -+ if (ret == 1) -+ wcn_core_dump_flush(0, MTK_WCN_BOOL_FALSE); -+ -+ return ret; -+} -+ -+UINT8 *_stp_dbg_id_to_task(UINT32 id) -+{ -+ UINT8 *taskStr[] = { -+ "Task_WMT", -+ "Task_BT", -+ "Task_Wifi", -+ "Task_Tst", -+ "Task_FM", -+ "Task_Idle", -+ "Task_DrvStp", -+ "Task_DrvBtif", -+ "Task_NatBt" -+ }; -+ return taskStr[id]; -+} -+ -+INT32 _stp_dbg_parser_assert_str(PINT8 str, ENUM_ASSERT_INFO_PARSER_TYPE type) -+{ -+ char *pStr = NULL; -+ char *pDtr = NULL; -+ char *pTemp = NULL; -+ char *pTemp2 = NULL; -+ char tempBuf[64] = { 0 }; -+ UINT32 len = 0; -+ long res; -+ INT32 ret; -+ -+ PUINT8 parser_sub_string[] = { -+ " ", -+ "id=", -+ "isr=", -+ "irq=", -+ "rc=" -+ }; -+ -+ if (!str) { -+ STP_DBG_ERR_FUNC("NULL string source\n"); -+ return -1; -+ } -+ -+ if (!g_stp_dbg_cpupcr) { -+ STP_DBG_ERR_FUNC("NULL pointer\n"); -+ return -2; -+ } -+ -+ pStr = str; -+ STP_DBG_DBG_FUNC("source infor:%s\n", pStr); -+ switch (type) { -+ case STP_DBG_ASSERT_INFO: -+ pDtr = osal_strstr(pStr, parser_sub_string[type]); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen(parser_sub_string[type]); -+ pTemp = osal_strchr(pDtr, ' '); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); -+ return -3; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], "assert@", osal_strlen("assert@")); -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@")], pDtr, len); -+ g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len] = '_'; -+ -+ pTemp = osal_strchr(pDtr, '#'); -+ pTemp += 1; -+ -+ pTemp2 = osal_strchr(pTemp, ' '); -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1], pTemp, pTemp2 - pTemp); -+ g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1 + pTemp2 - pTemp] = '\0'; -+ STP_DBG_INFO_FUNC("assert info:%s\n", &g_stp_dbg_cpupcr->assert_info[0]); -+ break; -+ case STP_DBG_FW_TASK_ID: -+ pDtr = osal_strstr(pStr, parser_sub_string[type]); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen(parser_sub_string[type]); -+ pTemp = osal_strchr(pDtr, ' '); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); -+ return -3; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&tempBuf[0], pDtr, len); -+ tempBuf[len] = '\0'; -+ ret = osal_strtol(tempBuf, 16, &res); -+ if (ret) { -+ STP_DBG_ERR_FUNC("get fw task id fail(%d)\n", ret); -+ return -4; -+ } -+ g_stp_dbg_cpupcr->fwTaskId = (UINT32)res; -+ -+ STP_DBG_INFO_FUNC("fw task id :%x\n", (UINT32)res); -+ break; -+ case STP_DBG_FW_ISR: -+ pDtr = osal_strstr(pStr, parser_sub_string[type]); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen(parser_sub_string[type]); -+ pTemp = osal_strchr(pDtr, ','); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); -+ return -3; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&tempBuf[0], pDtr, len); -+ tempBuf[len] = '\0'; -+ ret = osal_strtol(tempBuf, 16, &res); -+ if (ret) { -+ STP_DBG_ERR_FUNC("get fw isr id fail(%d)\n", ret); -+ return -4; -+ } -+ g_stp_dbg_cpupcr->fwIsr = (UINT32)res; -+ -+ STP_DBG_INFO_FUNC("fw isr str:%x\n", (UINT32)res); -+ break; -+ case STP_DBG_FW_IRQ: -+ pDtr = osal_strstr(pStr, parser_sub_string[type]); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen(parser_sub_string[type]); -+ pTemp = osal_strchr(pDtr, ','); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); -+ return -3; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&tempBuf[0], pDtr, len); -+ tempBuf[len] = '\0'; -+ ret = osal_strtol(tempBuf, 16, &res); -+ if (ret) { -+ STP_DBG_ERR_FUNC("get fw irq id fail(%d)\n", ret); -+ return -4; -+ } -+ g_stp_dbg_cpupcr->fwRrq = (UINT32)res; -+ -+ STP_DBG_INFO_FUNC("fw irq value:%x\n", (UINT32)res); -+ break; -+ case STP_DBG_ASSERT_TYPE: -+ pDtr = osal_strstr(pStr, parser_sub_string[type]); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen(parser_sub_string[type]); -+ pTemp = osal_strchr(pDtr, ','); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); -+ return -3; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&tempBuf[0], pDtr, len); -+ tempBuf[len] = '\0'; -+ -+ if (0 == osal_memcmp(tempBuf, "*", len)) -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], "general assert", osal_strlen("general assert")); -+ if (0 == osal_memcmp(tempBuf, "Watch Dog Timeout", len)) -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], "wdt", osal_strlen("wdt")); -+ if (0 == osal_memcmp(tempBuf, "RB_FULL", osal_strlen("RB_FULL"))) { -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], tempBuf, len); -+ -+ pDtr = osal_strstr(&g_stp_dbg_cpupcr->assert_type[0], "RB_FULL("); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen("RB_FULL("); -+ pTemp = osal_strchr(pDtr, ')'); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(RB_FULL()\n"); -+ return -4; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&tempBuf[0], pDtr, len); -+ tempBuf[len] = '\0'; -+ ret = osal_strtol(tempBuf, 16, &res); -+ if (ret) { -+ STP_DBG_ERR_FUNC("get fw task id fail(%d)\n", ret); -+ return -5; -+ } -+ g_stp_dbg_cpupcr->fwTaskId = (UINT32)res; -+ -+ STP_DBG_INFO_FUNC("update fw task id :%x\n", (UINT32)res); -+ } -+ -+ STP_DBG_INFO_FUNC("fw asert type:%s\n", g_stp_dbg_cpupcr->assert_type); -+ break; -+ default: -+ STP_DBG_ERR_FUNC("unknown parser type\n"); -+ break; -+ } -+ -+ return 0; -+} -+ -+P_STP_DBG_CPUPCR_T stp_dbg_cpupcr_init(VOID) -+{ -+ P_STP_DBG_CPUPCR_T pSdCpupcr = NULL; -+ -+ pSdCpupcr = (P_STP_DBG_CPUPCR_T) osal_malloc(osal_sizeof(STP_DBG_CPUPCR_T)); -+ if (!pSdCpupcr) { -+ STP_DBG_ERR_FUNC("stp dbg cpupcr allocate memory fail!\n"); -+ return NULL; -+ } -+ -+ osal_memset(pSdCpupcr, 0, osal_sizeof(STP_DBG_CPUPCR_T)); -+ -+ osal_sleepable_lock_init(&pSdCpupcr->lock); -+ -+ return pSdCpupcr; -+} -+ -+P_STP_DBG_DMAREGS_T stp_dbg_dmaregs_init(VOID) -+{ -+ P_STP_DBG_DMAREGS_T pDmaRegs = NULL; -+ -+ pDmaRegs = (P_STP_DBG_DMAREGS_T) osal_malloc(osal_sizeof(STP_DBG_DMAREGS_T)); -+ if (!pDmaRegs) { -+ STP_DBG_ERR_FUNC("stp dbg dmareg allocate memory fail!\n"); -+ return NULL; -+ } -+ -+ osal_memset(pDmaRegs, 0, osal_sizeof(STP_DBG_DMAREGS_T)); -+ -+ osal_sleepable_lock_init(&pDmaRegs->lock); -+ -+ return pDmaRegs; -+} -+ -+VOID stp_dbg_cpupcr_deinit(P_STP_DBG_CPUPCR_T pCpupcr) -+{ -+ if (pCpupcr) { -+ osal_sleepable_lock_deinit(&pCpupcr->lock); -+ osal_free(pCpupcr); -+ pCpupcr = NULL; -+ } -+} -+ -+VOID stp_dbg_dmaregs_deinit(P_STP_DBG_DMAREGS_T pDmaRegs) -+{ -+ if (pDmaRegs) { -+ osal_sleepable_lock_deinit(&pDmaRegs->lock); -+ osal_free(pDmaRegs); -+ pDmaRegs = NULL; -+ } -+} -+ -+INT32 stp_dbg_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd) -+{ -+ INT32 i = 0; -+ -+ if (!g_stp_dbg_cpupcr) { -+ STP_DBG_ERR_FUNC("NULL reference pointer\n"); -+ return -1; -+ } -+ -+ if (!cmd) { -+ if (g_stp_dbg_cpupcr->count + times > STP_DBG_CPUPCR_NUM) -+ times = STP_DBG_CPUPCR_NUM - g_stp_dbg_cpupcr->count; -+ -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ for (i = 0; i < times; i++) { -+ STP_DBG_INFO_FUNC("i:%d,cpupcr:%08x\n", i, wmt_plat_read_cpupcr()); -+ /* osal_memcpy( -+ * &g_stp_dbg_cpupcr->buffer[i], -+ * (UINT8*)(CONSYS_REG_READ(CONSYS_CPUPCR_REG)), -+ * osal_sizeof(UINT32)); -+ */ -+ g_stp_dbg_cpupcr->buffer[g_stp_dbg_cpupcr->count + i] = wmt_plat_read_cpupcr(); -+ osal_sleep_ms(sleep); -+ } -+ g_stp_dbg_cpupcr->count += times; -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else { -+ STP_DBG_INFO_FUNC("stp-dbg: for proc test polling cpupcr\n"); -+ if (times > STP_DBG_CPUPCR_NUM) -+ times = STP_DBG_CPUPCR_NUM; -+ -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ g_stp_dbg_cpupcr->count = 0; -+ for (i = 0; i < times; i++) { -+ STP_DBG_INFO_FUNC("i:%d,cpupcr:%08x\n", i, wmt_plat_read_cpupcr()); -+ /* osal_memcpy( -+ * &g_stp_dbg_cpupcr->buffer[i], -+ * (UINT8*)(CONSYS_REG_READ(CONSYS_CPUPCR_REG)), -+ * osal_sizeof(UINT32)); -+ */ -+ g_stp_dbg_cpupcr->buffer[i] = wmt_plat_read_cpupcr(); -+ osal_sleep_ms(sleep); -+ } -+ g_stp_dbg_cpupcr->count = times; -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ } -+ return 0; -+} -+ -+INT32 stp_dbg_poll_dmaregs(UINT32 times, UINT32 sleep) -+{ -+#if 0 -+ INT32 i = 0; -+ -+ if (!g_stp_dbg_dmaregs) { -+ STP_DBG_ERR_FUNC("NULL reference pointer\n"); -+ return -1; -+ } -+ -+ osal_lock_sleepable_lock(&g_stp_dbg_dmaregs->lock); -+ -+ if (g_stp_dbg_dmaregs->count + times > STP_DBG_DMAREGS_NUM) { -+ if (g_stp_dbg_dmaregs->count > STP_DBG_DMAREGS_NUM) { -+ STP_DBG_ERR_FUNC("g_stp_dbg_dmaregs->count:%d must less than STP_DBG_DMAREGS_NUM:%d\n", -+ g_stp_dbg_dmaregs->count, STP_DBG_DMAREGS_NUM); -+ g_stp_dbg_dmaregs->count = 0; -+ STP_DBG_ERR_FUNC("g_stp_dbg_dmaregs->count be set default value 0\n"); -+ } -+ times = STP_DBG_DMAREGS_NUM - g_stp_dbg_dmaregs->count; -+ } -+ if (times > STP_DBG_DMAREGS_NUM) { -+ STP_DBG_ERR_FUNC("times overflow, set default value:0\n"); -+ times = 0; -+ } -+ STP_DBG_WARN_FUNC("---------Now Polling DMA relative Regs -------------\n"); -+ for (i = 0; i < times; i++) { -+ INT32 k = 0; -+ -+ for (; k < DMA_REGS_MAX; k++) { -+ STP_DBG_WARN_FUNC("times:%d,i:%d reg: %s, regs:%08x\n", times, i, dmaRegsStr[k], -+ wmt_plat_read_dmaregs(k)); -+ /* g_stp_dbg_dmaregs->dmaIssue[k][g_stp_dbg_dmaregs->count + i] = wmt_plat_read_dmaregs(k); */ -+ } -+ osal_sleep_ms(sleep); -+ } -+ STP_DBG_WARN_FUNC("---------Polling DMA relative Regs End-------------\n"); -+ g_stp_dbg_dmaregs->count += times; -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_dmaregs->lock); -+#else -+ return 0; -+#endif -+} -+ -+INT32 stp_dbg_poll_cuppcr_ctrl(UINT32 en) -+{ -+ -+ STP_DBG_INFO_FUNC("%s polling cpupcr\n", en == 0 ? "start" : "stop"); -+ -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ g_stp_dbg_cpupcr->stop_flag = en; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ return 0; -+} -+ -+INT32 stp_dbg_set_version_info(UINT32 chipid, UINT8 *pRomVer, UINT8 *pPatchVer, UINT8 *pPatchBrh) -+{ -+ if (g_stp_dbg_cpupcr) { -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ g_stp_dbg_cpupcr->chipId = chipid; -+ -+ if (pRomVer) -+ osal_memcpy(g_stp_dbg_cpupcr->romVer, pRomVer, 2); -+ if (pPatchVer) -+ osal_memcpy(g_stp_dbg_cpupcr->patchVer, pPatchVer, 8); -+ if (pPatchBrh) -+ osal_memcpy(g_stp_dbg_cpupcr->branchVer, pPatchBrh, 4); -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else { -+ STP_DBG_ERR_FUNC("NULL pointer\n"); -+ return -1; -+ } -+ STP_DBG_INFO_FUNC("chipid(0x%x),romver(%s),patchver(%s),branchver(%s)\n", g_stp_dbg_cpupcr->chipId, -+ &g_stp_dbg_cpupcr->romVer[0], &g_stp_dbg_cpupcr->patchVer[0], &g_stp_dbg_cpupcr->branchVer[0]); -+ return 0; -+} -+INT32 stp_dbg_set_wifiver(UINT32 wifiver) -+{ -+ if (g_stp_dbg_cpupcr) { -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ g_stp_dbg_cpupcr->wifiVer = wifiver; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else { -+ STP_DBG_ERR_FUNC("NULL pointer\n"); -+ return -1; -+ } -+ STP_DBG_INFO_FUNC("wifiver(%x)\n", g_stp_dbg_cpupcr->wifiVer); -+ return 0; -+} -+ -+INT32 stp_dbg_set_host_assert_info(UINT32 drv_type, UINT32 reason, UINT32 en) -+{ -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ g_stp_dbg_cpupcr->host_assert_info.assert_from_host = en; -+ g_stp_dbg_cpupcr->host_assert_info.drv_type = drv_type; -+ g_stp_dbg_cpupcr->host_assert_info.reason = reason; -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ return 0; -+} -+ -+UINT32 stp_dbg_get_host_trigger_assert(VOID) -+{ -+ return g_stp_dbg_cpupcr->host_assert_info.assert_from_host; -+} -+ -+INT32 stp_dbg_set_fw_info(UINT8 *issue_info, UINT32 len, ENUM_STP_FW_ISSUE_TYPE issue_type) -+{ -+ ENUM_ASSERT_INFO_PARSER_TYPE type_index; -+ PUINT8 tempbuf = NULL; -+ UINT32 i = 0; -+ INT32 iRet = 0; -+ -+ if (NULL == issue_info) { -+ STP_DBG_ERR_FUNC("null issue infor\n"); -+ return -1; -+ } -+ STP_DBG_INFO_FUNC("issue type(%d)\n", issue_type); -+ g_stp_dbg_cpupcr->issue_type = issue_type; -+ osal_memset(&g_stp_dbg_cpupcr->assert_info[0], 0, STP_ASSERT_INFO_SIZE); -+ -+ /*print patch version when assert happened */ -+ STP_DBG_INFO_FUNC("=======================================\n"); -+ STP_DBG_INFO_FUNC("[consys patch]patch version:%s\n", g_stp_dbg_cpupcr->patchVer); -+ STP_DBG_INFO_FUNC("[consys patch]ALPS branch:%s\n", g_stp_dbg_cpupcr->branchVer); -+ STP_DBG_INFO_FUNC("=======================================\n"); -+ -+ if ((STP_FW_ASSERT_ISSUE == issue_type) || -+ (STP_HOST_TRIGGER_FW_ASSERT == issue_type) || (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type)) { -+ if ((STP_FW_ASSERT_ISSUE == issue_type) || (STP_HOST_TRIGGER_FW_ASSERT == issue_type)) { -+ tempbuf = osal_malloc(len + 1); -+ if (!tempbuf) -+ return -2; -+ -+ osal_memcpy(&tempbuf[0], issue_info, len); -+ -+ for (i = 0; i < len; i++) { -+ if (tempbuf[i] == '\0') -+ tempbuf[i] = '?'; -+ } -+ -+ tempbuf[len] = '\0'; -+ -+ for (type_index = STP_DBG_ASSERT_INFO; type_index < STP_DBG_PARSER_TYPE_MAX; type_index++) -+ iRet += _stp_dbg_parser_assert_str(&tempbuf[0], type_index); -+ -+ if (iRet) -+ STP_DBG_ERR_FUNC("passert assert infor fail(%d)\n", iRet); -+ -+ } -+ if ((STP_HOST_TRIGGER_FW_ASSERT == issue_type) || (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type)) { -+ switch (g_stp_dbg_cpupcr->host_assert_info.drv_type) { -+ case 0: -+ STP_DBG_INFO_FUNC("BT trigger assert\n"); -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ if (31 != g_stp_dbg_cpupcr->host_assert_info.reason) -+ /*BT firmware trigger assert */ -+ { -+ g_stp_dbg_cpupcr->fwTaskId = 1; -+ -+ } else -+ /*BT stack trigger assert */ -+ { -+ g_stp_dbg_cpupcr->fwTaskId = 8; -+ } -+ -+ g_stp_dbg_cpupcr->host_assert_info.assert_from_host = 0; -+ /* g_stp_dbg_cpupcr->host_assert_info.drv_type = 0; */ -+ /* g_stp_dbg_cpupcr->host_assert_info.reason = 0; */ -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ break; -+ case 4: -+ STP_DBG_INFO_FUNC("WMT trigger assert\n"); -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ if (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type) -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); -+ -+ if ((38 == g_stp_dbg_cpupcr->host_assert_info.reason) || -+ (39 == g_stp_dbg_cpupcr->host_assert_info.reason) || -+ (40 == g_stp_dbg_cpupcr->host_assert_info.reason)) -+ g_stp_dbg_cpupcr->fwTaskId = 6; /* HOST schedule reason trigger */ -+ else -+ g_stp_dbg_cpupcr->fwTaskId = 0; /* Must be firmware reason */ -+ g_stp_dbg_cpupcr->host_assert_info.assert_from_host = 0; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ break; -+ default: -+ break; -+ } -+ -+ } -+ osal_free(tempbuf); -+ } else if (STP_FW_NOACK_ISSUE == issue_type) { -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); -+ g_stp_dbg_cpupcr->fwTaskId = 6; -+ g_stp_dbg_cpupcr->fwRrq = 0; -+ g_stp_dbg_cpupcr->fwIsr = 0; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else if (STP_DBG_PROC_TEST == issue_type) { -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); -+ g_stp_dbg_cpupcr->fwTaskId = 0; -+ g_stp_dbg_cpupcr->fwRrq = 0; -+ g_stp_dbg_cpupcr->fwIsr = 0; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else if (STP_FW_WARM_RST_ISSUE == issue_type) { -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); -+ g_stp_dbg_cpupcr->fwTaskId = 0; -+ g_stp_dbg_cpupcr->fwRrq = 0; -+ g_stp_dbg_cpupcr->fwIsr = 0; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else { -+ STP_DBG_ERR_FUNC("invalid issue type(%d)\n", issue_type); -+ return -3; -+ } -+ -+ return iRet; -+} -+ -+INT32 stp_dbg_cpupcr_infor_format(PPUINT8 buf, PUINT32 str_len) -+{ -+ UINT32 len = 0; -+ UINT32 i = 0; -+ -+ if (!g_stp_dbg_cpupcr) { -+ STP_DBG_ERR_FUNC("NULL pointer\n"); -+ return -1; -+ } -+ -+ /*format common information about issue */ -+ len = osal_sprintf(*buf, "
\n\t"); -+ len += osal_sprintf(*buf + len, "\n\t\tMT%x\n\t\n\t", g_stp_dbg_cpupcr->chipId); -+ len += osal_sprintf(*buf + len, "\n\t\t"); -+ len += osal_sprintf(*buf + len, "%s\n\t\t", g_stp_dbg_cpupcr->romVer); -+ if (!(osal_memcmp(g_stp_dbg_cpupcr->branchVer, "ALPS", strlen("ALPS")))) -+ len += osal_sprintf(*buf + len, "Internal Dev\n\t\t", g_stp_dbg_cpupcr->branchVer); -+ else -+ len += osal_sprintf(*buf + len, "W%sMP\n\t\t", g_stp_dbg_cpupcr->branchVer); -+ -+ len += osal_sprintf(*buf + len, "%s\n\t\t", g_stp_dbg_cpupcr->patchVer); -+ -+ if (0 == g_stp_dbg_cpupcr->wifiVer) -+ len += osal_sprintf(*buf + len, "NULL\n\t"); -+ else -+ len += osal_sprintf(*buf + len, "0x%X.%X\n\t", -+ (UINT8)((g_stp_dbg_cpupcr->wifiVer & 0xFF00)>>8), (UINT8)(g_stp_dbg_cpupcr->wifiVer & 0xFF)); -+ -+ len += osal_sprintf(*buf + len, "\n\t"); -+ -+ /*format issue information: no ack, assert */ -+ len += osal_sprintf(*buf + len, "\n\t\t\n\t\t\t"); -+ if ((STP_FW_NOACK_ISSUE == g_stp_dbg_cpupcr->issue_type) || -+ (STP_DBG_PROC_TEST == g_stp_dbg_cpupcr->issue_type) || -+ (STP_FW_WARM_RST_ISSUE == g_stp_dbg_cpupcr->issue_type)) { -+ len += -+ osal_sprintf(*buf + len, "%s\n\t\t\n\t\t\n\t\t\t", -+ g_stp_dbg_cpupcr->assert_info); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\n\t"); -+ len += osal_sprintf(*buf + len, "\n\t\tNULL\n\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t"); -+ len += -+ osal_sprintf(*buf + len, "\n\t\t\t%s\n\t\t\t", -+ _stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId)); -+ len += osal_sprintf(*buf + len, "IRQ_0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwRrq); -+ len += osal_sprintf(*buf + len, "0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwIsr); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ } else if ((STP_FW_ASSERT_ISSUE == g_stp_dbg_cpupcr->issue_type) || -+ (STP_HOST_TRIGGER_FW_ASSERT == g_stp_dbg_cpupcr->issue_type) || -+ (STP_HOST_TRIGGER_ASSERT_TIMEOUT == g_stp_dbg_cpupcr->issue_type)) { -+ len += -+ osal_sprintf(*buf + len, "%s\n\t\t\n\t\t\n\t\t\t", -+ g_stp_dbg_cpupcr->assert_info); -+ len += osal_sprintf(*buf + len, "%s\n\t\t\n\t\n\t", g_stp_dbg_cpupcr->assert_type); -+ len += osal_sprintf(*buf + len, "\n\t\tNULL\n\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t"); -+ len += -+ osal_sprintf(*buf + len, "\n\t\t\t%s\n\t\t\t", -+ _stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId)); -+ if (32 == g_stp_dbg_cpupcr->host_assert_info.reason || 33 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 34 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 35 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 36 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 37 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 38 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 39 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 40 == g_stp_dbg_cpupcr->host_assert_info.reason) { -+ /*handling wmt turn on/off bt cmd has ack but no evt issue */ -+ /*one of both the irqx and irs is nULL, then use task to find MOF */ -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ } else { -+ len += osal_sprintf(*buf + len, "IRQ_0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwRrq); -+ } -+ len += osal_sprintf(*buf + len, "0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwIsr); -+ -+ if (STP_FW_ASSERT_ISSUE == g_stp_dbg_cpupcr->issue_type) { -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ } -+ -+ if ((STP_HOST_TRIGGER_FW_ASSERT == g_stp_dbg_cpupcr->issue_type) || -+ (STP_HOST_TRIGGER_ASSERT_TIMEOUT == g_stp_dbg_cpupcr->issue_type)) { -+ len += -+ osal_sprintf(*buf + len, "%d\n\t\t\t", -+ g_stp_dbg_cpupcr->host_assert_info.drv_type); -+ len += -+ osal_sprintf(*buf + len, "%d\n\t\t\t", -+ g_stp_dbg_cpupcr->host_assert_info.reason); -+ } -+ } else { -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\t\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\n\t"); -+ len += osal_sprintf(*buf + len, "\n\t\tNULL\n\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t"); -+ len += osal_sprintf(*buf + len, "\n\t\t\tNULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ } -+ -+ len += osal_sprintf(*buf + len, ""); -+ STP_DBG_INFO_FUNC("stp-dbg:sub len1 for debug(%d)\n", len); -+ -+ if (!g_stp_dbg_cpupcr->count) -+ len += osal_sprintf(*buf + len, "NULL"); -+ else { -+ for (i = 0; i < g_stp_dbg_cpupcr->count; i++) -+ len += osal_sprintf(*buf + len, "%08x,", g_stp_dbg_cpupcr->buffer[i]); -+ } -+ STP_DBG_INFO_FUNC("stp-dbg:sub len2 for debug(%d)\n", len); -+ len += osal_sprintf(*buf + len, "\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\n
\n"); -+ STP_DBG_INFO_FUNC("buffer len[%d]\n", len); -+ /* STP_DBG_INFO_FUNC("Format infor:\n%s\n",*buf); */ -+ *str_len = len; -+ -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ osal_memset(&g_stp_dbg_cpupcr->buffer[0], 0, STP_DBG_CPUPCR_NUM); -+ g_stp_dbg_cpupcr->count = 0; -+ g_stp_dbg_cpupcr->host_assert_info.reason = 0; -+ g_stp_dbg_cpupcr->host_assert_info.drv_type = 0; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ return 0; -+ -+} -+ -+MTKSTP_DBG_T *stp_dbg_init(void *btm_half) -+{ -+ -+ MTKSTP_DBG_T *stp_dbg = NULL; -+ -+ STP_DBG_INFO_FUNC("stp-dbg init\n"); -+ -+ stp_dbg = kzalloc(sizeof(MTKSTP_DBG_T), GFP_KERNEL); -+ if (stp_dbg == NULL) -+ goto ERR_EXIT1; -+ if (IS_ERR(stp_dbg)) { -+ STP_DBG_ERR_FUNC("-ENOMEM\n"); -+ goto ERR_EXIT1; -+ } -+ -+ stp_dbg->logsys = vmalloc(sizeof(MTKSTP_LOG_SYS_T)); -+ if (stp_dbg->logsys == NULL) -+ goto ERR_EXIT2; -+ if (IS_ERR(stp_dbg->logsys)) { -+ STP_DBG_ERR_FUNC("-ENOMEM stp_gdb->logsys\n"); -+ goto ERR_EXIT2; -+ } -+ memset(stp_dbg->logsys, 0, sizeof(MTKSTP_LOG_SYS_T)); -+ spin_lock_init(&(stp_dbg->logsys->lock)); -+ stp_dbg->pkt_trace_no = 0; -+ stp_dbg->is_enable = 0; -+ g_stp_dbg = stp_dbg; -+ -+ if (btm_half != NULL) -+ stp_dbg->btm = btm_half; -+ else -+ stp_dbg->btm = NULL; -+ -+ -+ /* bind to netlink */ -+ stp_dbg_nl_init(); -+ g_core_dump = wcn_core_dump_init(STP_CORE_DUMP_INIT_SIZE, STP_CORE_DUMP_TIMEOUT); -+ g_stp_dbg_cpupcr = stp_dbg_cpupcr_init(); -+ g_stp_dbg_dmaregs = stp_dbg_dmaregs_init(); -+ -+ return stp_dbg; -+ -+ERR_EXIT2: -+ kfree(stp_dbg); -+ return NULL; -+ -+ERR_EXIT1: -+ kfree(stp_dbg); -+ return NULL; -+} -+ -+int stp_dbg_deinit(MTKSTP_DBG_T *stp_dbg) -+{ -+ -+ STP_DBG_INFO_FUNC("stp-dbg deinit\n"); -+ -+ wcn_core_dump_deinit(g_core_dump); -+ -+ stp_dbg_cpupcr_deinit(g_stp_dbg_cpupcr); -+ stp_dbg_dmaregs_deinit(g_stp_dbg_dmaregs); -+ /* unbind with netlink */ -+ stp_dbg_nl_deinit(); -+ -+ if (stp_dbg->logsys) -+ vfree(stp_dbg->logsys); -+ -+ kfree(stp_dbg); -+ -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c -new file mode 100644 -index 0000000000000..f7f4aff010d4a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c -@@ -0,0 +1,279 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include /* udelay() */ -+ -+#include -+ -+ -+#include "osal_typedef.h" -+#include "stp_core.h" -+#include "stp_exp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static MTK_WCN_STP_IF_TX stp_uart_if_tx; -+static MTK_WCN_STP_IF_TX stp_sdio_if_tx; -+static MTK_WCN_STP_IF_TX stp_btif_if_tx; -+static ENUM_STP_TX_IF_TYPE g_stp_if_type = STP_MAX_IF_TX; -+static MTK_WCN_STP_IF_RX stp_if_rx; -+static MTK_WCN_STP_EVENT_CB event_callback_tbl[MTKSTP_MAX_TASK_NUM] = { 0x0 }; -+static MTK_WCN_STP_EVENT_CB tx_event_callback_tbl[MTKSTP_MAX_TASK_NUM] = { 0x0 }; -+ -+/****************************************************************************** -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************* -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+INT32 mtk_wcn_sys_if_rx(UINT8 *data, INT32 size) -+{ -+ if (stp_if_rx == 0x0) -+ return -1; -+ -+ (*stp_if_rx) (data, size); -+ return 0; -+} -+ -+static INT32 mtk_wcn_sys_if_tx(const PUINT8 data, const UINT32 size, PUINT32 written_size) -+{ -+ -+ if (STP_UART_IF_TX == g_stp_if_type) -+ return stp_uart_if_tx != NULL ? (*stp_uart_if_tx) (data, size, written_size) : -1; -+ else if (STP_SDIO_IF_TX == g_stp_if_type) -+ return stp_sdio_if_tx != NULL ? (*stp_sdio_if_tx) (data, size, written_size) : -1; -+ else if (STP_BTIF_IF_TX == g_stp_if_type) -+ return stp_btif_if_tx != NULL ? (*stp_btif_if_tx) (data, size, written_size) : -1; -+ /*if (g_stp_if_type >= STP_MAX_IF_TX) *//* George: remove ALWAYS TRUE condition */ -+ return -1; -+} -+ -+static INT32 mtk_wcn_sys_event_set(UINT8 function_type) -+{ -+ if ((function_type < MTKSTP_MAX_TASK_NUM) && (event_callback_tbl[function_type] != 0x0)) { -+ (*event_callback_tbl[function_type]) (); -+ } else { -+ /* FIXME: error handling */ -+ pr_err("[%s] STP set event fail. It seems the function is not active.\n", __func__); -+ } -+ -+ return 0; -+} -+ -+static INT32 mtk_wcn_sys_event_tx_resume(UINT8 winspace) -+{ -+ int type = 0; -+ -+ for (type = 0; type < MTKSTP_MAX_TASK_NUM; type++) { -+ if (tx_event_callback_tbl[type]) -+ tx_event_callback_tbl[type] (); -+ } -+ -+ return 0; -+} -+ -+static INT32 mtk_wcn_sys_check_function_status(UINT8 type, UINT8 op) -+{ -+ -+ /* op == FUNCTION_ACTIVE, to check if funciton[type] is active ? */ -+ if (!(type < MTKSTP_MAX_TASK_NUM)) -+ return STATUS_FUNCTION_INVALID; -+ -+ if (op == OP_FUNCTION_ACTIVE) { -+ if (event_callback_tbl[type] != 0x0) -+ return STATUS_FUNCTION_ACTIVE; -+ else -+ return STATUS_FUNCTION_INACTIVE; -+ -+ } -+ /* you can define more operation here ..., to queury function's status/information */ -+ -+ return STATUS_OP_INVALID; -+} -+ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) -+#else -+INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) -+#endif -+{ -+ stp_if_rx = func; -+ -+ return 0; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_register_if_rx); -+#endif -+ -+VOID mtk_wcn_stp_set_if_tx_type(ENUM_STP_TX_IF_TYPE stp_if_type) -+{ -+ static const char * const ifType[] = { -+ "UART", -+ "SDIO", -+ "BTIF", -+ "UNKNOWN" -+ }; -+ g_stp_if_type = stp_if_type; -+ pr_debug("[%s] set STP_IF_TX to %s.\n", __func__, ifType[stp_if_type]); -+} -+ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) -+#else -+INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) -+#endif -+{ -+ if (STP_UART_IF_TX == stp_if) { -+ stp_uart_if_tx = func; -+ } else if (STP_SDIO_IF_TX == stp_if) { -+ stp_sdio_if_tx = func; -+ } else if (STP_BTIF_IF_TX == stp_if) { -+ stp_btif_if_tx = func; -+ } else { -+ pr_debug("[%s] STP_IF_TX(%d) out of boundary.\n", __func__, stp_if); -+ return -1; -+ } -+ -+ return 0; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_register_if_tx); -+#endif -+ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+#else -+INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+#endif -+{ -+ if (type < MTKSTP_MAX_TASK_NUM) { -+ event_callback_tbl[type] = func; -+ -+ /*clear rx queue */ -+ pr_debug("Flush type = %d Rx Queue\n", type); -+ mtk_wcn_stp_flush_rx_queue(type); -+ } -+ -+ return 0; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_register_event_cb); -+#endif -+ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+#else -+INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+#endif -+{ -+ if (type < MTKSTP_MAX_TASK_NUM) -+ tx_event_callback_tbl[type] = func; -+ else -+ BUG_ON(0); -+ -+ return 0; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_register_tx_event_cb); -+#endif -+ -+INT32 stp_drv_init(VOID) -+{ -+ INT32 ret = 0; -+ -+ mtkstp_callback cb = { -+ .cb_if_tx = mtk_wcn_sys_if_tx, -+ .cb_event_set = mtk_wcn_sys_event_set, -+ .cb_event_tx_resume = mtk_wcn_sys_event_tx_resume, -+ .cb_check_funciton_status = mtk_wcn_sys_check_function_status -+ }; -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ MTK_WCN_STP_EXP_CB_INFO stpExpCb = { -+ .stp_send_data_cb = _mtk_wcn_stp_send_data, -+ .stp_send_data_raw_cb = _mtk_wcn_stp_send_data_raw, -+ .stp_parser_data_cb = _mtk_wcn_stp_parser_data, -+ .stp_receive_data_cb = _mtk_wcn_stp_receive_data, -+ .stp_is_rxqueue_empty_cb = _mtk_wcn_stp_is_rxqueue_empty, -+ .stp_is_ready_cb = _mtk_wcn_stp_is_ready, -+ .stp_set_bluez_cb = _mtk_wcn_stp_set_bluez, -+ .stp_if_tx_cb = _mtk_wcn_stp_register_if_tx, -+ .stp_if_rx_cb = _mtk_wcn_stp_register_if_rx, -+ .stp_reg_event_cb = _mtk_wcn_stp_register_event_cb, -+ .stp_reg_tx_event_cb = _mtk_wcn_stp_register_tx_event_cb, -+ .stp_coredump_start_get_cb = _mtk_wcn_stp_coredump_start_get, -+ }; -+#endif -+ -+ ret = mtk_wcn_stp_init(&cb); -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ mtk_wcn_stp_exp_cb_reg(&stpExpCb); -+#endif -+ return ret; -+} -+ -+VOID stp_drv_exit(VOID) -+{ -+ mtk_wcn_stp_deinit(); -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ mtk_wcn_stp_exp_cb_unreg(); -+#endif -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c -new file mode 100644 -index 0000000000000..f70c88796f091 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c -@@ -0,0 +1,2566 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief brief description -+ -+ Detailed descriptions here. -+ -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-DEV]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "wmt_dev.h" -+#include "wmt_core.h" -+#include "wmt_exp.h" -+#include "wmt_lib.h" -+#include "wmt_conf.h" -+#include "psm_core.h" -+#include "stp_core.h" -+#include "stp_exp.h" -+#include "bgw_desense.h" -+#include -+#include "wmt_idc.h" -+#ifdef CONFIG_COMPAT -+#include -+#endif -+#if WMT_CREATE_NODE_DYNAMIC -+#include -+#endif -+#define BUF_LEN_MAX 384 -+#include -+#ifdef CONFIG_COMPAT -+#define COMPAT_WMT_IOCTL_SET_PATCH_NAME _IOW(WMT_IOC_MAGIC, 4, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 8, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_SET_PATCH_INFO _IOW(WMT_IOC_MAGIC, 15, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_PORT_NAME _IOWR(WMT_IOC_MAGIC, 20, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_WMT_CFG_NAME _IOWR(WMT_IOC_MAGIC, 21, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_SEND_BGW_DS_CMD _IOW(WMT_IOC_MAGIC, 25, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_ADIE_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 26, compat_uptr_t) -+#endif -+ -+#define WMT_IOC_MAGIC 0xa0 -+#define WMT_IOCTL_SET_PATCH_NAME _IOW(WMT_IOC_MAGIC, 4, char*) -+#define WMT_IOCTL_SET_STP_MODE _IOW(WMT_IOC_MAGIC, 5, int) -+#define WMT_IOCTL_FUNC_ONOFF_CTRL _IOW(WMT_IOC_MAGIC, 6, int) -+#define WMT_IOCTL_LPBK_POWER_CTRL _IOW(WMT_IOC_MAGIC, 7, int) -+#define WMT_IOCTL_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 8, char*) -+#define WMT_IOCTL_GET_CHIP_INFO _IOR(WMT_IOC_MAGIC, 12, int) -+#define WMT_IOCTL_SET_LAUNCHER_KILL _IOW(WMT_IOC_MAGIC, 13, int) -+#define WMT_IOCTL_SET_PATCH_NUM _IOW(WMT_IOC_MAGIC, 14, int) -+#define WMT_IOCTL_SET_PATCH_INFO _IOW(WMT_IOC_MAGIC, 15, char*) -+#define WMT_IOCTL_PORT_NAME _IOWR(WMT_IOC_MAGIC, 20, char*) -+#define WMT_IOCTL_WMT_CFG_NAME _IOWR(WMT_IOC_MAGIC, 21, char*) -+#define WMT_IOCTL_WMT_QUERY_CHIPID _IOR(WMT_IOC_MAGIC, 22, int) -+#define WMT_IOCTL_WMT_TELL_CHIPID _IOW(WMT_IOC_MAGIC, 23, int) -+#define WMT_IOCTL_WMT_COREDUMP_CTRL _IOW(WMT_IOC_MAGIC, 24, int) -+#define WMT_IOCTL_SEND_BGW_DS_CMD _IOW(WMT_IOC_MAGIC, 25, char*) -+#define WMT_IOCTL_ADIE_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 26, char*) -+#define WMT_IOCTL_FW_DBGLOG_CTRL _IOR(WMT_IOC_MAGIC, 29, int) -+#define WMT_IOCTL_DYNAMIC_DUMP_CTRL _IOR(WMT_IOC_MAGIC, 30, char*) -+ -+#define MTK_WMT_VERSION "SOC Consys WMT Driver - v1.0" -+#define MTK_WMT_DATE "2013/01/20" -+#define WMT_DEV_MAJOR 190 /* never used number */ -+#define WMT_DEV_NUM 1 -+#define WMT_DEV_INIT_TO_MS (2 * 1000) -+#define DYNAMIC_DUMP_BUF 109 -+ -+#if CFG_WMT_DBG_SUPPORT -+#define WMT_DBG_PROCNAME "driver/wmt_dbg" -+#endif -+ -+#define WMT_DRIVER_NAME "mtk_stp_wmt" -+ -+P_OSAL_EVENT gpRxEvent = NULL; -+ -+UINT32 u4RxFlag = 0x0; -+static atomic_t gRxCount = ATOMIC_INIT(0); -+ -+/* Linux UINT8 device */ -+static int gWmtMajor = WMT_DEV_MAJOR; -+static struct cdev gWmtCdev; -+static atomic_t gWmtRefCnt = ATOMIC_INIT(0); -+/* WMT driver information */ -+static UINT8 gLpbkBuf[1024+5] = { 0 }; -+ -+static UINT32 gLpbkBufLog; /* George LPBK debug */ -+static INT32 gWmtInitDone; -+static wait_queue_head_t gWmtInitWq; -+ -+P_WMT_PATCH_INFO pPatchInfo = NULL; -+UINT32 pAtchNum = 0; -+ -+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MT_ENG_BUILD)) -+#define WMT_EMI_DEBUG_BUF_SIZE (8*1024) -+#else -+#define WMT_EMI_DEBUG_BUF_SIZE (32*1024) -+#endif -+ -+static UINT8 gEmiBuf[WMT_EMI_DEBUG_BUF_SIZE]; -+UINT8 *buf_emi; -+ -+#if CFG_WMT_PROC_FOR_AEE -+static struct proc_dir_entry *gWmtAeeEntry; -+#define WMT_AEE_PROCNAME "driver/wmt_aee" -+#define WMT_PROC_AEE_SIZE 3072 -+static UINT32 g_buf_len; -+static UINT8 *pBuf; -+#endif -+ -+#if WMT_CREATE_NODE_DYNAMIC -+struct class *wmt_class = NULL; -+struct device *wmt_dev = NULL; -+#endif -+ -+#if CFG_WMT_DBG_SUPPORT -+static struct proc_dir_entry *gWmtDbgEntry; -+COEX_BUF gCoexBuf; -+ -+static INT32 wmt_dbg_psm_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_quick_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_dsns_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_hwver_get(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_inband_rst(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_chip_rst(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_raed_chipid(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_wmt_dbg_level(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_stp_dbg_level(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_reg_read(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_reg_write(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_coex_test(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd); -+static INT32 wmt_dbg_rst_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_efuse_read(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_efuse_write(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_sdio_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_stp_dbg_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_stp_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3); -+ -+#if CFG_CORE_INTERNAL_TXRX -+static INT32 wmt_dbg_internal_lpbk_test(INT32 par1, INT32 par2, INT32 par3); -+#endif -+static INT32 wmt_dbg_fwinfor_from_emi(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_set_mcu_clock(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_poll_cpupcr(INT32 par1, INT32 par2, INT32 par3); -+#if CONSYS_ENALBE_SET_JTAG -+static INT32 wmt_dbg_jtag_flag_ctrl(INT32 par1, INT32 par2, INT32 par3); -+#endif -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 wmt_dbg_lte_coex_test(INT32 par1, INT32 par2, INT32 par3); -+#endif -+#endif -+static void wmt_dbg_fwinfor_print_buff(UINT32 len) -+{ -+ UINT32 i = 0; -+ UINT32 idx = 0; -+ -+ for (i = 0; i < len; i++) { -+ buf_emi[idx] = gEmiBuf[i]; -+ if (gEmiBuf[i] == '\n') { -+ pr_cont("%s", buf_emi); -+ osal_memset(buf_emi, 0, BUF_LEN_MAX); -+ idx = 0; -+ } else { -+ idx++; -+ } -+ if (idx == BUF_LEN_MAX-1) { -+ buf_emi[idx] = '\0'; -+ pr_cont("%s", buf_emi); -+ osal_memset(buf_emi, 0, BUF_LEN_MAX); -+ idx = 0; -+ } -+ } -+} -+ -+/*LCM on/off ctrl for wmt varabile*/ -+static struct work_struct gPwrOnOffWork; -+UINT32 g_es_lr_flag_for_quick_sleep = 1; /* for ctrl quick sleep flag */ -+UINT32 g_es_lr_flag_for_lpbk_onoff = 0; /* for ctrl lpbk on off */ -+OSAL_SLEEPABLE_LOCK g_es_lr_lock; -+ -+#ifdef CONFIG_EARLYSUSPEND -+ -+static void wmt_dev_early_suspend(struct early_suspend *h) -+{ -+ osal_lock_sleepable_lock(&g_es_lr_lock); -+ g_es_lr_flag_for_quick_sleep = 1; -+ g_es_lr_flag_for_lpbk_onoff = 0; -+ osal_unlock_sleepable_lock(&g_es_lr_lock); -+ -+ WMT_WARN_FUNC("@@@@@@@@@@wmt enter early suspend@@@@@@@@@@@@@@\n"); -+ -+ schedule_work(&gPwrOnOffWork); -+} -+ -+static void wmt_dev_late_resume(struct early_suspend *h) -+{ -+ osal_lock_sleepable_lock(&g_es_lr_lock); -+ g_es_lr_flag_for_quick_sleep = 0; -+ g_es_lr_flag_for_lpbk_onoff = 1; -+ osal_unlock_sleepable_lock(&g_es_lr_lock); -+ -+ WMT_WARN_FUNC("@@@@@@@@@@wmt enter late resume@@@@@@@@@@@@@@\n"); -+ -+ schedule_work(&gPwrOnOffWork); -+ -+} -+ -+struct early_suspend wmt_early_suspend_handler = { -+ .suspend = wmt_dev_early_suspend, -+ .resume = wmt_dev_late_resume, -+}; -+ -+#else -+ -+static struct notifier_block wmt_fb_notifier; -+static int wmt_fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) -+{ -+ struct fb_event *evdata = data; -+ INT32 blank; -+ -+ WMT_DBG_FUNC("wmt_fb_notifier_callback\n"); -+ -+ /* If we aren't interested in this event, skip it immediately ... */ -+ if (event != FB_EVENT_BLANK) -+ return 0; -+ -+ blank = *(INT32 *)evdata->data; -+ WMT_DBG_FUNC("fb_notify(blank=%d)\n", blank); -+ -+ switch (blank) { -+ case FB_BLANK_UNBLANK: -+ osal_lock_sleepable_lock(&g_es_lr_lock); -+ g_es_lr_flag_for_quick_sleep = 0; -+ g_es_lr_flag_for_lpbk_onoff = 1; -+ osal_unlock_sleepable_lock(&g_es_lr_lock); -+ WMT_WARN_FUNC("@@@@@@@@@@wmt enter UNBLANK @@@@@@@@@@@@@@\n"); -+ schedule_work(&gPwrOnOffWork); -+ break; -+ case FB_BLANK_POWERDOWN: -+ osal_lock_sleepable_lock(&g_es_lr_lock); -+ g_es_lr_flag_for_quick_sleep = 1; -+ g_es_lr_flag_for_lpbk_onoff = 0; -+ osal_unlock_sleepable_lock(&g_es_lr_lock); -+ WMT_WARN_FUNC("@@@@@@@@@@wmt enter early POWERDOWN @@@@@@@@@@@@@@\n"); -+ schedule_work(&gPwrOnOffWork); -+ break; -+ default: -+ break; -+ } -+ return 0; -+} -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static void wmt_pwr_on_off_handler(struct work_struct *work) -+{ -+ INT32 retryCounter = 1; -+ -+ WMT_DBG_FUNC("wmt_pwr_on_off_handler start to run\n"); -+ -+ osal_lock_sleepable_lock(&g_es_lr_lock); -+ -+ if (g_es_lr_flag_for_lpbk_onoff) { -+ do { -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK)) { -+ WMT_WARN_FUNC("WMT turn on LPBK fail, retrying, retryCounter left:%d!\n", retryCounter); -+ retryCounter--; -+ osal_sleep_ms(1000); -+ } else { -+ WMT_INFO_FUNC("WMT turn on LPBK suceed\n"); -+ break; -+ } -+ } while (retryCounter > 0); -+ } else { -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK)) -+ WMT_WARN_FUNC("WMT turn off LPBK fail\n"); -+ else -+ WMT_DBG_FUNC("WMT turn off LPBK suceed\n"); -+ -+ } -+ -+ osal_unlock_sleepable_lock(&g_es_lr_lock); -+ -+} -+ -+ -+MTK_WCN_BOOL wmt_dev_get_early_suspend_state(void) -+{ -+ MTK_WCN_BOOL bRet = (0 == g_es_lr_flag_for_quick_sleep) ? MTK_WCN_BOOL_FALSE : MTK_WCN_BOOL_TRUE; -+ /* WMT_INFO_FUNC("bRet:%d\n", bRet); */ -+ return bRet; -+} -+ -+#if CFG_WMT_DBG_SUPPORT -+ -+static const WMT_DEV_DBG_FUNC wmt_dev_dbg_func[] = { -+ [0] = wmt_dbg_psm_ctrl, -+ [1] = wmt_dbg_quick_sleep_ctrl, -+ [2] = wmt_dbg_dsns_ctrl, -+ [3] = wmt_dbg_hwver_get, -+ [4] = wmt_dbg_assert_test, -+ [5] = wmt_dbg_inband_rst, -+ [6] = wmt_dbg_chip_rst, -+ [7] = wmt_dbg_func_ctrl, -+ [8] = wmt_dbg_raed_chipid, -+ [9] = wmt_dbg_wmt_dbg_level, -+ [0xa] = wmt_dbg_stp_dbg_level, -+ [0xb] = wmt_dbg_reg_read, -+ [0xc] = wmt_dbg_reg_write, -+ [0xd] = wmt_dbg_coex_test, -+ [0xe] = wmt_dbg_rst_ctrl, -+ [0xf] = wmt_dbg_ut_test, -+ [0x10] = wmt_dbg_efuse_read, -+ [0x11] = wmt_dbg_efuse_write, -+ [0x12] = wmt_dbg_sdio_ctrl, -+ [0x13] = wmt_dbg_stp_dbg_ctrl, -+ [0x14] = wmt_dbg_stp_dbg_log_ctrl, -+ [0x15] = wmt_dbg_wmt_assert_ctrl, -+ [0x16] = wmt_dbg_fwinfor_from_emi, -+ [0x17] = wmt_dbg_set_mcu_clock, -+ [0x18] = wmt_dbg_poll_cpupcr, -+ [0x19] = wmt_dbg_jtag_flag_ctrl, -+#if CFG_WMT_LTE_COEX_HANDLING -+ [0x20] = wmt_dbg_lte_coex_test, -+#endif -+}; -+ -+INT32 wmt_dbg_psm_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+#if CFG_WMT_PS_SUPPORT -+ if (0 == par2) { -+ wmt_lib_ps_ctrl(0); -+ WMT_INFO_FUNC("disable PSM\n"); -+ } else { -+ par2 = (1 > par2 || 20000 < par2) ? STP_PSM_IDLE_TIME_SLEEP : par2; -+ wmt_lib_ps_set_idle_time(par2); -+ wmt_lib_ps_ctrl(1); -+ WMT_WARN_FUNC("enable PSM, idle to sleep time = %d ms\n", par2); -+ } -+#else -+ WMT_INFO_FUNC("WMT PS not supported\n"); -+#endif -+ return 0; -+} -+ -+INT32 wmt_dbg_quick_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+#if CFG_WMT_PS_SUPPORT -+ UINT32 en_flag = par2; -+ -+ wmt_lib_quick_sleep_ctrl(en_flag); -+#else -+ WMT_WARN_FUNC("WMT PS not supported\n"); -+#endif -+ return 0; -+} -+ -+INT32 wmt_dbg_dsns_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (WMTDSNS_FM_DISABLE <= par2 && WMTDSNS_MAX > par2) { -+ WMT_INFO_FUNC("DSNS type (%d)\n", par2); -+ mtk_wcn_wmt_dsns_ctrl(par2); -+ } else { -+ WMT_WARN_FUNC("invalid DSNS type\n"); -+ } -+ return 0; -+} -+ -+INT32 wmt_dbg_hwver_get(INT32 par1, INT32 par2, INT32 par3) -+{ -+ WMT_INFO_FUNC("query chip version\n"); -+ mtk_wcn_wmt_hwver_get(); -+ return 0; -+} -+ -+INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (0 == par3) { -+ /* par2 = 0: send assert command */ -+ /* par2 != 0: send exception command */ -+ return wmt_dbg_cmd_test_api(0 == par2 ? 0 : 1); -+ } else if (1 == par3) { -+ /* send noack command */ -+ return wmt_dbg_cmd_test_api(18); -+ } else if (2 == par3) { -+ /* warn reset test */ -+ return wmt_dbg_cmd_test_api(19); -+ } else if (3 == par3) { -+ /* firmware trace test */ -+ return wmt_dbg_cmd_test_api(20); -+ } -+ { -+ INT32 sec = 8; -+ INT32 times = 0; -+ -+ times = par3; -+ do { -+ WMT_INFO_FUNC("Send Assert Command per 8 secs!!\n"); -+ wmt_dbg_cmd_test_api(0); -+ osal_sleep_ms(sec * 1000); -+ } while (--times); -+ } -+ return 0; -+} -+ -+INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd) -+{ -+ -+ P_OSAL_OP pOp = NULL; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_OSAL_SIGNAL pSignal; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pSignal = &pOp->signal; -+ -+ pOp->op.opId = WMT_OPID_CMD_TEST; -+ -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ /*this test command should be run with usb cable connected, so no host awake is needed */ -+ /* wmt_lib_host_awake_get(); */ -+ switch (cmd) { -+ case WMTDRV_CMD_ASSERT: -+ pOp->op.au4OpData[0] = 0; -+ break; -+ case WMTDRV_CMD_EXCEPTION: -+ pOp->op.au4OpData[0] = 1; -+ break; -+ case WMTDRV_CMD_NOACK_TEST: -+ pOp->op.au4OpData[0] = 3; -+ break; -+ case WMTDRV_CMD_WARNRST_TEST: -+ pOp->op.au4OpData[0] = 4; -+ break; -+ case WMTDRV_CMD_FWTRACE_TEST: -+ pOp->op.au4OpData[0] = 5; -+ break; -+ default: -+ if (WMTDRV_CMD_COEXDBG_00 <= cmd && WMTDRV_CMD_COEXDBG_15 >= cmd) { -+ pOp->op.au4OpData[0] = 2; -+ pOp->op.au4OpData[1] = cmd - 2; -+ } else { -+ pOp->op.au4OpData[0] = 0xff; -+ pOp->op.au4OpData[1] = 0xff; -+ } -+ pOp->op.au4OpData[2] = (SIZE_T) gCoexBuf.buffer; -+ pOp->op.au4OpData[3] = osal_sizeof(gCoexBuf.buffer); -+ break; -+ } -+ WMT_INFO_FUNC("CMD_TEST, opid(%d), par(%d, %d)\n", pOp->op.opId, pOp->op.au4OpData[0], pOp->op.au4OpData[1]); -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if ((cmd != WMTDRV_CMD_ASSERT) && -+ (cmd != WMTDRV_CMD_EXCEPTION) && -+ (cmd != WMTDRV_CMD_NOACK_TEST) && (cmd != WMTDRV_CMD_WARNRST_TEST) && (cmd != WMTDRV_CMD_FWTRACE_TEST)) { -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ gCoexBuf.availSize = 0; -+ } else { -+ gCoexBuf.availSize = pOp->op.au4OpData[3]; -+ WMT_INFO_FUNC("gCoexBuf.availSize = %d\n", gCoexBuf.availSize); -+ } -+ } -+ /* wmt_lib_host_awake_put(); */ -+ WMT_INFO_FUNC("CMD_TEST, opid (%d), par(%d, %d), ret(%d), result(%s)\n", -+ pOp->op.opId, -+ pOp->op.au4OpData[0], -+ pOp->op.au4OpData[1], bRet, MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); -+ -+ return 0; -+} -+ -+INT32 wmt_dbg_inband_rst(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (0 == par2) { -+ WMT_INFO_FUNC("inband reset test!!\n"); -+ mtk_wcn_stp_inband_reset(); -+ } else { -+ WMT_INFO_FUNC("STP context reset in host side!!\n"); -+ mtk_wcn_stp_flush_context(); -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_dbg_chip_rst(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (0 == par2) { -+ if (mtk_wcn_stp_is_ready()) { -+ WMT_INFO_FUNC("whole chip reset test\n"); -+ wmt_lib_cmb_rst(WMTRSTSRC_RESET_TEST); -+ } else { -+ WMT_INFO_FUNC("STP not ready , not to launch whole chip reset test\n"); -+ } -+ } else if (1 == par2) { -+ WMT_INFO_FUNC("chip hardware reset test\n"); -+ wmt_lib_hw_rst(); -+ } else { -+ WMT_INFO_FUNC("chip software reset test\n"); -+ wmt_lib_sw_rst(1); -+ } -+ return 0; -+} -+ -+INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (WMTDRV_TYPE_WMT > par2 || WMTDRV_TYPE_LPBK == par2) { -+ if (0 == par3) { -+ WMT_INFO_FUNC("function off test, type(%d)\n", par2); -+ mtk_wcn_wmt_func_off(par2); -+ } else { -+ WMT_INFO_FUNC("function on test, type(%d)\n", par2); -+ mtk_wcn_wmt_func_on(par2); -+ } -+ } else { -+ WMT_INFO_FUNC("function ctrl test, invalid type(%d)\n", par2); -+ } -+ return 0; -+} -+ -+INT32 wmt_dbg_raed_chipid(INT32 par1, INT32 par2, INT32 par3) -+{ -+ WMT_INFO_FUNC("chip version = %d\n", wmt_lib_get_icinfo(WMTCHIN_MAPPINGHWVER)); -+ return 0; -+} -+ -+INT32 wmt_dbg_wmt_dbg_level(INT32 par1, INT32 par2, INT32 par3) -+{ -+ par2 = (WMT_LOG_ERR <= par2 && WMT_LOG_LOUD >= par2) ? par2 : WMT_LOG_INFO; -+ wmt_lib_dbg_level_set(par2); -+ WMT_INFO_FUNC("set wmt log level to %d\n", par2); -+ return 0; -+} -+ -+INT32 wmt_dbg_stp_dbg_level(INT32 par1, INT32 par2, INT32 par3) -+{ -+ par2 = (0 <= par2 && 4 >= par2) ? par2 : 2; -+ mtk_wcn_stp_dbg_level(par2); -+ WMT_INFO_FUNC("set stp log level to %d\n", par2); -+ return 0; -+ -+} -+ -+INT32 wmt_dbg_reg_read(INT32 par1, INT32 par2, INT32 par3) -+{ -+ /* par2-->register address */ -+ /* par3-->register mask */ -+ UINT32 value = 0x0; -+ UINT32 iRet = -1; -+#if 0 -+ DISABLE_PSM_MONITOR(); -+ iRet = wmt_core_reg_rw_raw(0, par2, &value, par3); -+ ENABLE_PSM_MONITOR(); -+#endif -+ iRet = wmt_lib_reg_rw(0, par2, &value, par3); -+ WMT_INFO_FUNC("read combo chip register (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n", -+ par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value); -+ return 0; -+} -+ -+INT32 wmt_dbg_reg_write(INT32 par1, INT32 par2, INT32 par3) -+{ -+ /* par2-->register address */ -+ /* par3-->value to set */ -+ UINT32 iRet = -1; -+#if 0 -+ DISABLE_PSM_MONITOR(); -+ iRet = wmt_core_reg_rw_raw(1, par2, &par3, 0xffffffff); -+ ENABLE_PSM_MONITOR(); -+#endif -+ iRet = wmt_lib_reg_rw(1, par2, &par3, 0xffffffff); -+ WMT_INFO_FUNC("write combo chip register (0x%08x) with value (0x%08x) %s\n", -+ par2, par3, iRet != 0 ? "failed" : "succeed"); -+ return 0; -+} -+ -+INT32 wmt_dbg_efuse_read(INT32 par1, INT32 par2, INT32 par3) -+{ -+ /* par2-->efuse address */ -+ /* par3-->register mask */ -+ UINT32 value = 0x0; -+ UINT32 iRet = -1; -+ -+ iRet = wmt_lib_efuse_rw(0, par2, &value, par3); -+ WMT_INFO_FUNC("read combo chip efuse (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n", -+ par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value); -+ return 0; -+} -+ -+INT32 wmt_dbg_efuse_write(INT32 par1, INT32 par2, INT32 par3) -+{ -+ /* par2-->efuse address */ -+ /* par3-->value to set */ -+ UINT32 iRet = -1; -+ -+ iRet = wmt_lib_efuse_rw(1, par2, &par3, 0xffffffff); -+ WMT_INFO_FUNC("write combo chip efuse (0x%08x) with value (0x%08x) %s\n", -+ par2, par3, iRet != 0 ? "failed" : "succeed"); -+ return 0; -+} -+ -+INT32 wmt_dbg_sdio_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+/*remove sdio card detect/remove control because of btif is used*/ -+#if 0 -+ INT32 iRet = -1; -+ -+ iRet = wmt_lib_sdio_ctrl(0 != par2 ? 1 : 0); -+ WMT_INFO_FUNC("ctrl SDIO function %s\n", 0 == iRet ? "succeed" : "failed"); -+#endif -+ return 0; -+} -+ -+INT32 wmt_dbg_stp_dbg_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (1 < par2) { -+ mtk_wcn_stp_dbg_dump_package(); -+ return 0; -+ } -+ WMT_INFO_FUNC("%s stp debug function\n", 0 == par2 ? "disable" : "enable"); -+ if (0 == par2) -+ mtk_wcn_stp_dbg_disable(); -+ else if (1 == par2) -+ mtk_wcn_stp_dbg_enable(); -+ -+ return 0; -+} -+ -+INT32 wmt_dbg_stp_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ mtk_wcn_stp_dbg_log_ctrl(0 != par2 ? 1 : 0); -+ return 0; -+} -+ -+INT32 wmt_dbg_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ mtk_wcn_stp_coredump_flag_ctrl(0 != par2 ? 1 : 0); -+ return 0; -+} -+ -+INT32 wmt_dbg_fwinfor_from_emi(INT32 par1, INT32 par2, INT32 par3) -+{ -+ UINT32 offset = 0; -+ UINT32 len = 0; -+ UINT32 *pAddr = NULL; -+ UINT32 cur_idx_pagedtrace; -+ static UINT32 prev_idx_pagedtrace; -+ MTK_WCN_BOOL isBreak = MTK_WCN_BOOL_TRUE; -+ -+ offset = par2; -+ len = par3; -+ -+ buf_emi = kmalloc(sizeof(UINT8) * BUF_LEN_MAX, GFP_KERNEL); -+ if (!buf_emi) { -+ WMT_ERR_FUNC("buf kmalloc memory fail\n"); -+ return 0; -+ } -+ osal_memset(buf_emi, 0, BUF_LEN_MAX); -+ osal_memset(&gEmiBuf[0], 0, WMT_EMI_DEBUG_BUF_SIZE); -+ wmt_lib_get_fwinfor_from_emi(0, offset, &gEmiBuf[0], 0x100); -+ -+ if (offset == 1) { -+ do { -+ pAddr = (PUINT32) wmt_plat_get_emi_virt_add(0x24); -+ cur_idx_pagedtrace = *pAddr; -+ -+ if (cur_idx_pagedtrace > prev_idx_pagedtrace) { -+ len = cur_idx_pagedtrace - prev_idx_pagedtrace; -+ wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace, &gEmiBuf[0], len); -+ wmt_dbg_fwinfor_print_buff(len); -+ prev_idx_pagedtrace = cur_idx_pagedtrace; -+ } -+ -+ if (cur_idx_pagedtrace < prev_idx_pagedtrace) { -+ if (prev_idx_pagedtrace >= 0x8000) { -+ pr_debug("++ prev_idx_pagedtrace invalid ...++\n\\n"); -+ prev_idx_pagedtrace = 0x8000 - 1; -+ continue; -+ } -+ -+ len = 0x8000 - prev_idx_pagedtrace - 1; -+ wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace, &gEmiBuf[0], len); -+ pr_debug("\n\n -- CONNSYS paged trace ascii output (cont...) --\n\n"); -+ wmt_dbg_fwinfor_print_buff(len); -+ -+ len = cur_idx_pagedtrace; -+ wmt_lib_get_fwinfor_from_emi(1, 0x0, &gEmiBuf[0], len); -+ pr_debug("\n\n -- CONNSYS paged trace ascii output (end) --\n\n"); -+ wmt_dbg_fwinfor_print_buff(len); -+ prev_idx_pagedtrace = cur_idx_pagedtrace; -+ } -+ msleep(100); -+ } while (isBreak); -+ } -+ -+ pr_debug("\n\n -- control word --\n\n"); -+ wmt_dbg_fwinfor_print_buff(256); -+ if (len > 1024 * 4) -+ len = 1024 * 4; -+ -+ WMT_WARN_FUNC("get fw infor from emi at offset(0x%x),len(0x%x)\n", offset, len); -+ osal_memset(&gEmiBuf[0], 0, WMT_EMI_DEBUG_BUF_SIZE); -+ wmt_lib_get_fwinfor_from_emi(1, offset, &gEmiBuf[0], len); -+ -+ pr_debug("\n\n -- paged trace hex output --\n\n"); -+ wmt_dbg_fwinfor_print_buff(len); -+ pr_debug("\n\n -- paged trace ascii output --\n\n"); -+ wmt_dbg_fwinfor_print_buff(len); -+ kfree(buf_emi); -+ return 0; -+} -+ -+INT32 wmt_dbg_coex_test(INT32 par1, INT32 par2, INT32 par3) -+{ -+ WMT_INFO_FUNC("coexistance test cmd!!\n"); -+ return wmt_dbg_cmd_test_api(par2 + WMTDRV_CMD_COEXDBG_00); -+} -+ -+INT32 wmt_dbg_rst_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ WMT_INFO_FUNC("%s audo rst\n", 0 == par2 ? "disable" : "enable"); -+ mtk_wcn_stp_set_auto_rst(0 == par2 ? 0 : 1); -+ return 0; -+} -+ -+INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3) -+{ -+ -+ INT32 i = 0; -+ INT32 j = 0; -+ INT32 iRet = 0; -+ -+ i = 20; -+ while ((i--) > 0) { -+ WMT_INFO_FUNC("#### UT WMT and STP Function On/Off .... %d\n", i); -+ j = 10; -+ while ((j--) > 0) { -+ WMT_INFO_FUNC("#### BT On .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### GPS On .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPS); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### FM On .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### WIFI On .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### BT Off .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### GPS Off ....(%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_GPS); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### FM Off .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### WIFI Off ....(%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ } -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ } -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ WMT_INFO_FUNC("#### UT FAIL!!\n"); -+ else -+ WMT_INFO_FUNC("#### UT PASS!!\n"); -+ -+ return iRet; -+} -+ -+#if CFG_CORE_INTERNAL_TXRX -+ -+struct lpbk_package { -+ long payload_length; -+ unsigned char out_payload[2048]; -+ unsigned char in_payload[2048]; -+}; -+ -+static INT32 wmt_internal_loopback(INT32 count, INT32 max) -+{ -+ int ret = 0; -+ int loop; -+ int offset; -+ struct lpbk_package lpbk_buffer; -+ P_OSAL_OP pOp; -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ for (loop = 0; loop < count; loop++) { -+ /* <1> init buffer */ -+ osal_memset((void *)&lpbk_buffer, 0, sizeof(struct lpbk_package)); -+ lpbk_buffer.payload_length = max; -+ for (offset = 0; offset < max; offset++) -+ lpbk_buffer.out_payload[offset] = (offset + 1) /*for test use: begin from 1 */ & 0xFF; -+ -+ -+ memcpy(&gLpbkBuf[0], &lpbk_buffer.out_payload[0], max); -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ ret = -1; -+ break; -+ } -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_LPBK; -+ pOp->op.au4OpData[0] = lpbk_buffer.payload_length; /* packet length */ -+ pOp->op.au4OpData[1] = (UINT32) &gLpbkBuf[0]; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ ret = -2; -+ } -+ -+ ret = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == ret) { -+ WMT_WARN_FUNC("OPID(%d) type(%d)fail\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ ret = -3; -+ break; -+ } -+ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ memcpy(&lpbk_buffer.in_payload[0], &gLpbkBuf[0], max); -+ -+ ret = pOp->op.au4OpData[0]; -+ /*<3> compare result */ -+ if (memcmp(lpbk_buffer.in_payload, lpbk_buffer.out_payload, lpbk_buffer.payload_length)) { -+ WMT_INFO_FUNC("[%s] WMT_TEST_LPBK_CMD payload compare error\n", __func__); -+ ret = -4; -+ break; -+ } -+ WMT_ERR_FUNC("[%s] exec WMT_TEST_LPBK_CMD succeed(loop = %d, size = %ld)\n", __func__, loop, -+ lpbk_buffer.payload_length); -+ -+ } -+ -+ if (loop != count) -+ WMT_ERR_FUNC("fail at loop(%d) buf_length(%d)\n", loop, max); -+ -+ -+ return ret; -+} -+ -+INT32 wmt_dbg_internal_lpbk_test(INT32 par1, INT32 par2, INT32 par3) -+{ -+ UINT32 count; -+ UINT32 length; -+ -+ count = par1; -+ length = par2; -+ -+ WMT_INFO_FUNC("count[%d],length[%d]\n", count, length); -+ -+ wmt_core_lpbk_do_stp_init(); -+ -+ wmt_internal_loopback(count, length); -+ -+ wmt_core_lpbk_do_stp_deinit(); -+ return 0; -+} -+#endif -+ -+static INT32 wmt_dbg_set_mcu_clock(INT32 par1, INT32 par2, INT32 par3) -+{ -+ int ret = 0; -+ P_OSAL_OP pOp; -+ P_OSAL_SIGNAL pSignal = NULL; -+ UINT32 kind = 0; -+ -+ kind = par2; -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; -+ } -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_SET_MCU_CLK; -+ pOp->op.au4OpData[0] = kind; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ -+ WMT_INFO_FUNC("OPID(%d) kind(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) kind(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -2; -+ } -+ -+ ret = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == ret) { -+ WMT_WARN_FUNC("OPID(%d) kind(%d)fail(%d)\n", pOp->op.opId, pOp->op.au4OpData[0], ret); -+ return -3; -+ } -+ WMT_INFO_FUNC("OPID(%d) kind(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ return ret; -+} -+ -+static INT32 wmt_dbg_poll_cpupcr(INT32 par1, INT32 par2, INT32 par3) -+{ -+ UINT32 count = 0; -+ UINT16 sleep = 0; -+ UINT16 toAee = 0; -+ -+ count = par2; -+ sleep = (par3 & 0xF0) >> 4; -+ toAee = (par3 & 0x0F); -+ -+ WMT_INFO_FUNC("polling count[%d],polling sleep[%d],toaee[%d]\n", count, sleep, toAee); -+ wmt_lib_poll_cpupcr(count, sleep, toAee); -+ -+ return 0; -+} -+ -+#if CONSYS_ENALBE_SET_JTAG -+static INT32 wmt_dbg_jtag_flag_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ UINT32 en_flag = par2; -+ -+ wmt_lib_jtag_flag_set(en_flag); -+ return 0; -+} -+#endif -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 wmt_dbg_lte_to_wmt_test(UINT32 opcode, UINT32 msg_len) -+{ -+ ipc_ilm_t ilm; -+ local_para_struct *p_buf_str; -+ INT32 i = 0; -+ INT32 iRet = -1; -+ -+ WMT_INFO_FUNC("opcode(0x%02x),msg_len(%d)\n", opcode, msg_len); -+ p_buf_str = osal_malloc(osal_sizeof(local_para_struct) + msg_len); -+ if (NULL == p_buf_str) { -+ WMT_ERR_FUNC("kmalloc for local para ptr structure failed.\n"); -+ return -1; -+ } -+ p_buf_str->msg_len = msg_len; -+ for (i = 0; i < msg_len; i++) -+ p_buf_str->data[i] = i; -+ -+ ilm.local_para_ptr = p_buf_str; -+ ilm.msg_id = opcode; -+ -+ iRet = wmt_lib_handle_idc_msg(&ilm); -+ osal_free(p_buf_str); -+ return iRet; -+ -+} -+ -+static INT32 wmt_dbg_lte_coex_test(INT32 par1, INT32 par2, INT32 par3) -+{ -+ UINT8 *local_buffer = NULL; -+ UINT32 handle_len; -+ INT32 iRet = -1; -+ static UINT8 wmt_to_lte_test_evt1[] = { 0x02, 0x16, 0x0d, 0x00, -+ 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, -+ 0xa, 0xb -+ }; -+ static UINT8 wmt_to_lte_test_evt2[] = { 0x02, 0x16, 0x09, 0x00, -+ 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 -+ }; -+ static UINT8 wmt_to_lte_test_evt3[] = { 0x02, 0x16, 0x02, 0x00, -+ 0x02, 0xff -+ }; -+ static UINT8 wmt_to_lte_test_evt4[] = { 0x02, 0x16, 0x0d, 0x00, -+ 0x03, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, -+ 0xa, 0xb -+ }; -+ -+ local_buffer = kmalloc(512, GFP_KERNEL); -+ if (!local_buffer) { -+ WMT_ERR_FUNC("local_buffer kmalloc memory fail\n"); -+ return 0; -+ } -+ -+ if (par2 == 1) { -+ handle_len = -+ wmt_idc_msg_to_lte_handing_for_test(&wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); -+ if (handle_len != osal_sizeof(wmt_to_lte_test_evt1)) { -+ WMT_ERR_FUNC("par2=1,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", -+ handle_len, osal_sizeof(wmt_to_lte_test_evt1)); -+ } else { -+ WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); -+ } -+ } -+ if (par2 == 2) { -+ osal_memcpy(&local_buffer[0], &wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); -+ osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1)], -+ &wmt_to_lte_test_evt2[0], osal_sizeof(wmt_to_lte_test_evt2)); -+ -+ handle_len = -+ wmt_idc_msg_to_lte_handing_for_test(&local_buffer[0], -+ osal_sizeof(wmt_to_lte_test_evt1) + -+ osal_sizeof(wmt_to_lte_test_evt2)); -+ if (handle_len != osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)) { -+ WMT_ERR_FUNC("par2=2,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", -+ handle_len, osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)); -+ } else { -+ WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); -+ } -+ } -+ if (par2 == 3) { -+ osal_memcpy(&local_buffer[0], &wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); -+ osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1)], -+ &wmt_to_lte_test_evt2[0], osal_sizeof(wmt_to_lte_test_evt2)); -+ osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)], -+ &wmt_to_lte_test_evt3[0], osal_sizeof(wmt_to_lte_test_evt3)); -+ -+ handle_len = wmt_idc_msg_to_lte_handing_for_test(&local_buffer[0], osal_sizeof(wmt_to_lte_test_evt1) + -+ osal_sizeof(wmt_to_lte_test_evt2) + -+ osal_sizeof(wmt_to_lte_test_evt3)); -+ if (handle_len != -+ osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2) + -+ osal_sizeof(wmt_to_lte_test_evt3)) { -+ WMT_ERR_FUNC("par2=3,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", handle_len, -+ osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2) + -+ osal_sizeof(wmt_to_lte_test_evt3)); -+ } else { -+ WMT_INFO_FUNC("par3=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); -+ } -+ } -+ if (par2 == 4) { -+ handle_len = -+ wmt_idc_msg_to_lte_handing_for_test(&wmt_to_lte_test_evt4[0], osal_sizeof(wmt_to_lte_test_evt4)); -+ if (handle_len != osal_sizeof(wmt_to_lte_test_evt4)) { -+ WMT_ERR_FUNC("par2=1,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", -+ handle_len, osal_sizeof(wmt_to_lte_test_evt4)); -+ } else { -+ WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); -+ } -+ } -+ if (par2 == 5) { -+ if (par3 >= 1024) -+ par3 = 1024; -+ -+ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND, par3); -+ WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND test result(%d)\n", iRet); -+ } -+ if (par2 == 6) { -+ if (par3 >= 1024) -+ par3 = 1024; -+ -+ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND, par3); -+ WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND test result(%d)\n", iRet); -+ } -+ if (par2 == 7) { -+ if (par3 >= 1024) -+ par3 = 1024; -+ -+ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND, par3); -+ WMT_INFO_FUNC("IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND test result(%d)\n", iRet); -+ } -+ if (par2 == 8) { -+ if (par3 >= 1024) -+ par3 = 1024; -+ -+ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_TX_IND, par3); -+ WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_TX_IND test result(%d)\n", iRet); -+ } -+ if (par2 == 9) { -+ if (par3 > 0) -+ wmt_core_set_flag_for_test(1); -+ else -+ wmt_core_set_flag_for_test(0); -+ } -+ return 0; -+ kfree(local_buffer); -+} -+#endif -+ -+static ssize_t wmt_dev_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ -+ INT32 retval = 0; -+ INT32 i_ret = 0; -+ PINT8 warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"; -+ -+ if (*f_pos > 0) { -+ retval = 0; -+ } else { -+ /*len = sprintf(page, "%d\n", g_psm_enable); */ -+ if (gCoexBuf.availSize <= 0) { -+ WMT_INFO_FUNC("no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"); -+ retval = osal_strlen(warn_msg) + 1; -+ if (count < retval) -+ retval = count; -+ -+ i_ret = copy_to_user(buf, warn_msg, retval); -+ if (i_ret) { -+ WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ *f_pos += retval; -+ } else { -+ INT32 i = 0; -+ INT32 len = 0; -+ INT8 msg_info[128]; -+ INT32 max_num = 0; -+ /*we do not check page buffer, because there are only -+ * 100 bytes in g_coex_buf, no reason page buffer is not -+ * enough, a bomb is placed here on unexpected condition -+ */ -+ -+ WMT_INFO_FUNC("%d bytes available\n", gCoexBuf.availSize); -+ max_num = ((osal_sizeof(msg_info) > count ? osal_sizeof(msg_info) : count) - 1) / 5; -+ -+ if (max_num > gCoexBuf.availSize) -+ max_num = gCoexBuf.availSize; -+ else -+ WMT_INFO_FUNC("round to %d bytes due to local buffer size limitation\n", max_num); -+ -+ -+ for (i = 0; i < max_num; i++) -+ len += osal_sprintf(msg_info + len, "0x%02x ", gCoexBuf.buffer[i]); -+ -+ -+ len += osal_sprintf(msg_info + len, "\n"); -+ retval = len; -+ -+ i_ret = copy_to_user(buf, msg_info, retval); -+ if (i_ret) { -+ WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ *f_pos += retval; -+ -+ } -+ } -+ gCoexBuf.availSize = 0; -+err_exit: -+ -+ return retval; -+} -+ -+static ssize_t wmt_dev_dbg_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos) -+{ -+ INT8 buf[256]; -+ PINT8 pBuf; -+ ssize_t len = count; -+ INT32 x = 0, y = 0, z = 0; -+ PINT8 pToken = NULL; -+ PINT8 pDelimiter = " \t"; -+ long res; -+ INT32 ret; -+ -+ WMT_INFO_FUNC("write parameter len = %d\n\r", (INT32) len); -+ if (len >= osal_sizeof(buf)) { -+ WMT_ERR_FUNC("input handling fail!\n"); -+ len = osal_sizeof(buf) - 1; -+ return -1; -+ } -+ -+ if (copy_from_user(buf, buffer, len)) -+ return -EFAULT; -+ -+ buf[len] = '\0'; -+ WMT_INFO_FUNC("write parameter data = %s\n\r", buf); -+ -+ pBuf = buf; -+ pToken = osal_strsep(&pBuf, pDelimiter); -+ -+ if (pToken != NULL) { -+ ret = osal_strtol(pToken, 16, &res); -+ if (ret) { -+ WMT_ERR_FUNC("get x fail(%d)\n", ret); -+ x = 0; -+ } -+ x = res; -+ } else { -+ x = 0; -+ } -+ -+ pToken = osal_strsep(&pBuf, "\t\n "); -+ if (pToken != NULL) { -+ ret = osal_strtol(pToken, 16, &res); -+ if (ret) { -+ WMT_ERR_FUNC("get y fail(%d)\n", ret); -+ y = 0; -+ } -+ y = res; -+ WMT_INFO_FUNC("y = 0x%08x\n\r", y); -+ } else { -+ y = 3000; -+ /*efuse, register read write default value */ -+ if (0x11 == x || 0x12 == x || 0x13 == x) -+ y = 0x80000000; -+ -+ } -+ -+ pToken = osal_strsep(&pBuf, "\t\n "); -+ if (pToken != NULL) { -+ ret = osal_strtol(pToken, 16, &res); -+ if (ret) { -+ WMT_ERR_FUNC("get z fail(%d)\n", ret); -+ z = 0; -+ } -+ z = res; -+ } else { -+ z = 10; -+ /*efuse, register read write default value */ -+ if (0x11 == x || 0x12 == x || 0x13 == x) -+ z = 0xffffffff; -+ -+ } -+ -+ WMT_WARN_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); -+ -+ if (osal_array_size(wmt_dev_dbg_func) > x && NULL != wmt_dev_dbg_func[x]) -+ (*wmt_dev_dbg_func[x]) (x, y, z); -+ else -+ WMT_WARN_FUNC("no handler defined for command id(0x%08x)\n\r", x); -+ -+ return len; -+} -+ -+INT32 wmt_dev_dbg_setup(VOID) -+{ -+ static const struct file_operations wmt_dbg_fops = { -+ .owner = THIS_MODULE, -+ .read = wmt_dev_dbg_read, -+ .write = wmt_dev_dbg_write, -+ }; -+ gWmtDbgEntry = proc_create(WMT_DBG_PROCNAME, 0664, NULL, &wmt_dbg_fops); -+ if (gWmtDbgEntry == NULL) { -+ WMT_ERR_FUNC("Unable to create /proc entry\n\r"); -+ return -1; -+ } -+ return 0; -+} -+ -+INT32 wmt_dev_dbg_remove(VOID) -+{ -+ if (NULL != gWmtDbgEntry) -+ remove_proc_entry(WMT_DBG_PROCNAME, NULL); -+ -+#if CFG_WMT_PS_SUPPORT -+ wmt_lib_ps_deinit(); -+#endif -+ return 0; -+} -+#endif -+ -+#if CFG_WMT_PROC_FOR_AEE -+ -+static ssize_t wmt_dev_proc_for_aee_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ INT32 retval = 0; -+ UINT32 len = 0; -+ -+ WMT_INFO_FUNC("%s: count %d pos %lld\n", __func__, count, *f_pos); -+ -+ if (0 == *f_pos) { -+ pBuf = wmt_lib_get_cpupcr_xml_format(&len); -+ g_buf_len = len; -+ WMT_INFO_FUNC("wmt_dev:wmt for aee buffer len(%d)\n", g_buf_len); -+ } -+ -+ if (g_buf_len >= count) { -+ -+ retval = copy_to_user(buf, pBuf, count); -+ if (retval) { -+ WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ -+ *f_pos += count; -+ g_buf_len -= count; -+ pBuf += count; -+ WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len); -+ -+ retval = count; -+ } else if (0 != g_buf_len) { -+ -+ retval = copy_to_user(buf, pBuf, g_buf_len); -+ if (retval) { -+ WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ -+ *f_pos += g_buf_len; -+ len = g_buf_len; -+ g_buf_len = 0; -+ pBuf += len; -+ retval = len; -+ WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len); -+ } else { -+ WMT_INFO_FUNC("wmt_dev: no data available for aee\n"); -+ retval = 0; -+ } -+err_exit: -+ return retval; -+} -+ -+static ssize_t wmt_dev_proc_for_aee_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ WMT_TRC_FUNC(); -+ return 0; -+} -+ -+INT32 wmt_dev_proc_for_aee_setup(VOID) -+{ -+ static const struct file_operations wmt_aee_fops = { -+ .owner = THIS_MODULE, -+ .read = wmt_dev_proc_for_aee_read, -+ .write = wmt_dev_proc_for_aee_write, -+ }; -+ -+ gWmtDbgEntry = proc_create(WMT_AEE_PROCNAME, 0664, NULL, &wmt_aee_fops); -+ if (gWmtDbgEntry == NULL) { -+ WMT_ERR_FUNC("Unable to create /proc entry\n\r"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_dev_proc_for_aee_remove(VOID) -+{ -+ if (NULL != gWmtAeeEntry) -+ remove_proc_entry(WMT_AEE_PROCNAME, NULL); -+ -+ return 0; -+} -+#endif -+ -+VOID wmt_dev_rx_event_cb(VOID) -+{ -+ u4RxFlag = 1; -+ atomic_inc(&gRxCount); -+ if (NULL != gpRxEvent) { -+ /* u4RxFlag = 1; */ -+ /* atomic_inc(&gRxCount); */ -+ wake_up_interruptible(&gpRxEvent->waitQueue); -+ } else { -+ /* WMT_ERR_FUNC("null gpRxEvent, flush rx!\n"); */ -+ /* wmt_lib_flush_rx(); */ -+ } -+} -+ -+INT32 wmt_dev_rx_timeout(P_OSAL_EVENT pEvent) -+{ -+ -+ UINT32 ms = pEvent->timeoutValue; -+ long lRet = 0; -+ -+ gpRxEvent = pEvent; -+ if (0 != ms) -+ lRet = wait_event_interruptible_timeout(gpRxEvent->waitQueue, 0 != u4RxFlag, msecs_to_jiffies(ms)); -+ else -+ lRet = wait_event_interruptible(gpRxEvent->waitQueue, u4RxFlag != 0); -+ -+ u4RxFlag = 0; -+/* gpRxEvent = NULL; */ -+ if (atomic_dec_return(&gRxCount)) { -+ WMT_ERR_FUNC("gRxCount != 0 (%d), reset it!\n", atomic_read(&gRxCount)); -+ atomic_set(&gRxCount, 0); -+ } -+ -+ return lRet; -+} -+ -+INT32 wmt_dev_read_file(PUINT8 pName, const PPUINT8 ppBufPtr, INT32 offset, INT32 padSzBuf) -+{ -+ INT32 iRet = -1; -+ struct file *fd; -+ /* ssize_t iRet; */ -+ INT32 file_len; -+ INT32 read_len; -+ PVOID pBuf; -+ mm_segment_t fs; -+ -+ /* struct cred *cred = get_task_cred(current); */ -+ //const struct cred *cred = get_current_cred(); -+ -+ if (!ppBufPtr) { -+ WMT_ERR_FUNC("invalid ppBufptr!\n"); -+ return -1; -+ } -+ *ppBufPtr = NULL; -+ -+ fd = filp_open(pName, O_RDONLY, 0); -+ if (IS_ERR(fd)) { -+ WMT_ERR_FUNC("error code:%d\n", PTR_ERR(fd)); -+ return -2; -+ } -+ -+ if(fd->f_op == NULL) { -+ printk(KERN_ERR "invalid file op \r\n"); -+ return -3; -+ } -+ -+#if 0 -+ if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) { -+ WMT_ERR_FUNC("failed to open or read!(0x%p, %d, %d, %d)\n", fd, PTR_ERR(fd), cred->fsuid, cred->fsgid); -+ if (IS_ERR(fd)) -+ WMT_ERR_FUNC("error code:%d\n", PTR_ERR(fd)); -+ return -1; -+ } -+#endif -+ file_len = fd->f_path.dentry->d_inode->i_size; -+ file_len = fd->f_op->llseek(fd, 0, 2); -+ fd->f_op->llseek(fd, 0, 0); -+ pBuf = vmalloc((file_len + BCNT_PATCH_BUF_HEADROOM + 3) & ~0x3UL); -+ if (!pBuf) { -+ WMT_ERR_FUNC("failed to vmalloc(%d)\n", (INT32) ((file_len + 3) & ~0x3UL)); -+ goto read_file_done; -+ } -+ -+ do { -+ if (fd->f_pos != offset) { -+ if (fd->f_op->llseek) { -+ if (fd->f_op->llseek(fd, offset, 0) != offset) { -+ WMT_ERR_FUNC("failed to seek!!\n"); -+ goto read_file_done; -+ } -+ } else { -+ fd->f_pos = offset; -+ } -+ } -+ -+ fs=get_fs(); -+ read_len = vfs_read(fd, pBuf + padSzBuf, file_len, &fd->f_pos); -+ set_fs(fs); -+ if (read_len != file_len) -+ WMT_WARN_FUNC("read abnormal: read_len(%d), file_len(%d)\n", read_len, file_len); -+ -+ } while (false); -+ -+ iRet = 0; -+ *ppBufPtr = pBuf; -+ -+read_file_done: -+ if (iRet) { -+ if (pBuf) -+ vfree(pBuf); -+ -+ } -+ -+ filp_close(fd, NULL); -+ -+ return (iRet) ? iRet : read_len; -+} -+ -+/* TODO: [ChangeFeature][George] refine this function name for general filesystem read operation, not patch only. */ -+INT32 wmt_dev_patch_get(PUINT8 pPatchName, osal_firmware **ppPatch, INT32 padSzBuf) -+{ -+ INT32 iRet = -1; -+ osal_firmware *pfw; -+ uid_t orig_uid; -+ gid_t orig_gid; -+ -+ /* struct cred *cred = get_task_cred(current); */ -+ struct cred *cred = (struct cred *)get_current_cred(); -+ -+ mm_segment_t orig_fs = get_fs(); -+ -+ if (*ppPatch) { -+ WMT_WARN_FUNC("f/w patch already exists\n"); -+ if ((*ppPatch)->data) -+ vfree((*ppPatch)->data); -+ -+ kfree(*ppPatch); -+ *ppPatch = NULL; -+ } -+ -+ if (!osal_strlen(pPatchName)) { -+ WMT_ERR_FUNC("empty f/w name\n"); -+ osal_assert((osal_strlen(pPatchName) > 0)); -+ return -1; -+ } -+ -+ pfw = kzalloc(sizeof(osal_firmware), /*GFP_KERNEL */ GFP_ATOMIC); -+ if (!pfw) { -+ WMT_ERR_FUNC("kzalloc(%d) fail\n", sizeof(osal_firmware)); -+ return -2; -+ } -+ -+ orig_uid = cred->fsuid.val; -+ orig_gid = cred->fsgid.val; -+ cred->fsuid.val = cred->fsgid.val = 0; -+ -+ set_fs(get_ds()); -+ -+ /* load patch file from fs */ -+ iRet = wmt_dev_read_file(pPatchName, (const PPUINT8)&pfw->data, 0, padSzBuf); -+ set_fs(orig_fs); -+ -+ cred->fsuid.val = orig_uid; -+ cred->fsgid.val = orig_gid; -+ -+ -+ if (iRet > 0) { -+ pfw->size = iRet; -+ *ppPatch = pfw; -+ WMT_DBG_FUNC("load (%s) to addr(0x%p) success\n", pPatchName, pfw->data); -+ return 0; -+ } -+ kfree(pfw); -+ *ppPatch = NULL; -+ WMT_ERR_FUNC("load file (%s) fail, iRet(%d)\n", pPatchName, iRet); -+ return -1; -+} -+ -+INT32 wmt_dev_patch_put(osal_firmware **ppPatch) -+{ -+ if (NULL != *ppPatch) { -+ if ((*ppPatch)->data) -+ vfree((*ppPatch)->data); -+ -+ kfree(*ppPatch); -+ *ppPatch = NULL; -+ } -+ return 0; -+} -+ -+VOID wmt_dev_patch_info_free(VOID) -+{ -+ -+ kfree(pPatchInfo); -+ pPatchInfo = NULL; -+ -+} -+ -+MTK_WCN_BOOL wmt_dev_is_file_exist(PUINT8 pFileName) -+{ -+ struct file *fd = NULL; -+ /* ssize_t iRet; */ -+ INT32 fileLen = -1; -+ const struct cred *cred = get_current_cred(); -+ -+ if (pFileName == NULL) { -+ WMT_ERR_FUNC("invalid file name pointer(%p)\n", pFileName); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ if (osal_strlen(pFileName) < osal_strlen(defaultPatchName)) { -+ WMT_ERR_FUNC("invalid file name(%s)\n", pFileName); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ /* struct cred *cred = get_task_cred(current); */ -+ -+ fd = filp_open(pFileName, O_RDONLY, 0); -+ if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) { -+ WMT_ERR_FUNC("failed to open or read(%s)!(0x%p, %d, %d)\n", pFileName, fd, cred->fsuid, cred->fsgid); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ fileLen = fd->f_path.dentry->d_inode->i_size; -+ filp_close(fd, NULL); -+ fd = NULL; -+ if (fileLen <= 0) { -+ WMT_ERR_FUNC("invalid file(%s), length(%d)\n", pFileName, fileLen); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ WMT_ERR_FUNC("valid file(%s), length(%d)\n", pFileName, fileLen); -+ return true; -+ -+} -+ -+/* static unsigned long count_last_access_sdio = 0; */ -+static unsigned long count_last_access_btif; -+static unsigned long jiffies_last_poll; -+ -+#if 0 -+static INT32 wmt_dev_tra_sdio_update(void) -+{ -+ count_last_access_sdio += 1; -+ /* WMT_INFO_FUNC("jiffies_last_access_sdio: jiffies = %ul\n", jiffies); */ -+ -+ return 0; -+} -+#endif -+ -+extern INT32 wmt_dev_tra_bitf_update(void) -+{ -+ count_last_access_btif += 1; -+ /* WMT_INFO_FUNC("jiffies_last_access_btif: jiffies = %ul\n", jiffies); */ -+ -+ return 0; -+} -+ -+static UINT32 wmt_dev_tra_ahb_poll(void) -+{ -+#define TIME_THRESHOLD_TO_TEMP_QUERY 3000 -+#define COUNT_THRESHOLD_TO_TEMP_QUERY 200 -+ -+ unsigned long ahb_during_count = 0; -+ unsigned long poll_during_time = 0; -+ -+ /* if (jiffies > jiffies_last_poll) */ -+ if (time_after(jiffies, jiffies_last_poll)) -+ poll_during_time = jiffies - jiffies_last_poll; -+ else -+ poll_during_time = 0xffffffff; -+ -+ -+ WMT_DBG_FUNC("**jiffies_to_mesecs(0xffffffff) = %lu\n", jiffies_to_msecs(0xffffffff)); -+ -+ if (jiffies_to_msecs(poll_during_time) < TIME_THRESHOLD_TO_TEMP_QUERY) { -+ WMT_DBG_FUNC("**poll_during_time = %lu < %lu, not to query\n", -+ jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY); -+ return -1; -+ } -+ /* ahb_during_count = count_last_access_sdio; */ -+ if (NULL == mtk_wcn_wlan_bus_tx_cnt) { -+ WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt null pointer\n"); -+ return -1; -+ } -+ ahb_during_count = (*mtk_wcn_wlan_bus_tx_cnt) (); -+ -+ if (ahb_during_count < COUNT_THRESHOLD_TO_TEMP_QUERY) { -+ WMT_DBG_FUNC("**ahb_during_count = %lu < %lu, not to query\n", -+ ahb_during_count, COUNT_THRESHOLD_TO_TEMP_QUERY); -+ return -2; -+ } -+ -+ if (NULL == mtk_wcn_wlan_bus_tx_cnt_clr) { -+ WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt_clr null pointer\n"); -+ return -3; -+ } -+ (*mtk_wcn_wlan_bus_tx_cnt_clr) (); -+ /* count_last_access_sdio = 0; */ -+ jiffies_last_poll = jiffies; -+ -+ WMT_INFO_FUNC("**poll_during_time = %lu > %lu, ahb_during_count = %lu > %lu, query\n", -+ jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY, -+ jiffies_to_msecs(ahb_during_count), COUNT_THRESHOLD_TO_TEMP_QUERY); -+ -+ return 0; -+} -+ -+long wmt_dev_tm_temp_query(void) -+{ -+#define HISTORY_NUM 5 -+#define TEMP_THRESHOLD 65 -+#define REFRESH_TIME 300 /* sec */ -+ -+ static INT32 temp_table[HISTORY_NUM] = { 99 }; /* not query yet. */ -+ static INT32 idx_temp_table; -+ static struct timeval query_time, now_time; -+ -+ INT8 query_cond = 0; -+ INT32 current_temp = 0; -+ INT32 index = 0; -+ long return_temp = 0; -+ /* Query condition 1: */ -+ /* If we have the high temperature records on the past, we continue to query/monitor */ -+ /* the real temperature until cooling */ -+ for (index = 0; index < HISTORY_NUM; index++) { -+ if (temp_table[index] >= TEMP_THRESHOLD) { -+ query_cond = 1; -+ WMT_DBG_FUNC("temperature table is still initial value, we should query temp temperature..\n"); -+ } -+ } -+ -+ do_gettimeofday(&now_time); -+#if 1 -+ /* Query condition 2: */ -+ /* Moniter the ahb bus activity to decide if we have the need to query temperature. */ -+ if (!query_cond) { -+ if (wmt_dev_tra_ahb_poll() == 0) { -+ query_cond = 1; -+ WMT_INFO_FUNC("ahb traffic , we must query temperature..\n"); -+ } else { -+ WMT_DBG_FUNC("ahb idle traffic ....\n"); -+ } -+ -+ /* only WIFI tx power might make temperature varies largely */ -+#if 0 -+ if (!query_cond) { -+ last_access_time = wmt_dev_tra_uart_poll(); -+ if (jiffies_to_msecs(last_access_time) < TIME_THRESHOLD_TO_TEMP_QUERY) { -+ query_cond = 1; -+ WMT_DBG_FUNC("uart busy traffic , we must query temperature..\n"); -+ } else { -+ WMT_DBG_FUNC("uart still idle traffic , we don't query temp temperature..\n"); -+ } -+ } -+#endif -+ } -+#endif -+ /* Query condition 3: */ -+ /* If the query time exceeds the a certain of period, refresh temp table. */ -+ /* */ -+ if (!query_cond) { -+ /* time overflow, we refresh temp table again for simplicity! */ -+ if ((now_time.tv_sec < query_time.tv_sec) || -+ ((now_time.tv_sec > query_time.tv_sec) && (now_time.tv_sec - query_time.tv_sec) > REFRESH_TIME)) { -+ query_cond = 1; -+ -+ WMT_INFO_FUNC("It is long time (> %d sec) not to query, we must query temp temperature..\n", -+ REFRESH_TIME); -+ for (index = 0; index < HISTORY_NUM; index++) -+ temp_table[index] = 99; -+ -+ } -+ } -+ -+ if (query_cond) { -+ /* update the temperature record */ -+ mtk_wcn_wmt_therm_ctrl(WMTTHERM_ENABLE); -+ current_temp = mtk_wcn_wmt_therm_ctrl(WMTTHERM_READ); -+ mtk_wcn_wmt_therm_ctrl(WMTTHERM_DISABLE); -+ idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM; -+ temp_table[idx_temp_table] = current_temp; -+ do_gettimeofday(&query_time); -+ -+ WMT_INFO_FUNC("[Thermal] current_temp = 0x%x\n", (current_temp & 0xFF)); -+ } else { -+ current_temp = temp_table[idx_temp_table]; -+ idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM; -+ temp_table[idx_temp_table] = current_temp; -+ } -+ -+ /* */ -+ /* Dump information */ -+ /* */ -+ WMT_DBG_FUNC("[Thermal] idx_temp_table = %d\n", idx_temp_table); -+ WMT_DBG_FUNC("[Thermal] now.time = %d, query.time = %d, REFRESH_TIME = %d\n", now_time.tv_sec, -+ query_time.tv_sec, REFRESH_TIME); -+ -+ WMT_DBG_FUNC("[0] = %d, [1] = %d, [2] = %d, [3] = %d, [4] = %d\n----\n", -+ temp_table[0], temp_table[1], temp_table[2], temp_table[3], temp_table[4]); -+ -+ return_temp = ((current_temp & 0x80) == 0x0) ? current_temp : (-1) * (current_temp & 0x7f); -+ -+ return return_temp; -+} -+ -+ssize_t WMT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ INT32 iRet = 0; -+ UINT8 wrBuf[NAME_MAX + 1] = { 0 }; -+ INT32 copySize = (count < NAME_MAX) ? count : NAME_MAX; -+ -+ WMT_LOUD_FUNC("count:%d copySize:%d\n", count, copySize); -+ -+ if (copySize > 0) { -+ if (copy_from_user(wrBuf, buf, copySize)) { -+ iRet = -EFAULT; -+ goto write_done; -+ } -+ iRet = copySize; -+ wrBuf[NAME_MAX] = '\0'; -+ -+ if (!strncasecmp(wrBuf, "ok", NAME_MAX)) { -+ WMT_DBG_FUNC("resp str ok\n"); -+ /* pWmtDevCtx->cmd_result = 0; */ -+ wmt_lib_trigger_cmd_signal(0); -+ } else { -+ WMT_WARN_FUNC("warning resp str (%s)\n", wrBuf); -+ /* pWmtDevCtx->cmd_result = -1; */ -+ wmt_lib_trigger_cmd_signal(-1); -+ } -+ /* complete(&pWmtDevCtx->cmd_comp); */ -+ -+ } -+ -+write_done: -+ return iRet; -+} -+ -+ssize_t WMT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ INT32 iRet = 0; -+ PUINT8 pCmd = NULL; -+ UINT32 cmdLen = 0; -+ -+ pCmd = wmt_lib_get_cmd(); -+ -+ if (pCmd != NULL) { -+ cmdLen = osal_strlen(pCmd) < NAME_MAX ? osal_strlen(pCmd) : NAME_MAX; -+ WMT_DBG_FUNC("cmd str(%s)\n", pCmd); -+ if (copy_to_user(buf, pCmd, cmdLen)) -+ iRet = -EFAULT; -+ else -+ iRet = cmdLen; -+ -+ } -+#if 0 -+ if (test_and_clear_bit(WMT_STAT_CMD, &pWmtDevCtx->state)) { -+ iRet = osal_strlen(localBuf) < NAME_MAX ? osal_strlen(localBuf) : NAME_MAX; -+ /* we got something from STP driver */ -+ WMT_DBG_FUNC("copy cmd to user by read:%s\n", localBuf); -+ if (copy_to_user(buf, localBuf, iRet)) { -+ iRet = -EFAULT; -+ goto read_done; -+ } -+ } -+#endif -+ return iRet; -+} -+ -+unsigned int WMT_poll(struct file *filp, poll_table *wait) -+{ -+ UINT32 mask = 0; -+ P_OSAL_EVENT pEvent = wmt_lib_get_cmd_event(); -+ -+ poll_wait(filp, &pEvent->waitQueue, wait); -+ /* empty let select sleep */ -+ if (MTK_WCN_BOOL_TRUE == wmt_lib_get_cmd_status()) -+ mask |= POLLIN | POLLRDNORM; /* readable */ -+ -+#if 0 -+ if (test_bit(WMT_STAT_CMD, &pWmtDevCtx->state)) -+ mask |= POLLIN | POLLRDNORM; /* readable */ -+ -+#endif -+ mask |= POLLOUT | POLLWRNORM; /* writable */ -+ return mask; -+} -+ -+/* INT32 WMT_ioctl(struct inode *inode, struct file *filp, UINT32 cmd, unsigned long arg) */ -+long WMT_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ -+ INT32 iRet = 0; -+ UINT8 *pBuffer = NULL; -+ -+ WMT_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg); -+ switch (cmd) { -+ case WMT_IOCTL_SET_PATCH_NAME: /* patch location */ -+ { -+ -+ pBuffer = kmalloc(NAME_MAX + 1, GFP_KERNEL); -+ if (!pBuffer) { -+ WMT_ERR_FUNC("pBuffer kmalloc memory fail\n"); -+ return 0; -+ } -+ if (copy_from_user(pBuffer, (void *)arg, NAME_MAX)) { -+ iRet = -EFAULT; -+ kfree(pBuffer); -+ break; -+ } -+ pBuffer[NAME_MAX] = '\0'; -+ wmt_lib_set_patch_name(pBuffer); -+ kfree(pBuffer); -+ } -+ break; -+ -+ case WMT_IOCTL_SET_STP_MODE: /* stp/hif/fm mode */ -+ -+ /* set hif conf */ -+ do { -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal = NULL; -+ P_WMT_HIF_CONF pHif = NULL; -+ -+ iRet = wmt_lib_set_hif(arg); -+ if (0 != iRet) { -+ WMT_INFO_FUNC("wmt_lib_set_hif fail\n"); -+ break; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_INFO_FUNC("get_free_lxop fail\n"); -+ break; -+ } -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_HIF_CONF; -+ -+ pHif = wmt_lib_get_hif(); -+ -+ osal_memcpy(&pOp->op.au4OpData[0], pHif, sizeof(WMT_HIF_CONF)); -+ pOp->op.u4InfoBit = WMT_OP_HIF_BIT; -+ pSignal->timeoutValue = 0; -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ WMT_DBG_FUNC("WMT_OPID_HIF_CONF result(%d)\n", bRet); -+ iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; -+ } while (0); -+ -+ break; -+ -+ case WMT_IOCTL_FUNC_ONOFF_CTRL: /* test turn on/off func */ -+ -+ do { -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ -+ if (arg & 0x80000000) -+ bRet = mtk_wcn_wmt_func_on(arg & 0xF); -+ else -+ bRet = mtk_wcn_wmt_func_off(arg & 0xF); -+ -+ iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; -+ } while (0); -+ -+ break; -+ -+ case WMT_IOCTL_LPBK_POWER_CTRL: -+ /*switch Loopback function on/off -+ arg: bit0 = 1:turn loopback function on -+ bit0 = 0:turn loopback function off -+ */ -+ do { -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ -+ if (arg & 0x01) -+ bRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK); -+ else -+ bRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK); -+ -+ iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; -+ } while (0); -+ -+ break; -+ -+ case WMT_IOCTL_LPBK_TEST: -+ do { -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ UINT32 u4Wait; -+ /* UINT8 lpbk_buf[1024] = {0}; */ -+ UINT32 effectiveLen = 0; -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ if (copy_from_user(&effectiveLen, (void *)arg, sizeof(effectiveLen))) { -+ iRet = -EFAULT; -+ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); -+ break; -+ } -+ if (effectiveLen > sizeof(gLpbkBuf)) { -+ iRet = -EFAULT; -+ WMT_ERR_FUNC("length is too long\n"); -+ break; -+ } -+ WMT_DBG_FUNC("len = %d\n", effectiveLen); -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ iRet = -EFAULT; -+ break; -+ } -+ u4Wait = 2000; -+ if (copy_from_user(&gLpbkBuf[0], (void *)arg + sizeof(unsigned long), effectiveLen)) { -+ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); -+ iRet = -EFAULT; -+ break; -+ } -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_LPBK; -+ pOp->op.au4OpData[0] = effectiveLen; /* packet length */ -+ pOp->op.au4OpData[1] = (SIZE_T) &gLpbkBuf[0]; /* packet buffer pointer */ -+ memcpy(&gLpbkBufLog, &gLpbkBuf[((effectiveLen >= 4) ? effectiveLen - 4 : 0)], 4); -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", -+ pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("OPID(%d) type(%d) buf tail(0x%08x) fail\n", -+ pOp->op.opId, pOp->op.au4OpData[0], gLpbkBufLog); -+ iRet = -1; -+ break; -+ } -+ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ iRet = pOp->op.au4OpData[0]; -+ if (copy_to_user((void *)arg + sizeof(SIZE_T) + sizeof(UINT8[2048]), gLpbkBuf, iRet)) { -+ iRet = -EFAULT; -+ break; -+ } -+ -+ } while (0); -+ -+ break; -+ -+ case WMT_IOCTL_ADIE_LPBK_TEST: -+ do { -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ iRet = -EFAULT; -+ break; -+ } -+ -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_ADIE_LPBK_TEST; -+ pOp->op.au4OpData[0] = 0; -+ pOp->op.au4OpData[1] = (SIZE_T) &gLpbkBuf[0]; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ WMT_INFO_FUNC("OPID(%d) start\n", pOp->op.opId); -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d)abort\n", pOp->op.opId); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("OPID(%d) fail\n", pOp->op.opId); -+ iRet = -1; -+ break; -+ } -+ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ iRet = pOp->op.au4OpData[0]; -+ if (copy_to_user((void *)arg + sizeof(SIZE_T), gLpbkBuf, iRet)) { -+ iRet = -EFAULT; -+ break; -+ } -+ -+ } while (0); -+ -+ break; -+ -+ case 10: -+ { -+ pBuffer = kmalloc(NAME_MAX + 1, GFP_KERNEL); -+ if (!pBuffer) { -+ WMT_ERR_FUNC("pBuffer kmalloc memory fail\n"); -+ return 0; -+ } -+ wmt_lib_host_awake_get(); -+ mtk_wcn_stp_coredump_start_ctrl(1); -+ osal_strcpy(pBuffer, "MT662x f/w coredump start-"); -+ if (copy_from_user -+ (pBuffer + osal_strlen(pBuffer), (void *)arg, NAME_MAX - osal_strlen(pBuffer))) { -+ /* osal_strcpy(pBuffer, "MT662x f/w assert core dump start"); */ -+ WMT_ERR_FUNC("copy assert string failed\n"); -+ } -+ pBuffer[NAME_MAX] = '\0'; -+ osal_dbg_assert_aee(pBuffer, pBuffer); -+ kfree(pBuffer); -+ } -+ break; -+ case 11: -+ { -+ osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends"); -+ wmt_lib_host_awake_put(); -+ } -+ break; -+ -+ case WMT_IOCTL_GET_CHIP_INFO: -+ { -+ if (0 == arg) -+ return wmt_lib_get_icinfo(WMTCHIN_CHIPID); -+ else if (1 == arg) -+ return wmt_lib_get_icinfo(WMTCHIN_HWVER); -+ else if (2 == arg) -+ return wmt_lib_get_icinfo(WMTCHIN_FWVER); -+ -+ } -+ break; -+ -+ case WMT_IOCTL_SET_LAUNCHER_KILL:{ -+ if (1 == arg) { -+ WMT_INFO_FUNC("launcher may be killed,block abnormal stp tx.\n"); -+ wmt_lib_set_stp_wmt_last_close(1); -+ } else { -+ wmt_lib_set_stp_wmt_last_close(0); -+ } -+ -+ } -+ break; -+ -+ case WMT_IOCTL_SET_PATCH_NUM:{ -+ pAtchNum = arg; -+ WMT_DBG_FUNC(" get patch num from launcher = %d\n", pAtchNum); -+ wmt_lib_set_patch_num(pAtchNum); -+ pPatchInfo = kcalloc(pAtchNum, sizeof(WMT_PATCH_INFO), GFP_ATOMIC); -+ if (!pPatchInfo) { -+ WMT_ERR_FUNC("allocate memory fail!\n"); -+ break; -+ } -+ } -+ break; -+ -+ case WMT_IOCTL_SET_PATCH_INFO:{ -+ WMT_PATCH_INFO wMtPatchInfo; -+ P_WMT_PATCH_INFO pTemp = NULL; -+ UINT32 dWloadSeq; -+ static UINT32 counter; -+ -+ if (!pPatchInfo) { -+ WMT_ERR_FUNC("NULL patch info pointer\n"); -+ break; -+ } -+ -+ if (copy_from_user(&wMtPatchInfo, (void *)arg, sizeof(WMT_PATCH_INFO))) { -+ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); -+ iRet = -EFAULT; -+ break; -+ } -+ -+ dWloadSeq = wMtPatchInfo.dowloadSeq; -+ WMT_DBG_FUNC( -+ "patch dl seq %d,name %s,address info 0x%02x,0x%02x,0x%02x,0x%02x\n", -+ dWloadSeq, wMtPatchInfo.patchName, -+ wMtPatchInfo.addRess[0], -+ wMtPatchInfo.addRess[1], -+ wMtPatchInfo.addRess[2], -+ wMtPatchInfo.addRess[3]); -+ osal_memcpy(pPatchInfo + dWloadSeq - 1, &wMtPatchInfo, sizeof(WMT_PATCH_INFO)); -+ pTemp = pPatchInfo + dWloadSeq - 1; -+ if (++counter == pAtchNum) { -+ wmt_lib_set_patch_info(pPatchInfo); -+ counter = 0; -+ } -+ } -+ break; -+ -+ case WMT_IOCTL_WMT_COREDUMP_CTRL: -+ mtk_wcn_stp_coredump_flag_ctrl(arg); -+ break; -+ case WMT_IOCTL_WMT_QUERY_CHIPID: -+ { -+ iRet = mtk_wcn_wmt_chipid_query(); -+ WMT_WARN_FUNC("chipid = 0x%x\n", iRet); -+ } -+ break; -+ case WMT_IOCTL_SEND_BGW_DS_CMD: -+ do { -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ UINT8 desense_buf[14] = { 0 }; -+ UINT32 effectiveLen = 14; -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ iRet = -EFAULT; -+ break; -+ } -+ if (copy_from_user(&desense_buf[0], (void *)arg, effectiveLen)) { -+ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); -+ iRet = -EFAULT; -+ break; -+ } -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_BGW_DS; -+ pOp->op.au4OpData[0] = effectiveLen; /* packet length */ -+ pOp->op.au4OpData[1] = (SIZE_T) &desense_buf[0]; /* packet buffer pointer */ -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ WMT_INFO_FUNC("OPID(%d) start\n", pOp->op.opId); -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,opid(%d) abort\n", pOp->op.opId); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("OPID(%d) fail\n", pOp->op.opId); -+ iRet = -1; -+ break; -+ } -+ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ iRet = pOp->op.au4OpData[0]; -+ -+ } while (0); -+ -+ break; -+ case WMT_IOCTL_FW_DBGLOG_CTRL: -+ { -+ iRet = wmt_plat_set_dbg_mode(arg); -+ if (iRet == 0) -+ wmt_dbg_fwinfor_from_emi(0, 1, 0); -+ } -+ break; -+ case WMT_IOCTL_DYNAMIC_DUMP_CTRL: -+ { -+ UINT32 i = 0, j = 0, k = 0; -+ UINT8 *pBuf = NULL; -+ UINT32 int_buf[10]; -+ char Buffer[10][11]; -+ -+ pBuf = kmalloc(DYNAMIC_DUMP_BUF + 1, GFP_KERNEL); -+ if (!pBuf) { -+ WMT_ERR_FUNC("pBuf kmalloc memory fail\n"); -+ return 0; -+ } -+ if (copy_from_user(pBuf, (void *)arg, DYNAMIC_DUMP_BUF)) { -+ iRet = -EFAULT; -+ kfree(pBuf); -+ break; -+ } -+ pBuf[DYNAMIC_DUMP_BUF] = '\0'; -+ WMT_INFO_FUNC("get dynamic dump data from property(%s)\n", pBuf); -+ memset(Buffer, 0, 10*11); -+ for (i = 0; i < DYNAMIC_DUMP_BUF; i++) { -+ if (pBuf[i] == '/') { -+ k = 0; -+ j++; -+ } else { -+ Buffer[j][k] = pBuf[i]; -+ k++; -+ } -+ } -+ for (j = 0; j < 10; j++) { -+ iRet = kstrtou32(Buffer[j], 0, &int_buf[j]); -+ if (iRet) { -+ WMT_ERR_FUNC("string convert fail(%d)\n", iRet); -+ break; -+ } -+ WMT_INFO_FUNC("dynamic dump data buf[%d]:(0x%x)\n", j, int_buf[j]); -+ } -+ wmt_plat_set_dynamic_dumpmem(int_buf); -+ kfree(pBuf); -+ } -+ break; -+ default: -+ iRet = -EINVAL; -+ WMT_WARN_FUNC("unknown cmd (%d)\n", cmd); -+ break; -+ } -+ -+ return iRet; -+} -+#ifdef CONFIG_COMPAT -+long WMT_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ long ret; -+ WMT_INFO_FUNC("cmd[0x%x]\n", cmd); -+ switch (cmd) { -+ case COMPAT_WMT_IOCTL_SET_PATCH_NAME: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_PATCH_NAME, (unsigned long)compat_ptr(arg)); -+ break; -+ case COMPAT_WMT_IOCTL_LPBK_TEST: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_LPBK_TEST, (unsigned long)compat_ptr(arg)); -+ break; -+ case COMPAT_WMT_IOCTL_SET_PATCH_INFO: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_PATCH_INFO, (unsigned long)compat_ptr(arg)); -+ break; -+ case COMPAT_WMT_IOCTL_PORT_NAME: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_PORT_NAME, (unsigned long)compat_ptr(arg)); -+ break; -+ case COMPAT_WMT_IOCTL_WMT_CFG_NAME: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_WMT_CFG_NAME, (unsigned long)compat_ptr(arg)); -+ break; -+ case COMPAT_WMT_IOCTL_SEND_BGW_DS_CMD: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SEND_BGW_DS_CMD, (unsigned long)compat_ptr(arg)); -+ break; -+ default: { -+ ret = WMT_unlocked_ioctl(filp, cmd, arg); -+ break; -+ } -+ } -+ return ret; -+} -+#endif -+static int WMT_open(struct inode *inode, struct file *file) -+{ -+ long ret; -+ -+ WMT_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); -+ ret = wait_event_timeout(gWmtInitWq, gWmtInitDone != 0, msecs_to_jiffies(WMT_DEV_INIT_TO_MS)); -+ if (!ret) { -+ WMT_WARN_FUNC("wait_event_timeout (%d)ms,(%d)jiffies,return -EIO\n", -+ WMT_DEV_INIT_TO_MS, msecs_to_jiffies(WMT_DEV_INIT_TO_MS)); -+ return -EIO; -+ } -+ -+ if (atomic_inc_return(&gWmtRefCnt) == 1) -+ WMT_INFO_FUNC("1st call\n"); -+ -+ return 0; -+} -+ -+static int WMT_close(struct inode *inode, struct file *file) -+{ -+ WMT_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); -+ -+ if (atomic_dec_return(&gWmtRefCnt) == 0) -+ WMT_INFO_FUNC("last call\n"); -+ -+ return 0; -+} -+ -+const struct file_operations gWmtFops = { -+ .open = WMT_open, -+ .release = WMT_close, -+ .read = WMT_read, -+ .write = WMT_write, -+/* .ioctl = WMT_ioctl, */ -+ .unlocked_ioctl = WMT_unlocked_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = WMT_compat_ioctl, -+#endif -+ .poll = WMT_poll, -+}; -+ -+void wmt_dev_bgw_desense_init(VOID) -+{ -+ bgw_init_socket(); -+} -+ -+void wmt_dev_bgw_desense_deinit(VOID) -+{ -+ bgw_destroy_netlink_kernel(); -+} -+ -+void wmt_dev_send_cmd_to_daemon(UINT32 cmd) -+{ -+ send_command_to_daemon(cmd); -+} -+ -+static int WMT_init(void) -+{ -+ dev_t devID = MKDEV(gWmtMajor, 0); -+ INT32 cdevErr = -1; -+ INT32 ret = -1; -+ -+ WMT_INFO_FUNC("WMT Version= %s DATE=%s\n", MTK_WMT_VERSION, MTK_WMT_DATE); -+ /* Prepare a UINT8 device */ -+ /*static allocate chrdev */ -+ gWmtInitDone = 0; -+ init_waitqueue_head((wait_queue_head_t *) &gWmtInitWq); -+ stp_drv_init(); -+ -+ ret = register_chrdev_region(devID, WMT_DEV_NUM, WMT_DRIVER_NAME); -+ if (ret) { -+ WMT_ERR_FUNC("fail to register chrdev\n"); -+ return ret; -+ } -+ cdev_init(&gWmtCdev, &gWmtFops); -+ gWmtCdev.owner = THIS_MODULE; -+ cdevErr = cdev_add(&gWmtCdev, devID, WMT_DEV_NUM); -+ if (cdevErr) { -+ WMT_ERR_FUNC("cdev_add() fails (%d)\n", cdevErr); -+ goto error; -+ } -+ WMT_INFO_FUNC("driver(major %d) installed\n", gWmtMajor); -+#if WMT_CREATE_NODE_DYNAMIC -+ wmt_class = class_create(THIS_MODULE, "stpwmt"); -+ if (IS_ERR(wmt_class)) -+ goto error; -+ wmt_dev = device_create(wmt_class, NULL, devID, NULL, "stpwmt"); -+ if (IS_ERR(wmt_dev)) -+ goto error; -+#endif -+ -+#if 0 -+ pWmtDevCtx = wmt_drv_create(); -+ if (!pWmtDevCtx) { -+ WMT_ERR_FUNC("wmt_drv_create() fails\n"); -+ goto error; -+ } -+ ret = wmt_drv_init(pWmtDevCtx); -+ if (ret) { -+ WMT_ERR_FUNC("wmt_drv_init() fails (%d)\n", ret); -+ goto error; -+ } -+ WMT_INFO_FUNC("stp_btmcb_reg\n"); -+ wmt_cdev_btmcb_reg(); -+ ret = wmt_drv_start(pWmtDevCtx); -+ if (ret) { -+ WMT_ERR_FUNC("wmt_drv_start() fails (%d)\n", ret); -+ goto error; -+ } -+#endif -+ ret = wmt_lib_init(); -+ if (ret) { -+ WMT_ERR_FUNC("wmt_lib_init() fails (%d)\n", ret); -+ goto error; -+ } -+#if CFG_WMT_DBG_SUPPORT -+ wmt_dev_dbg_setup(); -+#endif -+ -+#if CFG_WMT_PROC_FOR_AEE -+ wmt_dev_proc_for_aee_setup(); -+#endif -+ -+ WMT_INFO_FUNC("wmt_dev register thermal cb\n"); -+ wmt_lib_register_thermal_ctrl_cb(wmt_dev_tm_temp_query); -+ wmt_dev_bgw_desense_init(); -+ gWmtInitDone = 1; -+ wake_up(&gWmtInitWq); -+ osal_sleepable_lock_init(&g_es_lr_lock); -+ INIT_WORK(&gPwrOnOffWork, wmt_pwr_on_off_handler); -+#ifdef CONFIG_EARLYSUSPEND -+ register_early_suspend(&wmt_early_suspend_handler); -+ WMT_INFO_FUNC("register_early_suspend finished\n"); -+#else -+ wmt_fb_notifier.notifier_call = wmt_fb_notifier_callback; -+ ret = fb_register_client(&wmt_fb_notifier); -+ if (ret) -+ WMT_ERR_FUNC("wmt register fb_notifier failed! ret(%d)\n", ret); -+ else -+ WMT_INFO_FUNC("wmt register fb_notifier OK!\n"); -+#endif -+ WMT_INFO_FUNC("success\n"); -+ return 0; -+ -+error: -+ wmt_lib_deinit(); -+#if CFG_WMT_DBG_SUPPORT -+ wmt_dev_dbg_remove(); -+#endif -+#if WMT_CREATE_NODE_DYNAMIC -+ if (!(IS_ERR(wmt_dev))) -+ device_destroy(wmt_class, devID); -+ if (!(IS_ERR(wmt_class))) { -+ class_destroy(wmt_class); -+ wmt_class = NULL; -+ } -+#endif -+ -+ if (cdevErr == 0) -+ cdev_del(&gWmtCdev); -+ -+ if (ret == 0) { -+ unregister_chrdev_region(devID, WMT_DEV_NUM); -+ gWmtMajor = -1; -+ } -+ -+ WMT_ERR_FUNC("fail\n"); -+ -+ return -1; -+} -+ -+static void WMT_exit(void) -+{ -+ dev_t dev = MKDEV(gWmtMajor, 0); -+ -+ osal_sleepable_lock_deinit(&g_es_lr_lock); -+#ifdef CONFIG_EARLYSUSPEND -+ unregister_early_suspend(&wmt_early_suspend_handler); -+ WMT_INFO_FUNC("unregister_early_suspend finished\n"); -+#else -+ fb_unregister_client(&wmt_fb_notifier); -+#endif -+ -+ wmt_dev_bgw_desense_deinit(); -+ -+ wmt_lib_register_thermal_ctrl_cb(NULL); -+ -+ wmt_lib_deinit(); -+ -+#if CFG_WMT_DBG_SUPPORT -+ wmt_dev_dbg_remove(); -+#endif -+ -+#if CFG_WMT_PROC_FOR_AEE -+ wmt_dev_proc_for_aee_remove(); -+#endif -+#if WMT_CREATE_NODE_DYNAMIC -+ if (wmt_dev) { -+ device_destroy(wmt_class, dev); -+ wmt_dev = NULL; -+ } -+ if (wmt_class) { -+ class_destroy(wmt_class); -+ wmt_class = NULL; -+ } -+#endif -+ cdev_del(&gWmtCdev); -+ unregister_chrdev_region(dev, WMT_DEV_NUM); -+ gWmtMajor = -1; -+ -+ stp_drv_exit(); -+ -+ WMT_INFO_FUNC("done\n"); -+} -+ -+#ifdef MTK_WCN_REMOVE_KERNEL_MODULE -+ -+int mtk_wcn_soc_common_drv_init(void) -+{ -+ return WMT_init(); -+ -+} -+EXPORT_SYMBOL(mtk_wcn_soc_common_drv_init); -+void mtk_wcn_soc_common_drv_exit(void) -+{ -+ return WMT_exit(); -+} -+EXPORT_SYMBOL(mtk_wcn_soc_common_drv_exit); -+ -+#else -+module_init(WMT_init); -+module_exit(WMT_exit); -+#endif -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("MediaTek Inc WCN"); -+MODULE_DESCRIPTION("MTK WCN combo driver for WMT function"); -+ -+module_param(gWmtMajor, uint, 0); -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c -new file mode 100644 -index 0000000000000..8d5c23732c1c7 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c -@@ -0,0 +1,610 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-EXP]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+ -+#include -+#include -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+wmt_wlan_probe_cb mtk_wcn_wlan_probe = NULL; -+wmt_wlan_remove_cb mtk_wcn_wlan_remove = NULL; -+wmt_wlan_bus_cnt_get_cb mtk_wcn_wlan_bus_tx_cnt = NULL; -+wmt_wlan_bus_cnt_clr_cb mtk_wcn_wlan_bus_tx_cnt_clr = NULL; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+OSAL_BIT_OP_VAR gBtWifiGpsState; -+OSAL_BIT_OP_VAR gGpsFmState; -+UINT32 gWifiProbed = 0; -+UINT32 gWmtDbgLvl = WMT_LOG_ERR; -+MTK_WCN_BOOL g_pwr_off_flag = MTK_WCN_BOOL_TRUE; -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static MTK_WCN_BOOL mtk_wcn_wmt_func_ctrl(ENUM_WMTDRV_TYPE_T type, ENUM_WMT_OPID_T opId); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static MTK_WCN_BOOL mtk_wcn_wmt_func_ctrl(ENUM_WMTDRV_TYPE_T type, ENUM_WMT_OPID_T opId) -+{ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pSignal = &pOp->signal; -+ -+ pOp->op.opId = opId; -+ pOp->op.au4OpData[0] = type; -+ if (WMTDRV_TYPE_WIFI == type) -+ pSignal->timeoutValue = 4000; -+ /*donot block system server/init/netd from longer than 5s, in case of ANR happens*/ -+ else -+ pSignal->timeoutValue = (WMT_OPID_FUNC_ON == pOp->op.opId) ? MAX_FUNC_ON_TIME : MAX_FUNC_OFF_TIME; -+ -+ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ /*do not check return value, we will do this either way */ -+ wmt_lib_host_awake_get(); -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ wmt_lib_host_awake_put(); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ wmt_lib_host_awake_put(); -+ -+ if (MTK_WCN_BOOL_FALSE == bRet) -+ WMT_WARN_FUNC("OPID(%d) type(%d) fail\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ else -+ WMT_WARN_FUNC("OPID(%d) type(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ return bRet; -+} -+ -+#if WMT_EXP_HID_API_EXPORT -+MTK_WCN_BOOL _mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type) -+#else -+MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type) -+#endif -+{ -+ MTK_WCN_BOOL ret; -+ -+ if (type == WMTDRV_TYPE_BT) -+ osal_printtimeofday("############ BT OFF ====>"); -+ -+ ret = mtk_wcn_wmt_func_ctrl(type, WMT_OPID_FUNC_OFF); -+ -+ if (type == WMTDRV_TYPE_BT) -+ osal_printtimeofday("############ BT OFF <===="); -+ -+ return ret; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_func_off); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+MTK_WCN_BOOL _mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type) -+#else -+MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type) -+#endif -+{ -+ MTK_WCN_BOOL ret; -+ -+ if (type == WMTDRV_TYPE_BT) -+ osal_printtimeofday("############ BT ON ====>"); -+ -+ ret = mtk_wcn_wmt_func_ctrl(type, WMT_OPID_FUNC_ON); -+ -+ if (type == WMTDRV_TYPE_BT) -+ osal_printtimeofday(" ############BT ON <===="); -+ -+ return ret; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_func_on); -+#endif -+ -+VOID mtk_wcn_wmt_func_ctrl_for_plat(UINT32 on, ENUM_WMTDRV_TYPE_T type) -+{ -+ if (on) -+ mtk_wcn_wmt_func_on(type); -+ else -+ mtk_wcn_wmt_func_off(type); -+} -+ -+/* -+return value: -+enable/disable thermal sensor function: true(1)/false(0) -+read thermal sensor function:thermal value -+ -+*/ -+#if WMT_EXP_HID_API_EXPORT -+INT8 _mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType) -+#else -+INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType) -+#endif -+{ -+ P_OSAL_OP pOp; -+ P_WMT_OP pOpData; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ /*parameter validation check */ -+ if (WMTTHERM_MAX < eType || WMTTHERM_ENABLE > eType) { -+ WMT_ERR_FUNC("invalid thermal control command (%d)\n", eType); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ /*check if chip support thermal control function or not */ -+ bRet = wmt_lib_is_therm_ctrl_support(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_ERR_FUNC("thermal ctrl function not supported\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pSignal = &pOp->signal; -+ pOpData = &pOp->op; -+ pOpData->opId = WMT_OPID_THERM_CTRL; -+ /*parameter fill */ -+ pOpData->au4OpData[0] = eType; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ -+ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort!\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("OPID(%d) type(%d) fail\n\n", pOpData->opId, pOpData->au4OpData[0]); -+ /*0xFF means read error occurs */ -+ /*will return to function driver */ -+ pOpData->au4OpData[1] = (eType == WMTTHERM_READ) ? 0xFF : MTK_WCN_BOOL_FALSE; -+ } else { -+ WMT_INFO_FUNC("OPID(%d) type(%d) return(%d) ok\n\n", -+ pOpData->opId, pOpData->au4OpData[0], pOpData->au4OpData[1]); -+ } -+ /*return value will be put to lxop->op.au4OpData[1] */ -+ WMT_DBG_FUNC("therm ctrl type(%d), iRet(0x%08x)\n", eType, pOpData->au4OpData[1]); -+ return (INT8) pOpData->au4OpData[1]; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_therm_ctrl); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+ENUM_WMTHWVER_TYPE_T _mtk_wcn_wmt_hwver_get(VOID) -+#else -+ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID) -+#endif -+{ -+ /* TODO: [ChangeFeature][GeorgeKuo] Reconsider usage of this type */ -+ /* TODO: how do we extend for new chip and newer revision? */ -+ /* TODO: This way is hard to extend */ -+ return wmt_lib_get_icinfo(WMTCHIN_MAPPINGHWVER); -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_hwver_get); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+MTK_WCN_BOOL _mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType) -+#else -+MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType) -+#endif -+{ -+ P_OSAL_OP pOp; -+ P_WMT_OP pOpData; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ if (WMTDSNS_MAX <= eType) { -+ WMT_ERR_FUNC("invalid desense control command (%d)\n", eType); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ /*check if chip support thermal control function or not */ -+ bRet = wmt_lib_is_dsns_ctrl_support(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_ERR_FUNC("thermal ctrl function not supported\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pSignal = &pOp->signal; -+ pOpData = &pOp->op; -+ pOpData->opId = WMT_OPID_DSNS; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ /*parameter fill */ -+ if ((WMTDSNS_FM_DISABLE <= eType) && (WMTDSNS_FM_GPS_ENABLE >= eType)) { -+ pOpData->au4OpData[0] = WMTDRV_TYPE_FM; -+ pOpData->au4OpData[1] = eType; -+ } -+ -+ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ -+ if (MTK_WCN_BOOL_FALSE == bRet) -+ WMT_WARN_FUNC("OPID(%d) type(%d) fail\n\n", pOpData->opId, pOpData->au4OpData[0]); -+ else -+ WMT_INFO_FUNC("OPID(%d) type(%d) ok\n\n", pOpData->opId, pOpData->au4OpData[0]); -+ -+ return bRet; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_dsns_ctrl); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) -+#else -+INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) -+#endif -+{ -+ return (INT32) wmt_lib_msgcb_reg(eType, pCb); -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_reg); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) -+#else -+INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) -+#endif -+{ -+ return (INT32) wmt_lib_msgcb_unreg(eType); -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_unreg); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb) -+#else -+INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb) -+#endif -+{ -+ wmt_lib_ps_set_sdio_psop(own_cb); -+ return 0; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_op_reg); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_wmt_sdio_host_awake(VOID) -+#else -+INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID) -+#endif -+{ -+ wmt_lib_ps_irq_cb(); -+ return 0; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_host_awake); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+MTK_WCN_BOOL _mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) -+#else -+MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) -+#endif -+{ -+ P_OSAL_OP pOp = NULL; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_OSAL_SIGNAL pSignal; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ wmt_lib_set_host_assert_info(type, reason, 1); -+ -+ pSignal = &pOp->signal; -+ -+ pOp->op.opId = WMT_OPID_CMD_TEST; -+ -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ /*this test command should be run with usb cable connected, so no host awake is needed */ -+ /* wmt_lib_host_awake_get(); */ -+ pOp->op.au4OpData[0] = 0; -+ -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,assert flow abort\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ -+ /* wmt_lib_host_awake_put(); */ -+ WMT_INFO_FUNC("CMD_TEST, opid (%d), par(%d, %d), ret(%d), result(%s)\n", -+ pOp->op.opId, -+ pOp->op.au4OpData[0], -+ pOp->op.au4OpData[1], bRet, MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); -+ -+ return bRet; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_assert); -+#endif -+ -+INT8 mtk_wcn_wmt_co_clock_flag_get(void) -+{ -+ return wmt_lib_co_clock_get(); -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_co_clock_flag_get); -+ -+INT32 mtk_wcn_wmt_system_state_reset(void) -+{ -+ osal_memset(&gBtWifiGpsState, 0, osal_sizeof(gBtWifiGpsState)); -+ osal_memset(&gGpsFmState, 0, osal_sizeof(gGpsFmState)); -+ -+ return 0; -+} -+ -+INT32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo) -+{ -+ INT32 iRet = -1; -+ -+ if (!pWmtWlanCbInfo) { -+ WMT_ERR_FUNC("wlan cb info in null!\n"); -+ return -1; -+ } -+ -+ WMT_INFO_FUNC("wmt wlan cb register\n"); -+ mtk_wcn_wlan_probe = pWmtWlanCbInfo->wlan_probe_cb; -+ mtk_wcn_wlan_remove = pWmtWlanCbInfo->wlan_remove_cb; -+ mtk_wcn_wlan_bus_tx_cnt = pWmtWlanCbInfo->wlan_bus_cnt_get_cb; -+ mtk_wcn_wlan_bus_tx_cnt_clr = pWmtWlanCbInfo->wlan_bus_cnt_clr_cb; -+ -+ if (gWifiProbed) { -+ WMT_INFO_FUNC("wlan has been done power on,call probe directly\n"); -+ iRet = (*mtk_wcn_wlan_probe) (); -+ if (!iRet) { -+ WMT_INFO_FUNC("call wlan probe OK when do wlan register to wmt\n"); -+ gWifiProbed = 0; -+ } else { -+ WMT_ERR_FUNC("call wlan probe fail(%d) when do wlan register to wmt\n", iRet); -+ return -2; -+ } -+ } -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_wlan_reg); -+ -+INT32 mtk_wcn_wmt_wlan_unreg(void) -+{ -+ WMT_INFO_FUNC("wmt wlan cb unregister\n"); -+ mtk_wcn_wlan_probe = NULL; -+ mtk_wcn_wlan_remove = NULL; -+ mtk_wcn_wlan_bus_tx_cnt = NULL; -+ mtk_wcn_wlan_bus_tx_cnt_clr = NULL; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_wlan_unreg); -+ -+MTK_WCN_BOOL mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL value) -+{ -+ g_pwr_off_flag = value; -+ if (g_pwr_off_flag) -+ WMT_DBG_FUNC("enable connsys power off flag\n"); -+ else -+ WMT_INFO_FUNC("disable connsys power off, maybe need trigger coredump!\n"); -+ return g_pwr_off_flag; -+} -+EXPORT_SYMBOL(mtk_wcn_set_connsys_power_off_flag); -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+VOID mtk_wcn_wmt_exp_init(void) -+{ -+ MTK_WCN_WMT_EXP_CB_INFO wmtExpCb = { -+ -+ .wmt_func_on_cb = _mtk_wcn_wmt_func_on, -+ .wmt_func_off_cb = _mtk_wcn_wmt_func_off, -+ .wmt_therm_ctrl_cb = _mtk_wcn_wmt_therm_ctrl, -+ .wmt_hwver_get_cb = _mtk_wcn_wmt_hwver_get, -+ .wmt_dsns_ctrl_cb = _mtk_wcn_wmt_dsns_ctrl, -+ .wmt_msgcb_reg_cb = _mtk_wcn_wmt_msgcb_reg, -+ .wmt_msgcb_unreg_cb = _mtk_wcn_wmt_msgcb_unreg, -+ .wmt_sdio_op_reg_cb = _mtk_wcn_stp_wmt_sdio_op_reg, -+ .wmt_sdio_host_awake_cb = _mtk_wcn_stp_wmt_sdio_host_awake, -+ .wmt_assert_cb = _mtk_wcn_wmt_assert -+ }; -+ -+ mtk_wcn_wmt_exp_cb_reg(&wmtExpCb); -+} -+ -+VOID mtk_wcn_wmt_exp_deinit(void) -+{ -+ mtk_wcn_wmt_exp_cb_unreg(); -+} -+#ifdef CONFIG_MTK_COMBO_ANT -+/* -+ ctrlId: get ram code status opId or ram code download opId -+ pBuf: pointer to ANT ram code -+ length: total length of ANT ram code -+*/ -+ENUM_WMT_ANT_RAM_STATUS mtk_wcn_wmt_ant_ram_ctrl(ENUM_WMT_ANT_RAM_CTRL ctrlId, PUINT8 pBuf, -+ UINT32 length, ENUM_WMT_ANT_RAM_SEQ seq) -+{ -+ ENUM_WMT_ANT_RAM_STATUS eRet = 0; -+ P_OSAL_OP pOp = NULL; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_OSAL_SIGNAL pSignal; -+ -+ /*1. parameter validation check */ -+ /*for WMT_ANT_RAM_GET_STATUS, ignore pBuf and length */ -+ /*for WMT_ANT_RAM_DOWNLOAD, -+ pBuf must not be NULL, kernel space memory pointer -+ length must be large than 0 */ -+ -+ if ((WMT_ANT_RAM_GET_STATUS > ctrlId) || (WMT_ANT_RAM_CTRL_MAX <= ctrlId)) { -+ WMT_ERR_FUNC("error ctrlId:%d detected.\n", ctrlId); -+ eRet = WMT_ANT_RAM_PARA_ERR; -+ return eRet; -+ } -+ -+ if ((WMT_ANT_RAM_DOWNLOAD == ctrlId) && -+ ((NULL == pBuf) || -+ (0 >= length) || -+ (1000 < length) || (seq >= WMT_ANT_RAM_SEQ_MAX) || (seq < WMT_ANT_RAM_START_PKT))) { -+ eRet = WMT_ANT_RAM_PARA_ERR; -+ WMT_ERR_FUNC -+ ("error parameter detected, ctrlId:%d, pBuf:%p,length(0x%x),seq(%d) .\n", -+ ctrlId, pBuf, length, seq); -+ return eRet; -+ } -+ /*get WMT opId */ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_DBG_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pSignal = &pOp->signal; -+ pSignal->timeoutValue = -+ (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? MAX_FUNC_ON_TIME : MAX_EACH_WMT_CMD; -+ -+ pOp->op.opId = -+ (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? WMT_OPID_ANT_RAM_DOWN : WMT_OPID_ANT_RAM_STA_GET; -+ pOp->op.au4OpData[0] = (size_t) pBuf; -+ pOp->op.au4OpData[1] = length; -+ pOp->op.au4OpData[2] = seq; -+ -+ -+ /*disable PSM monitor */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ /*wakeup wmtd thread */ -+ bRet = wmt_lib_put_act_op(pOp); -+ -+ /*enable PSM monitor */ -+ ENABLE_PSM_MONITOR(); -+ -+ WMT_DBG_FUNC("CMD_TEST, opid (%d), ret(%d),retVal(%zu) result(%s)\n", -+ pOp->op.opId, -+ bRet, -+ pOp->op.au4OpData[2], MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); -+ -+ /*check return value and return result */ -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ eRet = WMT_ANT_RAM_OP_ERR; -+ } else { -+ eRet = (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? -+ WMT_ANT_RAM_DOWN_OK : -+ ((1 == pOp->op.au4OpData[2]) ? WMT_ANT_RAM_EXIST : WMT_ANT_RAM_NOT_EXIST); -+ } -+ -+ return eRet; -+ -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_ant_ram_ctrl); -+#endif -+ -+#endif -+VOID mtk_wcn_wmt_set_wifi_ver(UINT32 Value) -+{ -+ wmt_lib_soc_set_wifiver(Value); -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_set_wifi_ver); -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile -new file mode 100644 -index 0000000000000..eb37baf87b025 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile -@@ -0,0 +1,27 @@ -+ifeq ($(CONFIG_MTK_COMBO), y) -+ -+ccflags-y += \ -+ -I$(src)/../../linux/include \ -+ -I$(src)/../../linux/pri/include \ -+ -I$(src)/../../core/include \ -+ -I$(src)/../../include \ -+ -I$(src)/../include \ -+ -I$(src)/../../../common_detect \ -+ -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach \ -+ -DMTK_BT_HCI=1 -+ -+ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1 -+ -+ifeq ($(CONFIG_MTK_TC1_FEATURE), y) -+ ccflags-y += -DCFG_TC1_FEATURE=1 -+else -+ ccflags-y += -DCFG_TC1_FEATURE=0 -+endif -+ -+obj-y += osal.o \ -+ bgw_desense.o \ -+ wmt_idc.o -+obj-$(CONFIG_MTK_COMBO_BT) += stp_chrdev_bt.o -+obj-$(CONFIG_MTK_COMBO_WIFI) += wmt_chrdev_wifi.o -+ -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c -new file mode 100644 -index 0000000000000..11e45aa130872 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c -@@ -0,0 +1,153 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include "bgw_desense.h" -+ -+static struct sock *g_nl_sk; -+/* static struct sockaddr_nl src_addr, des_addr; */ -+/* static struct iovec iov; */ -+static int pid; -+/* static struct msghdr msg; */ -+ -+void bgw_destroy_netlink_kernel(void) -+{ -+ if (g_nl_sk != NULL) { -+ /* sock_release(g_nl_sk->sk_socket); */ -+ netlink_kernel_release(g_nl_sk); -+ MSG("release socket\n"); -+ return; -+ } -+ ERR("no socket yet\n"); -+} -+ -+void send_command_to_daemon(const int command /*struct sk_buff *skb */) -+{ -+/* -+ struct iphdr *iph; -+ struct ethhdr *ehdr; -+ */ -+ struct nlmsghdr *nlh; -+ struct sk_buff *nl_skb; -+ int res; -+ -+ MSG("here we will send command to native daemon\n"); -+/* if(skb == NULL) -+ { -+ ERR("invalid sk_buff\n"); -+ return; -+ } -+*/ -+ if (!g_nl_sk) { -+ ERR("invalid socket\n"); -+ return; -+ } -+ if (pid == 0) { -+ ERR("invalid native process pid\n"); -+ return; -+ } -+ /*alloc data buffer for sending to native */ -+ /*malloc data space at least 1500 bytes, which is ethernet data length */ -+ nl_skb = alloc_skb(NLMSG_SPACE(MAX_NL_MSG_LEN), GFP_ATOMIC); -+ if (nl_skb == NULL) { -+ ERR("malloc skb error\n"); -+ return; -+ } -+ MSG("malloc data space done\n"); -+ /* -+ ehdr = eth_hdr(skb); -+ iph = ip_hdr(skb); -+ */ -+ -+/* nlh = NLMSG_PUT(nl_skb, 0, 0, 0, NLMSG_SPACE(1500)-sizeof(struct nlmsghdr)); */ -+ nlh = nlmsg_put(nl_skb, 0, 0, 0, MAX_NL_MSG_LEN, 0); -+ if (nlh == NULL) { -+ MSG("nlh is NULL\n"); -+ kfree_skb(nl_skb); -+ return; -+ } -+ NETLINK_CB(nl_skb).portid = 0; -+ -+/* memcpy(NLMSG_DATA(nlh), ACK, 5); */ -+ *(char *)NLMSG_DATA(nlh) = command; -+ res = netlink_unicast(g_nl_sk, nl_skb, pid, MSG_DONTWAIT); -+ if (res == 0) { -+ MSG("send to user space process error\n"); -+ return; -+ } -+ ERR("send to user space process done, data length = %d\n", res); -+} -+ -+static void nl_data_handler(struct sk_buff *__skb) -+{ -+ struct sk_buff *skb; -+ struct nlmsghdr *nlh; -+ int i; -+ int len; -+ char str[128]; -+ -+ MSG("we got netlink message\n"); -+ len = NLMSG_SPACE(MAX_NL_MSG_LEN); -+ skb = skb_get(__skb); -+ if (skb == NULL) -+ ERR("skb_get return NULL"); -+ if (skb->len >= NLMSG_SPACE(0)) { /*presume there is 5byte payload at leaset */ -+ MSG("length is enough\n"); -+ nlh = nlmsg_hdr(skb); /* point to data which include in skb */ -+ memcpy(str, NLMSG_DATA(nlh), sizeof(str)); -+ for (i = 0; i < 3; i++) -+ MSG("str[%d = %c]", i, str[i]); -+ MSG("str[0] = %d, str[1] = %d, str[2] = %d\n", str[0], str[1], str[2]); -+ if (str[0] == 'B' && str[1] == 'G' && str[2] == 'W') { -+ MSG("got native daemon init command, record it's pid\n"); -+ pid = nlh->nlmsg_pid; /*record the native process PID */ -+ MSG("native daemon pid is %d\n", pid); -+ } else { -+ ERR("this is not BGW message, ignore it\n"); -+ return; -+ } -+ } else { -+ ERR("not engouth data length\n"); -+ return; -+ } -+ -+ kfree_skb(skb); -+ -+ send_command_to_daemon(ACK); -+} -+ -+int bgw_init_socket(void) -+{ -+ struct netlink_kernel_cfg cfg; -+ -+ memset(&cfg, 0, sizeof(cfg)); -+ cfg.input = nl_data_handler; -+ -+ g_nl_sk = __netlink_kernel_create(&init_net, NETLINK_TEST, THIS_MODULE, &cfg); -+ -+ if (g_nl_sk == NULL) { -+ ERR("netlink_kernel_create error\n"); -+ return -1; -+ } -+ MSG("netlink_kernel_create ok\n"); -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c -new file mode 100644 -index 0000000000000..959b68de24311 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c -@@ -0,0 +1,1211 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+#include "osal.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */ -+static UINT16 const crc16_table[256] = { -+ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, -+ 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, -+ 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, -+ 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, -+ 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, -+ 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, -+ 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, -+ 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, -+ 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, -+ 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, -+ 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, -+ 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, -+ 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, -+ 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, -+ 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, -+ 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, -+ 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, -+ 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, -+ 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, -+ 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, -+ 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, -+ 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, -+ 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, -+ 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, -+ 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, -+ 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, -+ 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, -+ 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, -+ 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, -+ 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, -+ 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, -+ 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 -+}; -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*string operations*/ -+_osal_inline_ UINT32 osal_strlen(const char *str) -+{ -+ return strlen(str); -+} -+ -+_osal_inline_ INT32 osal_strcmp(const char *dst, const char *src) -+{ -+ return strcmp(dst, src); -+} -+ -+_osal_inline_ INT32 osal_strncmp(const char *dst, const char *src, UINT32 len) -+{ -+ return strncmp(dst, src, len); -+} -+ -+_osal_inline_ char *osal_strcpy(char *dst, const char *src) -+{ -+ return strcpy(dst, src); -+} -+ -+_osal_inline_ char *osal_strncpy(char *dst, const char *src, UINT32 len) -+{ -+ return strncpy(dst, src, len); -+} -+ -+_osal_inline_ char *osal_strcat(char *dst, const char *src) -+{ -+ return strcat(dst, src); -+} -+ -+_osal_inline_ char *osal_strncat(char *dst, const char *src, UINT32 len) -+{ -+ return strncat(dst, src, len); -+} -+ -+_osal_inline_ char *osal_strchr(const char *str, UINT8 c) -+{ -+ return strchr(str, c); -+} -+ -+_osal_inline_ char *osal_strsep(char **str, const char *c) -+{ -+ return strsep(str, c); -+} -+ -+_osal_inline_ int osal_strtol(const char *str, UINT32 adecimal, long *res) -+{ -+ return kstrtol(str, adecimal, res); -+} -+ -+_osal_inline_ char *osal_strstr(char *str1, const char *str2) -+{ -+ return strstr(str1, str2); -+} -+ -+INT32 osal_snprintf(char *buf, UINT32 len, const char *fmt, ...) -+{ -+ INT32 iRet = 0; -+ va_list args; -+ -+ /*va_start(args, fmt); */ -+ va_start(args, fmt); -+ /*iRet = snprintf(buf, len, fmt, args); */ -+ iRet = vsnprintf(buf, len, fmt, args); -+ va_end(args); -+ -+ return iRet; -+} -+ -+INT32 osal_err_print(const char *str, ...) -+{ -+ va_list args; -+ char tempString[DBG_LOG_STR_SIZE]; -+ -+ va_start(args, str); -+ vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); -+ va_end(args); -+ -+ pr_err("%s", tempString); -+ -+ return 0; -+} -+ -+INT32 osal_dbg_print(const char *str, ...) -+{ -+ va_list args; -+ char tempString[DBG_LOG_STR_SIZE]; -+ -+ va_start(args, str); -+ vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); -+ va_end(args); -+ -+ pr_debug("%s", tempString); -+ -+ return 0; -+} -+ -+INT32 osal_warn_print(const char *str, ...) -+{ -+ va_list args; -+ char tempString[DBG_LOG_STR_SIZE]; -+ -+ va_start(args, str); -+ vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); -+ va_end(args); -+ -+ pr_warn("%s", tempString); -+ -+ return 0; -+} -+ -+INT32 osal_dbg_assert(INT32 expr, const char *file, INT32 line) -+{ -+ if (!expr) { -+ pr_warn("%s (%d)\n", file, line); -+ /*BUG_ON(!expr); */ -+#ifdef CFG_COMMON_GPIO_DBG_PIN -+/* package this part */ -+ mt_set_gpio_out(GPIO70, GPIO_OUT_ZERO); -+ pr_warn("toggle GPIO70\n"); -+ udelay(10); -+ mt_set_gpio_out(GPIO70, GPIO_OUT_ONE); -+#endif -+ return 1; -+ } -+ return 0; -+ -+} -+ -+INT32 osal_dbg_assert_aee(const char *module, const char *detail_description) -+{ -+ osal_err_print("[WMT-ASSERT]" "[E][Module]:%s, [INFO]%s\n", module, detail_description); -+ -+#ifdef WMT_PLAT_ALPS -+ /* aee_kernel_warning(module,detail_description); */ -+ aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_WCN_ISSUE_INFO, module, detail_description); -+#endif -+ return 0; -+} -+ -+INT32 osal_sprintf(char *str, const char *format, ...) -+{ -+ INT32 iRet = 0; -+ va_list args; -+ -+ va_start(args, format); -+ iRet = vsnprintf(str, DBG_LOG_STR_SIZE, format, args); -+ va_end(args); -+ -+ return iRet; -+} -+ -+_osal_inline_ VOID *osal_malloc(UINT32 size) -+{ -+ return vmalloc(size); -+} -+ -+_osal_inline_ VOID osal_free(const VOID *dst) -+{ -+ vfree(dst); -+} -+ -+_osal_inline_ VOID *osal_memset(VOID *buf, INT32 i, UINT32 len) -+{ -+ return memset(buf, i, len); -+} -+ -+_osal_inline_ VOID *osal_memcpy(VOID *dst, const VOID *src, UINT32 len) -+{ -+#ifdef CONFIG_MTK_WCN_ARM64 -+ char *tmp; -+ const char *s; -+ size_t i; -+ -+ tmp = dst; -+ s = src; -+ for (i = 0; i < len; i++) -+ tmp[i] = s[i]; -+ -+ return dst; -+ -+#else -+ return memcpy(dst, src, len); -+#endif -+} -+ -+_osal_inline_ INT32 osal_memcmp(const VOID *buf1, const VOID *buf2, UINT32 len) -+{ -+ return memcmp(buf1, buf2, len); -+} -+ -+_osal_inline_ UINT16 osal_crc16(const UINT8 *buffer, const UINT32 length) -+{ -+ UINT16 crc = 0; -+ UINT32 i = 0; -+ -+ /* FIXME: Add STP checksum feature */ -+ crc = 0; -+ for (i = 0; i < length; i++, buffer++) -+ crc = (crc >> 8) ^ crc16_table[(crc ^ (*buffer)) & 0xff]; -+ -+ return crc; -+} -+ -+_osal_inline_ VOID osal_thread_show_stack(P_OSAL_THREAD pThread) -+{ -+ return show_stack(pThread->pThread, NULL); -+} -+ -+/* -+ *OSAL layer Thread Opeartion related APIs -+ * -+ * -+*/ -+_osal_inline_ INT32 osal_thread_create(P_OSAL_THREAD pThread) -+{ -+ pThread->pThread = kthread_create(pThread->pThreadFunc, pThread->pThreadData, pThread->threadName); -+ if (NULL == pThread->pThread) -+ return -1; -+ -+ return 0; -+} -+ -+_osal_inline_ INT32 osal_thread_run(P_OSAL_THREAD pThread) -+{ -+ if (pThread->pThread) { -+ wake_up_process(pThread->pThread); -+ return 0; -+ } else { -+ return -1; -+ } -+} -+ -+_osal_inline_ INT32 osal_thread_stop(P_OSAL_THREAD pThread) -+{ -+ INT32 iRet; -+ -+ if ((pThread) && (pThread->pThread)) { -+ iRet = kthread_stop(pThread->pThread); -+ /* pThread->pThread = NULL; */ -+ return iRet; -+ } -+ return -1; -+} -+ -+_osal_inline_ INT32 osal_thread_should_stop(P_OSAL_THREAD pThread) -+{ -+ if ((pThread) && (pThread->pThread)) -+ return kthread_should_stop(); -+ else -+ return 1; -+ -+} -+ -+_osal_inline_ INT32 -+osal_thread_wait_for_event(P_OSAL_THREAD pThread, P_OSAL_EVENT pEvent, P_OSAL_EVENT_CHECKER pChecker) -+{ -+ /* P_DEV_WMT pDevWmt;*/ -+ -+ if ((pThread) && (pThread->pThread) && (pEvent) && (pChecker)) { -+ /* pDevWmt = (P_DEV_WMT)(pThread->pThreadData);*/ -+ return wait_event_interruptible(pEvent->waitQueue, (/*!RB_EMPTY(&pDevWmt->rActiveOpQ) || */ -+ osal_thread_should_stop(pThread) -+ || (*pChecker) (pThread))); -+ } -+ return -1; -+} -+ -+_osal_inline_ INT32 osal_thread_destroy(P_OSAL_THREAD pThread) -+{ -+ if (pThread && (pThread->pThread)) { -+ kthread_stop(pThread->pThread); -+ pThread->pThread = NULL; -+ } -+ return 0; -+} -+ -+/* -+ *OSAL layer Signal Opeartion related APIs -+ *initialization -+ *wait for signal -+ *wait for signal timerout -+ *raise signal -+ *destroy a signal -+ * -+*/ -+ -+_osal_inline_ INT32 osal_signal_init(P_OSAL_SIGNAL pSignal) -+{ -+ if (pSignal) { -+ init_completion(&pSignal->comp); -+ return 0; -+ } else { -+ return -1; -+ } -+} -+ -+_osal_inline_ INT32 osal_wait_for_signal(P_OSAL_SIGNAL pSignal) -+{ -+ if (pSignal) { -+ wait_for_completion_interruptible(&pSignal->comp); -+ return 0; -+ } else { -+ return -1; -+ } -+} -+ -+_osal_inline_ INT32 osal_wait_for_signal_timeout(P_OSAL_SIGNAL pSignal) -+{ -+ /* return wait_for_completion_interruptible_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); */ -+ /* [ChangeFeature][George] gps driver may be closed by -ERESTARTSYS. -+ * Avoid using *interruptible" version in order to complete our jobs, such -+ * as function off gracefully. -+ */ -+ return wait_for_completion_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); -+} -+ -+_osal_inline_ INT32 osal_raise_signal(P_OSAL_SIGNAL pSignal) -+{ -+ /* TODO:[FixMe][GeorgeKuo]: DO sanity check here!!! */ -+ complete(&pSignal->comp); -+ return 0; -+} -+ -+_osal_inline_ INT32 osal_signal_deinit(P_OSAL_SIGNAL pSignal) -+{ -+ /* TODO:[FixMe][GeorgeKuo]: DO sanity check here!!! */ -+ pSignal->timeoutValue = 0; -+ return 0; -+} -+ -+/* -+ *OSAL layer Event Opeartion related APIs -+ *initialization -+ *wait for signal -+ *wait for signal timerout -+ *raise signal -+ *destroy a signal -+ * -+*/ -+ -+INT32 osal_event_init(P_OSAL_EVENT pEvent) -+{ -+ init_waitqueue_head(&pEvent->waitQueue); -+ -+ return 0; -+} -+ -+INT32 osal_wait_for_event(P_OSAL_EVENT pEvent, INT32(*condition) (PVOID), void *cond_pa) -+{ -+ return wait_event_interruptible(pEvent->waitQueue, condition(cond_pa)); -+} -+ -+INT32 osal_wait_for_event_timeout(P_OSAL_EVENT pEvent, INT32(*condition) (PVOID), void *cond_pa) -+{ -+ return wait_event_interruptible_timeout(pEvent->waitQueue, condition(cond_pa), -+ msecs_to_jiffies(pEvent->timeoutValue)); -+} -+ -+INT32 osal_trigger_event(P_OSAL_EVENT pEvent) -+{ -+ INT32 ret = 0; -+ -+ wake_up_interruptible(&pEvent->waitQueue); -+ return ret; -+} -+ -+INT32 osal_event_deinit(P_OSAL_EVENT pEvent) -+{ -+ return 0; -+} -+ -+_osal_inline_ long osal_wait_for_event_bit_set(P_OSAL_EVENT pEvent, unsigned long *pState, UINT32 bitOffset) -+{ -+ UINT32 ms = pEvent->timeoutValue; -+ -+ if (ms != 0) { -+ return wait_event_interruptible_timeout(pEvent->waitQueue, test_bit(bitOffset, pState), -+ msecs_to_jiffies(ms)); -+ } else { -+ return wait_event_interruptible(pEvent->waitQueue, test_bit(bitOffset, pState)); -+ } -+ -+} -+ -+_osal_inline_ long osal_wait_for_event_bit_clr(P_OSAL_EVENT pEvent, unsigned long *pState, UINT32 bitOffset) -+{ -+ UINT32 ms = pEvent->timeoutValue; -+ -+ if (ms != 0) { -+ return wait_event_interruptible_timeout(pEvent->waitQueue, !test_bit(bitOffset, pState), -+ msecs_to_jiffies(ms)); -+ } else { -+ return wait_event_interruptible(pEvent->waitQueue, !test_bit(bitOffset, pState)); -+ } -+ -+} -+ -+/* -+ *bit test and set/clear operations APIs -+ * -+ * -+*/ -+#if OS_BIT_OPS_SUPPORT -+#define osal_bit_op_lock(x) -+#define osal_bit_op_unlock(x) -+#else -+ -+_osal_inline_ INT32 osal_bit_op_lock(P_OSAL_UNSLEEPABLE_LOCK pLock) -+{ -+ -+ return 0; -+} -+ -+_osal_inline_ INT32 osal_bit_op_unlock(P_OSAL_UNSLEEPABLE_LOCK pLock) -+{ -+ -+ return 0; -+} -+#endif -+_osal_inline_ INT32 osal_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) -+{ -+ osal_bit_op_lock(&(pData->opLock)); -+ clear_bit(bitOffset, &pData->data); -+ osal_bit_op_unlock(&(pData->opLock)); -+ return 0; -+} -+ -+_osal_inline_ INT32 osal_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) -+{ -+ osal_bit_op_lock(&(pData->opLock)); -+ set_bit(bitOffset, &pData->data); -+ osal_bit_op_unlock(&(pData->opLock)); -+ return 0; -+} -+ -+_osal_inline_ INT32 osal_test_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) -+{ -+ UINT32 iRet = 0; -+ -+ osal_bit_op_lock(&(pData->opLock)); -+ iRet = test_bit(bitOffset, &pData->data); -+ osal_bit_op_unlock(&(pData->opLock)); -+ return iRet; -+} -+ -+_osal_inline_ INT32 osal_test_and_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) -+{ -+ UINT32 iRet = 0; -+ -+ osal_bit_op_lock(&(pData->opLock)); -+ iRet = test_and_clear_bit(bitOffset, &pData->data); -+ osal_bit_op_unlock(&(pData->opLock)); -+ return iRet; -+ -+} -+ -+_osal_inline_ INT32 osal_test_and_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) -+{ -+ UINT32 iRet = 0; -+ -+ osal_bit_op_lock(&(pData->opLock)); -+ iRet = test_and_set_bit(bitOffset, &pData->data); -+ osal_bit_op_unlock(&(pData->opLock)); -+ return iRet; -+} -+ -+/* -+ *tiemr operations APIs -+ *create -+ *stop -+ * modify -+ *create -+ *delete -+ * -+*/ -+ -+INT32 osal_timer_create(P_OSAL_TIMER pTimer) -+{ -+ struct timer_list *timer = &pTimer->timer; -+ -+ /*init_timer(timer); -+ timer->function = pTimer->timeoutHandler; -+ timer->data = (unsigned long)pTimer->timeroutHandlerData;*/ -+ timer_setup(timer,pTimer->timeoutHandler,0); -+ return 0; -+} -+ -+INT32 osal_timer_start(P_OSAL_TIMER pTimer, UINT32 ms) -+{ -+ -+ struct timer_list *timer = &pTimer->timer; -+ -+ timer->expires = jiffies + (ms / (1000 / HZ)); -+ add_timer(timer); -+ return 0; -+} -+ -+INT32 osal_timer_stop(P_OSAL_TIMER pTimer) -+{ -+ struct timer_list *timer = &pTimer->timer; -+ -+ del_timer(timer); -+ return 0; -+} -+ -+INT32 osal_timer_stop_sync(P_OSAL_TIMER pTimer) -+{ -+ struct timer_list *timer = &pTimer->timer; -+ -+ del_timer_sync(timer); -+ return 0; -+} -+ -+INT32 osal_timer_modify(P_OSAL_TIMER pTimer, UINT32 ms) -+{ -+ -+ mod_timer(&pTimer->timer, jiffies + (ms) / (1000 / HZ)); -+ return 0; -+} -+ -+INT32 _osal_fifo_init(OSAL_FIFO *pFifo, UINT8 *buf, UINT32 size) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = -1; -+ -+ if (!pFifo) { -+ pr_err("pFifo must be !NULL\n"); -+ return -1; -+ } -+ if (pFifo->pFifoBody) { -+ pr_err("pFifo->pFifoBody must be NULL\n"); -+ pr_err("pFifo(0x%p), pFifo->pFifoBody(0x%p)\n", pFifo, pFifo->pFifoBody); -+ return -1; -+ } -+ fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC); -+ if (!buf) { -+ /*fifo's buffer is not ready, we allocate automatically */ -+ ret = kfifo_alloc(fifo, size, /*GFP_KERNEL */ GFP_ATOMIC); -+ } else { -+ if (is_power_of_2(size)) { -+ kfifo_init(fifo, buf, size); -+ ret = 0; -+ } else { -+ kfifo_free(fifo); -+ fifo = NULL; -+ ret = -1; -+ } -+ } -+ -+ pFifo->pFifoBody = fifo; -+ return (ret < 0) ? (-1) : (0); -+} -+ -+INT32 _osal_fifo_deinit(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ kfifo_free(fifo); -+ -+ return 0; -+} -+ -+INT32 _osal_fifo_size(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ ret = kfifo_size(fifo); -+ -+ return ret; -+} -+ -+/*returns unused bytes in fifo*/ -+INT32 _osal_fifo_avail_size(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ ret = kfifo_avail(fifo); -+ -+ return ret; -+} -+ -+/*returns used bytes in fifo*/ -+INT32 _osal_fifo_len(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ ret = kfifo_len(fifo); -+ -+ return ret; -+} -+ -+INT32 _osal_fifo_is_empty(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ ret = kfifo_is_empty(fifo); -+ -+ return ret; -+} -+ -+INT32 _osal_fifo_is_full(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ ret = kfifo_is_full(fifo); -+ -+ return ret; -+} -+ -+INT32 _osal_fifo_data_in(OSAL_FIFO *pFifo, const VOID *buf, UINT32 len) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo && buf && (len <= _osal_fifo_avail_size(pFifo))) { -+ ret = kfifo_in(fifo, buf, len); -+ } else { -+ pr_err("%s: kfifo_in, error, len = %d, _osal_fifo_avail_size = %d, buf=%p\n", -+ __func__, len, _osal_fifo_avail_size(pFifo), buf); -+ -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+INT32 _osal_fifo_data_out(OSAL_FIFO *pFifo, void *buf, UINT32 len) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo && buf && (len <= _osal_fifo_len(pFifo))) { -+ ret = kfifo_out(fifo, buf, len); -+ } else { -+ pr_err("%s: kfifo_out, error, len = %d, osal_fifo_len = %d, buf=%p\n", -+ __func__, len, _osal_fifo_len(pFifo), buf); -+ -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+INT32 _osal_fifo_reset(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ kfifo_reset(fifo); -+ -+ return 0; -+} -+ -+INT32 osal_fifo_init(P_OSAL_FIFO pFifo, UINT8 *buffer, UINT32 size) -+{ -+ if (!pFifo) { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ pFifo->FifoInit = _osal_fifo_init; -+ pFifo->FifoDeInit = _osal_fifo_deinit; -+ pFifo->FifoSz = _osal_fifo_size; -+ pFifo->FifoAvailSz = _osal_fifo_avail_size; -+ pFifo->FifoLen = _osal_fifo_len; -+ pFifo->FifoIsEmpty = _osal_fifo_is_empty; -+ pFifo->FifoIsFull = _osal_fifo_is_full; -+ pFifo->FifoDataIn = _osal_fifo_data_in; -+ pFifo->FifoDataOut = _osal_fifo_data_out; -+ pFifo->FifoReset = _osal_fifo_reset; -+ -+ if (NULL != pFifo->pFifoBody) { -+ pr_err("%s:Because pFifo room is avialable, we clear the room and allocate them again.\n", __func__); -+ pFifo->FifoDeInit(pFifo->pFifoBody); -+ pFifo->pFifoBody = NULL; -+ } -+ -+ pFifo->FifoInit(pFifo, buffer, size); -+ -+ return 0; -+} -+ -+VOID osal_fifo_deinit(P_OSAL_FIFO pFifo) -+{ -+ if (pFifo) -+ pFifo->FifoDeInit(pFifo); -+ else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ return; -+ } -+ kfree(pFifo->pFifoBody); -+} -+ -+INT32 osal_fifo_reset(P_OSAL_FIFO pFifo) -+{ -+ INT32 ret = -1; -+ -+ if (pFifo) { -+ ret = pFifo->FifoReset(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = -1; -+ } -+ return ret; -+} -+ -+UINT32 osal_fifo_in(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoDataIn(pFifo, buffer, size); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_out(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoDataOut(pFifo, buffer, size); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_len(P_OSAL_FIFO pFifo) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoLen(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_sz(P_OSAL_FIFO pFifo) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoSz(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_avail(P_OSAL_FIFO pFifo) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoAvailSz(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_is_empty(P_OSAL_FIFO pFifo) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoIsEmpty(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_is_full(P_OSAL_FIFO pFifo) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoIsFull(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ return ret; -+} -+ -+INT32 osal_wake_lock_init(P_OSAL_WAKE_LOCK pLock) -+{ -+ if (!pLock) -+ return -1; -+ -+ #ifdef CONFIG_PM_WAKELOCKS -+ wakeup_source_init(&pLock->wake_lock, pLock->name); -+ #else -+ wake_lock_init(&pLock->wake_lock, WAKE_LOCK_SUSPEND, pLock->name); -+ #endif -+ return 0; -+} -+ -+INT32 osal_wake_lock_deinit(P_OSAL_WAKE_LOCK pLock) -+{ -+ if (!pLock) -+ return -1; -+ -+ #ifdef CONFIG_PM_WAKELOCKS -+ wakeup_source_trash(&pLock->wake_lock); -+ #else -+ wake_lock_destroy(&pLock->wake_lock); -+ #endif -+ return 0; -+} -+ -+INT32 osal_wake_lock(P_OSAL_WAKE_LOCK pLock) -+{ -+ if (!pLock) -+ return -1; -+ -+ #ifdef CONFIG_PM_WAKELOCKS -+ __pm_stay_awake(&pLock->wake_lock); -+ #else -+ wake_lock(&pLock->wake_lock); -+ #endif -+ -+ return 0; -+} -+ -+INT32 osal_wake_unlock(P_OSAL_WAKE_LOCK pLock) -+{ -+ if (!pLock) -+ return -1; -+ -+ #ifdef CONFIG_PM_WAKELOCKS -+ __pm_relax(&pLock->wake_lock); -+ #else -+ wake_unlock(&pLock->wake_lock); -+ #endif -+ -+ return 0; -+ -+} -+ -+INT32 osal_wake_lock_count(P_OSAL_WAKE_LOCK pLock) -+{ -+ INT32 count = 0; -+ -+ if (!pLock) -+ return -1; -+ -+ #ifdef CONFIG_PM_WAKELOCKS -+ count = pLock->wake_lock.active; -+ #else -+ count = wake_lock_active(&pLock->wake_lock); -+ #endif -+ return count; -+} -+ -+/* -+ *sleepable lock operations APIs -+ *init -+ *lock -+ *unlock -+ *destroy -+ * -+*/ -+ -+#if !defined(CONFIG_PROVE_LOCKING) -+INT32 osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK pUSL) -+{ -+ spin_lock_init(&(pUSL->lock)); -+ return 0; -+} -+#endif -+ -+INT32 osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL) -+{ -+ spin_lock_irqsave(&(pUSL->lock), pUSL->flag); -+ return 0; -+} -+ -+INT32 osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL) -+{ -+ spin_unlock_irqrestore(&(pUSL->lock), pUSL->flag); -+ return 0; -+} -+ -+INT32 osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK pUSL) -+{ -+ return 0; -+} -+ -+/* -+ *unsleepable operations APIs -+ *init -+ *lock -+ *unlock -+ *destroy -+ -+ * -+*/ -+ -+#if !defined(CONFIG_PROVE_LOCKING) -+INT32 osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK pSL) -+{ -+ mutex_init(&pSL->lock); -+ return 0; -+} -+#endif -+ -+INT32 osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL) -+{ -+ return mutex_lock_killable(&pSL->lock); -+} -+ -+INT32 osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL) -+{ -+ mutex_unlock(&pSL->lock); -+ return 0; -+} -+ -+INT32 osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK pSL) -+{ -+ mutex_destroy(&pSL->lock); -+ return 0; -+} -+ -+INT32 osal_sleep_ms(UINT32 ms) -+{ -+ msleep(ms); -+ return 0; -+} -+ -+INT32 osal_udelay(UINT32 us) -+{ -+ udelay(us); -+ return 0; -+} -+ -+INT32 osal_gettimeofday(PINT32 sec, PINT32 usec) -+{ -+ INT32 ret = 0; -+ struct timeval now; -+ -+ do_gettimeofday(&now); -+ -+ if (sec != NULL) -+ *sec = now.tv_sec; -+ else -+ ret = -1; -+ -+ if (usec != NULL) -+ *usec = now.tv_usec; -+ else -+ ret = -1; -+ -+ return ret; -+} -+ -+INT32 osal_printtimeofday(const PUINT8 prefix) -+{ -+ INT32 ret; -+ INT32 sec; -+ INT32 usec; -+ -+ ret = osal_gettimeofday(&sec, &usec); -+ ret += osal_dbg_print("%s>sec=%d, usec=%d\n", prefix, sec, usec); -+ -+ return ret; -+} -+ -+VOID osal_buffer_dump(const UINT8 *buf, const UINT8 *title, const UINT32 len, const UINT32 limit) -+{ -+ INT32 k; -+ UINT32 dump_len; -+ -+ pr_warn("start of dump>[%s] len=%d, limit=%d,", title, len, limit); -+ -+ dump_len = ((0 != limit) && (len > limit)) ? limit : len; -+#if 0 -+ if (limit != 0) -+ len = (len > limit) ? (limit) : (len); -+ -+#endif -+ -+ for (k = 0; k < dump_len; k++) { -+ if ((k != 0) && (k % 16 == 0)) -+ pr_cont("\n"); -+ pr_cont("0x%02x ", buf[k]); -+ } -+ pr_warn("op.opId : 0xFFFFFFFF; -+} -+ -+MTK_WCN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp) -+{ -+ return (pOp && pOp->signal.timeoutValue) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; -+} -+ -+VOID osal_op_raise_signal(P_OSAL_OP pOp, INT32 result) -+{ -+ if (pOp) { -+ pOp->result = result; -+ osal_raise_signal(&pOp->signal); -+ } -+} -+ -+VOID osal_set_op_result(P_OSAL_OP pOp, INT32 result) -+{ -+ if (pOp) -+ pOp->result = result; -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c -new file mode 100644 -index 0000000000000..190fa3944d801 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c -@@ -0,0 +1,899 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if WMT_CREATE_NODE_DYNAMIC -+#include -+#endif -+#include -+ -+#include "osal_typedef.h" -+#include "stp_exp.h" -+#include "wmt_exp.h" -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+ -+#ifdef MTK_BT_HCI -+#define MTK_BT_DEBUG 0 -+#include -+#include -+#endif -+ -+ -+#define BT_DRIVER_NAME "mtk_stp_BT_chrdev" -+#define BT_DEV_MAJOR 192 /* Never used number */ -+ -+#define PFX "[MTK-BT] " -+#define BT_LOG_DBG 3 -+#define BT_LOG_INFO 2 -+#define BT_LOG_WARN 1 -+#define BT_LOG_ERR 0 -+ -+#define COMBO_IOC_MAGIC 0xb0 -+#define COMBO_IOCTL_FW_ASSERT _IOWR(COMBO_IOC_MAGIC, 0, int) -+#define COMBO_IOCTL_BT_IC_HW_VER _IOWR(COMBO_IOC_MAGIC, 1, void*) -+#define COMBO_IOCTL_BT_IC_FW_VER _IOWR(COMBO_IOC_MAGIC, 2, void*) -+#define COMBO_IOC_BT_HWVER _IOWR(COMBO_IOC_MAGIC, 3, void*) -+ -+static UINT32 gDbgLevel = BT_LOG_INFO; -+ -+#define BT_DBG_FUNC(fmt, arg...) \ -+ do { if (gDbgLevel >= BT_LOG_DBG) \ -+ pr_debug(PFX "%s: " fmt, __func__ , ##arg); \ -+ } while (0) -+#define BT_INFO_FUNC(fmt, arg...) \ -+ do { if (gDbgLevel >= BT_LOG_INFO) \ -+ pr_warn(PFX "%s: " fmt, __func__ , ##arg); \ -+ } while (0) -+#define BT_WARN_FUNC(fmt, arg...) \ -+ do { if (gDbgLevel >= BT_LOG_WARN) \ -+ pr_err(PFX "%s: " fmt, __func__ , ##arg); \ -+ } while (0) -+#define BT_ERR_FUNC(fmt, arg...) \ -+ do { if (gDbgLevel >= BT_LOG_ERR) \ -+ pr_err(PFX "%s: " fmt, __func__ , ##arg); \ -+ } while (0) -+ -+#define VERSION "1.0" -+ -+#ifdef MTK_BT_HCI -+ -+#define NUM_REASSEMBLY 32 -+struct mtk_hci { -+ struct hci_dev *hdev; -+ struct work_struct work; -+ struct sk_buff_head txq; -+ struct sk_buff *reassembly[NUM_REASSEMBLY]; -+}; -+ -+static struct mtk_hci mtk_hci; -+ -+#endif -+ -+#if WMT_CREATE_NODE_DYNAMIC -+struct class *stpbt_class = NULL; -+struct device *stpbt_dev = NULL; -+#endif -+ -+static INT32 BT_devs = 1; /* Device count */ -+static INT32 BT_major = BT_DEV_MAJOR; /* Dynamic allocation */ -+module_param(BT_major, uint, 0); -+static struct cdev BT_cdev; -+ -+#define BT_BUFFER_SIZE 2048 -+static UINT8 i_buf[BT_BUFFER_SIZE]; /* Input buffer of read() */ -+static UINT8 o_buf[BT_BUFFER_SIZE]; /* Output buffer of write() */ -+ -+static struct semaphore wr_mtx, rd_mtx; -+/* Wait queue for poll and read */ -+static wait_queue_head_t inq; -+static DECLARE_WAIT_QUEUE_HEAD(BT_wq); -+static INT32 flag; -+/* Reset flag for whole chip reset senario */ -+static volatile INT32 rstflag; -+ -+#ifdef MTK_BT_HCI -+static int hci_reassembly(struct hci_dev *hdev, int type, void *data, -+ int count, __u8 index) -+{ -+ int len = 0; -+ int hlen = 0; -+ int offset = 0; -+ int remain = count; -+ struct sk_buff *skb; -+ struct bt_skb_cb *scb; -+ u16 opcode = 0; -+ unsigned char *pdata = data; -+ -+ struct mtk_hci *info = NULL; -+ struct hci_event_hdr *ehdr = NULL; -+ struct hci_ev_cmd_complete *ev = NULL; -+ struct hci_rp_read_local_ext_features *ext = NULL; -+ -+ info = hci_get_drvdata(hdev); -+ if ( NULL == info ) { -+ printk(KERN_ERR "mtk_bt_hci: invalid info point\n"); -+ return 0; -+ } -+ -+ if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || -+ index >= NUM_REASSEMBLY) -+ return -EILSEQ; -+ -+ skb = info->reassembly[index]; -+ -+ if (!skb) { -+ switch (type) { -+ case HCI_ACLDATA_PKT: -+ len = HCI_MAX_FRAME_SIZE; -+ hlen = HCI_ACL_HDR_SIZE; -+ break; -+ case HCI_EVENT_PKT: -+ len = HCI_MAX_EVENT_SIZE; -+ hlen = HCI_EVENT_HDR_SIZE; -+ break; -+ case HCI_SCODATA_PKT: -+ len = HCI_MAX_SCO_SIZE; -+ hlen = HCI_SCO_HDR_SIZE; -+ break; -+ } -+ -+ skb = bt_skb_alloc(len, GFP_ATOMIC); -+ if (!skb) -+ return -ENOMEM; -+ -+ scb = (void *) skb->cb; -+ scb->expect = hlen; -+ scb->pkt_type = type; -+ -+ info->reassembly[index] = skb; -+ } -+ -+ while (count) { -+ scb = (void *) skb->cb; -+ len = min_t(uint, scb->expect, count); -+ -+ /* -+ * Workaround for MT7623+MT6625 BT: the max page in response of cmd READ_LOCAL_EXT_FEATURES -+ * should be 1, instead of 2, so changing it to 1 here -+ */ -+ -+ if (HCI_EVENT_PKT == type) -+ { -+ ehdr = (void *)pdata; -+ offset = sizeof(struct hci_event_hdr); -+ if ( HCI_EV_CMD_COMPLETE == ehdr->evt) -+ { -+ ev = (struct hci_ev_cmd_complete *)&pdata[offset]; -+ -+ offset += sizeof(struct hci_ev_cmd_complete); -+ -+ opcode = __le16_to_cpu(ev->opcode); -+ if(HCI_OP_READ_LOCAL_EXT_FEATURES == opcode) { -+ ext = (struct hci_rp_read_local_ext_features *) &pdata[offset]; -+ if( !ext->status && ext->max_page >= 2) { -+ pr_info("%s: this workaround is applied for mediatek BT\n", __func__); -+ ext->max_page = 1; -+ } -+ } -+ -+ } -+ } -+ -+ memcpy(skb_put(skb, len), data, len); -+ -+ count -= len; -+ data += len; -+ scb->expect -= len; -+ remain = count; -+ -+ switch (type) { -+ case HCI_EVENT_PKT: -+ if (skb->len == HCI_EVENT_HDR_SIZE) { -+ struct hci_event_hdr *h = hci_event_hdr(skb); -+ -+ scb->expect = h->plen; -+ -+ if (skb_tailroom(skb) < scb->expect) { -+ kfree_skb(skb); -+ info->reassembly[index] = NULL; -+ return -ENOMEM; -+ } -+ } -+ -+ break; -+ -+ case HCI_ACLDATA_PKT: -+ if (skb->len == HCI_ACL_HDR_SIZE) { -+ struct hci_acl_hdr *h = hci_acl_hdr(skb); -+ -+ scb->expect = __le16_to_cpu(h->dlen); -+ -+ if (skb_tailroom(skb) < scb->expect) { -+ kfree_skb(skb); -+ info->reassembly[index] = NULL; -+ return -ENOMEM; -+ } -+ } -+ break; -+ -+ case HCI_SCODATA_PKT: -+ if (skb->len == HCI_SCO_HDR_SIZE) { -+ struct hci_sco_hdr *h = hci_sco_hdr(skb); -+ -+ scb->expect = h->dlen; -+ -+ if (skb_tailroom(skb) < scb->expect) { -+ kfree_skb(skb); -+ info->reassembly[index] = NULL; -+ return -ENOMEM; -+ } -+ } -+ break; -+ } -+ -+ if (scb->expect == 0) { -+ /* Complete frame */ -+ -+ bt_cb(skb)->pkt_type = type; -+ hci_recv_frame(hdev, skb); -+ -+ info->reassembly[index] = NULL; -+ return remain; -+ } -+ } -+ -+ return remain; -+} -+ -+int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) -+{ -+ int rem = 0; -+ -+ if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) -+ return -EILSEQ; -+ -+ while (count) { -+ rem = hci_reassembly(hdev, type, data, count, type - 1); -+ if (rem < 0) -+ return rem; -+ -+ data += (count - rem); -+ count = rem; -+ } -+ -+ return rem; -+} -+#endif -+ -+#ifdef MTK_BT_HCI -+void -+hex_dump(char *prefix, char *p, int len) -+{ -+ int i; -+ -+ pr_err("%s ", prefix); -+ for (i = 0; i < len; i++) -+ pr_err("%02x ", (*p++ & 0xff)); -+ pr_err("\n"); -+} -+ -+static int -+mtk_bt_hci_open(struct hci_dev *hdev) -+{ -+ int err = 0; -+ -+#if MTK_BT_DEBUG == 1 -+ pr_err("# %s\n", __func__); -+#endif -+ -+ err = mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT); -+ if (err != MTK_WCN_BOOL_TRUE) { -+ pr_err("%s func on failed with %d\n", __func__, err); -+ return -ENODEV; -+ } -+ -+ set_bit(HCI_RUNNING, &hdev->flags); -+ -+ mtk_wcn_stp_set_bluez(1); -+ -+ return 0; -+} -+ -+static int -+mtk_bt_hci_close(struct hci_dev *hdev) -+{ -+ int err = 0; -+ -+#if MTK_BT_DEBUG == 1 -+ pr_err("# %s\n", __func__); -+#endif -+ -+ mtk_wcn_stp_set_bluez(0); -+ -+ clear_bit(HCI_RUNNING, &hdev->flags); -+ -+ err = mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); -+ if (err != MTK_WCN_BOOL_TRUE) { -+ pr_err("%s func off failed with %d\n", __func__, err); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static void -+mtk_bt_hci_work(struct work_struct *work) -+{ -+ int err; -+ struct sk_buff *skb; -+ -+#if MTK_BT_DEBUG == 1 -+ pr_err("# %s\n", __func__); -+#endif -+ -+ while ((skb = skb_dequeue(&mtk_hci.txq))) { -+ skb_push(skb, 1); -+ skb->data[0] = bt_cb(skb)->pkt_type; -+ -+#if MTK_BT_DEBUG == 1 -+ hex_dump(">>", skb->data, skb->len); -+#endif -+ -+ err = mtk_wcn_stp_send_data(skb->data, skb->len, BT_TASK_INDX); -+ if (err < 0) { -+ pr_err("%s err=%d\n", __func__, err); -+ mtk_hci.hdev->stat.err_tx++; -+ skb_queue_head(&mtk_hci.txq, skb); -+ break; -+ } -+ -+ mtk_hci.hdev->stat.byte_tx += skb->len; -+ kfree_skb(skb); -+ } -+} -+ -+static int -+mtk_bt_hci_send(struct hci_dev *hdev, struct sk_buff *skb) -+{ -+#if MTK_BT_DEBUG == 1 -+ pr_err("# %s\n", __func__); -+#endif -+ -+ if (mtk_hci.hdev && !test_bit(HCI_RUNNING, &mtk_hci.hdev->flags)) -+ return -EBUSY; -+ -+ switch (bt_cb(skb)->pkt_type) { -+ case HCI_COMMAND_PKT: -+ mtk_hci.hdev->stat.cmd_tx++; -+ break; -+ -+ case HCI_ACLDATA_PKT: -+ mtk_hci.hdev->stat.acl_tx++; -+ break; -+ -+ case HCI_SCODATA_PKT: -+ mtk_hci.hdev->stat.sco_tx++; -+ break; -+ -+ default: -+ return -EILSEQ; -+ } -+ -+ skb_queue_tail(&mtk_hci.txq, skb); -+ schedule_work(&mtk_hci.work); -+ -+ return 0; -+} -+ -+static int -+mtk_bt_hci_flush(struct hci_dev *hdev) -+{ -+ pr_err("%s: todo\n", __func__); -+ -+ return 0; -+} -+ -+static void -+mtk_bt_hci_receive(const PUINT8 data, INT32 size) -+{ -+ int err; -+ -+#if MTK_BT_DEBUG == 1 -+ pr_err("# %s\n", __func__); -+ hex_dump("<<", data, size); -+#endif -+ -+ err = hci_recv_fragment(mtk_hci.hdev, data[0], (void *)&data[1], size - 1); -+ if (err < 0) -+ pr_err("%s: hci_recv_fragment failed with %d\n", __func__, err); -+ -+ if (mtk_hci.hdev) -+ mtk_hci.hdev->stat.byte_rx += size - 1; -+} -+ -+static void -+mtk_bt_hci_notify(struct hci_dev *hdev, unsigned int evt) -+{ -+ static const char * const notify_str[] = { -+ "null", -+ "HCI_NOTIFY_CONN_ADD", -+ "HCI_NOTIFY_CONN_DEL", -+ "HCI_NOTIFY_VOICE_SETTING" -+ }; -+ -+ if (evt > HCI_NOTIFY_VOICE_SETTING) -+ pr_info("%s event=0x%x\n", __func__, evt); -+ else -+ pr_info("%s event(%d)=%s\n", __func__, evt, notify_str[evt]); -+} -+#endif -+ -+#ifdef MTK_BT_HCI -+ -+int mtk_bt_hci_init(void) -+{ -+ INT32 hci_err = 0; -+ -+ mtk_hci.hdev = hci_alloc_dev(); -+ if (!(mtk_hci.hdev)) { -+ mtk_hci.hdev = NULL; -+ BT_ERR_FUNC("%s hci_alloc_dev failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ mtk_hci.hdev->bus = HCI_SDIO; -+ mtk_hci.hdev->open = mtk_bt_hci_open; -+ mtk_hci.hdev->close = mtk_bt_hci_close; -+ mtk_hci.hdev->send = mtk_bt_hci_send; -+ mtk_hci.hdev->flush = mtk_bt_hci_flush; -+ mtk_hci.hdev->notify = mtk_bt_hci_notify; -+ SET_HCIDEV_DEV(mtk_hci.hdev, stpbt_dev); -+ -+ hci_set_drvdata(mtk_hci.hdev, &mtk_hci); -+ -+ mtk_wcn_stp_register_if_rx(mtk_bt_hci_receive); -+ -+ hci_err = hci_register_dev(mtk_hci.hdev); -+ if (hci_err) { -+ BT_ERR_FUNC("%s hci_register_dev failed with %d\n", __func__, hci_err); -+ hci_free_dev(mtk_hci.hdev); -+ mtk_hci.hdev = NULL; -+ return hci_err; -+ } -+ -+ skb_queue_head_init(&mtk_hci.txq); -+ INIT_WORK(&mtk_hci.work, mtk_bt_hci_work); -+ -+ return 0; -+} -+#endif -+ -+ -+static VOID bt_cdev_rst_cb(ENUM_WMTDRV_TYPE_T src, -+ ENUM_WMTDRV_TYPE_T dst, ENUM_WMTMSG_TYPE_T type, PVOID buf, UINT32 sz) -+{ -+ /* -+ Handle whole chip reset messages -+ */ -+ ENUM_WMTRSTMSG_TYPE_T rst_msg; -+ -+ if (sz <= sizeof(ENUM_WMTRSTMSG_TYPE_T)) { -+ memcpy((PINT8)&rst_msg, (PINT8)buf, sz); -+ BT_DBG_FUNC("src = %d, dst = %d, type = %d, buf = 0x%x sz = %d, max = %d\n", src, -+ dst, type, rst_msg, sz, WMTRSTMSG_RESET_MAX); -+ if ((src == WMTDRV_TYPE_WMT) && (dst == WMTDRV_TYPE_BT) -+ && (type == WMTMSG_TYPE_RESET)) { -+ if (rst_msg == WMTRSTMSG_RESET_START) { -+ BT_INFO_FUNC("BT reset start!\n"); -+ rstflag = 1; -+ wake_up_interruptible(&inq); -+ -+ } else if (rst_msg == WMTRSTMSG_RESET_END) { -+ BT_INFO_FUNC("BT reset end!\n"); -+ rstflag = 2; -+ wake_up_interruptible(&inq); -+ } -+ } -+ } else { -+ /* Invalid message format */ -+ BT_WARN_FUNC("Invalid message format!\n"); -+ } -+} -+ -+VOID BT_event_cb(VOID) -+{ -+ BT_DBG_FUNC("BT_event_cb()\n"); -+ -+ flag = 1; -+ -+ /* -+ * Finally, wake up any reader blocked in poll or read -+ */ -+ wake_up_interruptible(&inq); -+ wake_up(&BT_wq); -+} -+ -+unsigned int BT_poll(struct file *filp, poll_table *wait) -+{ -+ UINT32 mask = 0; -+ -+/* down(&wr_mtx); */ -+ /* -+ * The buffer is circular; it is considered full -+ * if "wp" is right behind "rp". "left" is 0 if the -+ * buffer is empty, and it is "1" if it is completely full. -+ */ -+ if (mtk_wcn_stp_is_rxqueue_empty(BT_TASK_INDX)) { -+ poll_wait(filp, &inq, wait); -+ -+ if (!mtk_wcn_stp_is_rxqueue_empty(BT_TASK_INDX) || rstflag) -+ /* BT Rx queue has valid data, or whole chip reset occurs */ -+ mask |= POLLIN | POLLRDNORM; /* Readable */ -+ } else { -+ mask |= POLLIN | POLLRDNORM; /* Readable */ -+ } -+ -+ /* Do we need condition here? */ -+ mask |= POLLOUT | POLLWRNORM; /* Writable */ -+/* up(&wr_mtx); */ -+ return mask; -+} -+ -+ssize_t BT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ INT32 retval = 0; -+ INT32 write_size; -+ INT32 written = 0; -+ -+ down(&wr_mtx); -+ -+ BT_DBG_FUNC("%s: count %zd pos %lld\n", __func__, count, *f_pos); -+ if (rstflag) { -+ if (rstflag == 1) { /* Reset start */ -+ retval = -88; -+ BT_INFO_FUNC("%s: detect whole chip reset start\n", __func__); -+ } else if (rstflag == 2) { /* Reset end */ -+ retval = -99; -+ BT_INFO_FUNC("%s: detect whole chip reset end\n", __func__); -+ } -+ goto OUT; -+ } -+ -+ if (count > 0) { -+ if (count < BT_BUFFER_SIZE) { -+ write_size = count; -+ } else { -+ write_size = BT_BUFFER_SIZE; -+ BT_ERR_FUNC("%s: count > BT_BUFFER_SIZE\n", __func__); -+ } -+ -+ if (copy_from_user(&o_buf[0], &buf[0], write_size)) { -+ retval = -EFAULT; -+ goto OUT; -+ } -+ -+ written = mtk_wcn_stp_send_data(&o_buf[0], write_size, BT_TASK_INDX); -+ if (0 == written) { -+ retval = -ENOSPC; -+ /* No space is available, native program should not call BT_write with no delay */ -+ BT_ERR_FUNC -+ ("Packet length %zd, sent length %d, retval = %d\n", -+ count, written, retval); -+ } else { -+ retval = written; -+ } -+ -+ } else { -+ retval = -EFAULT; -+ BT_ERR_FUNC("Packet length %zd is not allowed, retval = %d\n", count, retval); -+ } -+ -+OUT: -+ up(&wr_mtx); -+ return retval; -+} -+ -+ssize_t BT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ static int chip_reset_count; -+ INT32 retval = 0; -+ -+ down(&rd_mtx); -+ -+ BT_DBG_FUNC("%s: count %zd pos %lld\n", __func__, count, *f_pos); -+ if (rstflag) { -+ if (rstflag == 1) { /* Reset start */ -+ retval = -88; -+ if ((chip_reset_count%500) == 0) -+ BT_INFO_FUNC("%s: detect whole chip reset start, %d\n", __func__, chip_reset_count); -+ chip_reset_count++; -+ } else if (rstflag == 2) { /* Reset end */ -+ retval = -99; -+ BT_INFO_FUNC("%s: detect whole chip reset end\n", __func__); -+ chip_reset_count = 0; -+ } -+ goto OUT; -+ } -+ -+ if (count > BT_BUFFER_SIZE) { -+ count = BT_BUFFER_SIZE; -+ BT_ERR_FUNC("%s: count > BT_BUFFER_SIZE\n", __func__); -+ } -+ -+ retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX); -+ -+ while (retval == 0) { /* Got nothing, wait for STP's signal */ -+ /* -+ * If nonblocking mode, return directly. -+ * O_NONBLOCK is specified during open() -+ */ -+ if (filp->f_flags & O_NONBLOCK) { -+ BT_DBG_FUNC("Non-blocking BT_read\n"); -+ retval = -EAGAIN; -+ goto OUT; -+ } -+ -+ BT_DBG_FUNC("%s: wait_event 1\n", __func__); -+ wait_event(BT_wq, flag != 0); -+ BT_DBG_FUNC("%s: wait_event 2\n", __func__); -+ flag = 0; -+ retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX); -+ BT_DBG_FUNC("%s: mtk_wcn_stp_receive_data returns %d\n", __func__, retval); -+ } -+ -+ /* Got something from STP driver */ -+ if (copy_to_user(buf, i_buf, retval)) { -+ retval = -EFAULT; -+ goto OUT; -+ } -+ -+OUT: -+ up(&rd_mtx); -+ BT_DBG_FUNC("%s: retval = %d\n", __func__, retval); -+ return retval; -+} -+ -+/* int BT_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) */ -+long BT_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ INT32 retval = 0; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_TRUE; -+ ENUM_WMTHWVER_TYPE_T hw_ver_sym = WMTHWVER_INVALID; -+ -+ BT_DBG_FUNC("%s: cmd: 0x%x\n", __func__, cmd); -+ -+ switch (cmd) { -+ case COMBO_IOC_BT_HWVER: -+ /* Get combo HW version */ -+ hw_ver_sym = mtk_wcn_wmt_hwver_get(); -+ BT_INFO_FUNC("%s: HW version = %d, sizeof(hw_ver_sym) = %zd\n", -+ __func__, hw_ver_sym, sizeof(hw_ver_sym)); -+ if (copy_to_user((int __user *)arg, &hw_ver_sym, sizeof(hw_ver_sym))) -+ retval = -EFAULT; -+ break; -+ -+ case COMBO_IOCTL_FW_ASSERT: -+ /* Trigger FW assert for debug */ -+ BT_INFO_FUNC("%s: Host trigger FW assert......, reason:%lu\n", __func__, arg); -+ bRet = mtk_wcn_wmt_assert(WMTDRV_TYPE_BT, arg); -+ if (bRet == MTK_WCN_BOOL_TRUE) { -+ BT_INFO_FUNC("Host trigger FW assert succeed\n"); -+ retval = 0; -+ } else { -+ BT_ERR_FUNC("Host trigger FW assert Failed\n"); -+ retval = (-EBUSY); -+ } -+ break; -+ case COMBO_IOCTL_BT_IC_HW_VER: -+ retval = mtk_wcn_wmt_ic_info_get(WMTCHIN_HWVER); -+ break; -+ case COMBO_IOCTL_BT_IC_FW_VER: -+ retval = mtk_wcn_wmt_ic_info_get(WMTCHIN_FWVER); -+ break; -+ default: -+ retval = -EFAULT; -+ BT_ERR_FUNC("Unknown cmd (%d)\n", cmd); -+ break; -+ } -+ -+ return retval; -+} -+ -+long BT_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ return BT_unlocked_ioctl(filp, cmd, arg); -+} -+ -+static int BT_open(struct inode *inode, struct file *file) -+{ -+ BT_INFO_FUNC("%s: major %d minor %d pid %d\n", __func__, imajor(inode), iminor(inode), current->pid); -+ -+ /* Turn on BT */ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT)) { -+ BT_WARN_FUNC("WMT turn on BT fail!\n"); -+ return -ENODEV; -+ } -+ -+ BT_INFO_FUNC("WMT turn on BT OK!\n"); -+ rstflag = 0; -+ -+ if (mtk_wcn_stp_is_ready()) { -+ -+ mtk_wcn_stp_set_bluez(0); -+ -+ BT_INFO_FUNC("Now it's in MTK Bluetooth Mode\n"); -+ BT_INFO_FUNC("STP is ready!\n"); -+ -+ BT_DBG_FUNC("Register BT event callback!\n"); -+ mtk_wcn_stp_register_event_cb(BT_TASK_INDX, BT_event_cb); -+ } else { -+ BT_ERR_FUNC("STP is not ready\n"); -+ mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); -+ return -ENODEV; -+ } -+ -+ BT_DBG_FUNC("Register BT reset callback!\n"); -+ mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_BT, bt_cdev_rst_cb); -+ -+ /* init_MUTEX(&wr_mtx); */ -+ sema_init(&wr_mtx, 1); -+ /* init_MUTEX(&rd_mtx); */ -+ sema_init(&rd_mtx, 1); -+ BT_INFO_FUNC("%s: finish\n", __func__); -+ -+ return 0; -+} -+ -+static int BT_close(struct inode *inode, struct file *file) -+{ -+ BT_INFO_FUNC("%s: major %d minor %d pid %d\n", __func__, imajor(inode), iminor(inode), current->pid); -+ rstflag = 0; -+ mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_BT); -+ mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL); -+ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT)) { -+ BT_ERR_FUNC("WMT turn off BT fail!\n"); -+ return -EIO; /* Mostly, native program will not check this return value. */ -+ } -+ -+ BT_INFO_FUNC("WMT turn off BT OK!\n"); -+ -+ return 0; -+} -+ -+const struct file_operations BT_fops = { -+ .open = BT_open, -+ .release = BT_close, -+ .read = BT_read, -+ .write = BT_write, -+ /* .ioctl = BT_ioctl, */ -+ .unlocked_ioctl = BT_unlocked_ioctl, -+ .compat_ioctl = BT_compat_ioctl, -+ .poll = BT_poll -+}; -+ -+ -+ -+static int BT_init(void) -+{ -+ dev_t dev = MKDEV(BT_major, 0); -+ INT32 alloc_ret = 0; -+ INT32 cdev_err = 0; -+ -+ /* Static allocate char device */ -+ alloc_ret = register_chrdev_region(dev, 1, BT_DRIVER_NAME); -+ if (alloc_ret) { -+ BT_ERR_FUNC("%s: Failed to register char device\n", __func__); -+ return alloc_ret; -+ } -+ -+ cdev_init(&BT_cdev, &BT_fops); -+ BT_cdev.owner = THIS_MODULE; -+ -+ cdev_err = cdev_add(&BT_cdev, dev, BT_devs); -+ if (cdev_err) -+ goto error; -+ -+#if WMT_CREATE_NODE_DYNAMIC -+ stpbt_class = class_create(THIS_MODULE, "stpbt"); -+ if (IS_ERR(stpbt_class)) -+ goto error; -+ stpbt_dev = device_create(stpbt_class, NULL, dev, NULL, "stpbt"); -+ if (IS_ERR(stpbt_dev)) -+ goto error; -+#endif -+ -+ BT_INFO_FUNC("%s driver(major %d) installed\n", BT_DRIVER_NAME, BT_major); -+ -+ /* Init wait queue */ -+ init_waitqueue_head(&(inq)); -+ -+#ifdef MTK_BT_HCI -+ mtk_bt_hci_init(); -+#endif -+ -+ return 0; -+ -+error: -+#if WMT_CREATE_NODE_DYNAMIC -+ if (!IS_ERR(stpbt_dev)) -+ device_destroy(stpbt_class, dev); -+ if (!IS_ERR(stpbt_class)) { -+ class_destroy(stpbt_class); -+ stpbt_class = NULL; -+ } -+#endif -+ if (cdev_err == 0) -+ cdev_del(&BT_cdev); -+ -+ if (alloc_ret == 0) -+ unregister_chrdev_region(dev, BT_devs); -+ -+ return -1; -+} -+ -+static void BT_exit(void) -+{ -+ dev_t dev = MKDEV(BT_major, 0); -+ -+#if WMT_CREATE_NODE_DYNAMIC -+ if (stpbt_dev) { -+ device_destroy(stpbt_class, dev); -+ stpbt_dev = NULL; -+ } -+ if (stpbt_class) { -+ class_destroy(stpbt_class); -+ stpbt_class = NULL; -+ } -+#endif -+ -+ cdev_del(&BT_cdev); -+ unregister_chrdev_region(dev, BT_devs); -+ -+ BT_INFO_FUNC("%s driver removed\n", BT_DRIVER_NAME); -+} -+ -+#ifdef MTK_WCN_REMOVE_KERNEL_MODULE -+ -+int mtk_wcn_stpbt_drv_init(void) -+{ -+ return BT_init(); -+} -+EXPORT_SYMBOL(mtk_wcn_stpbt_drv_init); -+ -+void mtk_wcn_stpbt_drv_exit(void) -+{ -+ return BT_exit(); -+} -+EXPORT_SYMBOL(mtk_wcn_stpbt_drv_exit); -+ -+#else -+ -+module_init(BT_init); -+module_exit(BT_exit); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -new file mode 100644 -index 0000000000000..3c7b2969c98a8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -@@ -0,0 +1,668 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "wmt_exp.h" -+#include "stp_exp.h" -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+ -+#define WIFI_DRIVER_NAME "mtk_wmt_WIFI_chrdev" -+#define WIFI_DEV_MAJOR 155 -+ -+#define PFX "[MTK-WIFI] " -+#define WIFI_LOG_DBG 3 -+#define WIFI_LOG_INFO 2 -+#define WIFI_LOG_WARN 1 -+#define WIFI_LOG_ERR 0 -+ -+UINT32 gDbgLevel = WIFI_LOG_DBG; -+ -+#define WIFI_DBG_FUNC(fmt, arg...)\ -+ do {if (gDbgLevel >= WIFI_LOG_DBG) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) -+#define WIFI_INFO_FUNC(fmt, arg...)\ -+ do {if (gDbgLevel >= WIFI_LOG_INFO) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) -+#define WIFI_WARN_FUNC(fmt, arg...)\ -+ do {if (gDbgLevel >= WIFI_LOG_WARN) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) -+#define WIFI_ERR_FUNC(fmt, arg...)\ -+ do {if (gDbgLevel >= WIFI_LOG_ERR) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) -+#define WIFI_TRC_FUNC(f)\ -+ do {if (gDbgLevel >= WIFI_LOG_DBG) printk(PFX "<%s> <%d>\n", __func__, __LINE__); } while (0) -+ -+#define VERSION "1.0" -+ -+#define WLAN_IFACE_NAME "wlan0" -+#if CFG_TC1_FEATURE -+#define LEGACY_IFACE_NAME "legacy0" -+#endif -+ -+enum { -+ WLAN_MODE_HALT, -+ WLAN_MODE_AP, -+ WLAN_MODE_STA_P2P, -+ WLAN_MODE_MAX -+}; -+static INT32 wlan_mode = WLAN_MODE_HALT; -+static INT32 powered; -+static INT8 *ifname = WLAN_IFACE_NAME; -+#if CFG_TC1_FEATURE -+volatile INT32 wlan_if_changed = 0; -+EXPORT_SYMBOL(wlan_if_changed); -+#endif -+ -+typedef enum _ENUM_RESET_STATUS_T { -+ RESET_FAIL, -+ RESET_SUCCESS -+} ENUM_RESET_STATUS_T; -+ -+/* -+ * enable = 1, mode = 0 => init P2P network -+ * enable = 1, mode = 1 => init Soft AP network -+ * enable = 0 => uninit P2P/AP network -+ */ -+typedef struct _PARAM_CUSTOM_P2P_SET_STRUCT_T { -+ UINT32 u4Enable; -+ UINT32 u4Mode; -+} PARAM_CUSTOM_P2P_SET_STRUCT_T, *P_PARAM_CUSTOM_P2P_SET_STRUCT_T; -+typedef INT32(*set_p2p_mode) (struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode); -+ -+static set_p2p_mode pf_set_p2p_mode; -+VOID register_set_p2p_mode_handler(set_p2p_mode handler) -+{ -+ WIFI_INFO_FUNC("(pid %d) register set p2p mode handler %p\n", current->pid, handler); -+ pf_set_p2p_mode = handler; -+} -+EXPORT_SYMBOL(register_set_p2p_mode_handler); -+ -+/* For dynamical debug level setting */ -+/* copy of debug.h in wlan driver */ -+#define DBG_CLASS_ERROR BIT(0) -+#define DBG_CLASS_WARN BIT(1) -+#define DBG_CLASS_STATE BIT(2) -+#define DBG_CLASS_EVENT BIT(3) -+#define DBG_CLASS_TRACE BIT(4) -+#define DBG_CLASS_INFO BIT(5) -+#define DBG_CLASS_LOUD BIT(6) -+#define DBG_CLASS_TEMP BIT(7) -+#define DBG_CLASS_MASK BITS(0, 7) -+ -+typedef enum _ENUM_DBG_MODULE_T { -+ DBG_INIT_IDX = 0, /* For driver initial */ -+ DBG_HAL_IDX, /* For HAL(HW) Layer */ -+ DBG_INTR_IDX, /* For Interrupt */ -+ DBG_REQ_IDX, -+ DBG_TX_IDX, -+ DBG_RX_IDX, -+ DBG_RFTEST_IDX, /* For RF test mode */ -+ DBG_EMU_IDX, /* Developer specific */ -+ -+ DBG_SW1_IDX, /* Developer specific */ -+ DBG_SW2_IDX, /* Developer specific */ -+ DBG_SW3_IDX, /* Developer specific */ -+ DBG_SW4_IDX, /* Developer specific */ -+ -+ DBG_HEM_IDX, /* HEM */ -+ DBG_AIS_IDX, /* AIS */ -+ DBG_RLM_IDX, /* RLM */ -+ DBG_MEM_IDX, /* RLM */ -+ DBG_CNM_IDX, /* CNM */ -+ DBG_RSN_IDX, /* RSN */ -+ DBG_BSS_IDX, /* BSS */ -+ DBG_SCN_IDX, /* SCN */ -+ DBG_SAA_IDX, /* SAA */ -+ DBG_AAA_IDX, /* AAA */ -+ DBG_P2P_IDX, /* P2P */ -+ DBG_QM_IDX, /* QUE_MGT */ -+ DBG_SEC_IDX, /* SEC */ -+ DBG_BOW_IDX, /* BOW */ -+ DBG_WAPI_IDX, /* WAPI */ -+ DBG_ROAMING_IDX, /* ROAMING */ -+ -+ DBG_MODULE_NUM /* Notice the XLOG check */ -+} ENUM_DBG_MODULE_T; -+/* end */ -+typedef VOID(*set_dbg_level) (UINT8 modules[DBG_MODULE_NUM]); -+ -+UINT8 wlan_dbg_level[DBG_MODULE_NUM]; -+static set_dbg_level pf_set_dbg_level; -+VOID register_set_dbg_level_handler(set_dbg_level handler) -+{ -+ pf_set_dbg_level = handler; -+} -+EXPORT_SYMBOL(register_set_dbg_level_handler); -+ -+static INT32 WIFI_devs = 1; -+static INT32 WIFI_major = WIFI_DEV_MAJOR; -+module_param(WIFI_major, uint, 0); -+static struct cdev WIFI_cdev; -+volatile INT32 retflag = 0; -+static struct semaphore wr_mtx; -+ -+#define WMT_CHECK_DO_CHIP_RESET() \ -+do { \ -+ if (g_IsNeedDoChipReset) { \ -+ g_IsNeedDoChipReset = 0; \ -+ WIFI_ERR_FUNC("Do core dump and chip reset in %s line %d\n", __func__, __LINE__); \ -+ mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 40); \ -+ } \ -+} while (0) -+ -+/******************************************************************* -+ * WHOLE CHIP RESET PROCEDURE: -+ * -+ * WMTRSTMSG_RESET_START callback -+ * -> wlanRemove -+ * -> WMTRSTMSG_RESET_END callback -+ * -+ ******************************************************************* -+*/ -+/*-----------------------------------------------------------------*/ -+/* -+ * Receiving RESET_START message -+ */ -+/*-----------------------------------------------------------------*/ -+INT32 wifi_reset_start(VOID) -+{ -+ struct net_device *netdev = NULL; -+ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; -+ -+ down(&wr_mtx); -+ -+ if (powered == 1) { -+ netdev = dev_get_by_name(&init_net, ifname); -+ if (netdev == NULL) { -+ WIFI_ERR_FUNC("Fail to get %s net device\n", ifname); -+ } else { -+ p2pmode.u4Enable = 0; -+ p2pmode.u4Mode = 0; -+ -+ if (pf_set_p2p_mode) { -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) -+ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); -+ else -+ WIFI_INFO_FUNC("Turn off p2p/ap mode"); -+ } -+ dev_put(netdev); -+ netdev = NULL; -+ } -+ } else { -+ /* WIFI is off before whole chip reset, do nothing */ -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(wifi_reset_start); -+ -+/*-----------------------------------------------------------------*/ -+/* -+ * Receiving RESET_END/RESET_END_FAIL message -+ */ -+/*-----------------------------------------------------------------*/ -+INT32 wifi_reset_end(ENUM_RESET_STATUS_T status) -+{ -+ struct net_device *netdev = NULL; -+ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; -+ INT32 wait_cnt = 0; -+ INT32 ret = -1; -+ -+ if (status == RESET_FAIL) { -+ /* whole chip reset fail, donot recover WIFI */ -+ ret = 0; -+ up(&wr_mtx); -+ } else if (status == RESET_SUCCESS) { -+ WIFI_WARN_FUNC("WIFI state recovering...\n"); -+ -+ if (powered == 1) { -+ /* WIFI is on before whole chip reset, reopen it now */ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { -+ WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); -+ goto done; -+ } else { -+ WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); -+ } -+ -+ if (pf_set_p2p_mode == NULL) { -+ WIFI_ERR_FUNC("Set p2p mode handler is NULL\n"); -+ goto done; -+ } -+ -+ netdev = dev_get_by_name(&init_net, ifname); -+ while (netdev == NULL && wait_cnt < 10) { -+ WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname); -+ msleep(300); -+ wait_cnt++; -+ netdev = dev_get_by_name(&init_net, ifname); -+ } -+ if (wait_cnt >= 10) { -+ WIFI_ERR_FUNC("Get %s net device timeout\n", ifname); -+ goto done; -+ } -+ -+ if (wlan_mode == WLAN_MODE_STA_P2P) { -+ p2pmode.u4Enable = 1; -+ p2pmode.u4Mode = 0; -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Set wlan mode fail\n"); -+ } else { -+ WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_STA_P2P); -+ ret = 0; -+ } -+ } else if (wlan_mode == WLAN_MODE_AP) { -+ p2pmode.u4Enable = 1; -+ p2pmode.u4Mode = 1; -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Set wlan mode fail\n"); -+ } else { -+ WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_AP); -+ ret = 0; -+ } -+ } -+done: -+ if (netdev != NULL) -+ dev_put(netdev); -+ } else { -+ /* WIFI is off before whole chip reset, do nothing */ -+ ret = 0; -+ } -+ up(&wr_mtx); -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL(wifi_reset_end); -+ -+static int WIFI_open(struct inode *inode, struct file *file) -+{ -+ WIFI_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); -+ -+ return 0; -+} -+ -+static int WIFI_close(struct inode *inode, struct file *file) -+{ -+ WIFI_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); -+ retflag = 0; -+ -+ return 0; -+} -+ -+ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ INT32 retval = -EIO; -+ INT8 local[12] = { 0 }; -+ struct net_device *netdev = NULL; -+ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; -+ INT32 wait_cnt = 0; -+ -+ down(&wr_mtx); -+ if (count <= 0) { -+ WIFI_ERR_FUNC("WIFI_write invalid param\n"); -+ goto done; -+ } -+ -+ if (0 == copy_from_user(local, buf, (count > sizeof(local)) ? sizeof(local) : count)) { -+ local[11] = 0; -+ WIFI_INFO_FUNC("WIFI_write %s\n", local); -+ -+ if (local[0] == '0') { -+ if (powered == 0) { -+ WIFI_INFO_FUNC("WIFI is already power off!\n"); -+ retval = count; -+ wlan_mode = WLAN_MODE_HALT; -+ goto done; -+ } -+ -+ netdev = dev_get_by_name(&init_net, ifname); -+ if (netdev == NULL) { -+ WIFI_ERR_FUNC("Fail to get %s net device\n", ifname); -+ } else { -+ p2pmode.u4Enable = 0; -+ p2pmode.u4Mode = 0; -+ -+ if (pf_set_p2p_mode) { -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); -+ } else { -+ WIFI_INFO_FUNC("Turn off p2p/ap mode"); -+ wlan_mode = WLAN_MODE_HALT; -+ } -+ } -+ dev_put(netdev); -+ netdev = NULL; -+ } -+ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI)) { -+ WIFI_ERR_FUNC("WMT turn off WIFI fail!\n"); -+ WMT_CHECK_DO_CHIP_RESET(); -+ } else { -+ WIFI_INFO_FUNC("WMT turn off WIFI OK!\n"); -+ powered = 0; -+ retval = count; -+ wlan_mode = WLAN_MODE_HALT; -+#if CFG_TC1_FEATURE -+ ifname = WLAN_IFACE_NAME; -+ wlan_if_changed = 0; -+#endif -+ } -+ } else if (local[0] == '1') { -+ if (powered == 1) { -+ WIFI_INFO_FUNC("WIFI is already power on!\n"); -+ retval = count; -+ goto done; -+ } -+ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { -+ WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); -+ WMT_CHECK_DO_CHIP_RESET(); -+ } else { -+ powered = 1; -+ retval = count; -+ WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); -+ wlan_mode = WLAN_MODE_HALT; -+ } -+ } else if (local[0] == 'D') { -+ INT32 k = 0; -+ /* -+ * 0: no debug -+ * 1: common debug output -+ * 2: more detials -+ * 3: verbose -+ */ -+ switch (local[1]) { -+ case '0': -+ for (k = 0; k < DBG_MODULE_NUM; k++) -+ wlan_dbg_level[k] = 0; -+ if (pf_set_dbg_level) -+ pf_set_dbg_level(wlan_dbg_level); -+ break; -+ case '1': -+ for (k = 0; k < DBG_MODULE_NUM; k++) { -+ wlan_dbg_level[k] = DBG_CLASS_ERROR | -+ DBG_CLASS_WARN | -+ DBG_CLASS_STATE | DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO; -+ } -+ wlan_dbg_level[DBG_TX_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); -+ wlan_dbg_level[DBG_RX_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); -+ wlan_dbg_level[DBG_REQ_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); -+ wlan_dbg_level[DBG_INTR_IDX] = 0; -+ wlan_dbg_level[DBG_MEM_IDX] = 0; -+ if (pf_set_dbg_level) -+ pf_set_dbg_level(wlan_dbg_level); -+ break; -+ case '2': -+ for (k = 0; k < DBG_MODULE_NUM; k++) { -+ wlan_dbg_level[k] = DBG_CLASS_ERROR | -+ DBG_CLASS_WARN | -+ DBG_CLASS_STATE | DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO; -+ } -+ wlan_dbg_level[DBG_INTR_IDX] = 0; -+ wlan_dbg_level[DBG_MEM_IDX] = 0; -+ if (pf_set_dbg_level) -+ pf_set_dbg_level(wlan_dbg_level); -+ break; -+ case '3': -+ for (k = 0; k < DBG_MODULE_NUM; k++) { -+ wlan_dbg_level[k] = DBG_CLASS_ERROR | -+ DBG_CLASS_WARN | -+ DBG_CLASS_STATE | -+ DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO | DBG_CLASS_LOUD; -+ } -+ if (pf_set_dbg_level) -+ pf_set_dbg_level(wlan_dbg_level); -+ break; -+ default: -+ break; -+ } -+ } else if (local[0] == 'S' || local[0] == 'P' || local[0] == 'A') { -+ if (powered == 0) { -+ /* If WIFI is off, turn on WIFI first */ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { -+ WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); -+ WMT_CHECK_DO_CHIP_RESET(); -+ goto done; -+ } else { -+ powered = 1; -+ WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); -+ wlan_mode = WLAN_MODE_HALT; -+ } -+ } -+ -+ if (pf_set_p2p_mode == NULL) { -+ WIFI_ERR_FUNC("Set p2p mode handler is NULL\n"); -+ goto done; -+ } -+ -+ netdev = dev_get_by_name(&init_net, ifname); -+ while (netdev == NULL && wait_cnt < 10) { -+ WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname); -+ msleep(300); -+ wait_cnt++; -+ netdev = dev_get_by_name(&init_net, ifname); -+ } -+ if (wait_cnt >= 10) { -+ WIFI_ERR_FUNC("Get %s net device timeout\n", ifname); -+ goto done; -+ } -+ -+ if ((wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'S' || local[0] == 'P')) || -+ (wlan_mode == WLAN_MODE_AP && (local[0] == 'A'))) { -+ WIFI_INFO_FUNC("WIFI is already in mode %d!\n", wlan_mode); -+ retval = count; -+ goto done; -+ } -+ -+ if ((wlan_mode == WLAN_MODE_AP && (local[0] == 'S' || local[0] == 'P')) || -+ (wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'A'))) { -+ p2pmode.u4Enable = 0; -+ p2pmode.u4Mode = 0; -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); -+ goto done; -+ } -+ } -+ -+ if (local[0] == 'S' || local[0] == 'P') { -+#if CFG_TC1_FEATURE -+ /* Restore NIC name to wlan0 */ -+ rtnl_lock(); -+ if (strcmp(ifname, WLAN_IFACE_NAME) != 0) { -+ if (dev_change_name(netdev, WLAN_IFACE_NAME) != 0) { -+ WIFI_ERR_FUNC("netdev name change to %s fail\n", WLAN_IFACE_NAME); -+ rtnl_unlock(); -+ goto done; -+ } else { -+ WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname, -+ WLAN_IFACE_NAME); -+ ifname = WLAN_IFACE_NAME; -+ wlan_if_changed = 0; -+ } -+ } -+ rtnl_unlock(); -+#endif -+ p2pmode.u4Enable = 1; -+ p2pmode.u4Mode = 0; -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Set wlan mode fail\n"); -+ } else { -+ WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_STA_P2P); -+ wlan_mode = WLAN_MODE_STA_P2P; -+ retval = count; -+ } -+ } else if (local[0] == 'A') { -+#if CFG_TC1_FEATURE -+ /* Change NIC name to legacy0, since wlan0 is used for AP */ -+ rtnl_lock(); -+ if (strcmp(ifname, LEGACY_IFACE_NAME) != 0) { -+ if (dev_change_name(netdev, LEGACY_IFACE_NAME) != 0) { -+ WIFI_ERR_FUNC("netdev name change to %s fail\n", LEGACY_IFACE_NAME); -+ rtnl_unlock(); -+ goto done; -+ } else { -+ WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname, -+ LEGACY_IFACE_NAME); -+ ifname = LEGACY_IFACE_NAME; -+ wlan_if_changed = 1; -+ } -+ } -+ rtnl_unlock(); -+#endif -+ p2pmode.u4Enable = 1; -+ p2pmode.u4Mode = 1; -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Set wlan mode fail\n"); -+ } else { -+ WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_AP); -+ wlan_mode = WLAN_MODE_AP; -+ retval = count; -+ } -+ } -+ dev_put(netdev); -+ netdev = NULL; -+ } -+ } -+done: -+ if (netdev != NULL) -+ dev_put(netdev); -+ -+ up(&wr_mtx); -+ return retval; -+} -+ -+const struct file_operations WIFI_fops = { -+ .open = WIFI_open, -+ .release = WIFI_close, -+ .write = WIFI_write, -+}; -+ -+#if WMT_CREATE_NODE_DYNAMIC -+struct class *wmtwifi_class = NULL; -+#endif -+ -+static int WIFI_init(void) -+{ -+ dev_t dev = MKDEV(WIFI_major, 0); -+ INT32 alloc_ret = 0; -+ INT32 cdev_err = 0; -+#if WMT_CREATE_NODE_DYNAMIC -+ struct device *wmtwifi_dev = NULL; -+#endif -+ -+ /* static allocate chrdev */ -+ alloc_ret = register_chrdev_region(dev, 1, WIFI_DRIVER_NAME); -+ if (alloc_ret) { -+ WIFI_ERR_FUNC("Fail to register chrdev\n"); -+ return alloc_ret; -+ } -+ -+ cdev_init(&WIFI_cdev, &WIFI_fops); -+ WIFI_cdev.owner = THIS_MODULE; -+ -+ cdev_err = cdev_add(&WIFI_cdev, dev, WIFI_devs); -+ if (cdev_err) -+ goto error; -+ -+#if WMT_CREATE_NODE_DYNAMIC /* mknod replace */ -+ wmtwifi_class = class_create(THIS_MODULE, "wmtWifi"); -+ if (IS_ERR(wmtwifi_class)) -+ goto error; -+ wmtwifi_dev = device_create(wmtwifi_class, NULL, dev, NULL, "wmtWifi"); -+ if (wmtwifi_dev == NULL) -+ goto error; -+ if (IS_ERR(wmtwifi_dev)) -+ goto error; -+#endif -+ -+ sema_init(&wr_mtx, 1); -+ -+ WIFI_INFO_FUNC("%s driver(major %d) installed.\n", WIFI_DRIVER_NAME, WIFI_major); -+ retflag = 0; -+ wlan_mode = WLAN_MODE_HALT; -+ pf_set_p2p_mode = NULL; -+ -+ return 0; -+ -+error: -+#if WMT_CREATE_NODE_DYNAMIC -+ if (!IS_ERR(wmtwifi_dev)) -+ device_destroy(wmtwifi_class, dev); -+ if (!IS_ERR(wmtwifi_class)) { -+ class_destroy(wmtwifi_class); -+ wmtwifi_class = NULL; -+ } -+#endif -+ -+ if (cdev_err == 0) -+ cdev_del(&WIFI_cdev); -+ -+ if (alloc_ret == 0) -+ unregister_chrdev_region(dev, WIFI_devs); -+ -+ return -1; -+} -+ -+static void WIFI_exit(void) -+{ -+ dev_t dev = MKDEV(WIFI_major, 0); -+ -+ retflag = 0; -+ -+#if WMT_CREATE_NODE_DYNAMIC -+ device_destroy(wmtwifi_class, dev); -+ class_destroy(wmtwifi_class); -+ wmtwifi_class = NULL; -+#endif -+ -+ cdev_del(&WIFI_cdev); -+ unregister_chrdev_region(dev, WIFI_devs); -+ -+ WIFI_INFO_FUNC("%s driver removed.\n", WIFI_DRIVER_NAME); -+} -+ -+#ifdef MTK_WCN_REMOVE_KERNEL_MODULE -+ -+INT32 mtk_wcn_wmt_wifi_init(VOID) -+{ -+ return WIFI_init(); -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_wifi_init); -+ -+VOID mtk_wcn_wmt_wifi_exit(VOID) -+{ -+ return WIFI_exit(); -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_wifi_exit); -+ -+#else -+ -+module_init(WIFI_init); -+module_exit(WIFI_exit); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c -new file mode 100644 -index 0000000000000..641e516f603d4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c -@@ -0,0 +1,307 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+#include "osal_typedef.h" -+#include "wmt_idc.h" -+#include "wmt_lib.h" -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ -+MTK_WCN_WMT_IDC_INFO gWmtIdcInfo; -+ -+INT32 wmt_idc_init(VOID) -+{ -+ INT32 iRet; -+ -+ osal_memset(&gWmtIdcInfo, 0, osal_sizeof(gWmtIdcInfo)); -+ gWmtIdcInfo.iit.src_mod_id = AP_MOD_WMT; -+ gWmtIdcInfo.iit.dest_mod_id = MD_MOD_EL1; -+ gWmtIdcInfo.iit.sap_id = 0; -+ gWmtIdcInfo.ops.rx_cb = wmt_idc_msg_from_lte_handing; -+ -+ iRet = mtk_conn_md_bridge_reg(gWmtIdcInfo.iit.src_mod_id, &gWmtIdcInfo.ops); -+ if (iRet) { -+ WMT_ERR_FUNC("mtk_conn_md_bridge_reg fail(%d)\n", iRet); -+ return -1; -+ } -+ /* mtk_wcn_stp_flush_rx_queue(COEX_TASK_INDX); */ -+ return 0; -+ -+} -+ -+INT32 wmt_idc_deinit(VOID) -+{ -+ INT32 iRet; -+ -+ iRet = mtk_conn_md_bridge_unreg(gWmtIdcInfo.iit.src_mod_id); -+ if (iRet) -+ WMT_ERR_FUNC("mtk_conn_md_bridge_unreg fail(%d)\n", iRet); -+ -+ osal_memset(&gWmtIdcInfo, 0, osal_sizeof(gWmtIdcInfo)); -+ -+ return 0; -+} -+ -+INT32 wmt_idc_msg_from_lte_handing(ipc_ilm_t *ilm) -+{ -+ MTK_WCN_BOOL bRet; -+ -+ if (NULL == ilm) { -+ WMT_ERR_FUNC("NULL pointer\n"); -+ return -1; -+ } -+ if (mtk_wcn_stp_is_ready()) { -+ bRet = wmt_lib_handle_idc_msg(ilm); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_ERR_FUNC("wmt handing idc msg fail\n"); -+ return -2; -+ } -+ } else { -+ WMT_INFO_FUNC("Received LTE msg,but STP is not ready,drop it!\n"); -+ } -+ return 0; -+} -+ -+VOID wmt_idc_dump_debug_msg(UINT8 *str, UINT8 *p_buf, UINT32 buf_len) -+{ -+ UINT32 idx = 0; -+ -+ WMT_DBG_FUNC("%s:, length:%d\n", str, buf_len); -+ -+ WMT_DBG_FUNC("ASCII output:\n"); -+ -+ for (idx = 0; idx < buf_len;) { -+ WMT_DBG_FUNC("%c", p_buf[idx]); -+ idx++; -+ if (0 == idx % 16) -+ WMT_DBG_FUNC("\n"); -+ } -+ -+ WMT_DBG_FUNC("HEX output:\n"); -+ -+ for (idx = 0; idx < buf_len;) { -+ WMT_DBG_FUNC("%02x ", p_buf[idx]); -+ idx++; -+ if (0 == idx % 16) -+ WMT_DBG_FUNC("\n"); -+ } -+} -+ -+INT32 wmt_idc_msg_to_lte_handing(VOID) -+{ -+ UINT32 readlen = 0; -+ local_para_struct *p_lps = NULL; -+ UINT8 *p_data = NULL; -+ UINT8 opcode = 0; -+ UINT16 msg_len = 0; -+ UINT32 handle_len = 0; -+#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING -+ MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; -+#endif -+ readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], LTE_IDC_BUFFER_MAX_SIZE, COEX_TASK_INDX); -+ if (readlen == 0) { -+ osal_sleep_ms(5); -+ readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], LTE_IDC_BUFFER_MAX_SIZE, COEX_TASK_INDX); -+ } -+ -+ if (readlen > 0) { -+ WMT_DBG_FUNC("read data len from fw(%d)\n", readlen); -+ wmt_idc_dump_debug_msg("WMT->LTE from STP buffer", &gWmtIdcInfo.buffer[0], readlen); -+ p_data = &gWmtIdcInfo.buffer[0]; -+ -+ while (handle_len < readlen) { -+ p_data += 2; /*omit direction & opcode 2 bytes */ -+ osal_memcpy(&msg_len, p_data, 2); -+ msg_len -= 1; /*flag byte */ -+ WMT_DBG_FUNC("current raw data len(%d) from connsys firmware\n", msg_len); -+ -+ p_data += 2; /*length: 2 bytes */ -+ -+ /*how to handle flag(msg type) need to Scott comment */ -+ /************************************************/ -+ -+ if (*p_data == WMT_IDC_RX_OPCODE_DEBUG_MONITOR) -+ /*do not need transfer to LTE */ -+ { -+ p_data += 1; /*flag : 1 byte */ -+ /*need to handle these debug message */ -+ wmt_idc_dump_debug_msg("WIFI DEBUG MONITOR", p_data, msg_len); -+ } else -+ /*need to transfer to LTE */ -+ { -+ p_lps = -+ (local_para_struct *) osal_malloc(osal_sizeof(local_para_struct) + -+ osal_sizeof(UINT8) * msg_len); -+ if (NULL == p_lps) { -+ WMT_ERR_FUNC("allocate local_para_struct memory fail\n"); -+ return -1; -+ } -+ -+ p_lps->msg_len = msg_len + osal_sizeof(local_para_struct); -+ -+ opcode = *p_data; -+ WMT_DBG_FUNC("current opcode(%d) to LTE\n", opcode); -+ -+ p_data += 1; /*flag : 1 byte */ -+ osal_memcpy(p_lps->data, p_data, msg_len); -+ -+ gWmtIdcInfo.iit.local_para_ptr = p_lps; -+ -+#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING -+ switch (opcode) { -+ case WMT_IDC_RX_OPCODE_BTWF_DEF_PARA: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND; -+ break; -+ case WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; -+ break; -+ case WMT_IDC_RX_OPCODE_LTE_FREQ_IDX_TABLE: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_FREQ_IDX_TABLE_IND; -+ break; -+ case WMT_IDC_RX_OPCODE_BTWF_PROFILE_IND: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_PROFILE_IND; -+ break; -+ case WMT_IDC_RX_OPCODE_UART_PIN_SEL: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_PIN_TYPE_IND; -+ break; -+ /* case WMT_IDC_RX_OPCODE_TDM_REQ: */ -+ /* gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; */ -+ /* break; */ -+ default: -+ unknown_msgid = MTK_WCN_BOOL_TRUE; -+ WMT_ERR_FUNC("unknown opcode(%d) from connsys firmware\n", opcode); -+ break; -+ } -+ if (MTK_WCN_BOOL_FALSE == unknown_msgid) { -+ /*handling flag value in wmt cmd */ -+ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); -+ } -+#else -+ if (opcode >= LTE_MSG_ID_OFFSET) { -+ gWmtIdcInfo.iit.msg_id = opcode + IPC_EL1_MSG_ID_BEGIN - LTE_MSG_ID_OFFSET + 1; -+ /*handling flag value in wmt cmd */ -+ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); -+ WMT_DBG_FUNC("CONN->LTE: (0x%x->0x%x)\n", opcode, gWmtIdcInfo.iit.msg_id); -+ } else { -+ WMT_ERR_FUNC("opcode(%d)from connsys fw is out of range,drop it!\n", opcode); -+ } -+#endif -+ osal_free(p_lps); -+ } -+ -+ p_data += msg_len; /*point to next package header */ -+ -+ handle_len += (msg_len + 5); -+ } -+ -+ } else { -+ WMT_ERR_FUNC("there is no coex data in stp buffer\n"); -+ } -+ -+ osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); -+ -+ return 0; -+} -+ -+UINT32 wmt_idc_msg_to_lte_handing_for_test(UINT8 *p_buf, UINT32 len) -+{ -+ UINT32 readlen = len; -+ local_para_struct *p_lps = NULL; -+ UINT8 *p_data = NULL; -+ UINT8 opcode = 0; -+ UINT16 msg_len = 0; -+ UINT32 handle_len = 0; -+ MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; -+ -+ osal_memcpy(&gWmtIdcInfo.buffer[0], p_buf, len); -+ -+ if (readlen > 0) { -+ WMT_DBG_FUNC("read data len from fw(%d)\n", readlen); -+ p_data = &gWmtIdcInfo.buffer[0]; -+ -+ while (handle_len < readlen) { -+ p_data += 2; /*omit direction & opcode 2 bytes */ -+ osal_memcpy(&msg_len, p_data, 2); -+ msg_len -= 1; /*flag byte */ -+ WMT_DBG_FUNC("current raw data len(%d) from connsys firmware\n", msg_len); -+ -+ p_data += 2; /*length: 2 bytes */ -+ -+ /*how to handle flag(msg type) need to Scott comment */ -+ /************************************************/ -+ -+ if (*p_data == WMT_IDC_RX_OPCODE_DEBUG_MONITOR) -+ /*do not need transfer to LTE */ -+ { -+ p_data += 1; /*flag : 1 byte */ -+ /*need to handle these debug message */ -+ wmt_idc_dump_debug_msg("WIFI DEBUG MONITOR", p_data, msg_len); -+ } else -+ /*need to transfer to LTE */ -+ { -+ p_lps = -+ (local_para_struct *) osal_malloc(osal_sizeof(local_para_struct) + -+ osal_sizeof(UINT8) * msg_len); -+ if (NULL == p_lps) { -+ WMT_ERR_FUNC("allocate local_para_struct memory fail\n"); -+ return -1; -+ } -+ -+ p_lps->msg_len = msg_len + osal_sizeof(local_para_struct); -+ -+ opcode = *p_data; -+ WMT_DBG_FUNC("current opcode(%d) to LTE\n", opcode); -+ -+ p_data += 1; /*flag : 1 byte */ -+ osal_memcpy(p_lps->data, p_data, msg_len); -+ -+ gWmtIdcInfo.iit.local_para_ptr = p_lps; -+ -+ switch (opcode) { -+ case WMT_IDC_RX_OPCODE_BTWF_DEF_PARA: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND; -+ break; -+ case WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; -+ break; -+ /* case WMT_IDC_RX_OPCODE_TDM_REQ: */ -+ /* gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; */ -+ /* break; */ -+ default: -+ unknown_msgid = MTK_WCN_BOOL_TRUE; -+ WMT_ERR_FUNC("unknown opcode(%d) from connsys firmware\n", opcode); -+ break; -+ } -+ if (MTK_WCN_BOOL_FALSE == unknown_msgid) { -+ /*handling flag value in wmt cmd */ -+ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); -+ } -+ osal_free(p_lps); -+ } -+ -+ p_data += msg_len; /*point to next package header */ -+ -+ handle_len += (msg_len + 5); -+ } -+ -+ } else { -+ WMT_ERR_FUNC("there is no coex data in stp buffer\n"); -+ } -+ -+ osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); -+ -+ return handle_len; -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile -new file mode 100644 -index 0000000000000..c201e8291b8ef ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile -@@ -0,0 +1,25 @@ -+# WMT HAL driver for MT7623 -+ -+ccflags-y += \ -+ -I$(src)/include \ -+ -I$(src)/../linux/include \ -+ -I$(src)/../include \ -+ -I$(src)/../../common_detect -+ -+ ifeq ($(CONFIG_MTK_CLKMGR),y) -+ ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach -+ endif -+ #ifeq ($(CONFIG_MTK_EMI_MPU),y) -+ ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach -+ #endif -+ -+subdir-ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ -+ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y) -+ subdir-ccflags-y += -DWMT_IDC_SUPPORT=1 -+else -+ subdir-ccflags-y += -DWMT_IDC_SUPPORT=0 -+endif -+ -+obj-y += mtk_wcn_consys_hw.o -+obj-y += wmt_plat_alps.o -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h -new file mode 100644 -index 0000000000000..94d6af9d0b3ea ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h -@@ -0,0 +1,287 @@ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _MTK_WCN_CONSYS_HW_H_ -+#define _MTK_WCN_CONSYS_HW_H_ -+ -+#include -+/*#include */ -+#include "wmt_plat.h" -+ -+/*device tree mode*/ -+#ifdef CONFIG_OF -+/* #if 1 */ -+#include -+#include -+#include -+#include -+#endif -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#define CONSYS_BT_WIFI_SHARE_V33 0 -+#define CONSYS_PMIC_CTRL_ENABLE 1 -+#define CONSYS_PMIC_CTRL_UPMU 1 -+#define CONSYS_EMI_MPU_SETTING 0 -+#define CONSYS_AHB_CLK_MAGEMENT 1 -+#define CONSYS_USE_PLATFORM_WRITE 1 -+#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1 -+#define CONSYS_CLOCK_BUF_CTRL 0 -+#if defined(CONFIG_MTK_LEGACY) -+#define CONFIG_MTK_PMIC_LEGACY 0 -+#endif -+#define CONFIG_RESET_CONTROL 1 -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/*tag start:new platform need to make sure these define */ -+#define PLATFORM_SOC_CHIP 0x7623 -+/*tag end*/ -+ -+#ifdef CONFIG_OF -+ -+struct CONSYS_BASE_ADDRESS { -+ SIZE_T mcu_base; -+ SIZE_T ap_rgu_base; -+ SIZE_T topckgen_base; -+ SIZE_T spm_base; -+}; -+ -+/*TOPCKGEN_BASE*/ -+#define CONSYS_TOP_CLKCG_CLR_OFFSET 0x00000084 -+#define CONSYS_TOP_CLKCG_SET_OFFSET 0x00000054 -+#define CONSYS_WD_SYS_RST_OFFSET 0x00000018 -+#define CONSYS_AP2CONN_OSC_EN_OFFSET 0x00000800 -+#define CONSYS_EMI_MAPPING_OFFSET 0x00000310 -+/*AP_RGU_BASE*/ -+#define CONSYS_CPU_SW_RST_OFFSET 0x00000018 -+/*SPM_BASE*/ -+#define CONSYS_PWRON_CONFG_EN_OFFSET 0x00000000 -+#define CONSYS_TOP1_PWR_CTRL_OFFSET 0x00000280 -+#define CONSYS_PWR_CONN_ACK_OFFSET 0x0000060c -+#define CONSYS_PWR_CONN_ACK_S_OFFSET 0x00000610 -+/*CONN_MCU_CONFIG_BASE*/ -+#define CONSYS_CHIP_ID_OFFSET 0x00000008 -+#define CONSYS_ROM_RAM_DELSEL_OFFSET 0x00000114 -+#define CONSYS_MCU_CFG_ACR_OFFSET 0x00000110 -+#define CONSYS_CPUPCR_OFFSET 0x00000160 -+/*AXI bus*/ -+ -+#define CONSYS_TOPAXI_PROT_EN_OFFSET 0x1220 -+#define CONSYS_TOPAXI_PROT_STA1_OFFSET 0x0228 -+#endif -+ -+#define CONSYS_SET_BIT(REG, BITVAL) (*((volatile UINT32*)(REG)) |= ((UINT32)(BITVAL))) -+#define CONSYS_CLR_BIT(REG, BITVAL) ((*(volatile UINT32*)(REG)) &= ~((UINT32)(BITVAL))) -+#define CONSYS_CLR_BIT_WITH_KEY(REG, BITVAL, KEY) {\ -+ UINT32 val = (*(volatile UINT32*)(REG)); \ -+ val &= ~((UINT32)(BITVAL)); \ -+ val |= ((UINT32)(KEY)); \ -+ (*(volatile UINT32*)(REG)) = val;\ -+} -+#define CONSYS_REG_READ(addr) (*((volatile UINT32*)(addr))) -+#if CONSYS_USE_PLATFORM_WRITE -+#define CONSYS_REG_WRITE(addr, data) mt_reg_sync_writel(data, addr) -+#else -+#define CONSYS_REG_WRITE(addr, data) (*((volatile UINT32*)(addr)) = (UINT32)(data)) -+#endif -+ -+/*tag start: connsys register base address (hard code, no use) */ -+#define AP_RGU_BASE 0xF0007000 -+#define TOPCKGEN_BASE 0xF0000000 -+#define SPM_BASE 0xF0006000 -+#define CONN_MCU_CONFIG_BASE 0xF8070000 -+/*GIC Interrupt ID*/ -+#define MT_CONN2AP_BTIF_WAKEUP_IRQ_ID 237 -+/*tag end*/ -+ -+/*connsys register offset define(hard code mode)*/ -+#if 1 -+ /*top clock gating control register */ -+#define CONSYS_TOP_CLKCG_CLR_REG (TOPCKGEN_BASE + 0x00000084) -+#define CONSYS_TOP_CLKCG_SET_REG (TOPCKGEN_BASE + 0x00000054) -+#define CONSYS_TOP_CLKCG_BIT (0x1 << 26) -+ -+ /*SPM clock gating control register */ -+#define CONSYS_PWRON_CONFG_EN_REG (SPM_BASE + 0x00000000) -+#define CONSYS_PWRON_CONFG_EN_VALUE (0x0b160001) -+#define CONSYS_PWRON_CONFG_DIS_VALUE (0x0b160000) -+#endif -+ -+#define CONSYS_CPU_SW_RST_REG (AP_RGU_BASE + 0x00000018) -+#define CONSYS_TOP1_PWR_CTRL_REG (SPM_BASE + 0x00000280) -+#define CONSYS_PWR_CONN_ACK_REG (SPM_BASE + 0x0000060c) -+#define CONSYS_PWR_CONN_ACK_S_REG (SPM_BASE + 0x00000610) -+ -+#define CONSYS_WD_SYS_RST_REG (TOPCKGEN_BASE + 0x00000018) -+#define CONSYS_CHIP_ID_REG (CONN_MCU_CONFIG_BASE + 0x00000008) -+#define CONSYS_ROM_RAM_DELSEL_REG (CONN_MCU_CONFIG_BASE + 0x00000114) -+#define CONSYS_MCU_CFG_ACR_REG (CONN_MCU_CONFIG_BASE + 0x00000110) -+#define CONSYS_AFE_REG (CONN_TOP_CR_BASE + 0x00002000) -+#define CONSYS_AFE_REG_DIG_RCK_01 (CONSYS_AFE_REG + 0x00000010) -+#define CONSYS_AFE_REG_WBG_PLL_02 (CONSYS_AFE_REG + 0x00000028) -+#define CONSYS_AFE_REG_WBG_WB_TX_01 (CONSYS_AFE_REG + 0x0000003c) -+#define CONSYS_AFE_REG_DIG_RCK_01_VALUE (0x174b0160) -+#define CONSYS_AFE_REG_WBG_PLL_02_VALUE (0x844083fe) -+#define CONSYS_AFE_REG_WBG_WB_TX_01_VALUE (0x7fc39a20) -+ -+#define CONSYS_TOPAXI_PROT_EN (TOPCKGEN_BASE + 0x0220) -+#define CONSYS_TOPAXI_PROT_STA1 (TOPCKGEN_BASE + 0x0228) -+#define CONSYS_PROT_MASK ((0x1<<13) | (0x1<<14) | (0x1<<15)) /* bit 13, 14, 15 */ -+/*CONSYS_CPU_SW_RST_REG*/ -+#define CONSYS_CPU_SW_RST_BIT (0x1 << 12) -+#define CONSYS_CPU_SW_RST_CTRL_KEY (0x88 << 24) -+ -+/*CONSYS_TOP1_PWR_CTRL_REG*/ -+#define CONSYS_SPM_PWR_RST_BIT (0x1 << 0) -+#define CONSYS_SPM_PWR_ISO_S_BIT (0x1 << 1) -+#define CONSYS_SPM_PWR_ON_BIT (0x1 << 2) -+#define CONSYS_SPM_PWR_ON_S_BIT (0x1 << 3) -+#define CONSYS_CLK_CTRL_BIT (0x1 << 4) -+#define CONSYS_SRAM_CONN_PD_BIT (0x1 << 8) -+ -+/*CONSYS_PWR_CONN_ACK_REG*/ -+#define CONSYS_PWR_ON_ACK_BIT (0x1 << 1) -+ -+/*CONSYS_PWR_CONN_ACK_S_REG*/ -+#define CONSYS_PWR_CONN_ACK_S_BIT (0x1 << 1) -+ -+/*CONSYS_WD_SYS_RST_REG*/ -+#define CONSYS_WD_SYS_RST_CTRL_KEY (0x88 << 24) -+#define CONSYS_WD_SYS_RST_BIT (0x1 << 9) -+ -+/*CONSYS_MCU_CFG_ACR_REG*/ -+#define CONSYS_MCU_CFG_ACR_MBIST_BIT (0x1 << 18) -+ -+/* EMI part mapping & ctrl*/ -+#define KBYTE (1024*sizeof(char)) -+#define CONSYS_EMI_AP_PHY_OFFSET (0x80000) -+#define CONSYS_EMI_AP_PHY_BASE (0x80080000) -+#define CONSYS_EMI_FW_PHY_BASE (0xf0080000) -+#define CONSYS_EMI_MEM_SIZE (343*KBYTE) /*coredump space , 343K is enough */ -+#define CONSYS_EMI_PAGED_TRACE_OFFSET (0x400) -+#define CONSYS_EMI_PAGED_DUMP_OFFSET (0x8400) -+#define CONSYS_EMI_FULL_DUMP_OFFSET (0x10400) -+ -+/*cpupcr*/ -+#define CONSYS_CPUPCR_REG (CONN_MCU_CONFIG_BASE + 0x00000160) -+/*emi mapping*/ -+#define CONSYS_EMI_MAPPING (TOPCKGEN_BASE + 0x1310) -+ -+/*control app2cnn_osc_en*/ -+#define CONSYS_AP2CONN_OSC_EN_REG (TOPCKGEN_BASE + 0x00001800) -+#define CONSYS_AP2CONN_OSC_EN_BIT (0x1 << 16) -+#define CONSYS_AP2CONN_WAKEUP_BIT (0x1 << 17) -+ -+/*paged dump address start*/ -+#define CONSYS_PAGED_DUMP_START_ADDR (0xf0088400) -+#define CONSYS_PAGED_DUMP_SIZE (32*KBYTE) -+ -+/*full dump address start*/ -+#define CONSYS_FULL_DUMP_START_ADDR (0xf0090400) -+#define CONSYS_FULL_DUMP_DLM_LEN (0x1f000) -+#define CONSYS_FULL_DUMP_SYSB2_START (CONSYS_FULL_DUMP_START_ADDR + CONSYS_FULL_DUMP_DLM_LEN) -+#define CONSYS_FULL_DUMP_SYSB2_LEN (0x6800) -+#define CONSYS_FULL_DUMP_SYSB3_START (CONSYS_FULL_DUMP_SYSB2_START + CONSYS_FULL_DUMP_SYSB2_LEN) -+#define CONSYS_FULL_DUMP_SYSB3_LEN (0x16800) -+ -+/*force fw assert pattern*/ -+#define EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1 (0x19b30bb1) -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _ENUM_EMI_CTRL_STATE_OFFSET_ { -+ EXP_APMEM_CTRL_STATE = 0x0, -+ EXP_APMEM_CTRL_HOST_SYNC_STATE = 0x4, -+ EXP_APMEM_CTRL_HOST_SYNC_NUM = 0x8, -+ EXP_APMEM_CTRL_CHIP_SYNC_STATE = 0xc, -+ EXP_APMEM_CTRL_CHIP_SYNC_NUM = 0x10, -+ EXP_APMEM_CTRL_CHIP_SYNC_ADDR = 0x14, -+ EXP_APMEM_CTRL_CHIP_SYNC_LEN = 0x18, -+ EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START = 0x1c, -+ EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN = 0x20, -+ EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX = 0x24, -+ EXP_APMEM_CTRL_CHIP_INT_STATUS = 0x28, -+ EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END = 0x2c, -+ EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1 = 0x30, -+ EXP_APMEM_CTRL_CHIP_DYNAMIC_DUMP = 0x48, -+ EXP_APMEM_CTRL_MAX -+} ENUM_EMI_CTRL_STATE_OFFSET, *P_ENUM_EMI_CTRL_STATE_OFFSET; -+ -+#if CONSYS_BT_WIFI_SHARE_V33 -+typedef struct _BT_WIFI_V33_STATUS_ { -+ UINT32 counter; -+ UINT32 flags; -+ spinlock_t lock; -+} BT_WIFI_V33_STATUS; -+ -+#endif -+ -+typedef enum _CONSYS_GPS_CO_CLOCK_TYPE_ { -+ GPS_TCXO_TYPE = 0, -+ GPS_CO_TSX_TYPE = 1, -+ GPS_CO_DCXO_TYPE = 2, -+ GPS_CO_VCTCXO_TYPE = 3, -+ GPS_CO_CLOCK_TYPE_MAX -+} CONSYS_GPS_CO_CLOCK_TYPE, *P_CONSYS_GPS_CO_CLOCK_TYPE; -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern struct CONSYS_BASE_ADDRESS conn_reg; -+#if CONSYS_BT_WIFI_SHARE_V33 -+extern BT_WIFI_V33_STATUS gBtWifiV33; -+#endif -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+extern INT32 mtk_wcn_consys_hw_init(VOID); -+extern INT32 mtk_wcn_consys_hw_deinit(VOID); -+extern INT32 mtk_wcn_consys_hw_pwr_off(VOID); -+extern INT32 mtk_wcn_consys_hw_pwr_on(UINT32 co_clock_type); -+extern INT32 mtk_wcn_consys_hw_rst(UINT32 co_clock_type); -+extern INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable); -+extern INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable); -+extern INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable); -+extern INT32 mtk_wcn_consys_hw_state_show(VOID); -+extern UINT8 *mtk_wcn_consys_emi_virt_addr_get(UINT32 ctrl_state_offset); -+#if CONSYS_ENALBE_SET_JTAG -+extern UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en); -+#endif -+extern UINT32 mtk_wcn_consys_soc_chipid(VOID); -+#if !defined(CONFIG_MTK_GPIO_LEGACY) -+extern struct pinctrl *mtk_wcn_consys_get_pinctrl(VOID); -+#endif -+extern INT32 mtk_wcn_consys_set_dynamic_dump(PUINT32 buf); -+#endif /* _MTK_WCN_CMB_HW_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c -new file mode 100644 -index 0000000000000..53b69a7b3e872 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c -@@ -0,0 +1,738 @@ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-CONSYS-HW]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#include "osal_typedef.h" -+#include "mtk_wcn_consys_hw.h" -+#include -+#include -+#include -+#if CONSYS_EMI_MPU_SETTING -+#include -+#endif -+ -+#include -+#include -+#ifdef CONFIG_MTK_HIBERNATION -+#include -+#endif -+ -+#include -+ -+#if CONSYS_CLOCK_BUF_CTRL -+#include -+#endif -+ -+#include -+#include -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static INT32 mtk_wmt_probe(struct platform_device *pdev); -+static INT32 mtk_wmt_remove(struct platform_device *pdev); -+ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+struct CONSYS_BASE_ADDRESS conn_reg; -+static phys_addr_t gConEmiPhyBase; -+static UINT8 __iomem *pEmibaseaddr; -+static struct clk *clk_infra_conn_main; /*ctrl infra_connmcu_bus clk */ -+static struct platform_device *my_pdev; -+static struct reset_control *rstc; -+static struct regulator *reg_VCN18; -+static struct regulator *reg_VCN28; -+static struct regulator *reg_VCN33_BT; -+static struct regulator *reg_VCN33_WIFI; -+static struct pinctrl *consys_pinctrl; -+static struct pinctrl *mt6625_spi_pinctrl; -+static struct pinctrl_state *mt6625_spi_default; -+static struct regmap *pmic_regmap; -+#define DYNAMIC_DUMP_GROUP_NUM 5 -+ -+static const struct of_device_id apwmt_of_ids[] = { -+ {.compatible = "mediatek,mt7623-consys",} -+}; -+MODULE_DEVICE_TABLE(of, apwmt_of_ids); -+ -+static struct platform_driver mtk_wmt_dev_drv = { -+ .probe = mtk_wmt_probe, -+ .remove = mtk_wmt_remove, -+ .driver = { -+ .name = "mt7623consys", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(apwmt_of_ids), -+ }, -+}; -+ -+static INT32 mtk_wmt_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ struct device_node *node = NULL; -+ -+ pm_runtime_enable(&pdev->dev); -+ my_pdev = pdev; -+ mt6625_spi_pinctrl = devm_pinctrl_get(&pdev->dev); -+ if (IS_ERR(mt6625_spi_pinctrl)) { -+ ret = PTR_ERR(mt6625_spi_pinctrl); -+ WMT_PLAT_ERR_FUNC("Wmt cannot find pinctrl!\n"); -+ goto set_pin_exit; -+ } -+ mt6625_spi_default = pinctrl_lookup_state(mt6625_spi_pinctrl, "consys_pins_default"); -+ if (IS_ERR(mt6625_spi_default)) { -+ ret = PTR_ERR(mt6625_spi_default); -+ WMT_PLAT_ERR_FUNC("Wmt Cannot find pinctrl default!\n"); -+ goto set_pin_exit; -+ } -+ pinctrl_select_state(mt6625_spi_pinctrl, mt6625_spi_default); -+set_pin_exit: -+ -+ node = of_parse_phandle(pdev->dev.of_node, "mediatek,pwrap-regmap", 0); -+ if (node) { -+ pmic_regmap = pwrap_node_to_regmap(node); -+ if (IS_ERR(pmic_regmap)) -+ goto set_pmic_wrap_exit; -+ } else { -+ WMT_PLAT_ERR_FUNC("Pwrap node has not register regmap.\n"); -+ goto set_pmic_wrap_exit; -+ } -+set_pmic_wrap_exit: -+ -+ clk_infra_conn_main = devm_clk_get(&pdev->dev, "consysbus"); -+ if (IS_ERR(clk_infra_conn_main)) { -+ WMT_PLAT_ERR_FUNC("sean debug [CCF]cannot get clk_infra_conn_main clock.\n"); -+ return PTR_ERR(clk_infra_conn_main); -+ } -+ WMT_PLAT_DBG_FUNC("[CCF]clk_infra_conn_main=%p\n", clk_infra_conn_main); -+ -+ reg_VCN18 = devm_regulator_get(&pdev->dev, "vcn18"); -+ if (IS_ERR(reg_VCN18)) { -+ ret = PTR_ERR(reg_VCN18); -+ WMT_PLAT_ERR_FUNC("Regulator_get VCN_1V8 fail, ret=%d\n", ret); -+ } -+ reg_VCN28 = devm_regulator_get(&pdev->dev, "vcn28"); -+ if (IS_ERR(reg_VCN28)) { -+ ret = PTR_ERR(reg_VCN28); -+ WMT_PLAT_ERR_FUNC("Regulator_get VCN_2V8 fail, ret=%d\n", ret); -+ } -+ reg_VCN33_BT = devm_regulator_get(&pdev->dev, "vcn33_bt"); -+ if (IS_ERR(reg_VCN33_BT)) { -+ ret = PTR_ERR(reg_VCN33_BT); -+ WMT_PLAT_ERR_FUNC("Regulator_get VCN33_BT fail, ret=%d\n", ret); -+ } -+ reg_VCN33_WIFI = devm_regulator_get(&pdev->dev, "vcn33_wifi"); -+ if (IS_ERR(reg_VCN33_WIFI)) { -+ ret = PTR_ERR(reg_VCN33_WIFI); -+ WMT_PLAT_ERR_FUNC("Regulator_get VCN33_WIFI fail, ret=%d\n", ret); -+ } -+ -+ rstc = devm_reset_control_get(&pdev->dev, "connsys"); -+ if (IS_ERR(rstc)) { -+ ret = PTR_ERR(rstc); -+ WMT_PLAT_ERR_FUNC("CanNot get consys reset. ret=%d\n", ret); -+ return PTR_ERR(rstc); -+ } -+ -+ consys_pinctrl = devm_pinctrl_get(&pdev->dev); -+ if (IS_ERR(consys_pinctrl)) { -+ ret = PTR_ERR(consys_pinctrl); -+ WMT_PLAT_ERR_FUNC("CanNot find consys pinctrl. ret=%d\n", ret); -+ return PTR_ERR(consys_pinctrl); -+ } -+ return 0; -+} -+ -+static INT32 mtk_wmt_remove(struct platform_device *pdev) -+{ -+ pm_runtime_disable(&pdev->dev); -+ -+ return 0; -+} -+ -+VOID mtk_wcn_consys_power_on(VOID) -+{ -+ INT32 iRet = -1; -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ iRet = pm_runtime_get_sync(&my_pdev->dev); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ if (iRet) -+ WMT_PLAT_ERR_FUNC("pm_runtime_get_sync() fail(%d)\n", iRet); -+ else -+ WMT_PLAT_INFO_FUNC("pm_runtime_get_sync() CONSYS ok\n"); -+ -+ iRet = device_init_wakeup(&my_pdev->dev, true); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ if (iRet) -+ WMT_PLAT_ERR_FUNC("device_init_wakeup(true) fail.\n"); -+ else -+ WMT_PLAT_INFO_FUNC("device_init_wakeup(true) CONSYS ok\n"); -+} -+ -+VOID mtk_wcn_consys_power_off(VOID) -+{ -+ INT32 iRet = -1; -+ -+ iRet = pm_runtime_put_sync(&my_pdev->dev); -+ if (iRet) -+ WMT_PLAT_ERR_FUNC("pm_runtime_put_sync() fail.\n"); -+ else -+ WMT_PLAT_INFO_FUNC("pm_runtime_put_sync() CONSYS ok\n"); -+ -+ iRet = device_init_wakeup(&my_pdev->dev, false); -+ if (iRet) -+ WMT_PLAT_ERR_FUNC("device_init_wakeup(false) fail.\n"); -+ else -+ WMT_PLAT_INFO_FUNC("device_init_wakeup(false) CONSYS ok\n"); -+} -+ -+INT32 mtk_wcn_consys_hw_reg_ctrl(UINT32 on, UINT32 co_clock_type) -+{ -+ UINT32 retry = 10; -+ UINT32 consysHwChipId = 0; -+ -+ WMT_PLAT_DBG_FUNC("CONSYS-HW-REG-CTRL(0x%08x),start\n", on); -+ if (on) { -+ WMT_PLAT_DBG_FUNC("++\n"); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ /*need PMIC driver provide new API protocol */ -+ /*1.AP power on VCN_1V8 LDO (with PMIC_WRAP API) VCN_1V8 */ -+ regulator_set_mode(reg_VCN18, REGULATOR_MODE_STANDBY); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ /* VOL_DEFAULT, VOL_1200, VOL_1300, VOL_1500, VOL_1800... */ -+ if (reg_VCN18) { -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ regulator_set_voltage(reg_VCN18, 1800000, 1800000); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ if (regulator_enable(reg_VCN18)) -+ WMT_PLAT_ERR_FUNC("enable VCN18 fail\n"); -+ else -+ WMT_PLAT_DBG_FUNC("enable VCN18 ok\n"); -+ } -+ udelay(150); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ if (co_clock_type) { -+ /*step0,clk buf ctrl */ -+ WMT_PLAT_INFO_FUNC("co clock type(%d),turn on clk buf\n", co_clock_type); -+#if CONSYS_CLOCK_BUF_CTRL -+ clk_buf_ctrl(CLK_BUF_CONN, 1); -+#endif -+ /*if co-clock mode: */ -+ /*2.set VCN28 to SW control mode (with PMIC_WRAP API) */ -+ /*turn on VCN28 LDO only when FMSYS is activated" */ -+ regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x0 << 14);/*V28*/ -+ } else { -+ /*if NOT co-clock: */ -+ /*2.1.switch VCN28 to HW control mode (with PMIC_WRAP API) */ -+ regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x1 << 14);/*V28*/ -+ /*2.2.turn on VCN28 LDO (with PMIC_WRAP API)" */ -+ /*fix vcn28 not balance warning */ -+ if (reg_VCN28) { -+ regulator_set_voltage(reg_VCN28, 2800000, 2800000); -+ if (regulator_enable(reg_VCN28)) -+ WMT_PLAT_ERR_FUNC("enable VCN_2V8 fail!\n"); -+ else -+ WMT_PLAT_DBG_FUNC("enable VCN_2V8 ok\n"); -+ } -+ } -+ -+ /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ reset_control_reset(rstc); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ mtk_wcn_consys_power_on(); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ /*11.26M is ready now, delay 10us for mem_pd de-assert */ -+ udelay(10); -+ /*enable AP bus clock : connmcu_bus_pd API: enable_clock() ++?? */ -+ clk_prepare_enable(clk_infra_conn_main); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ WMT_PLAT_DBG_FUNC("[CCF]enable clk_infra_conn_main\n"); -+ /*12.poll CONNSYS CHIP ID until chipid is returned 0x18070008 */ -+ while (retry-- > 0) { -+ consysHwChipId = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CHIP_ID_OFFSET) - 0xf6d; -+ -+ if ((consysHwChipId == 0x0321) || (consysHwChipId == 0x0335) || (consysHwChipId == 0x0337)) { -+ WMT_PLAT_INFO_FUNC("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); -+ break; -+ } -+ if ((consysHwChipId == 0x8163) || (consysHwChipId == 0x8127) || (consysHwChipId == 0x7623)) { -+ WMT_PLAT_INFO_FUNC("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); -+ break; -+ } -+ -+ WMT_PLAT_ERR_FUNC("Read CONSYS chipId(0x%08x)", consysHwChipId); -+ msleep(20); -+ } -+ -+ if ((0 == retry) || (0 == consysHwChipId)) -+ WMT_PLAT_ERR_FUNC("Maybe has a consys power on issue,(0x%08x)\n", consysHwChipId); -+ -+ msleep(40); -+ -+ } else { -+ -+ clk_disable_unprepare(clk_infra_conn_main); -+ WMT_PLAT_DBG_FUNC("[CCF] clk_disable_unprepare(clk_infra_conn_main) calling\n"); -+ mtk_wcn_consys_power_off(); -+ -+ if (co_clock_type) { -+ /*VCN28 has been turned off by GPS OR FM */ -+#if CONSYS_CLOCK_BUF_CTRL -+ clk_buf_ctrl(CLK_BUF_CONN, 0); -+#endif -+ } else { -+ regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x0 << 14);/*V28*/ -+ /*turn off VCN28 LDO (with PMIC_WRAP API)" */ -+ if (reg_VCN28) { -+ if (regulator_disable(reg_VCN28)) -+ WMT_PLAT_ERR_FUNC("disable VCN_2V8 fail!\n"); -+ else -+ WMT_PLAT_DBG_FUNC("disable VCN_2V8 ok\n"); -+ } -+ } -+ -+ /*AP power off MT6625L VCN_1V8 LDO */ -+ regulator_set_mode(reg_VCN18, REGULATOR_MODE_STANDBY); -+ if (reg_VCN18) { -+ if (regulator_disable(reg_VCN18)) -+ WMT_PLAT_ERR_FUNC("disable VCN_1V8 fail!\n"); -+ else -+ WMT_PLAT_DBG_FUNC("disable VCN_1V8 ok\n"); -+ } -+ -+ } -+ WMT_PLAT_DBG_FUNC("CONSYS-HW-REG-CTRL(0x%08x),finish\n", on); -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_hw_gpio_ctrl(UINT32 on) -+{ -+ INT32 iRet = 0; -+ -+ WMT_PLAT_DBG_FUNC("CONSYS-HW-GPIO-CTRL(0x%08x), start\n", on); -+ -+ if (on) { -+ -+ /* TODO: [FixMe][GeorgeKuo] double check if BGF_INT is implemented ok */ -+ /* iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_MUX); */ -+ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_INIT); -+ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); -+ WMT_PLAT_DBG_FUNC("CONSYS-HW, BGF IRQ registered and disabled\n"); -+ -+ } else { -+ -+ /* set bgf eint/all eint to deinit state, namely input low state */ -+ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); -+ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_DEINIT); -+ WMT_PLAT_DBG_FUNC("CONSYS-HW, BGF IRQ unregistered and disabled\n"); -+ /* iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_DEINIT); */ -+ } -+ WMT_PLAT_DBG_FUNC("CONSYS-HW-GPIO-CTRL(0x%08x), finish\n", on); -+ return iRet; -+ -+} -+ -+INT32 mtk_wcn_consys_hw_pwr_on(UINT32 co_clock_type) -+{ -+ INT32 iRet = 0; -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-ON, start\n"); -+ -+ iRet += mtk_wcn_consys_hw_reg_ctrl(1, co_clock_type); -+ iRet += mtk_wcn_consys_hw_gpio_ctrl(1); -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-ON, finish(%d)\n", iRet); -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_hw_pwr_off(VOID) -+{ -+ INT32 iRet = 0; -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-OFF, start\n"); -+ -+ iRet += mtk_wcn_consys_hw_reg_ctrl(0, 0); -+ iRet += mtk_wcn_consys_hw_gpio_ctrl(0); -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-OFF, finish(%d)\n", iRet); -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_hw_rst(UINT32 co_clock_type) -+{ -+ INT32 iRet = 0; -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW, hw_rst start, eirq should be disabled before this step\n"); -+ -+ /*1. do whole hw power off flow */ -+ iRet += mtk_wcn_consys_hw_reg_ctrl(0, co_clock_type); -+ -+ /*2. do whole hw power on flow */ -+ iRet += mtk_wcn_consys_hw_reg_ctrl(1, co_clock_type); -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW, hw_rst finish, eirq should be enabled after this step\n"); -+ return iRet; -+} -+ -+#if CONSYS_BT_WIFI_SHARE_V33 -+INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable) -+{ -+ /* spin_lock_irqsave(&gBtWifiV33.lock,gBtWifiV33.flags); */ -+ if (enable) { -+ if (1 == gBtWifiV33.counter) { -+ gBtWifiV33.counter++; -+ WMT_PLAT_DBG_FUNC("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); -+ } else if (2 == gBtWifiV33.counter) { -+ WMT_PLAT_DBG_FUNC("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); -+ } else { -+#if CONSYS_PMIC_CTRL_ENABLE -+ /*do BT PMIC on,depenency PMIC API ready */ -+ /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ -+ /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ -+ hwPowerOn(MT6323_POWER_LDO_VCN33, VOL_3300, "wcn_drv"); -+ upmu_set_vcn33_on_ctrl_bt(1); -+#endif -+ WMT_PLAT_INFO_FUNC("WMT do BT/WIFI v3.3 on\n"); -+ gBtWifiV33.counter++; -+ } -+ -+ } else { -+ if (1 == gBtWifiV33.counter) { -+ /*do BT PMIC off */ -+ /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ -+#if CONSYS_PMIC_CTRL_ENABLE -+ upmu_set_vcn33_on_ctrl_bt(0); -+ hwPowerDown(MT6323_POWER_LDO_VCN33, "wcn_drv"); -+#endif -+ WMT_PLAT_INFO_FUNC("WMT do BT/WIFI v3.3 off\n"); -+ gBtWifiV33.counter--; -+ } else if (2 == gBtWifiV33.counter) { -+ gBtWifiV33.counter--; -+ WMT_PLAT_DBG_FUNC("V33 no need disabled,counter(%d)\n", gBtWifiV33.counter); -+ } else { -+ WMT_PLAT_DBG_FUNC("V33 has been disabled,counter(%d)\n", gBtWifiV33.counter); -+ } -+ -+ } -+ /* spin_unlock_irqrestore(&gBtWifiV33.lock,gBtWifiV33.flags); */ -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable) -+{ -+ mtk_wcn_consys_hw_bt_paldo_ctrl(enable); -+ return 0; -+} -+ -+#else -+INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable) -+{ -+ -+ if (enable) { -+ /*do BT PMIC on,depenency PMIC API ready */ -+ /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ -+ if (reg_VCN33_BT) { -+ regulator_set_voltage(reg_VCN33_BT, 3300000, 3300000); -+ if (regulator_enable(reg_VCN33_BT)) -+ WMT_PLAT_ERR_FUNC("WMT do BT PMIC on fail!\n"); -+ } -+ regmap_update_bits(pmic_regmap, 0x416, 0x1 << 5, 0x1 << 5);/*BT*/ -+ WMT_PLAT_INFO_FUNC("WMT do BT PMIC on\n"); -+ } else { -+ /*do BT PMIC off */ -+ /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ -+ regmap_update_bits(pmic_regmap, 0x416, 0x1 << 5, 0x0 << 5);/*BT*/ -+ if (reg_VCN33_BT) -+ if (regulator_disable(reg_VCN33_BT)) -+ WMT_PLAT_ERR_FUNC("WMT do BT PMIC off fail!\n"); -+ WMT_PLAT_INFO_FUNC("WMT do BT PMIC off\n"); -+ } -+ -+ return 0; -+ -+} -+ -+INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable) -+{ -+ -+ if (enable) { -+ /*do WIFI PMIC on,depenency PMIC API ready */ -+ /*switch WIFI PALDO control from SW mode to HW mode:0x418[14]-->0x1 */ -+ if (reg_VCN33_WIFI) { -+ regulator_set_voltage(reg_VCN33_WIFI, 3300000, 3300000); -+ if (regulator_enable(reg_VCN33_WIFI)) -+ WMT_PLAT_ERR_FUNC("WMT do WIFI PMIC on fail!\n"); -+ else -+ WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC on !\n"); -+ } -+ regmap_update_bits(pmic_regmap, 0x418, 0x1 << 14, 0x1 << 14);/*WIFI*/ -+ WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC on\n"); -+ } else { -+ /*do WIFI PMIC off */ -+ /*switch WIFI PALDO control from HW mode to SW mode:0x418[14]-->0x0 */ -+ regmap_update_bits(pmic_regmap, 0x418, 0x1 << 14, 0x0 << 14);/*WIFI*/ -+ if (reg_VCN33_WIFI) -+ if (regulator_disable(reg_VCN33_WIFI)) -+ WMT_PLAT_ERR_FUNC("WMT do WIFI PMIC off fail!\n"); -+ WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC off\n"); -+ } -+ -+ return 0; -+} -+ -+#endif -+INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable) -+{ -+ if (enable) { -+ /*in co-clock mode,need to turn on vcn28 when fm on */ -+ if (reg_VCN28) { -+ regulator_set_voltage(reg_VCN28, 2800000, 2800000); -+ if (regulator_enable(reg_VCN28)) -+ WMT_PLAT_ERR_FUNC("WMT do VCN28 PMIC on fail!\n"); -+ } -+ WMT_PLAT_INFO_FUNC("turn on vcn28 for fm/gps usage in co-clock mode\n"); -+ } else { -+ /*in co-clock mode,need to turn off vcn28 when fm off */ -+ if (reg_VCN28) -+ if (regulator_disable(reg_VCN28)) -+ WMT_PLAT_ERR_FUNC("WMT do VCN28 PMIC off fail!\n"); -+ WMT_PLAT_INFO_FUNC("turn off vcn28 for fm/gps usage in co-clock mode\n"); -+ } -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_hw_state_show(VOID) -+{ -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_hw_restore(struct device *device) -+{ -+ UINT32 addrPhy = 0; -+ -+ if (gConEmiPhyBase) { -+ -+#if CONSYS_EMI_MPU_SETTING -+ /*set MPU for EMI share Memory */ -+ WMT_PLAT_INFO_FUNC("setting MPU for EMI share memory\n"); -+ -+#if 0 -+ emi_mpu_set_region_protection(gConEmiPhyBase + SZ_1M/2, -+ gConEmiPhyBase + SZ_1M, -+ 5, -+ SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION)); -+ -+ -+#else -+ WMT_PLAT_WARN_FUNC("not define platform config\n"); -+#endif -+ -+#endif -+ /*consys to ap emi remapping register:10001310, cal remapping address */ -+ addrPhy = (gConEmiPhyBase & 0xFFF00000) >> 20; -+ -+ /*enable consys to ap emi remapping bit12 */ -+ addrPhy = addrPhy | 0x1000; -+ -+ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy); -+ -+ WMT_PLAT_INFO_FUNC("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); -+ -+#if 1 -+ pEmibaseaddr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_AP_PHY_OFFSET, CONSYS_EMI_MEM_SIZE); -+#else -+ pEmibaseaddr = ioremap_nocache(CONSYS_EMI_AP_PHY_BASE, CONSYS_EMI_MEM_SIZE); -+#endif -+ if (pEmibaseaddr) { -+ WMT_PLAT_INFO_FUNC("EMI mapping OK(0x%p)\n", pEmibaseaddr); -+ memset_io(pEmibaseaddr, 0, CONSYS_EMI_MEM_SIZE); -+ } else { -+ WMT_PLAT_ERR_FUNC("EMI mapping fail\n"); -+ } -+ } else { -+ WMT_PLAT_ERR_FUNC("consys emi memory address gConEmiPhyBase invalid\n"); -+ } -+ -+ return 0; -+} -+ -+/*Reserved memory by device tree!*/ -+int reserve_memory_consys_fn(struct reserved_mem *rmem) -+{ -+ WMT_PLAT_WARN_FUNC(" name: %s, base: 0x%llx, size: 0x%llx\n", rmem->name, -+ (unsigned long long)rmem->base, (unsigned long long)rmem->size); -+ gConEmiPhyBase = rmem->base; -+ return 0; -+} -+ -+RESERVEDMEM_OF_DECLARE(reserve_memory_test, "mediatek,consys-reserve-memory", reserve_memory_consys_fn); -+ -+ -+INT32 mtk_wcn_consys_hw_init(void) -+{ -+ -+ INT32 iRet = -1; -+ UINT32 addrPhy = 0; -+ INT32 i = 0; -+ struct device_node *node = NULL; -+ -+ node = of_find_compatible_node(NULL, NULL, "mediatek,mt7623-consys"); -+ if (node) { -+ /* registers base address */ -+ conn_reg.mcu_base = (SIZE_T) of_iomap(node, i); -+ WMT_PLAT_DBG_FUNC("Get mcu register base(0x%zx)\n", conn_reg.mcu_base); -+ i++; -+ -+ conn_reg.topckgen_base = (SIZE_T) of_iomap(node, i); -+ WMT_PLAT_DBG_FUNC("Get topckgen register base(0x%zx)\n", conn_reg.topckgen_base); -+ i++; -+ } else { -+ WMT_PLAT_ERR_FUNC("[%s] can't find CONSYS compatible node\n", __func__); -+ return iRet; -+ } -+ if (gConEmiPhyBase) { -+#if CONSYS_EMI_MPU_SETTING -+ /*set MPU for EMI share Memory */ -+ WMT_PLAT_INFO_FUNC("setting MPU for EMI share memory\n"); -+ -+#if 0 -+ emi_mpu_set_region_protection(gConEmiPhyBase + SZ_1M/2, -+ gConEmiPhyBase + SZ_1M, -+ 5, -+ SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION)); -+#else -+ WMT_PLAT_WARN_FUNC("not define platform config\n"); -+#endif -+ -+#endif -+ WMT_PLAT_DBG_FUNC("get consys start phy address(0x%zx)\n", (SIZE_T) gConEmiPhyBase); -+ -+ /*consys to ap emi remapping register:10001310, cal remapping address */ -+ addrPhy = (gConEmiPhyBase & 0xFFF00000) >> 20; -+ -+ /*enable consys to ap emi remapping bit12 */ -+ addrPhy = addrPhy | 0x1000; -+ -+ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy); -+ -+ WMT_PLAT_INFO_FUNC("CONSYS_EMI_MAPPING dump(0x%08x)\n", -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); -+ -+#if 1 -+ pEmibaseaddr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_AP_PHY_OFFSET, CONSYS_EMI_MEM_SIZE); -+#else -+ pEmibaseaddr = ioremap_nocache(CONSYS_EMI_AP_PHY_BASE, CONSYS_EMI_MEM_SIZE); -+#endif -+ /* pEmibaseaddr = ioremap_nocache(0x80090400,270*KBYTE); */ -+ if (pEmibaseaddr) { -+ WMT_PLAT_INFO_FUNC("EMI mapping OK(0x%p)\n", pEmibaseaddr); -+ memset_io(pEmibaseaddr, 0, CONSYS_EMI_MEM_SIZE); -+ iRet = 0; -+ } else { -+ WMT_PLAT_ERR_FUNC("EMI mapping fail\n"); -+ } -+ } else { -+ WMT_PLAT_ERR_FUNC("consys emi memory address gConEmiPhyBase invalid\n"); -+ } -+#ifdef CONFIG_MTK_HIBERNATION -+ WMT_PLAT_INFO_FUNC("register connsys restore cb for complying with IPOH function\n"); -+ register_swsusp_restore_noirq_func(ID_M_CONNSYS, mtk_wcn_consys_hw_restore, NULL); -+#endif -+ iRet = platform_driver_register(&mtk_wmt_dev_drv); -+ if (iRet) -+ WMT_PLAT_ERR_FUNC("WMT platform driver registered failed(%d)\n", iRet); -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_hw_deinit(void) -+{ -+ if (pEmibaseaddr) { -+ iounmap(pEmibaseaddr); -+ pEmibaseaddr = NULL; -+ } -+#ifdef CONFIG_MTK_HIBERNATION -+ unregister_swsusp_restore_noirq_func(ID_M_CONNSYS); -+#endif -+ -+ platform_driver_unregister(&mtk_wmt_dev_drv); -+ return 0; -+} -+ -+UINT8 *mtk_wcn_consys_emi_virt_addr_get(UINT32 ctrl_state_offset) -+{ -+ UINT8 *p_virtual_addr = NULL; -+ -+ if (!pEmibaseaddr) { -+ WMT_PLAT_ERR_FUNC("EMI base address is NULL\n"); -+ return NULL; -+ } -+ WMT_PLAT_DBG_FUNC("ctrl_state_offset(%08x)\n", ctrl_state_offset); -+ p_virtual_addr = pEmibaseaddr + ctrl_state_offset; -+ -+ return p_virtual_addr; -+} -+ -+UINT32 mtk_wcn_consys_soc_chipid(void) -+{ -+ return PLATFORM_SOC_CHIP; -+} -+ -+struct pinctrl *mtk_wcn_consys_get_pinctrl() -+{ -+ return consys_pinctrl; -+} -+INT32 mtk_wcn_consys_set_dynamic_dump(PUINT32 str_buf) -+{ -+ PUINT8 vir_addr = NULL; -+ -+ vir_addr = mtk_wcn_consys_emi_virt_addr_get(EXP_APMEM_CTRL_CHIP_DYNAMIC_DUMP); -+ if (!vir_addr) { -+ WMT_PLAT_ERR_FUNC("get vir address fail\n"); -+ return -2; -+ } -+ memcpy(vir_addr, str_buf, DYNAMIC_DUMP_GROUP_NUM*8); -+ WMT_PLAT_INFO_FUNC("dynamic dump register value(0x%08x)\n", CONSYS_REG_READ(vir_addr)); -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c -new file mode 100644 -index 0000000000000..7163dc18a255e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c -@@ -0,0 +1,1071 @@ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-PLAT]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+/* ALPS header files */ -+/*#include */ -+/*#include */ -+#if defined(CONFIG_MTK_GPIO_LEGACY) -+#include -+#endif -+#include -+ -+/* MTK_WCN_COMBO header files */ -+#include "osal_typedef.h" -+#include "mtk_wcn_consys_hw.h" -+#include "stp_dbg.h" -+ -+#define CFG_WMT_WAKELOCK_SUPPORT 1 -+ -+#ifdef CONFIG_MTK_MT6306_SUPPORT -+#define MTK_WCN_MT6306_IS_READY 1 -+#else -+#define MTK_WCN_MT6306_IS_READY 0 -+#endif -+ -+#if MTK_WCN_MT6306_IS_READY -+#include -+ -+#ifdef GPIO_GPS_LNA_PIN -+#undef GPIO_GPS_LNA_PIN -+#endif -+ -+#define GPIO_GPS_LNA_PIN GPIO7 -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = { -+ .emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE, -+ .emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE, -+ .emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM, -+ .emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE, -+ .emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM, -+ .emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR, -+ .emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN, -+ .emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START, -+ .emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN, -+ .emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX, -+ .emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS, -+ .emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END, -+ .emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, -+}; -+ -+CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = { -+ .emi_phy_addr = CONSYS_EMI_FW_PHY_BASE, -+ .paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET, -+ .paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET, -+ .full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET, -+ .p_ecso = &mtk_wcn_emi_state_off, -+}; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static VOID wmt_plat_bgf_eirq_cb(VOID); -+ -+static INT32 wmt_plat_bgf_eint_ctrl(ENUM_PIN_STATE state); -+static INT32 wmt_plat_i2s_ctrl(ENUM_PIN_STATE state); -+static INT32 wmt_plat_gps_sync_ctrl(ENUM_PIN_STATE state); -+static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state); -+ -+static INT32 wmt_plat_dump_pin_conf(VOID); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+UINT32 gCoClockFlag = 0; -+BGF_IRQ_BALANCE gbgfIrqBle; -+UINT32 wmtPlatLogLvl = WMT_PLAT_LOG_DBG; -+#if CONSYS_BT_WIFI_SHARE_V33 -+BT_WIFI_V33_STATUS gBtWifiV33; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if CFG_WMT_WAKELOCK_SUPPORT -+static struct mutex gOsSLock; -+#ifdef CONFIG_PM_WAKELOCKS -+static struct wakeup_source wmtWakeLock; -+#else -+static struct wake_lock wmtWakeLock; -+#endif -+#endif -+ -+irq_cb wmt_plat_bgf_irq_cb = NULL; -+device_audio_if_cb wmt_plat_audio_if_cb = NULL; -+func_ctrl_cb wmt_plat_func_ctrl_cb = NULL; -+thermal_query_ctrl_cb wmt_plat_thermal_query_ctrl_cb = NULL; -+deep_idle_ctrl_cb wmt_plat_deep_idle_ctrl_cb = NULL; -+ -+static const fp_set_pin gfp_set_pin_table[] = { -+ [PIN_BGF_EINT] = wmt_plat_bgf_eint_ctrl, -+ [PIN_I2S_GRP] = wmt_plat_i2s_ctrl, -+ [PIN_GPS_SYNC] = wmt_plat_gps_sync_ctrl, -+ [PIN_GPS_LNA] = wmt_plat_gps_lna_ctrl, -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*! -+ * \brief audio control callback function for CMB_STUB on ALPS -+ * -+ * A platform function required for dynamic binding with CMB_STUB on ALPS. -+ * -+ * \param state desired audio interface state to use -+ * \param flag audio interface control options -+ * -+ * \retval 0 operation success -+ * \retval -1 invalid parameters -+ * \retval < 0 error for operation fail -+ */ -+INT32 wmt_plat_audio_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl) -+{ -+ INT32 iRet = 0; -+ UINT32 pinShare = 0; -+ -+ /* input sanity check */ -+ if ((CMB_STUB_AIF_MAX <= state) -+ || (CMB_STUB_AIF_CTRL_MAX <= ctrl)) { -+ return -1; -+ } -+ -+ iRet = 0; -+ -+ /* set host side first */ -+ switch (state) { -+ case CMB_STUB_AIF_0: -+ /* BT_PCM_OFF & FM line in/out */ -+ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT); -+ break; -+ -+ case CMB_STUB_AIF_1: -+ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT); -+ break; -+ -+ case CMB_STUB_AIF_2: -+ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT); -+ break; -+ -+ case CMB_STUB_AIF_3: -+ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT); -+ break; -+ -+ default: -+ /* FIXME: move to cust folder? */ -+ WMT_PLAT_ERR_FUNC("invalid state [%d]\n", state); -+ iRet = -1; -+ break; -+ } -+ -+ if (CMB_STUB_AIF_CTRL_EN == ctrl) { -+ WMT_PLAT_INFO_FUNC("call chip aif setting\n"); -+ /* need to control chip side GPIO */ -+ if (NULL != wmt_plat_audio_if_cb) { -+ iRet += (*wmt_plat_audio_if_cb) (state, (pinShare) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); -+ } else { -+ WMT_PLAT_WARN_FUNC("wmt_plat_audio_if_cb is not registered\n"); -+ iRet -= 1; -+ } -+ -+ } else { -+ WMT_PLAT_INFO_FUNC("skip chip aif setting\n"); -+ } -+ -+ return iRet; -+ -+} -+ -+static VOID wmt_plat_func_ctrl(UINT32 type, UINT32 on) -+{ -+ if (wmt_plat_func_ctrl_cb) -+ (*wmt_plat_func_ctrl_cb) (on, type); -+} -+ -+static long wmt_plat_thermal_ctrl(VOID) -+{ -+ long temp = 0; -+ -+ if (wmt_plat_thermal_query_ctrl_cb) -+ temp = (*wmt_plat_thermal_query_ctrl_cb) (); -+ -+ return temp; -+} -+ -+static INT32 wmt_plat_deep_idle_ctrl(UINT32 dpilde_ctrl) -+{ -+ INT32 iRet = -1; -+ -+ if (wmt_plat_deep_idle_ctrl_cb) -+ iRet = (*wmt_plat_deep_idle_ctrl_cb) (dpilde_ctrl); -+ -+ return iRet; -+} -+ -+static VOID wmt_plat_bgf_eirq_cb(VOID) -+{ -+#if CFG_WMT_PS_SUPPORT -+/* #error "need to disable EINT here" */ -+ /* wmt_lib_ps_irq_cb(); */ -+ if (NULL != wmt_plat_bgf_irq_cb) -+ (*(wmt_plat_bgf_irq_cb)) (); -+ else -+ WMT_PLAT_WARN_FUNC("WMT-PLAT: wmt_plat_bgf_irq_cb not registered\n"); -+#else -+ return; -+#endif -+ -+} -+ -+irqreturn_t wmt_plat_bgf_irq_isr(INT32 i, VOID *arg) -+{ -+#if CFG_WMT_PS_SUPPORT -+ wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); -+ wmt_plat_bgf_eirq_cb(); -+#else -+ WMT_PLAT_INFO_FUNC("skip irq handing because psm is disable"); -+#endif -+ return IRQ_HANDLED; -+} -+ -+VOID wmt_plat_irq_cb_reg(irq_cb bgf_irq_cb) -+{ -+ wmt_plat_bgf_irq_cb = bgf_irq_cb; -+} -+EXPORT_SYMBOL(wmt_plat_irq_cb_reg); -+ -+VOID wmt_plat_aif_cb_reg(device_audio_if_cb aif_ctrl_cb) -+{ -+ wmt_plat_audio_if_cb = aif_ctrl_cb; -+} -+EXPORT_SYMBOL(wmt_plat_aif_cb_reg); -+ -+VOID wmt_plat_func_ctrl_cb_reg(func_ctrl_cb subsys_func_ctrl) -+{ -+ wmt_plat_func_ctrl_cb = subsys_func_ctrl; -+} -+EXPORT_SYMBOL(wmt_plat_func_ctrl_cb_reg); -+ -+VOID wmt_plat_thermal_ctrl_cb_reg(thermal_query_ctrl_cb thermal_query_ctrl) -+{ -+ wmt_plat_thermal_query_ctrl_cb = thermal_query_ctrl; -+} -+EXPORT_SYMBOL(wmt_plat_thermal_ctrl_cb_reg); -+ -+VOID wmt_plat_deep_idle_ctrl_cb_reg(deep_idle_ctrl_cb deep_idle_ctrl) -+{ -+ wmt_plat_deep_idle_ctrl_cb = deep_idle_ctrl; -+} -+EXPORT_SYMBOL(wmt_plat_deep_idle_ctrl_cb_reg); -+ -+UINT32 wmt_plat_soc_co_clock_flag_get(VOID) -+{ -+ return gCoClockFlag; -+} -+ -+static UINT32 wmt_plat_soc_co_clock_flag_set(UINT32 flag) -+{ -+ gCoClockFlag = flag; -+ return 0; -+} -+ -+INT32 wmt_plat_init(UINT32 co_clock_type) -+{ -+ CMB_STUB_CB stub_cb; -+ INT32 iret; -+ /*init wmt function ctrl wakelock if wake lock is supported by host platform */ -+ -+ wmt_plat_soc_co_clock_flag_set(co_clock_type); -+ -+ stub_cb.aif_ctrl_cb = wmt_plat_audio_ctrl; -+ stub_cb.func_ctrl_cb = wmt_plat_func_ctrl; -+ stub_cb.thermal_query_cb = wmt_plat_thermal_ctrl; -+ stub_cb.deep_idle_ctrl_cb = wmt_plat_deep_idle_ctrl; -+ stub_cb.size = sizeof(stub_cb); -+ -+ /* register to cmb_stub */ -+ iret = mtk_wcn_cmb_stub_reg(&stub_cb); -+#ifdef CFG_WMT_WAKELOCK_SUPPORT -+#ifdef CONFIG_PM_WAKELOCKS -+ wakeup_source_init(&wmtWakeLock, "wmtFuncCtrl"); -+#else -+ wake_lock_init(&wmtWakeLock, WAKE_LOCK_SUSPEND, "wmtFuncCtrl"); -+#endif -+ mutex_init(&gOsSLock); -+#endif -+ -+#if CONSYS_BT_WIFI_SHARE_V33 -+ gBtWifiV33.counter = 0; -+ spin_lock_init(&gBtWifiV33.lock); -+#endif -+ -+ iret += mtk_wcn_consys_hw_init(); -+ -+ spin_lock_init(&gbgfIrqBle.lock); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret); -+ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_init); -+ -+INT32 wmt_plat_deinit(VOID) -+{ -+ INT32 iret = 0; -+ /* 2. unreg to cmb_stub */ -+ iret = mtk_wcn_cmb_stub_unreg(); -+printk(KERN_ALERT "DEBUG: Passed %s %d now calling wmt wakelock deinit\n",__FUNCTION__,__LINE__); -+ /*3. wmt wakelock deinit */ -+#ifdef CFG_WMT_WAKELOCK_SUPPORT -+#ifdef CONFIG_PM_WAKELOCKS -+printk(KERN_ALERT "DEBUG: Passed %s %d now calling wakeup_source_trash\n",__FUNCTION__,__LINE__); -+ wakeup_source_trash(&wmtWakeLock); -+#else -+printk(KERN_ALERT "DEBUG: Passed %s %d now calling wake lock destroy %d\n",__FUNCTION__,__LINE__,(int)&wmtWakeLock); -+//destroy calls wakeup_source_trash with &lock->ws -+printk(KERN_ALERT "DEBUG: Passed %s %d now wmtWakeLock:%d\n",__FUNCTION__,__LINE__,(int)&wmtWakeLock); -+printk(KERN_ALERT "DEBUG: Passed %s %d now wmtWakeLock->ws: %d\n",__FUNCTION__,__LINE__,(int)&(wmtWakeLock.ws)); -+ wake_lock_destroy(&wmtWakeLock); -+#endif -+printk(KERN_ALERT "DEBUG: Passed %s %d now calling mutex_destroy\n",__FUNCTION__,__LINE__); -+ mutex_destroy(&gOsSLock); -+ WMT_PLAT_DBG_FUNC("destroy wmtWakeLock\n"); -+#endif -+printk(KERN_ALERT "DEBUG: Passed %s %d now calling consys hw deinit\n",__FUNCTION__,__LINE__); -+ -+ iret += mtk_wcn_consys_hw_deinit(); -+ -+ WMT_PLAT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret); -+ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_deinit); -+ -+static INT32 wmt_plat_dump_pin_conf(VOID) -+{ -+ WMT_PLAT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration start<=\n"); -+#if defined(CONFIG_MTK_GPIO_LEGACY) -+ -+#ifdef GPIO_COMBO_BGF_EINT_PIN -+ WMT_PLAT_DBG_FUNC("BGF_EINT(GPIO%d)\n", GPIO_COMBO_BGF_EINT_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("BGF_EINT(not defined)\n"); -+#endif -+ -+#ifdef CUST_EINT_COMBO_BGF_NUM -+ WMT_PLAT_DBG_FUNC("BGF_EINT_NUM(%d)\n", CUST_EINT_COMBO_BGF_NUM); -+#else -+ WMT_PLAT_DBG_FUNC("BGF_EINT_NUM(not defined)\n"); -+#endif -+ -+#ifdef GPIO_COMBO_URXD_PIN -+ WMT_PLAT_DBG_FUNC("UART_RX(GPIO%d)\n", GPIO_COMBO_URXD_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("UART_RX(not defined)\n"); -+#endif -+#if defined(FM_DIGITAL_INPUT) || defined(FM_DIGITAL_OUTPUT) -+#ifdef GPIO_COMBO_I2S_CK_PIN -+ WMT_PLAT_DBG_FUNC("I2S_CK(GPIO%d)\n", GPIO_COMBO_I2S_CK_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("I2S_CK(not defined)\n"); -+#endif -+#ifdef GPIO_COMBO_I2S_WS_PIN -+ WMT_PLAT_DBG_FUNC("I2S_WS(GPIO%d)\n", GPIO_COMBO_I2S_WS_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("I2S_WS(not defined)\n"); -+#endif -+#ifdef GPIO_COMBO_I2S_DAT_PIN -+ WMT_PLAT_DBG_FUNC("I2S_DAT(GPIO%d)\n", GPIO_COMBO_I2S_DAT_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("I2S_DAT(not defined)\n"); -+#endif -+#else /* FM_ANALOG_INPUT || FM_ANALOG_OUTPUT */ -+ WMT_PLAT_DBG_FUNC("FM digital mode is not set, no need for I2S GPIOs\n"); -+#endif -+#ifdef GPIO_GPS_SYNC_PIN -+ WMT_PLAT_DBG_FUNC("GPS_SYNC(GPIO%d)\n", GPIO_GPS_SYNC_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("GPS_SYNC(not defined)\n"); -+#endif -+ -+#ifdef GPIO_GPS_LNA_PIN -+ WMT_PLAT_INFO_FUNC("GPS_LNA(GPIO%d)\n", GPIO_GPS_LNA_PIN); -+#else -+ WMT_PLAT_INFO_FUNC("GPS_LNA(not defined)\n"); -+#endif -+ -+#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ -+#endif -+ WMT_PLAT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration emds<=\n"); -+ return 0; -+} -+ -+INT32 wmt_plat_pwr_ctrl(ENUM_FUNC_STATE state) -+{ -+ INT32 ret = -1; -+ -+ switch (state) { -+ case FUNC_ON: -+ /* TODO:[ChangeFeature][George] always output this or by request throuth /proc or sysfs? */ -+ wmt_plat_dump_pin_conf(); -+ ret = mtk_wcn_consys_hw_pwr_on(gCoClockFlag); -+ break; -+ -+ case FUNC_OFF: -+ ret = mtk_wcn_consys_hw_pwr_off(); -+ break; -+ -+ case FUNC_RST: -+ ret = mtk_wcn_consys_hw_rst(gCoClockFlag); -+ break; -+ case FUNC_STAT: -+ ret = mtk_wcn_consys_hw_state_show(); -+ break; -+ default: -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) in pwr_ctrl\n", state); -+ break; -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL(wmt_plat_pwr_ctrl); -+ -+INT32 wmt_plat_eirq_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state) -+{ -+#ifdef CONFIG_OF -+ struct device_node *node; -+ unsigned int irq_info[3] = { 0, 0, 0 }; -+#endif -+ INT32 iret = -EINVAL; -+ static INT32 bgf_irq_num = -1; -+ static UINT32 bgf_irq_flag; -+ /* TODO: [ChangeFeature][GeorgeKuo]: use another function to handle this, as done in gpio_ctrls */ -+ -+ if ((PIN_STA_INIT != state) -+ && (PIN_STA_DEINIT != state) -+ && (PIN_STA_EINT_EN != state) -+ && (PIN_STA_EINT_DIS != state)) { -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:invalid PIN_STATE(%d) in eirq_ctrl for PIN(%d)\n", state, id); -+ return -1; -+ } -+ -+ switch (id) { -+ case PIN_BGF_EINT: -+ -+ if (PIN_STA_INIT == state) { -+#ifdef CONFIG_OF -+ node = of_find_compatible_node(NULL, NULL, "mediatek,mt7623-consys"); -+ if (node) { -+ bgf_irq_num = irq_of_parse_and_map(node, 0); -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ WMT_PLAT_ERR_FUNC("get irq flags from DTS fail!!\n"); -+ return iret; -+ } -+ bgf_irq_flag = irq_info[2]; -+ WMT_PLAT_INFO_FUNC("get irq id(%d) and irq trigger flag(%d) from DT\n", bgf_irq_num, -+ bgf_irq_flag); -+ } else { -+ WMT_PLAT_ERR_FUNC("[%s] can't find CONSYS compatible node\n", __func__); -+ return iret; -+ } -+#else -+ bgf_irq_num = MT_CONN2AP_BTIF_WAKEUP_IRQ_ID; -+ bgf_irq_flag = IRQF_TRIGGER_LOW; -+#endif -+ iret = request_irq(bgf_irq_num, wmt_plat_bgf_irq_isr, bgf_irq_flag, "BTIF_WAKEUP_IRQ", NULL); -+ if (iret) { -+ WMT_PLAT_ERR_FUNC("request_irq fail,irq_no(%d),iret(%d)\n", bgf_irq_num, iret); -+ return iret; -+ } -+ gbgfIrqBle.counter = 1; -+ -+ } else if (PIN_STA_EINT_EN == state) { -+ -+ spin_lock_irqsave(&gbgfIrqBle.lock, gbgfIrqBle.flags); -+ if (gbgfIrqBle.counter) { -+ WMT_PLAT_DBG_FUNC("BGF INT has been enabled,counter(%d)\n", gbgfIrqBle.counter); -+ } else { -+ enable_irq(bgf_irq_num); -+ gbgfIrqBle.counter++; -+ } -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt (en)\n"); -+ spin_unlock_irqrestore(&gbgfIrqBle.lock, gbgfIrqBle.flags); -+ } else if (PIN_STA_EINT_DIS == state) { -+ spin_lock_irqsave(&gbgfIrqBle.lock, gbgfIrqBle.flags); -+ if (!gbgfIrqBle.counter) { -+ WMT_PLAT_INFO_FUNC("BGF INT has been disabled,counter(%d)\n", gbgfIrqBle.counter); -+ } else { -+ disable_irq_nosync(bgf_irq_num); -+ gbgfIrqBle.counter--; -+ } -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt (dis)\n"); -+ spin_unlock_irqrestore(&gbgfIrqBle.lock, gbgfIrqBle.flags); -+ } else { -+ free_irq(bgf_irq_num, NULL); -+ /* de-init: nothing to do in ALPS, such as un-registration... */ -+ } -+ iret = 0; -+ break; -+ -+ default: -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:unsupported EIRQ(PIN_ID:%d) in eirq_ctrl\n", id); -+ iret = -1; -+ break; -+ } -+ -+ return iret; -+} -+EXPORT_SYMBOL(wmt_plat_eirq_ctrl); -+ -+INT32 wmt_plat_gpio_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state) -+{ -+ if ((PIN_ID_MAX > id) -+ && (PIN_STA_MAX > state)) { -+ -+ /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ -+ if (gfp_set_pin_table[id]) -+ return (*(gfp_set_pin_table[id])) (state); /* .handler */ -+ WMT_PLAT_WARN_FUNC("WMT-PLAT: null fp for gpio_ctrl(%d)\n", id); -+ return -2; -+ } -+ return -1; -+} -+EXPORT_SYMBOL(wmt_plat_gpio_ctrl); -+ -+INT32 wmt_plat_bgf_eint_ctrl(ENUM_PIN_STATE state) -+{ -+#if defined(CONFIG_MTK_GPIO_LEGACY) -+#ifdef GPIO_COMBO_BGF_EINT_PIN -+ switch (state) { -+ case PIN_STA_INIT: -+ /*set to gpio input low, pull down enable */ -+ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_COMBO_BGF_EINT_PIN, GPIO_DIR_IN); -+ mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_DOWN); -+ mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt init(in pd)\n"); -+ break; -+ -+ case PIN_STA_MUX: -+ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO); -+ mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE); -+ mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_UP); -+ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_EINT); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt mux (eint)\n"); -+ break; -+ -+ case PIN_STA_IN_L: -+ case PIN_STA_DEINIT: -+ /*set to gpio input low, pull down enable */ -+ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_COMBO_BGF_EINT_PIN, GPIO_DIR_IN); -+ mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_DOWN); -+ mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt deinit(in pd)\n"); -+ break; -+ -+ default: -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on BGF EINT\n", state); -+ break; -+ } -+#else -+ WMT_PLAT_INFO_FUNC("WMT-PLAT:BGF EINT not defined\n"); -+#endif -+#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ -+#endif -+ return 0; -+} -+ -+static INT32 wmt_plat_gps_sync_ctrl(ENUM_PIN_STATE state) -+{ -+#if defined(CONFIG_MTK_GPIO_LEGACY) -+ -+#ifdef GPIO_GPS_SYNC_PIN -+#ifndef GPIO_GPS_SYNC_PIN_M_GPS_SYNC -+#ifdef GPIO_GPS_SYNC_PIN_M_MD1_GPS_SYNC -+#define GPIO_GPS_SYNC_PIN_M_GPS_SYNC GPIO_GPS_SYNC_PIN_M_MD1_GPS_SYNC -+#else -+#ifdef GPIO_GPS_SYNC_PIN_M_MD2_GPS_SYNC -+#define GPIO_GPS_SYNC_PIN_M_GPS_SYNC GPIO_GPS_SYNC_PIN_M_MD2_GPS_SYNC -+#endif -+#endif -+#endif -+ switch (state) { -+ case PIN_STA_INIT: -+ case PIN_STA_DEINIT: -+ mt_set_gpio_mode(GPIO_GPS_SYNC_PIN, GPIO_GPS_SYNC_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_GPS_SYNC_PIN, GPIO_DIR_OUT); -+ mt_set_gpio_out(GPIO_GPS_SYNC_PIN, GPIO_OUT_ZERO); -+ break; -+ -+ case PIN_STA_MUX: -+ mt_set_gpio_mode(GPIO_GPS_SYNC_PIN, GPIO_GPS_SYNC_PIN_M_GPS_SYNC); -+ break; -+ -+ default: -+ break; -+ } -+#endif -+ -+#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ -+#endif -+ return 0; -+} -+ -+#if MTK_WCN_MT6306_IS_READY -+/* MT6306 GPIO7 is GPIO_GPS_LNA_EN, for K2 common phone pin modification */ -+static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state) -+{ -+#ifdef GPIO_GPS_LNA_PIN -+ switch (state) { -+ case PIN_STA_INIT: -+ case PIN_STA_DEINIT: -+ WMT_PLAT_ERR_FUNC("Gps LNA pin ctrl %d!\n", state); -+ mt6306_set_gpio_dir(GPIO_GPS_LNA_PIN, GPIO_DIR_OUT); -+ mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); -+ break; -+ case PIN_STA_OUT_H: -+ WMT_PLAT_ERR_FUNC("Gps LNA pin output high!\n"); -+ mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ONE); -+ break; -+ case PIN_STA_OUT_L: -+ WMT_PLAT_ERR_FUNC("Gps LNA pin output low!\n"); -+ mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); -+ break; -+ default: -+ WMT_PLAT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); -+ break; -+ } -+ return 0; -+#else -+ WMT_PLAT_WARN_FUNC("host gps lna pin not defined!!!\n"); -+ return 0; -+#endif -+} -+#else -+ -+static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state) -+{ -+#if !defined(CONFIG_MTK_GPIO_LEGACY) -+ static struct pinctrl_state *gps_lna_init; -+ static struct pinctrl_state *gps_lna_oh; -+ static struct pinctrl_state *gps_lna_ol; -+ static struct pinctrl *consys_pinctrl; -+ -+ WMT_PLAT_DBG_FUNC("ENTER++\n"); -+ consys_pinctrl = mtk_wcn_consys_get_pinctrl(); -+ if (NULL == consys_pinctrl) { -+ WMT_PLAT_ERR_FUNC("get consys pinctrl fail\n"); -+ return -1; -+ } -+ -+ gps_lna_init = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_init"); -+ if (NULL == gps_lna_init) { -+ WMT_PLAT_ERR_FUNC("Cannot find gps lna pin init state!\n"); -+ return -2; -+ } -+ -+ gps_lna_oh = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_oh"); -+ if (NULL == gps_lna_oh) { -+ WMT_PLAT_ERR_FUNC("Cannot find gps lna pin oh state!\n"); -+ return -3; -+ } -+ -+ gps_lna_ol = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_ol"); -+ if (NULL == gps_lna_ol) { -+ WMT_PLAT_ERR_FUNC("Cannot find gps lna pin ol state!\n"); -+ return -4; -+ } -+ -+ switch (state) { -+ case PIN_STA_INIT: -+ case PIN_STA_DEINIT: -+ pinctrl_select_state(consys_pinctrl, gps_lna_init); -+ WMT_PLAT_INFO_FUNC("set gps lna to init\n"); -+ break; -+ case PIN_STA_OUT_H: -+ pinctrl_select_state(consys_pinctrl, gps_lna_oh); -+ WMT_PLAT_INFO_FUNC("set gps lna to oh\n"); -+ break; -+ case PIN_STA_OUT_L: -+ pinctrl_select_state(consys_pinctrl, gps_lna_ol); -+ WMT_PLAT_INFO_FUNC("set gps lna to ol\n"); -+ break; -+ -+ default: -+ WMT_PLAT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); -+ break; -+ } -+ return 0; -+#else -+#ifdef GPIO_GPS_LNA_PIN -+ switch (state) { -+ case PIN_STA_INIT: -+ case PIN_STA_DEINIT: -+ mt_set_gpio_pull_enable(GPIO_GPS_LNA_PIN, GPIO_PULL_DISABLE); -+ mt_set_gpio_dir(GPIO_GPS_LNA_PIN, GPIO_DIR_OUT); -+ mt_set_gpio_mode(GPIO_GPS_LNA_PIN, GPIO_GPS_LNA_PIN_M_GPIO); -+ mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); -+ break; -+ case PIN_STA_OUT_H: -+ mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ONE); -+ break; -+ case PIN_STA_OUT_L: -+ mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); -+ break; -+ -+ default: -+ WMT_PLAT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); -+ break; -+ } -+ return 0; -+#else -+ WMT_PLAT_WARN_FUNC("host gps lna pin not defined!!!\n"); -+ return 0; -+#endif -+#endif /* !defined(CONFIG_MTK_GPIO_LEGACY) */ -+} -+#endif -+ -+INT32 wmt_plat_i2s_ctrl(ENUM_PIN_STATE state) -+{ -+ /* TODO: [NewFeature][GeorgeKuo]: GPIO_I2Sx is changed according to different project. */ -+ /* TODO: provide a translation table in board_custom.h for different ALPS project customization. */ -+#if defined(CONFIG_MTK_GPIO_LEGACY) -+ -+#if defined(FM_DIGITAL_INPUT) || defined(FM_DIGITAL_OUTPUT) -+#if defined(GPIO_COMBO_I2S_CK_PIN) -+ switch (state) { -+ case PIN_STA_INIT: -+ case PIN_STA_MUX: -+ mt_set_gpio_mode(GPIO_COMBO_I2S_CK_PIN, GPIO_COMBO_I2S_CK_PIN_M_I2S0_CK); -+ mt_set_gpio_mode(GPIO_COMBO_I2S_WS_PIN, GPIO_COMBO_I2S_WS_PIN_M_I2S0_WS); -+ mt_set_gpio_mode(GPIO_COMBO_I2S_DAT_PIN, GPIO_COMBO_I2S_DAT_PIN_M_I2S0_DAT); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:I2S init (I2S0 system)\n"); -+ break; -+ case PIN_STA_IN_L: -+ case PIN_STA_DEINIT: -+ mt_set_gpio_mode(GPIO_COMBO_I2S_CK_PIN, GPIO_COMBO_I2S_CK_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_COMBO_I2S_CK_PIN, GPIO_DIR_OUT); -+ mt_set_gpio_out(GPIO_COMBO_I2S_CK_PIN, GPIO_OUT_ZERO); -+ -+ mt_set_gpio_mode(GPIO_COMBO_I2S_WS_PIN, GPIO_COMBO_I2S_WS_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_COMBO_I2S_WS_PIN, GPIO_DIR_OUT); -+ mt_set_gpio_out(GPIO_COMBO_I2S_WS_PIN, GPIO_OUT_ZERO); -+ -+ mt_set_gpio_mode(GPIO_COMBO_I2S_DAT_PIN, GPIO_COMBO_I2S_DAT_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_COMBO_I2S_DAT_PIN, GPIO_DIR_OUT); -+ mt_set_gpio_out(GPIO_COMBO_I2S_DAT_PIN, GPIO_OUT_ZERO); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:I2S deinit (out 0)\n"); -+ break; -+ default: -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on I2S Group\n", state); -+ break; -+ } -+#else -+ WMT_PLAT_ERR_FUNC("[MT6620]Error:FM digital mode set, but no I2S GPIOs defined\n"); -+#endif -+#else -+ WMT_PLAT_INFO_FUNC -+ ("[MT6620]warnning:FM digital mode is not set, no I2S GPIO settings should be modified by combo driver\n"); -+#endif -+ -+#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ -+#endif -+ return 0; -+} -+ -+INT32 wmt_plat_wake_lock_ctrl(ENUM_WL_OP opId) -+{ -+#ifdef CFG_WMT_WAKELOCK_SUPPORT -+ static INT32 counter; -+ INT32 status; -+ INT32 ret = 0; -+ -+ ret = mutex_lock_killable(&gOsSLock); -+ if (ret) { -+ WMT_PLAT_ERR_FUNC("--->lock gOsSLock failed, ret=%d\n", ret); -+ return ret; -+ } -+ -+ if (WL_OP_GET == opId) -+ ++counter; -+ else if (WL_OP_PUT == opId) -+ --counter; -+ -+ mutex_unlock(&gOsSLock); -+ if (WL_OP_GET == opId && counter == 1) { -+ #ifdef CONFIG_PM_WAKELOCKS -+ __pm_stay_awake(&wmtWakeLock); -+ status = wmtWakeLock.active; -+ #else -+ wake_lock(&wmtWakeLock); -+ status = wake_lock_active(&wmtWakeLock); -+ #endif -+ WMT_PLAT_DBG_FUNC("WMT-PLAT: after wake_lock(%d), counter(%d)\n", status, counter); -+ -+ } else if (WL_OP_PUT == opId && counter == 0) { -+ #ifdef CONFIG_PM_WAKELOCKS -+ __pm_relax(&wmtWakeLock); -+ status = wmtWakeLock.active; -+ #else -+ wake_unlock(&wmtWakeLock); -+ status = wake_lock_active(&wmtWakeLock); -+ #endif -+ WMT_PLAT_DBG_FUNC("WMT-PLAT: after wake_unlock(%d), counter(%d)\n", status, counter); -+ } else { -+ #ifdef CONFIG_PM_WAKELOCKS -+ status = wmtWakeLock.active; -+ #else -+ status = wake_lock_active(&wmtWakeLock); -+ #endif -+ WMT_PLAT_WARN_FUNC("WMT-PLAT: wakelock status(%d), counter(%d)\n", status, counter); -+ } -+ return 0; -+#else -+ WMT_PLAT_WARN_FUNC("WMT-PLAT: host awake function is not supported.\n"); -+ return 0; -+ -+#endif -+} -+EXPORT_SYMBOL(wmt_plat_wake_lock_ctrl); -+ -+INT32 wmt_plat_soc_paldo_ctrl(ENUM_PALDO_TYPE ePt, ENUM_PALDO_OP ePo) -+{ -+ INT32 iRet = 0; -+ -+ switch (ePt) { -+ -+ case BT_PALDO: -+ iRet = mtk_wcn_consys_hw_bt_paldo_ctrl(ePo); -+ break; -+ case WIFI_PALDO: -+ iRet = mtk_wcn_consys_hw_wifi_paldo_ctrl(ePo); -+ break; -+ case FM_PALDO: -+ case GPS_PALDO: -+ iRet = mtk_wcn_consys_hw_vcn28_ctrl(ePo); -+ break; -+ default: -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid type(%d) in palod_ctrl\n", ePt); -+ break; -+ } -+ return iRet; -+} -+EXPORT_SYMBOL(wmt_plat_soc_paldo_ctrl); -+ -+UINT8 *wmt_plat_get_emi_virt_add(UINT32 offset) -+{ -+ return mtk_wcn_consys_emi_virt_addr_get(offset); -+} -+EXPORT_SYMBOL(wmt_plat_get_emi_virt_add); -+ -+P_CONSYS_EMI_ADDR_INFO wmt_plat_get_emi_phy_add(VOID) -+{ -+ return &mtk_wcn_emi_addr_info; -+} -+EXPORT_SYMBOL(wmt_plat_get_emi_phy_add); -+ -+#if CONSYS_ENALBE_SET_JTAG -+UINT32 wmt_plat_jtag_flag_ctrl(UINT32 en) -+{ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_jtag_flag_ctrl); -+#endif -+ -+#if CFG_WMT_DUMP_INT_STATUS -+VOID wmt_plat_BGF_irq_dump_status(VOID) -+{ -+ WMT_PLAT_INFO_FUNC("this function is null in MT8127\n"); -+} -+EXPORT_SYMBOL(wmt_plat_BGF_irq_dump_status); -+ -+MTK_WCN_BOOL wmt_plat_dump_BGF_irq_status(VOID) -+{ -+ return MTK_WCN_BOOL_FALSE; -+} -+EXPORT_SYMBOL(wmt_plat_dump_BGF_irq_status); -+#endif -+ -+UINT32 wmt_plat_read_cpupcr(void) -+{ -+ return CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CPUPCR_OFFSET); -+} -+EXPORT_SYMBOL(wmt_plat_read_cpupcr); -+ -+UINT32 wmt_plat_read_dmaregs(UINT32 type) -+{ -+ return 0; -+#if 0 -+ switch (type) { -+ case CONNSYS_CLK_GATE_STATUS: -+ return CONSYS_REG_READ(CONNSYS_CLK_GATE_STATUS_REG); -+ case CONSYS_EMI_STATUS: -+ return CONSYS_REG_READ(CONSYS_EMI_STATUS_REG); -+ case SYSRAM1: -+ return CONSYS_REG_READ(SYSRAM1_REG); -+ case SYSRAM2: -+ return CONSYS_REG_READ(SYSRAM2_REG); -+ case SYSRAM3: -+ return CONSYS_REG_READ(SYSRAM3_REG); -+ default: -+ return 0; -+ } -+#endif -+} -+ -+INT32 wmt_plat_set_host_dump_state(ENUM_HOST_DUMP_STATE state) -+{ -+ PUINT8 p_virtual_addr = NULL; -+ -+ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_SYNC_STATE); -+ if (!p_virtual_addr) { -+ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); -+ return -1; -+ } -+ -+ CONSYS_REG_WRITE(p_virtual_addr, state); -+ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_set_host_dump_state); -+ -+UINT32 wmt_plat_force_trigger_assert(ENUM_FORCE_TRG_ASSERT_T type) -+{ -+ PUINT8 p_virtual_addr = NULL; -+ -+ switch (type) { -+ case STP_FORCE_TRG_ASSERT_EMI: -+ -+ WMT_PLAT_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi -->\n"); -+ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1); -+ if (!p_virtual_addr) { -+ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); -+ return -1; -+ } -+ -+ CONSYS_REG_WRITE(p_virtual_addr, EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1); -+ WMT_PLAT_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi <--\n"); -+ break; -+ case STP_FORCE_TRG_ASSERT_DEBUG_PIN: -+ -+ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, -+ CONSYS_REG_READ(conn_reg.topckgen_base + -+ CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT); -+ WMT_PLAT_INFO_FUNC("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); -+ usleep_range(64, 96); -+ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, -+ CONSYS_REG_READ(conn_reg.topckgen_base + -+ CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT); -+ WMT_PLAT_INFO_FUNC("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); -+ -+ break; -+ default: -+ WMT_PLAT_ERR_FUNC("unknown force trigger assert type\n"); -+ break; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_force_trigger_assert); -+ -+INT32 wmt_plat_update_host_sync_num(VOID) -+{ -+ PUINT8 p_virtual_addr = NULL; -+ UINT32 sync_num = 0; -+ -+ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_SYNC_NUM); -+ if (!p_virtual_addr) { -+ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); -+ return -1; -+ } -+ -+ sync_num = CONSYS_REG_READ(p_virtual_addr); -+ CONSYS_REG_WRITE(p_virtual_addr, sync_num + 1); -+ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_update_host_sync_num); -+ -+INT32 wmt_plat_get_dump_info(UINT32 offset) -+{ -+ PUINT8 p_virtual_addr = NULL; -+ -+ p_virtual_addr = wmt_plat_get_emi_virt_add(offset); -+ if (!p_virtual_addr) { -+ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); -+ return -1; -+ } -+ WMT_PLAT_INFO_FUNC("connsys_reg_read (0x%x), (0x%p), (0x%x)\n", CONSYS_REG_READ(p_virtual_addr), p_virtual_addr, -+ offset); -+ return CONSYS_REG_READ(p_virtual_addr); -+} -+EXPORT_SYMBOL(wmt_plat_get_dump_info); -+ -+UINT32 wmt_plat_get_soc_chipid(void) -+{ -+ UINT32 chipId = mtk_wcn_consys_soc_chipid(); -+ -+ WMT_PLAT_INFO_FUNC("current SOC chip:0x%x\n", chipId); -+ return chipId; -+} -+EXPORT_SYMBOL(wmt_plat_get_soc_chipid); -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+INT32 wmt_plat_get_tdm_antsel_index(VOID) -+{ -+ WMT_PLAT_INFO_FUNC("not support LTE in this platform\n"); -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_get_tdm_antsel_index); -+#endif -+INT32 wmt_plat_set_dbg_mode(UINT32 flag) -+{ -+ return -1; -+} -+VOID wmt_plat_set_dynamic_dumpmem(UINT32 *buf) -+{ -+ mtk_wcn_consys_set_dynamic_dump(buf); -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/Makefile b/drivers/misc/mediatek/connectivity/wlan/Makefile -new file mode 100644 -index 0000000000000..2961aeb073eaa ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/Makefile -@@ -0,0 +1,8 @@ -+ifeq ($(CONFIG_MTK_COMBO_WIFI),y) -+ subdir-ccflags-y += -D MTK_WCN_BUILT_IN_DRIVER -+endif -+ -+ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) -+#$(warning include gen2) -+ obj-y += gen2/ -+endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile b/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile -new file mode 100644 -index 0000000000000..b86ab49fce3a0 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile -@@ -0,0 +1,237 @@ -+# --------------------------------------------------- -+# Compile Options -+# --------------------------------------------------- -+ccflags-y += -DLINUX -DMT6628 -+ -+ccflags-y += -DCFG_SUPPORT_AGPS_ASSIST=1 -+ccflags-y += -DCFG_SUPPORT_TSF_USING_BOOTTIME=1 -+ccflags-y += -DCFG_P2P_LEGACY_COEX_REVISE=1 -+ccflags-y += -DARP_MONITER_ENABLE=1 -+ -+ifeq ($(CONFIG_MTK_WAPI_SUPPORT), y) -+ ccflags-y += -DCFG_SUPPORT_WAPI=1 -+else -+ ccflags-y += -DCFG_SUPPORT_WAPI=0 -+endif -+ -+ifeq ($(CONFIG_MTK_WIFI_MCC_SUPPORT), y) -+ ccflags-y += -DCFG_SUPPORT_MCC=1 -+else -+ ccflags-y += -DCFG_SUPPORT_MCC=0 -+endif -+ -+ifeq ($(CONFIG_HAVE_XLOG_FEATURE), y) -+ ccflags-y += -DCFG_SUPPORT_XLOG=1 -+else -+ ccflags-y += -DCFG_SUPPORT_XLOG=0 -+endif -+ -+ifeq ($(CONFIG_MTK_AEE_FEATURE), y) -+ ccflags-y += -DCFG_SUPPORT_AEE=1 -+else -+ ccflags-y += -DCFG_SUPPORT_AEE=0 -+endif -+ -+#ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF_SDIO1), y) -+# ccflags-y += -D_HIF_SDIO=1 -+#endif -+ -+ifeq ($(CONFIG_MTK_PASSPOINT_R1_SUPPORT), y) -+ ccflags-y += -DCFG_SUPPORT_HOTSPOT_2_0=1 -+ ccflags-y += -DCFG_HS20_DEBUG=1 -+ ccflags-y += -DCFG_ENABLE_GTK_FRAME_FILTER=1 -+else -+ ccflags-y += -DCFG_SUPPORT_HOTSPOT_2_0=0 -+ ccflags-y += -DCFG_HS20_DEBUG=0 -+ ccflags-y += -DCFG_ENABLE_GTK_FRAME_FILTER=0 -+endif -+ -+MTK_MET_PROFILING_SUPPORT = no -+ifeq ($(MTK_MET_PROFILING_SUPPORT), yes) -+ ccflags-y += -DCFG_SUPPORT_MET_PROFILING=1 -+else -+ ccflags-y += -DCFG_SUPPORT_MET_PROFILING=0 -+endif -+ -+ifeq ($(CONFIG_MTK_TC1_FEATURE), y) -+ifeq ($(CONFIG_MTK_GPT_SCHEME_SUPPORT), y) -+ ccflags-y += -I$(srctree)/drivers/misc/mediatek/tc1_interface/gpt -+else -+ ccflags-y += -I$(srctree)/drivers/misc/mediatek/tc1_interface/pmt -+endif -+ ccflags-y += -DCFG_TC1_FEATURE=1 -+ ccflags-y += -DCFG_SUPPORT_CFG_FILE=1 -+else -+ ccflags-y += -DCFG_TC1_FEATURE=0 -+endif -+ -+MTK_SRAM_SIZE_OPTION=0 -+ifeq ($(CONFIG_ARCH_MT6755), y) -+ MTK_SRAM_SIZE_OPTION=2 -+endif -+ifeq ($(CONFIG_ARCH_MT6735), y) -+ MTK_SRAM_SIZE_OPTION=1 -+endif -+ifeq ($(CONFIG_ARCH_MT6735M), y) -+ MTK_SRAM_SIZE_OPTION=1 -+endif -+ifeq ($(CONFIG_ARCH_MT6753), y) -+ MTK_SRAM_SIZE_OPTION=1 -+endif -+ifeq ($(CONFIG_ARCH_MT6580), y) -+ MTK_SRAM_SIZE_OPTION=1 -+endif -+ifeq ($(CONFIG_ARCH_MT8163), y) -+ MTK_SRAM_SIZE_OPTION=1 -+endif -+ccflags-y += -DCFG_SRAM_SIZE_OPTION=$(MTK_SRAM_SIZE_OPTION) -+ -+ifeq ($(strip $(TRUSTONIC_TEE_SUPPORT)),yes) -+ifeq ($(strip $(MTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT)),yes) -+ ccflags-y += -DTRUSTONIC_TEE_SUPPORT -+ ccflags-y += -DMTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT -+endif -+endif -+ -+ccflags-y += -D_HIF_SDIO=1 -+ -+ccflags-y += -DDBG=0 -+ccflags-y += -I$(src)/os -I$(src)/os/linux/include -I$(src)/os/linux/hif/ahb/include -+ccflags-y += -I$(src)/include -I$(src)/include/nic -I$(src)/include/mgmt -+ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include -+ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/ -+ -+MODULE_NAME := wlan_gen2 -+obj-$(CONFIG_MTK_COMBO_WIFI) += $(MODULE_NAME).o -+#obj-m += $(MODULE_NAME).o if CONFIG_MTK_COMBO_WIFI=m ==> obj-m means ko module, not build in obj-y -+ -+# --------------------------------------------------- -+# Directory List -+# --------------------------------------------------- -+COMMON_DIR := common/ -+OS_DIR := os/linux/ -+HIF_DIR := os/linux/hif/ahb/ -+NIC_DIR := nic/ -+MGMT_DIR := mgmt/ -+DMA_DIR := ../../../../platform/$(call lc,$(MTK_PLATFORM))/kernel/drivers/wifi/ -+PLAT_DIR := os/linux/plat/$(MTK_PLATFORM)/ -+HIF_AHB_PDMA := $(HIF_DIR)$(MTK_PLATFORM)/ -+#$(call lc,$(MTK_PLATFORM)) -+ -+ -+# --------------------------------------------------- -+# Objects List -+# --------------------------------------------------- -+ -+COMMON_OBJS := $(COMMON_DIR)dump.o \ -+ $(COMMON_DIR)wlan_lib.o \ -+ $(COMMON_DIR)wlan_oid.o \ -+ $(COMMON_DIR)wlan_bow.o \ -+ $(COMMON_DIR)debug.o -+ -+NIC_OBJS := $(NIC_DIR)nic.o \ -+ $(NIC_DIR)nic_tx.o \ -+ $(NIC_DIR)nic_rx.o \ -+ $(NIC_DIR)nic_pwr_mgt.o \ -+ $(NIC_DIR)cmd_buf.o \ -+ $(NIC_DIR)que_mgt.o \ -+ $(NIC_DIR)nic_cmd_event.o -+ -+OS_OBJS := $(OS_DIR)gl_init.o \ -+ $(OS_DIR)gl_kal.o \ -+ $(OS_DIR)gl_bow.o \ -+ $(OS_DIR)gl_wext.o \ -+ $(OS_DIR)gl_wext_priv.o \ -+ $(OS_DIR)gl_rst.o \ -+ $(OS_DIR)gl_cfg80211.o \ -+ $(OS_DIR)gl_vendor.o \ -+ $(OS_DIR)platform.o \ -+ $(OS_DIR)gl_proc.o -+ -+MGMT_OBJS := $(MGMT_DIR)ais_fsm.o \ -+ $(MGMT_DIR)aaa_fsm.o \ -+ $(MGMT_DIR)assoc.o \ -+ $(MGMT_DIR)auth.o \ -+ $(MGMT_DIR)bss.o \ -+ $(MGMT_DIR)cnm.o \ -+ $(MGMT_DIR)cnm_timer.o \ -+ $(MGMT_DIR)cnm_mem.o \ -+ $(MGMT_DIR)hem_mbox.o \ -+ $(MGMT_DIR)mib.o \ -+ $(MGMT_DIR)privacy.o \ -+ $(MGMT_DIR)rate.o \ -+ $(MGMT_DIR)rlm.o \ -+ $(MGMT_DIR)rlm_domain.o \ -+ $(MGMT_DIR)rlm_obss.o \ -+ $(MGMT_DIR)rlm_protection.o \ -+ $(MGMT_DIR)rsn.o \ -+ $(MGMT_DIR)saa_fsm.o \ -+ $(MGMT_DIR)scan.o \ -+ $(MGMT_DIR)scan_fsm.o \ -+ $(MGMT_DIR)sec_fsm.o \ -+ $(MGMT_DIR)swcr.o \ -+ $(MGMT_DIR)swcr.o \ -+ $(MGMT_DIR)roaming_fsm.o \ -+ $(MGMT_DIR)hs20.o -+ -+# --------------------------------------------------- -+# TDLS Objects List -+# --------------------------------------------------- -+MGMT_OBJS += $(MGMT_DIR)tdls.o \ -+ $(MGMT_DIR)tdls_com.o -+ -+# --------------------------------------------------- -+# STATS Objects List -+# --------------------------------------------------- -+MGMT_OBJS += $(MGMT_DIR)stats.o -+ -+# --------------------------------------------------- -+# P2P Objects List -+# --------------------------------------------------- -+ -+COMMON_OBJS += $(COMMON_DIR)wlan_p2p.o -+ -+NIC_OBJS += $(NIC_DIR)p2p_nic.o -+ -+OS_OBJS += $(OS_DIR)gl_p2p.o \ -+ $(OS_DIR)gl_p2p_cfg80211.o \ -+ $(OS_DIR)gl_p2p_init.o \ -+ $(OS_DIR)gl_p2p_kal.o -+ -+MGMT_OBJS += $(MGMT_DIR)p2p_assoc.o \ -+ $(MGMT_DIR)p2p_bss.o \ -+ $(MGMT_DIR)p2p_fsm.o \ -+ $(MGMT_DIR)p2p_func.o \ -+ $(MGMT_DIR)p2p_rlm.o \ -+ $(MGMT_DIR)p2p_rlm_obss.o \ -+ $(MGMT_DIR)p2p_scan.o \ -+ $(MGMT_DIR)p2p_ie.o \ -+ $(MGMT_DIR)p2p_state.o -+ -+ -+ifeq ($(CONFIG_MTK_WAPI_SUPPORT), y) -+MGMT_OBJS += $(MGMT_DIR)wapi.o -+endif -+ -+ifeq ($(WLAN_PROC), y) -+OS_OBJS += gl_proc.o -+endif -+ -+#$(warning $(CONFIG_MACH_MT7623)) -+ -+ifeq ($(CONFIG_MACH_MT7623), y) -+HIF_AHB_PDMA = $(HIF_DIR)mt8127/ -+endif -+HIF_OBJS := $(HIF_DIR)arm.o \ -+ $(HIF_DIR)ahb.o \ -+ $(HIF_AHB_PDMA)ahb_pdma.o -+ifeq ($(CONFIG_ARCH_MT6755), y) -+PLAT_OBJS := $(PLAT_DIR)plat_priv.o -+$(MODULE_NAME)-objs += $(PLAT_OBJS) -+endif -+$(MODULE_NAME)-objs += $(COMMON_OBJS) -+$(MODULE_NAME)-objs += $(NIC_OBJS) -+$(MODULE_NAME)-objs += $(OS_OBJS) -+$(MODULE_NAME)-objs += $(HIF_OBJS) -+$(MODULE_NAME)-objs += $(MGMT_OBJS) -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c -new file mode 100644 -index 0000000000000..e31e0b86d231e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c -@@ -0,0 +1,165 @@ -+#include "precomp.h" -+#include "gl_kal.h" -+ -+struct COMMAND { -+ UINT_8 ucCID; -+ BOOLEAN fgSetQuery; -+ BOOLEAN fgNeedResp; -+ UINT_8 ucCmdSeqNum; -+}; -+ -+struct SECURITY_FRAME { -+ UINT_16 u2EthType; -+ UINT_16 u2Reserved; -+}; -+ -+struct MGMT_FRAME { -+ UINT_16 u2FrameCtl; -+ UINT_16 u2DurationID; -+}; -+ -+struct TC_RES_RELEASE_ENTRY { -+ UINT_64 u8RelaseTime; -+ UINT_32 u4RelCID; -+ UINT_8 ucTc4RelCnt; -+ UINT_8 ucAvailableTc4; -+}; -+ -+struct CMD_TRACE_ENTRY { -+ UINT_64 u8TxTime; -+ COMMAND_TYPE eCmdType; -+ union { -+ struct COMMAND rCmd; -+ struct SECURITY_FRAME rSecFrame; -+ struct MGMT_FRAME rMgmtFrame; -+ } u; -+}; -+ -+#define TC_RELEASE_TRACE_BUF_MAX_NUM 100 -+#define TXED_CMD_TRACE_BUF_MAX_NUM 100 -+ -+static struct TC_RES_RELEASE_ENTRY *gprTcReleaseTraceBuffer; -+static struct CMD_TRACE_ENTRY *gprCmdTraceEntry; -+VOID wlanDebugInit(VOID) -+{ -+ /* debug for command/tc4 resource begin */ -+ gprTcReleaseTraceBuffer = -+ kalMemAlloc(TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY), PHY_MEM_TYPE); -+ kalMemZero(gprTcReleaseTraceBuffer, TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY)); -+ gprCmdTraceEntry = kalMemAlloc(TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY), PHY_MEM_TYPE); -+ kalMemZero(gprCmdTraceEntry, TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY)); -+ /* debug for command/tc4 resource end */ -+} -+ -+VOID wlanDebugUninit(VOID) -+{ -+ /* debug for command/tc4 resource begin */ -+ kalMemFree(gprTcReleaseTraceBuffer, PHY_MEM_TYPE, -+ TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY)); -+ kalMemFree(gprCmdTraceEntry, PHY_MEM_TYPE, TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY)); -+ /* debug for command/tc4 resource end */ -+} -+ -+VOID wlanTraceTxCmd(P_CMD_INFO_T prCmd) -+{ -+ static UINT_16 u2CurEntry; -+ struct CMD_TRACE_ENTRY *prCurCmd = &gprCmdTraceEntry[u2CurEntry]; -+ -+ prCurCmd->u8TxTime = sched_clock(); -+ prCurCmd->eCmdType = prCmd->eCmdType; -+ if (prCmd->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { -+ P_WLAN_MAC_MGMT_HEADER_T prMgmt = (P_WLAN_MAC_MGMT_HEADER_T)((P_MSDU_INFO_T)prCmd->prPacket)->prPacket; -+ -+ prCurCmd->u.rMgmtFrame.u2FrameCtl = prMgmt->u2FrameCtrl; -+ prCurCmd->u.rMgmtFrame.u2DurationID = prMgmt->u2Duration; -+ } else if (prCmd->eCmdType == COMMAND_TYPE_SECURITY_FRAME) { -+ PUINT_8 pucPkt = (PUINT_8)((struct sk_buff *)prCmd->prPacket)->data; -+ -+ prCurCmd->u.rSecFrame.u2EthType = -+ (pucPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pucPkt[ETH_TYPE_LEN_OFFSET + 1]); -+ } else { -+ prCurCmd->u.rCmd.ucCID = prCmd->ucCID; -+ prCurCmd->u.rCmd.ucCmdSeqNum = prCmd->ucCmdSeqNum; -+ prCurCmd->u.rCmd.fgNeedResp = prCmd->fgNeedResp; -+ prCurCmd->u.rCmd.fgSetQuery = prCmd->fgSetQuery; -+ } -+ u2CurEntry++; -+ if (u2CurEntry == TC_RELEASE_TRACE_BUF_MAX_NUM) -+ u2CurEntry = 0; -+} -+ -+VOID wlanTraceReleaseTcRes(P_ADAPTER_T prAdapter, PUINT_8 aucTxRlsCnt, UINT_8 ucAvailable) -+{ -+ static UINT_16 u2CurEntry; -+ struct TC_RES_RELEASE_ENTRY *prCurBuf = &gprTcReleaseTraceBuffer[u2CurEntry]; -+ -+ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &prCurBuf->u4RelCID); -+ prCurBuf->u8RelaseTime = sched_clock(); -+ prCurBuf->ucTc4RelCnt = aucTxRlsCnt[TC4_INDEX]; -+ prCurBuf->ucAvailableTc4 = ucAvailable; -+ u2CurEntry++; -+ if (u2CurEntry == TXED_CMD_TRACE_BUF_MAX_NUM) -+ u2CurEntry = 0; -+} -+ -+VOID wlanDumpTcResAndTxedCmd(PUINT_8 pucBuf, UINT_32 maxLen) -+{ -+ UINT_16 i = 0; -+ struct CMD_TRACE_ENTRY *prCmd = gprCmdTraceEntry; -+ struct TC_RES_RELEASE_ENTRY *prTcRel = gprTcReleaseTraceBuffer; -+ -+ if (pucBuf) { -+ int bufLen = 0; -+ -+ for (; i < TXED_CMD_TRACE_BUF_MAX_NUM/2; i++) { -+ bufLen = snprintf(pucBuf, maxLen, -+ "%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x\n", -+ i*2, prCmd[i*2].u8TxTime, prCmd[i*2].eCmdType, *(PUINT_32)(&prCmd[i*2].u.rCmd.ucCID), -+ i*2+1, prCmd[i*2+1].u8TxTime, prCmd[i*2+1].eCmdType, -+ *(PUINT_32)(&prCmd[i*2+1].u.rCmd.ucCID)); -+ if (bufLen <= 0 || (UINT_32)bufLen >= maxLen) -+ break; -+ pucBuf += bufLen; -+ maxLen -= bufLen; -+ } -+ for (i = 0; i < TC_RELEASE_TRACE_BUF_MAX_NUM/2; i++) { -+ bufLen = snprintf(pucBuf, maxLen, -+ "%d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d CID %08x\n", -+ i*2, prTcRel[i*2].u8RelaseTime, prTcRel[i*2].ucTc4RelCnt, prTcRel[i*2].ucAvailableTc4, -+ prTcRel[i*2].u4RelCID, -+ i*2+1, prTcRel[i*2+1].u8RelaseTime, prTcRel[i*2+1].ucTc4RelCnt, -+ prTcRel[i*2+1].ucAvailableTc4, prTcRel[i*2+1].u4RelCID); -+ if (bufLen <= 0 || (UINT_32)bufLen >= maxLen) -+ break; -+ pucBuf += bufLen; -+ maxLen -= bufLen; -+ } -+ return; -+ } -+ for (; i < TXED_CMD_TRACE_BUF_MAX_NUM/4; i++) { -+ LOG_FUNC("%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x; ", -+ i*4, prCmd[i*4].u8TxTime, prCmd[i*4].eCmdType, -+ *(PUINT_32)(&prCmd[i*4].u.rCmd.ucCID), -+ i*4+1, prCmd[i*4+1].u8TxTime, prCmd[i*4+1].eCmdType, -+ *(PUINT_32)(&prCmd[i*4+1].u.rCmd.ucCID)); -+ LOG_FUNC("%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x\n", -+ i*4+2, prCmd[i*4+2].u8TxTime, prCmd[i*4+2].eCmdType, -+ *(PUINT_32)(&prCmd[i*4+2].u.rCmd.ucCID), -+ i*4+3, prCmd[i*4+3].u8TxTime, prCmd[i*4+3].eCmdType, -+ *(PUINT_32)(&prCmd[i*4+3].u.rCmd.ucCID)); -+ } -+ for (i = 0; i < TC_RELEASE_TRACE_BUF_MAX_NUM/4; i++) { -+ LOG_FUNC( -+ "%d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x;", -+ i*4, prTcRel[i*4].u8RelaseTime, prTcRel[i*4].ucTc4RelCnt, -+ prTcRel[i*4].ucAvailableTc4, prTcRel[i*4].u4RelCID, -+ i*4+1, prTcRel[i*4+1].u8RelaseTime, prTcRel[i*4+1].ucTc4RelCnt, -+ prTcRel[i*4+1].ucAvailableTc4, prTcRel[i*4+1].u4RelCID); -+ LOG_FUNC( -+ " %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x\n", -+ i*4+2, prTcRel[i*4+2].u8RelaseTime, prTcRel[i*4+2].ucTc4RelCnt, -+ prTcRel[i*4+2].ucAvailableTc4, prTcRel[i*4+2].u4RelCID, -+ i*4+3, prTcRel[i*4+3].u8RelaseTime, prTcRel[i*4+3].ucTc4RelCnt, -+ prTcRel[i*4+3].ucAvailableTc4, prTcRel[i*4+3].u4RelCID); -+ } -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c -new file mode 100644 -index 0000000000000..486ba239f16a5 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c -@@ -0,0 +1,345 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/dump.c#1 -+*/ -+ -+/*! \file "dump.c" -+ \brief Provide memory dump function for debugging. -+ -+ Provide memory dump function for debugging. -+*/ -+ -+/* -+** Log: dump.c -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Using the new XLOG define for dum Memory. -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Add dumpMemory8 at XLOG support. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 19:58:51 GMT mtk01426 -+** Init develop -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to dump a segment of memory in bytes. -+* -+* \param[in] pucStartAddr Pointer to the starting address of the memory to be dumped. -+* \param[in] u4Length Length of the memory to be dumped. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID dumpMemory8(IN PUINT_8 pucStartAddr, IN UINT_32 u4Length) -+{ -+ ASSERT(pucStartAddr); -+ -+ LOG_FUNC("DUMP8 ADDRESS: %p, Length: %u\n", pucStartAddr, u4Length); -+ -+ while (u4Length > 0) { -+ if (u4Length >= 16) { -+ LOG_FUNC( -+ "(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], pucStartAddr[8], -+ pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], pucStartAddr[12], pucStartAddr[13], -+ pucStartAddr[14], pucStartAddr[15]); -+ u4Length -= 16; -+ pucStartAddr += 16; -+ } else { -+ switch (u4Length) { -+ case 1: -+ LOG_FUNC("(%p) %02x\n", pucStartAddr, pucStartAddr[0]); -+ break; -+ case 2: -+ LOG_FUNC("(%p) %02x %02x\n", pucStartAddr, pucStartAddr[0], pucStartAddr[1]); -+ break; -+ case 3: -+ LOG_FUNC("(%p) %02x %02x %02x\n", -+ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2]); -+ break; -+ case 4: -+ LOG_FUNC("(%p) %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3]); -+ break; -+ case 5: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4]); -+ break; -+ case 6: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5]); -+ break; -+ case 7: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6]); -+ break; -+ case 8: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7]); -+ break; -+ case 9: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8]); -+ break; -+ case 10: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9]); -+ break; -+ case 11: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10]); -+ break; -+ case 12: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11]); -+ break; -+ case 13: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], -+ pucStartAddr[12]); -+ break; -+ case 14: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], -+ pucStartAddr[12], pucStartAddr[13]); -+ break; -+ case 15: -+ LOG_FUNC( -+ "(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], -+ pucStartAddr[12], pucStartAddr[13], pucStartAddr[14]); -+ break; -+ /* -+ default: -+ break; -+ */ -+ } -+ u4Length = 0; -+ } -+ } -+ -+ LOG_FUNC("\n"); -+ -+} /* end of dumpMemory8() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to dump a segment of memory in double words. -+* -+* \param[in] pucStartAddr Pointer to the starting address of the memory to be dumped. -+* \param[in] u4Length Length of the memory to be dumped. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID dumpMemory32(IN PUINT_32 pu4StartAddr, IN UINT_32 u4Length) -+{ -+ PUINT_8 pucAddr; -+ -+ ASSERT(pu4StartAddr); -+ -+ LOG_FUNC("DUMP32 ADDRESS: %p, Length: %u\n", pu4StartAddr, u4Length); -+ -+ if (IS_NOT_ALIGN_4((ULONG) pu4StartAddr)) { -+ UINT_32 u4ProtrudeLen = sizeof(UINT_32) - ((ULONG) pu4StartAddr % 4); -+ -+ u4ProtrudeLen = ((u4Length < u4ProtrudeLen) ? u4Length : u4ProtrudeLen); -+ LOG_FUNC("pu4StartAddr is not at DW boundary.\n"); -+ pucAddr = (PUINT_8) &pu4StartAddr[0]; -+ -+ switch (u4ProtrudeLen) { -+ case 1: -+ LOG_FUNC("(%p) %02x------\n", pu4StartAddr, pucAddr[0]); -+ break; -+ case 2: -+ LOG_FUNC("(%p) %02x%02x----\n", pu4StartAddr, pucAddr[1], pucAddr[0]); -+ break; -+ case 3: -+ LOG_FUNC("(%p) %02x%02x%02x--\n", pu4StartAddr, pucAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ default: -+ break; -+ } -+ -+ u4Length -= u4ProtrudeLen; -+ pu4StartAddr = (PUINT_32) ((ULONG) pu4StartAddr + u4ProtrudeLen); -+ } -+ -+ while (u4Length > 0) { -+ if (u4Length >= 16) { -+ LOG_FUNC("(%p) %08x %08x %08x %08x\n", -+ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pu4StartAddr[3]); -+ pu4StartAddr += 4; -+ u4Length -= 16; -+ } else { -+ switch (u4Length) { -+ case 1: -+ pucAddr = (PUINT_8) &pu4StartAddr[0]; -+ LOG_FUNC("(%p) ------%02x\n", pu4StartAddr, pucAddr[0]); -+ break; -+ case 2: -+ pucAddr = (PUINT_8) &pu4StartAddr[0]; -+ LOG_FUNC("(%p) ----%02x%02x\n", pu4StartAddr, pucAddr[1], pucAddr[0]); -+ break; -+ case 3: -+ pucAddr = (PUINT_8) &pu4StartAddr[0]; -+ LOG_FUNC("(%p) --%02x%02x%02x\n", pu4StartAddr, pucAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ case 4: -+ LOG_FUNC("(%p) %08x\n", pu4StartAddr, pu4StartAddr[0]); -+ break; -+ case 5: -+ pucAddr = (PUINT_8) &pu4StartAddr[1]; -+ LOG_FUNC("(%p) %08x ------%02x\n", pu4StartAddr, pu4StartAddr[0], pucAddr[0]); -+ break; -+ case 6: -+ pucAddr = (PUINT_8) &pu4StartAddr[1]; -+ LOG_FUNC("(%p) %08x ----%02x%02x\n", -+ pu4StartAddr, pu4StartAddr[0], pucAddr[1], pucAddr[0]); -+ break; -+ case 7: -+ pucAddr = (PUINT_8) &pu4StartAddr[1]; -+ LOG_FUNC("(%p) %08x --%02x%02x%02x\n", -+ pu4StartAddr, pu4StartAddr[0], pucAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ case 8: -+ LOG_FUNC("(%p) %08x %08x\n", pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1]); -+ break; -+ case 9: -+ pucAddr = (PUINT_8) &pu4StartAddr[2]; -+ LOG_FUNC("(%p) %08x %08x ------%02x\n", -+ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pucAddr[0]); -+ break; -+ case 10: -+ pucAddr = (PUINT_8) &pu4StartAddr[2]; -+ LOG_FUNC("(%p) %08x %08x ----%02x%02x\n", -+ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pucAddr[1], pucAddr[0]); -+ break; -+ case 11: -+ pucAddr = (PUINT_8) &pu4StartAddr[2]; -+ LOG_FUNC("(%p) %08x %08x --%02x%02x%02x\n", -+ pu4StartAddr, -+ pu4StartAddr[0], pu4StartAddr[1], pucAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ case 12: -+ LOG_FUNC("(%p) %08x %08x %08x\n", -+ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2]); -+ break; -+ case 13: -+ pucAddr = (PUINT_8) &pu4StartAddr[3]; -+ LOG_FUNC("(%p) %08x %08x %08x ------%02x\n", -+ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pucAddr[0]); -+ break; -+ case 14: -+ pucAddr = (PUINT_8) &pu4StartAddr[3]; -+ LOG_FUNC("(%p) %08x %08x %08x ----%02x%02x\n", -+ pu4StartAddr, -+ pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ case 15: -+ pucAddr = (PUINT_8) &pu4StartAddr[3]; -+ LOG_FUNC("(%p) %08x %08x %08x --%02x%02x%02x\n", -+ pu4StartAddr, -+ pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], -+ pucAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ /* -+ default: -+ break; -+ */ -+ } -+ u4Length = 0; -+ } -+ } -+ -+} /* end of dumpMemory32() */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c -new file mode 100644 -index 0000000000000..21bd849827e17 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c -@@ -0,0 +1,3442 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_bow.c#1 -+*/ -+ -+/*! \file wlan_bow.c -+ \brief This file contains the 802.11 PAL commands processing routines for -+ MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_bow.c -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 16 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support BOW for 5GHz band. -+ * -+ * 01 09 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * [ALPS00110632] [Rose][LCA42][Cross Feature][Bluetooth]The "KE" pops up after the device reboots automatically.(once) -+ * -+ * Fix bow link disconnected event dereference. -+ * -+ * 09 29 2011 cm.chang -+ * NULL -+ * Change the function prototype of rlmDomainGetChnlList() -+ * -+ * 07 06 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Improve BoW connection establishment speed. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 21 2011 terry.wu -+ * NULL -+ * Fix BoW KE. -+ * -+ * 06 20 2011 terry.wu -+ * NULL -+ * Add BoW Rate Limitation. -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 06 17 2011 terry.wu -+ * NULL -+ * Add BoW 11N support. -+ * -+ * 06 07 2011 cp.wu -+ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction -+ * aware more compile options. -+ * -+ * 05 25 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add BoW Cancel Scan Request and Turn On deactive network function. -+ * -+ * 05 23 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add some BoW error handling. -+ * -+ * 05 22 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * . -+ * -+ * 05 22 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Only reply probe response to its peer or mached SSID for BoW AP. -+ * -+ * 05 22 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add BoW SAA retry and disable disconnect event when AAA fail . -+ * -+ * 05 21 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Protect BoW connection establishment. -+ * -+ * 05 17 2011 terry.wu -+ * [WCXRP00000730] [MT6620 Wi-Fi][BoW] Send deauth while disconnecting -+ * Send deauth while disconnecting BoW link. -+ * -+ * 05 17 2011 terry.wu -+ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue -+ * Fix wrong StaRec state of BoW . -+ * -+ * 05 06 2011 terry.wu -+ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue -+ * Fix BoW Multiple Physical Link connect/disconnect issue. -+ * -+ * 05 03 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Use kalMemAlloc to allocate event buffer for kalIndicateBOWEvent. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix prAssocRspSwRfb casting. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 04 12 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add WMM IE for BOW initiator data. -+ * -+ * 04 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Change Link disconnection event procedure for hotspot and change skb length check to 1514 bytes. -+ * -+ * 04 09 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Change Link connection event procedure and change skb length check to 1512 bytes. -+ * -+ * 03 28 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Simplify link disconnected routine, remove link disconnected other routine. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support multiple physical link. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add new feature - multiple physical link support. -+ * -+ * 02 22 2011 wh.su -+ * [WCXRP00000486] [MT6620 Wi-Fi][BOW] Fixed the bow send frame but not encrypted issue -+ * fixed the BOW packet sending without encrypted issue. -+ * -+ * 02 21 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix BOW link disconnection bug. -+ * -+ * 02 16 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add bowNotifyAllLinkDisconnected interface and change channel grant procedure for bow starting. -+ * -+ * 02 11 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update BOW channel granted function. -+ * -+ * 02 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix kernel API change issue. -+ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is -+ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); -+ * After ALPS 2.3, kfifo_alloc() is changed to -+ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); -+ * -+ * 02 09 2011 cp.wu -+ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3 -+ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031 -+ * with BOW and P2P enabled as default -+ * -+ * 02 08 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in. -+ * Update BOW get MAC status, remove returning event for AIS network type. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 11 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update BOW Activity Report structure and bug fix. -+ * -+ * 01 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update BOW to support multiple physical link. -+ * -+ * 12 08 2010 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support concurrent networks. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 11 11 2010 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix BoW timer assert issue. -+ * -+ * 10 18 2010 chinghwa.yu -+ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size -+ * Fix for event returnning Band. -+ * -+ * 10 18 2010 chinghwa.yu -+ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size -+ * Fix wrong BoW event size. -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced -+ * by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 16 2010 chinghwa.yu -+ * NULL -+ * Fix bowResponderScanDone error when prBssDesc is NULL. -+ * -+ * 09 14 2010 chinghwa.yu -+ * NULL -+ * Add bowRunEventAAAComplete. -+ * -+ * 09 14 2010 cp.wu -+ * NULL -+ * indicate correct AIS network information for PAL. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Initialize nicActivateNetwork(prAdapter as soon as bow is starting.. -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update BOW for the 1st time. -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 15 2010 cp.wu -+ * -+ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add NULL OID implementation for WOL-related OIDs. -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * 1) all BT physical handles shares the same RSSI/Link Quality. -+ * 2) simplify BT command composing -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * 2) command sequence number is now increased atomically -+ * * 3) private data could be hold and taken use for other purpose -+** -+*/ -+ -+/****************************************************************************** -+* C O M P I L E R F L A G S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************* -+*/ -+#include "precomp.h" -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ -+/****************************************************************************** -+* C O N S T A N T S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* D A T A T Y P E S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* P U B L I C D A T A -+******************************************************************************* -+*/ -+ -+static UINT_32 g_u4LinkCount; -+static UINT_32 g_u4Beaconing; -+static BOW_TABLE_T arBowTable[CFG_BOW_PHYSICAL_LINK_NUM]; -+ -+/****************************************************************************** -+* P R I V A T E D A T A -+******************************************************************************* -+*/ -+ -+const BOW_CMD_T arBowCmdTable[] = { -+ {BOW_CMD_ID_GET_MAC_STATUS, bowCmdGetMacStatus}, -+ {BOW_CMD_ID_SETUP_CONNECTION, bowCmdSetupConnection}, -+ {BOW_CMD_ID_DESTROY_CONNECTION, bowCmdDestroyConnection}, -+ {BOW_CMD_ID_SET_PTK, bowCmdSetPTK}, -+ {BOW_CMD_ID_READ_RSSI, bowCmdReadRSSI}, -+ {BOW_CMD_ID_READ_LINK_QUALITY, bowCmdReadLinkQuality}, -+ {BOW_CMD_ID_SHORT_RANGE_MODE, bowCmdShortRangeMode}, -+ {BOW_CMD_ID_GET_CHANNEL_LIST, bowCmdGetChannelList}, -+}; -+ -+/****************************************************************************** -+* M A C R O S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N S -+******************************************************************************* -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command packet generation utility -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] ucCID Command ID -+* \param[in] fgSetQuery Set or Query -+* \param[in] fgNeedResp Need for response -+* \param[in] pfCmdDoneHandler Function pointer when command is done -+* \param[in] u4SetQueryInfoLen The length of the set/query buffer -+* \param[in] pucInfoBuffer Pointer to set/query buffer -+* -+* -+* \retval WLAN_STATUS_PENDING -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendSetQueryBowCmd(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucCID, -+ IN BOOLEAN fgSetQuery, -+ IN BOOLEAN fgNeedResp, -+ IN PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ IN PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ IN UINT_32 u4SetQueryInfoLen, IN PUINT_8 pucInfoBuffer, IN UINT_8 ucSeqNumber) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_8 ucCmdSeqNum; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "Command ID = 0x%08X\n", ucCID); -+ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_BOW_INDEX; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen); -+ prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; -+ prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = ucCID; -+ prCmdInfo->fgSetQuery = fgSetQuery; -+ prCmdInfo->fgNeedResp = fgNeedResp; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; -+ prCmdInfo->pvInformationBuffer = NULL; -+ prCmdInfo->u4InformationBufferLength = 0; -+ prCmdInfo->u4PrivateData = (UINT_32) ucSeqNumber; -+ -+ /* Setup WIFI_CMD_T (no payload) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) -+ kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen); -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ return WLAN_STATUS_PENDING; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to dispatch command coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanbowHandleCommand(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ WLAN_STATUS retval = WLAN_STATUS_FAILURE; -+ UINT_16 i; -+ -+ ASSERT(prAdapter); -+ -+ for (i = 0; i < sizeof(arBowCmdTable) / sizeof(BOW_CMD_T); i++) { -+ if ((arBowCmdTable[i].uCmdID == prCmd->rHeader.ucCommandId) && arBowCmdTable[i].pfCmdHandle) { -+ retval = arBowCmdTable[i].pfCmdHandle(prAdapter, prCmd); -+ break; -+ } -+ } -+ -+ return retval; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_GET_MAC_STATUS -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdGetMacStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_MAC_STATUS prMacStatus; -+ UINT_8 idx = 0; -+ UINT_8 ucPrimaryChannel; -+ ENUM_BAND_T eBand; -+ ENUM_CHNL_EXT_T eBssSCO; -+ UINT_8 ucNumOfChannel = 0; /* MAX_BOW_NUMBER_OF_CHANNEL; */ -+ -+ RF_CHANNEL_INFO_T aucChannelList[MAX_BOW_NUMBER_OF_CHANNEL]; -+ -+ ASSERT(prAdapter); -+ -+ /* 3 <1> If LinkCount != 0 -> OK (optional) */ -+ -+ eBand = BAND_2G4; -+ eBssSCO = CHNL_EXT_SCN; -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_MAC_STATUS)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return WLAN_STATUS_FAILURE; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_MAC_STATUS; -+ prEvent->rHeader.ucSeqNumber = prCmd->rHeader.ucSeqNumber; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_MAC_STATUS); -+ -+ /* fill event body */ -+ prMacStatus = (P_BOW_MAC_STATUS) (prEvent->aucPayload); -+ kalMemZero(prMacStatus, sizeof(BOW_MAC_STATUS)); -+ -+ /* 3 <2> Call CNM to decide if BOW available. */ -+ if (cnmBowIsPermitted(prAdapter)) -+ prMacStatus->ucAvailability = TRUE; -+ else -+ prMacStatus->ucAvailability = FALSE; -+ -+ memcpy(prMacStatus->aucMacAddr, prAdapter->rWifiVar.aucDeviceAddress, PARAM_MAC_ADDR_LEN); -+ -+ if (cnmPreferredChannel(prAdapter, &eBand, &ucPrimaryChannel, &eBssSCO)) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, "bowCmdGetMacStatus, Get preferred channel.\n"); -+#endif -+ -+ prMacStatus->ucNumOfChannel = 1; -+ prMacStatus->arChannelList[0].ucChannelBand = eBand; -+ prMacStatus->arChannelList[0].ucChannelNum = ucPrimaryChannel; -+ } else { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, -+ "bowCmdGetMacStatus, Get channel list. Current number of channel, %d.\n", ucNumOfChannel); -+#endif -+ -+ rlmDomainGetChnlList(prAdapter, BAND_2G4, FALSE, MAX_BOW_NUMBER_OF_CHANNEL_2G4, -+ &ucNumOfChannel, aucChannelList); -+ -+ if (ucNumOfChannel > 0) { -+ for (idx = 0; idx < ucNumOfChannel; idx++) { -+ prMacStatus->arChannelList[idx].ucChannelBand = aucChannelList[idx].eBand; -+ prMacStatus->arChannelList[idx].ucChannelNum = aucChannelList[idx].ucChannelNum; -+ } -+ -+ prMacStatus->ucNumOfChannel = ucNumOfChannel; -+ } -+ -+ rlmDomainGetChnlList(prAdapter, BAND_5G, FALSE, MAX_BOW_NUMBER_OF_CHANNEL_5G, -+ &ucNumOfChannel, aucChannelList); -+ -+ if (ucNumOfChannel > 0) { -+ for (idx = 0; idx < ucNumOfChannel; idx++) { -+ prMacStatus->arChannelList[prMacStatus->ucNumOfChannel + idx].ucChannelBand = -+ aucChannelList[idx].eBand; -+ prMacStatus->arChannelList[prMacStatus->ucNumOfChannel + idx].ucChannelNum = -+ aucChannelList[idx].ucChannelNum; -+ } -+ -+ prMacStatus->ucNumOfChannel = prMacStatus->ucNumOfChannel + ucNumOfChannel; -+ -+ } -+ } -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, -+ "ucNumOfChannel,eBand,aucChannelList,%x,%x,%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", -+ ucNumOfChannel, aucChannelList[0].eBand, aucChannelList[0].ucChannelNum, aucChannelList[1].ucChannelNum, -+ aucChannelList[2].ucChannelNum, aucChannelList[3].ucChannelNum, aucChannelList[4].ucChannelNum, -+ aucChannelList[5].ucChannelNum, aucChannelList[6].ucChannelNum, aucChannelList[7].ucChannelNum, -+ aucChannelList[8].ucChannelNum, aucChannelList[9].ucChannelNum, aucChannelList[10].ucChannelNum, -+ aucChannelList[11].ucChannelNum, aucChannelList[12].ucChannelNum, aucChannelList[13].ucChannelNum, -+ aucChannelList[14].ucChannelNum, aucChannelList[15].ucChannelNum, aucChannelList[16].ucChannelNum, -+ aucChannelList[17].ucChannelNum)); -+ -+ DBGLOG(BOW, TRACE, -+ "prMacStatus->ucNumOfChannel, eBand, %x, %x.\n", -+ prMacStatus->ucNumOfChannel, prMacStatus->arChannelList[0].ucChannelBand); -+ DBGLOG(BOW, TRACE, -+ "prMacStatus->arChannelList, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", -+ prMacStatus->arChannelList[0].ucChannelNum, prMacStatus->arChannelList[1].ucChannelNum, -+ prMacStatus->arChannelList[2].ucChannelNum, prMacStatus->arChannelList[3].ucChannelNum, -+ prMacStatus->arChannelList[4].ucChannelNum, prMacStatus->arChannelList[5].ucChannelNum, -+ prMacStatus->arChannelList[6].ucChannelNum, prMacStatus->arChannelList[7].ucChannelNum, -+ prMacStatus->arChannelList[8].ucChannelNum, prMacStatus->arChannelList[9].ucChannelNum, -+ prMacStatus->arChannelList[10].ucChannelNum, prMacStatus->arChannelList[11].ucChannelNum, -+ prMacStatus->arChannelList[12].ucChannelNum, prMacStatus->arChannelList[13].ucChannelNum, -+ prMacStatus->arChannelList[14].ucChannelNum, prMacStatus->arChannelList[15].ucChannelNum, -+ prMacStatus->arChannelList[16].ucChannelNum, prMacStatus->arChannelList[17].ucChannelNum)); -+ -+ DBGLOG(BOW, TRACE, "prMacStatus->ucNumOfChannel, %x.\n", prMacStatus->ucNumOfChannel); -+ DBGLOG(BOW, TRACE, -+ "prMacStatus->arChannelList[0].ucChannelBand, %x.\n", prMacStatus->arChannelList[0].ucChannelBand); -+ DBGLOG(BOW, TRACE, -+ "prMacStatus->arChannelList[0].ucChannelNum, %x.\n", prMacStatus->arChannelList[0].ucChannelNum); -+ DBGLOG(BOW, TRACE, "prMacStatus->ucAvailability, %x.\n", prMacStatus->ucAvailability); -+ DBGLOG(BOW, TRACE, "prMacStatus->aucMacAddr, %x:%x:%x:%x:%x:%x.\n", -+ prMacStatus->aucMacAddr[0], -+ prMacStatus->aucMacAddr[1], -+ prMacStatus->aucMacAddr[2], -+ prMacStatus->aucMacAddr[3], prMacStatus->aucMacAddr[4], prMacStatus->aucMacAddr[5])); -+#endif -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_MAC_STATUS))); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_SETUP_CONNECTION -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdSetupConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_SETUP_CONNECTION prBowSetupConnection; -+ CMD_BT_OVER_WIFI rCmdBtOverWifi; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ BOW_TABLE_T rBowTable; -+ -+ UINT_8 ucBowTableIdx = 0; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBowSetupConnection = (P_BOW_SETUP_CONNECTION) &(prCmd->aucPayload[0]); -+ -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SETUP_CONNECTION)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_INVALID); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ /* 3 <1> If ucLinkCount >= 4 -> Fail. */ -+ if (g_u4LinkCount >= CFG_BOW_PHYSICAL_LINK_NUM) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ /* 3 <2> Call CNM, check if BOW is available. */ -+ if (!cnmBowIsPermitted(prAdapter)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ /* 3 <3> Lookup BOW Table, if Peer MAC address exist and valid -> Fail. */ -+ if (bowCheckBowTableIfVaild(prAdapter, prBowSetupConnection->aucPeerAddress)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ -+ if (EQUAL_MAC_ADDR(prBowSetupConnection->aucPeerAddress, prAdapter->rWifiVar.aucDeviceAddress)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_INVALID); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ /* fill CMD_BT_OVER_WIFI */ -+ rCmdBtOverWifi.ucAction = BOW_SETUP_CMD; -+ rCmdBtOverWifi.ucChannelNum = prBowSetupConnection->ucChannelNum; -+ COPY_MAC_ADDR(rCmdBtOverWifi.rPeerAddr, prBowSetupConnection->aucPeerAddress); -+ rCmdBtOverWifi.u2BeaconInterval = prBowSetupConnection->u2BeaconInterval; -+ rCmdBtOverWifi.ucTimeoutDiscovery = prBowSetupConnection->ucTimeoutDiscovery; -+ rCmdBtOverWifi.ucTimeoutInactivity = prBowSetupConnection->ucTimeoutInactivity; -+ rCmdBtOverWifi.ucRole = prBowSetupConnection->ucRole; -+ rCmdBtOverWifi.PAL_Capabilities = prBowSetupConnection->ucPAL_Capabilities; -+ rCmdBtOverWifi.cMaxTxPower = prBowSetupConnection->cMaxTxPower; -+ -+ if (prBowSetupConnection->ucChannelNum > 14) -+ rCmdBtOverWifi.ucChannelBand = BAND_5G; -+ else -+ rCmdBtOverWifi.ucChannelBand = BAND_2G4; -+ -+ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prBowSetupConnection->aucPeerAddress); -+ -+#if CFG_BOW_PHYSICAL_LINK_NUM > 1 -+ /*Channel check for supporting multiple physical link */ -+ if (g_u4LinkCount > 0) { -+ if (prBowSetupConnection->ucChannelNum != prBowFsmInfo->ucPrimaryChannel) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ } -+#endif -+ -+ prBowFsmInfo->ucPrimaryChannel = prBowSetupConnection->ucChannelNum; -+ prBowFsmInfo->eBand = rCmdBtOverWifi.ucChannelBand; -+ prBowFsmInfo->u2BeaconInterval = prBowSetupConnection->u2BeaconInterval; -+ prBowFsmInfo->ucRole = prBowSetupConnection->ucRole; -+ -+ if (prBowSetupConnection->ucPAL_Capabilities > 0) -+ prBowFsmInfo->fgSupportQoS = TRUE; -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowCmdSetupConnection.\n"); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Channel Number - 0x%x.\n", rCmdBtOverWifi.ucChannelNum); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Peer address - %x:%x:%x:%x:%x:%x.\n", rCmdBtOverWifi.rPeerAddr[0], -+ rCmdBtOverWifi.rPeerAddr[1], -+ rCmdBtOverWifi.rPeerAddr[2], -+ rCmdBtOverWifi.rPeerAddr[3], rCmdBtOverWifi.rPeerAddr[4], rCmdBtOverWifi.rPeerAddr[5]); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Beacon interval - 0x%x.\n", rCmdBtOverWifi.u2BeaconInterval); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Timeout activity - 0x%x.\n", rCmdBtOverWifi.ucTimeoutDiscovery); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Timeout inactivity - 0x%x.\n", rCmdBtOverWifi.ucTimeoutInactivity); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Role - 0x%x.\n", rCmdBtOverWifi.ucRole); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi PAL capability - 0x%x.\n", rCmdBtOverWifi.PAL_Capabilities); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Max Tx power - 0x%x.\n", rCmdBtOverWifi.cMaxTxPower); -+#endif -+ -+ /* 3 <4> Get a free BOW entry, mark as Valid, fill in Peer MAC address, LinkCount += 1, state == Starting. */ -+ if (!bowGetBowTableFreeEntry(prAdapter, &ucBowTableIdx)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ -+ prBowFsmInfo->prTargetBssDesc = NULL; -+ -+ kalMemZero(&rBowTable, sizeof(BOW_TABLE_T)); -+ -+ COPY_MAC_ADDR(rBowTable.aucPeerAddress, prBowSetupConnection->aucPeerAddress); -+ /* owTable.eState = BOW_DEVICE_STATE_ACQUIRING_CHANNEL; */ -+ rBowTable.fgIsValid = TRUE; -+ rBowTable.ucAcquireID = prBowFsmInfo->ucSeqNumOfChReq; -+ /* rBowTable.ucRole = prBowSetupConnection->ucRole; */ -+ /* rBowTable.ucChannelNum = prBowSetupConnection->ucChannelNum; */ -+ bowSetBowTableContent(prAdapter, ucBowTableIdx, &rBowTable); -+ -+ kalSetBowRole(prAdapter->prGlueInfo, rCmdBtOverWifi.ucRole, prBowSetupConnection->aucPeerAddress); -+ -+ GLUE_INC_REF_CNT(g_u4LinkCount); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowStarting, g_u4LinkCount, %x.\n", g_u4LinkCount); -+#endif -+ -+ if (g_u4LinkCount == 1) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowStarting, cnmTimerInitTimer.\n"); -+ DBGLOG(BOW, EVENT, "prBowFsmInfo->u2BeaconInterval, %d.\n", prBowFsmInfo->u2BeaconInterval); -+#endif -+ cnmTimerInitTimer(prAdapter, -+ &prBowFsmInfo->rStartingBeaconTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) bowSendBeacon, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prBowFsmInfo->rChGrantedTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) bowChGrantedTimeout, (ULONG) NULL); -+ -+ /* Reset Global Variable */ -+ g_u4Beaconing = 0; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowCmdSetupConnection, g_u4LinkCount, %x.\n", g_u4LinkCount); -+ DBGLOG(BOW, EVENT, "kalInitBowDevice, bow0\n"); -+#endif -+#if CFG_BOW_SEPARATE_DATA_PATH -+ kalInitBowDevice(prAdapter->prGlueInfo, BOWDEVNAME); -+#endif -+ -+ /*Active BoW Network */ -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ } -+ -+ if (rCmdBtOverWifi.ucRole == BOW_INITIATOR) { -+ bowSetBowTableState(prAdapter, prBowSetupConnection->aucPeerAddress, -+ BOW_DEVICE_STATE_ACQUIRING_CHANNEL); -+ bowRequestCh(prAdapter); -+ } else { -+ bowSetBowTableState(prAdapter, prBowSetupConnection->aucPeerAddress, BOW_DEVICE_STATE_SCANNING); -+ bowResponderScan(prAdapter); -+ } -+ -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_DESTROY_CONNECTION -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdDestroyConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_DESTROY_CONNECTION prBowDestroyConnection; -+ CMD_BT_OVER_WIFI rCmdBtOverWifi; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+#if CFG_BOW_TEST -+ UINT_8 ucIdx; -+#endif -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ /* 3 <1> If LinkCount == 0 ->Fail (Optional) */ -+ if (g_u4LinkCount == 0) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_DESTROY_CONNECTION)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ /* 3 <2> Lookup BOW table, check if is not exist (Valid and Peer MAC address) -> Fail */ -+ prBowDestroyConnection = (P_BOW_DESTROY_CONNECTION) &(prCmd->aucPayload[0]); -+ -+ if (!bowCheckBowTableIfVaild(prAdapter, prBowDestroyConnection->aucPeerAddress)) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowCmdDestroyConnection, bowCheckIfVaild, not accepted.\n"); -+#endif -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "bowCmdDestroyConnection, destroy Peer address - %x:%x:%x:%x:%x:%x.\n", -+ prBowDestroyConnection->aucPeerAddress[0], prBowDestroyConnection->aucPeerAddress[1], -+ prBowDestroyConnection->aucPeerAddress[2], prBowDestroyConnection->aucPeerAddress[3], -+ prBowDestroyConnection->aucPeerAddress[4], prBowDestroyConnection->aucPeerAddress[5])); -+#endif -+ -+ /* fill CMD_BT_OVER_WIFI */ -+ rCmdBtOverWifi.ucAction = 2; -+ COPY_MAC_ADDR(rCmdBtOverWifi.rPeerAddr, prBowDestroyConnection->aucPeerAddress); -+ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prBowDestroyConnection->aucPeerAddress); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "bowCmdDestroyConnection, rCmdBtOverWifi.rPeerAddr - %x:%x:%x:%x:%x:%x.\n", rCmdBtOverWifi.rPeerAddr[0], -+ rCmdBtOverWifi.rPeerAddr[1], rCmdBtOverWifi.rPeerAddr[2], rCmdBtOverWifi.rPeerAddr[3], -+ rCmdBtOverWifi.rPeerAddr[4], rCmdBtOverWifi.rPeerAddr[5]); -+#endif -+ -+#if CFG_BOW_TEST -+ for (ucIdx = 0; ucIdx < 11; ucIdx++) { -+ DBGLOG(BOW, EVENT, -+ "BoW receiving PAL packet delta time vs packet number -- %d ms vs %x.\n", ucIdx, -+ g_arBowRevPalPacketTime[ucIdx]); -+ } -+#endif -+ -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); -+ -+ return wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkDisconnected, -+ wlanbowCmdTimeoutHandler, -+ sizeof(CMD_BT_OVER_WIFI), -+ (PUINT_8)&rCmdBtOverWifi, prCmd->rHeader.ucSeqNumber); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_SET_PTK -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdSetPTK(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_SET_PTK prBowSetPTK; -+ CMD_802_11_KEY rCmdKey; -+ -+ ASSERT(prAdapter); -+ -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SET_PTK)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prBowSetPTK = (P_BOW_SET_PTK) &(prCmd->aucPayload[0]); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prBowSetPTK->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowSetPTK->aucPeerAddress[0], -+ prBowSetPTK->aucPeerAddress[1], -+ prBowSetPTK->aucPeerAddress[2], -+ prBowSetPTK->aucPeerAddress[3], -+ prBowSetPTK->aucPeerAddress[4], prBowSetPTK->aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "rCmdKey.ucIsAuthenticator, %x.\n", kalGetBowRole(prAdapter->prGlueInfo, prBowSetPTK->aucPeerAddress)); -+#endif -+ -+ if (!bowCheckBowTableIfVaild(prAdapter, prBowSetPTK->aucPeerAddress)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ -+ if (bowGetBowTableState(prAdapter, prBowSetPTK->aucPeerAddress) != BOW_DEVICE_STATE_CONNECTED) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); -+ -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ /* fill CMD_802_11_KEY */ -+ rCmdKey.ucAddRemove = 1; /* add */ -+ rCmdKey.ucTxKey = 1; -+ rCmdKey.ucKeyType = 1; -+ rCmdKey.ucIsAuthenticator = kalGetBowRole(prAdapter->prGlueInfo, prBowSetPTK->aucPeerAddress); -+ COPY_MAC_ADDR(rCmdKey.aucPeerAddr, prBowSetPTK->aucPeerAddress); -+ rCmdKey.ucNetType = NETWORK_TYPE_BOW_INDEX; /* BT Over Wi-Fi */ -+ rCmdKey.ucAlgorithmId = CIPHER_SUITE_CCMP; /* AES */ -+ rCmdKey.ucKeyId = 0; -+ rCmdKey.ucKeyLen = 16; /* AES = 128bit */ -+ kalMemCopy(rCmdKey.aucKeyMaterial, prBowSetPTK->aucTemporalKey, 16); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prBowSetPTK->aucTemporalKey, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", -+ prBowSetPTK->aucTemporalKey[0], -+ prBowSetPTK->aucTemporalKey[1], -+ prBowSetPTK->aucTemporalKey[2], -+ prBowSetPTK->aucTemporalKey[3], -+ prBowSetPTK->aucTemporalKey[4], -+ prBowSetPTK->aucTemporalKey[5], -+ prBowSetPTK->aucTemporalKey[6], -+ prBowSetPTK->aucTemporalKey[7], -+ prBowSetPTK->aucTemporalKey[8], -+ prBowSetPTK->aucTemporalKey[9], -+ prBowSetPTK->aucTemporalKey[10], -+ prBowSetPTK->aucTemporalKey[11], -+ prBowSetPTK->aucTemporalKey[12], -+ prBowSetPTK->aucTemporalKey[13], -+ prBowSetPTK->aucTemporalKey[14], prBowSetPTK->aucTemporalKey[15])); -+ -+ DBGLOG(BOW, EVENT, "rCmdKey.aucKeyMaterial, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", -+ rCmdKey.aucKeyMaterial[0], -+ rCmdKey.aucKeyMaterial[1], -+ rCmdKey.aucKeyMaterial[2], -+ rCmdKey.aucKeyMaterial[3], -+ rCmdKey.aucKeyMaterial[4], -+ rCmdKey.aucKeyMaterial[5], -+ rCmdKey.aucKeyMaterial[6], -+ rCmdKey.aucKeyMaterial[7], -+ rCmdKey.aucKeyMaterial[8], -+ rCmdKey.aucKeyMaterial[9], -+ rCmdKey.aucKeyMaterial[10], -+ rCmdKey.aucKeyMaterial[11], -+ rCmdKey.aucKeyMaterial[12], -+ rCmdKey.aucKeyMaterial[13], rCmdKey.aucKeyMaterial[14], rCmdKey.aucKeyMaterial[15])); -+#endif -+ -+ return wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_ADD_REMOVE_KEY, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventSetCommon, -+ wlanbowCmdTimeoutHandler, -+ sizeof(CMD_802_11_KEY), (PUINT_8)&rCmdKey, prCmd->rHeader.ucSeqNumber); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_READ_RSSI -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdReadRSSI(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_READ_RSSI prBowReadRSSI; -+ -+ ASSERT(prAdapter); -+ -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_READ_RSSI)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prBowReadRSSI = (P_BOW_READ_RSSI) &(prCmd->aucPayload[0]); -+ -+ return wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ wlanbowCmdEventReadRssi, -+ wlanbowCmdTimeoutHandler, 0, NULL, prCmd->rHeader.ucSeqNumber); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_READ_LINK_QUALITY -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_READ_LINK_QUALITY prBowReadLinkQuality; -+ -+ ASSERT(prAdapter); -+ -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(P_BOW_READ_LINK_QUALITY)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prBowReadLinkQuality = (P_BOW_READ_LINK_QUALITY) &(prCmd->aucPayload[0]); -+ -+ return wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ wlanbowCmdEventReadLinkQuality, -+ wlanbowCmdTimeoutHandler, 0, NULL, prCmd->rHeader.ucSeqNumber); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_SHORT_RANGE_MODE -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdShortRangeMode(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_SHORT_RANGE_MODE prBowShortRangeMode; -+ CMD_TX_PWR_T rTxPwrParam; -+ -+ ASSERT(prAdapter); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowCmdShortRangeMode.\n"); -+#endif -+ -+ prBowShortRangeMode = (P_BOW_SHORT_RANGE_MODE) &(prCmd->aucPayload[0]); -+ -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SHORT_RANGE_MODE)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ if (!bowCheckBowTableIfVaild(prAdapter, prBowShortRangeMode->aucPeerAddress)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ -+ if (bowGetBowTableState(prAdapter, prBowShortRangeMode->aucPeerAddress) != BOW_DEVICE_STATE_CONNECTED) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prBowShortRangeMode->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowShortRangeMode->aucPeerAddress[0], -+ prBowShortRangeMode->aucPeerAddress[1], -+ prBowShortRangeMode->aucPeerAddress[2], -+ prBowShortRangeMode->aucPeerAddress[3], -+ prBowShortRangeMode->aucPeerAddress[4], prBowShortRangeMode->aucPeerAddress[5])); -+#endif -+ -+ rTxPwrParam.cTxPwr2G4Cck = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr2G4OFDM_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4OFDM_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4OFDM_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr2G4OFDM_48Mbps = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4OFDM_54Mbps = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr2G4HT20_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT20_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT20_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT20_MCS5 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT20_MCS6 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT20_MCS7 = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr2G4HT40_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT40_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT40_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT40_MCS5 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT40_MCS6 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT40_MCS7 = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr5GOFDM_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GOFDM_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GOFDM_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GOFDM_48Mbps = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GOFDM_54Mbps = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr5GHT20_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT20_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT20_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT20_MCS5 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT20_MCS6 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT20_MCS7 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_MCS5 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_MCS6 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_MCS7 = (prBowShortRangeMode->cTxPower << 1); -+ -+ if (nicUpdateTxPower(prAdapter, &rTxPwrParam) == WLAN_STATUS_SUCCESS) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowCmdShortRangeMode, %x.\n", WLAN_STATUS_SUCCESS); -+#endif -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); -+ return WLAN_STATUS_SUCCESS; -+ } -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); -+ return WLAN_STATUS_FAILURE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_GET_CHANNEL_LIST -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdGetChannelList(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ ASSERT(prAdapter); -+ -+ /* not supported yet */ -+ return WLAN_STATUS_FAILURE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is generic command done handler -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventSetStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd, IN UINT_8 ucEventBuf) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_COMMAND_STATUS prBowCmdStatus; -+ -+ ASSERT(prAdapter); -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; -+ prEvent->rHeader.ucSeqNumber = prCmd->rHeader.ucSeqNumber; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); -+ -+ /* fill event body */ -+ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); -+ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); -+ -+ prBowCmdStatus->ucStatus = ucEventBuf; -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is generic command done handler -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_COMMAND_STATUS prBowCmdStatus; -+ -+ ASSERT(prAdapter); -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); -+ -+ /* fill event body */ -+ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); -+ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); -+ -+ prBowCmdStatus->ucStatus = BOWCMD_STATUS_SUCCESS; -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventLinkConnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_LINK_CONNECTED prBowLinkConnected; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_CONNECTED)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED); -+ -+ /* fill event body */ -+ prBowLinkConnected = (P_BOW_LINK_CONNECTED) (prEvent->aucPayload); -+ kalMemZero(prBowLinkConnected, sizeof(BOW_LINK_CONNECTED)); -+ prBowLinkConnected->rChannel.ucChannelNum = prBssInfo->ucPrimaryChannel; -+ prBowLinkConnected->rChannel.ucChannelBand = prBssInfo->eBand; -+ COPY_MAC_ADDR(prBowLinkConnected->aucPeerAddress, prBowFsmInfo->aucPeerAddress); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucEventId, 0x%x\n", prEvent->rHeader.ucEventId); -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucSeqNumber, 0x%x\n", prEvent->rHeader.ucSeqNumber); -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.u2PayloadLength, 0x%x\n", prEvent->rHeader.u2PayloadLength); -+ DBGLOG(BOW, EVENT, -+ "prBowLinkConnected->rChannel.ucChannelNum, 0x%x\n", prBowLinkConnected->rChannel.ucChannelNum); -+ DBGLOG(BOW, EVENT, -+ "prBowLinkConnected->rChannel.ucChannelBand, 0x%x\n", prBowLinkConnected->rChannel.ucChannelBand); -+ DBGLOG(BOW, EVENT, -+ "wlanbowCmdEventLinkConnected, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowFsmInfo->aucPeerAddress[0], prBowFsmInfo->aucPeerAddress[1], prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5]); -+ DBGLOG(BOW, EVENT, -+ "wlanbowCmdEventLinkConnected, prBowLinkConnected->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowLinkConnected->aucPeerAddress[0], prBowLinkConnected->aucPeerAddress[1], -+ prBowLinkConnected->aucPeerAddress[2], prBowLinkConnected->aucPeerAddress[3], -+ prBowLinkConnected->aucPeerAddress[4], prBowLinkConnected->aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkConnected, g_u4LinkCount, %x.\n", g_u4LinkCount); -+#endif -+ -+ /*Indicate Event to PAL */ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_CONNECTED))); -+ -+ /*Release channel if granted */ -+ if (prBowFsmInfo->fgIsChannelGranted) { -+ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); -+ /* bowReleaseCh(prAdapter); */ -+ /*Requested, not granted yet */ -+ } else if (prBowFsmInfo->fgIsChannelRequested) { -+ prBowFsmInfo->fgIsChannelRequested = FALSE; -+ } -+ -+ /* set to connected status */ -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_CONNECTED); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventLinkDisconnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_LINK_DISCONNECTED prBowLinkDisconnected; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ BOW_TABLE_T rBowTable; -+ UINT_8 ucBowTableIdx; -+ ENUM_BOW_DEVICE_STATE eFsmState; -+ BOOLEAN fgSendDeauth = FALSE; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); -+ -+ if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { -+ /*do nothing */ -+ return; -+ } -+ /*Cancel scan */ -+ else if (eFsmState == BOW_DEVICE_STATE_SCANNING && !(prBowFsmInfo->fgIsChannelRequested)) { -+ bowResponderCancelScan(prAdapter, FALSE); -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_DISCONNECTING); -+ return; -+ } -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED; -+ if ((prCmdInfo->u4PrivateData)) -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ else -+ prEvent->rHeader.ucSeqNumber = 0; -+ -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED); -+ -+ /* fill event body */ -+ prBowLinkDisconnected = (P_BOW_LINK_DISCONNECTED) (prEvent->aucPayload); -+ kalMemZero(prBowLinkDisconnected, sizeof(BOW_LINK_DISCONNECTED)); -+ prBowLinkDisconnected->ucReason = 0x0; -+ COPY_MAC_ADDR(prBowLinkDisconnected->aucPeerAddress, prBowFsmInfo->aucPeerAddress); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucEventId, 0x%x\n", prEvent->rHeader.ucEventId); -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucSeqNumber, 0x%x\n", prEvent->rHeader.ucSeqNumber); -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.u2PayloadLength, 0x%x\n", prEvent->rHeader.u2PayloadLength); -+ -+ DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkDisconnected, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowFsmInfo->aucPeerAddress[0], -+ prBowFsmInfo->aucPeerAddress[1], -+ prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], -+ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "wlanbowCmdEventLinkDisconnected, prBowLinkDisconnected->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowLinkDisconnected->aucPeerAddress[0], prBowLinkDisconnected->aucPeerAddress[1], -+ prBowLinkDisconnected->aucPeerAddress[2], prBowLinkDisconnected->aucPeerAddress[3], -+ prBowLinkDisconnected->aucPeerAddress[4], prBowLinkDisconnected->aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkDisconnected, g_u4LinkCount, %x.\n", g_u4LinkCount); -+#endif -+ -+ /*Indicate BoW event to PAL */ -+#if 0 -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED))); -+#endif -+ -+ /* set to disconnected status */ -+ prBowFsmInfo->prTargetStaRec = -+ cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_BOW_INDEX, prBowLinkDisconnected->aucPeerAddress); -+ if (!(prBowFsmInfo->prTargetStaRec)) { -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED))); -+ ASSERT(FALSE); -+ return; -+ } -+ -+ /*Release channel if granted */ -+ if (prBowFsmInfo->fgIsChannelGranted) { -+ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); -+ bowReleaseCh(prAdapter); -+ /*Requested, not granted yet */ -+ } else if (prBowFsmInfo->fgIsChannelRequested) { -+ prBowFsmInfo->fgIsChannelRequested = FALSE; -+ /* bowReleaseCh(prAdapter); */ -+ } -+#if 1 -+ /*Send Deauth to connected peer */ -+ if (eFsmState == BOW_DEVICE_STATE_CONNECTED && (prBowFsmInfo->prTargetStaRec->ucStaState == STA_STATE_3)) { -+ fgSendDeauth = TRUE; -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "wlanbowCmdEventLinkDisconnected, bowGetBowTableState, %x.\n", -+ bowGetBowTableState(prAdapter, prBowLinkDisconnected->aucPeerAddress)); -+#endif -+ authSendDeauthFrame(prAdapter, -+ prBowFsmInfo->prTargetStaRec, -+ (P_SW_RFB_T) NULL, -+ REASON_CODE_DEAUTH_LEAVING_BSS, (PFN_TX_DONE_HANDLER) bowDisconnectLink); -+ } -+#endif -+ -+#if 0 -+ /* 3 <3>Stop this link; flush Tx; -+ * send deAuthentication -> abort. SAA, AAA. need to check BOW table state == Connected. -+ */ -+ if (prAdapter->prGlueInfo->i4TxPendingFrameNum > 0) -+ kalFlushPendingTxPackets(prAdapter->prGlueInfo); -+ -+ /* flush pending security frames */ -+ if (prAdapter->prGlueInfo->i4TxPendingSecurityFrameNum > 0) -+ kalClearSecurityFrames(prAdapter->prGlueInfo); -+#endif -+ -+ /*Update BoW table */ -+ bowGetBowTableEntryByPeerAddress(prAdapter, prBowLinkDisconnected->aucPeerAddress, &ucBowTableIdx); -+ rBowTable.fgIsValid = FALSE; -+ rBowTable.eState = BOW_DEVICE_STATE_DISCONNECTED; -+ kalMemZero(rBowTable.aucPeerAddress, sizeof(rBowTable.aucPeerAddress)); -+ bowSetBowTableContent(prAdapter, ucBowTableIdx, &rBowTable); -+ -+ /*Indicate BoW event to PAL */ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED))); -+ -+ /*Decrease link count */ -+ GLUE_DEC_REF_CNT(g_u4LinkCount); -+ -+ /*If no need to send deauth, DO disconnect now */ -+ /*If need to send deauth, DO disconnect at deauth Tx done */ -+ if (!fgSendDeauth) -+ bowDisconnectLink(prAdapter, NULL, TX_RESULT_SUCCESS); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventSetSetupConnection(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_COMMAND_STATUS prBowCmdStatus; -+ P_WIFI_CMD_T prWifiCmd; -+ P_CMD_BT_OVER_WIFI prCmdBtOverWifi; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ /* restore original command for rPeerAddr */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prCmdBtOverWifi = (P_CMD_BT_OVER_WIFI) (prWifiCmd->aucBuffer); -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); -+ -+ /* fill event body */ -+ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); -+ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); -+ prBowCmdStatus->ucStatus = BOWCMD_STATUS_SUCCESS; -+ -+ /*Indicate BoW event to PAL */ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); -+ -+ /* set to starting status */ -+ kalSetBowState(prAdapter->prGlueInfo, BOW_DEVICE_STATE_STARTING, prCmdBtOverWifi->rPeerAddr); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is the command done handler for BOW_CMD_ID_READ_LINK_QUALITY -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_LINK_QUALITY prLinkQuality; -+ P_AMPC_EVENT prEvent; -+ P_BOW_LINK_QUALITY prBowLinkQuality; -+ -+ ASSERT(prAdapter); -+ -+ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_QUALITY; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_QUALITY); -+ -+ /* fill event body */ -+ prBowLinkQuality = (P_BOW_LINK_QUALITY) (prEvent->aucPayload); -+ kalMemZero(prBowLinkQuality, sizeof(BOW_LINK_QUALITY)); -+ prBowLinkQuality->ucLinkQuality = (UINT_8) prLinkQuality->cLinkQuality; -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY))); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is the command done handler for BOW_CMD_ID_READ_RSSI -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventReadRssi(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_LINK_QUALITY prLinkQuality; -+ P_AMPC_EVENT prEvent; -+ P_BOW_RSSI prBowRssi; -+ -+ ASSERT(prAdapter); -+ -+ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_RSSI; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_RSSI); -+ -+ /* fill event body */ -+ prBowRssi = (P_BOW_RSSI) (prEvent->aucPayload); -+ kalMemZero(prBowRssi, sizeof(BOW_RSSI)); -+ prBowRssi->cRssi = (INT_8) prLinkQuality->cRssi; -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY))); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is the default command timeout handler -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdTimeoutHandler(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_COMMAND_STATUS prBowCmdStatus; -+ -+ ASSERT(prAdapter); -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); -+ -+ /* fill event body */ -+ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); -+ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); -+ -+ prBowCmdStatus->ucStatus = BOWCMD_STATUS_TIMEOUT; /* timeout */ -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); -+ -+} -+ -+VOID bowStopping(IN P_ADAPTER_T prAdapter) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_INFO_T prBowBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowStoping.\n"); -+ DBGLOG(BOW, EVENT, "bowStoping, SSID %s.\n", prBowBssInfo->aucSSID); -+ DBGLOG(BOW, EVENT, "bowStoping, prBowBssInfo->aucBSSID, %x:%x:%x:%x:%x:%x.\n", -+ prBowBssInfo->aucBSSID[0], -+ prBowBssInfo->aucBSSID[1], -+ prBowBssInfo->aucBSSID[2], -+ prBowBssInfo->aucBSSID[3], prBowBssInfo->aucBSSID[4], prBowBssInfo->aucBSSID[5])); -+ DBGLOG(BOW, EVENT, "bowStoping, prBssInfo->aucOwnMacAddr, %x:%x:%x:%x:%x:%x.\n", -+ prBowBssInfo->aucOwnMacAddr[0], -+ prBowBssInfo->aucOwnMacAddr[1], -+ prBowBssInfo->aucOwnMacAddr[2], -+ prBowBssInfo->aucOwnMacAddr[3], -+ prBowBssInfo->aucOwnMacAddr[4], prBowBssInfo->aucOwnMacAddr[5])); -+ DBGLOG(BOW, EVENT, "bowStoping, prAdapter->rWifiVar.aucDeviceAddress, %x:%x:%x:%x:%x:%x.\n", -+ prAdapter->rWifiVar.aucDeviceAddress[0], -+ prAdapter->rWifiVar.aucDeviceAddress[1], -+ prAdapter->rWifiVar.aucDeviceAddress[2], -+ prAdapter->rWifiVar.aucDeviceAddress[3], -+ prAdapter->rWifiVar.aucDeviceAddress[4], prAdapter->rWifiVar.aucDeviceAddress[5])); -+ DBGLOG(BOW, EVENT, "bowStopping, g_u4LinkCount, %x.\n", g_u4LinkCount); -+ DBGLOG(BOW, EVENT, "prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", prBowFsmInfo->aucPeerAddress[0], -+ prBowFsmInfo->aucPeerAddress[1], -+ prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], -+ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); -+ kalPrint("BoW Stoping,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); -+#endif -+ -+ if (g_u4LinkCount == 0) { -+ /*Stop beaconing */ -+ GLUE_DEC_REF_CNT(g_u4Beaconing); -+ -+ /*Deactive BoW network */ -+ /* prBowBssInfo->fgIsNetActive = FALSE; */ -+ /* prBowBssInfo->fgIsBeaconActivated = FALSE; */ -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ /*temp solution for FW hal_pwr_mgt.c#3037 ASSERT */ -+ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ } -+ -+} -+ -+VOID bowStarting(IN P_ADAPTER_T prAdapter) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ if (g_u4LinkCount == 1) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "BoW Starting.\n"); -+ DBGLOG(BOW, EVENT, "BoW channel granted.\n"); -+#endif -+ -+#if 0 -+ /*Active BoW Network */ -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX); -+#endif -+ -+ /* 3 <1> Update BSS_INFO_T per Network Basis */ -+ /* 4 <1.1> Setup Operation Mode */ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ prBssInfo->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ prBssInfo->eCurrentOPMode = OP_MODE_BOW; -+ -+ /* 4 <1.2> Setup SSID */ -+ COPY_MAC_ADDR(prBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucDeviceAddress); -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, prAdapter->rWifiVar.aucDeviceAddress); -+ prBssInfo->ucSSIDLen = BOW_SSID_LEN; -+ bowAssignSsid(prBssInfo->aucSSID, prBssInfo->aucOwnMacAddr); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "SSID %s.\n", prBssInfo->aucSSID); -+ DBGLOG(BOW, EVENT, "prBssInfo->aucBSSID, %x:%x:%x:%x:%x:%x.\n", -+ prBssInfo->aucBSSID[0], -+ prBssInfo->aucBSSID[1], -+ prBssInfo->aucBSSID[2], -+ prBssInfo->aucBSSID[3], prBssInfo->aucBSSID[4], prBssInfo->aucBSSID[5])); -+ DBGLOG(BOW, EVENT, "prBssInfo->aucOwnMacAddr, %x:%x:%x:%x:%x:%x.\n", -+ prBssInfo->aucOwnMacAddr[0], -+ prBssInfo->aucOwnMacAddr[1], -+ prBssInfo->aucOwnMacAddr[2], -+ prBssInfo->aucOwnMacAddr[3], -+ prBssInfo->aucOwnMacAddr[4], prBssInfo->aucOwnMacAddr[5])); -+ DBGLOG(BOW, EVENT, "prAdapter->rWifiVar.aucDeviceAddress, %x:%x:%x:%x:%x:%x.\n", -+ prAdapter->rWifiVar.aucDeviceAddress[0], -+ prAdapter->rWifiVar.aucDeviceAddress[1], -+ prAdapter->rWifiVar.aucDeviceAddress[2], -+ prAdapter->rWifiVar.aucDeviceAddress[3], -+ prAdapter->rWifiVar.aucDeviceAddress[4], prAdapter->rWifiVar.aucDeviceAddress[5])); -+#endif -+ -+ /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ -+ prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ prBssInfo->u2AssocId = 0; -+ -+ /* 4 <1.4> Setup Channel, Band and Phy Attributes */ -+ prBssInfo->ucPrimaryChannel = prBowFsmInfo->ucPrimaryChannel; -+ if (prBowFsmInfo->eBand == BAND_2G4) -+ prBssInfo->eBand = BAND_2G4; -+ else -+ prBssInfo->eBand = BAND_5G; -+ -+#if CFG_BOW_SUPPORT_11N -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN; -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; -+ -+ prBssInfo->ucNonHTBasicPhyType = (UINT_8) -+ rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; -+ prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; -+ -+ prBssInfo->u2OperationalRateSet = -+ rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; -+ -+ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, -+ prBssInfo->u2BSSBasicRateSet, -+ prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen); -+ -+#else -+ if (prBssInfo->eBand == BAND_2G4) { -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; -+ -+ /* RATE_SET_ERP; */ -+ prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_ERP; -+ prBssInfo->u2OperationalRateSet = RATE_SET_ERP; -+ prBssInfo->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; -+ } else { -+ /* Depend on eBand */ -+ /* prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; */ -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ /* prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; */ -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11A; -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A; -+ -+ /* RATE_SET_ERP; */ -+ /* prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_ERP; */ -+ /* prBssInfo->u2OperationalRateSet = RATE_SET_ERP; */ -+ -+ /* RATE_SET_ERP; */ -+ prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_OFDM; -+ prBssInfo->u2OperationalRateSet = RATE_SET_OFDM; -+ prBssInfo->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; -+ } -+ -+#endif -+ prBssInfo->fgErpProtectMode = FALSE; -+ -+ /* 4 <1.5> Setup MIB for current BSS */ -+ prBssInfo->u2BeaconInterval = prBowFsmInfo->u2BeaconInterval; -+ prBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; -+ prBssInfo->u2ATIMWindow = 0; -+ prBssInfo->ucBeaconTimeoutCount = 0; -+ if (prBowFsmInfo->fgSupportQoS) { -+ prAdapter->rWifiVar.fgSupportQoS = TRUE; -+ prBssInfo->fgIsQBSS = TRUE; -+ } -+ /* 3 <2> Update BSS_INFO_T common part */ -+#if CFG_SUPPORT_AAA -+ bssInitForAP(prAdapter, prBssInfo, TRUE); -+ nicQmUpdateWmmParms(prAdapter, NETWORK_TYPE_BOW_INDEX); -+#endif /* CFG_SUPPORT_AAA */ -+ prBssInfo->fgIsNetActive = TRUE; -+ prBssInfo->fgIsBeaconActivated = TRUE; -+ -+ /* 3 <3> Set MAC HW */ -+ -+ /* 4 <2> Initiate BSS_INFO_T - common part */ -+ BOW_BSS_INFO_INIT(prAdapter, NETWORK_TYPE_BOW_INDEX); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", prBowFsmInfo->aucPeerAddress[0], -+ prBowFsmInfo->aucPeerAddress[1], prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], prBowFsmInfo->aucPeerAddress[4], -+ prBowFsmInfo->aucPeerAddress[5])); -+#endif -+ -+ /* 4 <3.1> use command packets to inform firmware */ -+ rlmBssInitForAPandIbss(prAdapter, prBssInfo); -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ /* 4 <3.2> Update AdHoc PM parameter */ -+ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ /* 4 <3.1> Reset HW TSF Update Mode and Beacon Mode */ -+ -+ /* 4 <3.2> Setup BSSID */ -+ /* TODO: rxmSetRxFilterBSSID0 */ -+/* rxmSetRxFilterBSSID0(prBssInfo->ucHwBssidId, prBssInfo->aucBSSID); */ -+ -+ /* 4 <3.3> Setup RX Filter to accept Probe Request */ -+ /* TODO: f get/set RX filter. */ -+ -+#if 0 -+ { -+ UINT_32 u4RxFilter; -+ -+ if (halMacRxGetRxFilters(&u4RxFilter) == HAL_STATUS_SUCCESS) { -+ -+ u4RxFilter &= ~BIT(RXFILTER_DROP_PROBE_REQ); -+ -+ halMacRxSetRxFilters(u4RxFilter); -+ } -+ } -+#endif -+ } -+ -+ /*Update BoW Table */ -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_STARTING); -+ -+#if CFG_BOW_TEST -+ kalPrint("BoW Starting,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); -+ DBGLOG(BOW, EVENT, "bowStarting, g_u4LinkCount, %x.\n", g_u4LinkCount); -+#endif -+ -+ /*Start beaconing */ -+ if (g_u4Beaconing < 1) { -+ GLUE_INC_REF_CNT(g_u4Beaconing); -+ bssSendBeaconProbeResponse(prAdapter, NETWORK_TYPE_BOW_INDEX, NULL, 0); -+ cnmTimerStartTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer, prBowFsmInfo->u2BeaconInterval); -+ } -+#if 0 -+ /*Responder: Start to scan Initiator */ -+ if (prBowFsmInfo->ucRole == BOW_RESPONDER) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowStarting responder, start scan result searching.\n"); -+#endif -+ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); -+ bowReleaseCh(prAdapter); -+ bowResponderScan(prAdapter); -+ } -+ /*Initiator: Request channel, wait for responder */ -+ else { -+ /* Todo:: Nothing*/ -+ /* bowRequestCh(prAdapter); */ -+ } -+#endif -+ -+} -+ -+VOID bowAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 puOwnMacAddr) -+{ -+ UINT_8 i; -+ UINT_8 aucSSID[] = BOW_WILDCARD_SSID; -+ -+ kalMemCopy(pucSsid, aucSSID, BOW_WILDCARD_SSID_LEN); -+ -+ for (i = 0; i < 6; i++) { -+ pucSsid[(3 * i) + 3] = 0x2D; -+ if ((*(puOwnMacAddr + i) >> 4) < 0xA) -+ *(pucSsid + (3 * i) + 4) = (*(puOwnMacAddr + i) >> 4) + 0x30; -+ else -+ *(pucSsid + (3 * i) + 4) = (*(puOwnMacAddr + i) >> 4) + 0x57; -+ -+ if ((*(puOwnMacAddr + i) & 0x0F) < 0xA) -+ pucSsid[(3 * i) + 5] = (*(puOwnMacAddr + i) & 0x0F) + 0x30; -+ else -+ pucSsid[(3 * i) + 5] = (*(puOwnMacAddr + i) & 0x0F) + 0x57; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Probe Request Frame and then return -+* result to BSS to indicate if need to send the corresponding Probe Response -+* Frame if the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu4ControlFlags Control flags for replying the Probe Response -+* -+* @retval TRUE Reply the Probe Response -+* @retval FALSE Don't reply the Probe Response -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN bowValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags) -+{ -+ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; -+ PUINT_8 pucIE; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ BOOLEAN fgReplyProbeResp = FALSE; -+ -+ ASSERT(prSwRfb); -+ ASSERT(pu4ControlFlags); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+#if 0 /* CFG_BOW_TEST */ -+ DBGLOG(BOW, EVENT, "bowValidateProbeReq.\n"); -+#endif -+ -+ /* 4 <1> Parse Probe Req IE and Get IE ptr (SSID, Supported Rate IE, ...) */ -+ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; -+ -+ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; -+ pucIE = (PUINT_8) ((ULONG) prSwRfb->pvHeader + prSwRfb->u2HeaderLen); -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ if (ELEM_ID_SSID == IE_ID(pucIE)) { -+ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ if (ELEM_ID_SSID == IE_ID(pucIE)) { -+ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ /* 4 <2> Check network conditions */ -+ /*If BoW AP is beaconing */ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_BOW && g_u4Beaconing > 0) { -+ -+ /*Check the probe requset sender is our peer */ -+ if (bowCheckBowTableIfVaild(prAdapter, prMgtHdr->aucSrcAddr)) -+ fgReplyProbeResp = TRUE; -+ /*Check the probe request target SSID is our SSID */ -+ else if ((prIeSsid) && -+ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prIeSsid->aucSSID, prIeSsid->ucLength)) -+ fgReplyProbeResp = TRUE; -+ else -+ fgReplyProbeResp = FALSE; -+ } -+ -+ return fgReplyProbeResp; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Media Disconnect" to HOST -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowSendBeacon(IN P_ADAPTER_T prAdapter, IN ULONG ulParam) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ if ((g_u4Beaconing != 0) && (g_u4LinkCount > 0) && (g_u4LinkCount < CFG_BOW_PHYSICAL_LINK_NUM)) { -+ /* Send beacon */ -+ bssSendBeaconProbeResponse(prAdapter, NETWORK_TYPE_BOW_INDEX, NULL, 0); -+ cnmTimerStartTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer, prBowFsmInfo->u2BeaconInterval); -+ } -+#if CFG_BOW_TEST -+ else -+ kalPrint("BoW Send Beacon,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Media Disconnect" to HOST -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowResponderScan(IN P_ADAPTER_T prAdapter) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_MSG_SCN_SCAN_REQ prScanReqMsg; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowResponderScan.\n"); -+ kalPrint("BOW SCAN [REQ:%d]\n", prBowFsmInfo->ucSeqNumOfScanReq + 1); -+#endif -+ -+ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); -+ -+ if (!prScanReqMsg) { -+ ASSERT(0); /* Can't trigger SCAN FSM */ -+ return; -+ } -+ -+ /*Fill scan message */ -+ prScanReqMsg->rMsgHdr.eMsgId = MID_BOW_SCN_SCAN_REQ; -+ prScanReqMsg->ucSeqNum = ++prBowFsmInfo->ucSeqNumOfScanReq; -+ prScanReqMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_BOW_INDEX; -+ prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ prScanReqMsg->ucSSIDLength = BOW_SSID_LEN; -+ bowAssignSsid(prScanReqMsg->aucSSID, prBowFsmInfo->aucPeerAddress); -+ prScanReqMsg->ucChannelListNum = 1; -+ -+ if (prBowFsmInfo->eBand == BAND_2G4) { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; -+ prScanReqMsg->arChnlInfoList[0].eBand = BAND_2G4; -+ } else { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; -+ prScanReqMsg->arChnlInfoList[0].eBand = BAND_5G; -+ } -+ -+ prScanReqMsg->arChnlInfoList[0].ucChannelNum = prBowFsmInfo->ucPrimaryChannel; -+ prScanReqMsg->u2IELen = 0; -+ -+ /*Send scan message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); -+ -+ /*Change state to SCANNING */ -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_SCANNING); -+ -+ /* prBowFsmInfo->fgTryScan = FALSE; */ /* Will enable background sleep for infrastructure */ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowResponderScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SCN_SCAN_DONE prScanDoneMsg; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_DESC_T prBssDesc; -+ UINT_8 ucSeqNumOfCompMsg; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ ENUM_BOW_DEVICE_STATE eFsmState; -+ ENUM_SCAN_STATUS eScanStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; -+ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); -+ -+ ASSERT(prScanDoneMsg->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX); -+ -+ ucSeqNumOfCompMsg = prScanDoneMsg->ucSeqNum; -+ eScanStatus = prScanDoneMsg->eScanStatus; -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowResponderScanDone.\n"); -+ kalPrint("BOW SCAN [DONE:%d]\n", ucSeqNumOfCompMsg); -+#endif -+ -+ if (eScanStatus == SCAN_STATUS_CANCELLED) { -+#if CFG_BOW_TEST -+ kalPrint("BOW SCAN [CANCELLED:%d]\n", ucSeqNumOfCompMsg); -+#endif -+ if (eFsmState == BOW_DEVICE_STATE_DISCONNECTING) { -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkDisconnected, -+ wlanbowCmdTimeoutHandler, 0, NULL, 0); -+ } -+ return; -+ } else if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { -+ /* bowDisconnectLink(prAdapter, NULL, TX_RESULT_SUCCESS); */ -+ return; -+ } else if (ucSeqNumOfCompMsg != prBowFsmInfo->ucSeqNumOfScanReq) { -+ DBGLOG(BOW, EVENT, "Sequence no. of BOW Responder scan done is not matched.\n"); -+ return; -+ } -+ prConnSettings->fgIsScanReqIssued = FALSE; -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prBowFsmInfo->aucPeerAddress); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "End scan result searching.\n"); -+#endif -+ -+ /* Initiator is FOUND */ -+ if (prBssDesc != NULL) { -+ /* (prBssDesc->aucBSSID != NULL)) */ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Search Bow Peer address - %x:%x:%x:%x:%x:%x.\n", prBssDesc->aucBSSID[0], -+ prBssDesc->aucBSSID[1], -+ prBssDesc->aucBSSID[2], -+ prBssDesc->aucBSSID[3], prBssDesc->aucBSSID[4], prBssDesc->aucBSSID[5]); -+ DBGLOG(BOW, EVENT, "Starting to join initiator.\n"); -+#endif -+ /*Set target BssDesc */ -+ prBowFsmInfo->prTargetBssDesc = prBssDesc; -+ /*Request channel to do JOIN */ -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, -+ BOW_DEVICE_STATE_ACQUIRING_CHANNEL); -+ bowRequestCh(prAdapter); -+ } -+ /*Initiator is NOT FOUND */ -+ else { -+ /*Scan again, until PAL timeout */ -+ bowResponderScan(prAdapter); -+#if 0 -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkDisconnected, -+ wlanbowCmdTimeoutHandler, 0, NULL, 0); -+#endif -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Function for cancelling scan request. There is another option to extend channel privilige -+* for another purpose. -+* -+* @param fgIsChannelExtention - Keep the channel previlege, but can cancel scan timer. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowResponderCancelScan(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtention) -+{ -+ -+ P_MSG_SCN_SCAN_CANCEL prScanCancel = (P_MSG_SCN_SCAN_CANCEL) NULL; -+ P_BOW_FSM_INFO_T prBowFsmInfo = (P_BOW_FSM_INFO_T) NULL; -+ -+ DEBUGFUNC("bowResponderCancelScan()"); -+ -+ do { -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ if (TRUE) { -+#if CFG_BOW_TEST -+ kalPrint("BOW SCAN [CANCEL:%d]\n", prBowFsmInfo->ucSeqNumOfScanReq); -+#endif -+ /* There is a channel privilege on hand. */ -+ -+ DBGLOG(P2P, TRACE, "BOW Cancel Scan\n"); -+ -+ prScanCancel = -+ (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL)); -+ if (!prScanCancel) { -+ /* Buffer not enough, can not cancel scan request. */ -+ DBGLOG(P2P, TRACE, "Buffer not enough, can not cancel scan.\n"); -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prScanCancel->rMsgHdr.eMsgId = MID_BOW_SCN_SCAN_CANCEL; -+ prScanCancel->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ prScanCancel->ucSeqNum = prBowFsmInfo->ucSeqNumOfScanReq; -+#if CFG_ENABLE_WIFI_DIRECT -+ prScanCancel->fgIsChannelExt = fgIsChannelExtention; -+#endif -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancel, MSG_SEND_METHOD_BUF); -+ -+ } -+ -+ } while (FALSE); -+ -+} /* bowResponderCancelScan */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialization of JOIN STATE -+* -+* @param[in] prBssDesc The pointer of BSS_DESC_T which is the BSS we will try to join with. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowResponderJoin(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_STA_RECORD_T prStaRec; -+ P_MSG_JOIN_REQ_T prJoinReqMsg; -+ -+ ASSERT(prBssDesc); -+ ASSERT(prAdapter); -+ -+ DBGLOG(BOW, EVENT, "Starting bowResponderJoin.\n"); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* 4 <1> We are going to connect to this BSS. */ -+ prBssDesc->fgIsConnecting = TRUE; -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_CONNECTING); -+ -+ /* 4 <2> Setup corresponding STA_RECORD_T */ -+ /*Support First JOIN and retry */ -+ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_BOW_AP, NETWORK_TYPE_BOW_INDEX, prBssDesc); -+ if (!prStaRec) -+ return; -+ -+ prBowFsmInfo->prTargetStaRec = prStaRec; -+ -+ /* 4 <3> Update ucAvailableAuthTypes which we can choice during SAA */ -+ prStaRec->fgIsReAssoc = FALSE; -+ prBowFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; -+ -+ /* 4 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes */ -+ if (prBowFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) { -+ -+ DBGLOG(BOW, LOUD, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); -+ prBowFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; -+ } else { -+ ASSERT(0); -+ } -+ -+ /* 4 <4.1> sync. to firmware domain */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ /* 4 <5> Overwrite Connection Setting for eConnectionPolicy */ -+ if (prBssDesc->ucSSIDLen) { -+ COPY_SSID(prConnSettings->aucSSID, prConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowResponderJoin, SSID %s.\n", prBssDesc->aucSSID); -+ DBGLOG(BOW, EVENT, "bowResponderJoin, SSID %s.\n", prConnSettings->aucSSID); -+#endif -+ } -+ /* 4 <6> Send a Msg to trigger SAA to start JOIN process. */ -+ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); -+ if (!prJoinReqMsg) { -+ -+ ASSERT(0); /* Can't trigger SAA FSM */ -+ return; -+ } -+ -+ prJoinReqMsg->rMsgHdr.eMsgId = MID_BOW_SAA_FSM_START; -+ prJoinReqMsg->ucSeqNum = ++prBowFsmInfo->ucSeqNumOfReqMsg; -+ prJoinReqMsg->prStaRec = prStaRec; -+ -+ prBssInfo->prStaRecOfAP = prStaRec; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prStaRec->eStaType, %x.\n", prStaRec->eStaType); -+ DBGLOG(BOW, INFO, "BoW trigger SAA [%pM]\n", prStaRec->aucMacAddr); -+#endif -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Join Complete Event from SAA FSM for BOW FSM -+* -+* @param[in] prMsgHdr Message of Join Complete of SAA FSM. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_JOIN_COMP_T prJoinCompMsg; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_STA_RECORD_T prStaRec; -+ P_SW_RFB_T prAssocRspSwRfb; -+ P_BSS_INFO_T prBssInfo; -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL; -+ UINT_16 u2IELength; -+ PUINT_8 pucIE; -+ P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr; -+ prStaRec = prJoinCompMsg->prStaRec; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Start bowfsmRunEventJoinComplete.\n"); -+ DBGLOG(BOW, EVENT, "bowfsmRunEventJoinComplete ptr check\n"); -+ DBGLOG(BOW, EVENT, "prMsgHdr %x\n", prMsgHdr); -+ DBGLOG(BOW, EVENT, "prAdapter %x\n", prAdapter); -+ DBGLOG(BOW, EVENT, "prBowFsmInfo %x\n", prBowFsmInfo); -+ DBGLOG(BOW, EVENT, "prStaRec %x\n", prStaRec); -+#endif -+ -+ ASSERT(prStaRec); -+ ASSERT(prBowFsmInfo); -+ -+ /* Check SEQ NUM */ -+ if (prJoinCompMsg->ucSeqNum == prBowFsmInfo->ucSeqNumOfReqMsg) { -+ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prStaRec->aucMacAddr); -+ -+ /* 4 <1> JOIN was successful */ -+ if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { -+ prAssocRspSwRfb = prJoinCompMsg->prSwRfb; -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) - -+ (OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - -+ WLAN_MAC_MGMT_HEADER_LEN)); -+ pucIE = prAssocRspFrame->aucInfoElem; -+ -+ prStaRec->eStaType = STA_TYPE_BOW_AP; -+ prStaRec->u2DesiredNonHTRateSet &= prBowBssInfo->u2OperationalRateSet; -+ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prBowBssInfo->ucPhyTypeSet; -+#if CFG_BOW_RATE_LIMITATION -+ /* 4 <1.2>Update Rate Set */ -+ /*Limit Rate Set to 24M, 48M, 54M */ -+ prStaRec->u2DesiredNonHTRateSet &= (RATE_SET_BIT_24M | RATE_SET_BIT_48M | RATE_SET_BIT_54M); -+ /*If peer cannot support the above rate set, fix on the available highest rate */ -+ if (prStaRec->u2DesiredNonHTRateSet == 0) { -+ UINT_8 ucHighestRateIndex; -+ -+ if (rateGetHighestRateIndexFromRateSet -+ (prBowBssInfo->u2OperationalRateSet, &ucHighestRateIndex)) { -+ prStaRec->u2DesiredNonHTRateSet = BIT(ucHighestRateIndex); -+ } -+ } -+#endif -+ -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+ -+ /* 4 <1.2> Update HT information and set channel */ -+ /* Record HT related parameters in rStaRec and rBssInfo -+ * Note: it shall be called before nicUpdateBss() -+ */ -+#if CFG_BOW_SUPPORT_11N -+ rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+#endif -+ -+ /* 4 <1.3> Update BSS_INFO_T */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Finish bowUpdateBssInfoForJOIN.\n"); -+#endif -+ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowFsmRunEventJoinComplete, qmActivateStaRec.\n"); -+#endif -+ -+ /* 4 <1.7> Set the Next State of BOW FSM */ -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkConnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); -+ } -+ /* 4 <2> JOIN was not successful */ -+ else { -+ /*Retry */ -+ bowResponderJoin(prAdapter, prBowFsmInfo->prTargetBssDesc); -+#if 0 -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkDisconnected, -+ wlanbowCmdTimeoutHandler, 0, NULL, 0); -+#endif -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Start bowfsmRunEventJoinComplete -- Join failed.\n"); -+ DBGLOG(BOW, INFO, "BoW trigger SAA REJOIN\n"); -+#endif -+ } -+ } -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Media State to HOST -+* -+* @param[in] eConnectionState Current Media State -+* @param[in] fgDelayIndication Set TRUE for postponing the Disconnect Indication. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+bowIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, -+ IN ENUM_PARAM_MEDIA_STATE_T eConnectionState, IN BOOLEAN fgDelayIndication) -+{ -+ EVENT_CONNECTION_STATUS rEventConnStatus; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prBssInfo; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ /* NOTE(Kevin): Move following line to bowChangeMediaState() macro per CM's request. */ -+ /* prBowBssInfo->eConnectionState = eConnectionState; */ -+ -+ /* For indicating the Disconnect Event only if current media state is -+ * disconnected and we didn't do indication yet. -+ */ -+ if (prBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ if (prBssInfo->eConnectionStateIndicated == eConnectionState) -+ return; -+ } -+ -+ if (!fgDelayIndication) { -+ /* 4 <0> Cancel Delay Timer */ -+ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rIndicationOfDisconnectTimer); -+ -+ /* 4 <1> Fill EVENT_CONNECTION_STATUS */ -+ rEventConnStatus.ucMediaStatus = (UINT_8) eConnectionState; -+ -+ if (eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ rEventConnStatus.ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_BOW) { -+ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_INFRA; -+ rEventConnStatus.u2AID = prBssInfo->u2AssocId; -+ rEventConnStatus.u2ATIMWindow = 0; -+ } else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_IBSS; -+ rEventConnStatus.u2AID = 0; -+ rEventConnStatus.u2ATIMWindow = prBssInfo->u2ATIMWindow; -+ } else { -+ ASSERT(0); -+ } -+ -+ COPY_SSID(rEventConnStatus.aucSsid, -+ rEventConnStatus.ucSsidLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ COPY_MAC_ADDR(rEventConnStatus.aucBssid, prBssInfo->aucBSSID); -+ -+ rEventConnStatus.u2BeaconPeriod = prBssInfo->u2BeaconInterval; -+ rEventConnStatus.u4FreqInKHz = nicChannelNum2Freq(prBssInfo->ucPrimaryChannel); -+ -+ switch (prBssInfo->ucNonHTBasicPhyType) { -+ case PHY_TYPE_HR_DSSS_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; -+ break; -+ -+ case PHY_TYPE_ERP_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM24; -+ break; -+ -+ case PHY_TYPE_OFDM_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM5; -+ break; -+ -+ default: -+ ASSERT(0); -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; -+ break; -+ } -+ } else { -+#if CFG_PRIVACY_MIGRATION -+ /* Clear the pmkid cache while media disconnect */ -+ secClearPmkid(prAdapter); -+#endif -+ -+ rEventConnStatus.ucReasonOfDisconnect = prBssInfo->ucReasonOfDisconnect; -+ -+ } -+ -+ /* 4 <2> Indication */ -+ nicMediaStateChange(prAdapter, NETWORK_TYPE_BOW_INDEX, &rEventConnStatus); -+ prBssInfo->eConnectionStateIndicated = eConnectionState; -+ } else { -+ /* NOTE: Only delay the Indication of Disconnect Event */ -+ ASSERT(eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ DBGLOG(BOW, INFO, "Postpone the indication of Disconnect for %d seconds\n", -+ prConnSettings->ucDelayTimeOfDisconnectEvent); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prBowFsmInfo->rIndicationOfDisconnectTimer, -+ SEC_TO_MSEC(prConnSettings->ucDelayTimeOfDisconnectEvent)); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Event of Tx Fail of AAA Module. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowRunEventAAATxFail , bssRemoveStaRecFromClientList.\n"); -+ DBGLOG(BOW, INFO, "BoW AAA TxFail, target state %d\n", prStaRec->ucStaState + 1); -+#endif -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Event of Successful Completion of AAA Module. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ -+ ASSERT(prStaRec); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowRunEventAAAComplete, cnmStaRecChangeState, STA_STATE_3.\n"); -+ DBGLOG(BOW, INFO, "BoW AAA complete [%pM]\n", prStaRec->aucMacAddr); -+#endif -+ -+ /*Update BssInfo to connected */ -+ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ /*Update StaRec to State3 */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+ /*Connected */ -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, FALSE, wlanbowCmdEventLinkConnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle RxDeauth -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS bowRunEventRxDeAuth(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prBowBssInfo; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ ENUM_BOW_DEVICE_STATE eFsmState; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ if (!IS_STA_IN_BOW(prStaRec)) -+ return WLAN_STATUS_NOT_ACCEPTED; -+ -+ eFsmState = bowGetBowTableState(prAdapter, prStaRec->aucMacAddr); -+ -+ if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { -+ /*do nothing */ -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ -+ if (prStaRec->ucStaState > STA_STATE_1) { -+ -+ if (STA_STATE_3 == prStaRec->ucStaState) { -+ /* P_MSG_AIS_ABORT_T prAisAbortMsg; */ -+ -+ /* NOTE(Kevin): Change state immediately to avoid starvation of -+ * MSG buffer because of too many deauth frames before changing -+ * the STA state. -+ */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ } -+ -+ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prStaRec->aucMacAddr); -+ -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, wlanbowCmdEventLinkDisconnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ return WLAN_STATUS_NOT_ACCEPTED; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function handle BoW Link disconnect. -+* -+* \param[in] pMsduInfo Pointer to the Msdu Info -+* \param[in] rStatus The Tx done status -+* -+* \return - -+* -+* \note after receive deauth frame, callback function call this -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowDisconnectLink(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ /*Free target StaRec */ -+ if (prMsduInfo) -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ else -+ prStaRec = prBowFsmInfo->prTargetStaRec; -+ -+ if (prStaRec) -+ /* cnmStaRecFree(prAdapter, prStaRec, TRUE); */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ kalPrint("bowDisconnectLink\n"); -+ /*No one connected */ -+ if (g_u4LinkCount == 0 && g_u4Beaconing != 0) { -+ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer); -+ bowStopping(prAdapter); -+ kalPrint("bowStopping\n"); -+ /*Restore TxPower from Short range mode */ -+#if CFG_SUPPORT_NVRAM && 0 -+ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); -+#endif -+ /*Uninit BoW Interface */ -+#if CFG_BOW_SEPARATE_DATA_PATH -+ kalUninitBowDevice(prAdapter->prGlueInfo); -+#endif -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Assoc Req Frame and then return -+* the status code to AAA to indicate if need to perform following actions -+* when the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu2StatusCode The Status Code of Validation Result -+* -+* @retval TRUE Reply the Assoc Resp -+* @retval FALSE Don't reply the Assoc Resp -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN bowValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) -+{ -+ BOOLEAN fgReplyAssocResp = FALSE; -+ P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) NULL; -+ OS_SYSTIME rCurrentTime; -+ static OS_SYSTIME rLastRejectAssocTime; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; -+ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAssocReq, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowFsmInfo->aucPeerAddress[0], -+ prBowFsmInfo->aucPeerAddress[1], -+ prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], -+ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, "bowValidateAssocReq, prAssocReqFrame->aucSrcAddr, %x:%x:%x:%x:%x:%x.\n", -+ prAssocReqFrame->aucSrcAddr[0], -+ prAssocReqFrame->aucSrcAddr[1], -+ prAssocReqFrame->aucSrcAddr[2], -+ prAssocReqFrame->aucSrcAddr[3], -+ prAssocReqFrame->aucSrcAddr[4], prAssocReqFrame->aucSrcAddr[5])); -+#endif -+ -+ /*Assoc Accept */ -+ while (EQUAL_MAC_ADDR(prAssocReqFrame->aucSrcAddr, prBowFsmInfo->aucPeerAddress)) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAssocReq, return wlanbowCmdEventLinkConnected.\n"); -+#endif -+ /*Update StaRec */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, -+ (UINT_8) NETWORK_TYPE_BOW_INDEX, prAssocReqFrame->aucSrcAddr); -+ if (!prStaRec) -+ break; -+ prStaRec->eStaType = STA_TYPE_BOW_CLIENT; -+ prStaRec->u2DesiredNonHTRateSet &= prBowBssInfo->u2OperationalRateSet; -+ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prBowBssInfo->ucPhyTypeSet; -+ -+#if CFG_BOW_RATE_LIMITATION -+ /*Limit Rate Set to 24M, 48M, 54M */ -+ prStaRec->u2DesiredNonHTRateSet &= (RATE_SET_BIT_24M | RATE_SET_BIT_48M | RATE_SET_BIT_54M); -+ /*If peer cannot support the above rate set, fix on the available highest rate */ -+ if (prStaRec->u2DesiredNonHTRateSet == 0) { -+ UINT_8 ucHighestRateIndex; -+ -+ if (rateGetHighestRateIndexFromRateSet(prBowBssInfo->u2OperationalRateSet, &ucHighestRateIndex)) -+ prStaRec->u2DesiredNonHTRateSet = BIT(ucHighestRateIndex); -+ else { -+ /*If no available rate is found, DECLINE the association */ -+ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; -+ break; -+ } -+ } -+#endif -+ prStaRec->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ -+ /*Undpate BssInfo to FW */ -+ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ /*reply successful */ -+ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; -+ fgReplyAssocResp = TRUE; -+ break; -+ } -+ -+ /*Reject Assoc */ -+ if (*pu2StatusCode != STATUS_CODE_SUCCESSFUL) { -+ /*Reply Assoc with reject every 5s */ -+ rCurrentTime = kalGetTimeTick(); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, rLastRejectAssocTime, MSEC_TO_SYSTIME(5000)) || -+ rLastRejectAssocTime == 0) { -+ fgReplyAssocResp = TRUE; -+ rLastRejectAssocTime = rCurrentTime; -+ } -+ } -+ -+ return fgReplyAssocResp; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Auth Frame and then return -+* the status code to AAA to indicate if need to perform following actions -+* when the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] pprStaRec Pointer to pointer of STA_RECORD_T structure. -+* @param[out] pu2StatusCode The Status Code of Validation Result -+* -+* @retval TRUE Reply the Auth -+* @retval FALSE Don't reply the Auth -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+bowValidateAuth(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode) -+{ -+ BOOLEAN fgReplyAuth = FALSE; -+ P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_WLAN_AUTH_FRAME_T prAuthFrame = (P_WLAN_AUTH_FRAME_T) NULL; -+ OS_SYSTIME rCurrentTime; -+ static OS_SYSTIME rLastRejectAuthTime; -+ -+ /* TODO(Kevin): Call BoW functions to check .. -+ 1. Check we are BoW now. -+ 2. Check we can accept connection from thsi peer -+ 3. Check Black List here. -+ */ -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowFsmInfo->aucPeerAddress[0], -+ prBowFsmInfo->aucPeerAddress[1], -+ prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], -+ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, "bowValidateAuth, prAuthFrame->aucSrcAddr, %x:%x:%x:%x:%x:%x.\n", -+ prAuthFrame->aucSrcAddr[0], -+ prAuthFrame->aucSrcAddr[1], -+ prAuthFrame->aucSrcAddr[2], -+ prAuthFrame->aucSrcAddr[3], prAuthFrame->aucSrcAddr[4], prAuthFrame->aucSrcAddr[5])); -+#endif -+ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_BOW_INDEX, prAuthFrame->aucSrcAddr); -+ if (!prStaRec) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, cnmStaRecAlloc.\n"); -+#endif -+ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_BOW_INDEX); -+ -+ /* TODO(Kevin): Error handling of allocation of STA_RECORD_T for -+ * exhausted case and do removal of unused STA_RECORD_T. -+ */ -+ if (!prStaRec) -+ return fgReplyAuth; -+ COPY_MAC_ADDR(prStaRec->aucMacAddr, prAuthFrame->aucSrcAddr); -+ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; -+ prBowBssInfo->prStaRecOfAP = prStaRec; -+ -+ /* NOTE(Kevin): Better to change state here, not at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, cnmStaRecChangeState.\n"); -+#endif -+ } else { -+ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->ucIndex, %x.\n", prStaRec->ucIndex); -+#endif -+ bssRemoveStaRecFromClientList(prAdapter, prBowBssInfo, prStaRec); -+ } -+ -+ if (EQUAL_MAC_ADDR(prAuthFrame->aucSrcAddr, prBowFsmInfo->aucPeerAddress)) { -+ -+ prStaRec->eStaType = STA_TYPE_BOW_CLIENT; -+ prStaRec->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->eStaType, %x.\n", prStaRec->eStaType); -+ DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->ucNetTypeIndex, %x.\n", prStaRec->ucNetTypeIndex); -+#endif -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ prStaRec->ucJoinFailureCount = 0; -+ *pprStaRec = prStaRec; -+ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; -+ fgReplyAuth = TRUE; -+ } else { -+ cnmStaRecFree(prAdapter, prStaRec, FALSE); -+ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; -+ -+ /*Reply auth with reject every 5s */ -+ rCurrentTime = kalGetTimeTick(); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, rLastRejectAuthTime, MSEC_TO_SYSTIME(5000)) || -+ rLastRejectAuthTime == 0) { -+ fgReplyAuth = TRUE; -+ rLastRejectAuthTime = rCurrentTime; -+ } -+ } -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, fgReplyAuth, %x.\n", fgReplyAuth); -+#endif -+ return fgReplyAuth; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is invoked when CNM granted channel privilege -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_BSS_INFO_T prBowBssInfo; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_MSG_CH_GRANT_T prMsgChGrant; -+ UINT_8 ucTokenID; -+ UINT_32 u4GrantInterval; -+ ENUM_BOW_DEVICE_STATE eFsmState; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr; -+ ucTokenID = prMsgChGrant->ucTokenID; -+ u4GrantInterval = prMsgChGrant->u4GrantInterval; -+ -+ /* 1. free message */ -+ cnmMemFree(prAdapter, prMsgHdr); -+ prBowFsmInfo->fgIsChannelGranted = TRUE; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Entering bowRunEventChGrant.\n"); -+#endif -+ -+ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); -+ -+ /*Release channel */ -+ if ((!prBowFsmInfo->fgIsChannelRequested) || -+ (prBowFsmInfo->ucSeqNumOfChReq != ucTokenID) || -+ (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) || (eFsmState == BOW_DEVICE_STATE_DISCONNECTING)) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "BoW Channel [GIVE UP:%d]\n", ucTokenID); -+ DBGLOG(BOW, INFO, "[Requested:%d][ucSeqNumOfChReq:%d][eFsmState:%d]\n", -+ prBowFsmInfo->fgIsChannelRequested, prBowFsmInfo->ucSeqNumOfChReq, eFsmState); -+#endif -+ bowReleaseCh(prAdapter); -+ return; -+ } -+ -+ /* 2. channel privilege has been approved */ -+ prBowFsmInfo->u4ChGrantedInterval = u4GrantInterval; -+ -+#if 0 -+ cnmTimerStartTimer(prAdapter, -+ &prBowFsmInfo->rChGrantedTimer, -+ prBowFsmInfo->u4ChGrantedInterval - BOW_JOIN_CH_GRANT_THRESHOLD); -+#else -+ cnmTimerStartTimer(prAdapter, -+ &prBowFsmInfo->rChGrantedTimer, BOW_JOIN_CH_REQUEST_INTERVAL - BOW_JOIN_CH_GRANT_THRESHOLD); -+#endif -+ -+ /* 3.2 set local variable to indicate join timer is ticking */ -+ prBowFsmInfo->fgIsInfraChannelFinished = FALSE; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "BoW Channel [GRANTED:%d].\n", ucTokenID); -+#endif -+ -+ if (eFsmState == BOW_DEVICE_STATE_ACQUIRING_CHANNEL) { -+ bowStarting(prAdapter); -+ bowReleaseCh(prAdapter); -+ if (prBowFsmInfo->ucRole == BOW_RESPONDER) -+ bowResponderJoin(prAdapter, prBowFsmInfo->prTargetBssDesc); -+ } else { -+ /*update bssinfo */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ bowReleaseCh(prAdapter); -+ } -+ -+} /* end of aisFsmRunEventChGrant() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform CNM for channel privilege requesting -+* has been released -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowRequestCh(IN P_ADAPTER_T prAdapter) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_MSG_CH_REQ_T prMsgChReq; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ if (prBowFsmInfo->fgIsChannelGranted == FALSE) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "BoW channel [REQUEST:%d], %d, %d.\n", prBowFsmInfo->ucSeqNumOfChReq + 1, -+ prBowFsmInfo->ucPrimaryChannel, prBowFsmInfo->eBand); -+#endif -+ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); -+ -+ if (!prMsgChReq) { -+ ASSERT(0); /* Can't indicate CNM for channel acquiring */ -+ return; -+ } -+ -+ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; -+ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ prMsgChReq->ucTokenID = ++prBowFsmInfo->ucSeqNumOfChReq; -+ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; -+#if 0 -+ prMsgChReq->u4MaxInterval = BOW_JOIN_CH_REQUEST_INTERVAL; -+#else -+ prMsgChReq->u4MaxInterval = 1; -+#endif -+ /* prBowFsmInfo->prTargetBssDesc->ucChannelNum; */ -+ prMsgChReq->ucPrimaryChannel = prBowFsmInfo->ucPrimaryChannel; -+ /* prBowFsmInfo->prTargetBssDesc->eSco; */ -+ prMsgChReq->eRfSco = CHNL_EXT_SCN; -+ /* prBowFsmInfo->prTargetBssDesc->eBand; */ -+ prMsgChReq->eRfBand = prBowFsmInfo->eBand; -+ COPY_MAC_ADDR(prMsgChReq->aucBSSID, prBowFsmInfo->aucPeerAddress); -+ -+ prBowFsmInfo->fgIsChannelRequested = TRUE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform BOW that channel privilege is granted -+* has been released -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowReleaseCh(IN P_ADAPTER_T prAdapter) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_MSG_CH_ABORT_T prMsgChAbort; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ if (prBowFsmInfo->fgIsChannelGranted != FALSE || prBowFsmInfo->fgIsChannelRequested != FALSE) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "BoW channel [RELEASE:%d] %d, %d.\n", prBowFsmInfo->ucSeqNumOfChReq, -+ prBowFsmInfo->ucPrimaryChannel, prBowFsmInfo->eBand); -+#endif -+ -+ prBowFsmInfo->fgIsChannelRequested = FALSE; -+ prBowFsmInfo->fgIsChannelGranted = FALSE; -+ -+ /* 1. return channel privilege to CNM immediately */ -+ prMsgChAbort = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T)); -+ if (!prMsgChAbort) { -+ ASSERT(0); /* Can't release Channel to CNM */ -+ return; -+ } -+ -+ prMsgChAbort->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; -+ prMsgChAbort->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ prMsgChAbort->ucTokenID = prBowFsmInfo->ucSeqNumOfChReq; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChAbort, MSG_SEND_METHOD_BUF); -+ } -+ -+} /* end of aisFsmReleaseCh() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Media Disconnect" to HOST -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowChGrantedTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ ENUM_BOW_DEVICE_STATE eFsmState; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "BoW Channel [TIMEOUT]\n"); -+#endif -+#if 1 -+ /* bowReleaseCh(prAdapter); */ -+ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); -+ -+ /*If connecting is not completed, request CH again */ -+ if ((eFsmState == BOW_DEVICE_STATE_CONNECTING) || (eFsmState == BOW_DEVICE_STATE_STARTING)) -+ bowRequestCh(prAdapter); -+#endif -+} -+ -+BOOLEAN bowNotifyAllLinkDisconnected(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucBowTableIdx = 0; -+ CMD_INFO_T rCmdInfo; -+ -+ ASSERT(prAdapter); -+ -+ kalMemZero(&rCmdInfo, sizeof(CMD_INFO_T)); -+ -+ while (ucBowTableIdx < CFG_BOW_PHYSICAL_LINK_NUM) { -+ if (arBowTable[ucBowTableIdx].fgIsValid) { -+ COPY_MAC_ADDR(prAdapter->rWifiVar.rBowFsmInfo.aucPeerAddress, -+ arBowTable[ucBowTableIdx].aucPeerAddress); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "bowNotifyAllLinkDisconnected, arBowTable[%x].aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ ucBowTableIdx, arBowTable[ucBowTableIdx].aucPeerAddress[0], -+ arBowTable[ucBowTableIdx].aucPeerAddress[1], -+ arBowTable[ucBowTableIdx].aucPeerAddress[2], -+ arBowTable[ucBowTableIdx].aucPeerAddress[3], -+ arBowTable[ucBowTableIdx].aucPeerAddress[4], -+ arBowTable[ucBowTableIdx].aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, -+ "bowNotifyAllLinkDisconnected, arBowTable[%x].fgIsValid, %x.\n", ucBowTableIdx, -+ arBowTable[ucBowTableIdx].fgIsValid); -+#endif -+#if 1 -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkDisconnected, -+ wlanbowCmdTimeoutHandler, 0, NULL, 0); -+#else -+ wlanbowCmdEventLinkDisconnected(prAdapter, &rCmdInfo, NULL); -+#endif -+ } -+ -+ ucBowTableIdx += 1; -+ } -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi state from glue layer -+* -+* \param[in] -+* prGlueInfo -+* rPeerAddr -+* \return -+* ENUM_BOW_DEVICE_STATE -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+BOOLEAN bowCheckBowTableIfVaild(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]) -+{ -+ UINT_8 idx; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { -+ if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalCheckBowifVaild, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], -+ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "kalCheckBowifVaild, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ arBowTable[idx].aucPeerAddress[0], arBowTable[idx].aucPeerAddress[1], -+ arBowTable[idx].aucPeerAddress[2], arBowTable[idx].aucPeerAddress[3], -+ arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "kalCheckBowifVaild, arBowTable[idx].fgIsValid, %x, %x.\n", idx, -+ arBowTable[idx].fgIsValid); -+ -+#endif -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ return TRUE; -+ } -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ return FALSE; -+} -+ -+BOOLEAN bowGetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, OUT P_BOW_TABLE_T prBowTable) -+{ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ if (arBowTable[ucBowTableIdx].fgIsValid) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "bowGetBowTableContent, arBowTable[idx].fgIsValid, %x, %x.\n", ucBowTableIdx, -+ arBowTable[ucBowTableIdx].fgIsValid); -+ DBGLOG(BOW, INFO, "GET State [%d]\n", arBowTable[ucBowTableIdx].eState); -+#endif -+ prBowTable = &(arBowTable[ucBowTableIdx]); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return TRUE; -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return FALSE; -+} -+ -+BOOLEAN bowSetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, IN P_BOW_TABLE_T prBowTable) -+{ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ COPY_MAC_ADDR(arBowTable[ucBowTableIdx].aucPeerAddress, prBowTable->aucPeerAddress); -+ arBowTable[ucBowTableIdx].eState = prBowTable->eState; -+ arBowTable[ucBowTableIdx].fgIsValid = prBowTable->fgIsValid; -+ arBowTable[ucBowTableIdx].ucAcquireID = prBowTable->ucAcquireID; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ kalSetBowState(prAdapter->prGlueInfo, prBowTable->eState, prBowTable->aucPeerAddress); -+ /* kalSetBowRole(prAdapter->prGlueInfo, prBowTable->ucRole, prBowTable->aucPeerAddress); */ -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "SET State [%d]\n", arBowTable[ucBowTableIdx].eState); -+ DBGLOG(BOW, EVENT, -+ "kalCheckBowifVaild, arBowTable[ucBowTableIdx].fgIsValid, %x, %x.\n", ucBowTableIdx, -+ arBowTable[ucBowTableIdx].fgIsValid); -+#endif -+ -+ return TRUE; -+ -+} -+ -+BOOLEAN -+bowGetBowTableEntryByPeerAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], OUT PUINT_8 pucBowTableIdx) -+{ -+ UINT_8 idx; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { -+ if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalCheckBowifVaild, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], -+ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, -+ "kalCheckBowifVaild, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ arBowTable[idx].aucPeerAddress[0], arBowTable[idx].aucPeerAddress[1], -+ arBowTable[idx].aucPeerAddress[2], arBowTable[idx].aucPeerAddress[3], -+ arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, -+ "kalCheckBowifVaild, arBowTable[idx].fgIsValid, %x, %x.\n", idx, -+ arBowTable[idx].fgIsValid); -+#endif -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ *pucBowTableIdx = idx; -+ -+ return TRUE; -+ } -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return FALSE; -+} -+ -+BOOLEAN bowGetBowTableFreeEntry(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucBowTableIdx) -+{ -+ UINT_8 idx; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { -+ if (!arBowTable[idx].fgIsValid) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "bowGetBowTableFreeEntry, arBowTable[idx].fgIsValid, %x, %x.\n", idx, -+ arBowTable[idx].fgIsValid); -+#endif -+ *pucBowTableIdx = idx; -+ arBowTable[idx].fgIsValid = TRUE; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return TRUE; -+ } -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return FALSE; -+} -+ -+ENUM_BOW_DEVICE_STATE bowGetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]) -+{ -+ UINT_8 idx; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { -+ if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowGetState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], -+ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, "bowGetState, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ arBowTable[idx].aucPeerAddress[0], -+ arBowTable[idx].aucPeerAddress[1], -+ arBowTable[idx].aucPeerAddress[2], -+ arBowTable[idx].aucPeerAddress[3], -+ arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, -+ "bowGetState, arBowTable[idx].fgIsValid, %x, %x.\n", idx, arBowTable[idx].fgIsValid); -+ DBGLOG(BOW, EVENT, -+ "bowGetState, arBowTable[idx].eState;, %x, %x.\n", idx, arBowTable[idx].eState); -+ DBGLOG(BOW, INFO, "GET State [%d]\n", arBowTable[idx].eState); -+#endif -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return arBowTable[idx].eState; -+ } -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return BOW_DEVICE_STATE_DISCONNECTED; -+} -+ -+BOOLEAN bowSetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], IN ENUM_BOW_DEVICE_STATE eState) -+{ -+ UINT_8 ucBowTableIdx; -+ -+ if (bowGetBowTableEntryByPeerAddress(prAdapter, aucPeerAddress, &ucBowTableIdx)) { -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ arBowTable[ucBowTableIdx].eState = eState; -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "SET State [%d]\n", eState); -+#endif -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ kalSetBowState(prAdapter->prGlueInfo, eState, aucPeerAddress); -+ return TRUE; -+ } -+ return FALSE; -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c -new file mode 100644 -index 0000000000000..1c59f861047e6 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c -@@ -0,0 +1,6240 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_lib.c#2 -+*/ -+/*! \file wlan_lib.c -+ \brief Internal driver stack will export the required procedures here for GLUE Layer. -+ -+ This file contains all routines which are exported from MediaTek 802.11 Wireless -+ LAN driver stack to GLUE Layer. -+*/ -+ -+/* -+** Log: wlan_lib.c -+** -+** 08 15 2012 eason.tsai -+** [ALPS00338170] [Need Patch] [Volunteer Patch] modify build warning -+** fix build waring for codechange -+ * -+ * 07 13 2012 cp.wu -+ * [WCXRP00001259] [MT6620 Wi-Fi][Driver][Firmware] Send a signal to firmware for termination -+ * after SDIO error has happened -+ * [driver domain] add force reset by host-to-device interrupt mechanism -+ * -+ * 06 11 2012 cp.wu -+ * [WCXRP00001252] [MT6620 Wi-Fi][Driver] Add debug message while encountering firmware response timeout -+ * output message while timeout event occurs -+ * -+ * 06 11 2012 eason.tsai -+ * NULL -+ * change from binay to hex code -+ * -+ * 06 08 2012 eason.tsai -+ * NULL -+ * Nvram context covert from 6620 to 6628 for old 6620 meta tool -+ * -+ * 05 11 2012 cp.wu -+ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience -+ * show MAC address & source while initiliazation -+ * -+ * 03 29 2012 eason.tsai -+ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define -+ * add conditional define. -+ * -+ * 03 04 2012 eason.tsai -+ * NULL -+ * modify the cal fail report code. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 16 2012 cp.wu -+ * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band -+ * configuration with corresponding network configuration correct scan result removing policy. -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with -+ * corresponding network configuration add wlanSetPreferBandByNetwork() for glue layer to invoke -+ * for setting preferred band configuration corresponding to network type. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 11 28 2011 cp.wu -+ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment -+ * when returining to ROM code -+ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware -+ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not -+ * -+ * 11 14 2011 cm.chang -+ * [WCXRP00001104] [All Wi-Fi][FW] Show init process by HW mail-box register -+ * Show FW initial ID when timeout to wait for ready bit -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 10 18 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * when powering off, always clear pending interrupts, then wait for RDY to be de-asserted -+ * -+ * 10 14 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * shorten the packet length for firmware download if no more than 2048 bytes. -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware download path in divided scatters. -+ * -+ * 10 03 2011 cp.wu -+ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware downloading aggregated path. -+ * -+ * 09 30 2011 cm.chang -+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band -+ * . -+ * -+ * 09 20 2011 cp.wu -+ * [WCXRP00000994] [MT6620 Wi-Fi][Driver] dump message for bus error and reset bus error flag while re-initialized -+ * 1. always show error message for SDIO bus errors. -+ * 2. reset bus error flag when re-initialization -+ * -+ * 08 26 2011 cm.chang -+ * [WCXRP00000952] [MT5931 Wi-Fi][FW] Handshake with BWCS before DPD/TX power calibration -+ * Fix compiling error for WinXP MT5931 driver -+ * -+ * 08 25 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS Sync ready for WinXP. -+ * -+ * 08 25 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add DFS switch. -+ * -+ * 08 24 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Update RDD test mode cases. -+ * -+ * 08 19 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * escape from normal path if any error is occurred. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * reuse firmware download logic of MT6620 for MT6628. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms. -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a -+ * disconnecting device issue. -+ * Fix GO send deauth frame issue. -+ * -+ * 07 22 2011 jeffrey.chang -+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time -+ * modify driver to set OSC stable time after f/w download -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 06 24 2011 cp.wu -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * if there is no valid address in chip, generate a new one from driver domain instead of firmware domain -+ * due to sufficient randomness -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * check with firmware for valid MAC address. -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * disable whole-chip resetting mechanism due to the need of further ECO to work as expected. -+ * -+ * 05 31 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * changed to use non-zero checking for valid bit in NVRAM content -+ * -+ * 05 27 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. -+ * -+ * 05 18 2011 cp.wu -+ * [WCXRP00000734] [MT6620 Wi-Fi][Driver] Pass PHY_PARAM in NVRAM to firmware domain -+ * pass PHY_PARAM in NVRAM from driver to firmware. -+ * -+ * 05 11 2011 cp.wu -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * correct assertion. -+ * -+ * 05 11 2011 cp.wu -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. -+ * -+ * 05 11 2011 cm.chang -+ * [WCXRP00000717] [MT5931 Wi-Fi][Driver] Handle wrong NVRAM content about AP bandwidth setting -+ * . -+ * -+ * 05 05 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * change delay from 100ms to 120ms upon DE's suggestion. -+ * -+ * 05 05 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * add delay after whole-chip resetting for MT5931 E1 ASIC. -+ * -+ * 04 22 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space -+ * process for RESET_START and RESET_END events skip power-off handshaking when RESET indication is received. -+ * -+ * 04 22 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * . -+ * -+ * 04 18 2011 cp.wu -+ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) -+ * 1) add API for glue layer to query ACPI state -+ * 2) Windows glue should not access to hardware after switched into D3 state -+ * -+ * 04 15 2011 cp.wu -+ * [WCXRP00000654] [MT6620 Wi-Fi][Driver] Add loop termination criterion for wlanAdapterStop(). -+ * add loop termination criteria for wlanAdapterStop(). -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing -+ * frame dropping cases for TC4 path -+ * 1. add nicTxGetResource() API for QM to make decisions. -+ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case. -+ * -+ * 04 06 2011 cp.wu -+ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure -+ * happend inside wlanAdapterStart invoke nicReleaseAdapterMemory() as failure handling in case -+ * wlanAdapterStart() failed unexpectedly -+ * -+ * 03 29 2011 wh.su -+ * [WCXRP00000248] [MT6620 Wi-Fi][FW]Fixed the Klockwork error -+ * fixed the kclocwork error. -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically -+ * continuous memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 10 2011 cp.wu -+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 -+ * deprecate configuration used by MT6620 E2 -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 02 25 2011 cp.wu -+ * [WCXRP00000496] [MT5931][Driver] Apply host-triggered chip reset before initializing firmware download procedures -+ * apply host-triggered chip reset mechanism before initializing firmware download procedures. -+ * -+ * 02 17 2011 eddie.chen -+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel -+ * 1) Change GetFrameAction decision when BSS is absent. -+ * 2) Check channel and resource in processing ProbeRequest -+ * -+ * 02 16 2011 cm.chang -+ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism -+ * . -+ * -+ * 02 01 2011 george.huang -+ * [WCXRP00000333] [MT5931][FW] support SRAM power control drivers -+ * init variable for CTIA. -+ * -+ * 01 27 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Support current measure mode, assigned by registry (XP only). -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result in OID handling layer when the -+ * corresponding BSS is disconnected due to beacon timeout remove from scanning result when the BSS -+ * is disconnected due to beacon timeout. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to -+ * ease physically continuous memory demands separate kalMemAlloc() into virtually-continuous -+ * and physically-continuous type to ease slab system pressure -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * while being unloaded, clear all pending interrupt then set LP-own to firmware -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay -+ * to avoid blocking to system scheduling change to use msleep() and shorten waiting interval -+ * to reduce blocking to other task while Wi-Fi driver is being loaded -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * report EEPROM used flag via NIC_CAPABILITY -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools -+ * -+ * 12 22 2010 eddie.chen -+ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry -+ * Remove controling auto rate from initial setting. The initial setting is defined by FW code. -+ * -+ * 12 15 2010 cp.wu -+ * NULL -+ * sync. with ALPS code by enabling interrupt just before leaving wlanAdapterStart() -+ * -+ * 12 08 2010 yuche.tsai -+ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in -+ * Change Param name for invitation connection. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 03 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * 1) use 8 buffers for MT5931 which is equipped with less memory -+ * 2) modify MT5931 debug level to TRACE when download is successful -+ * -+ * 11 02 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * for MT5931, adapter initialization is done *after* firmware is downloaded. -+ * -+ * 11 02 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * correct MT5931 firmware download procedure: -+ * MT5931 will download firmware first then acquire LP-OWN -+ * -+ * 11 02 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * 1) update MT5931 firmware encryption tool. (using 64-bytes unit) -+ * 2) update MT5931 firmware download procedure -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying -+ * current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add code to run WlanIST in SDIO callback. -+ * -+ * 10 27 2010 george.huang -+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function -+ * for SQA test by using E1 EVB -+ * Support registry option for disable beacon lost detection. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 26 2010 eddie.chen -+ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB -+ * Add auto rate parameter in registry. -+ * -+ * 10 25 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add option for enable/disable TX PWR gain adjustment (default: off) -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion -+ * 2. shorten polling count for shorter response time -+ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 15 2010 cp.wu -+ * [WCXRP00000103] [MT6620 Wi-Fi][Driver] Driver crashed when using WZC to connect to AP#B with connection with AP#A -+ * bugfix: always reset pointer to IEbuf to zero when keeping scanning result for the connected AP -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * divide a single function into 2 part to surpress a weird compiler warning from gcc-4.4.0 -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced -+ * by ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate unused variables which lead gcc to argue -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature -+ * Modify online scan as a run-time adjustable option (for Windows, in registry) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item -+ * use firmware reported mac address right after wlanAdapterStart() as permanent address -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with -+ * AIS associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 13 2010 cp.wu -+ * NULL -+ * acquire & release power control in oid handing wrapper. -+ * -+ * 09 09 2010 cp.wu -+ * NULL -+ * move IE to buffer head when the IE pointer is not pointed at head. -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * HIFSYS Clock Source Workaround -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * move HIF CR initialization from where after sdioSetupCardFeature() to wlanAdapterStart() -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add AT GO test configure mode under WinXP. -+ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cp.wu -+ * NULL -+ * 1) initialize variable for enabling short premable/short time slot. -+ * 2) add compile option for disabling online scan -+ * -+ * 08 13 2010 cp.wu -+ * NULL -+ * correction issue: desired phy type not initialized as ABGN mode. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 10 2010 cm.chang -+ * NULL -+ * Support EEPROM read/write in RF test mode -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * Centralize mgmt/system service procedures into independent calls. -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 13 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Reduce unnecessary type casting -+ * -+ * 07 13 2010 cp.wu -+ * -+ * use multiple queues to keep 1x/MMPDU/CMD's strict order even when there is incoming 1x frames. -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under concurrent -+ * network operation -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) ignore RSN checking when RSN is not turned on. -+ * 2) set STA-REC deactivation callback as NULL -+ * 3) add variable initialization API based on PHY configuration -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) for event packet, no need to fill RFB. -+ * 2) when wlanAdapterStart() failed, no need to initialize state machines -+ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support sync command of STA_REC -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan uninitialization procedure -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * initialize mbox & ais_fsm in wlanAdapterStart() -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change MAC address updating logic. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * simplify timer usage. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 28 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * disable interrupt then send power control command packet. -+ * -+ * 05 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) when stopping adapter, wait til RDY bit has been cleaerd. -+ * 2) set TASK_OFFLOAD as driver-core OIDs -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add CFG_STARTUP_DEBUG for debugging starting up issue. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * roll-back to rev.60. -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove redundant firmware image unloading -+ * 2) use compile-time macros to separate logic related to accquiring own -+ * -+ * 04 16 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * treat BUS access failure as kind of card removal. -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always set fw-own before driver is unloaded. -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * 2) command sequence number is now increased atomically -+ * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * finish non-glue layer access to glue variables -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * are done in adapter layer. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * ePowerCtrl is not necessary as a glue variable. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add timeout check in the kalOidComplete -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) for some OID, never do timeout expiration -+ * 2) add 2 kal API for later integration -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) eliminate unused definitions -+ * 2) ready bit will be polled for limited iteration -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * kalOidComplete is not necessary in linux -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change to use pass-in prRegInfo instead of accessing prGlueInfo directly -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change to use WIFI_TCM_ALWAYS_ON as firmware image -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * . -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding none-glue code portability -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding non-glue code portability -+ * -+ * 03 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve non-glue code portability -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * firmware download load address & start address are now configured from config.h -+ * due to the different configurations on FPGA and ASIC -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * only send CMD_NIC_POWER_CTRL in wlanAdapterStop() when card is not removed and is not in D3 state -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always send CMD_NIC_POWER_CTRL packet when nic is being halted -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+* 03 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add two option for ACK and ENCRYPTION for firmware download -+ * -+ * 03 11 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING -+ * -+ * 03 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. -+ * 2) change own-back acquiring procedure to wait for up to 16.67 seconds -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * when starting adapter, read local adminsitrated address from registry and send to firmware via CMD_BASIC_CONFIG. -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock -+ * 2) ensure wlanReleasePendingOid will clear all command queues -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add mutex to avoid multiple access to qmTxQueue simultaneously. -+ * -+ * 03 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add command/event definitions for initial states -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Added code for QM_TEST_MODE -+ * -+ * 02 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct function name .. -+ * -+ * 02 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * separate wlanProcesQueuePacket() into 2 APIs upon request -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add new API: wlanProcessQueuedPackets() -+ * -+ * 02 11 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct wlanAdapterStart -+ * -+ * 02 11 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. add logic for firmware download -+ * 2. firmware image filename and start/load address are now retrieved from registry -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement host-side firmware download logic -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * 2) firmware image length is now retrieved via NdisFileOpen -+ * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * 4) nicRxWaitResponse() revised -+ * 5) another set of TQ counter default value is added for fw-download state -+ * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * 2. follow MSDN defined behavior when associates to another AP -+ * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+ * 02 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * wlanoidSetFrequency is now implemented by RF test command. -+ * -+ * 02 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * QueryRssi is no longer w/o hardware access, it is now implemented by command/event handling loop -+ * -+ * 02 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. clear prPendingCmdInfo properly -+ * 2. while allocating memory for cmdinfo, no need to add extra 4 bytes. -+ * -+ * 01 28 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * allow MCR read/write OIDs in RF test mode -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) implement timeout mechanism when OID is pending for longer than 1 second -+ * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * 2. block TX/ordinary OID when RF test mode is engaged -+ * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * 4. correct some HAL implementation -+ * -+ * 01 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Under WinXP with SDIO, use prGlueInfo->rHifInfo.pvInformationBuffer instead of prGlueInfo->pvInformationBuffer -+** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-12-10 16:54:36 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-12-09 20:04:59 GMT mtk02752 -+** only report as connected when CFG_HIF_EMULATION_TEST is set to 1 -+** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-12-08 17:39:41 GMT mtk02752 -+** wlanoidRftestQueryAutoTest could be executed without touching hardware -+** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-12-03 16:10:26 GMT mtk01461 -+** Add debug message -+** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-12-02 22:05:33 GMT mtk02752 -+** kalOidComplete() will decrease i4OidPendingCount -+** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-12-01 23:02:36 GMT mtk02752 -+** remove unnecessary spinlock -+** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-12-01 22:50:38 GMT mtk02752 -+** use TC4 for command, maintein i4OidPendingCount -+** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-27 12:45:34 GMT mtk02752 -+** prCmdInfo should be freed when invoking wlanReleasePendingOid() to clear pending oid -+** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-24 19:55:51 GMT mtk02752 -+** wlanSendPacket & wlanRetransmitOfPendingFrames is only used in old data path -+** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-23 17:59:55 GMT mtk02752 -+** clear prPendingOID inside wlanSendCommand() when the OID didn't need to be replied. -+** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-23 14:45:29 GMT mtk02752 -+** add another version of wlanSendCommand() for command-sending only without blocking for response -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-17 22:40:44 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-11 10:14:56 GMT mtk01084 -+** modify place to invoke wlanIst -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-10-30 18:17:07 GMT mtk01084 -+** fix compiler warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-10-29 19:46:15 GMT mtk01084 -+** invoke interrupt process routine -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-10-13 21:58:24 GMT mtk01084 -+** modify for new HW architecture -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-09-09 17:26:01 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-05-20 12:21:27 GMT mtk01461 -+** Add SeqNum check when process Event Packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-05-19 10:38:44 GMT mtk01461 -+** Add wlanReleasePendingOid() for mpReset() if there is a pending OID and no available TX resource to send it. -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-04-29 15:41:34 GMT mtk01461 -+** Add handle of EVENT of CMD Result in wlanSendCommand() -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-04-22 09:11:23 GMT mtk01461 -+** Fix wlanSendCommand() for Driver Domain CR -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-04-21 09:33:56 GMT mtk01461 -+** Update wlanSendCommand() for Driver Domain Response and handle Event Packet, -+** wlanQuery/SetInformation() for enqueue CMD_INFO_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-04-17 20:00:08 GMT mtk01461 -+** Update wlanImageSectionDownload for optimized CMD process -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-04-14 20:50:51 GMT mtk01426 -+** Fixed compile error -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-04-13 16:38:40 GMT mtk01084 -+** add wifi start function -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-04-13 14:26:44 GMT mtk01084 -+** modify a parameter about FW download length -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-10 21:53:42 GMT mtk01461 -+** Update wlanSendCommand() -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-08 16:51:04 GMT mtk01084 -+** Update for the image download part -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-01 10:32:47 GMT mtk01461 -+** Add wlanSendLeftClusteredFrames() for SDIO_TX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-03-23 21:44:13 GMT mtk01461 -+** Refine TC assignment for WmmAssoc flag -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 16:51:57 GMT mtk01084 -+** modify the input argument of caller to RECLAIM_POWER_CONTROL_TO_PM() -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:27:13 GMT mtk01461 -+** Add reference code of FW Image Download -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:37 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:09:08 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 16:28:45 GMT mtk01426 -+** Init develop -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+#include "mgmt/ais_fsm.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* 6.1.1.2 Interpretation of priority parameter in MAC service primitives */ -+/* Static convert the Priority Parameter/TID(User Priority/TS Identifier) to Traffic Class */ -+const UINT_8 aucPriorityParam2TC[] = { -+ TC1_INDEX, -+ TC0_INDEX, -+ TC0_INDEX, -+ TC1_INDEX, -+ TC2_INDEX, -+ TC2_INDEX, -+ TC3_INDEX, -+ TC3_INDEX -+}; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _CODE_MAPPING_T { -+ UINT_32 u4RegisterValue; -+ INT_32 i4TxpowerOffset; -+} CODE_MAPPING_T, *P_CODE_MAPPING_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+BOOLEAN fgIsBusAccessFailed = FALSE; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define SIGNED_EXTEND(n, _sValue) \ -+ (((_sValue) & BIT((n)-1)) ? ((_sValue) | BITS(n, 31)) : \ -+ ((_sValue) & ~BITS(n, 31))) -+ -+/* TODO: Check */ -+/* OID set handlers without the need to access HW register */ -+PFN_OID_HANDLER_FUNC apfnOidSetHandlerWOHwAccess[] = { -+ wlanoidSetChannel, -+ wlanoidSetBeaconInterval, -+ wlanoidSetAtimWindow, -+ wlanoidSetFrequency, -+}; -+ -+/* TODO: Check */ -+/* OID query handlers without the need to access HW register */ -+PFN_OID_HANDLER_FUNC apfnOidQueryHandlerWOHwAccess[] = { -+ wlanoidQueryBssid, -+ wlanoidQuerySsid, -+ wlanoidQueryInfrastructureMode, -+ wlanoidQueryAuthMode, -+ wlanoidQueryEncryptionStatus, -+ wlanoidQueryPmkid, -+ wlanoidQueryNetworkTypeInUse, -+ wlanoidQueryBssidList, -+ wlanoidQueryAcpiDevicePowerState, -+ wlanoidQuerySupportedRates, -+ wlanoidQueryDesiredRates, -+ wlanoidQuery802dot11PowerSaveProfile, -+ wlanoidQueryBeaconInterval, -+ wlanoidQueryAtimWindow, -+ wlanoidQueryFrequency, -+}; -+ -+/* OID set handlers allowed in RF test mode */ -+PFN_OID_HANDLER_FUNC apfnOidSetHandlerAllowedInRFTest[] = { -+ wlanoidRftestSetTestMode, -+ wlanoidRftestSetAbortTestMode, -+ wlanoidRftestSetAutoTest, -+ wlanoidSetMcrWrite, -+ wlanoidSetEepromWrite -+}; -+ -+/* OID query handlers allowed in RF test mode */ -+PFN_OID_HANDLER_FUNC apfnOidQueryHandlerAllowedInRFTest[] = { -+ wlanoidRftestQueryAutoTest, -+ wlanoidQueryMcrRead, -+ wlanoidQueryEepromRead -+} -+ -+; -+ -+PFN_OID_HANDLER_FUNC apfnOidWOTimeoutCheck[] = { -+ wlanoidRftestSetTestMode, -+ wlanoidRftestSetAbortTestMode, -+ wlanoidSetAcpiDevicePowerState, -+}; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#if 0 /* no use */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is a private routine, which is used to check if HW access is needed -+* for the OID query/ set handlers. -+* -+* \param[IN] pfnOidHandler Pointer to the OID handler. -+* \param[IN] fgSetInfo It is a Set information handler. -+* -+* \retval TRUE This function needs HW access -+* \retval FALSE This function does not need HW access -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanIsHandlerNeedHwAccess(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo) -+{ -+ PFN_OID_HANDLER_FUNC *apfnOidHandlerWOHwAccess; -+ UINT_32 i; -+ UINT_32 u4NumOfElem; -+ -+ if (fgSetInfo) { -+ apfnOidHandlerWOHwAccess = apfnOidSetHandlerWOHwAccess; -+ u4NumOfElem = sizeof(apfnOidSetHandlerWOHwAccess) / sizeof(PFN_OID_HANDLER_FUNC); -+ } else { -+ apfnOidHandlerWOHwAccess = apfnOidQueryHandlerWOHwAccess; -+ u4NumOfElem = sizeof(apfnOidQueryHandlerWOHwAccess) / sizeof(PFN_OID_HANDLER_FUNC); -+ } -+ -+ for (i = 0; i < u4NumOfElem; i++) { -+ if (apfnOidHandlerWOHwAccess[i] == pfnOidHandler) -+ return FALSE; -+ } -+ -+ return TRUE; -+} /* wlanIsHandlerNeedHwAccess */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set flag for later handling card -+* ejected event. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+* -+* \note When surprised removal happens, Glue layer should invoke this -+* function to notify WPDD not to do any hw access. -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanCardEjected(IN P_ADAPTER_T prAdapter) -+{ -+ DEBUGFUNC("wlanCardEjected"); -+ /* INITLOG(("\n")); */ -+ -+ ASSERT(prAdapter); -+ -+ /* mark that the card is being ejected, NDIS will shut us down soon */ -+ nicTxRelease(prAdapter); -+ -+} /* wlanCardEjected */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Create adapter object -+* -+* \param prAdapter This routine is call to allocate the driver software objects. -+* If fails, return NULL. -+* \retval NULL If it fails, NULL is returned. -+* \retval NOT NULL If the adapter was initialized successfully. -+*/ -+/*----------------------------------------------------------------------------*/ -+P_ADAPTER_T wlanAdapterCreate(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_ADAPTER_T prAdpater = (P_ADAPTER_T) NULL; -+ -+ DEBUGFUNC("wlanAdapterCreate"); -+ -+ do { -+ prAdpater = (P_ADAPTER_T) kalMemAlloc(sizeof(ADAPTER_T), VIR_MEM_TYPE); -+ -+ if (!prAdpater) { -+ DBGLOG(INIT, ERROR, "Allocate ADAPTER memory ==> FAILED\n"); -+ break; -+ } -+ -+ kalMemZero(prAdpater, sizeof(ADAPTER_T)); -+ prAdpater->prGlueInfo = prGlueInfo; -+ -+ } while (FALSE); -+ -+ return prAdpater; -+} /* wlanAdapterCreate */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Destroy adapter object -+* -+* \param prAdapter This routine is call to destroy the driver software objects. -+* If fails, return NULL. -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanAdapterDestroy(IN P_ADAPTER_T prAdapter) -+{ -+ -+ if (!prAdapter) -+ return; -+ -+ kalMemFree(prAdapter, VIR_MEM_TYPE, sizeof(ADAPTER_T)); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Initialize the adapter. The sequence is -+* 1. Disable interrupt -+* 2. Read adapter configuration from EEPROM and registry, verify chip ID. -+* 3. Create NIC Tx/Rx resource. -+* 4. Initialize the chip -+* 5. Initialize the protocol -+* 6. Enable Interrupt -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS: Success -+* \retval WLAN_STATUS_FAILURE: Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanAdapterStart(IN P_ADAPTER_T prAdapter, -+ IN P_REG_INFO_T prRegInfo, IN PVOID pvFwImageMapFile, IN UINT_32 u4FwImageFileLength) -+{ -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ UINT_32 i, u4Value = 0; -+ UINT_32 u4WHISR = 0; -+ UINT_8 aucTxCount[8]; -+#if CFG_ENABLE_FW_DOWNLOAD -+ UINT_32 u4FwLoadAddr, u4ImgSecSize; -+#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD -+ UINT_32 j; -+ P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead; -+ BOOLEAN fgValidHead; -+ const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries); -+#endif -+#endif -+ enum Adapter_Start_Fail_Reason { -+ ALLOC_ADAPTER_MEM_FAIL, -+ DRIVER_OWN_FAIL, -+ INIT_ADAPTER_FAIL, -+ RAM_CODE_DOWNLOAD_FAIL, -+ WAIT_FIRMWARE_READY_FAIL, -+ FAIL_REASON_MAX -+ } eFailReason; -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanAdapterStart"); -+ -+ eFailReason = FAIL_REASON_MAX; -+ /* 4 <0> Reset variables in ADAPTER_T */ -+ prAdapter->fgIsFwOwn = TRUE; -+ prAdapter->fgIsEnterD3ReqIssued = FALSE; -+ -+ QUEUE_INITIALIZE(&(prAdapter->rPendingCmdQueue)); -+ -+ /* Initialize rWlanInfo */ -+ kalMemSet(&(prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T)); -+ -+ /* 4 <0.1> reset fgIsBusAccessFailed */ -+ fgIsBusAccessFailed = FALSE; -+ prAdapter->ulSuspendFlag = 0; -+ -+ do { -+ u4Status = nicAllocateAdapterMemory(prAdapter); -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "nicAllocateAdapterMemory Error!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = ALLOC_ADAPTER_MEM_FAIL; -+ break; -+ } -+ -+ prAdapter->u4OsPacketFilter = PARAM_PACKET_FILTER_SUPPORTED; -+ -+ DBGLOG(INIT, TRACE, "wlanAdapterStart(): Acquiring LP-OWN %d\n", fgIsResetting); -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+#if !CFG_ENABLE_FULL_PM -+ nicpmSetDriverOwn(prAdapter); -+#endif -+ -+ if (prAdapter->fgIsFwOwn == TRUE) { -+ DBGLOG(INIT, ERROR, "nicpmSetDriverOwn() failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = DRIVER_OWN_FAIL; -+ break; -+ } -+ /* 4 <1> Initialize the Adapter */ -+ u4Status = nicInitializeAdapter(prAdapter); -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "nicInitializeAdapter failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = INIT_ADAPTER_FAIL; -+ break; -+ } -+ -+ /* init wake lock before interrupt enable and tx thread */ -+ KAL_WAKE_LOCK_INIT(prAdapter, &prAdapter->rTxThreadWakeLock, "WLAN TX THREAD"); -+ -+ /* 4 <2> Initialize System Service (MGMT Memory pool and STA_REC) */ -+ nicInitSystemService(prAdapter); -+ -+ /* 4 <3> Initialize Tx */ -+ nicTxInitialize(prAdapter); -+ wlanDefTxPowerCfg(prAdapter); -+ -+ /* 4 <4> Initialize Rx */ -+ nicRxInitialize(prAdapter); -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+ if (pvFwImageMapFile == NULL) { -+ DBGLOG(INIT, ERROR, "No Firmware found!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = RAM_CODE_DOWNLOAD_FAIL; -+ break; -+ } -+ -+ /* 1. disable interrupt, download is done by polling mode only */ -+ nicDisableInterrupt(prAdapter); -+ -+ /* 2. Initialize Tx Resource to fw download state */ -+ nicTxInitResetResource(prAdapter); -+ -+ /* 3. FW download here */ -+ u4FwLoadAddr = prRegInfo->u4LoadAddress; -+ -+#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD -+ /* 3a. parse file header for decision of divided firmware download or not */ -+ prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T) pvFwImageMapFile; -+ -+ if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE && -+ prFwHead->u4CRC == wlanCRC32((PUINT_8) pvFwImageMapFile + u4CRCOffset, -+ u4FwImageFileLength - u4CRCOffset)) { -+ fgValidHead = TRUE; -+ } else { -+ fgValidHead = FALSE; -+ } -+ -+ /* 3b. engage divided firmware downloading */ -+ if (fgValidHead == TRUE) { -+ DBGLOG(INIT, TRACE, "wlanAdapterStart(): fgValidHead == TRUE\n"); -+ -+ for (i = 0; i < prFwHead->u4NumOfEntries; i++) { -+ -+#if CFG_START_ADDRESS_IS_1ST_SECTION_ADDR -+ if (i == 0) { -+ prRegInfo->u4StartAddress = prFwHead->arSection[i].u4DestAddr; -+ DBGLOG(INIT, TRACE, -+ "wlanAdapterStart(): FW start address 0x%08x\n", -+ prRegInfo->u4StartAddress); -+ } -+#endif -+ -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+ if (wlanImageSectionDownloadAggregated(prAdapter, -+ prFwHead->arSection[i].u4DestAddr, -+ prFwHead->arSection[i].u4Length, -+ (PUINT_8) pvFwImageMapFile + -+ prFwHead->arSection[i].u4Offset) != -+ WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } -+#else -+ for (j = 0; j < prFwHead->arSection[i].u4Length; j += CMD_PKT_SIZE_FOR_IMAGE) { -+ if (j + CMD_PKT_SIZE_FOR_IMAGE < prFwHead->arSection[i].u4Length) -+ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; -+ else -+ u4ImgSecSize = prFwHead->arSection[i].u4Length - j; -+ -+ if (wlanImageSectionDownload(prAdapter, -+ prFwHead->arSection[i].u4DestAddr + j, -+ u4ImgSecSize, -+ (PUINT_8) pvFwImageMapFile + -+ prFwHead->arSection[i].u4Offset + j) != -+ WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, -+ "Firmware scatter download failed %d!\n", (int)i); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ } -+#endif -+ -+ /* escape from loop if any pending error occurs */ -+ if (u4Status == WLAN_STATUS_FAILURE) -+ break; -+ } -+ } else -+#endif -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+ if (wlanImageSectionDownloadAggregated(prAdapter, -+ u4FwLoadAddr, -+ u4FwImageFileLength, -+ (PUINT_8) pvFwImageMapFile) != -+ WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } -+#else -+ for (i = 0; i < u4FwImageFileLength; i += CMD_PKT_SIZE_FOR_IMAGE) { -+ if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImageFileLength) -+ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; -+ else -+ u4ImgSecSize = u4FwImageFileLength - i; -+ -+ if (wlanImageSectionDownload(prAdapter, -+ u4FwLoadAddr + i, -+ u4ImgSecSize, -+ (PUINT_8) pvFwImageMapFile + i) != -+ WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ } -+#endif -+ -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ eFailReason = RAM_CODE_DOWNLOAD_FAIL; -+ break; -+ } -+#if !CFG_ENABLE_FW_DOWNLOAD_ACK -+ /* Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response */ -+ if (wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Firmware download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+#endif -+ -+ /* 4. send Wi-Fi Start command */ -+ DBGLOG(INIT, INFO, " send Wi-Fi Start command\n"); -+#if CFG_OVERRIDE_FW_START_ADDRESS -+ wlanConfigWifiFunc(prAdapter, TRUE, prRegInfo->u4StartAddress); -+#else -+ wlanConfigWifiFunc(prAdapter, FALSE, 0); -+#endif -+#endif -+ -+ DBGLOG(INIT, TRACE, "wlanAdapterStart(): Waiting for Ready bit..\n"); -+ /* 4 <5> check Wi-Fi FW asserts ready bit */ -+ i = 0; -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); -+ -+ if (u4Value & WCIR_WLAN_READY) { -+ DBGLOG(INIT, TRACE, "Ready bit asserted\n"); -+ break; -+ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = WAIT_FIRMWARE_READY_FAIL; -+ break; -+ } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) { -+ UINT_32 u4MailBox0; -+ -+ nicGetMailbox(prAdapter, 0, &u4MailBox0); -+ DBGLOG(INIT, ERROR, "Waiting for Ready bit: Timeout, ID=%u\n", -+ (u4MailBox0 & 0x0000FFFF)); -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = WAIT_FIRMWARE_READY_FAIL; -+ break; -+ } -+ i++; -+ kalMsleep(10); -+ } -+ -+ if (u4Status == WLAN_STATUS_SUCCESS) { -+ /* 1. reset interrupt status */ -+ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR); -+ if (HAL_IS_TX_DONE_INTR(u4WHISR)) -+ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); -+ -+ /* 2. reset TX Resource for normal operation */ -+ nicTxResetResource(prAdapter); -+ -+ /* 3. query for permanent address by polling */ -+ wlanQueryPermanentAddress(prAdapter); -+ -+#if (CFG_SUPPORT_NIC_CAPABILITY == 1) -+ /* 4. query for NIC capability */ -+ wlanQueryNicCapability(prAdapter); -+#endif -+ /* 4.1 query for compiler flags */ -+ wlanQueryCompileFlags(prAdapter); -+ -+ /* 5. Override network address */ -+ wlanUpdateNetworkAddress(prAdapter); -+ -+ /* 6. indicate disconnection as default status */ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ } -+ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ eFailReason = WAIT_FIRMWARE_READY_FAIL; -+ break; -+ } -+ -+ /* OID timeout timer initialize */ -+ cnmTimerInitTimer(prAdapter, -+ &prAdapter->rOidTimeoutTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) wlanReleasePendingOid, (ULONG) NULL); -+ -+ /* Return Indicated Rfb list timer */ -+ cnmTimerInitTimer(prAdapter, -+ &prAdapter->rReturnIndicatedRfbListTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) wlanReturnIndicatedPacketsTimeOut, (ULONG) NULL); -+ -+ /* Power state initialization */ -+ prAdapter->fgWiFiInSleepyState = FALSE; -+ prAdapter->rAcpiState = ACPI_STATE_D0; -+ -+ /* Online scan option */ -+ if (prRegInfo->fgDisOnlineScan == 0) -+ prAdapter->fgEnOnlineScan = TRUE; -+ else -+ prAdapter->fgEnOnlineScan = FALSE; -+ -+ /* Beacon lost detection option */ -+ if (prRegInfo->fgDisBcnLostDetection != 0) -+ prAdapter->fgDisBcnLostDetection = TRUE; -+ -+ /* Load compile time constant */ -+ prAdapter->rWlanInfo.u2BeaconPeriod = CFG_INIT_ADHOC_BEACON_INTERVAL; -+ prAdapter->rWlanInfo.u2AtimWindow = CFG_INIT_ADHOC_ATIM_WINDOW; -+ -+#if 1 /* set PM parameters */ -+ prAdapter->fgEnArpFilter = prRegInfo->fgEnArpFilter; -+ prAdapter->u4PsCurrentMeasureEn = prRegInfo->u4PsCurrentMeasureEn; -+ -+ prAdapter->u4UapsdAcBmp = prRegInfo->u4UapsdAcBmp; -+ -+ prAdapter->u4MaxSpLen = prRegInfo->u4MaxSpLen; -+ -+ DBGLOG(INIT, TRACE, "[1] fgEnArpFilter:0x%x, u4UapsdAcBmp:0x%x, u4MaxSpLen:0x%x", -+ prAdapter->fgEnArpFilter, prAdapter->u4UapsdAcBmp, prAdapter->u4MaxSpLen); -+ -+ prAdapter->fgEnCtiaPowerMode = FALSE; -+ -+#if CFG_SUPPORT_DBG_POWERMODE -+ prAdapter->fgEnDbgPowerMode = FALSE; -+#endif -+ -+#endif -+ -+ /* MGMT Initialization */ -+ nicInitMGMT(prAdapter, prRegInfo); -+ -+ /* Enable WZC Disassociation */ -+ prAdapter->rWifiVar.fgSupportWZCDisassociation = TRUE; -+ -+ /* Apply Rate Setting */ -+ if ((ENUM_REGISTRY_FIXED_RATE_T) (prRegInfo->u4FixedRate) < FIXED_RATE_NUM) -+ prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (prRegInfo->u4FixedRate); -+ else -+ prAdapter->rWifiVar.eRateSetting = FIXED_RATE_NONE; -+ -+ if (prAdapter->rWifiVar.eRateSetting == FIXED_RATE_NONE) { -+ /* Enable Auto (Long/Short) Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_AUTO; -+ } else if ((prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_20M_400NS && -+ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS7_20M_400NS) -+ || (prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_40M_400NS && -+ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS32_400NS)) { -+ /* Force Short Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_SHORT; -+ } else { -+ /* Force Long Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_LONG; -+ } -+ -+ /* Disable Hidden SSID Join */ -+ prAdapter->rWifiVar.fgEnableJoinToHiddenSSID = FALSE; -+ -+ /* Enable Short Slot Time */ -+ prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable = TRUE; -+ -+ /* configure available PHY type set */ -+ nicSetAvailablePhyTypeSet(prAdapter); -+ -+#if 1 /* set PM parameters */ -+ { -+#if CFG_SUPPORT_PWR_MGT -+ prAdapter->u4PowerMode = prRegInfo->u4PowerMode; -+ prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucNetTypeIndex = -+ NETWORK_TYPE_P2P_INDEX; -+ prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucPsProfile = ENUM_PSP_FAST_SWITCH; -+#else -+ prAdapter->u4PowerMode = ENUM_PSP_CONTINUOUS_ACTIVE; -+#endif -+ -+ nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, /* FIXIT */ -+ prAdapter->u4PowerMode, FALSE); -+ } -+ -+#endif -+ -+#if CFG_SUPPORT_NVRAM -+ /* load manufacture data */ -+ wlanLoadManufactureData(prAdapter, prRegInfo); -+#endif -+ -+#ifdef CONFIG_MTK_TC1_FEATURE /* 1 //keep alive packet time change from default 30secs to 20secs. //TC01// */ -+ { -+ CMD_SW_DBG_CTRL_T rCmdSwCtrl; -+ -+ rCmdSwCtrl.u4Id = 0x90100000; -+ rCmdSwCtrl.u4Data = 30; -+ DBGLOG(INIT, TRACE, "wlanAdapterStart Keepaliveapcket 0x%x, %d\n", -+ rCmdSwCtrl.u4Id, rCmdSwCtrl.u4Data); -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8) (&rCmdSwCtrl), NULL, 0); -+ } -+#endif -+ -+#if 0 -+ /* Update Auto rate parameters in FW */ -+ nicRlmArUpdateParms(prAdapter, -+ prRegInfo->u4ArSysParam0, -+ prRegInfo->u4ArSysParam1, prRegInfo->u4ArSysParam2, prRegInfo->u4ArSysParam3); -+#endif -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ /* clock gating workaround */ -+ prAdapter->fgIsClockGatingEnabled = FALSE; -+#endif -+ -+ } while (FALSE); -+ -+ if (u4Status == WLAN_STATUS_SUCCESS) { -+ /* restore to hardware default */ -+ HAL_SET_INTR_STATUS_READ_CLEAR(prAdapter); -+ HAL_SET_MAILBOX_READ_CLEAR(prAdapter, FALSE); -+ -+ /* Enable interrupt */ -+ nicEnableInterrupt(prAdapter); -+ -+ } else { -+ /* release allocated memory */ -+ switch (eFailReason) { -+ case WAIT_FIRMWARE_READY_FAIL: -+ DBGLOG(INIT, ERROR, "Wait firmware ready fail, FailReason: %d\n", -+ eFailReason); -+ g_IsNeedDoChipReset = 1; -+ kalSendAeeWarning("[Wait firmware ready fail!]", __func__); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); -+ nicRxUninitialize(prAdapter); -+ nicTxRelease(prAdapter); -+ /* System Service Uninitialization */ -+ nicUninitSystemService(prAdapter); -+ nicReleaseAdapterMemory(prAdapter); -+ break; -+ case RAM_CODE_DOWNLOAD_FAIL: -+ DBGLOG(INIT, ERROR, "Ram code download fail, FailReason: %d\n", -+ eFailReason); -+ g_IsNeedDoChipReset = 1; -+ kalSendAeeWarning("[Ram code download fail!]", __func__); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); -+ nicRxUninitialize(prAdapter); -+ nicTxRelease(prAdapter); -+ /* System Service Uninitialization */ -+ nicUninitSystemService(prAdapter); -+ nicReleaseAdapterMemory(prAdapter); -+ break; -+ case INIT_ADAPTER_FAIL: -+ nicReleaseAdapterMemory(prAdapter); -+ break; -+ case DRIVER_OWN_FAIL: -+ nicReleaseAdapterMemory(prAdapter); -+ break; -+ case ALLOC_ADAPTER_MEM_FAIL: -+ break; -+ default: -+ break; -+ } -+ } -+ -+ return u4Status; -+} /* wlanAdapterStart */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Uninitialize the adapter -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS: Success -+* \retval WLAN_STATUS_FAILURE: Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanAdapterStop(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i, u4Value = 0; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == TRUE) -+ nicDisableClockGating(prAdapter); -+#endif -+ -+ /* MGMT - unitialization */ -+ nicUninitMGMT(prAdapter); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D0 && -+#if (CFG_CHIP_RESET_SUPPORT == 1) -+ kalIsResetting() == FALSE && -+#endif -+ kalIsCardRemoved(prAdapter->prGlueInfo) == FALSE) { -+ -+ /* 0. Disable interrupt, this can be done without Driver own */ -+ nicDisableInterrupt(prAdapter); -+ -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+ /* 1. Set CMD to FW to tell WIFI to stop (enter power off state) */ -+ /* the command must be issue to firmware even in wlanRemove() */ -+ if (prAdapter->fgIsFwOwn == FALSE && wlanSendNicPowerCtrlCmd(prAdapter, 1) == WLAN_STATUS_SUCCESS) { -+ /* 2. Clear pending interrupt */ -+ i = 0; -+ while (i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { -+ i++; -+ }; -+ -+ /* 3. Wait til RDY bit has been cleaerd */ -+ i = 0; -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); -+ -+ if ((u4Value & WCIR_WLAN_READY) == 0) -+ break; -+ else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE -+ || fgIsBusAccessFailed == TRUE || i >= CFG_RESPONSE_POLLING_TIMEOUT) { -+ g_IsNeedDoChipReset = 1; -+ kalSendAeeWarning("[Read WCIR_WLAN_READY fail!]", __func__); -+ break; -+ } -+ i++; -+ kalMsleep(10); -+ } -+ } -+ -+ /* 4. Set Onwership to F/W */ -+ nicpmSetFWOwn(prAdapter, FALSE); -+ -+#if CFG_FORCE_RESET_UNDER_BUS_ERROR -+ if (HAL_TEST_FLAG(prAdapter, ADAPTER_FLAG_HW_ERR) == TRUE) { -+ /* force acquire firmware own */ -+ kalDevRegWrite(prAdapter->prGlueInfo, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); -+ -+ /* delay for 10ms */ -+ kalMdelay(10); -+ -+ /* force firmware reset via software interrupt */ -+ kalDevRegWrite(prAdapter->prGlueInfo, MCR_WSICR, WSICR_H2D_SW_INT_SET); -+ -+ /* force release firmware own */ -+ kalDevRegWrite(prAdapter->prGlueInfo, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); -+ } -+#endif -+ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ } -+ -+ nicRxUninitialize(prAdapter); -+ -+ nicTxRelease(prAdapter); -+ -+ /* System Service Uninitialization */ -+ nicUninitSystemService(prAdapter); -+ -+ nicReleaseAdapterMemory(prAdapter); -+ -+#if defined(_HIF_SPI) -+ /* Note: restore the SPI Mode Select from 32 bit to default */ -+ nicRestoreSpiDefMode(prAdapter); -+#endif -+ -+ return u4Status; -+} /* wlanAdapterStop */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by ISR (interrupt). -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* -+* \retval TRUE: NIC's interrupt -+* \retval FALSE: Not NIC's interrupt -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanISR(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgGlobalIntrCtrl) -+{ -+ ASSERT(prAdapter); -+ -+ if (fgGlobalIntrCtrl) { -+ nicDisableInterrupt(prAdapter); -+ -+ /* wlanIST(prAdapter); */ -+ } -+ -+ return TRUE; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by IST (task_let). -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanIST(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* wake up CONNSYS */ -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+ /* handle interrupts */ -+ nicProcessIST(prAdapter); -+ -+ /* re-enable HIF interrupts */ -+ nicEnableInterrupt(prAdapter); -+ -+ /* CONNSYS can decide to sleep */ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will check command queue to find out if any could be dequeued -+* and/or send to HIF to MT6620 -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* \param prCmdQue Pointer of Command Queue (in Glue Layer) -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanProcessCommandQueue(IN P_ADAPTER_T prAdapter, IN P_QUE_T prCmdQue) -+{ -+ WLAN_STATUS rStatus; -+ QUE_T rTempCmdQue, rMergeCmdQue, rStandInCmdQue; -+ P_QUE_T prTempCmdQue, prMergeCmdQue, prStandInCmdQue; -+ P_QUE_ENTRY_T prQueueEntry; -+ P_CMD_INFO_T prCmdInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ ENUM_FRAME_ACTION_T eFrameAction = FRAME_ACTION_DROP_PKT; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ /* sanity check */ -+ ASSERT(prAdapter); -+ ASSERT(prCmdQue); -+ -+ /* init */ -+ prTempCmdQue = &rTempCmdQue; -+ prMergeCmdQue = &rMergeCmdQue; -+ prStandInCmdQue = &rStandInCmdQue; -+ -+ QUEUE_INITIALIZE(prTempCmdQue); -+ QUEUE_INITIALIZE(prMergeCmdQue); -+ QUEUE_INITIALIZE(prStandInCmdQue); -+ -+ /* 4 <1> Move whole list of CMD_INFO to the temp queue */ -+ /* copy all commands to prTempCmdQue and empty prCmdQue */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); -+ -+ /* 4 <2> Dequeue from head and check it is able to be sent */ -+ /* remove the first one */ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ /* check how to handle the command: drop, queue, or tx */ -+ switch (prCmdInfo->eCmdType) { -+ case COMMAND_TYPE_GENERAL_IOCTL: -+ case COMMAND_TYPE_NETWORK_IOCTL: -+ /* command packet will be always sent */ -+ eFrameAction = FRAME_ACTION_TX_PKT; -+ break; -+ -+ case COMMAND_TYPE_SECURITY_FRAME: -+ /* inquire with QM */ -+ eFrameAction = qmGetFrameAction(prAdapter, -+ prCmdInfo->eNetworkType, -+ prCmdInfo->ucStaRecIndex, NULL, FRAME_TYPE_802_1X); -+ break; -+ -+ case COMMAND_TYPE_MANAGEMENT_FRAME: -+ /* inquire with QM */ -+ prMsduInfo = (P_MSDU_INFO_T) (prCmdInfo->prPacket); -+ -+ eFrameAction = qmGetFrameAction(prAdapter, -+ prMsduInfo->ucNetworkType, -+ prMsduInfo->ucStaRecIndex, prMsduInfo, FRAME_TYPE_MMPDU); -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+ -+ /* 4 <3> handling upon dequeue result */ -+ if (eFrameAction == FRAME_ACTION_DROP_PKT) { -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) -+ DBGLOG(TX, WARN, "Drop Security frame seqNo=%d\n", -+ prCmdInfo->ucCmdSeqNum); -+ wlanReleaseCommand(prAdapter, prCmdInfo); -+ } else if (eFrameAction == FRAME_ACTION_QUEUE_PKT) { -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) -+ DBGLOG(TX, INFO, "Queue Security frame seqNo=%d\n", -+ prCmdInfo->ucCmdSeqNum); -+ QUEUE_INSERT_TAIL(prMergeCmdQue, prQueueEntry); -+ } else if (eFrameAction == FRAME_ACTION_TX_PKT) { -+ /* 4 <4> Send the command */ -+ rStatus = wlanSendCommand(prAdapter, prCmdInfo); -+ -+ if (rStatus == WLAN_STATUS_RESOURCES) { -+ /* no more TC4 resource for further transmission */ -+ QUEUE_INSERT_TAIL(prMergeCmdQue, prQueueEntry); -+ DBGLOG(TX, EVENT, "No TC4 resource to send cmd, CID=%d, SEQ=%d, CMD type=%d, OID=%d\n", -+ prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, -+ prCmdInfo->eCmdType, prCmdInfo->fgIsOid); -+ break; -+ } else if (rStatus == WLAN_STATUS_PENDING) { -+ /* command packet which needs further handling upon response */ -+ /* i.e. we need to wait for FW's response */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ QUEUE_INSERT_TAIL(&(prAdapter->rPendingCmdQueue), prQueueEntry); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ } else { -+ /* send success or fail */ -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (rStatus == WLAN_STATUS_SUCCESS) { -+ /* send success */ -+ if (prCmdInfo->pfCmdDoneHandler) { -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, -+ prCmdInfo->pucInfoBuffer); -+ } -+ } else { -+ /* send fail */ -+ if (prCmdInfo->fgIsOid) { -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, -+ prCmdInfo->u4SetInfoLen, rStatus); -+ } -+ DBGLOG(TX, WARN, "Send CMD, status=%u, CID=%d, SEQ=%d, CMD type=%d, OID=%d\n", -+ rStatus, prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, -+ prCmdInfo->eCmdType, prCmdInfo->fgIsOid); -+ } -+ -+ /* free the command memory */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ } else { -+ -+ /* impossible, wrong eFrameAction */ -+ ASSERT(0); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ /* 4 <3> Merge back to original queue */ -+ /* 4 <3.1> Merge prMergeCmdQue & prTempCmdQue */ -+ QUEUE_CONCATENATE_QUEUES(prMergeCmdQue, prTempCmdQue); -+ -+ /* 4 <3.2> Move prCmdQue to prStandInQue, due to prCmdQue might differ due to incoming 802.1X frames */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); -+ -+ /* ??? here, prCmdQue shall be empty, why QUEUE_MOVE_ALL ??? */ -+ QUEUE_MOVE_ALL(prStandInCmdQue, prCmdQue); -+ -+ /* 4 <3.3> concatenate prStandInQue to prMergeCmdQue */ -+ QUEUE_CONCATENATE_QUEUES(prMergeCmdQue, prStandInCmdQue); -+ -+ /* 4 <3.4> then move prMergeCmdQue to prCmdQue */ -+ QUEUE_MOVE_ALL(prCmdQue, prMergeCmdQue); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanProcessCommandQueue() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will take CMD_INFO_T which carry some information of -+* incoming OID and notify the NIC_TX to send CMD. -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* \param prCmdInfo Pointer of P_CMD_INFO_T -+* -+* \retval WLAN_STATUS_SUCCESS : CMD was written to HIF and be freed(CMD Done) immediately. -+* \retval WLAN_STATUS_RESOURCE : No resource for current command, need to wait for previous -+* frame finishing their transmission. -+* \retval WLAN_STATUS_FAILURE : Get failure while access HIF or been rejected. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanSendCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ UINT_8 ucTC; /* "Traffic Class" SW(Driver) resource classification */ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ BOOLEAN pfgIsSecOrMgmt = FALSE; -+ -+ /* sanity check */ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ /* init */ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ /* DbgPrint("wlanSendCommand()\n"); */ -+ /* */ -+ /* */ -+#if DBG && 0 -+ LOG_FUNC("wlanSendCommand()\n"); -+ LOG_FUNC("CmdType %u NetworkType %u StaRecIndex %u Oid %u CID 0x%x SetQuery %u NeedResp %u CmdSeqNum %u\n", -+ prCmdInfo->eCmdType, -+ prCmdInfo->eNetworkType, -+ prCmdInfo->ucStaRecIndex, -+ prCmdInfo->fgIsOid, -+ prCmdInfo->ucCID, prCmdInfo->fgSetQuery, prCmdInfo->fgNeedResp, prCmdInfo->ucCmdSeqNum); -+#endif -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == TRUE) -+ nicDisableClockGating(prAdapter); -+#endif -+ -+ do { -+ /* <0> card removal check */ -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ rStatus = WLAN_STATUS_FAILURE; -+ break; -+ } -+ /* <1> Normal case of sending CMD Packet */ -+ if (!prCmdInfo->fgDriverDomainMCR) { -+ /* <1.1> Assign Traffic Class(TC) = TC4. */ -+ ucTC = TC4_INDEX; -+ -+ if ((prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) || -+ (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME)) -+ pfgIsSecOrMgmt = TRUE; -+ -+ /* <1.2> Check if pending packet or resource was exhausted */ -+ rStatus = nicTxAcquireResource(prAdapter, ucTC, pfgIsSecOrMgmt); -+ if (rStatus == WLAN_STATUS_RESOURCES) { -+ DbgPrint("NO Resource:%d\n", ucTC); -+ break; -+ } -+ /* <1.3> Forward CMD_INFO_T to NIC Layer */ -+ rStatus = nicTxCmd(prAdapter, prCmdInfo, ucTC); -+ -+ /* <1.4> Set Pending in response to Query Command/Need Response */ -+ if (rStatus == WLAN_STATUS_SUCCESS) { -+ if ((!prCmdInfo->fgSetQuery) || (prCmdInfo->fgNeedResp)) -+ rStatus = WLAN_STATUS_PENDING; -+ } -+ } -+ /* <2> "Special case" for access Driver Domain MCR */ -+ else { -+ -+ P_CMD_ACCESS_REG prCmdAccessReg; -+ -+ prCmdAccessReg = (P_CMD_ACCESS_REG) (prCmdInfo->pucInfoBuffer + CMD_HDR_SIZE); -+ -+ if (prCmdInfo->fgSetQuery) { -+ /* address is in DWORD unit */ -+ HAL_MCR_WR(prAdapter, (prCmdAccessReg->u4Address & BITS(2, 31)), -+ prCmdAccessReg->u4Data); -+ } else { -+ P_CMD_ACCESS_REG prEventAccessReg; -+ UINT_32 u4Address; -+ -+ u4Address = prCmdAccessReg->u4Address; -+ prEventAccessReg = (P_CMD_ACCESS_REG) prCmdInfo->pucInfoBuffer; -+ prEventAccessReg->u4Address = u4Address; -+ /* address is in DWORD unit */ -+ HAL_MCR_RD(prAdapter, prEventAccessReg->u4Address & BITS(2, 31), -+ &prEventAccessReg->u4Data); -+ } -+ } -+ -+ } while (FALSE); -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == FALSE) -+ nicEnableClockGating(prAdapter); -+#endif -+ -+ return rStatus; -+} /* end of wlanSendCommand() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief This function will release thd CMD_INFO upon its attribution -+ * -+ * \param prAdapter Pointer of Adapter Data Structure -+ * \param prCmdInfo Pointer of CMD_INFO_T -+ * -+ * \return (none) -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID wlanReleaseCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ switch (prCmdInfo->eCmdType) { -+ case COMMAND_TYPE_GENERAL_IOCTL: -+ case COMMAND_TYPE_NETWORK_IOCTL: -+ if (prCmdInfo->fgIsOid) { -+ /* for OID command, we need to do complete() to wake up kalIoctl() */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_FAILURE); -+ } -+ break; -+ -+ case COMMAND_TYPE_SECURITY_FRAME: -+ /* free packets in kalSecurityFrameSendComplete() */ -+ kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_FAILURE); -+ break; -+ -+ case COMMAND_TYPE_MANAGEMENT_FRAME: -+ prMsduInfo = (P_MSDU_INFO_T) prCmdInfo->prPacket; -+ -+ /* invoke callbacks */ -+ if (prMsduInfo->pfTxDoneHandler != NULL) -+ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER); -+ -+ GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ break; -+ -+ default: -+ /* impossible, shall not be here */ -+ ASSERT(0); -+ break; -+ } -+ -+ /* free command buffer and return the command header to command pool */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+} /* end of wlanReleaseCommand() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will search the CMD Queue to look for the pending OID and -+* compelete it immediately when system request a reset. -+* -+* \param prAdapter ointer of Adapter Data Structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanReleasePendingOid(IN P_ADAPTER_T prAdapter, IN ULONG ulData) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("wlanReleasePendingOid"); -+ -+ ASSERT(prAdapter); -+ -+ DBGLOG(OID, ERROR, "OID Timeout! Releasing pending OIDs ..\n"); -+ -+ do { -+ /* 1: Handle OID commands in pending queue */ -+ /* Clear Pending OID in prAdapter->rPendingCmdQueue */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ /* move all pending commands to prTempCmdQue and empty prCmdQue */ -+ prCmdQue = &prAdapter->rPendingCmdQueue; -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ /* get first pending command */ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->fgIsOid) { -+ if (prCmdInfo->pfCmdTimeoutHandler) { -+ prCmdInfo->pfCmdTimeoutHandler(prAdapter, prCmdInfo); -+ } else { -+ /* send complete() to wake up kalIoctl() */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); -+ } -+ -+ /* free command memory */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } else { -+ /* nothing to do so re-queue it to prCmdQue */ -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ /* 2: Clear pending OID staying in command queue */ -+ kalOidCmdClearance(prAdapter->prGlueInfo); -+ -+ /* 3: Do complete(), do we need this? because we have completed in kalOidComplete */ -+ kalOidClearance(prAdapter->prGlueInfo); -+ -+ } while (FALSE); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will search the CMD Queue to look for the pending CMD/OID for specific -+* NETWORK TYPE and compelete it immediately when system request a reset. -+* -+* \param prAdapter ointer of Adapter Data Structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanReleasePendingCMDbyNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ /* only free commands from the network interface, AIS, P2P, or BOW */ -+ -+ do { -+ /* 1: Clear Pending OID in prAdapter->rPendingCmdQueue */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ prCmdQue = &prAdapter->rPendingCmdQueue; -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ DBGLOG(P2P, TRACE, "Pending CMD for Network Type:%d\n", prCmdInfo->eNetworkType); -+ -+ if (prCmdInfo->eNetworkType == eNetworkType) { -+ if (prCmdInfo->pfCmdTimeoutHandler) { -+ prCmdInfo->pfCmdTimeoutHandler(prAdapter, prCmdInfo); -+ } else -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); -+ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } else { -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ } while (FALSE); -+ -+} /* wlanReleasePendingCMDbyNetwork */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Return the packet buffer and reallocate one to the RFB -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* \param pvPacket Pointer of returned packet -+* -+* \retval WLAN_STATUS_SUCCESS: Success -+* \retval WLAN_STATUS_FAILURE: Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanReturnPacket(IN P_ADAPTER_T prAdapter, IN PVOID pvPacket) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("wlanReturnPacket"); -+ -+ ASSERT(prAdapter); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ /* free the packet */ -+ if (pvPacket) { -+ kalPacketFree(prAdapter->prGlueInfo, pvPacket); -+ RX_ADD_CNT(prRxCtrl, RX_DATA_RETURNED_COUNT, 1); -+#if CFG_NATIVE_802_11 -+ if (GLUE_TEST_FLAG(prAdapter->prGlueInfo, GLUE_FLAG_HALT)) { -+ /*Todo:: nothing*/ -+ /*Todo:: nothing*/ -+ } -+#endif -+ } -+ -+ /* free the packet control block */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rIndicatedRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ if (!prSwRfb) { -+ ASSERT(0); -+ return; -+ } -+ -+ if (nicRxSetupRFB(prAdapter, prSwRfb)) { -+ ASSERT(0); -+ /* return; // Don't return here or it would lost SwRfb --kc */ -+ if (!timerPendingTimer(&prAdapter->rReturnIndicatedRfbListTimer)) { -+ DBGLOG(RX, WARN, -+ "wlanReturnPacket, Start ReturnIndicatedRfbList Timer (%ds)\n", -+ RX_RETURN_INDICATED_RFB_TIMEOUT_SEC); -+ cnmTimerStartTimer(prAdapter, &prAdapter->rReturnIndicatedRfbListTimer, -+ SEC_TO_MSEC(RX_RETURN_INDICATED_RFB_TIMEOUT_SEC)); -+ } -+ } -+ nicRxReturnRFB(prAdapter, prSwRfb); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Return the indicated packet buffer and reallocate one to the RFB -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* \param pvPacket Pointer of returned packet -+* -+* \retval WLAN_STATUS_SUCCESS: Success -+* \retval WLAN_STATUS_FAILURE: Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanReturnIndicatedPacketsTimeOut(IN P_ADAPTER_T prAdapter, IN ULONG ulData) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ WLAN_STATUS status = WLAN_STATUS_SUCCESS; -+ P_QUE_T prQueList; -+ -+ DEBUGFUNC("wlanReturnIndicatedPacketsTimeOut"); -+ DBGLOG(RX, WARN, "wlanReturnIndicatedPacketsTimeOut"); -+ -+ ASSERT(prAdapter); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ prQueList = &prRxCtrl->rIndicatedRfbList; -+ DBGLOG(RX, WARN, "IndicatedRfbList num = %u\n", (unsigned int)prQueList->u4NumElem); -+ -+ while (QUEUE_IS_NOT_EMPTY(&prRxCtrl->rIndicatedRfbList)) { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rIndicatedRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (nicRxSetupRFB(prAdapter, prSwRfb)) { -+ status = WLAN_STATUS_RESOURCES; -+ ASSERT(0); -+ } -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ if (status == WLAN_STATUS_RESOURCES) -+ break; -+ } -+ if (status == WLAN_STATUS_RESOURCES) { -+ DBGLOG(RX, WARN, "Start ReturnIndicatedRfbList Timer (%ds)\n", RX_RETURN_INDICATED_RFB_TIMEOUT_SEC); -+ /* restart timer */ -+ cnmTimerStartTimer(prAdapter, -+ &prAdapter->rReturnIndicatedRfbListTimer, -+ SEC_TO_MSEC(RX_RETURN_INDICATED_RFB_TIMEOUT_SEC)); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a required function that returns information about -+* the capabilities and status of the driver and/or its network adapter. -+* -+* \param[IN] prAdapter Pointer to the Adapter structure. -+* \param[IN] pfnOidQryHandler Function pointer for the OID query handler. -+* \param[IN] pvInfoBuf Points to a buffer for return the query information. -+* \param[IN] u4QueryBufferLen Specifies the number of bytes at pvInfoBuf. -+* \param[OUT] pu4QueryInfoLen Points to the number of bytes it written or is needed. -+* -+* \retval WLAN_STATUS_xxx Different WLAN_STATUS code returned by different handlers. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanQueryInformation(IN P_ADAPTER_T prAdapter, -+ IN PFN_OID_HANDLER_FUNC pfnOidQryHandler, -+ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4QryInfoLen) -+{ -+ WLAN_STATUS status = WLAN_STATUS_FAILURE; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QryInfoLen); -+ -+ /* ignore any OID request after connected, under PS current measurement mode */ -+ /* note: return WLAN_STATUS_FAILURE or WLAN_STATUS_SUCCESS for -+ * blocking OIDs during current measurement -+ */ -+ if (prAdapter->u4PsCurrentMeasureEn && -+ (prAdapter->prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED)) -+ return WLAN_STATUS_SUCCESS; -+#if 1 -+ /* most OID handler will just queue a command packet */ -+ status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen); -+#else -+ if (wlanIsHandlerNeedHwAccess(pfnOidQryHandler, FALSE)) { -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+ /* Reset sleepy state */ -+ if (prAdapter->fgWiFiInSleepyState == TRUE) -+ prAdapter->fgWiFiInSleepyState = FALSE; -+ -+ status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen); -+ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ } else -+ status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen); -+#endif -+ -+ return status; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a required function that allows bound protocol drivers, -+* or NDIS, to request changes in the state information that the miniport -+* maintains for particular object identifiers, such as changes in multicast -+* addresses. -+* -+* \param[IN] prAdapter Pointer to the Glue info structure. -+* \param[IN] pfnOidSetHandler Points to the OID set handlers. -+* \param[IN] pvInfoBuf Points to a buffer containing the OID-specific data for the set. -+* \param[IN] u4InfoBufLen Specifies the number of bytes at prSetBuffer. -+* \param[OUT] pu4SetInfoLen Points to the number of bytes it read or is needed. -+* -+* \retval WLAN_STATUS_xxx Different WLAN_STATUS code returned by different handlers. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanSetInformation(IN P_ADAPTER_T prAdapter, -+ IN PFN_OID_HANDLER_FUNC pfnOidSetHandler, -+ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS status = WLAN_STATUS_FAILURE; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ /* ignore any OID request after connected, under PS current measurement mode */ -+ /* note: return WLAN_STATUS_FAILURE or WLAN_STATUS_SUCCESS for blocking -+ * OIDs during current measurement -+ */ -+ if (prAdapter->u4PsCurrentMeasureEn && -+ (prAdapter->prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED)) -+ return WLAN_STATUS_SUCCESS; -+#if 1 -+ /* most OID handler will just queue a command packet -+ * for power state transition OIDs, handler will acquire power control by itself -+ */ -+ status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen); -+#else -+ if (wlanIsHandlerNeedHwAccess(pfnOidSetHandler, TRUE)) { -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+ /* Reset sleepy state */ -+ if (prAdapter->fgWiFiInSleepyState == TRUE) -+ prAdapter->fgWiFiInSleepyState = FALSE; -+ -+ status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen); -+ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ } else { -+ status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen); -+ } -+#endif -+ -+ return status; -+} -+ -+#if CFG_SUPPORT_WAPI -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a used to query driver's config wapi mode or not -+* -+* \param[IN] prAdapter Pointer to the Glue info structure. -+* -+* \retval TRUE for use wapi mode -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanQueryWapiMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ return prAdapter->rWifiVar.rConnSettings.fgWapiMode; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to set RX filter to Promiscuous Mode. -+* -+* \param[IN] prAdapter Pointer to the Adapter structure. -+* \param[IN] fgEnablePromiscuousMode Enable/ disable RX Promiscuous Mode. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSetPromiscuousMode(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnablePromiscuousMode) -+{ -+ ASSERT(prAdapter); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to set RX filter to allow to receive -+* broadcast address packets. -+* -+* \param[IN] prAdapter Pointer to the Adapter structure. -+* \param[IN] fgEnableBroadcast Enable/ disable broadcast packet to be received. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanRxSetBroadcast(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableBroadcast) -+{ -+ ASSERT(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to send out CMD_NIC_POWER_CTRL command packet -+* -+* \param[IN] prAdapter Pointer to the Adapter structure. -+* \param[IN] ucPowerMode refer to CMD/EVENT document -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanSendNicPowerCtrlCmd(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPowerMode) -+{ -+ WLAN_STATUS status = WLAN_STATUS_SUCCESS; -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_8 ucTC, ucCmdSeqNum; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* 1. Prepare CMD */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_NIC_POWER_CTRL))); -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* 2.1 increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); -+ -+ /* 2.2 Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + sizeof(CMD_NIC_POWER_CTRL)); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->pfCmdTimeoutHandler = NULL; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_NIC_POWER_CTRL; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_NIC_POWER_CTRL); -+ -+ /* 2.3 Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ kalMemZero(prWifiCmd->aucBuffer, sizeof(CMD_NIC_POWER_CTRL)); -+ ((P_CMD_NIC_POWER_CTRL) (prWifiCmd->aucBuffer))->ucPowerMode = ucPowerMode; -+ -+ /* 3. Issue CMD for entering specific power mode */ -+ ucTC = TC4_INDEX; -+ -+ while (1) { -+ /* 3.0 Removal check */ -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ /* 3.1 Acquire TX Resource */ -+ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { -+ -+ /* wait and poll tx resource */ -+ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); -+ status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ continue; -+ } -+ /* 3.2 Send CMD Info Packet */ -+ if (nicTxCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Fail to transmit CMD_NIC_POWER_CTRL command\n"); -+ status = WLAN_STATUS_FAILURE; -+ } -+ -+ break; -+ }; -+ -+ /* 4. Free CMD Info Packet. */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ /* 5. Add flag */ -+ if (ucPowerMode == 1) -+ prAdapter->fgIsEnterD3ReqIssued = TRUE; -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to check if it is RF test mode and -+* the OID is allowed to be called or not -+* -+* \param[IN] prAdapter Pointer to the Adapter structure. -+* \param[IN] fgEnableBroadcast Enable/ disable broadcast packet to be received. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanIsHandlerAllowedInRFTest(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo) -+{ -+ PFN_OID_HANDLER_FUNC *apfnOidHandlerAllowedInRFTest; -+ UINT_32 i; -+ UINT_32 u4NumOfElem; -+ -+ if (fgSetInfo) { -+ apfnOidHandlerAllowedInRFTest = apfnOidSetHandlerAllowedInRFTest; -+ u4NumOfElem = sizeof(apfnOidSetHandlerAllowedInRFTest) / sizeof(PFN_OID_HANDLER_FUNC); -+ } else { -+ apfnOidHandlerAllowedInRFTest = apfnOidQueryHandlerAllowedInRFTest; -+ u4NumOfElem = sizeof(apfnOidQueryHandlerAllowedInRFTest) / sizeof(PFN_OID_HANDLER_FUNC); -+ } -+ -+ for (i = 0; i < u4NumOfElem; i++) { -+ if (apfnOidHandlerAllowedInRFTest[i] == pfnOidHandler) -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to download FW image in an aggregated way -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanImageSectionDownloadAggregated(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf) -+{ -+#if defined(MT6620) || defined(MT6628) -+ P_CMD_INFO_T prCmdInfo; -+ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; -+ P_INIT_CMD_DOWNLOAD_BUF prInitCmdDownloadBuf; -+ UINT_8 ucTC, ucCmdSeqNum; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ -+ UINT_32 u4PktCnt, u4Offset, u4Length; -+ UINT_32 u4TotalLength; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucImgSecBuf); -+ -+ pucOutputBuf = prAdapter->rTxCtrl.pucTxCoalescingBufPtr; -+ -+ DEBUGFUNC("wlanImageSectionDownloadAggregated"); -+ -+ if (u4ImgSecSize == 0) -+ return WLAN_STATUS_SUCCESS; -+ /* 1. Allocate CMD Info Packet and Pre-fill Headers */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, -+ sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + -+ CMD_PKT_SIZE_FOR_IMAGE); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + CMD_PKT_SIZE_FOR_IMAGE; -+ -+ /* 2. Use TC0's resource to download image. (only TC0 is allowed) */ -+ ucTC = TC0_INDEX; -+ -+ /* 3. Setup common CMD Info Packet */ -+ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); -+ prInitHifTxHeader->ucEtherTypeOffset = 0; -+ prInitHifTxHeader->ucCSflags = 0; -+ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_DOWNLOAD_BUF; -+ -+ /* 4. Setup CMD_DOWNLOAD_BUF */ -+ prInitCmdDownloadBuf = (P_INIT_CMD_DOWNLOAD_BUF) (prInitHifTxHeader->rInitWifiCmd.aucBuffer); -+ prInitCmdDownloadBuf->u4DataMode = 0 -+#if CFG_ENABLE_FW_ENCRYPTION -+ | DOWNLOAD_BUF_ENCRYPTION_MODE -+#endif -+ ; -+ -+ /* 5.0 reset loop control variable */ -+ u4TotalLength = 0; -+ u4Offset = u4PktCnt = 0; -+ -+ /* 5.1 main loop for maximize transmission count per access */ -+ while (u4Offset < u4ImgSecSize) { -+ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_SUCCESS) { -+ /* 5.1.1 calculate u4Length */ -+ if (u4Offset + CMD_PKT_SIZE_FOR_IMAGE < u4ImgSecSize) -+ u4Length = CMD_PKT_SIZE_FOR_IMAGE; -+ else -+ u4Length = u4ImgSecSize - u4Offset; -+ -+ /* 5.1.1 increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; -+ -+ /* 5.1.2 update HIF TX hardware header */ -+ prInitHifTxHeader->u2TxByteCount = -+ ALIGN_4(sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + (UINT_16) u4Length); -+ -+ /* 5.1.3 fill command header */ -+ prInitCmdDownloadBuf->u4Address = u4DestAddr + u4Offset; -+ prInitCmdDownloadBuf->u4Length = u4Length; -+ prInitCmdDownloadBuf->u4CRC32 = wlanCRC32(pucImgSecBuf + u4Offset, u4Length); -+ -+ /* 5.1.4.1 copy header to coalescing buffer */ -+ kalMemCopy(pucOutputBuf + u4TotalLength, -+ (PVOID) prCmdInfo->pucInfoBuffer, -+ sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF)); -+ -+ /* 5.1.4.2 copy payload to coalescing buffer */ -+ kalMemCopy(pucOutputBuf + u4TotalLength + sizeof(INIT_HIF_TX_HEADER_T) + -+ sizeof(INIT_CMD_DOWNLOAD_BUF), pucImgSecBuf + u4Offset, u4Length); -+ -+ /* 5.1.4.3 update length and other variables */ -+ u4TotalLength += -+ ALIGN_4(sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + u4Length); -+ u4Offset += u4Length; -+ u4PktCnt++; -+ -+ if (u4Offset < u4ImgSecSize) -+ continue; -+ } else if (u4PktCnt == 0) { -+ /* no resource, so get some back */ -+ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); -+ break; -+ } -+ } -+ -+ if (u4PktCnt != 0) { -+ /* start transmission */ -+ HAL_WRITE_TX_PORT(prAdapter, -+ 0, -+ u4TotalLength, (PUINT_8) pucOutputBuf, prAdapter->u4CoalescingBufCachedSize); -+ -+ /* reset varaibles */ -+ u4PktCnt = 0; -+ u4TotalLength = 0; -+ } -+ } -+ -+ /* 8. Free CMD Info Packet. */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return u4Status; -+ -+#else -+#error "Only MT6620/MT6628/MT6582 supports firmware download in an aggregated way" -+ -+ return WLAN_STATUS_FAILURE; -+ -+#endif -+} -+ -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to download FW image. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanImageSectionDownload(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; -+ P_INIT_CMD_DOWNLOAD_BUF prInitCmdDownloadBuf; -+ UINT_8 ucTC, ucCmdSeqNum; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucImgSecBuf); -+ ASSERT(u4ImgSecSize <= CMD_PKT_SIZE_FOR_IMAGE); -+ -+ DEBUGFUNC("wlanImageSectionDownload"); -+ -+ if (u4ImgSecSize == 0) -+ return WLAN_STATUS_SUCCESS; -+ /* 1. Allocate CMD Info Packet and its Buffer. */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, -+ sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + u4ImgSecSize); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + (UINT_16) u4ImgSecSize; -+ -+ /* 2. Use TC0's resource to download image. (only TC0 is allowed) */ -+ ucTC = TC0_INDEX; -+ -+ /* 3. increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* 4. Setup common CMD Info Packet */ -+ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); -+ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_DOWNLOAD_BUF; -+ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; -+ -+ /* 5. Setup CMD_DOWNLOAD_BUF */ -+ prInitCmdDownloadBuf = (P_INIT_CMD_DOWNLOAD_BUF) (prInitHifTxHeader->rInitWifiCmd.aucBuffer); -+ prInitCmdDownloadBuf->u4Address = u4DestAddr; -+ prInitCmdDownloadBuf->u4Length = u4ImgSecSize; -+ prInitCmdDownloadBuf->u4CRC32 = wlanCRC32(pucImgSecBuf, u4ImgSecSize); -+ -+ prInitCmdDownloadBuf->u4DataMode = 0 -+#if CFG_ENABLE_FW_DOWNLOAD_ACK -+ | DOWNLOAD_BUF_ACK_OPTION /* ACK needed */ -+#endif -+#if CFG_ENABLE_FW_ENCRYPTION -+ | DOWNLOAD_BUF_ENCRYPTION_MODE -+#endif -+ ; -+ -+ kalMemCopy(prInitCmdDownloadBuf->aucBuffer, pucImgSecBuf, u4ImgSecSize); -+ -+ /* 6. Send FW_Download command */ -+ while (1) { -+ /* 6.1 Acquire TX Resource */ -+ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { -+ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); -+ break; -+ } -+ continue; -+ } -+ /* 6.2 Send CMD Info Packet */ -+ if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to transmit image download command\n"); -+ } -+ -+ break; -+ }; -+ -+#if CFG_ENABLE_FW_DOWNLOAD_ACK -+ /* 7. Wait for INIT_EVENT_ID_CMD_RESULT */ -+ u4Status = wlanImageSectionDownloadStatus(prAdapter, ucCmdSeqNum); -+#endif -+ -+ /* 8. Free CMD Info Packet. */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return u4Status; -+} -+ -+#if !CFG_ENABLE_FW_DOWNLOAD_ACK -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to confirm previously firmware download is done without error -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanImageQueryStatus(IN P_ADAPTER_T prAdapter) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; -+ UINT_8 aucBuffer[sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_PENDING_ERROR)]; -+ UINT_32 u4RxPktLength; -+ P_INIT_HIF_RX_HEADER_T prInitHifRxHeader; -+ P_INIT_EVENT_PENDING_ERROR prEventPendingError; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ UINT_8 ucTC, ucCmdSeqNum; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanImageQueryStatus"); -+ -+ /* 1. Allocate CMD Info Packet and it Buffer. */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, sizeof(INIT_HIF_TX_HEADER_T)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ kalMemZero(prCmdInfo, sizeof(INIT_HIF_TX_HEADER_T)); -+ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T); -+ -+ /* 2. Use TC0's resource to download image. (only TC0 is allowed) */ -+ ucTC = TC0_INDEX; -+ -+ /* 3. increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* 4. Setup common CMD Info Packet */ -+ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); -+ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_QUERY_PENDING_ERROR; -+ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; -+ -+ /* 5. Send command */ -+ while (1) { -+ /* 5.1 Acquire TX Resource */ -+ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { -+ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); -+ break; -+ } -+ continue; -+ } -+ /* 5.2 Send CMD Info Packet */ -+ if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to transmit image download command\n"); -+ } -+ -+ break; -+ }; -+ -+ /* 6. Wait for INIT_EVENT_ID_PENDING_ERROR */ -+ do { -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ u4Status = WLAN_STATUS_FAILURE; -+ } else if (nicRxWaitResponse(prAdapter, -+ 0, -+ aucBuffer, -+ sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_PENDING_ERROR), -+ &u4RxPktLength) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ } else { -+ prInitHifRxHeader = (P_INIT_HIF_RX_HEADER_T) aucBuffer; -+ -+ /* EID / SeqNum check */ -+ if (prInitHifRxHeader->rInitWifiEvent.ucEID != INIT_EVENT_ID_PENDING_ERROR) { -+ u4Status = WLAN_STATUS_FAILURE; -+ } else if (prInitHifRxHeader->rInitWifiEvent.ucSeqNum != ucCmdSeqNum) { -+ u4Status = WLAN_STATUS_FAILURE; -+ } else { -+ prEventPendingError = -+ (P_INIT_EVENT_PENDING_ERROR) (prInitHifRxHeader->rInitWifiEvent.aucBuffer); -+ if (prEventPendingError->ucStatus != 0) { /* 0 for download success */ -+ u4Status = WLAN_STATUS_FAILURE; -+ } else { -+ u4Status = WLAN_STATUS_SUCCESS; -+ } -+ } -+ } -+ } while (FALSE); -+ -+ /* 7. Free CMD Info Packet. */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return u4Status; -+} -+ -+#else -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to confirm the status of -+* previously downloaded firmware scatter -+* -+* @param prAdapter Pointer to the Adapter structure. -+* ucCmdSeqNum Sequence number of previous firmware scatter -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanImageSectionDownloadStatus(IN P_ADAPTER_T prAdapter, IN UINT_8 ucCmdSeqNum) -+{ -+ UINT_8 aucBuffer[sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_CMD_RESULT)]; -+ P_INIT_HIF_RX_HEADER_T prInitHifRxHeader; -+ P_INIT_EVENT_CMD_RESULT prEventCmdResult; -+ UINT_32 u4RxPktLength; -+ WLAN_STATUS u4Status; -+ -+ ASSERT(prAdapter); -+ -+ do { -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ DBGLOG(INIT, ERROR, "kalIsCardRemoved or fgIsBusAccessFailed\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } else if (nicRxWaitResponse(prAdapter, -+ 0, -+ aucBuffer, -+ sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_CMD_RESULT),/* 4B + 4B */ -+ &u4RxPktLength) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "nicRxWaitResponse fail\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } else { -+ prInitHifRxHeader = (P_INIT_HIF_RX_HEADER_T) aucBuffer; -+ -+ /* EID / SeqNum check */ -+ if (prInitHifRxHeader->rInitWifiEvent.ucEID != INIT_EVENT_ID_CMD_RESULT) { -+ DBGLOG(INIT, ERROR, "rInitWifiEvent.ucEID != INIT_EVENT_ID_CMD_RESULT\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ g_IsNeedDoChipReset = 1; -+ kalSendAeeWarning("[Check EID error!]", __func__); -+ } else if (prInitHifRxHeader->rInitWifiEvent.ucSeqNum != ucCmdSeqNum) { -+ DBGLOG(INIT, ERROR, "rInitWifiEvent.ucSeqNum != ucCmdSeqNum\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ g_IsNeedDoChipReset = 1; -+ kalSendAeeWarning("[Check SeqNum error!]", __func__); -+ } else { -+ prEventCmdResult = -+ (P_INIT_EVENT_CMD_RESULT) (prInitHifRxHeader->rInitWifiEvent.aucBuffer); -+ if (prEventCmdResult->ucStatus != 0) { /* 0 for download success */ -+ /* -+ 0: success -+ 1: rejected by invalid param -+ 2: rejected by incorrect CRC -+ 3: rejected by decryption failure -+ 4: unknown CMD -+ */ -+ DBGLOG(INIT, ERROR, "Read Response status error = %d\n", -+ prEventCmdResult->ucStatus); -+ u4Status = WLAN_STATUS_FAILURE; -+ } else { -+ u4Status = WLAN_STATUS_SUCCESS; -+ } -+ } -+ } -+ } while (FALSE); -+ -+ return u4Status; -+} -+ -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to start FW normal operation. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanConfigWifiFunc(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable, IN UINT_32 u4StartAddress) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; -+ P_INIT_CMD_WIFI_START prInitCmdWifiStart; -+ UINT_8 ucTC, ucCmdSeqNum; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanConfigWifiFunc"); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer. */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ kalMemZero(prCmdInfo->pucInfoBuffer, sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START)); -+ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START); -+ -+ /* 2. Always use TC0 */ -+ ucTC = TC0_INDEX; -+ -+ /* 3. increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* 4. Setup common CMD Info Packet */ -+ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); -+ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_WIFI_START; -+ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; -+ -+ prInitCmdWifiStart = (P_INIT_CMD_WIFI_START) (prInitHifTxHeader->rInitWifiCmd.aucBuffer); -+ prInitCmdWifiStart->u4Override = (fgEnable == TRUE ? 1 : 0); -+ prInitCmdWifiStart->u4Address = u4StartAddress; -+ -+ /* 5. Seend WIFI start command */ -+ while (1) { -+ /* 5.1 Acquire TX Resource */ -+ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { -+ -+ /* wait and poll tx resource */ -+ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); -+ break; -+ } -+ -+ continue; -+ } -+ /* 5.2 Send CMD Info Packet */ -+ if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to transmit WIFI start command\n"); -+ } -+ -+ break; -+ }; -+ -+ /* 6. Free CMD Info Packet. */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return u4Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate CRC32 checksum -+* -+* @param buf Pointer to the data. -+* @param len data length -+* -+* @return crc32 value -+*/ -+/*----------------------------------------------------------------------------*/ -+static const UINT_32 crc32_ccitt_table[256] = { -+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, -+ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, -+ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, -+ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, -+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, -+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, -+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, -+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, -+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, -+ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, -+ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, -+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, -+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, -+ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, -+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, -+ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, -+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, -+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, -+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, -+ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, -+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, -+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, -+ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, -+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, -+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, -+ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, -+ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, -+ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, -+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, -+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, -+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, -+ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, -+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, -+ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, -+ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, -+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, -+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, -+ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, -+ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, -+ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, -+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, -+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, -+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, -+ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, -+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, -+ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, -+ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, -+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, -+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, -+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, -+ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, -+ 0x2d02ef8d -+ }; -+ -+UINT_32 wlanCRC32(PUINT_8 buf, UINT_32 len) -+{ -+ UINT_32 i, crc32 = 0xFFFFFFFF; -+ -+ for (i = 0; i < len; i++) -+ crc32 = crc32_ccitt_table[(crc32 ^ buf[i]) & 0xff] ^ (crc32 >> 8); -+ -+ return ~crc32; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to process queued RX packets -+* -+* @param prAdapter Pointer to the Adapter structure. -+* prSwRfbListHead Pointer to head of RX packets link list -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanProcessQueuedSwRfb(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead) -+{ -+ P_SW_RFB_T prSwRfb, prNextSwRfb; -+ P_TX_CTRL_T prTxCtrl; -+ P_RX_CTRL_T prRxCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfbListHead); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ prSwRfb = prSwRfbListHead; -+ -+ do { -+ /* save next first */ -+ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb); -+ -+ switch (prSwRfb->eDst) { -+ case RX_PKT_DESTINATION_HOST: -+ /* to host */ -+ nicRxProcessPktWithoutReorder(prAdapter, prSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_FORWARD: -+ /* need ot forward */ -+ nicRxProcessForwardPkt(prAdapter, prSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_HOST_WITH_FORWARD: -+ /* to host and forward */ -+ nicRxProcessGOBroadcastPkt(prAdapter, prSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_NULL: -+ /* free it */ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ break; -+ -+ default: -+ break; -+ } -+ -+#if CFG_HIF_RX_STARVATION_WARNING -+ prRxCtrl->u4DequeuedCnt++; -+#endif -+ -+ /* check next queued packet */ -+ prSwRfb = prNextSwRfb; -+ } while (prSwRfb); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to purge queued TX packets -+* by indicating failure to OS and returned to free list -+* -+* @param prAdapter Pointer to the Adapter structure. -+* prMsduInfoListHead Pointer to head of TX packets link list -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanProcessQueuedMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfoListHead); -+ -+ nicTxFreeMsduInfoPacket(prAdapter, prMsduInfoListHead); -+ nicTxReturnMsduInfo(prAdapter, prMsduInfoListHead); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to check if the OID handler needs timeout -+* -+* @param prAdapter Pointer to the Adapter structure. -+* pfnOidHandler Pointer to the OID handler -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanoidTimeoutCheck(IN P_ADAPTER_T prAdapter, IN PFN_OID_HANDLER_FUNC pfnOidHandler) -+{ -+ PFN_OID_HANDLER_FUNC *apfnOidHandlerWOTimeoutCheck; -+ UINT_32 i; -+ UINT_32 u4NumOfElem; -+ -+ apfnOidHandlerWOTimeoutCheck = apfnOidWOTimeoutCheck; -+ u4NumOfElem = sizeof(apfnOidWOTimeoutCheck) / sizeof(PFN_OID_HANDLER_FUNC); -+ -+ /* skip some OID timeout checks ? */ -+ for (i = 0; i < u4NumOfElem; i++) { -+ if (apfnOidHandlerWOTimeoutCheck[i] == pfnOidHandler) -+ return FALSE; -+ } -+ -+ /* set timer if need timeout check */ -+ /* cnmTimerStartTimer(prAdapter, */ -+ /* &(prAdapter->rOidTimeoutTimer), */ -+ /* 1000); */ -+ cnmTimerStartTimer(prAdapter, &(prAdapter->rOidTimeoutTimer), 2000); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to clear any pending OID timeout check -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanoidClearTimeoutCheck(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ cnmTimerStopTimer(prAdapter, &(prAdapter->rOidTimeoutTimer)); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to update network address in firmware domain -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return WLAN_STATUS_FAILURE The request could not be processed -+* WLAN_STATUS_PENDING The request has been queued for later processing -+* WLAN_STATUS_SUCCESS The request has been processed -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanUpdateNetworkAddress(IN P_ADAPTER_T prAdapter) -+{ -+ const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; -+ PARAM_MAC_ADDRESS rMacAddr = {0}; -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_CMD_BASIC_CONFIG prCmdBasicConfig; -+ UINT_32 u4SysTime; -+ -+ DEBUGFUNC("wlanUpdateNetworkAddress"); -+ -+ ASSERT(prAdapter); -+ -+ if (kalRetrieveNetworkAddress(prAdapter->prGlueInfo, &rMacAddr) == FALSE || IS_BMCAST_MAC_ADDR(rMacAddr) -+ || EQUAL_MAC_ADDR(aucZeroMacAddr, rMacAddr)) { -+ /* eFUSE has a valid address, don't do anything */ -+ if (prAdapter->fgIsEmbbededMacAddrValid == TRUE) { -+#if CFG_SHOW_MACADDR_SOURCE -+ DBGLOG(INIT, INFO, "Using embedded MAC address"); -+#endif -+ return WLAN_STATUS_SUCCESS; -+ } -+#if CFG_SHOW_MACADDR_SOURCE -+ DBGLOG(INIT, TRACE, "Using dynamically generated MAC address"); -+#endif -+ /* dynamic generate */ -+ u4SysTime = kalGetTimeTick(); -+ -+ rMacAddr[0] = 0x00; -+ rMacAddr[1] = 0x08; -+ rMacAddr[2] = 0x22; -+ -+ kalMemCopy(&rMacAddr[3], &u4SysTime, 3); -+ } else { -+#if CFG_SHOW_MACADDR_SOURCE -+ DBGLOG(INIT, INFO, "Using host-supplied MAC address"); -+#endif -+ } -+ -+ /* allocate command memory */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->pfCmdTimeoutHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_BASIC_CONFIG; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_BASIC_CONFIG); -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ /* configure CMD_BASIC_CONFIG */ -+ prCmdBasicConfig = (P_CMD_BASIC_CONFIG) (prWifiCmd->aucBuffer); -+ kalMemCopy(&(prCmdBasicConfig->rMyMacAddr), &rMacAddr, PARAM_MAC_ADDR_LEN); -+ prCmdBasicConfig->ucNative80211 = 0; -+ prCmdBasicConfig->rCsumOffload.u2RxChecksum = 0; -+ prCmdBasicConfig->rCsumOffload.u2TxChecksum = 0; -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP) -+ prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(2); -+ -+ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP) -+ prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(1); -+ -+ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_IP) -+ prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(0); -+ -+ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_RX_TCP) -+ prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(2); -+ -+ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_RX_UDP) -+ prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(1); -+ -+ if (prAdapter->u4CSUMFlags & (CSUM_OFFLOAD_EN_RX_IPv4 | CSUM_OFFLOAD_EN_RX_IPv6)) -+ prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(0); -+#endif -+ -+ /* send the command to FW */ -+ if (wlanSendCommand(prAdapter, prCmdInfo) == WLAN_STATUS_RESOURCES) { -+ -+ /* backup the command to wait response */ -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventQueryAddress; -+ kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ return WLAN_STATUS_PENDING; -+ } -+ /* send ok without response */ -+ nicCmdEventQueryAddress(prAdapter, prCmdInfo, (PUINT_8) prCmdBasicConfig); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to check if the device is in RF test mode -+* -+* @param pfnOidHandler Pointer to the OID handler -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanQueryTestMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ return prAdapter->fgTestMode; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to identify 802.1x and Bluetooth-over-Wi-Fi -+* security frames, and queued into command queue for strict ordering -+* due to 802.1x frames before add-key OIDs are not to be encrypted -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param prPacket Pointer of native packet -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanProcessSecurityFrame(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prPacket) -+{ -+ UINT_8 ucPriorityParam; -+ UINT_8 aucEthDestAddr[PARAM_MAC_ADDR_LEN]; -+ BOOLEAN fgIs1x = FALSE; -+ BOOLEAN fgIsPAL = FALSE; -+ UINT_32 u4PacketLen; -+ ULONG u4SysTime; -+ UINT_8 ucNetworkType; -+ P_CMD_INFO_T prCmdInfo; -+ UINT_8 ucCmdSeqNo = 0; -+ -+ /* 1x data packets */ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prPacket); -+ -+ /* retrieve some information for packet classification */ -+ if (kalQoSFrameClassifierAndPacketInfo(prAdapter->prGlueInfo, -+ prPacket, -+ &ucPriorityParam, -+ &u4PacketLen, -+ aucEthDestAddr, -+ &fgIs1x, -+ &fgIsPAL, -+ &ucNetworkType, -+ &ucCmdSeqNo) == TRUE) { -+ /* almost TRUE except frame length < 14B */ -+ -+ if (fgIs1x == FALSE) -+ return FALSE; -+ -+ /* get a free command entry */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ -+ if (prCmdInfo) { -+ P_STA_RECORD_T prStaRec; -+ -+ /* fill arrival time */ -+ u4SysTime = (OS_SYSTIME) kalGetTimeTick(); -+ GLUE_SET_PKT_ARRIVAL_TIME(prPacket, u4SysTime); -+ -+ kalMemZero(prCmdInfo, sizeof(CMD_INFO_T)); -+ -+ prCmdInfo->eCmdType = COMMAND_TYPE_SECURITY_FRAME; -+ prCmdInfo->u2InfoBufLen = (UINT_16) u4PacketLen; -+ prCmdInfo->pucInfoBuffer = NULL; -+ prCmdInfo->prPacket = prPacket; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNo; -+#if 0 -+ prCmdInfo->ucStaRecIndex = qmGetStaRecIdx(prAdapter, -+ aucEthDestAddr, -+ (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType); -+#endif -+ prStaRec = cnmGetStaRecByAddress(prAdapter, -+ (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType, -+ aucEthDestAddr); -+ if (prStaRec) -+ prCmdInfo->ucStaRecIndex = prStaRec->ucIndex; -+ else -+ prCmdInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; -+ -+ prCmdInfo->eNetworkType = (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType; -+ prCmdInfo->pfCmdDoneHandler = wlanSecurityFrameTxDone; -+ prCmdInfo->pfCmdTimeoutHandler = wlanSecurityFrameTxTimeout; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ -+ /* -+ queue the 1x packet and we will send the packet to CONNSYS by -+ using command queue -+ */ -+ kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* TRUE: means we have already handled it in the function */ -+ return TRUE; -+ } -+ -+ /* no memory, why assert ? can skip the packet ? */ -+ ASSERT(0); -+ return FALSE; -+ } -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when 802.1x or Bluetooth-over-Wi-Fi -+* security frames has been sent to firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param prCmdInfo Pointer of CMD_INFO_T -+* @param pucEventBuf meaningless, only for API compatibility -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSecurityFrameTxDone(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ if (prCmdInfo->eNetworkType == NETWORK_TYPE_AIS_INDEX && -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure) { -+ -+ /* AIS counter measure so change RSN FSM to SEND_DEAUTH state */ -+ P_STA_RECORD_T prSta = cnmGetStaRecByIndex(prAdapter, prCmdInfo->ucStaRecIndex); -+ -+ if (prSta) { -+ kalMsleep(10); -+ secFsmEventEapolTxDone(prAdapter, prSta, TX_RESULT_SUCCESS); -+ } -+ } -+ -+ /* free the packet */ -+ kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_SUCCESS); -+ DBGLOG(TX, INFO, "Security frame tx done, SeqNum: %d\n", prCmdInfo->ucCmdSeqNum); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when 802.1x or Bluetooth-over-Wi-Fi -+* security frames has failed sending to firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param prCmdInfo Pointer of CMD_INFO_T -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSecurityFrameTxTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ /* free the packet */ -+ kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_FAILURE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called before AIS is starting a new scan -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanClearScanningResult(IN P_ADAPTER_T prAdapter) -+{ -+ BOOLEAN fgKeepCurrOne = FALSE; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ /* clear scanning result except current one */ -+ /* copy current one to prAdapter->rWlanInfo.arScanResult[0] */ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, -+ prAdapter->rWlanInfo.arScanResult[i].arMacAddress)) { -+ fgKeepCurrOne = TRUE; -+ -+ if (i != 0) { -+ /* copy structure */ -+ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[0]), -+ &(prAdapter->rWlanInfo.arScanResult[i]), -+ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ } -+ -+ if (prAdapter->rWlanInfo.arScanResult[i].u4IELength > 0) { -+ if (prAdapter->rWlanInfo.apucScanResultIEs[i] != -+ &(prAdapter->rWlanInfo.aucScanIEBuf[0])) { -+ /* move IEs to head */ -+ kalMemCopy(prAdapter->rWlanInfo.aucScanIEBuf, -+ prAdapter->rWlanInfo.apucScanResultIEs[i], -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength); -+ } -+ /* modify IE pointer */ -+ prAdapter->rWlanInfo.apucScanResultIEs[0] = -+ &(prAdapter->rWlanInfo.aucScanIEBuf[0]); -+ } else { -+ prAdapter->rWlanInfo.apucScanResultIEs[0] = NULL; -+ } -+ -+ break; -+ } -+ } -+ } -+ -+ if (fgKeepCurrOne == TRUE) { -+ prAdapter->rWlanInfo.u4ScanResultNum = 1; -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage = ALIGN_4(prAdapter->rWlanInfo.arScanResult[0].u4IELength); -+ } else { -+ prAdapter->rWlanInfo.u4ScanResultNum = 0; -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage = 0; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when AIS received a beacon timeout event -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param arBSSID MAC address of the specified BSS -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanClearBssInScanningResult(IN P_ADAPTER_T prAdapter, IN PUINT_8 arBSSID) -+{ -+ UINT_32 i, j, u4IELength = 0, u4IEMoveLength; -+ PUINT_8 pucIEPtr; -+ -+ ASSERT(prAdapter); -+ -+ /* clear the scanning result for arBSSID */ -+ i = 0; -+ while (1) { -+ if (i >= prAdapter->rWlanInfo.u4ScanResultNum) -+ break; -+ -+ if (EQUAL_MAC_ADDR(arBSSID, prAdapter->rWlanInfo.arScanResult[i].arMacAddress)) { -+ -+ /* backup current IE length */ -+ u4IELength = ALIGN_4(prAdapter->rWlanInfo.arScanResult[i].u4IELength); -+ pucIEPtr = prAdapter->rWlanInfo.apucScanResultIEs[i]; -+ -+ /* removed from middle */ -+ for (j = i + 1; j < prAdapter->rWlanInfo.u4ScanResultNum; j++) { -+ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[j - 1]), -+ &(prAdapter->rWlanInfo.arScanResult[j]), -+ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ -+ prAdapter->rWlanInfo.apucScanResultIEs[j - 1] = -+ prAdapter->rWlanInfo.apucScanResultIEs[j]; -+ } -+ -+ prAdapter->rWlanInfo.u4ScanResultNum--; -+ -+ /* remove IE buffer if needed := move rest of IE buffer */ -+ if (u4IELength > 0) { -+ u4IEMoveLength = prAdapter->rWlanInfo.u4ScanIEBufferUsage - -+ (((ULONG) pucIEPtr) + (ULONG) u4IELength - -+ ((ULONG) (&(prAdapter->rWlanInfo.aucScanIEBuf[0])))); -+ -+ kalMemCopy(pucIEPtr, pucIEPtr + u4IELength, u4IEMoveLength); -+ -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage -= u4IELength; -+ -+ /* correction of pointers to IE buffer */ -+ for (j = 0; j < prAdapter->rWlanInfo.u4ScanResultNum; j++) { -+ if (prAdapter->rWlanInfo.apucScanResultIEs[j] > pucIEPtr) { -+ prAdapter->rWlanInfo.apucScanResultIEs[j] = -+ (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[j]) - -+ u4IELength); -+ } -+ } -+ } -+ } -+ -+ i++; -+ } -+ -+} -+ -+#if CFG_TEST_WIFI_DIRECT_GO -+VOID wlanEnableP2pFunction(IN P_ADAPTER_T prAdapter) -+{ -+#if 0 -+ P_MSG_P2P_FUNCTION_SWITCH_T prMsgFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) NULL; -+ -+ prMsgFuncSwitch = -+ (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ if (!prMsgFuncSwitch) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prMsgFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ prMsgFuncSwitch->fgIsFuncOn = TRUE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgFuncSwitch, MSG_SEND_METHOD_BUF); -+#endif -+ -+} -+ -+VOID wlanEnableATGO(IN P_ADAPTER_T prAdapter) -+{ -+ -+ P_MSG_P2P_CONNECTION_REQUEST_T prMsgConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; -+ UINT_8 aucTargetDeviceID[MAC_ADDR_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -+ -+ prMsgConnReq = -+ (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_REQUEST_T)); -+ if (!prMsgConnReq) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prMsgConnReq->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; -+ -+ /*=====Param Modified for test=====*/ -+ COPY_MAC_ADDR(prMsgConnReq->aucDeviceID, aucTargetDeviceID); -+ prMsgConnReq->fgIsTobeGO = TRUE; -+ prMsgConnReq->fgIsPersistentGroup = FALSE; -+ -+ /*=====Param Modified for test=====*/ -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgConnReq, MSG_SEND_METHOD_BUF); -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to retrieve permanent address from firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryPermanentAddress(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_32 u4RxPktLength; -+ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(EVENT_BASIC_CONFIG)]; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_WIFI_EVENT_T prEvent; -+ P_EVENT_BASIC_CONFIG prEventBasicConfig; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanQueryPermanentAddress"); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG)); -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_BASIC_CONFIG; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = TRUE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_BASIC_CONFIG); -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ /* send the command */ -+ wlanSendCommand(prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ /* wait for response */ -+ if (nicRxWaitResponse(prAdapter, -+ 1, -+ aucBuffer, -+ sizeof(WIFI_EVENT_T) + sizeof(EVENT_BASIC_CONFIG), /* 8B + 12B */ -+ &u4RxPktLength) != WLAN_STATUS_SUCCESS) -+ return WLAN_STATUS_FAILURE; -+ /* header checking .. */ -+ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; -+ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) -+ return WLAN_STATUS_FAILURE; -+ -+ prEvent = (P_WIFI_EVENT_T) aucBuffer; -+ if (prEvent->ucEID != EVENT_ID_BASIC_CONFIG) -+ return WLAN_STATUS_FAILURE; -+ -+ prEventBasicConfig = (P_EVENT_BASIC_CONFIG) (prEvent->aucBuffer); -+ -+ COPY_MAC_ADDR(prAdapter->rWifiVar.aucPermanentAddress, &(prEventBasicConfig->rMyMacAddr)); -+ COPY_MAC_ADDR(prAdapter->rWifiVar.aucMacAddress, &(prEventBasicConfig->rMyMacAddr)); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to retrieve NIC capability from firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryNicCapability(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_32 u4RxPktLength; -+ UINT_32 u4FwIDVersion = 0; -+ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(EVENT_NIC_CAPABILITY)]; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_WIFI_EVENT_T prEvent; -+ P_EVENT_NIC_CAPABILITY prEventNicCapability; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanQueryNicCapability"); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(EVENT_NIC_CAPABILITY)); -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(EVENT_NIC_CAPABILITY); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_GET_NIC_CAPABILITY; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = TRUE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = 0; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ /* send the command */ -+ wlanSendCommand(prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ /* wait for FW response */ -+ if (nicRxWaitResponse(prAdapter, -+ 1, -+ aucBuffer, -+ sizeof(WIFI_EVENT_T) + sizeof(EVENT_NIC_CAPABILITY), -+ &u4RxPktLength) != WLAN_STATUS_SUCCESS) -+ return WLAN_STATUS_FAILURE; -+ /* header checking .. */ -+ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; -+ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) -+ return WLAN_STATUS_FAILURE; -+ -+ prEvent = (P_WIFI_EVENT_T) aucBuffer; -+ if (prEvent->ucEID != EVENT_ID_NIC_CAPABILITY) -+ return WLAN_STATUS_FAILURE; -+ -+ prEventNicCapability = (P_EVENT_NIC_CAPABILITY) (prEvent->aucBuffer); -+ -+ prAdapter->rVerInfo.u2FwProductID = prEventNicCapability->u2ProductID; -+ prAdapter->rVerInfo.u2FwOwnVersion = prEventNicCapability->u2FwVersion; -+ prAdapter->rVerInfo.u2FwPeerVersion = prEventNicCapability->u2DriverVersion; -+ prAdapter->fgIsHw5GBandDisabled = (BOOLEAN) prEventNicCapability->ucHw5GBandDisabled; -+ prAdapter->fgIsEepromUsed = (BOOLEAN) prEventNicCapability->ucEepromUsed; -+ prAdapter->fgIsEfuseValid = (BOOLEAN) prEventNicCapability->ucEfuseValid; -+ prAdapter->fgIsEmbbededMacAddrValid = (BOOLEAN) prEventNicCapability->ucMacAddrValid; -+ -+ u4FwIDVersion = (prAdapter->rVerInfo.u2FwProductID << 16) | (prAdapter->rVerInfo.u2FwOwnVersion); -+ mtk_wcn_wmt_set_wifi_ver(u4FwIDVersion); -+#if (CFG_SUPPORT_TDLS == 1) -+ if (prEventNicCapability->ucFeatureSet & (1 << FEATURE_SET_OFFSET_TDLS)) -+ prAdapter->fgTdlsIsSup = TRUE; -+ DBGLOG(TDLS, TRACE, " support flag: 0x%x\n", prEventNicCapability->ucFeatureSet); -+#else -+ prAdapter->fgTdlsIsSup = 0; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ if (!(prEventNicCapability->ucFeatureSet & (1 << FEATURE_SET_OFFSET_5G_SUPPORT))) -+ prAdapter->fgEnable5GBand = FALSE; /* firmware does not support */ -+ -+#if CFG_ENABLE_CAL_LOG -+ DBGLOG(INIT, LOUD, " RF CAL FAIL = (%d),BB CAL FAIL = (%d)\n", -+ prEventNicCapability->ucRfCalFail, prEventNicCapability->ucBbCalFail); -+#endif -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to retrieve NIC capability from firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryDebugCode(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanQueryDebugCode"); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE); -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE; -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_GET_DEBUG_CODE; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = 0; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ /* send the command */ -+ wlanSendCommand(prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to retrieve compiler flag from firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryCompileFlag(IN P_ADAPTER_T prAdapter, IN UINT_32 u4QueryID, OUT PUINT_32 pu4CompilerFlag) -+{ -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_32 u4RxPktLength; -+ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(CMD_SW_DBG_CTRL_T)]; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_WIFI_EVENT_T prEvent; -+ P_CMD_SW_DBG_CTRL_T prCmdNicCompileFlag, prEventNicCompileFlag; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC(__func__); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_SW_DBG_CTRL_T)); -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_SW_DBG_CTRL_T); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_SW_DBG_CTRL; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = TRUE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = 0; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ /* Fill up SW CR */ -+ prCmdNicCompileFlag = (P_CMD_SW_DBG_CTRL_T) (prWifiCmd->aucBuffer); -+ -+ prCmdNicCompileFlag->u4Id = u4QueryID; -+ -+ wlanSendCommand(prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ if (nicRxWaitResponse(prAdapter, -+ 1, -+ aucBuffer, -+ sizeof(WIFI_EVENT_T) + sizeof(CMD_SW_DBG_CTRL_T), -+ &u4RxPktLength) != WLAN_STATUS_SUCCESS) -+ return WLAN_STATUS_FAILURE; -+ /* header checking .. */ -+ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; -+ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) -+ return WLAN_STATUS_FAILURE; -+ -+ prEvent = (P_WIFI_EVENT_T) aucBuffer; -+ if (prEvent->ucEID != EVENT_ID_SW_DBG_CTRL) -+ return WLAN_STATUS_FAILURE; -+ -+ prEventNicCompileFlag = (P_CMD_SW_DBG_CTRL_T) (prEvent->aucBuffer); -+ -+ *pu4CompilerFlag = prEventNicCompileFlag->u4Data; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS wlanQueryCompileFlags(IN P_ADAPTER_T prAdapter) -+{ -+ wlanQueryCompileFlag(prAdapter, 0xA0240000, &prAdapter->u4FwCompileFlag0); -+ wlanQueryCompileFlag(prAdapter, 0xA0240001, &prAdapter->u4FwCompileFlag1); -+ -+ DBGLOG(INIT, TRACE, -+ "Compile Flags: 0x%08x 0x%08x\n", prAdapter->u4FwCompileFlag0, prAdapter->u4FwCompileFlag1); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if defined(MT6628) -+static INT_32 wlanChangeCodeWord(INT_32 au4Input) -+{ -+ -+ UINT_16 i; -+#if TXPWR_USE_PDSLOPE -+ CODE_MAPPING_T arCodeTable[] = { -+ {0X100, -40}, -+ {0X104, -35}, -+ {0X128, -30}, -+ {0X14C, -25}, -+ {0X170, -20}, -+ {0X194, -15}, -+ {0X1B8, -10}, -+ {0X1DC, -5}, -+ {0, 0}, -+ {0X24, 5}, -+ {0X48, 10}, -+ {0X6C, 15}, -+ {0X90, 20}, -+ {0XB4, 25}, -+ {0XD8, 30}, -+ {0XFC, 35}, -+ {0XFF, 40}, -+ -+ }; -+#else -+ CODE_MAPPING_T arCodeTable[] = { -+ {0X100, 0x80}, -+ {0X104, 0x80}, -+ {0X128, 0x80}, -+ {0X14C, 0x80}, -+ {0X170, 0x80}, -+ {0X194, 0x94}, -+ {0X1B8, 0XB8}, -+ {0X1DC, 0xDC}, -+ {0, 0}, -+ {0X24, 0x24}, -+ {0X48, 0x48}, -+ {0X6C, 0x6c}, -+ {0X90, 0x7F}, -+ {0XB4, 0x7F}, -+ {0XD8, 0x7F}, -+ {0XFC, 0x7F}, -+ {0XFF, 0x7F}, -+ -+ }; -+#endif -+ -+ for (i = 0; i < sizeof(arCodeTable) / sizeof(CODE_MAPPING_T); i++) { -+ -+ if (arCodeTable[i].u4RegisterValue == au4Input) -+ return arCodeTable[i].i4TxpowerOffset; -+ } -+ -+ return 0; -+} -+#endif -+ -+#if TXPWR_USE_PDSLOPE -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryPdMcr(IN P_ADAPTER_T prAdapter, P_PARAM_MCR_RW_STRUCT_T prMcrRdInfo) -+{ -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_32 u4RxPktLength; -+ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(CMD_ACCESS_REG)]; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_WIFI_EVENT_T prEvent; -+ P_CMD_ACCESS_REG prCmdMcrQuery; -+ -+ ASSERT(prAdapter); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_ACCESS_REG)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + sizeof(CMD_ACCESS_REG)); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_ACCESS_REG; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = TRUE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_ACCESS_REG); -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ kalMemCopy(prWifiCmd->aucBuffer, prMcrRdInfo, sizeof(CMD_ACCESS_REG)); -+ -+ wlanSendCommand(prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ if (nicRxWaitResponse(prAdapter, -+ 1, -+ aucBuffer, -+ sizeof(WIFI_EVENT_T) + sizeof(CMD_ACCESS_REG), &u4RxPktLength) != WLAN_STATUS_SUCCESS) -+ return WLAN_STATUS_FAILURE; -+ /* header checking .. */ -+ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; -+ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) -+ return WLAN_STATUS_FAILURE; -+ -+ prEvent = (P_WIFI_EVENT_T) aucBuffer; -+ -+ if (prEvent->ucEID != EVENT_ID_ACCESS_REG) -+ return WLAN_STATUS_FAILURE; -+ -+ prCmdMcrQuery = (P_CMD_ACCESS_REG) (prEvent->aucBuffer); -+ prMcrRdInfo->u4McrOffset = prCmdMcrQuery->u4Address; -+ prMcrRdInfo->u4McrData = prCmdMcrQuery->u4Data; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+static INT_32 wlanIntRound(INT_32 au4Input) -+{ -+ -+ if (au4Input >= 0) { -+ if ((au4Input % 10) == 5) { -+ au4Input = au4Input + 5; -+ return au4Input; -+ } -+ } -+ -+ if (au4Input < 0) { -+ if ((au4Input % 10) == -5) { -+ au4Input = au4Input - 5; -+ return au4Input; -+ } -+ } -+ -+ return au4Input; -+} -+ -+static INT_32 wlanCal6628EfuseForm(IN P_ADAPTER_T prAdapter, INT_32 au4Input) -+{ -+ -+ PARAM_MCR_RW_STRUCT_T rMcrRdInfo; -+ INT_32 au4PdSlope, au4TxPwrOffset, au4TxPwrOffset_Round; -+ INT_8 auTxPwrOffset_Round; -+ -+ rMcrRdInfo.u4McrOffset = 0x60205c68; -+ rMcrRdInfo.u4McrData = 0; -+ au4TxPwrOffset = au4Input; -+ wlanQueryPdMcr(prAdapter, &rMcrRdInfo); -+ -+ au4PdSlope = (rMcrRdInfo.u4McrData) & BITS(0, 6); -+ au4TxPwrOffset_Round = wlanIntRound((au4TxPwrOffset * au4PdSlope)) / 10; -+ -+ au4TxPwrOffset_Round = -au4TxPwrOffset_Round; -+ -+ if (au4TxPwrOffset_Round < -128) -+ au4TxPwrOffset_Round = 128; -+ else if (au4TxPwrOffset_Round < 0) -+ au4TxPwrOffset_Round += 256; -+ else if (au4TxPwrOffset_Round > 127) -+ au4TxPwrOffset_Round = 127; -+ -+ auTxPwrOffset_Round = (UINT8) au4TxPwrOffset_Round; -+ -+ return au4TxPwrOffset_Round; -+} -+ -+#endif -+ -+#if defined(MT6628) -+static VOID wlanChangeNvram6620to6628(PUINT_8 pucEFUSE) -+{ -+ -+#define EFUSE_CH_OFFSET1_L_MASK_6620 BITS(0, 8) -+#define EFUSE_CH_OFFSET1_L_SHIFT_6620 0 -+#define EFUSE_CH_OFFSET1_M_MASK_6620 BITS(9, 17) -+#define EFUSE_CH_OFFSET1_M_SHIFT_6620 9 -+#define EFUSE_CH_OFFSET1_H_MASK_6620 BITS(18, 26) -+#define EFUSE_CH_OFFSET1_H_SHIFT_6620 18 -+#define EFUSE_CH_OFFSET1_VLD_MASK_6620 BIT(27) -+#define EFUSE_CH_OFFSET1_VLD_SHIFT_6620 27 -+ -+#define EFUSE_CH_OFFSET1_L_MASK_5931 BITS(0, 7) -+#define EFUSE_CH_OFFSET1_L_SHIFT_5931 0 -+#define EFUSE_CH_OFFSET1_M_MASK_5931 BITS(8, 15) -+#define EFUSE_CH_OFFSET1_M_SHIFT_5931 8 -+#define EFUSE_CH_OFFSET1_H_MASK_5931 BITS(16, 23) -+#define EFUSE_CH_OFFSET1_H_SHIFT_5931 16 -+#define EFUSE_CH_OFFSET1_VLD_MASK_5931 BIT(24) -+#define EFUSE_CH_OFFSET1_VLD_SHIFT_5931 24 -+#define EFUSE_ALL_CH_OFFSET1_MASK_5931 BITS(25, 27) -+#define EFUSE_ALL_CH_OFFSET1_SHIFT_5931 25 -+ -+ INT_32 au4ChOffset; -+ INT_16 au2ChOffsetL, au2ChOffsetM, au2ChOffsetH; -+ -+ au4ChOffset = *(UINT_32 *) (pucEFUSE + 72); -+ -+ if ((au4ChOffset & EFUSE_CH_OFFSET1_VLD_MASK_6620) && ((*(UINT_32 *) (pucEFUSE + 28)) == 0)) { -+ -+ au2ChOffsetL = ((au4ChOffset & EFUSE_CH_OFFSET1_L_MASK_6620) >> EFUSE_CH_OFFSET1_L_SHIFT_6620); -+ -+ au2ChOffsetM = ((au4ChOffset & EFUSE_CH_OFFSET1_M_MASK_6620) >> EFUSE_CH_OFFSET1_M_SHIFT_6620); -+ -+ au2ChOffsetH = ((au4ChOffset & EFUSE_CH_OFFSET1_H_MASK_6620) >> EFUSE_CH_OFFSET1_H_SHIFT_6620); -+ -+ au2ChOffsetL = wlanChangeCodeWord(au2ChOffsetL); -+ au2ChOffsetM = wlanChangeCodeWord(au2ChOffsetM); -+ au2ChOffsetH = wlanChangeCodeWord(au2ChOffsetH); -+ -+ au4ChOffset = 0; -+ au4ChOffset |= *(UINT_32 *) (pucEFUSE + 72) -+ >> (EFUSE_CH_OFFSET1_VLD_SHIFT_6620 - -+ EFUSE_CH_OFFSET1_VLD_SHIFT_5931) & EFUSE_CH_OFFSET1_VLD_MASK_5931; -+ -+ au4ChOffset |= -+ ((((UINT_32) au2ChOffsetL) << EFUSE_CH_OFFSET1_L_SHIFT_5931) & EFUSE_CH_OFFSET1_L_MASK_5931); -+ au4ChOffset |= -+ ((((UINT_32) au2ChOffsetM) << EFUSE_CH_OFFSET1_M_SHIFT_5931) & EFUSE_CH_OFFSET1_M_MASK_5931); -+ au4ChOffset |= -+ ((((UINT_32) au2ChOffsetH) << EFUSE_CH_OFFSET1_H_SHIFT_5931) & EFUSE_CH_OFFSET1_H_MASK_5931); -+ -+ *((INT_32 *) ((pucEFUSE + 28))) = au4ChOffset; -+ -+ } -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to load manufacture data from NVRAM -+* if available and valid -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param prRegInfo Pointer of REG_INFO_T -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanLoadManufactureData(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo) -+{ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ CMD_RDD_CH_T rRddParam; -+#endif -+ -+ ASSERT(prAdapter); -+ -+ /* 1. Version Check */ -+ kalGetConfigurationVersion(prAdapter->prGlueInfo, -+ &(prAdapter->rVerInfo.u2Part1CfgOwnVersion), -+ &(prAdapter->rVerInfo.u2Part1CfgPeerVersion), -+ &(prAdapter->rVerInfo.u2Part2CfgOwnVersion), -+ &(prAdapter->rVerInfo.u2Part2CfgPeerVersion)); -+ -+#if (CFG_SW_NVRAM_VERSION_CHECK == 1) -+ if (CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion -+ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion -+ || prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION -+ || prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION) { -+ return WLAN_STATUS_FAILURE; -+ } -+#endif -+ -+ /* MT6620 E1/E2 would be ignored directly */ -+ if (prAdapter->rVerInfo.u2Part1CfgOwnVersion == 0x0001) { -+ prRegInfo->ucTxPwrValid = 1; -+ } else { -+ /* 2. Load TX power gain parameters if valid */ -+ if (prRegInfo->ucTxPwrValid != 0) { -+ /* send to F/W */ -+ nicUpdateTxPower(prAdapter, (P_CMD_TX_PWR_T) (&(prRegInfo->rTxPwr))); -+ } -+ } -+ -+ /* Workaround for supporting 5G */ -+ prRegInfo->ucEnable5GBand = 1; -+ prRegInfo->ucSupport5GBand = 1; -+ -+ /* 3. Check if needs to support 5GHz */ -+ /* if(prRegInfo->ucEnable5GBand) { // Frank workaround */ -+ if (1) { -+ /* check if it is disabled by hardware */ -+ if (prAdapter->fgIsHw5GBandDisabled || prRegInfo->ucSupport5GBand == 0) -+ prAdapter->fgEnable5GBand = FALSE; -+ else -+ prAdapter->fgEnable5GBand = TRUE; -+ } else -+ prAdapter->fgEnable5GBand = FALSE; -+ /* Workaround for supporting 5G */ -+ prAdapter->fgEnable5GBand = TRUE; -+/* -+ DBGLOG(INIT, INFO, "NVRAM 5G Enable(%d) SW_En(%d) HW_Dis(%d)\n", -+ prRegInfo->ucEnable5GBand, prRegInfo->ucSupport5GBand, prAdapter->fgIsHw5GBandDisabled); -+*/ -+ /* 4. Send EFUSE data */ -+#if defined(MT6628) -+ wlanChangeNvram6620to6628(prRegInfo->aucEFUSE); -+#endif -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PHY_PARAM, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_PHY_PARAM_T), (PUINT_8) (prRegInfo->aucEFUSE), NULL, 0); -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ rRddParam.ucRddTestMode = (UINT_8) prRegInfo->u4RddTestMode; -+ rRddParam.ucRddShutCh = (UINT_8) prRegInfo->u4RddShutFreq; -+ rRddParam.ucRddStartCh = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4RddStartFreq); -+ rRddParam.ucRddStopCh = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4RddStopFreq); -+ rRddParam.ucRddDfs = (UINT_8) prRegInfo->u4RddDfs; -+ prAdapter->ucRddStatus = 0; -+ nicUpdateRddTestMode(prAdapter, (P_CMD_RDD_CH_T) (&rRddParam)); -+#endif -+ -+ /* 5. Get 16-bits Country Code and Bandwidth */ -+ prAdapter->rWifiVar.rConnSettings.u2CountryCode = -+ (((UINT_16) prRegInfo->au2CountryCode[0]) << 8) | (((UINT_16) prRegInfo->au2CountryCode[1]) & BITS(0, 7)); -+ -+ DBGLOG(INIT, INFO, "NVRAM 5G Enable(%d) SW_En(%d) HW_Dis(%d) CountryCode(0x%x 0x%x)\n", -+ prRegInfo->ucEnable5GBand, prRegInfo->ucSupport5GBand, prAdapter->fgIsHw5GBandDisabled, -+ prRegInfo->au2CountryCode[0], prRegInfo->au2CountryCode[1]); -+ -+#if 0 /* Bandwidth control will be controlled by GUI. 20110930 -+ * So ignore the setting from registry/NVRAM -+ */ -+ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = -+ prRegInfo->uc2G4BwFixed20M ? CONFIG_BW_20M : CONFIG_BW_20_40M; -+ prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = -+ prRegInfo->uc5GBwFixed20M ? CONFIG_BW_20M : CONFIG_BW_20_40M; -+#endif -+ -+ /* 6. Set domain and channel information to chip */ -+ rlmDomainSendCmd(prAdapter, FALSE); -+ /* Update supported channel list in channel table */ -+ wlanUpdateChannelTable(prAdapter->prGlueInfo); -+ -+ /* 7. Set band edge tx power if available */ -+ if (prRegInfo->fg2G4BandEdgePwrUsed) { -+ CMD_EDGE_TXPWR_LIMIT_T rCmdEdgeTxPwrLimit; -+ -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrCCK = prRegInfo->cBandEdgeMaxPwrCCK; -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20 = prRegInfo->cBandEdgeMaxPwrOFDM20; -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40 = prRegInfo->cBandEdgeMaxPwrOFDM40; -+ -+ DBGLOG(INIT, TRACE, "NVRAM 2G Bandedge CCK(%d) HT20(%d)HT40(%d)\n", -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrCCK, -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20, rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_EDGE_TXPWR_LIMIT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, sizeof(CMD_EDGE_TXPWR_LIMIT_T), (PUINT_8)&rCmdEdgeTxPwrLimit, NULL, 0); -+ } -+ /* 8. set 5G band edge tx power if available (add for 6625) */ -+ if (prAdapter->fgEnable5GBand) { -+#define NVRAM_5G_TX_BANDEDGE_VALID_OFFSET 10 -+#define NVRAM_5G_TX_BANDEDGE_OFDM20_OFFSET 11 -+#define NVRAM_5G_TX_BANDEDGE_OFDM40_OFFSET 12 -+ -+ if (prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_VALID_OFFSET]) { -+ CMD_EDGE_TXPWR_LIMIT_T rCmdEdgeTxPwrLimit; -+ -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20 -+ = prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_OFDM20_OFFSET]; -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40 -+ = prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_OFDM40_OFFSET]; -+ -+ DBGLOG(INIT, TRACE, "NVRAM 5G Bandedge HT20(%d)HT40(%d)\n", -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20, rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_5G_EDGE_TXPWR_LIMIT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_EDGE_TXPWR_LIMIT_T), (PUINT_8)&rCmdEdgeTxPwrLimit, NULL, 0); -+ } -+ } -+ /* 9. set RSSI compensation */ -+ /* DBGLOG(INIT, INFO, ("[frank] RSSI valid(%d) 2G(%d) 5G(%d)", -+ prRegInfo->fgRssiCompensationValidbit, -+ prRegInfo->uc2GRssiCompensation, -+ prRegInfo->uc5GRssiCompensation)); */ -+ if (prRegInfo->fgRssiCompensationValidbit) { -+ CMD_RSSI_COMPENSATE_T rCmdRssiCompensate; -+ -+ rCmdRssiCompensate.uc2GRssiCompensation = prRegInfo->uc2GRssiCompensation; -+ rCmdRssiCompensate.uc5GRssiCompensation = prRegInfo->uc5GRssiCompensation; -+ -+ DBGLOG(INIT, LOUD, "NVRAM RSSI Comp. 2G(%d)5G(%d)\n", -+ rCmdRssiCompensate.uc2GRssiCompensation, rCmdRssiCompensate.uc5GRssiCompensation); -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_RSSI_COMPENSATE, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_RSSI_COMPENSATE_T), (PUINT_8)&rCmdRssiCompensate, NULL, 0); -+ } -+ /* 10. notify FW Band Support 5G */ -+ if (prAdapter->fgEnable5GBand) { -+ CMD_BAND_SUPPORT_T rCmdBandSupport; -+ -+ rCmdBandSupport.uc5GBandSupport = TRUE; -+ DBGLOG(INIT, TRACE, "NVRAM 5G BandSupport\n"); -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_BAND_SUPPORT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_BAND_SUPPORT_T), (PUINT_8)&rCmdBandSupport, NULL, 0); -+ -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to check -+* Media Stream Mode is set to non-default value or not, -+* and clear to default value if above criteria is met -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return TRUE -+* The media stream mode was non-default value and has been reset -+* FALSE -+* The media stream mode is default value -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanResetMediaStreamMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode != 0) { -+ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 0; -+ -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to check if any pending timer has expired -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanTimerTimeoutCheck(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* check timer status */ -+ cnmTimerDoTimeOutCheck(prAdapter); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to check if any pending mailbox message -+* to be handled -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanProcessMboxMessage(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) { /* MBOX_ID_TOTAL_NUM = 1 */ -+ mboxRcvAllMsg(prAdapter, (ENUM_MBOX_ID_T) i); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to enqueue a single TX packet into CORE -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* prNativePacket Pointer of Native Packet -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_RESOURCES -+* WLAN_STATUS_INVALID_PACKET -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanEnqueueTxPacket(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prNativePacket) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ /* get a free packet header */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_REMOVE_HEAD(&prTxCtrl->rFreeMsduInfoList, prMsduInfo, P_MSDU_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ -+ if (prMsduInfo == NULL) -+ return WLAN_STATUS_RESOURCES; -+ -+ prMsduInfo->eSrc = TX_PACKET_OS; -+ -+ if (nicTxFillMsduInfo(prAdapter, prMsduInfo, prNativePacket) == FALSE) { -+ /* packet is not extractable */ -+ -+ /* fill fails */ -+ kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_INVALID_PACKET); -+ -+ nicTxReturnMsduInfo(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_INVALID_PACKET; -+ } -+ /* enqueue to QM */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to flush pending TX packets in CORE -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanFlushTxPendingPackets(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ return nicTxFlush(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief this function sends pending MSDU_INFO_T to MT6620 -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param pfgHwAccess Pointer for tracking LP-OWN status -+* -+* @retval WLAN_STATUS_SUCCESS Reset is done successfully. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanTxPendingPackets(IN P_ADAPTER_T prAdapter, IN OUT PBOOLEAN pfgHwAccess) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ ASSERT(pfgHwAccess); -+ -+ /* <1> dequeue packets by txDequeuTxPackets() */ -+ /* Note: prMsduInfo is a packet list queue */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ prMsduInfo = qmDequeueTxPackets(prAdapter, &prTxCtrl->rTc); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ -+ if (prMsduInfo != NULL) { -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == FALSE) { -+ /* <2> Acquire LP-OWN if necessary */ -+ if (*pfgHwAccess == FALSE) { -+ *pfgHwAccess = TRUE; -+ -+ wlanAcquirePowerControl(prAdapter); -+ } -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == TRUE) -+ nicDisableClockGating(prAdapter); -+#endif -+ /* <3> send packet"s" to HIF */ -+ nicTxMsduInfoList(prAdapter, prMsduInfo); -+ -+ /* <4> update TC by txAdjustTcQuotas() */ -+ nicTxAdjustTcq(prAdapter); -+ } else -+ wlanProcessQueuedMsduInfo(prAdapter, prMsduInfo); /* free the packet */ -+ } -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == FALSE) -+ nicEnableClockGating(prAdapter); -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to acquire power control from firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanAcquirePowerControl(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* do driver own */ -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+ /* Reset sleepy state *//* no use */ -+ if (prAdapter->fgWiFiInSleepyState == TRUE) -+ prAdapter->fgWiFiInSleepyState = FALSE; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to release power control to firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanReleasePowerControl(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* do FW own */ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to report currently pending TX frames count -+* (command packets are not included) -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return number of pending TX frames -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 wlanGetTxPendingFrameCount(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ UINT_32 u4Num; -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ /* number in prTxQueue + number in RX forward */ -+ u4Num = kalGetTxPendingFrameCount(prAdapter->prGlueInfo) + (UINT_32) (prTxCtrl->i4PendingFwdFrameCount); -+ -+ return u4Num; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to report current ACPI state -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return ACPI_STATE_D0 Normal Operation Mode -+* ACPI_STATE_D3 Suspend Mode -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_ACPI_STATE_T wlanGetAcpiState(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ return prAdapter->rAcpiState; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to update current ACPI state only -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param ePowerState ACPI_STATE_D0 Normal Operation Mode -+* ACPI_STATE_D3 Suspend Mode -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSetAcpiState(IN P_ADAPTER_T prAdapter, IN ENUM_ACPI_STATE_T ePowerState) -+{ -+ ASSERT(prAdapter); -+ ASSERT(ePowerState <= ACPI_STATE_D3); -+ -+ prAdapter->rAcpiState = ePowerState; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to query ECO version from HIFSYS CR -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return zero Unable to retrieve ECO version information -+* non-zero ECO version (1-based) -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 wlanGetEcoVersion(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ if (nicVerifyChipID(prAdapter) == TRUE) -+ return prAdapter->ucRevID + 1; -+ else -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to setting the default Tx Power configuration -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return zero Unable to retrieve ECO version information -+* non-zero ECO version (1-based) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanDefTxPowerCfg(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 i; -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ P_SET_TXPWR_CTRL_T prTxpwr; -+ -+ ASSERT(prGlueInfo); -+ -+ prTxpwr = &prGlueInfo->rTxPwr; -+ -+ prTxpwr->c2GLegacyStaPwrOffset = 0; -+ prTxpwr->c2GHotspotPwrOffset = 0; -+ prTxpwr->c2GP2pPwrOffset = 0; -+ prTxpwr->c2GBowPwrOffset = 0; -+ prTxpwr->c5GLegacyStaPwrOffset = 0; -+ prTxpwr->c5GHotspotPwrOffset = 0; -+ prTxpwr->c5GP2pPwrOffset = 0; -+ prTxpwr->c5GBowPwrOffset = 0; -+ prTxpwr->ucConcurrencePolicy = 0; -+ for (i = 0; i < 3; i++) -+ prTxpwr->acReserved1[i] = 0; -+ -+ for (i = 0; i < 14; i++) -+ prTxpwr->acTxPwrLimit2G[i] = 63; -+ -+ for (i = 0; i < 4; i++) -+ prTxpwr->acTxPwrLimit5G[i] = 63; -+ -+ for (i = 0; i < 2; i++) -+ prTxpwr->acReserved2[i] = 0; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to -+* set preferred band configuration corresponding to network type -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param eBand Given band -+* @param eNetTypeIndex Given Network Type -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+wlanSetPreferBandByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eBand <= BAND_NUM); -+ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); -+ -+ /* 1. set prefer band according to network type */ -+ prAdapter->aePreferBand[eNetTypeIndex] = eBand; -+ -+ /* 2. remove buffered BSS descriptors correspondingly */ -+ if (eBand == BAND_2G4) -+ scanRemoveBssDescByBandAndNetwork(prAdapter, BAND_5G, eNetTypeIndex); -+ else if (eBand == BAND_5G) -+ scanRemoveBssDescByBandAndNetwork(prAdapter, BAND_2G4, eNetTypeIndex); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to -+* get channel information corresponding to specified network type -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param eNetTypeIndex Given Network Type -+* -+* @return channel number -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 wlanGetChannelNumberByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ return prBssInfo->ucPrimaryChannel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to -+* get BSS descriptor information corresponding to specified network type -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param eNetTypeIndex Given Network Type -+* -+* @return pointer to BSS_DESC_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T wlanGetTargetBssDescByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); -+ -+ switch (eNetTypeIndex) { -+ case NETWORK_TYPE_AIS_INDEX: -+ return prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc; -+ -+ case NETWORK_TYPE_P2P_INDEX: -+ return NULL; -+ -+ case NETWORK_TYPE_BOW_INDEX: -+ return prAdapter->rWifiVar.rBowFsmInfo.prTargetBssDesc; -+ -+ default: -+ return NULL; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to -+* check unconfigured system properties and generate related message on -+* scan list to notify users -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanCheckSystemConfiguration(IN P_ADAPTER_T prAdapter) -+{ -+#if (CFG_NVRAM_EXISTENCE_CHECK == 1) || (CFG_SW_NVRAM_VERSION_CHECK == 1) -+ const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; -+ const UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+ BOOLEAN fgIsConfExist = TRUE; -+ BOOLEAN fgGenErrMsg = FALSE; -+ P_REG_INFO_T prRegInfo = NULL; -+ P_WLAN_BEACON_FRAME_T prBeacon = NULL; -+ P_IE_SSID_T prSsid = NULL; -+ UINT_32 u4ErrCode = 0; -+ UINT_8 aucErrMsg[32]; -+ PARAM_SSID_T rSsid; -+ PARAM_802_11_CONFIG_T rConfiguration; -+ PARAM_RATES_EX rSupportedRates; -+#endif -+ -+ DEBUGFUNC("wlanCheckSystemConfiguration"); -+ -+ ASSERT(prAdapter); -+ -+#if (CFG_NVRAM_EXISTENCE_CHECK == 1) -+ if (kalIsConfigurationExist(prAdapter->prGlueInfo) == FALSE) { -+ fgIsConfExist = FALSE; -+ fgGenErrMsg = TRUE; -+ } -+#endif -+ -+#if (CFG_SW_NVRAM_VERSION_CHECK == 1) -+ prRegInfo = kalGetConfiguration(prAdapter->prGlueInfo); -+ -+ if (fgIsConfExist == TRUE && (CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion -+ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion -+ || prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION -+ || prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION /* NVRAM */ -+ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2FwPeerVersion -+ || prAdapter->rVerInfo.u2FwOwnVersion <= CFG_DRV_PEER_VERSION -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ || prAdapter->fgIsPowerLimitTableValid == FALSE -+#endif -+ || (prAdapter->fgIsEmbbededMacAddrValid == FALSE && -+ (IS_BMCAST_MAC_ADDR(prRegInfo->aucMacAddr) -+ || EQUAL_MAC_ADDR(aucZeroMacAddr, prRegInfo->aucMacAddr))) -+ || prRegInfo->ucTxPwrValid == 0)) -+ fgGenErrMsg = TRUE; -+#endif -+ -+ if (fgGenErrMsg == TRUE) { -+ prBeacon = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(WLAN_BEACON_FRAME_T) + sizeof(IE_SSID_T)); -+ if (!prBeacon) { -+ ASSERT(FALSE); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* initialization */ -+ kalMemZero(prBeacon, sizeof(WLAN_BEACON_FRAME_T) + sizeof(IE_SSID_T)); -+ -+ /* prBeacon initialization */ -+ prBeacon->u2FrameCtrl = MAC_FRAME_BEACON; -+ COPY_MAC_ADDR(prBeacon->aucDestAddr, aucBCAddr); -+ COPY_MAC_ADDR(prBeacon->aucSrcAddr, aucZeroMacAddr); -+ COPY_MAC_ADDR(prBeacon->aucBSSID, aucZeroMacAddr); -+ prBeacon->u2BeaconInterval = 100; -+ prBeacon->u2CapInfo = CAP_INFO_ESS; -+ -+ /* prSSID initialization */ -+ prSsid = (P_IE_SSID_T) (&prBeacon->aucInfoElem[0]); -+ prSsid->ucId = ELEM_ID_SSID; -+ -+ /* rConfiguration initialization */ -+ rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T); -+ rConfiguration.u4BeaconPeriod = 100; -+ rConfiguration.u4ATIMWindow = 1; -+ rConfiguration.u4DSConfig = 2412; -+ rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); -+ -+ /* rSupportedRates initialization */ -+ kalMemZero(rSupportedRates, sizeof(PARAM_RATES_EX)); -+ } -+#if (CFG_NVRAM_EXISTENCE_CHECK == 1) -+#define NVRAM_ERR_MSG "NVRAM WARNING: Err = 0x01" -+ if ((kalIsConfigurationExist(prAdapter->prGlueInfo) == FALSE) && (prBeacon) && (prSsid)) { -+ COPY_SSID(prSsid->aucSSID, prSsid->ucLength, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG)); -+ -+ kalIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prBeacon, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, -+ aucSSID) + prSsid->ucLength, -+ 1, 0); -+ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG)); -+ nicAddScanResult(prAdapter, -+ prBeacon->aucBSSID, -+ &rSsid, -+ 0, -+ 0, -+ PARAM_NETWORK_TYPE_FH, -+ &rConfiguration, -+ NET_TYPE_INFRA, -+ rSupportedRates, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, -+ aucSSID) + prSsid->ucLength - -+ WLAN_MAC_MGMT_HEADER_LEN, (PUINT_8) ((ULONG) (prBeacon) + WLAN_MAC_MGMT_HEADER_LEN)); -+ } -+#endif -+ -+#if (CFG_SW_NVRAM_VERSION_CHECK == 1) -+#define VER_ERR_MSG "NVRAM WARNING: Err = 0x%02X" -+ if ((fgIsConfExist == TRUE) && (prBeacon) && (prSsid)) { -+ if ((CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion -+ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion -+ || prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION -+ || prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION /* NVRAM */ -+ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2FwPeerVersion -+ || prAdapter->rVerInfo.u2FwOwnVersion <= CFG_DRV_PEER_VERSION)) -+ u4ErrCode |= NVRAM_ERROR_VERSION_MISMATCH; -+ -+ if (prRegInfo->ucTxPwrValid == 0) -+ u4ErrCode |= NVRAM_ERROR_INVALID_TXPWR; -+ -+ if (prAdapter->fgIsEmbbededMacAddrValid == FALSE && (IS_BMCAST_MAC_ADDR(prRegInfo->aucMacAddr) -+ || EQUAL_MAC_ADDR(aucZeroMacAddr, -+ prRegInfo->aucMacAddr))) -+ u4ErrCode |= NVRAM_ERROR_INVALID_MAC_ADDR; -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ if (prAdapter->fgIsPowerLimitTableValid == FALSE) -+ u4ErrCode |= NVRAM_POWER_LIMIT_TABLE_INVALID; -+#endif -+ if (u4ErrCode != 0) { -+ sprintf(aucErrMsg, VER_ERR_MSG, (unsigned int)u4ErrCode); -+ COPY_SSID(prSsid->aucSSID, prSsid->ucLength, aucErrMsg, strlen(aucErrMsg)); -+ -+ kalIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prBeacon, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, -+ aucSSID) + -+ prSsid->ucLength, 1, 0); -+ -+ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG)); -+ nicAddScanResult(prAdapter, -+ prBeacon->aucBSSID, -+ &rSsid, -+ 0, -+ 0, -+ PARAM_NETWORK_TYPE_FH, -+ &rConfiguration, -+ NET_TYPE_INFRA, -+ rSupportedRates, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, -+ aucSSID) + -+ prSsid->ucLength - WLAN_MAC_MGMT_HEADER_LEN, -+ (PUINT_8) ((ULONG) (prBeacon) + WLAN_MAC_MGMT_HEADER_LEN)); -+ } -+ } -+#endif -+ -+ if (fgGenErrMsg == TRUE) -+ cnmMemFree(prAdapter, prBeacon); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS -+wlanoidQueryStaStatistics(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; -+ P_STA_RECORD_T prStaRec, prTempStaRec; -+ P_PARAM_GET_STA_STATISTICS prQueryStaStatistics; -+ UINT_8 ucStaRecIdx; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ CMD_GET_STA_STATISTICS_T rQueryCmdStaStatistics; -+ UINT_8 ucIdx; -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ do { -+ ASSERT(pvQueryBuffer); -+ -+ /* 4 1. Sanity test */ -+ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) -+ break; -+ -+ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) -+ break; -+ -+ if (u4QueryBufferLen < sizeof(PARAM_GET_STA_STA_STATISTICS)) { -+ *pu4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS); -+ rResult = WLAN_STATUS_BUFFER_TOO_SHORT; -+ break; -+ } -+ -+ prQueryStaStatistics = (P_PARAM_GET_STA_STATISTICS) pvQueryBuffer; -+ *pu4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS); -+ -+ /* 4 5. Get driver global QM counter */ -+ for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) { -+ prQueryStaStatistics->au4TcAverageQueLen[ucIdx] = prQM->au4AverageQueLen[ucIdx]; -+ prQueryStaStatistics->au4TcCurrentQueLen[ucIdx] = prQM->au4CurrentTcResource[ucIdx]; -+ } -+ -+ /* 4 2. Get StaRec by MAC address */ -+ prStaRec = NULL; -+ -+ for (ucStaRecIdx = 0; ucStaRecIdx < CFG_NUM_OF_STA_RECORD; ucStaRecIdx++) { -+ prTempStaRec = &(prAdapter->arStaRec[ucStaRecIdx]); -+ if (prTempStaRec->fgIsValid && prTempStaRec->fgIsInUse) { -+ if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, prQueryStaStatistics->aucMacAddr)) { -+ prStaRec = prTempStaRec; -+ break; -+ } -+ } -+ } -+ -+ if (!prStaRec) { -+ rResult = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ prQueryStaStatistics->u4Flag |= BIT(0); -+ -+#if CFG_ENABLE_PER_STA_STATISTICS -+ /* 4 3. Get driver statistics */ -+ DBGLOG(TX, INFO, "skbToDriver %lld, skbFreed: %lld\n", -+ prAdapter->prGlueInfo->u8SkbToDriver, -+ prAdapter->prGlueInfo->u8SkbFreed); -+ prAdapter->prGlueInfo->u8SkbFreed = 0; -+ prAdapter->prGlueInfo->u8SkbToDriver = 0; -+ -+ prQueryStaStatistics->u4TxTotalCount = prStaRec->u4TotalTxPktsNumber; -+ prQueryStaStatistics->u4TxExceedThresholdCount = prStaRec->u4ThresholdCounter; -+ prQueryStaStatistics->u4TxMaxTime = prStaRec->u4MaxTxPktsTime; -+ prQueryStaStatistics->u4TxMaxHifTime = prStaRec->u4MaxTxPktsHifTime; -+ if (prStaRec->u4TotalTxPktsNumber) { -+ prQueryStaStatistics->u4TxAverageProcessTime = -+ (prStaRec->u4TotalTxPktsTime / prStaRec->u4TotalTxPktsNumber); -+ prQueryStaStatistics->u4TxAverageHifTime = -+ (prStaRec->u4TotalTxPktsHifTime / prStaRec->u4TotalTxPktsNumber); -+ } else -+ prQueryStaStatistics->u4TxAverageProcessTime = 0; -+ -+ for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) { -+ prQueryStaStatistics->au4TcResourceEmptyCount[ucIdx] = -+ prQM->au4QmTcResourceEmptyCounter[prStaRec->ucNetTypeIndex][ucIdx]; -+ /* Reset */ -+ prQM->au4QmTcResourceEmptyCounter[prStaRec->ucNetTypeIndex][ucIdx] = 0; -+ prQueryStaStatistics->au4TcResourceBackCount[ucIdx] = -+ prQM->au4QmTcResourceBackCounter[ucIdx]; -+ prQM->au4QmTcResourceBackCounter[ucIdx] = 0; -+ -+ prQueryStaStatistics->au4DequeueNoTcResource[ucIdx] = -+ prQM->au4DequeueNoTcResourceCounter[ucIdx]; -+ prQM->au4DequeueNoTcResourceCounter[ucIdx] = 0; -+ prQueryStaStatistics->au4TcResourceUsedCount[ucIdx] = -+ prQM->au4ResourceUsedCounter[ucIdx]; -+ prQM->au4ResourceUsedCounter[ucIdx] = 0; -+ prQueryStaStatistics->au4TcResourceWantedCount[ucIdx] = -+ prQM->au4ResourceWantedCounter[ucIdx]; -+ prQM->au4ResourceWantedCounter[ucIdx] = 0; -+ } -+ -+ prQueryStaStatistics->u4EnqueueCounter = prQM->u4EnqeueuCounter; -+ prQueryStaStatistics->u4DequeueCounter = prQM->u4DequeueCounter; -+ prQueryStaStatistics->u4EnqueueStaCounter = prStaRec->u4EnqeueuCounter; -+ prQueryStaStatistics->u4DequeueStaCounter = prStaRec->u4DeqeueuCounter; -+ -+ prQueryStaStatistics->IsrCnt = prGlueInfo->IsrCnt - prGlueInfo->IsrPreCnt; -+ prQueryStaStatistics->IsrPassCnt = prGlueInfo->IsrPassCnt - prGlueInfo->IsrPrePassCnt; -+ prQueryStaStatistics->TaskIsrCnt = prGlueInfo->TaskIsrCnt - prGlueInfo->TaskPreIsrCnt; -+ -+ prQueryStaStatistics->IsrAbnormalCnt = prGlueInfo->IsrAbnormalCnt; -+ prQueryStaStatistics->IsrSoftWareCnt = prGlueInfo->IsrSoftWareCnt; -+ prQueryStaStatistics->IsrRxCnt = prGlueInfo->IsrRxCnt; -+ prQueryStaStatistics->IsrTxCnt = prGlueInfo->IsrTxCnt; -+ -+ /* 4 4.1 Reset statistics */ -+ prStaRec->u4ThresholdCounter = 0; -+ prStaRec->u4TotalTxPktsNumber = 0; -+ prStaRec->u4TotalTxPktsTime = 0; -+ prStaRec->u4MaxTxPktsTime = 0; -+ prStaRec->u4MaxTxPktsHifTime = 0; -+ -+ prStaRec->u4EnqeueuCounter = 0; -+ prStaRec->u4DeqeueuCounter = 0; -+ -+ prQM->u4EnqeueuCounter = 0; -+ prQM->u4DequeueCounter = 0; -+ -+ prGlueInfo->IsrPreCnt = prGlueInfo->IsrCnt; -+ prGlueInfo->IsrPrePassCnt = prGlueInfo->IsrPassCnt; -+ prGlueInfo->TaskPreIsrCnt = prGlueInfo->TaskIsrCnt; -+ prGlueInfo->IsrAbnormalCnt = 0; -+ prGlueInfo->IsrSoftWareCnt = 0; -+ prGlueInfo->IsrRxCnt = 0; -+ prGlueInfo->IsrTxCnt = 0; -+#endif -+ -+ for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) -+ prQueryStaStatistics->au4TcQueLen[ucIdx] = prStaRec->arTxQueue[ucIdx].u4NumElem; -+ -+ rResult = WLAN_STATUS_SUCCESS; -+ -+ /* 4 6. Ensure FW supports get station link status */ -+ if (prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) { -+ -+ rQueryCmdStaStatistics.ucIndex = prStaRec->ucIndex; -+ COPY_MAC_ADDR(rQueryCmdStaStatistics.aucMacAddr, prQueryStaStatistics->aucMacAddr); -+ rQueryCmdStaStatistics.ucReadClear = TRUE; -+ -+ rResult = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STA_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryStaStatistics, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_GET_STA_STATISTICS_T), -+ (PUINT_8)&rQueryCmdStaStatistics, -+ pvQueryBuffer, u4QueryBufferLen); -+ -+ prQueryStaStatistics->u4Flag |= BIT(1); -+ } else { -+ rResult = WLAN_STATUS_NOT_SUPPORTED; -+ } -+ -+ } while (FALSE); -+ -+ return rResult; -+} /* wlanoidQueryP2pVersion */ -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ -+/* 4 Auto Channel Selection */ -+WLAN_STATUS -+wlanoidQueryACSChannelList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; -+ /* P_PARAM_GET_CHN_LOAD prQueryChnLoad; */ -+ P_PARAM_GET_LTE_MODE prLteMode; -+ CMD_GET_LTE_SAFE_CHN_T rQuery_LTE_SAFE_CHN; -+ -+ DBGLOG(P2P, INFO, "[Auto Channel]wlanoidQueryACSChannelList\n"); -+ do { -+ ASSERT(pvQueryBuffer); -+ -+ /* 4 1. Sanity test */ -+ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) -+ break; -+ -+ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) -+ break; -+ -+ prLteMode = (P_PARAM_GET_LTE_MODE) pvQueryBuffer; -+ -+ /* 4 3. Ensure FW supports get station link status */ -+#if 0 -+ if (prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) { -+ CMD_ACCESS_REG rCmdAccessReg; -+ -+ rCmdAccessReg.u4Address = 0xFFFFFFFF; -+ rCmdAccessReg.u4Data = ELEM_RM_TYPE_ACS_CHN; -+ -+ rResult = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ TRUE, -+ TRUE, -+ TRUE, -+ /* The handler to receive firmware notification */ -+ nicCmdEventQueryChannelLoad, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8)&rCmdAccessReg, pvQueryBuffer, u4QueryBufferLen); -+ -+ prQueryChnLoad->u4Flag |= BIT(1); -+ } else { -+ rResult = WLAN_STATUS_NOT_SUPPORTED; -+ } -+#endif -+ /* 4 4.Avoid LTE Channels */ -+ prLteMode->u4Flags &= BIT(0); -+ /*if(prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) */ { -+ -+ rResult = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LTE_CHN, -+ FALSE, -+ TRUE, -+ /* Query ID */ -+ TRUE, -+ /* The handler to receive firmware notification */ -+ nicCmdEventQueryLTESafeChn, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_GET_LTE_SAFE_CHN_T), -+ (PUINT_8)&rQuery_LTE_SAFE_CHN, -+ pvQueryBuffer, u4QueryBufferLen); -+ -+ DBGLOG(P2P, INFO, "[Auto Channel] Get LTE Channels\n"); -+ prLteMode->u4Flags |= BIT(1); -+ } -+ -+ /* 4 5. Calc the value */ -+ -+ DBGLOG(P2P, INFO, "[Auto Channel] Candidated Channels\n"); -+ } while (FALSE); -+ -+ return rResult; -+} /* wlanoidQueryP2pVersion */ -+#endif -+#if CFG_SUPPORT_CFG_FILE -+ -+P_WLAN_CFG_ENTRY_T wlanCfgGetEntry(IN P_ADAPTER_T prAdapter, const PCHAR pucKey) -+{ -+ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ UINT_32 i; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ ASSERT(prWlanCfg); -+ ASSERT(pucKey); -+ -+ prWlanCfgEntry = NULL; -+ -+ for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) { -+ prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[i]; -+ if (prWlanCfgEntry->aucKey[0] != '\0') { -+ DBGLOG(INIT, LOUD, "compare key %s saved key %s\n", pucKey, prWlanCfgEntry->aucKey); -+ if (kalStrniCmp(pucKey, prWlanCfgEntry->aucKey, WLAN_CFG_KEY_LEN_MAX - 1) == 0) -+ return prWlanCfgEntry; -+ } -+ } -+ -+ DBGLOG(INIT, LOUD, "wifi config there is no entry \'%s\'\n", pucKey); -+ return NULL; -+ -+} -+ -+WLAN_STATUS wlanCfgGet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, PCHAR pucValueDef, UINT_32 u4Flags) -+{ -+ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ ASSERT(prWlanCfg); -+ ASSERT(pucValue); -+ -+ /* Find the exist */ -+ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); -+ -+ if (prWlanCfgEntry) { -+ kalStrnCpy(pucValue, prWlanCfgEntry->aucValue, WLAN_CFG_VALUE_LEN_MAX - 1); -+ return WLAN_STATUS_SUCCESS; -+ } -+ if (pucValueDef) -+ kalStrnCpy(pucValue, pucValueDef, WLAN_CFG_VALUE_LEN_MAX - 1); -+ return WLAN_STATUS_FAILURE; -+ -+} -+ -+UINT_32 wlanCfgGetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4ValueDef) -+{ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ UINT_32 u4Value; -+ INT_32 u4Ret; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ ASSERT(prWlanCfg); -+ -+ u4Value = u4ValueDef; -+ /* Find the exist */ -+ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); -+ -+ if (prWlanCfgEntry) { -+ u4Ret = kalkStrtou32(prWlanCfgEntry->aucValue, 0, &u4Value); -+ if (u4Ret) -+ DBGLOG(INIT, ERROR, "parse prWlanCfgEntry->aucValue u4Ret=%u\n", u4Ret); -+ /* u4Value = kalStrtoul(prWlanCfgEntry->aucValue, NULL, 0); */ -+ } -+ -+ return u4Value; -+} -+ -+INT_32 wlanCfgGetInt32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, INT_32 i4ValueDef) -+{ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ INT_32 i4Value; -+ INT_32 i4Ret; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ ASSERT(prWlanCfg); -+ -+ i4Value = i4ValueDef; -+ /* Find the exist */ -+ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); -+ -+ if (prWlanCfgEntry) { -+ i4Ret = kalkStrtos32(prWlanCfgEntry->aucValue, 0, &i4Value); -+ /* i4Ret = kalStrtol(prWlanCfgEntry->aucValue, NULL, 0); */ -+ if (i4Ret) -+ DBGLOG(INIT, ERROR, "parse prWlanCfgEntry->aucValue i4Ret=%u\n\r", i4Ret); -+ } -+ -+ return i4Value; -+} -+ -+WLAN_STATUS wlanCfgSet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, UINT_32 u4Flags) -+{ -+ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ UINT_32 u4EntryIndex; -+ UINT_32 i; -+ UINT_8 ucExist; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ ASSERT(prWlanCfg); -+ ASSERT(pucKey); -+ -+ /* Find the exist */ -+ ucExist = 0; -+ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); -+ -+ if (!prWlanCfgEntry) { -+ /* Find the empty */ -+ for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) { -+ prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[i]; -+ if (prWlanCfgEntry->aucKey[0] == '\0') -+ break; -+ } -+ -+ u4EntryIndex = i; -+ if (u4EntryIndex < WLAN_CFG_ENTRY_NUM_MAX) { -+ prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[u4EntryIndex]; -+ kalMemZero(prWlanCfgEntry, sizeof(WLAN_CFG_ENTRY_T)); -+ } else { -+ prWlanCfgEntry = NULL; -+ DBGLOG(INIT, ERROR, "wifi config there is no empty entry\n"); -+ } -+ } /* !prWlanCfgEntry */ -+ else -+ ucExist = 1; -+ -+ if (prWlanCfgEntry) { -+ if (ucExist == 0) { -+ kalStrnCpy(prWlanCfgEntry->aucKey, pucKey, WLAN_CFG_KEY_LEN_MAX - 1); -+ prWlanCfgEntry->aucKey[WLAN_CFG_KEY_LEN_MAX - 1] = '\0'; -+ } -+ -+ if (pucValue && pucValue[0] != '\0') { -+ kalStrnCpy(prWlanCfgEntry->aucValue, pucValue, WLAN_CFG_VALUE_LEN_MAX - 1); -+ prWlanCfgEntry->aucValue[WLAN_CFG_VALUE_LEN_MAX - 1] = '\0'; -+ -+ if (ucExist) { -+ if (prWlanCfgEntry->pfSetCb) -+ prWlanCfgEntry->pfSetCb(prAdapter, -+ prWlanCfgEntry->aucKey, -+ prWlanCfgEntry->aucValue, prWlanCfgEntry->pPrivate, 0); -+ } -+ } else { -+ /* Call the pfSetCb if value is empty ? */ -+ /* remove the entry if value is empty */ -+ kalMemZero(prWlanCfgEntry, sizeof(WLAN_CFG_ENTRY_T)); -+ } -+ -+ } -+ /* prWlanCfgEntry */ -+ if (prWlanCfgEntry) { -+ DBGLOG(INIT, LOUD, "Set wifi config exist %u \'%s\' \'%s\'\n", -+ ucExist, prWlanCfgEntry->aucKey, prWlanCfgEntry->aucValue); -+ return WLAN_STATUS_SUCCESS; -+ } -+ if (pucKey) -+ DBGLOG(INIT, ERROR, "Set wifi config error key \'%s\'\n", pucKey); -+ if (pucValue) -+ DBGLOG(INIT, ERROR, "Set wifi config error value \'%s\'\n", pucValue); -+ return WLAN_STATUS_FAILURE; -+ -+} -+ -+WLAN_STATUS -+wlanCfgSetCb(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, WLAN_CFG_SET_CB pfSetCb, void *pPrivate, UINT_32 u4Flags) -+{ -+ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ ASSERT(prWlanCfg); -+ -+ /* Find the exist */ -+ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); -+ -+ if (prWlanCfgEntry) { -+ prWlanCfgEntry->pfSetCb = pfSetCb; -+ prWlanCfgEntry->pPrivate = pPrivate; -+ } -+ -+ if (prWlanCfgEntry) -+ return WLAN_STATUS_SUCCESS; -+ else -+ return WLAN_STATUS_FAILURE; -+ -+} -+ -+WLAN_STATUS wlanCfgSetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4Value) -+{ -+ -+ P_WLAN_CFG_T prWlanCfg; -+ UINT_8 aucBuf[WLAN_CFG_VALUE_LEN_MAX]; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ ASSERT(prWlanCfg); -+ -+ kalMemZero(aucBuf, sizeof(aucBuf)); -+ -+ kalSnprintf(aucBuf, WLAN_CFG_VALUE_LEN_MAX, "0x%x", (unsigned int)u4Value); -+ -+ return wlanCfgSet(prAdapter, pucKey, aucBuf, 0); -+} -+ -+enum { -+ STATE_EOF = 0, -+ STATE_TEXT = 1, -+ STATE_NEWLINE = 2 -+}; -+ -+struct WLAN_CFG_PARSE_STATE_S { -+ CHAR *ptr; -+ CHAR *text; -+ INT_32 nexttoken; -+ UINT_32 maxSize; -+}; -+ -+INT_32 wlanCfgFindNextToken(struct WLAN_CFG_PARSE_STATE_S *state) -+{ -+ CHAR *x = state->ptr; -+ CHAR *s; -+ -+ if (state->nexttoken) { -+ INT_32 t = state->nexttoken; -+ -+ state->nexttoken = 0; -+ return t; -+ } -+ -+ for (;;) { -+ switch (*x) { -+ case 0: -+ state->ptr = x; -+ return STATE_EOF; -+ case '\n': -+ x++; -+ state->ptr = x; -+ return STATE_NEWLINE; -+ case ' ': -+ case '\t': -+ case '\r': -+ x++; -+ continue; -+ case '#': -+ while (*x && (*x != '\n')) -+ x++; -+ if (*x == '\n') { -+ state->ptr = x + 1; -+ return STATE_NEWLINE; -+ } -+ state->ptr = x; -+ return STATE_EOF; -+ default: -+ goto text; -+ } -+ } -+ -+textdone: -+ state->ptr = x; -+ *s = 0; -+ return STATE_TEXT; -+text: -+ state->text = s = x; -+textresume: -+ for (;;) { -+ switch (*x) { -+ case 0: -+ goto textdone; -+ case ' ': -+ case '\t': -+ case '\r': -+ x++; -+ goto textdone; -+ case '\n': -+ state->nexttoken = STATE_NEWLINE; -+ x++; -+ goto textdone; -+ case '"': -+ x++; -+ for (;;) { -+ switch (*x) { -+ case 0: -+ /* unterminated quoted thing */ -+ state->ptr = x; -+ return STATE_EOF; -+ case '"': -+ x++; -+ goto textresume; -+ default: -+ *s++ = *x++; -+ } -+ } -+ break; -+ case '\\': -+ x++; -+ switch (*x) { -+ case 0: -+ goto textdone; -+ case 'n': -+ *s++ = '\n'; -+ break; -+ case 'r': -+ *s++ = '\r'; -+ break; -+ case 't': -+ *s++ = '\t'; -+ break; -+ case '\\': -+ *s++ = '\\'; -+ break; -+ case '\r': -+ /* \ -> line continuation */ -+ if (x[1] != '\n') { -+ x++; -+ continue; -+ } -+ case '\n': -+ /* \ -> line continuation */ -+ x++; -+ /* eat any extra whitespace */ -+ while ((*x == ' ') || (*x == '\t')) -+ x++; -+ continue; -+ default: -+ /* unknown escape -- just copy */ -+ *s++ = *x++; -+ } -+ continue; -+ default: -+ *s++ = *x++; -+ } -+ } -+ return STATE_EOF; -+} -+ -+WLAN_STATUS wlanCfgParseArgument(CHAR *cmdLine, INT_32 *argc, CHAR *argv[]) -+{ -+ struct WLAN_CFG_PARSE_STATE_S state; -+ CHAR **args; -+ INT_32 nargs; -+ -+ if (cmdLine == NULL || argc == NULL || argv == NULL) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ args = argv; -+ nargs = 0; -+ state.ptr = cmdLine; -+ state.nexttoken = 0; -+ state.maxSize = 0; -+ -+ if (kalStrnLen(cmdLine, 512) >= 512) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ for (;;) { -+ switch (wlanCfgFindNextToken(&state)) { -+ case STATE_EOF: -+ goto exit; -+ case STATE_NEWLINE: -+ goto exit; -+ case STATE_TEXT: -+ if (nargs < WLAN_CFG_ARGV_MAX) -+ args[nargs++] = state.text; -+ break; -+ } -+ } -+ -+exit: -+ *argc = nargs; -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS -+wlanCfgParseAddEntry(IN P_ADAPTER_T prAdapter, -+ PUINT_8 pucKeyHead, PUINT_8 pucKeyTail, PUINT_8 pucValueHead, PUINT_8 pucValueTail) -+{ -+ -+ UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX]; -+ UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX]; -+ UINT_32 u4Len; -+ -+ kalMemZero(aucKey, sizeof(aucKey)); -+ kalMemZero(aucValue, sizeof(aucValue)); -+ -+ if ((pucKeyHead == NULL) -+ || (pucValueHead == NULL) -+ ) -+ return WLAN_STATUS_FAILURE; -+ -+ if (pucKeyTail) { -+ if (pucKeyHead > pucKeyTail) -+ return WLAN_STATUS_FAILURE; -+ u4Len = pucKeyTail - pucKeyHead + 1; -+ } else -+ u4Len = kalStrnLen(pucKeyHead, WLAN_CFG_KEY_LEN_MAX - 1); -+ -+ if (u4Len >= WLAN_CFG_KEY_LEN_MAX) -+ u4Len = WLAN_CFG_KEY_LEN_MAX - 1; -+ -+ if (u4Len < WLAN_CFG_VALUE_LEN_MAX) -+ kalStrnCpy(aucKey, pucKeyHead, u4Len); -+ else -+ DBGLOG(INIT, ERROR, "wifi entry parse error: Data len > %d\n", u4Len); -+ -+ if (pucValueTail) { -+ if (pucValueHead > pucValueTail) -+ return WLAN_STATUS_FAILURE; -+ u4Len = pucValueTail - pucValueHead + 1; -+ } else -+ u4Len = kalStrnLen(pucValueHead, WLAN_CFG_VALUE_LEN_MAX - 1); -+ -+ if (u4Len >= WLAN_CFG_VALUE_LEN_MAX) -+ u4Len = WLAN_CFG_VALUE_LEN_MAX - 1; -+ -+ if (u4Len < WLAN_CFG_VALUE_LEN_MAX) -+ kalStrnCpy(aucValue, pucValueHead, u4Len); -+ else -+ DBGLOG(INIT, ERROR, "wifi entry parse error: Data len > %d\n", u4Len); -+ -+ return wlanCfgSet(prAdapter, aucKey, aucValue, 0); -+} -+ -+enum { -+ WAIT_KEY_HEAD = 0, -+ WAIT_KEY_TAIL, -+ WAIT_VALUE_HEAD, -+ WAIT_VALUE_TAIL, -+ WAIT_COMMENT_TAIL -+}; -+ -+WLAN_STATUS wlanCfgParse(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen) -+{ -+ -+ struct WLAN_CFG_PARSE_STATE_S state; -+ PCHAR apcArgv[WLAN_CFG_ARGV_MAX]; -+ CHAR **args; -+ INT_32 nargs; -+ -+ if (pucConfigBuf == NULL) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ if (kalStrnLen(pucConfigBuf, 4000) >= 4000) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ if (u4ConfigBufLen == 0) -+ return WLAN_STATUS_FAILURE; -+ args = apcArgv; -+ nargs = 0; -+ state.ptr = pucConfigBuf; -+ state.nexttoken = 0; -+ state.maxSize = u4ConfigBufLen; -+ -+ for (;;) { -+ switch (wlanCfgFindNextToken(&state)) { -+ case STATE_EOF: -+ if (nargs > 1) -+ wlanCfgParseAddEntry(prAdapter, args[0], NULL, args[1], NULL); -+ goto exit; -+ case STATE_NEWLINE: -+ if (nargs > 1) -+ wlanCfgParseAddEntry(prAdapter, args[0], NULL, args[1], NULL); -+ nargs = 0; -+ break; -+ case STATE_TEXT: -+ if (nargs < WLAN_CFG_ARGV_MAX) -+ args[nargs++] = state.text; -+ break; -+ } -+ } -+ -+exit: -+ return WLAN_STATUS_SUCCESS; -+ -+#if 0 -+ /* Old version */ -+ UINT_32 i; -+ UINT_8 c; -+ PUINT_8 pbuf; -+ UINT_8 ucState; -+ PUINT_8 pucKeyTail = NULL; -+ PUINT_8 pucKeyHead = NULL; -+ PUINT_8 pucValueHead = NULL; -+ PUINT_8 pucValueTail = NULL; -+ -+ ucState = WAIT_KEY_HEAD; -+ pbuf = pucConfigBuf; -+ -+ for (i = 0; i < u4ConfigBufLen; i++) { -+ c = pbuf[i]; -+ if (c == '\r' || c == '\n') { -+ -+ if (ucState == WAIT_VALUE_TAIL) { -+ /* Entry found */ -+ if (pucValueHead) -+ wlanCfgParseAddEntry(prAdapter, pucKeyHead, pucKeyTail, -+ pucValueHead, pucValueTail); -+ } -+ ucState = WAIT_KEY_HEAD; -+ pucKeyTail = NULL; -+ pucKeyHead = NULL; -+ pucValueHead = NULL; -+ pucValueTail = NULL; -+ -+ } else if (c == '=') { -+ if (ucState == WAIT_KEY_TAIL) { -+ pucKeyTail = &pbuf[i - 1]; -+ ucState = WAIT_VALUE_HEAD; -+ } -+ } else if (c == ' ' || c == '\t') { -+ if (ucState == WAIT_KEY_HEAD) -+ ; -+ else if (ucState == WAIT_KEY_TAIL) { -+ pucKeyTail = &pbuf[i - 1]; -+ ucState = WAIT_VALUE_HEAD; -+ } -+ } else { -+ -+ if (c == '#') { -+ /* comments */ -+ if (ucState == WAIT_KEY_HEAD) -+ ucState = WAIT_COMMENT_TAIL; -+ else if (ucState == WAIT_VALUE_TAIL) -+ pucValueTail = &pbuf[i]; -+ -+ } else { -+ if (ucState == WAIT_KEY_HEAD) { -+ pucKeyHead = &pbuf[i]; -+ pucKeyTail = &pbuf[i]; -+ ucState = WAIT_KEY_TAIL; -+ } else if (ucState == WAIT_VALUE_HEAD) { -+ pucValueHead = &pbuf[i]; -+ pucValueTail = &pbuf[i]; -+ ucState = WAIT_VALUE_TAIL; -+ } else if (ucState == WAIT_VALUE_TAIL) -+ pucValueTail = &pbuf[i]; -+ } -+ } -+ -+ } /* for */ -+ -+ if (ucState == WAIT_VALUE_TAIL) { -+ /* Entry found */ -+ if (pucValueTail) -+ wlanCfgParseAddEntry(prAdapter, pucKeyHead, pucKeyTail, pucValueHead, pucValueTail); -+ } -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} -+#endif -+ -+#if CFG_SUPPORT_CFG_FILE -+WLAN_STATUS wlanCfgInit(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen, UINT_32 u4Flags) -+{ -+ P_WLAN_CFG_T prWlanCfg; -+ /* P_WLAN_CFG_ENTRY_T prWlanCfgEntry; */ -+ prAdapter->prWlanCfg = &prAdapter->rWlanCfg; -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ kalMemZero(prWlanCfg, sizeof(WLAN_CFG_T)); -+ ASSERT(prWlanCfg); -+ prWlanCfg->u4WlanCfgEntryNumMax = WLAN_CFG_ENTRY_NUM_MAX; -+ prWlanCfg->u4WlanCfgKeyLenMax = WLAN_CFG_KEY_LEN_MAX; -+ prWlanCfg->u4WlanCfgValueLenMax = WLAN_CFG_VALUE_LEN_MAX; -+#if 0 -+ DBGLOG(INIT, INFO, "Init wifi config len %u max entry %u\n", u4ConfigBufLen, prWlanCfg->u4WlanCfgEntryNumMax); -+#endif -+ /* self test */ -+ wlanCfgSet(prAdapter, "ConfigValid", "0x123", 0); -+ if (wlanCfgGetUint32(prAdapter, "ConfigValid", 0) != 0x123) -+ DBGLOG(INIT, ERROR, "wifi config error %u\n", __LINE__); -+ wlanCfgSet(prAdapter, "ConfigValid", "1", 0); -+ if (wlanCfgGetUint32(prAdapter, "ConfigValid", 0) != 1) -+ DBGLOG(INIT, ERROR, "wifi config error %u\n", __LINE__); -+#if 0 /* soc chip didn't support these parameters now */ -+ /* Add initil config */ -+ /* use g,wlan,p2p,ap as prefix */ -+ /* Don't set cb here , overwrite by another api */ -+ wlanCfgSet(prAdapter, "TxLdpc", "1", 0); -+ wlanCfgSet(prAdapter, "RxLdpc", "1", 0); -+ wlanCfgSet(prAdapter, "RxBeamformee", "1", 0); -+ wlanCfgSet(prAdapter, "RoamTh1", "100", 0); -+ wlanCfgSet(prAdapter, "RoamTh2", "150", 0); -+ wlanCfgSet(prAdapter, "wlanRxLdpc", "1", 0); -+ wlanCfgSet(prAdapter, "apRxLdpc", "1", 0); -+ wlanCfgSet(prAdapter, "p2pRxLdpc", "1", 0); -+#endif -+ /* Parse the pucConfigBuff */ -+ -+ if (pucConfigBuf && (u4ConfigBufLen > 0)) -+ wlanCfgParse(prAdapter, pucConfigBuf, u4ConfigBufLen); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to initialize WLAN feature options -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanCfgApply(IN P_ADAPTER_T prAdapter) -+{ -+#define STR2BYTE(s) (((((PUINT_8)s)[0]-'0')*10)+(((PUINT_8)s)[1]-'0')) -+ CHAR aucValue[WLAN_CFG_VALUE_LEN_MAX]; -+ P_WIFI_VAR_T prWifiVar = &prAdapter->rWifiVar; -+ P_REG_INFO_T prRegInfo = &prAdapter->prGlueInfo->rRegInfo; -+ P_TX_PWR_PARAM_T prTxPwr = &prRegInfo->rTxPwr; -+ -+ kalMemZero(aucValue, sizeof(aucValue)); -+ DBGLOG(INIT, LOUD, "CFG_FILE: Apply Config File\n"); -+ /* Apply COUNTRY Config */ -+ if (wlanCfgGet(prAdapter, "country", aucValue, "", 0) == WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, LOUD, "CFG_FILE: Found Country Key, Value=%s\n", aucValue); -+ prAdapter->rWifiVar.rConnSettings.u2CountryCode = -+ (((UINT_16) aucValue[0]) << 8) | ((UINT_16) aucValue[1]); -+ prRegInfo->au2CountryCode[0] = aucValue[0]; -+ prRegInfo->au2CountryCode[1] = aucValue[1]; -+ } -+ prWifiVar->ucApWpsMode = (UINT_8) wlanCfgGetUint32(prAdapter, "ApWpsMode", 0); -+ prWifiVar->ucCert11nMode = (UINT_8)wlanCfgGetUint32(prAdapter, "Cert11nMode", 0); -+ DBGLOG(INIT, LOUD, "CFG_FILE: ucApWpsMode = %u, ucCert11nMode = %u\n", -+ prWifiVar->ucApWpsMode, prWifiVar->ucCert11nMode); -+ if (prWifiVar->ucCert11nMode == 1) -+ nicWriteMcr(prAdapter, 0x11111115 , 1); -+ -+ if (wlanCfgGet(prAdapter, "5G_support", aucValue, "", 0) == WLAN_STATUS_SUCCESS) -+ prRegInfo->ucSupport5GBand = (*aucValue == 'y') ? 1 : 0; -+ if (wlanCfgGet(prAdapter, "TxPower2G4CCK", aucValue, "", 0) == WLAN_STATUS_SUCCESS -+ && kalStrLen(aucValue) == 2) { -+ prTxPwr->cTxPwr2G4Cck = STR2BYTE(aucValue); -+ DBGLOG(INIT, LOUD, "2.4G cck=%d\n", prTxPwr->cTxPwr2G4Cck); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower2G4OFDM", aucValue, "", 0) == WLAN_STATUS_SUCCESS && -+ kalStrLen(aucValue) == 10) { -+ prTxPwr->cTxPwr2G4OFDM_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr2G4OFDM_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr2G4OFDM_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr2G4OFDM_48Mbps = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr2G4OFDM_54Mbps = STR2BYTE(aucValue + 8); -+ DBGLOG(INIT, LOUD, "2.4G OFDM=%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr2G4OFDM_BPSK, prTxPwr->cTxPwr2G4OFDM_QPSK, -+ prTxPwr->cTxPwr2G4OFDM_16QAM, prTxPwr->cTxPwr2G4OFDM_48Mbps, -+ prTxPwr->cTxPwr2G4OFDM_54Mbps); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower2G4HT20", aucValue, "", 0) == WLAN_STATUS_SUCCESS && -+ kalStrLen(aucValue) == 12) { -+ prTxPwr->cTxPwr2G4HT20_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr2G4HT20_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr2G4HT20_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr2G4HT20_MCS5 = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr2G4HT20_MCS6 = STR2BYTE(aucValue + 8); -+ prTxPwr->cTxPwr2G4HT20_MCS7 = STR2BYTE(aucValue + 10); -+ DBGLOG(INIT, LOUD, "2.4G HT20=%d,%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr2G4HT20_BPSK, prTxPwr->cTxPwr2G4HT20_QPSK, -+ prTxPwr->cTxPwr2G4HT20_16QAM, prTxPwr->cTxPwr2G4HT20_MCS5, -+ prTxPwr->cTxPwr2G4HT20_MCS6, prTxPwr->cTxPwr2G4HT20_MCS7); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower2G4HT40", aucValue, "", 0) == WLAN_STATUS_SUCCESS && -+ kalStrLen(aucValue) == 12) { -+ prTxPwr->cTxPwr2G4HT40_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr2G4HT40_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr2G4HT40_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr2G4HT40_MCS5 = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr2G4HT40_MCS6 = STR2BYTE(aucValue + 8); -+ prTxPwr->cTxPwr2G4HT40_MCS7 = STR2BYTE(aucValue + 10); -+ DBGLOG(INIT, LOUD, "2.4G HT40=%d,%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr2G4HT40_BPSK, prTxPwr->cTxPwr2G4HT40_QPSK, -+ prTxPwr->cTxPwr2G4HT40_16QAM, prTxPwr->cTxPwr2G4HT40_MCS5, -+ prTxPwr->cTxPwr2G4HT40_MCS6, prTxPwr->cTxPwr2G4HT40_MCS7); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower5GOFDM", aucValue, "", 0) == WLAN_STATUS_SUCCESS -+ && kalStrLen(aucValue) == 10) { -+ prTxPwr->cTxPwr5GOFDM_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr5GOFDM_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr5GOFDM_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr5GOFDM_48Mbps = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr5GOFDM_54Mbps = STR2BYTE(aucValue + 8); -+ DBGLOG(INIT, LOUD, "5G OFDM=%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr5GOFDM_BPSK, prTxPwr->cTxPwr5GOFDM_QPSK, -+ prTxPwr->cTxPwr5GOFDM_16QAM, prTxPwr->cTxPwr5GOFDM_48Mbps, -+ prTxPwr->cTxPwr5GOFDM_54Mbps); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower5GHT20", aucValue, "", 0) == WLAN_STATUS_SUCCESS -+ && kalStrLen(aucValue) == 12) { -+ prTxPwr->cTxPwr5GHT20_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr5GHT20_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr5GHT20_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr5GHT20_MCS5 = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr5GHT20_MCS6 = STR2BYTE(aucValue + 8); -+ prTxPwr->cTxPwr5GHT20_MCS7 = STR2BYTE(aucValue + 10); -+ DBGLOG(INIT, LOUD, "5G HT20=%d,%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr5GHT20_BPSK, prTxPwr->cTxPwr5GHT20_QPSK, -+ prTxPwr->cTxPwr5GHT20_16QAM, prTxPwr->cTxPwr5GHT20_MCS5, prTxPwr->cTxPwr5GHT20_MCS6, -+ prTxPwr->cTxPwr5GHT20_MCS7); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower5GHT40", aucValue, "", 0) == WLAN_STATUS_SUCCESS -+ && kalStrLen(aucValue) == 12) { -+ prTxPwr->cTxPwr5GHT40_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr5GHT40_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr5GHT40_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr5GHT40_MCS5 = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr5GHT40_MCS6 = STR2BYTE(aucValue + 8); -+ prTxPwr->cTxPwr5GHT40_MCS7 = STR2BYTE(aucValue + 10); -+ DBGLOG(INIT, LOUD, "5G HT40=%d,%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr5GHT40_BPSK, prTxPwr->cTxPwr5GHT40_QPSK, -+ prTxPwr->cTxPwr5GHT40_16QAM, prTxPwr->cTxPwr5GHT40_MCS5, prTxPwr->cTxPwr5GHT40_MCS6, -+ prTxPwr->cTxPwr5GHT40_MCS7); -+ } -+ /* TODO: Apply other Config */ -+} -+#endif /* CFG_SUPPORT_CFG_FILE */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c -new file mode 100644 -index 0000000000000..993ff061ed203 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c -@@ -0,0 +1,11050 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_oid.c#5 -+*/ -+ -+/*! \file wlanoid.c -+ \brief This file contains the WLAN OID processing routines of Windows driver for -+ MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_oid.c -+** -+** 09 05 2013 cp.wu -+** isolate logic regarding roaming & reassociation -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+** -+** 09 02 2013 cp.wu -+** add path to handle reassociation request -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 06 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * using the wlanSendSetQueryCmd to set the tx power control cmd. -+ * -+ * 01 06 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * change the set tx power cmd name. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 12 20 2011 cp.wu -+ * [WCXRP00001144] [MT6620 Wi-Fi][Driver][Firmware] Add RF_FUNC_ID for exposing device and related version information -+ * add driver implementations for RF_AT_FUNCID_FW_INFO & RF_AT_FUNCID_DRV_INFO -+ * to expose version information -+ * -+ * 12 05 2011 cp.wu -+ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path -+ * add CONNECT_BY_BSSID policy -+ * -+ * 11 22 2011 cp.wu -+ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous to -+ * asynchronous approach to avoid incomplete state termination -+ * 1. change RDD related compile option brace position. -+ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state -+ * without join timeout timer ticking -+ * 3. otherwise, insert AIS_REQUEST into pending request queue -+ * -+ * 11 21 2011 cp.wu -+ * [WCXRP00001118] [MT6620 Wi-Fi][Driver] Corner case protections to pass Monkey testing -+ * 1. wlanoidQueryBssIdList might be passed with a non-zero length but a NULL pointer of buffer -+ * add more checking for such cases -+ * -+ * 2. kalSendComplete() might be invoked with a packet belongs to P2P network right after P2P is unregistered. -+ * add some tweaking to protect such cases because that net device has become invalid. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Fix compiling warning -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 11 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters of bb and ar for xlog. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 11 09 2011 george.huang -+ * [WCXRP00000871] [MT6620 Wi-Fi][FW] Include additional wakeup condition, which is by -+ * consequent DTIM unicast indication add XLOG for Set PS mode entry -+ * -+ * 11 08 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * check if CFG_SUPPORT_SWCR is defined to aoid compiler error. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG -+ * -+ * 11 02 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add RDD certification features. -+ * -+ * 10 21 2011 eddie.chen -+ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout -+ * Add switch to ignore the STA aging timeout. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 15 2011 tsaiyuan.hsu -+ * [WCXRP00000938] [MT6620 Wi-Fi][FW] add system config for CTIA -+ * correct fifo full control from query to set operation for CTIA. -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 08 17 2011 tsaiyuan.hsu -+ * [WCXRP00000938] [MT6620 Wi-Fi][FW] add system config for CTIA -+ * add system config for CTIA. -+ * -+ * 08 15 2011 george.huang -+ * [MT6620 Wi-Fi][FW] handle TSF drift for connection detection -+ * . -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 07 11 2011 wh.su -+ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define for make sure the value is initialize, -+ * for customer not enable WAPI -+ * For make sure wapi initial value is set. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * check with firmware for valid MAC address. -+ * -+ * 05 02 2011 eddie.chen -+ * [WCXRP00000373] [MT6620 Wi-Fi][FW] SW debug control -+ * Fix compile warning. -+ * -+ * 04 29 2011 george.huang -+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter -+ * . -+ * -+ * 04 27 2011 george.huang -+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter -+ * add more debug message -+ * -+ * 04 26 2011 eddie.chen -+ * [WCXRP00000373] [MT6620 Wi-Fi][FW] SW debug control -+ * Add rx path profiling. -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 03 31 2011 puff.wen -+ * NULL -+ * . -+ * -+ * 03 29 2011 puff.wen -+ * NULL -+ * Add chennel switch for stress test -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000604] [MT6620 Wi-Fi][Driver] Surpress Klockwork Warning -+ * surpress klock warning with code path rewritten -+ * -+ * 03 24 2011 wh.su -+ * [WCXRP00000595] [MT6620 Wi-Fi][Driver] at CTIA indicate disconnect to make the ps profile can apply -+ * use disconnect event instead of ais abort for CTIA testing. -+ * -+ * 03 23 2011 george.huang -+ * [WCXRP00000586] [MT6620 Wi-Fi][FW] Modify for blocking absence request right after connected -+ * revise for CTIA power mode setting -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 17 2011 yarco.yang -+ * [WCXRP00000569] [MT6620 Wi-Fi][F/W][Driver] Set multicast address support current network usage -+ * . -+ * -+ * 03 15 2011 george.huang -+ * [WCXRP00000557] [MT6620 Wi-Fi] Support current consumption test mode commands -+ * Support current consumption measurement mode command -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 03 10 2011 cp.wu -+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 -+ * deprecate configuration used by MT6620 E2 -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 04 2011 cp.wu -+ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection -+ * surpress compile warning occurred when compiled by GNU compiler collection. -+ * -+ * 03 03 2011 wh.su -+ * [WCXRP00000510] [MT6620 Wi-Fi] [Driver] Fixed the CTIA enter test mode issue -+ * fixed the enter ctia test mode issue. -+ * -+ * 03 02 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * Update sigma CAPI for U-APSD setting -+ * -+ * 03 02 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * Support UAPSD/OppPS/NoA parameter setting -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as -+ * initial RSSI right after connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 01 27 2011 george.huang -+ * [WCXRP00000400] [MT6620 Wi-Fi] support CTIA power mode setting -+ * Support CTIA power mode setting. -+ * -+ * 01 26 2011 wh.su -+ * [WCXRP00000396] [MT6620 Wi-Fi][Driver] Support Sw Ctrl ioctl at linux -+ * adding the SW cmd ioctl support, use set/get structure ioctl. -+ * -+ * 01 25 2011 cp.wu -+ * [WCXRP00000394] [MT6620 Wi-Fi][Driver] Count space needed for generating error message in -+ * scanning list into buffer size checking -+ * when doing size prechecking, check illegal MAC address as well -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 01 15 2011 puff.wen -+ * NULL -+ * Add Stress test -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * check if allow to switch to IBSS mode via concurrent module before setting to IBSS mode -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000342] [MT6620 Wi-Fi][Driver] show error code in scanning list when MAC address is not -+ * correctly configured in NVRAM -+ * show error code 0x10 when MAC address in NVRAM is not configured correctly. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations -+ * to ease physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 28 2010 george.huang -+ * [WCXRP00000232] [MT5931 Wi-Fi][FW] Modifications for updated HW power on sequence and related design -+ * support WMM-PS U-APSD AC assignment. -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * report EEPROM used flag via NIC_CAPABILITY -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools -+ * -+ * 12 16 2010 cp.wu -+ * [WCXRP00000268] [MT6620 Wi-Fi][Driver] correction for WHQL failed items -+ * correction for OID_802_11_NETWORK_TYPES_SUPPORTED handlers -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000256] [MT6620 Wi-Fi][Driver] Eliminate potential issues which is identified by Klockwork -+ * suppress warning reported by Klockwork. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 30 2010 cp.wu -+ * [WCXRP00000213] [MT6620 Wi-Fi][Driver] Implement scanning with specified SSID for wpa_supplicant with ap_scan=1 -+ * . -+ * -+ * 11 26 2010 cp.wu -+ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only -+ * with necessary data field checking -+ * 1. NVRAM error is now treated as warning only, thus normal operation is still available -+ * but extra scan result used to indicate user is attached -+ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown -+ * -+ * 11 25 2010 cp.wu -+ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM -+ * add scanning with specified SSID facility to AIS-FSM -+ * -+ * 11 21 2010 wh.su -+ * [WCXRP00000192] [MT6620 Wi-Fi][Driver] Fixed fail trying to build connection with Security -+ * AP while enable WAPI message check -+ * Not set the wapi mode while the wapi assoc info set non-wapi ie. -+ * -+ * 11 05 2010 wh.su -+ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value -+ * fixed the.pmkid value mismatch issue -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying -+ * current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 22 2010 cp.wu -+ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration -+ * dos2unix conversion. -+ * -+ * 10 20 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * use OID_CUSTOM_TEST_MODE as indication for driver reset -+ * by dropping pending TX packets -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android complete -+ * implementation of Android NVRAM access -+ * -+ * 10 06 2010 yuche.tsai -+ * NULL -+ * Update SLT 5G Test Channel Set. -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 10 06 2010 yuche.tsai -+ * NULL -+ * Update For SLT 5G Test Channel Selection Rule. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000075] [MT6620 Wi-Fi][Driver] Fill query buffer for OID_802_11_BSSID_LIST in 4-bytes aligned form -+ * Query buffer size needs to be enlarged due to result is filled in 4-bytes alignment boundary -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and -+ * replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000075] [MT6620 Wi-Fi][Driver] Fill query buffer for OID_802_11_BSSID_LIST in 4-bytes aligned form -+ * Extend result length to multiples of 4-bytes -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate unused variables which lead gcc to argue -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature -+ * Modify online scan as a run-time adjustable option (for Windows, in registry) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item -+ * use firmware reported mac address right after wlanAdapterStart() as permanent address -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Update SLT due to API change of SCAN module. -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * Androi/Linux: return current operating channel information -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * 1) initialize for correct parameter even for disassociation. -+ * 2) AIS-FSM should have a limit on trials to build connection -+ * -+ * 09 03 2010 yuche.tsai -+ * NULL -+ * Refine SLT IO control handler. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 30 2010 chinglan.wang -+ * NULL -+ * Modify the rescan condition. -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Finish SLT TX/RX & Rate Changing Support. -+ * -+ * 08 27 2010 chinglan.wang -+ * NULL -+ * Update configuration for MT6620_E1_PRE_ALPHA_1832_0827_2010 -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cp.wu -+ * NULL -+ * 1) initialize variable for enabling short premable/short time slot. -+ * 2) add compile option for disabling online scan -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * . -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * update params defined in CMD_SET_NETWORK_ADDRESS_LIST -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * fix for check build WHQL testing: -+ * 1) do not assert query buffer if indicated buffer length is zero -+ * 2) sdio.c has bugs which cause freeing same pointer twice -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * revert changelist #15371, efuse read/write access will be done by RF test approach -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add OID definitions for EFUSE read/write access. -+ * -+ * 08 04 2010 george.huang -+ * NULL -+ * handle change PS mode OID/ CMD -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add an extra parameter to rftestQueryATInfo 'cause it's necessary to pass u4FuncData for query request. -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * bypass u4FuncData for RF-Test query request as well. -+ * -+ * 08 04 2010 yarco.yang -+ * NULL -+ * Add TX_AMPDU and ADDBA_REJECT command -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 02 2010 george.huang -+ * NULL -+ * add WMM-PS test related OID/ CMD handlers -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 26 2010 cp.wu -+ * -+ * re-commit code logic being overwriten. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 20 2010 cp.wu -+ * -+ * 1) [AIS] when new scan is issued, clear currently available scanning result except the connected one -+ * 2) refine disconnection behaviour when issued during BG-SCAN process -+ * -+ * 07 19 2010 wh.su -+ * -+ * modify the auth and encry status variable. -+ * -+ * 07 16 2010 cp.wu -+ * -+ * remove work-around in case SCN is not available. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) change fake BSS_DESC from channel 6 to channel 1 due to channel switching is not done yet. -+ * 2) after MAC address is queried from firmware, all related variables in driver domain should be updated as well -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add SCN compilation option. -+ * 2) when SCN is not turned on, BSSID_SCAN will generate a fake entry for 1st connection -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implement SCAN-REQUEST oid as mailbox message dispatching. -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * integrate . -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * adding the compiling flag for oid pmkid. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable RX management frame handling. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move timer callback to glue layer. -+ * -+ * 05 28 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * simplify cmd packet sending for RF test and MCR access OIDs -+ * -+ * 05 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * disable radio even when STA is not associated. -+ * -+ * 05 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct 2 OID behaviour to meet WHQL requirement. -+ * -+ * 05 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) Modify set mac address code -+ * 2) remove power management macro -+ * -+ * 05 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct BSSID_LIST oid when radio if turned off. -+ * -+ * 05 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) when acquiring LP-own, write for clr-own with lower frequency compared to read poll -+ * 2) correct address list parsing -+ * -+ * 05 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * disable wlanoidSetNetworkAddress() temporally. -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * some OIDs should be DRIVER_CORE instead of GLUE_EXTENSION -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) disable NETWORK_LAYER_ADDRESSES handling temporally. -+ * 2) finish statistics OIDs -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change OID behavior to meet WHQL requirement. -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 05 18 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement Wakeup-on-LAN except firmware integration part -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct wlanoidSet802dot11PowerSaveProfile implementation. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) enable CMD/EVENT ver 0.9 definition. -+ * 2) abandon use of ENUM_MEDIA_STATE -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct OID_802_11_DISASSOCIATE handling. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Add dissassocation support for wpa supplicant -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct return value. -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add NULL OID implementation for WOL-related OIDs. -+ * -+ * 05 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * for disassociation, still use parameter with current setting. -+ * -+ * 05 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * for disassociation, generate a WZC-compatible invalid SSID. -+ * -+ * 05 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * associate to illegal SSID when handling OID_802_11_DISASSOCIATE -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * reserve field of privacy filter and RTS threshold setting. -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * . -+ * -+ * 04 22 2010 cp.wu -+ * [WPD00003830]add OID_802_11_PRIVACY_FILTER support -+ * enable RX filter OID -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Add ioctl of power management -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * 2) command sequence number is now increased atomically -+ * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct OID_802_11_CONFIGURATION query for infrastructure mode. -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) remove unused spin lock declaration -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * finish non-glue layer access to glue variables -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * are done in adapter layer. -+ * -+ * 04 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * (1)improve none-glue code portability -+ * (2) disable set Multicast address during atomic context -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * ePowerCtrl is not necessary as a glue variable. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * . -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * statistics information OIDs are now handled by querying from firmware domain -+ * -+ * 03 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve glue code portability -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * indicate media stream mode after set is done -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add a temporary flag for integration with CMD/EVENT v0.9. -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. -+ * the frequency is used for adhoc connection only -+ * 2) update with SD1 v0.9 CMD/EVENT documentation -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK -+ * -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00003824][MT6620 Wi-Fi][New Feature] Add support of large scan list -+ * Implement feature needed by CR: WPD00003824: refining association command by pasting scanning result -+ * -+ * 03 19 2010 wh.su -+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test -+ * adding the check for pass WHQL test item. -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+* 03 16 2010 wh.su -+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test -+ * fixed some whql pre-test fail case. -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement custom OID: EEPROM read/write access -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_3_MULTICAST_LIST oid handling -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock -+ * * 2) ensure wlanReleasePendingOid will clear all command queues -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * send CMD_ID_INFRASTRUCTURE when handling OID_802_11_INFRASTRUCTURE_MODE set. -+ * -+ * 02 24 2010 wh.su -+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test -+ * Don't needed to check the auth mode, WHQL testing not specific at auth wpa2. -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * do not check SSID validity anymore. -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add checksum offloading support. -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * 2. follow MSDN defined behavior when associates to another AP -+ * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move ucCmdSeqNum as instance variable -+ * -+ * 02 04 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * when OID_CUSTOM_OID_INTERFACE_VERSION is queried, do modify connection states -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) implement timeout mechanism when OID is pending for longer than 1 second -+ * * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * 4. correct some HAL implementation -+ * -+ * 01 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement following 802.11 OIDs: -+ * OID_802_11_RSSI, -+ * OID_802_11_RSSI_TRIGGER, -+ * OID_802_11_STATISTICS, -+ * OID_802_11_DISASSOCIATE, -+ * OID_802_11_POWER_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_MEDIA_STREAM_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * do not fill ucJoinOnly currently -+ * -+ * 01 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * enable to connect to ad-hoc network -+ * -+ * 01 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * .implement Set/Query BeaconInterval/AtimWindow -+ * -+ * 01 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * .Set/Get AT Info is not blocked even when driver is not in fg test mode -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * and result is retrieved by get ATInfo instead -+ * 2) add 4 counter for recording aggregation statistics -+ * -+ * 12 28 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate redundant variables for connection_state -+** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-12-16 22:13:36 GMT mtk02752 -+** change hard-coded MAC address to match with FW (temporally) -+** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-12-10 16:49:50 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-12-08 17:38:49 GMT mtk02752 -+** + add OID for RF test -+** * MCR RD/WR are modified to match with cmd/event definition -+** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-12-08 11:32:20 GMT mtk02752 -+** add skeleton for RF test implementation -+** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-12-03 16:43:24 GMT mtk01461 -+** Modify query SCAN list oid by adding prEventScanResult -+** -+** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-12-03 16:39:27 GMT mtk01461 -+** Sync CMD data structure in set ssid oid -+** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-12-03 16:28:22 GMT mtk01461 -+** Add invalid check of set SSID oid and fix query scan list oid -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-30 17:33:08 GMT mtk02752 -+** implement wlanoidSetInfrastructureMode/wlanoidQueryInfrastructureMode -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-30 10:53:49 GMT mtk02752 -+** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-30 09:22:48 GMT mtk02752 -+** correct wifi cmd length mismatch -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-25 21:34:33 GMT mtk02752 -+** sync EVENT_SCAN_RESULT_T with firmware -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-25 21:03:27 GMT mtk02752 -+** implement wlanoidQueryBssidList() -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-25 18:17:17 GMT mtk02752 -+** refine GL_WLAN_INFO_T for buffering scan result -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-23 20:28:51 GMT mtk02752 -+** some OID will be set to WLAN_STATUS_PENDING until it is sent via wlanSendCommand() -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-23 17:56:36 GMT mtk02752 -+** implement wlanoidSetBssidListScan(), wlanoidSetBssid() and wlanoidSetSsid() -+** -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-13 17:20:53 GMT mtk02752 -+** add Set BSSID/SSID path but disabled temporally due to FW is not ready yet -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-13 12:28:58 GMT mtk02752 -+** add wlanoidSetBssidListScan -> cmd_info path -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-09 22:48:07 GMT mtk01084 -+** modify test cases entry -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-04 14:10:58 GMT mtk01084 -+** add new test interfaces -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-10-30 18:17:10 GMT mtk01084 -+** fix compiler warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-10-29 19:46:26 GMT mtk01084 -+** add test functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-23 16:07:56 GMT mtk01084 -+** include new file -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:29 GMT mtk01084 -+** modify for new HW architecture -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-02 13:48:49 GMT mtk01725 -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-09-09 17:26:04 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-21 12:09:50 GMT mtk01461 -+** Update for MCR Write OID -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-21 09:35:18 GMT mtk01461 -+** Update wlanoidQueryMcrRead() for composing CMD_INFO_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-17 18:09:51 GMT mtk01426 -+** Remove kalIndicateStatusAndComplete() in wlanoidQueryOidInterfaceVersion() -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-14 15:51:50 GMT mtk01426 -+** Add MCR read/write support -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-19 18:32:40 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:06:31 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+/****************************************************************************** -+* C O M P I L E R F L A G S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************* -+*/ -+#include "precomp.h" -+#include "mgmt/rsn.h" -+ -+#include -+ -+/****************************************************************************** -+* C O N S T A N T S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* D A T A T Y P E S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* P U B L I C D A T A -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* P R I V A T E D A T A -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* M A C R O S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N S -+******************************************************************************* -+*/ -+#if CFG_ENABLE_STATISTICS_BUFFERING -+static BOOLEAN IsBufferedStatisticsUsable(P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->fgIsStatValid == TRUE && -+ (kalGetTimeTick() - prAdapter->rStatUpdateTime) <= CFG_STATISTICS_VALID_CYCLE) -+ return TRUE; -+ else -+ return FALSE; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the supported physical layer network -+* type that can be used by the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryNetworkTypesSupported(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ UINT_32 u4NumItem = 0; -+ ENUM_PARAM_NETWORK_TYPE_T eSupportedNetworks[PARAM_NETWORK_TYPE_NUM]; -+ PPARAM_NETWORK_TYPE_LIST prSupported; -+ -+ /* The array of all physical layer network subtypes that the driver supports. */ -+ -+ DEBUGFUNC("wlanoidQueryNetworkTypesSupported"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ /* Init. */ -+ for (u4NumItem = 0; u4NumItem < PARAM_NETWORK_TYPE_NUM; u4NumItem++) -+ eSupportedNetworks[u4NumItem] = 0; -+ -+ u4NumItem = 0; -+ -+ eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_DS; -+ u4NumItem++; -+ -+ eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_OFDM24; -+ u4NumItem++; -+ -+ *pu4QueryInfoLen = -+ (UINT_32) OFFSET_OF(PARAM_NETWORK_TYPE_LIST, eNetworkType) + -+ (u4NumItem * sizeof(ENUM_PARAM_NETWORK_TYPE_T)); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prSupported = (PPARAM_NETWORK_TYPE_LIST) pvQueryBuffer; -+ prSupported->NumberOfItems = u4NumItem; -+ kalMemCopy(prSupported->eNetworkType, eSupportedNetworks, u4NumItem * sizeof(ENUM_PARAM_NETWORK_TYPE_T)); -+ -+ DBGLOG(OID, TRACE, "NDIS supported network type list: %u\n", prSupported->NumberOfItems); -+ DBGLOG_MEM8(OID, TRACE, prSupported, *pu4QueryInfoLen); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryNetworkTypesSupported */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current physical layer network -+* type used by the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryNetworkTypeInUse(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ /* TODO: need to check the OID handler content again!! */ -+ -+ ENUM_PARAM_NETWORK_TYPE_T rCurrentNetworkTypeInUse = PARAM_NETWORK_TYPE_OFDM24; -+ -+ DEBUGFUNC("wlanoidQueryNetworkTypeInUse"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(ENUM_PARAM_NETWORK_TYPE_T)) { -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) -+ rCurrentNetworkTypeInUse = (ENUM_PARAM_NETWORK_TYPE_T) (prAdapter->rWlanInfo.ucNetworkType); -+ else -+ rCurrentNetworkTypeInUse = (ENUM_PARAM_NETWORK_TYPE_T) (prAdapter->rWlanInfo.ucNetworkTypeInUse); -+ -+ *(P_ENUM_PARAM_NETWORK_TYPE_T) pvQueryBuffer = rCurrentNetworkTypeInUse; -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); -+ -+ DBGLOG(OID, TRACE, "Network type in use: %d\n", rCurrentNetworkTypeInUse); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryNetworkTypeInUse */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the physical layer network type used -+* by the driver. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns the -+* amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS The given network type is supported and accepted. -+* \retval WLAN_STATUS_INVALID_DATA The given network type is not in the -+* supported list. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetNetworkTypeInUse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ /* TODO: need to check the OID handler content again!! */ -+ -+ ENUM_PARAM_NETWORK_TYPE_T eNewNetworkType; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidSetNetworkTypeInUse"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen < sizeof(ENUM_PARAM_NETWORK_TYPE_T)) { -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ eNewNetworkType = *(P_ENUM_PARAM_NETWORK_TYPE_T) pvSetBuffer; -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); -+ -+ DBGLOG(OID, INFO, "New network type: %d mode\n", eNewNetworkType); -+ -+ switch (eNewNetworkType) { -+ -+ case PARAM_NETWORK_TYPE_DS: -+ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_DS; -+ break; -+ -+ case PARAM_NETWORK_TYPE_OFDM5: -+ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_OFDM5; -+ break; -+ -+ case PARAM_NETWORK_TYPE_OFDM24: -+ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_OFDM24; -+ break; -+ -+ case PARAM_NETWORK_TYPE_AUTOMODE: -+ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_AUTOMODE; -+ break; -+ -+ case PARAM_NETWORK_TYPE_FH: -+ DBGLOG(OID, INFO, "Not support network type: %d\n", eNewNetworkType); -+ rStatus = WLAN_STATUS_NOT_SUPPORTED; -+ break; -+ -+ default: -+ DBGLOG(OID, INFO, "Unknown network type: %d\n", eNewNetworkType); -+ rStatus = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ /* Verify if we support the new network type. */ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(OID, WARN, "Unknown network type: %d\n", eNewNetworkType); -+ -+ return rStatus; -+} /* wlanoidSetNetworkTypeInUse */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current BSSID. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBssid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidQueryBssid"); -+ -+ ASSERT(prAdapter); -+ -+ if (u4QueryBufferLen < MAC_ADDR_LEN) { -+ ASSERT(pu4QueryInfoLen); -+ *pu4QueryInfoLen = MAC_ADDR_LEN; -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ ASSERT(u4QueryBufferLen >= MAC_ADDR_LEN); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) -+ kalMemCopy(pvQueryBuffer, prAdapter->rWlanInfo.rCurrBssId.arMacAddress, MAC_ADDR_LEN); -+ else if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS) { -+ PARAM_MAC_ADDRESS aucTemp; /*!< BSSID */ -+ -+ COPY_MAC_ADDR(aucTemp, prAdapter->rWlanInfo.rCurrBssId.arMacAddress); -+ aucTemp[0] &= ~BIT(0); -+ aucTemp[1] |= BIT(1); -+ COPY_MAC_ADDR(pvQueryBuffer, aucTemp); -+ } else -+ rStatus = WLAN_STATUS_ADAPTER_NOT_READY; -+ -+ *pu4QueryInfoLen = MAC_ADDR_LEN; -+ return rStatus; -+} /* wlanoidQueryBssid */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the list of all BSSIDs detected by -+* the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBssidList(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 i, u4BssidListExLen; -+ P_PARAM_BSSID_LIST_EX_T prList; -+ P_PARAM_BSSID_EX_T prBssidEx; -+ PUINT_8 cp; -+ -+ DEBUGFUNC("wlanoidQueryBssidList"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen) { -+ ASSERT(pvQueryBuffer); -+ -+ if (!pvQueryBuffer) -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in qeury BSSID list! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ u4BssidListExLen = 0; -+ -+ if (prAdapter->fgIsRadioOff == FALSE) { -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) -+ u4BssidListExLen += ALIGN_4(prAdapter->rWlanInfo.arScanResult[i].u4Length); -+ } -+ -+ if (u4BssidListExLen) -+ u4BssidListExLen += 4; /* u4NumberOfItems. */ -+ else -+ u4BssidListExLen = sizeof(PARAM_BSSID_LIST_EX_T); -+ -+ *pu4QueryInfoLen = u4BssidListExLen; -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ /* Clear the buffer */ -+ kalMemZero(pvQueryBuffer, u4BssidListExLen); -+ -+ prList = (P_PARAM_BSSID_LIST_EX_T) pvQueryBuffer; -+ cp = (PUINT_8) &prList->arBssid[0]; -+ -+ if (prAdapter->fgIsRadioOff == FALSE && prAdapter->rWlanInfo.u4ScanResultNum > 0) { -+ /* fill up for each entry */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ prBssidEx = (P_PARAM_BSSID_EX_T) cp; -+ -+ /* copy structure */ -+ kalMemCopy(prBssidEx, -+ &(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ -+ /*For WHQL test, Rssi should be in range -10 ~ -200 dBm */ -+ if (prBssidEx->rRssi > PARAM_WHQL_RSSI_MAX_DBM) -+ prBssidEx->rRssi = PARAM_WHQL_RSSI_MAX_DBM; -+ -+ if (prAdapter->rWlanInfo.arScanResult[i].u4IELength > 0) { -+ /* copy IEs */ -+ kalMemCopy(prBssidEx->aucIEs, -+ prAdapter->rWlanInfo.apucScanResultIEs[i], -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength); -+ } -+ /* 4-bytes alignement */ -+ prBssidEx->u4Length = ALIGN_4(prBssidEx->u4Length); -+ -+ cp += prBssidEx->u4Length; -+ prList->u4NumberOfItems++; -+ } -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryBssidList */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request the driver to perform -+* scanning. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBssidListScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_SSID_T prSsid; -+ PARAM_SSID_T rSsid; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidSetBssidListScan()"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pu4SetInfoLen); -+ *pu4SetInfoLen = 0; -+ -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(OID, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ DBGLOG(OID, TRACE, "Scan\n"); -+ -+ if (pvSetBuffer != NULL && u4SetBufferLen != 0) { -+ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, pvSetBuffer, u4SetBufferLen); -+ prSsid = &rSsid; -+ } else { -+ prSsid = NULL; -+ } -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) { -+ if ((prAdapter->fgEnOnlineScan == TRUE) && (prAdapter->ucRddStatus)) { -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ aisFsmScanRequest(prAdapter, prSsid, NULL, 0); -+ } else { -+ /* reject the scan request */ -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } else { -+ /* reject the scan request */ -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } else -+#endif -+ { -+ if (prAdapter->fgEnOnlineScan == TRUE) { -+ aisFsmScanRequest(prAdapter, prSsid, NULL, 0); -+ } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ aisFsmScanRequest(prAdapter, prSsid, NULL, 0); -+ } else { -+ /* reject the scan request */ -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } -+ -+ return rStatus; -+} /* wlanoidSetBssidListScan */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request the driver to perform -+* scanning with attaching information elements(IEs) specified from user space -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBssidListScanExt(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_SCAN_REQUEST_EXT_T prScanRequest; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_PARAM_SSID_T prSsid; -+ PUINT_8 pucIe; -+ UINT_32 u4IeLength; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_8 ucScanTime = AIS_SCN_DONE_TIMEOUT_SEC; -+ -+ DEBUGFUNC("wlanoidSetBssidListScanExt()"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, ERROR, "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (prAdapter->fgTestMode) { -+ DBGLOG(OID, WARN, "didn't support Scan in test mode\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ ASSERT(pu4SetInfoLen); -+ *pu4SetInfoLen = 0; -+ -+ if (u4SetBufferLen != sizeof(PARAM_SCAN_REQUEST_EXT_T)) { -+ DBGLOG(OID, ERROR, "u4SetBufferLen != sizeof(PARAM_SCAN_REQUEST_EXT_T)\n"); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(OID, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ DBGLOG(OID, TRACE, "ScanEx\n"); -+ -+ /* clear old scan backup results if exists */ -+ { -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { -+ kalMemZero(prBssDesc->aucRawBuf, CFG_RAW_BUFFER_SIZE); -+ prBssDesc->u2RawLength = 0; -+ } -+ } -+ } -+ -+ if (pvSetBuffer != NULL && u4SetBufferLen != 0) { -+ prScanRequest = (P_PARAM_SCAN_REQUEST_EXT_T) pvSetBuffer; -+ prSsid = &(prScanRequest->rSsid); -+ pucIe = prScanRequest->pucIE; -+ u4IeLength = prScanRequest->u4IELength; -+ } else { -+ prScanRequest = NULL; -+ prSsid = NULL; -+ pucIe = NULL; -+ u4IeLength = 0; -+ } -+ -+/* P_AIS_FSM_INFO_T prAisFsmInfo; */ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+/* #if CFG_SUPPORT_WFD */ -+#if 0 -+ if ((prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings.ucWfdEnable) && -+ ((prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings.u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) { -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == -+ PARAM_MEDIA_STATE_CONNECTED) { -+ DBGLOG(OID, TRACE, "Twice the Scan Time for WFD\n"); -+ ucScanTime *= 2; -+ } -+ } -+#endif /* CFG_SUPPORT_WFD */ -+ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer, SEC_TO_MSEC(ucScanTime)); -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) { -+ if ((prAdapter->fgEnOnlineScan == TRUE) && (prAdapter->ucRddStatus)) { -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); -+ } else { -+ /* reject the scan request */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } else { -+ /* reject the scan request */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } else -+#endif -+ { -+ if (prAdapter->fgEnOnlineScan == TRUE) { -+ aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); -+ } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); -+ } else { -+ /* reject the scan request */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ rStatus = WLAN_STATUS_FAILURE; -+ DBGLOG(OID, WARN, "ScanEx fail %d!\n", prAdapter->fgEnOnlineScan); -+ } -+ } -+ -+ return rStatus; -+} /* wlanoidSetBssidListScanWithIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine will initiate the join procedure to attempt to associate -+* with the specified BSSID. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBssid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_UINT_8 pAddr; -+ UINT_32 i; -+ INT_32 i4Idx = -1; -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ UINT_8 ucReasonOfDisconnect; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = MAC_ADDR_LEN; -+ if (u4SetBufferLen != MAC_ADDR_LEN) { -+ *pu4SetInfoLen = MAC_ADDR_LEN; -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ pAddr = (P_UINT_8) pvSetBuffer; -+ -+ /* re-association check */ -+ if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pAddr)) { -+ kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED); -+ ucReasonOfDisconnect = DISCONNECT_REASON_CODE_REASSOCIATION; -+ } else { -+ DBGLOG(OID, TRACE, "DisByBssid\n"); -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+ } -+ } else { -+ ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+ } -+ -+ /* check if any scanned result matchs with the BSSID */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) { -+ i4Idx = (INT_32) i; -+ break; -+ } -+ } -+ -+ /* prepare message to AIS */ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS -+ || prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_DEDICATED_IBSS) { -+ /* IBSS *//* beacon period */ -+ prAdapter->rWifiVar.rConnSettings.u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod; -+ prAdapter->rWifiVar.rConnSettings.u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow; -+ } -+ -+ /* Set Connection Request Issued Flag */ -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = TRUE; -+ prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_BSSID; -+ -+ /* Send AIS Abort Message */ -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; -+ prAisAbortMsg->ucReasonOfDisconnect = ucReasonOfDisconnect; -+ -+ /* Update the information to CONNECTION_SETTINGS_T */ -+ prAdapter->rWifiVar.rConnSettings.ucSSIDLen = 0; -+ prAdapter->rWifiVar.rConnSettings.aucSSID[0] = '\0'; -+ -+ COPY_MAC_ADDR(prAdapter->rWifiVar.rConnSettings.aucBSSID, pAddr); -+ -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pAddr)) -+ prAisAbortMsg->fgDelayIndication = TRUE; -+ else -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ DBGLOG(OID, INFO, "SetBssid\n"); -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetBssid() */ -+ -+WLAN_STATUS -+wlanoidSetConnect(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_PARAM_CONNECT_T pParamConn; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ UINT_32 i; -+ /*INT_32 i4Idx = -1, i4MaxRSSI = INT_MIN;*/ -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ BOOLEAN fgIsValidSsid = TRUE; -+ BOOLEAN fgEqualSsid = FALSE; -+ BOOLEAN fgEqualBssid = FALSE; -+ const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ /* MSDN: -+ * Powering on the radio if the radio is powered off through a setting of OID_802_11_DISASSOCIATE -+ */ -+ if (prAdapter->fgIsRadioOff == TRUE) -+ prAdapter->fgIsRadioOff = FALSE; -+ -+ if (u4SetBufferLen != sizeof(PARAM_CONNECT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ else if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; -+ -+ pParamConn = (P_PARAM_CONNECT_T) pvSetBuffer; -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ -+ if (pParamConn->u4SsidLen > 32) { -+ cnmMemFree(prAdapter, prAisAbortMsg); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (!pParamConn->pucBssid && !pParamConn->pucSsid) { -+ cnmMemFree(prAdapter, prAisAbortMsg); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ kalMemZero(prConnSettings->aucSSID, sizeof(prConnSettings->aucSSID)); -+ kalMemZero(prConnSettings->aucBSSID, sizeof(prConnSettings->aucBSSID)); -+ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_ANY; -+ prConnSettings->fgIsConnByBssidIssued = FALSE; -+ -+ if (pParamConn->pucSsid) { -+ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; -+ COPY_SSID(prConnSettings->aucSSID, -+ prConnSettings->ucSSIDLen, pParamConn->pucSsid, (UINT_8) pParamConn->u4SsidLen); -+ if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, -+ pParamConn->pucSsid, pParamConn->u4SsidLen)) -+ fgEqualSsid = TRUE; -+ } -+ if (pParamConn->pucBssid) { -+ if (!EQUAL_MAC_ADDR(aucZeroMacAddr, pParamConn->pucBssid) && IS_UCAST_MAC_ADDR(pParamConn->pucBssid)) { -+ prConnSettings->eConnectionPolicy = CONNECT_BY_BSSID; -+ prConnSettings->fgIsConnByBssidIssued = TRUE; -+ COPY_MAC_ADDR(prConnSettings->aucBSSID, pParamConn->pucBssid); -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pParamConn->pucBssid)) -+ fgEqualBssid = TRUE; -+ } else -+ DBGLOG(OID, TRACE, "wrong bssid %pM to connect\n", pParamConn->pucBssid); -+ } else -+ DBGLOG(OID, TRACE, "No Bssid set\n"); -+ prConnSettings->u4FreqInKHz = pParamConn->u4CenterFreq; -+ -+ /* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */ -+ /* re-association check */ -+ if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ if (fgEqualSsid) { -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_ROAMING; -+ if (fgEqualBssid) { -+ kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED); -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_REASSOCIATION; -+ } -+ } else { -+ DBGLOG(OID, TRACE, "DisBySsid\n"); -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+ } -+ } else -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+#if 0 -+ /* check if any scanned result matchs with the SSID */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ PUINT_8 aucSsid = prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid; -+ UINT_8 ucSsidLength = (UINT_8) prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen; -+ INT_32 i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi; -+ -+ if (EQUAL_SSID(aucSsid, ucSsidLength, pParamConn->pucSsid, pParamConn->u4SsidLen) && -+ i4RSSI >= i4MaxRSSI) { -+ i4Idx = (INT_32) i; -+ i4MaxRSSI = i4RSSI; -+ } -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) { -+ i4Idx = (INT_32) i; -+ break; -+ } -+ } -+#endif -+ /* prepare message to AIS */ -+ if (prConnSettings->eOPMode == NET_TYPE_IBSS || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) { -+ /* IBSS *//* beacon period */ -+ prConnSettings->u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod; -+ prConnSettings->u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow; -+ } -+ -+ if (prAdapter->rWifiVar.fgSupportWZCDisassociation) { -+ if (pParamConn->u4SsidLen == ELEM_MAX_LEN_SSID) { -+ fgIsValidSsid = FALSE; -+ -+ for (i = 0; i < ELEM_MAX_LEN_SSID; i++) { -+ if (pParamConn->pucSsid) { -+ if (!((0 < pParamConn->pucSsid[i]) && (pParamConn->pucSsid[i] <= 0x1F))) { -+ fgIsValidSsid = TRUE; -+ break; -+ } -+ } -+ } -+ } -+ } -+ -+ /* Set Connection Request Issued Flag */ -+ if (fgIsValidSsid) -+ prConnSettings->fgIsConnReqIssued = TRUE; -+ else -+ prConnSettings->fgIsConnReqIssued = FALSE; -+ -+ if (fgEqualSsid || fgEqualBssid) -+ prAisAbortMsg->fgDelayIndication = TRUE; -+ else -+ /* Update the information to CONNECTION_SETTINGS_T */ -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ DBGLOG(OID, INFO, "ssid %s, bssid %pM, conn policy %d, disc reason %d\n", -+ prConnSettings->aucSSID, prConnSettings->aucBSSID, -+ prConnSettings->eConnectionPolicy, prAisAbortMsg->ucReasonOfDisconnect); -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine will initiate the join procedure to attempt -+* to associate with the new SSID. If the previous scanning -+* result is aged, we will scan the channels at first. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetSsid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_PARAM_SSID_T pParamSsid; -+ UINT_32 i; -+ INT_32 i4Idx = -1, i4MaxRSSI = INT_MIN; -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ BOOLEAN fgIsValidSsid = TRUE; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ /* MSDN: -+ * Powering on the radio if the radio is powered off through a setting of OID_802_11_DISASSOCIATE -+ */ -+ if (prAdapter->fgIsRadioOff == TRUE) -+ prAdapter->fgIsRadioOff = FALSE; -+ -+ if (u4SetBufferLen < sizeof(PARAM_SSID_T) || u4SetBufferLen > sizeof(PARAM_SSID_T)) { -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ pParamSsid = (P_PARAM_SSID_T) pvSetBuffer; -+ -+ if (pParamSsid->u4SsidLen > 32) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */ -+ /* re-association check */ -+ if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, -+ pParamSsid->aucSsid, pParamSsid->u4SsidLen)) { -+ kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED); -+ } else { -+ DBGLOG(OID, TRACE, "DisBySsid\n"); -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ } -+ } -+ /* check if any scanned result matchs with the SSID */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ PUINT_8 aucSsid = prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid; -+ UINT_8 ucSsidLength = (UINT_8) prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen; -+ INT_32 i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi; -+ -+ if (EQUAL_SSID(aucSsid, ucSsidLength, pParamSsid->aucSsid, pParamSsid->u4SsidLen) && -+ i4RSSI >= i4MaxRSSI) { -+ i4Idx = (INT_32) i; -+ i4MaxRSSI = i4RSSI; -+ } -+ } -+ -+ /* prepare message to AIS */ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS -+ || prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_DEDICATED_IBSS) { -+ /* IBSS *//* beacon period */ -+ prAdapter->rWifiVar.rConnSettings.u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod; -+ prAdapter->rWifiVar.rConnSettings.u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow; -+ } -+ -+ if (prAdapter->rWifiVar.fgSupportWZCDisassociation) { -+ if (pParamSsid->u4SsidLen == ELEM_MAX_LEN_SSID) { -+ fgIsValidSsid = FALSE; -+ -+ for (i = 0; i < ELEM_MAX_LEN_SSID; i++) { -+ if (!((0 < pParamSsid->aucSsid[i]) && (pParamSsid->aucSsid[i] <= 0x1F))) { -+ fgIsValidSsid = TRUE; -+ break; -+ } -+ } -+ } -+ } -+ -+ /* Set Connection Request Issued Flag */ -+ if (fgIsValidSsid) { -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = TRUE; -+ -+ if (pParamSsid->u4SsidLen) { -+ prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; -+ } else { -+ /* wildcard SSID */ -+ prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_SSID_ANY; -+ } -+ } else { -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; -+ } -+ -+ /* Send AIS Abort Message */ -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+ -+ COPY_SSID(prAdapter->rWifiVar.rConnSettings.aucSSID, -+ prAdapter->rWifiVar.rConnSettings.ucSSIDLen, pParamSsid->aucSsid, (UINT_8) pParamSsid->u4SsidLen); -+ -+ prAdapter->rWifiVar.rConnSettings.u4FreqInKHz = pParamSsid->u4CenterFreq; -+ if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, pParamSsid->aucSsid, pParamSsid->u4SsidLen)) { -+ prAisAbortMsg->fgDelayIndication = TRUE; -+ } else { -+ /* Update the information to CONNECTION_SETTINGS_T */ -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ } -+ DBGLOG(SCN, INFO, "SSID %s\n", prAdapter->rWifiVar.rConnSettings.aucSSID); -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of wlanoidSetSsid() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the currently associated SSID. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQuerySsid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_SSID_T prAssociatedSsid; -+ -+ DEBUGFUNC("wlanoidQuerySsid"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_SSID_T); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prAssociatedSsid = (P_PARAM_SSID_T) pvQueryBuffer; -+ -+ kalMemZero(prAssociatedSsid->aucSsid, sizeof(prAssociatedSsid->aucSsid)); -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ prAssociatedSsid->u4SsidLen = prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen; -+ -+ if (prAssociatedSsid->u4SsidLen) { -+ kalMemCopy(prAssociatedSsid->aucSsid, -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, prAssociatedSsid->u4SsidLen); -+ } -+ } else { -+ prAssociatedSsid->u4SsidLen = 0; -+ -+ DBGLOG(OID, TRACE, "Null SSID\n"); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQuerySsid */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current 802.11 network type. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryInfrastructureMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryInfrastructureMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_OP_MODE_T); -+ -+ if (u4QueryBufferLen < sizeof(ENUM_PARAM_OP_MODE_T)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *(P_ENUM_PARAM_OP_MODE_T) pvQueryBuffer = prAdapter->rWifiVar.rConnSettings.eOPMode; -+ -+ /* -+ ** According to OID_802_11_INFRASTRUCTURE_MODE -+ ** If there is no prior OID_802_11_INFRASTRUCTURE_MODE, -+ ** NDIS_STATUS_ADAPTER_NOT_READY shall be returned. -+ */ -+#if DBG -+ switch (*(P_ENUM_PARAM_OP_MODE_T) pvQueryBuffer) { -+ case NET_TYPE_IBSS: -+ DBGLOG(OID, INFO, "IBSS mode\n"); -+ break; -+ case NET_TYPE_INFRA: -+ DBGLOG(OID, INFO, "Infrastructure mode\n"); -+ break; -+ default: -+ DBGLOG(OID, INFO, "Automatic mode\n"); -+ } -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryInfrastructureMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set mode to infrastructure or -+* IBSS, or automatic switch between the two. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid -+* length of the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetInfrastructureMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ -+ DEBUGFUNC("wlanoidSetInfrastructureMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (u4SetBufferLen < sizeof(ENUM_PARAM_OP_MODE_T)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_OP_MODE_T); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set infrastructure mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ eOpMode = *(P_ENUM_PARAM_OP_MODE_T) pvSetBuffer; -+ /* Verify the new infrastructure mode. */ -+ if (eOpMode >= NET_TYPE_NUM) { -+ DBGLOG(OID, TRACE, "Invalid mode value %d\n", eOpMode); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* check if possible to switch to AdHoc mode */ -+ if (eOpMode == NET_TYPE_IBSS || eOpMode == NET_TYPE_DEDICATED_IBSS) { -+ if (cnmAisIbssIsPermitted(prAdapter) == FALSE) { -+ DBGLOG(OID, TRACE, "Mode value %d unallowed\n", eOpMode); -+ return WLAN_STATUS_FAILURE; -+ } -+ } -+ -+ /* Save the new infrastructure mode setting. */ -+ prAdapter->rWifiVar.rConnSettings.eOPMode = eOpMode; -+ -+ /* Clean up the Tx key flag */ -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE; -+ -+ prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; -+#if CFG_SUPPORT_WAPI -+ prAdapter->prGlueInfo->u2WapiAssocInfoIESz = 0; -+ kalMemZero(&prAdapter->prGlueInfo->aucWapiAssocInfoIEs, 42); -+#endif -+ -+#if CFG_SUPPORT_802_11W -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE; -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled = FALSE; -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+ kalMemZero(&prAdapter->prGlueInfo->aucWSCAssocInfoIE, 200); -+ prAdapter->prGlueInfo->u2WSCAssocInfoIELen = 0; -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_INFRASTRUCTURE, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, nicOidCmdTimeoutCommon, 0, NULL, pvSetBuffer, u4SetBufferLen); -+ -+} /* wlanoidSetInfrastructureMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current 802.11 authentication -+* mode. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryAuthMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryAuthMode"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_AUTH_MODE_T); -+ -+ if (u4QueryBufferLen < sizeof(ENUM_PARAM_AUTH_MODE_T)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer = prAdapter->rWifiVar.rConnSettings.eAuthMode; -+ -+#if DBG -+ switch (*(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer) { -+ case AUTH_MODE_OPEN: -+ DBGLOG(OID, INFO, "Current auth mode: Open\n"); -+ break; -+ -+ case AUTH_MODE_SHARED: -+ DBGLOG(OID, INFO, "Current auth mode: Shared\n"); -+ break; -+ -+ case AUTH_MODE_AUTO_SWITCH: -+ DBGLOG(OID, INFO, "Current auth mode: Auto-switch\n"); -+ break; -+ -+ case AUTH_MODE_WPA: -+ DBGLOG(OID, INFO, "Current auth mode: WPA\n"); -+ break; -+ -+ case AUTH_MODE_WPA_PSK: -+ DBGLOG(OID, INFO, "Current auth mode: WPA PSK\n"); -+ break; -+ -+ case AUTH_MODE_WPA_NONE: -+ DBGLOG(OID, INFO, "Current auth mode: WPA None\n"); -+ break; -+ -+ case AUTH_MODE_WPA2: -+ DBGLOG(OID, INFO, "Current auth mode: WPA2\n"); -+ break; -+ -+ case AUTH_MODE_WPA2_PSK: -+ DBGLOG(OID, INFO, "Current auth mode: WPA2 PSK\n"); -+ break; -+ -+ default: -+ DBGLOG(OID, INFO, "Current auth mode: %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer); -+ break; -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryAuthMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the IEEE 802.11 authentication mode -+* to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_NOT_ACCEPTED -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAuthMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 i, u4AkmSuite; -+ P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry; -+ -+ DEBUGFUNC("wlanoidSetAuthMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ ASSERT(pvSetBuffer); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_AUTH_MODE_T); -+ -+ if (u4SetBufferLen < sizeof(ENUM_PARAM_AUTH_MODE_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ /* RF Test */ -+ /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ -+ /* return WLAN_STATUS_SUCCESS; */ -+ /* } */ -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ /* Check if the new authentication mode is valid. */ -+ if (*(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer >= AUTH_MODE_NUM) { -+ DBGLOG(OID, TRACE, "Invalid auth mode %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ switch (*(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer) { -+ case AUTH_MODE_WPA: -+ case AUTH_MODE_WPA_PSK: -+ case AUTH_MODE_WPA2: -+ case AUTH_MODE_WPA2_PSK: -+ /* infrastructure mode only */ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode != NET_TYPE_INFRA) -+ return WLAN_STATUS_NOT_ACCEPTED; -+ break; -+ -+ case AUTH_MODE_WPA_NONE: -+ /* ad hoc mode only */ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode != NET_TYPE_IBSS) -+ return WLAN_STATUS_NOT_ACCEPTED; -+ break; -+ -+ default: -+ break; -+ } -+ -+ /* Save the new authentication mode. */ -+ prAdapter->rWifiVar.rConnSettings.eAuthMode = *(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer; -+ -+#if DBG -+ switch (prAdapter->rWifiVar.rConnSettings.eAuthMode) { -+ case AUTH_MODE_OPEN: -+ DBGLOG(RSN, TRACE, "New auth mode: open\n"); -+ break; -+ -+ case AUTH_MODE_SHARED: -+ DBGLOG(RSN, TRACE, "New auth mode: shared\n"); -+ break; -+ -+ case AUTH_MODE_AUTO_SWITCH: -+ DBGLOG(RSN, TRACE, "New auth mode: auto-switch\n"); -+ break; -+ -+ case AUTH_MODE_WPA: -+ DBGLOG(RSN, TRACE, "New auth mode: WPA\n"); -+ break; -+ -+ case AUTH_MODE_WPA_PSK: -+ DBGLOG(RSN, TRACE, "New auth mode: WPA PSK\n"); -+ break; -+ -+ case AUTH_MODE_WPA_NONE: -+ DBGLOG(RSN, TRACE, "New auth mode: WPA None\n"); -+ break; -+ -+ case AUTH_MODE_WPA2: -+ DBGLOG(RSN, TRACE, "New auth mode: WPA2\n"); -+ break; -+ -+ case AUTH_MODE_WPA2_PSK: -+ DBGLOG(RSN, TRACE, "New auth mode: WPA2 PSK\n"); -+ break; -+ -+ default: -+ DBGLOG(RSN, TRACE, "New auth mode: unknown (%d)\n", prAdapter->rWifiVar.rConnSettings.eAuthMode); -+ } -+#endif -+ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode >= AUTH_MODE_WPA) { -+ switch (prAdapter->rWifiVar.rConnSettings.eAuthMode) { -+ case AUTH_MODE_WPA: -+ u4AkmSuite = WPA_AKM_SUITE_802_1X; -+ break; -+ -+ case AUTH_MODE_WPA_PSK: -+ u4AkmSuite = WPA_AKM_SUITE_PSK; -+ break; -+ -+ case AUTH_MODE_WPA_NONE: -+ u4AkmSuite = WPA_AKM_SUITE_NONE; -+ break; -+ -+ case AUTH_MODE_WPA2: -+ u4AkmSuite = RSN_AKM_SUITE_802_1X; -+ break; -+ -+ case AUTH_MODE_WPA2_PSK: -+ u4AkmSuite = RSN_AKM_SUITE_PSK; -+ break; -+ -+ default: -+ u4AkmSuite = 0; -+ } -+ } else { -+ u4AkmSuite = 0; -+ } -+ -+ /* Enable the specific AKM suite only. */ -+ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { -+ prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i]; -+ -+ if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite) -+ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE; -+ else -+ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = FALSE; -+#if CFG_SUPPORT_802_11W -+ if (kalGetMfpSetting(prAdapter->prGlueInfo) != RSN_AUTH_MFP_DISABLED) { -+ if ((u4AkmSuite == RSN_AKM_SUITE_PSK) && -+ prEntry->dot11RSNAConfigAuthenticationSuite == RSN_AKM_SUITE_PSK_SHA256) { -+ DBGLOG(RSN, TRACE, "Enable RSN_AKM_SUITE_PSK_SHA256 AKM support\n"); -+ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE; -+ -+ } -+ if ((u4AkmSuite == RSN_AKM_SUITE_802_1X) && -+ prEntry->dot11RSNAConfigAuthenticationSuite == RSN_AKM_SUITE_802_1X_SHA256) { -+ DBGLOG(RSN, TRACE, "Enable RSN_AKM_SUITE_802_1X_SHA256 AKM support\n"); -+ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE; -+ } -+ } -+#endif -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidSetAuthMode */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current 802.11 privacy filter -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryPrivacyFilter(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryPrivacyFilter"); -+ -+ ASSERT(prAdapter); -+ -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_PRIVACY_FILTER_T); -+ -+ if (u4QueryBufferLen < sizeof(ENUM_PARAM_PRIVACY_FILTER_T)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ *(P_ENUM_PARAM_PRIVACY_FILTER_T) pvQueryBuffer = prAdapter->rWlanInfo.ePrivacyFilter; -+ -+#if DBG -+ switch (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvQueryBuffer) { -+ case PRIVACY_FILTER_ACCEPT_ALL: -+ DBGLOG(OID, INFO, "Current privacy mode: open mode\n"); -+ break; -+ -+ case PRIVACY_FILTER_8021xWEP: -+ DBGLOG(OID, INFO, "Current privacy mode: filtering mode\n"); -+ break; -+ -+ default: -+ DBGLOG(OID, INFO, "Current auth mode: %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer); -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryPrivacyFilter */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the IEEE 802.11 privacy filter -+* to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_NOT_ACCEPTED -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetPrivacyFilter(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ DEBUGFUNC("wlanoidSetPrivacyFilter"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ ASSERT(pvSetBuffer); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_PRIVACY_FILTER_T); -+ -+ if (u4SetBufferLen < sizeof(ENUM_PARAM_PRIVACY_FILTER_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ /* Check if the new authentication mode is valid. */ -+ if (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer >= PRIVACY_FILTER_NUM) { -+ DBGLOG(OID, TRACE, "Invalid privacy filter %d\n", *(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ switch (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer) { -+ default: -+ break; -+ } -+ -+ /* Save the new authentication mode. */ -+ prAdapter->rWlanInfo.ePrivacyFilter = *(ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidSetPrivacyFilter */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to reload the available default settings for -+* the specified type field. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetReloadDefaults(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ ENUM_PARAM_NETWORK_TYPE_T eNetworkType; -+ UINT_32 u4Len; -+ UINT_8 ucCmdSeqNum; -+ -+ DEBUGFUNC("wlanoidSetReloadDefaults"); -+ -+ ASSERT(prAdapter); -+ -+ ASSERT(pu4SetInfoLen); -+ *pu4SetInfoLen = sizeof(PARAM_RELOAD_DEFAULTS); -+ -+ /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ -+ /* return WLAN_STATUS_SUCCESS; */ -+ /* } */ -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set Reload default! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pvSetBuffer); -+ /* Verify the available reload options and reload the settings. */ -+ switch (*(P_PARAM_RELOAD_DEFAULTS) pvSetBuffer) { -+ case ENUM_RELOAD_WEP_KEYS: -+ /* Reload available default WEP keys from the permanent -+ storage. */ -+ prAdapter->rWifiVar.rConnSettings.eAuthMode = AUTH_MODE_OPEN; -+ /* ENUM_ENCRYPTION_DISABLED; */ -+ prAdapter->rWifiVar.rConnSettings.eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT; -+ { -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_CMD_802_11_KEY prCmdKey; -+ UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY))); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_802_11_KEY cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T); -+ prCmdInfo->pvInformationBuffer = pvSetBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); -+ -+ kalMemZero((PUINT_8) prCmdKey, sizeof(CMD_802_11_KEY)); -+ -+ prCmdKey->ucAddRemove = 0; /* Remove */ -+ prCmdKey->ucKeyId = 0; /* (UINT_8)(prRemovedKey->u4KeyIndex & 0x000000ff); */ -+ kalMemCopy(prCmdKey->aucPeerAddr, aucBCAddr, MAC_ADDR_LEN); -+ -+ ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM); -+ -+ prCmdKey->ucKeyType = 0; -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+ } -+ -+ break; -+ -+ default: -+ DBGLOG(OID, TRACE, "Invalid reload option %d\n", *(P_PARAM_RELOAD_DEFAULTS) pvSetBuffer); -+ rStatus = WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* OID_802_11_RELOAD_DEFAULTS requiest to reset to auto mode */ -+ eNetworkType = PARAM_NETWORK_TYPE_AUTOMODE; -+ wlanoidSetNetworkTypeInUse(prAdapter, &eNetworkType, sizeof(eNetworkType), &u4Len); -+ -+ return rStatus; -+} /* wlanoidSetReloadDefaults */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a WEP key to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+#ifdef LINUX -+UINT_8 keyBuffer[sizeof(PARAM_KEY_T) + 16 /* LEGACY_KEY_MAX_LEN */]; -+UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+#endif -+WLAN_STATUS -+wlanoidSetAddWep(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+#ifndef LINUX -+ UINT_8 keyBuffer[sizeof(PARAM_KEY_T) + 16 /* LEGACY_KEY_MAX_LEN */]; -+ UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+#endif -+ P_PARAM_WEP_T prNewWepKey; -+ P_PARAM_KEY_T prParamKey = (P_PARAM_KEY_T) keyBuffer; -+ UINT_32 u4KeyId, u4SetLen; -+ -+ DEBUGFUNC("wlanoidSetAddWep"); -+ -+ ASSERT(prAdapter); -+ -+ *pu4SetInfoLen = OFFSET_OF(PARAM_WEP_T, aucKeyMaterial); -+ -+ if (u4SetBufferLen < OFFSET_OF(PARAM_WEP_T, aucKeyMaterial)) { -+ ASSERT(pu4SetInfoLen); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set add WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ prNewWepKey = (P_PARAM_WEP_T) pvSetBuffer; -+ -+ /* Verify the total buffer for minimum length. */ -+ if (u4SetBufferLen < OFFSET_OF(PARAM_WEP_T, aucKeyMaterial) + prNewWepKey->u4KeyLength) { -+ DBGLOG(OID, WARN, "Invalid total buffer length (%d) than minimum length (%d)\n", -+ (UINT_8) u4SetBufferLen, (UINT_8) OFFSET_OF(PARAM_WEP_T, aucKeyMaterial)); -+ -+ *pu4SetInfoLen = OFFSET_OF(PARAM_WEP_T, aucKeyMaterial); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Verify the key structure length. */ -+ if (prNewWepKey->u4Length > u4SetBufferLen) { -+ DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", -+ (UINT_8) prNewWepKey->u4Length, (UINT_8) u4SetBufferLen); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Verify the key material length for maximum key material length:16 */ -+ if (prNewWepKey->u4KeyLength > 16 /* LEGACY_KEY_MAX_LEN */) { -+ DBGLOG(OID, WARN, "Invalid key material length (%d) greater than maximum key material length (16)\n", -+ (UINT_8) prNewWepKey->u4KeyLength); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ u4KeyId = prNewWepKey->u4KeyIndex & BITS(0, 29) /* WEP_KEY_ID_FIELD */; -+ -+ /* Verify whether key index is valid or not, current version -+ driver support only 4 global WEP keys setting by this OID */ -+ if (u4KeyId > MAX_KEY_NUM - 1) { -+ DBGLOG(OID, ERROR, "Error, invalid WEP key ID: %d\n", (UINT_8) u4KeyId); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ prParamKey->u4KeyIndex = u4KeyId; -+ -+ /* Transmit key */ -+ if (prNewWepKey->u4KeyIndex & IS_TRANSMIT_KEY) -+ prParamKey->u4KeyIndex |= IS_TRANSMIT_KEY; -+ -+ /* Per client key */ -+ if (prNewWepKey->u4KeyIndex & IS_UNICAST_KEY) -+ prParamKey->u4KeyIndex |= IS_UNICAST_KEY; -+ -+ prParamKey->u4KeyLength = prNewWepKey->u4KeyLength; -+ -+ kalMemCopy(prParamKey->arBSSID, aucBCAddr, MAC_ADDR_LEN); -+ -+ kalMemCopy(prParamKey->aucKeyMaterial, prNewWepKey->aucKeyMaterial, prNewWepKey->u4KeyLength); -+ -+ prParamKey->u4Length = OFFSET_OF(PARAM_KEY_T, aucKeyMaterial) + prNewWepKey->u4KeyLength; -+ -+ wlanoidSetAddKey(prAdapter, (PVOID) prParamKey, prParamKey->u4Length, &u4SetLen); -+ -+ return WLAN_STATUS_PENDING; -+} /* wlanoidSetAddWep */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request the driver to remove the WEP key -+* at the specified key index. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRemoveWep(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_32 u4KeyId, u4SetLen; -+ PARAM_REMOVE_KEY_T rRemoveKey; -+ UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+ -+ DEBUGFUNC("wlanoidSetRemoveWep"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_KEY_INDEX); -+ -+ if (u4SetBufferLen < sizeof(PARAM_KEY_INDEX)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ u4KeyId = *(PUINT_32) pvSetBuffer; -+ -+ /* Dump PARAM_WEP content. */ -+ DBGLOG(OID, INFO, "Set: Dump PARAM_KEY_INDEX content\n"); -+ DBGLOG(OID, INFO, "Index : 0x%08x\n", u4KeyId); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set remove WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ if (u4KeyId & IS_TRANSMIT_KEY) { -+ /* Bit 31 should not be set */ -+ DBGLOG(OID, ERROR, "Invalid WEP key index: 0x%08x\n", u4KeyId); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ u4KeyId &= BITS(0, 7); -+ -+ /* Verify whether key index is valid or not. Current version -+ driver support only 4 global WEP keys. */ -+ if (u4KeyId > MAX_KEY_NUM - 1) { -+ DBGLOG(OID, ERROR, "invalid WEP key ID %u\n", u4KeyId); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T); -+ rRemoveKey.u4KeyIndex = *(PUINT_32) pvSetBuffer; -+ -+ kalMemCopy(rRemoveKey.arBSSID, aucBCAddr, MAC_ADDR_LEN); -+ -+ wlanoidSetRemoveKey(prAdapter, (PVOID)&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T), &u4SetLen); -+ -+ return WLAN_STATUS_PENDING; -+} /* wlanoidSetRemoveWep */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a key to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_KEY_T, which is set by NDIS, is unpacked. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+_wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, IN BOOLEAN fgIsOid, IN UINT_8 ucAlgorithmId, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_PARAM_KEY_T prNewKey; -+ P_CMD_802_11_KEY prCmdKey; -+ UINT_8 ucCmdSeqNum; -+ -+#if 0 -+ DEBUGFUNC("wlanoidSetAddKey"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+#endif -+ -+ prNewKey = (P_PARAM_KEY_T) pvSetBuffer; -+ -+#if 0 -+ /* Verify the key structure length. */ -+ if (prNewKey->u4Length > u4SetBufferLen) { -+ DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", -+ (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ /* Verify the key material length for key material buffer */ -+ if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) { -+ DBGLOG(OID, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength); -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Exception check */ -+ if (prNewKey->u4KeyIndex & 0x0fffff00) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ /* Exception check, pairwise key must with transmit bit enabled */ -+ if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ if (!(prNewKey->u4KeyLength == WEP_40_LEN || prNewKey->u4KeyLength == WEP_104_LEN || -+ prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN)) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Exception check, pairwise key must with transmit bit enabled */ -+ if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { -+ if (((prNewKey->u4KeyIndex & 0xff) != 0) || -+ ((prNewKey->arBSSID[0] == 0xff) && (prNewKey->arBSSID[1] == 0xff) && (prNewKey->arBSSID[2] == 0xff) -+ && (prNewKey->arBSSID[3] == 0xff) && (prNewKey->arBSSID[4] == 0xff) -+ && (prNewKey->arBSSID[5] == 0xff))) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+#endif -+ -+ /* Dump PARAM_KEY content. */ -+ DBGLOG(OID, TRACE, "Set: PARAM_KEY Length: 0x%08x, Key Index: 0x%08x, Key Length: 0x%08x\n", -+ prNewKey->u4Length, prNewKey->u4KeyIndex, prNewKey->u4KeyLength); -+ DBGLOG(OID, TRACE, "BSSID:\n"); -+ DBGLOG_MEM8(OID, TRACE, prNewKey->arBSSID, sizeof(PARAM_MAC_ADDRESS)); -+ DBGLOG(OID, TRACE, "Key RSC:\n"); -+ DBGLOG_MEM8(OID, TRACE, &prNewKey->rKeyRSC, sizeof(PARAM_KEY_RSC)); -+ DBGLOG(OID, TRACE, "Key Material:\n"); -+ DBGLOG_MEM8(OID, TRACE, prNewKey->aucKeyMaterial, prNewKey->u4KeyLength); -+ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) { -+ /* Todo:: Store the legacy wep key for OID_802_11_RELOAD_DEFAULTS */ -+ /* Todo:: Nothing */ -+ } -+ -+ if (prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = TRUE; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY))); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(OID, TRACE, "ucCmdSeqNum = %d\n", ucCmdSeqNum); -+ -+ /* compose CMD_802_11_KEY cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = fgIsOid; -+ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetBufferLen; -+ prCmdInfo->pvInformationBuffer = pvSetBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); -+ -+ kalMemZero(prCmdKey, sizeof(CMD_802_11_KEY)); -+ -+ prCmdKey->ucAddRemove = 1; /* Add */ -+ -+ prCmdKey->ucTxKey = ((prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) == IS_TRANSMIT_KEY) ? 1 : 0; -+ prCmdKey->ucKeyType = ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) ? 1 : 0; -+ prCmdKey->ucIsAuthenticator = ((prNewKey->u4KeyIndex & IS_AUTHENTICATOR) == IS_AUTHENTICATOR) ? 1 : 0; -+ -+ kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prNewKey->arBSSID, MAC_ADDR_LEN); -+ -+ prCmdKey->ucNetType = 0; /* AIS */ -+ -+ prCmdKey->ucKeyId = (UINT_8) (prNewKey->u4KeyIndex & 0xff); -+ -+ /* Note: adjust the key length for WPA-None */ -+ prCmdKey->ucKeyLen = (UINT_8) prNewKey->u4KeyLength; -+ -+ kalMemCopy(prCmdKey->aucKeyMaterial, (PUINT_8) prNewKey->aucKeyMaterial, prCmdKey->ucKeyLen); -+ -+ if (prNewKey->u4KeyLength == 5) { -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP40; -+ } else if (prNewKey->u4KeyLength == 13) { -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP104; -+ } else if (prNewKey->u4KeyLength == 16) { -+ if ((ucAlgorithmId != CIPHER_SUITE_CCMP) && -+ (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA)) -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP128; -+ else { -+#if CFG_SUPPORT_802_11W -+ if (prCmdKey->ucKeyId >= 4) { -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_BIP; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ prAisSpecBssInfo->fgBipKeyInstalled = TRUE; -+ } else -+#endif -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP; -+ if (rsnCheckPmkidCandicate(prAdapter)) { -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ DBGLOG(RSN, TRACE, -+ "Add key: Prepare a timer to indicate candidate PMKID Candidate\n"); -+ cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer); -+ cnmTimerStartTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer, -+ SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC)); -+ } -+ } -+ } else if (prNewKey->u4KeyLength == 32) { -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) { -+ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION2_ENABLED) -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP; -+ else if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) { -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP; -+ prCmdKey->ucKeyLen = CCMP_KEY_LEN; -+ } -+ } else -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP; -+ } -+ -+ DBGLOG(RSN, TRACE, "prCmdKey->ucAlgorithmId=%d, key len=%d\n", -+ prCmdKey->ucAlgorithmId, (UINT32) prNewKey->u4KeyLength); -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+} -+ -+WLAN_STATUS -+wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_KEY_T prNewKey; -+ -+ DEBUGFUNC("wlanoidSetAddKey"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ prNewKey = (P_PARAM_KEY_T) pvSetBuffer; -+ -+ /* Verify the key structure length. */ -+ if (prNewKey->u4Length > u4SetBufferLen) { -+ DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", -+ (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ /* Verify the key material length for key material buffer */ -+ if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) { -+ DBGLOG(OID, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength); -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Exception check */ -+ if (prNewKey->u4KeyIndex & 0x0fffff00) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ /* Exception check, pairwise key must with transmit bit enabled */ -+ if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { -+ if (((prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN) && -+ (prNewKey->u4KeyIndex & 0xff) != 0) || -+ EQUAL_MAC_ADDR(prNewKey->arBSSID, "\xff\xff\xff\xff\xff\xff")) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ } else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ if (!(prNewKey->u4KeyLength == WEP_40_LEN || prNewKey->u4KeyLength == WEP_104_LEN || -+ prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN)) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ /* -+ supplicant will set key before updating station & enabling the link so we need to -+ backup the key information and set key when link is enabled -+ */ -+ if (TdlsexKeyHandle(prAdapter, prNewKey) == TDLS_STATUS_SUCCESS) -+ return WLAN_STATUS_SUCCESS; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ return _wlanoidSetAddKey(prAdapter, pvSetBuffer, u4SetBufferLen, TRUE, CIPHER_SUITE_NONE, pu4SetInfoLen); -+} /* wlanoidSetAddKey */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request the driver to remove the key at -+* the specified key index. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRemoveKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_PARAM_REMOVE_KEY_T prRemovedKey; -+ P_CMD_802_11_KEY prCmdKey; -+ UINT_8 ucCmdSeqNum; -+ -+ DEBUGFUNC("wlanoidSetRemoveKey"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_REMOVE_KEY_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set remove key! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pvSetBuffer); -+ prRemovedKey = (P_PARAM_REMOVE_KEY_T) pvSetBuffer; -+ -+ /* Dump PARAM_REMOVE_KEY content. */ -+ DBGLOG(OID, TRACE, "Set: Dump PARAM_REMOVE_KEY content\n"); -+ DBGLOG(OID, TRACE, "Length : 0x%08x\n", prRemovedKey->u4Length); -+ DBGLOG(OID, TRACE, "Key Index : 0x%08x\n", prRemovedKey->u4KeyIndex); -+ DBGLOG(OID, TRACE, "BSSID:\n"); -+ DBGLOG_MEM8(OID, TRACE, prRemovedKey->arBSSID, MAC_ADDR_LEN); -+ -+ /* Check bit 31: this bit should always 0 */ -+ if (prRemovedKey->u4KeyIndex & IS_TRANSMIT_KEY) { -+ /* Bit 31 should not be set */ -+ DBGLOG(OID, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Check bits 8 ~ 29 should always be 0 */ -+ if (prRemovedKey->u4KeyIndex & BITS(8, 29)) { -+ /* Bit 31 should not be set */ -+ DBGLOG(OID, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Clean up the Tx key flag */ -+ if (prRemovedKey->u4KeyIndex & IS_UNICAST_KEY) -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY))); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_802_11_KEY cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T); -+ prCmdInfo->pvInformationBuffer = pvSetBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); -+ -+ kalMemZero((PUINT_8) prCmdKey, sizeof(CMD_802_11_KEY)); -+ -+ prCmdKey->ucAddRemove = 0; /* Remove */ -+ prCmdKey->ucKeyId = (UINT_8) (prRemovedKey->u4KeyIndex & 0x000000ff); -+ kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prRemovedKey->arBSSID, MAC_ADDR_LEN); -+ -+#if CFG_SUPPORT_802_11W -+ ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM + 2); -+#else -+ /* ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM); */ -+#endif -+ -+ if (prRemovedKey->u4KeyIndex & IS_UNICAST_KEY) -+ prCmdKey->ucKeyType = 1; -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+} /* wlanoidSetRemoveKey */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current encryption status. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryEncryptionStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ BOOLEAN fgTransmitKeyAvailable = TRUE; -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus = 0; -+ -+ DEBUGFUNC("wlanoidQueryEncryptionStatus"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T); -+ -+ fgTransmitKeyAvailable = prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist; -+ -+ switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) { -+ case ENUM_ENCRYPTION3_ENABLED: -+ if (fgTransmitKeyAvailable) -+ eEncStatus = ENUM_ENCRYPTION3_ENABLED; -+ else -+ eEncStatus = ENUM_ENCRYPTION3_KEY_ABSENT; -+ break; -+ -+ case ENUM_ENCRYPTION2_ENABLED: -+ if (fgTransmitKeyAvailable) { -+ eEncStatus = ENUM_ENCRYPTION2_ENABLED; -+ break; -+ } -+ eEncStatus = ENUM_ENCRYPTION2_KEY_ABSENT; -+ break; -+ -+ case ENUM_ENCRYPTION1_ENABLED: -+ if (fgTransmitKeyAvailable) -+ eEncStatus = ENUM_ENCRYPTION1_ENABLED; -+ else -+ eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT; -+ break; -+ -+ case ENUM_ENCRYPTION_DISABLED: -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ break; -+ -+ default: -+ DBGLOG(OID, ERROR, "Unknown Encryption Status Setting:%d\n", -+ prAdapter->rWifiVar.rConnSettings.eEncStatus); -+ } -+ -+#if DBG -+ DBGLOG(OID, INFO, -+ "Encryption status: %d Return:%d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus, eEncStatus); -+#endif -+ -+ *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvQueryBuffer = eEncStatus; -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryEncryptionStatus */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the encryption status to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_NOT_SUPPORTED -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetEncryptionStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEewEncrypt; -+ -+ DEBUGFUNC("wlanoidSetEncryptionStatus"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T); -+ -+ /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ -+ /* return WLAN_STATUS_SUCCESS; */ -+ /* } */ -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set encryption status! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ eEewEncrypt = *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer; -+ DBGLOG(OID, TRACE, "ENCRYPTION_STATUS %d\n", eEewEncrypt); -+ -+ switch (eEewEncrypt) { -+ case ENUM_ENCRYPTION_DISABLED: /* Disable WEP, TKIP, AES */ -+ DBGLOG(RSN, TRACE, "Disable Encryption\n"); -+ secSetCipherSuite(prAdapter, CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128); -+ break; -+ -+ case ENUM_ENCRYPTION1_ENABLED: /* Enable WEP. Disable TKIP, AES */ -+ DBGLOG(RSN, TRACE, "Enable Encryption1\n"); -+ secSetCipherSuite(prAdapter, CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128); -+ break; -+ -+ case ENUM_ENCRYPTION2_ENABLED: /* Enable WEP, TKIP. Disable AES */ -+ secSetCipherSuite(prAdapter, -+ CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128 | CIPHER_FLAG_TKIP); -+ DBGLOG(RSN, TRACE, "Enable Encryption2\n"); -+ break; -+ -+ case ENUM_ENCRYPTION3_ENABLED: /* Enable WEP, TKIP, AES */ -+ secSetCipherSuite(prAdapter, -+ CIPHER_FLAG_WEP40 | -+ CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128 | CIPHER_FLAG_TKIP | CIPHER_FLAG_CCMP); -+ DBGLOG(RSN, TRACE, "Enable Encryption3\n"); -+ break; -+ -+ default: -+ DBGLOG(RSN, WARN, "Unacceptible encryption status: %d\n", -+ *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer); -+ -+ rStatus = WLAN_STATUS_NOT_SUPPORTED; -+ } -+ -+ if (rStatus == WLAN_STATUS_SUCCESS) { -+ /* Save the new encryption status. */ -+ prAdapter->rWifiVar.rConnSettings.eEncStatus = *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer; -+ -+ DBGLOG(RSN, TRACE, "wlanoidSetEncryptionStatus to %d\n", -+ prAdapter->rWifiVar.rConnSettings.eEncStatus); -+ } -+ -+ return rStatus; -+} /* wlanoidSetEncryptionStatus */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to test the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetTest(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_802_11_TEST_T prTest; -+ PVOID pvTestData; -+ PVOID pvStatusBuffer; -+ UINT_32 u4StatusBufferSize; -+ -+ DEBUGFUNC("wlanoidSetTest"); -+ -+ ASSERT(prAdapter); -+ -+ ASSERT(pu4SetInfoLen); -+ ASSERT(pvSetBuffer); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ prTest = (P_PARAM_802_11_TEST_T) pvSetBuffer; -+ -+ DBGLOG(OID, TRACE, "Test - Type %u\n", prTest->u4Type); -+ -+ switch (prTest->u4Type) { -+ case 1: /* Type 1: generate an authentication event */ -+ pvTestData = (PVOID) &prTest->u.AuthenticationEvent; -+ pvStatusBuffer = (PVOID) prAdapter->aucIndicationEventBuffer; -+ u4StatusBufferSize = prTest->u4Length - 8; -+ if (u4StatusBufferSize > sizeof(PARAM_AUTH_EVENT_T)) { -+ DBGLOG(OID, TRACE, "prTest->u4Length error %u\n", u4StatusBufferSize); -+ ASSERT(FALSE); -+ } -+ break; -+ -+ case 2: /* Type 2: generate an RSSI status indication */ -+ pvTestData = (PVOID) &prTest->u.RssiTrigger; -+ pvStatusBuffer = (PVOID) &prAdapter->rWlanInfo.rCurrBssId.rRssi; -+ u4StatusBufferSize = sizeof(PARAM_RSSI); -+ break; -+ -+ default: -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ ASSERT(u4StatusBufferSize <= 180); -+ if (u4StatusBufferSize > 180) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ /* Get the contents of the StatusBuffer from the test structure. */ -+ kalMemCopy(pvStatusBuffer, pvTestData, u4StatusBufferSize); -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, pvStatusBuffer, u4StatusBufferSize); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidSetTest */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the driver's WPA2 status. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryCapability(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CAPABILITY_T prCap; -+ P_PARAM_AUTH_ENCRYPTION_T prAuthenticationEncryptionSupported; -+ -+ DEBUGFUNC("wlanoidQueryCapability"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = 4 * sizeof(UINT_32) + 14 * sizeof(PARAM_AUTH_ENCRYPTION_T); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prCap = (P_PARAM_CAPABILITY_T) pvQueryBuffer; -+ -+ prCap->u4Length = *pu4QueryInfoLen; -+ prCap->u4Version = 2; /* WPA2 */ -+ prCap->u4NoOfPMKIDs = CFG_MAX_PMKID_CACHE; -+ prCap->u4NoOfAuthEncryptPairsSupported = 14; -+ -+ prAuthenticationEncryptionSupported = &prCap->arAuthenticationEncryptionSupported[0]; -+ -+ /* fill 14 entries of supported settings */ -+ prAuthenticationEncryptionSupported[0].eAuthModeSupported = AUTH_MODE_OPEN; -+ -+ prAuthenticationEncryptionSupported[0].eEncryptStatusSupported = ENUM_ENCRYPTION_DISABLED; -+ -+ prAuthenticationEncryptionSupported[1].eAuthModeSupported = AUTH_MODE_OPEN; -+ prAuthenticationEncryptionSupported[1].eEncryptStatusSupported = ENUM_ENCRYPTION1_ENABLED; -+ -+ prAuthenticationEncryptionSupported[2].eAuthModeSupported = AUTH_MODE_SHARED; -+ prAuthenticationEncryptionSupported[2].eEncryptStatusSupported = ENUM_ENCRYPTION_DISABLED; -+ -+ prAuthenticationEncryptionSupported[3].eAuthModeSupported = AUTH_MODE_SHARED; -+ prAuthenticationEncryptionSupported[3].eEncryptStatusSupported = ENUM_ENCRYPTION1_ENABLED; -+ -+ prAuthenticationEncryptionSupported[4].eAuthModeSupported = AUTH_MODE_WPA; -+ prAuthenticationEncryptionSupported[4].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; -+ -+ prAuthenticationEncryptionSupported[5].eAuthModeSupported = AUTH_MODE_WPA; -+ prAuthenticationEncryptionSupported[5].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; -+ -+ prAuthenticationEncryptionSupported[6].eAuthModeSupported = AUTH_MODE_WPA_PSK; -+ prAuthenticationEncryptionSupported[6].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; -+ -+ prAuthenticationEncryptionSupported[7].eAuthModeSupported = AUTH_MODE_WPA_PSK; -+ prAuthenticationEncryptionSupported[7].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; -+ -+ prAuthenticationEncryptionSupported[8].eAuthModeSupported = AUTH_MODE_WPA_NONE; -+ prAuthenticationEncryptionSupported[8].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; -+ -+ prAuthenticationEncryptionSupported[9].eAuthModeSupported = AUTH_MODE_WPA_NONE; -+ prAuthenticationEncryptionSupported[9].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; -+ -+ prAuthenticationEncryptionSupported[10].eAuthModeSupported = AUTH_MODE_WPA2; -+ prAuthenticationEncryptionSupported[10].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; -+ -+ prAuthenticationEncryptionSupported[11].eAuthModeSupported = AUTH_MODE_WPA2; -+ prAuthenticationEncryptionSupported[11].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; -+ -+ prAuthenticationEncryptionSupported[12].eAuthModeSupported = AUTH_MODE_WPA2_PSK; -+ prAuthenticationEncryptionSupported[12].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; -+ -+ prAuthenticationEncryptionSupported[13].eAuthModeSupported = AUTH_MODE_WPA2_PSK; -+ prAuthenticationEncryptionSupported[13].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidQueryCapability */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the PMKID in the PMK cache. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryPmkid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ UINT_32 i; -+ P_PARAM_PMKID_T prPmkid; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("wlanoidQueryPmkid"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ *pu4QueryInfoLen = OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo) + -+ prAisSpecBssInfo->u4PmkidCacheCount * sizeof(PARAM_BSSID_INFO_T); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prPmkid = (P_PARAM_PMKID_T) pvQueryBuffer; -+ -+ prPmkid->u4Length = *pu4QueryInfoLen; -+ prPmkid->u4BSSIDInfoCount = prAisSpecBssInfo->u4PmkidCacheCount; -+ -+ for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) { -+ kalMemCopy(prPmkid->arBSSIDInfo[i].arBSSID, -+ prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, sizeof(PARAM_MAC_ADDRESS)); -+ kalMemCopy(prPmkid->arBSSIDInfo[i].arPMKID, -+ prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arPMKID, sizeof(PARAM_PMKID_VALUE)); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidQueryPmkid */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the PMKID to the PMK cache in the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetPmkid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_32 i, j; -+ P_PARAM_PMKID_T prPmkid; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("wlanoidSetPmkid"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ /* It's possibble BSSIDInfoCount is zero, because OS wishes to clean PMKID */ -+ if (u4SetBufferLen < OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ ASSERT(pvSetBuffer); -+ prPmkid = (P_PARAM_PMKID_T) pvSetBuffer; -+ -+ if (u4SetBufferLen < -+ ((prPmkid->u4BSSIDInfoCount * sizeof(PARAM_BSSID_INFO_T)) + OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo))) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ if (prPmkid->u4BSSIDInfoCount > CFG_MAX_PMKID_CACHE) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ DBGLOG(OID, TRACE, "Count %u\n", prPmkid->u4BSSIDInfoCount); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ /* This OID replace everything in the PMKID cache. */ -+ if (prPmkid->u4BSSIDInfoCount == 0) { -+ prAisSpecBssInfo->u4PmkidCacheCount = 0; -+ kalMemZero(prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE); -+ } -+ if ((prAisSpecBssInfo->u4PmkidCacheCount + prPmkid->u4BSSIDInfoCount > CFG_MAX_PMKID_CACHE)) { -+ prAisSpecBssInfo->u4PmkidCacheCount = 0; -+ kalMemZero(prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE); -+ } -+ -+ /* -+ The driver can only clear its PMKID cache whenever it make a media disconnect -+ indication. Otherwise, it must change the PMKID cache only when set through this OID. -+ */ -+#if CFG_RSN_MIGRATION -+ for (i = 0; i < prPmkid->u4BSSIDInfoCount; i++) { -+ /* Search for desired BSSID. If desired BSSID is found, -+ then set the PMKID */ -+ if (!rsnSearchPmkidEntry(prAdapter, (PUINT_8) prPmkid->arBSSIDInfo[i].arBSSID, &j)) { -+ /* No entry found for the specified BSSID, so add one entry */ -+ if (prAisSpecBssInfo->u4PmkidCacheCount < CFG_MAX_PMKID_CACHE - 1) { -+ j = prAisSpecBssInfo->u4PmkidCacheCount; -+ kalMemCopy(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID, -+ prPmkid->arBSSIDInfo[i].arBSSID, sizeof(PARAM_MAC_ADDRESS)); -+ prAisSpecBssInfo->u4PmkidCacheCount++; -+ } else { -+ j = CFG_MAX_PMKID_CACHE; -+ } -+ } -+ -+ if (j < CFG_MAX_PMKID_CACHE) { -+ kalMemCopy(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arPMKID, -+ prPmkid->arBSSIDInfo[i].arPMKID, sizeof(PARAM_PMKID_VALUE)); -+ DBGLOG(RSN, TRACE, "Add BSSID %pM idx=%d PMKID value %pM\n", -+ (prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID), (UINT_32) j, -+ (prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arPMKID)); -+ prAisSpecBssInfo->arPmkidCache[j].fgPmkidExist = TRUE; -+ } -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidSetPmkid */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the set of supported data rates that -+* the radio is capable of running -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query -+* \param[in] u4QueryBufferLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number -+* of bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQuerySupportedRates(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ PARAM_RATES eRate = { -+ /* BSSBasicRateSet for 802.11n Non-HT rates */ -+ 0x8C, /* 6M */ -+ 0x92, /* 9M */ -+ 0x98, /* 12M */ -+ 0xA4, /* 18M */ -+ 0xB0, /* 24M */ -+ 0xC8, /* 36M */ -+ 0xE0, /* 48M */ -+ 0xEC /* 54M */ -+ }; -+ -+ DEBUGFUNC("wlanoidQuerySupportedRates"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_RATES_EX); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ kalMemCopy(pvQueryBuffer, (PVOID) &eRate, sizeof(PARAM_RATES)); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidQuerySupportedRates() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current desired rates. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryDesiredRates(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryDesiredRates"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_RATES_EX); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ kalMemCopy(pvQueryBuffer, (PVOID) &(prAdapter->rWlanInfo.eDesiredRates), sizeof(PARAM_RATES)); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of wlanoidQueryDesiredRates() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to Set the desired rates. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetDesiredRates(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_32 i; -+ -+ DEBUGFUNC("wlanoidSetDesiredRates"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen < sizeof(PARAM_RATES)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *pu4SetInfoLen = sizeof(PARAM_RATES); -+ -+ if (u4SetBufferLen < sizeof(PARAM_RATES)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ kalMemCopy((PVOID) &(prAdapter->rWlanInfo.eDesiredRates), pvSetBuffer, sizeof(PARAM_RATES)); -+ -+ prAdapter->rWlanInfo.eLinkAttr.ucDesiredRateLen = PARAM_MAX_LEN_RATES; -+ for (i = 0; i < PARAM_MAX_LEN_RATES; i++) -+ prAdapter->rWlanInfo.eLinkAttr.u2DesiredRate[i] = (UINT_16) (prAdapter->rWlanInfo.eDesiredRates[i]); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_LINK_ATTRIB, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_LINK_ATTRIB), -+ (PUINT_8) &(prAdapter->rWlanInfo.eLinkAttr), pvSetBuffer, u4SetBufferLen); -+ -+} /* end of wlanoidSetDesiredRates() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the maximum frame size in bytes, -+* not including the header. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMaxFrameSize(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryMaxFrameSize"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *(PUINT_32) pvQueryBuffer = ETHERNET_MAX_PKT_SZ - ETHERNET_HEADER_SZ; -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryMaxFrameSize */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the maximum total packet length -+* in bytes. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMaxTotalSize(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryMaxTotalSize"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *(PUINT_32) pvQueryBuffer = ETHERNET_MAX_PKT_SZ; -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryMaxTotalSize */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the vendor ID of the NIC. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryVendorId(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+#if DBG -+ PUINT_8 cp; -+#endif -+ DEBUGFUNC("wlanoidQueryVendorId"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ kalMemCopy(pvQueryBuffer, prAdapter->aucMacAddress, 3); -+ *((PUINT_8) pvQueryBuffer + 3) = 1; -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+#if DBG -+ cp = (PUINT_8) pvQueryBuffer; -+ DBGLOG(OID, LOUD, "Vendor ID=%02x-%02x-%02x-%02x\n", cp[0], cp[1], cp[2], cp[3]); -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryVendorId */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current RSSI value. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call failed due to invalid length of -+* the query buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRssi(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRssi"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_RSSI); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) { -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (prAdapter->fgIsLinkQualityValid == TRUE && -+ (kalGetTimeTick() - prAdapter->rLinkQualityUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) { -+ PARAM_RSSI rRssi; -+ -+ rRssi = (PARAM_RSSI) prAdapter->rLinkQuality.cRssi; /* ranged from (-128 ~ 30) in unit of dBm */ -+ -+ if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) -+ rRssi = PARAM_WHQL_RSSI_MAX_DBM; -+ else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) -+ rRssi = PARAM_WHQL_RSSI_MIN_DBM; -+ -+ kalMemCopy(pvQueryBuffer, &rRssi, sizeof(PARAM_RSSI)); -+ return WLAN_STATUS_SUCCESS; -+ } -+#ifdef LINUX -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryLinkQuality, -+ nicOidCmdTimeoutCommon, -+ *pu4QueryInfoLen, pvQueryBuffer, pvQueryBuffer, u4QueryBufferLen); -+#else -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryLinkQuality, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+#endif -+} /* end of wlanoidQueryRssi() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current RSSI trigger value. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call failed due to invalid length of -+* the query buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRssiTrigger(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRssiTrigger"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_NONE) -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ -+ *pu4QueryInfoLen = sizeof(PARAM_RSSI); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ *(PARAM_RSSI *) pvQueryBuffer = prAdapter->rWlanInfo.rRssiTriggerValue; -+ DBGLOG(OID, INFO, "RSSI trigger: %d dBm\n", *(PARAM_RSSI *) pvQueryBuffer); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryRssiTrigger */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a trigger value of the RSSI event. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns the -+* amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRssiTrigger(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PARAM_RSSI rRssiTriggerValue; -+ -+ DEBUGFUNC("wlanoidSetRssiTrigger"); -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_RSSI); -+ rRssiTriggerValue = *(PARAM_RSSI *) pvSetBuffer; -+ -+ if (rRssiTriggerValue > PARAM_WHQL_RSSI_MAX_DBM || rRssiTriggerValue < PARAM_WHQL_RSSI_MIN_DBM) -+ return -+ /* Save the RSSI trigger value to the Adapter structure */ -+ prAdapter->rWlanInfo.rRssiTriggerValue = rRssiTriggerValue; -+ -+ /* If the RSSI trigger value is equal to the current RSSI value, the -+ * indication triggers immediately. We need to indicate the protocol -+ * that an RSSI status indication event triggers. */ -+ if (rRssiTriggerValue == (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) { -+ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID) &prAdapter->rWlanInfo.rRssiTriggerValue, sizeof(PARAM_RSSI)); -+ } else if (rRssiTriggerValue < (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) -+ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_GREATER; -+ else if (rRssiTriggerValue > (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) -+ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_LESS; -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidSetRssiTrigger */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a suggested value for the number of -+* bytes of received packet data that will be indicated to the protocol -+* driver. We just accept the set and ignore this value. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetCurrentLookahead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ DEBUGFUNC("wlanoidSetCurrentLookahead"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) { -+ *pu4SetInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidSetCurrentLookahead */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of frames that the driver -+* receives but does not indicate to the protocols due to errors. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRcvError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRcvError"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ /* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */ -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryRecvError, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryRcvError */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the number of frames that the NIC -+* cannot receive due to lack of NIC receive buffer space. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS If success; -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRcvNoBuffer(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRcvNoBuffer"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) 0; /* @FIXME */ -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) 0; /* @FIXME */ -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryRecvNoBuffer, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryRcvNoBuffer */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the number of frames that the NIC -+* received and it is CRC error. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS If success; -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRcvCrcError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRcvCrcError"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryRecvCrcError, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryRcvCrcError */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the current 802.11 statistics. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryStatisticsPL(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(PARAM_802_11_STATISTICS_STRUCT_T)) { -+ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics; -+ -+ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) pvQueryBuffer; -+ -+ prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics->rTransmittedFragmentCount = prAdapter->rStatStruct.rTransmittedFragmentCount; -+ prStatistics->rMulticastTransmittedFrameCount = prAdapter->rStatStruct.rMulticastTransmittedFrameCount; -+ prStatistics->rFailedCount = prAdapter->rStatStruct.rFailedCount; -+ prStatistics->rRetryCount = prAdapter->rStatStruct.rRetryCount; -+ prStatistics->rMultipleRetryCount = prAdapter->rStatStruct.rMultipleRetryCount; -+ prStatistics->rRTSSuccessCount = prAdapter->rStatStruct.rRTSSuccessCount; -+ prStatistics->rRTSFailureCount = prAdapter->rStatStruct.rRTSFailureCount; -+ prStatistics->rACKFailureCount = prAdapter->rStatStruct.rACKFailureCount; -+ prStatistics->rFrameDuplicateCount = prAdapter->rStatStruct.rFrameDuplicateCount; -+ prStatistics->rReceivedFragmentCount = prAdapter->rStatStruct.rReceivedFragmentCount; -+ prStatistics->rMulticastReceivedFrameCount = prAdapter->rStatStruct.rMulticastReceivedFrameCount; -+ prStatistics->rFCSErrorCount = prAdapter->rStatStruct.rFCSErrorCount; -+ prStatistics->rTKIPLocalMICFailures.QuadPart = 0; -+ prStatistics->rTKIPICVErrors.QuadPart = 0; -+ prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; -+ prStatistics->rTKIPReplays.QuadPart = 0; -+ prStatistics->rCCMPFormatErrors.QuadPart = 0; -+ prStatistics->rCCMPReplays.QuadPart = 0; -+ prStatistics->rCCMPDecryptErrors.QuadPart = 0; -+ prStatistics->rFourWayHandshakeFailures.QuadPart = 0; -+ prStatistics->rWEPUndecryptableCount.QuadPart = 0; -+ prStatistics->rWEPICVErrorCount.QuadPart = 0; -+ prStatistics->rDecryptSuccessCount.QuadPart = 0; -+ prStatistics->rDecryptFailureCount.QuadPart = 0; -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS_PL, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryStatistics, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryStatistics */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the current 802.11 statistics. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryStatistics(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryStatistics"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(PARAM_802_11_STATISTICS_STRUCT_T)) { -+ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics; -+ -+ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) pvQueryBuffer; -+ -+ prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics->rTransmittedFragmentCount = prAdapter->rStatStruct.rTransmittedFragmentCount; -+ prStatistics->rMulticastTransmittedFrameCount = prAdapter->rStatStruct.rMulticastTransmittedFrameCount; -+ prStatistics->rFailedCount = prAdapter->rStatStruct.rFailedCount; -+ prStatistics->rRetryCount = prAdapter->rStatStruct.rRetryCount; -+ prStatistics->rMultipleRetryCount = prAdapter->rStatStruct.rMultipleRetryCount; -+ prStatistics->rRTSSuccessCount = prAdapter->rStatStruct.rRTSSuccessCount; -+ prStatistics->rRTSFailureCount = prAdapter->rStatStruct.rRTSFailureCount; -+ prStatistics->rACKFailureCount = prAdapter->rStatStruct.rACKFailureCount; -+ prStatistics->rFrameDuplicateCount = prAdapter->rStatStruct.rFrameDuplicateCount; -+ prStatistics->rReceivedFragmentCount = prAdapter->rStatStruct.rReceivedFragmentCount; -+ prStatistics->rMulticastReceivedFrameCount = prAdapter->rStatStruct.rMulticastReceivedFrameCount; -+ prStatistics->rFCSErrorCount = prAdapter->rStatStruct.rFCSErrorCount; -+ prStatistics->rTKIPLocalMICFailures.QuadPart = 0; -+ prStatistics->rTKIPICVErrors.QuadPart = 0; -+ prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; -+ prStatistics->rTKIPReplays.QuadPart = 0; -+ prStatistics->rCCMPFormatErrors.QuadPart = 0; -+ prStatistics->rCCMPReplays.QuadPart = 0; -+ prStatistics->rCCMPDecryptErrors.QuadPart = 0; -+ prStatistics->rFourWayHandshakeFailures.QuadPart = 0; -+ prStatistics->rWEPUndecryptableCount.QuadPart = 0; -+ prStatistics->rWEPICVErrorCount.QuadPart = 0; -+ prStatistics->rDecryptSuccessCount.QuadPart = 0; -+ prStatistics->rDecryptFailureCount.QuadPart = 0; -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryStatistics, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryStatistics */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query current media streaming status. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMediaStreamMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryMediaStreamMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_MEDIA_STREAM_MODE); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *(P_ENUM_MEDIA_STREAM_MODE) pvQueryBuffer = -+ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode == 0 ? ENUM_MEDIA_STREAM_OFF : ENUM_MEDIA_STREAM_ON; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidQueryMediaStreamMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to enter media streaming mode or exit media streaming mode -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetMediaStreamMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ENUM_MEDIA_STREAM_MODE eStreamMode; -+ -+ DEBUGFUNC("wlanoidSetMediaStreamMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen < sizeof(ENUM_MEDIA_STREAM_MODE)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *pu4SetInfoLen = sizeof(ENUM_MEDIA_STREAM_MODE); -+ -+ eStreamMode = *(P_ENUM_MEDIA_STREAM_MODE) pvSetBuffer; -+ -+ if (eStreamMode == ENUM_MEDIA_STREAM_OFF) -+ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 0; -+ else -+ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 1; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_LINK_ATTRIB, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetMediaStreamMode, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_LINK_ATTRIB), -+ (PUINT_8) &(prAdapter->rWlanInfo.eLinkAttr), pvSetBuffer, u4SetBufferLen); -+} /* wlanoidSetMediaStreamMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the permanent MAC address of the NIC. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryPermanentAddr"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < MAC_ADDR_LEN) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ COPY_MAC_ADDR(pvQueryBuffer, prAdapter->rWifiVar.aucPermanentAddress); -+ *pu4QueryInfoLen = MAC_ADDR_LEN; -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryPermanentAddr */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the MAC address the NIC is currently using. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryCurrentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ CMD_BASIC_CONFIG rCmdBasicConfig; -+ -+ DEBUGFUNC("wlanoidQueryCurrentAddr"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < MAC_ADDR_LEN) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ kalMemZero(&rCmdBasicConfig, sizeof(CMD_BASIC_CONFIG)); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_BASIC_CONFIG, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryAddress, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_BASIC_CONFIG), -+ (PUINT_8) &rCmdBasicConfig, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryCurrentAddr */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query NIC link speed. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryLinkSpeed(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryLinkSpeed"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (prAdapter->fgIsLinkRateValid == TRUE && -+ (kalGetTimeTick() - prAdapter->rLinkRateUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) { -+ *(PUINT_32) pvQueryBuffer = prAdapter->rLinkQuality.u2LinkSpeed * 5000; /* change to unit of 100bps */ -+ return WLAN_STATUS_SUCCESS; -+ } else { -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryLinkSpeed, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ } -+} /* end of wlanoidQueryLinkSpeed() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query MCR value. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMcrRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrRdInfo; -+ CMD_ACCESS_REG rCmdAccessReg; -+ -+ DEBUGFUNC("wlanoidQueryMcrRead"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prMcrRdInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) pvQueryBuffer; -+ -+ /* 0x9000 - 0x9EFF reserved for FW */ -+#if CFG_SUPPORT_SWCR -+ if ((prMcrRdInfo->u4McrOffset >> 16) == 0x9F00) { -+ swCrReadWriteCmd(prAdapter, -+ SWCR_READ, -+ (UINT_16) (prMcrRdInfo->u4McrOffset & BITS(0, 15)), &prMcrRdInfo->u4McrData); -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif /* CFG_SUPPORT_SWCR */ -+ -+ /* Check if access F/W Domain MCR (due to WiFiSYS is placed from 0x6000-0000 */ -+ if (prMcrRdInfo->u4McrOffset & 0xFFFF0000) { -+ /* fill command */ -+ rCmdAccessReg.u4Address = prMcrRdInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = 0; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryMcrRead, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvQueryBuffer, u4QueryBufferLen); -+ } else { -+ HAL_MCR_RD(prAdapter, prMcrRdInfo->u4McrOffset & BITS(2, 31), /* address is in DWORD unit */ -+ &prMcrRdInfo->u4McrData); -+ -+ DBGLOG(OID, TRACE, "MCR Read: Offset = %#08x, Data = %#08x\n", -+ prMcrRdInfo->u4McrOffset, prMcrRdInfo->u4McrData); -+ return WLAN_STATUS_SUCCESS; -+ } -+} /* end of wlanoidQueryMcrRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to write MCR and enable specific function. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetMcrWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrWrInfo; -+ CMD_ACCESS_REG rCmdAccessReg; -+ -+#if CFG_STRESS_TEST_SUPPORT -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prBssInfo = &(prAdapter->rWifiVar.arBssInfo[(NETWORK_TYPE_AIS_INDEX)]); -+ P_STA_RECORD_T prStaRec = prBssInfo->prStaRecOfAP; -+ UINT_32 u4McrOffset, u4McrData; -+#endif -+ -+ DEBUGFUNC("wlanoidSetMcrWrite"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prMcrWrInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) pvSetBuffer; -+ -+ /* 0x9000 - 0x9EFF reserved for FW */ -+ /* 0xFFFE reserved for FW */ -+ -+ /* -- Puff Stress Test Begin */ -+#if CFG_STRESS_TEST_SUPPORT -+ -+ /* 0xFFFFFFFE for Control Rate */ -+ if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFE) { -+ if (prMcrWrInfo->u4McrData < FIXED_RATE_NUM && prMcrWrInfo->u4McrData > 0) -+ prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (prMcrWrInfo->u4McrData); -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ DEBUGFUNC("[Stress Test]Complete Rate is Changed...\n"); -+ DBGLOG(OID, TRACE, -+ "[Stress Test] Rate is Changed to index %d...\n", prAdapter->rWifiVar.eRateSetting); -+ } -+ /* 0xFFFFFFFD for Switch Channel */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFD) { -+ if (prMcrWrInfo->u4McrData <= 11 && prMcrWrInfo->u4McrData >= 1) -+ prBssInfo->ucPrimaryChannel = prMcrWrInfo->u4McrData; -+ nicUpdateBss(prAdapter, prBssInfo->ucNetTypeIndex); -+ DBGLOG(OID, TRACE, "[Stress Test] Channel is switched to %d ...\n", prBssInfo->ucPrimaryChannel); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+ /* 0xFFFFFFFFC for Control RF Band and SCO */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFC) { -+ /* Band */ -+ if (prMcrWrInfo->u4McrData & 0x80000000) { -+ /* prBssInfo->eBand = BAND_5G; */ -+ /* prBssInfo->ucPrimaryChannel = 52; // Bond to Channel 52 */ -+ } else { -+ prBssInfo->eBand = BAND_2G4; -+ prBssInfo->ucPrimaryChannel = 8; /* Bond to Channel 6 */ -+ } -+ -+ /* Bandwidth */ -+ if (prMcrWrInfo->u4McrData & 0x00010000) { -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ -+ if (prMcrWrInfo->u4McrData == 0x00010002) { -+ prBssInfo->eBssSCO = CHNL_EXT_SCB; /* U20 */ -+ prBssInfo->ucPrimaryChannel += 2; -+ } else if (prMcrWrInfo->u4McrData == 0x00010001) { -+ prBssInfo->eBssSCO = CHNL_EXT_SCA; /* L20 */ -+ prBssInfo->ucPrimaryChannel -= 2; -+ } else { -+ prBssInfo->eBssSCO = CHNL_EXT_SCA; /* 40 */ -+ } -+ } -+ -+ if (prMcrWrInfo->u4McrData & 0x00000000) { -+ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; -+ prBssInfo->eBssSCO = CHNL_EXT_SCN; -+ } -+ rlmBssInitForAPandIbss(prAdapter, prBssInfo); -+ } -+ /* 0xFFFFFFFB for HT Capability */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFB) { -+ /* Enable HT Capability */ -+ if (prMcrWrInfo->u4McrData & 0x00000001) { -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; -+ DEBUGFUNC("[Stress Test]Enable HT capability...\n"); -+ } else { -+ prStaRec->u2HtCapInfo &= (~HT_CAP_INFO_HT_GF); -+ DEBUGFUNC("[Stress Test]Disable HT capability...\n"); -+ } -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ } -+ /* 0xFFFFFFFA for Enable Random Rx Reset */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFA) { -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_RANDOM_RX_RESET_EN, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+ /* 0xFFFFFFF9 for Disable Random Rx Reset */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF9) { -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_RANDOM_RX_RESET_DE, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+ /* 0xFFFFFFF8 for Enable SAPP */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF8) { -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SAPP_EN, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+ /* 0xFFFFFFF7 for Disable SAPP */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF7) { -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SAPP_DE, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+ -+ else -+#endif -+ /* -- Puff Stress Test End */ -+ -+ /* Check if access F/W Domain MCR */ -+ if (prMcrWrInfo->u4McrOffset & 0xFFFF0000) { -+ -+ /* 0x9000 - 0x9EFF reserved for FW */ -+#if CFG_SUPPORT_SWCR -+ if ((prMcrWrInfo->u4McrOffset >> 16) == 0x9F00) { -+ swCrReadWriteCmd(prAdapter, -+ SWCR_WRITE, -+ (UINT_16) (prMcrWrInfo->u4McrOffset & BITS(0, 15)), &prMcrWrInfo->u4McrData); -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif /* CFG_SUPPORT_SWCR */ -+ -+#if 1 -+ /* low power test special command */ -+ if (prMcrWrInfo->u4McrOffset == 0x11111110) { -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ /* DbgPrint("Enter test mode\n"); */ -+ prAdapter->fgTestMode = TRUE; -+ return rStatus; -+ } -+ if (prMcrWrInfo->u4McrOffset == 0x11111111) { -+ /* DbgPrint("nicpmSetAcpiPowerD3\n"); */ -+ -+ nicpmSetAcpiPowerD3(prAdapter); -+ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3); -+ return WLAN_STATUS_SUCCESS; -+ } -+ if (prMcrWrInfo->u4McrOffset == 0x11111112) { -+ -+ /* DbgPrint("LP enter sleep\n"); */ -+ -+ /* fill command */ -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+#endif -+ -+#if 1 -+ /* low power test special command */ -+ if (prMcrWrInfo->u4McrOffset == 0x11111110) { -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ /* DbgPrint("Enter test mode\n"); */ -+ prAdapter->fgTestMode = TRUE; -+ return rStatus; -+ } -+ if (prMcrWrInfo->u4McrOffset == 0x11111111) { -+ /* DbgPrint("nicpmSetAcpiPowerD3\n"); */ -+ -+ nicpmSetAcpiPowerD3(prAdapter); -+ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3); -+ return WLAN_STATUS_SUCCESS; -+ } -+ if (prMcrWrInfo->u4McrOffset == 0x11111112) { -+ -+ /* DbgPrint("LP enter sleep\n"); */ -+ -+ /* fill command */ -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+#endif -+ /* fill command */ -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } else { -+ HAL_MCR_WR(prAdapter, (prMcrWrInfo->u4McrOffset & BITS(2, 31)), /* address is in DWORD unit */ -+ prMcrWrInfo->u4McrData); -+ -+ DBGLOG(OID, TRACE, "MCR Write: Offset = %#08x, Data = %#08x\n", -+ prMcrWrInfo->u4McrOffset, prMcrWrInfo->u4McrData); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+} /* wlanoidSetMcrWrite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query SW CTRL -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo; -+ WLAN_STATUS rWlanStatus; -+ UINT_16 u2Id, u2SubId; -+ UINT_32 u4Data; -+ -+ CMD_SW_DBG_CTRL_T rCmdSwCtrl; -+ -+ DEBUGFUNC("wlanoidQuerySwCtrlRead"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) pvQueryBuffer; -+ -+ u2Id = (UINT_16) (prSwCtrlInfo->u4Id >> 16); -+ u2SubId = (UINT_16) (prSwCtrlInfo->u4Id & BITS(0, 15)); -+ u4Data = 0; -+ rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ switch (u2Id) { -+ /* 0x9000 - 0x9EFF reserved for FW */ -+ /* 0xFFFE reserved for FW */ -+ -+#if CFG_SUPPORT_SWCR -+ case 0x9F00: -+ swCrReadWriteCmd(prAdapter, SWCR_READ /* Read */ , -+ (UINT_16) u2SubId, &u4Data); -+ break; -+#endif /* CFG_SUPPORT_SWCR */ -+ -+ case 0xFFFF: -+ { -+ u4Data = 0x5AA56620; -+ } -+ break; -+ -+ case 0x9000: -+ default: -+ { -+ rCmdSwCtrl.u4Id = prSwCtrlInfo->u4Id; -+ rCmdSwCtrl.u4Data = 0; -+ rWlanStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQuerySwCtrlRead, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_SW_DBG_CTRL_T), -+ (PUINT_8) &rCmdSwCtrl, pvQueryBuffer, u4QueryBufferLen); -+ } -+ } /* switch(u2Id) */ -+ -+ prSwCtrlInfo->u4Data = u4Data; -+ -+ return rWlanStatus; -+ -+} -+ -+ /* end of wlanoidQuerySwCtrlRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to write SW CTRL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetSwCtrlWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo; -+ CMD_SW_DBG_CTRL_T rCmdSwCtrl; -+ WLAN_STATUS rWlanStatus; -+ UINT_16 u2Id, u2SubId; -+ UINT_32 u4Data; -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ P_GLUE_INFO_T prGlueInfo; -+ CMD_HOTSPOT_OPTIMIZATION_CONFIG arHotspotOptimizationCfg; -+#endif -+ -+ DEBUGFUNC("wlanoidSetSwCtrlWrite"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ prGlueInfo = prAdapter->prGlueInfo; -+#endif -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) pvSetBuffer; -+ -+ u2Id = (UINT_16) (prSwCtrlInfo->u4Id >> 16); -+ u2SubId = (UINT_16) (prSwCtrlInfo->u4Id & BITS(0, 15)); -+ u4Data = prSwCtrlInfo->u4Data; -+ rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ switch (u2Id) { -+ -+ /* 0x9000 - 0x9EFF reserved for FW */ -+ /* 0xFFFE reserved for FW */ -+ -+#if CFG_SUPPORT_SWCR -+ case 0x9F00: -+ swCrReadWriteCmd(prAdapter, SWCR_WRITE, (UINT_16) u2SubId, &u4Data); -+ break; -+#endif /* CFG_SUPPORT_SWCR */ -+ -+ case 0x1000: -+ if (u2SubId == 0x8000) { -+ /* CTIA power save mode setting (code: 0x10008000) */ -+ prAdapter->u4CtiaPowerMode = u4Data; -+ prAdapter->fgEnCtiaPowerMode = TRUE; -+ -+ /* */ -+ { -+ PARAM_POWER_MODE ePowerMode; -+ -+ if (prAdapter->u4CtiaPowerMode == 0) -+ /* force to keep in CAM mode */ -+ ePowerMode = Param_PowerModeCAM; -+ else if (prAdapter->u4CtiaPowerMode == 1) -+ ePowerMode = Param_PowerModeMAX_PSP; -+ else -+ ePowerMode = Param_PowerModeFast_PSP; -+ -+ rWlanStatus = nicConfigPowerSaveProfile(prAdapter, -+ NETWORK_TYPE_AIS_INDEX, ePowerMode, TRUE); -+ } -+ } -+ break; -+ case 0x1001: -+ if (u2SubId == 0x0) -+ prAdapter->fgEnOnlineScan = (BOOLEAN) u4Data; -+ else if (u2SubId == 0x1) -+ prAdapter->fgDisBcnLostDetection = (BOOLEAN) u4Data; -+ else if (u2SubId == 0x2) -+ prAdapter->rWifiVar.fgSupportUAPSD = (BOOLEAN) u4Data; -+ else if (u2SubId == 0x3) { -+ prAdapter->u4UapsdAcBmp = u4Data & BITS(0, 15); -+ prAdapter->rWifiVar.arBssInfo[u4Data >> 16].rPmProfSetupInfo.ucBmpDeliveryAC = -+ (UINT_8) prAdapter->u4UapsdAcBmp; -+ prAdapter->rWifiVar.arBssInfo[u4Data >> 16].rPmProfSetupInfo.ucBmpTriggerAC = -+ (UINT_8) prAdapter->u4UapsdAcBmp; -+ } else if (u2SubId == 0x4) -+ prAdapter->fgDisStaAgingTimeoutDetection = (BOOLEAN) u4Data; -+ else if (u2SubId == 0x5) -+ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = (UINT_8) u4Data; -+ else if (u2SubId == 0x0100) -+ prAdapter->rWifiVar.u8SupportRxGf = (UINT_8) u4Data; -+ else if (u2SubId == 0x0101) { -+ prAdapter->rWifiVar.u8SupportRxSgi20 = (UINT_8) u4Data; -+ prAdapter->rWifiVar.u8SupportRxSgi40 = (UINT_8) u4Data; -+ } else if (u2SubId == 0x0102) -+ prAdapter->rWifiVar.u8SupportRxSTBC = (UINT_8) u4Data; -+ break; -+ -+#if CFG_SUPPORT_SWCR -+ case 0x1002: -+ if (u2SubId == 0x0) { -+ if (u4Data) -+ u4Data = BIT(HIF_RX_PKT_TYPE_MANAGEMENT); -+ swCrFrameCheckEnable(prAdapter, u4Data); -+ } else if (u2SubId == 0x1) { -+ BOOLEAN fgIsEnable; -+ UINT_8 ucType; -+ UINT_32 u4Timeout; -+ -+ fgIsEnable = (BOOLEAN) (u4Data & 0xff); -+ ucType = 0; /* ((u4Data>>4) & 0xf); */ -+ u4Timeout = ((u4Data >> 8) & 0xff); -+ swCrDebugCheckEnable(prAdapter, fgIsEnable, ucType, u4Timeout); -+ } -+ break; -+#endif -+ -+#if CFG_SUPPORT_802_11W -+ case 0x2000: -+ DBGLOG(RSN, TRACE, "802.11w test 0x%x\n", u2SubId); -+ if (u2SubId == 0x0) -+ rsnStartSaQuery(prAdapter); -+ if (u2SubId == 0x1) -+ rsnStopSaQuery(prAdapter); -+ if (u2SubId == 0x2) -+ rsnSaQueryRequest(prAdapter, NULL); -+ if (u2SubId == 0x3) { -+ P_BSS_INFO_T prBssInfo = &(prAdapter->rWifiVar.arBssInfo[(NETWORK_TYPE_AIS_INDEX)]); -+ -+ authSendDeauthFrame(prAdapter, prBssInfo->prStaRecOfAP, NULL, 7, NULL); -+ } -+ /* wext_set_mode */ -+ /* -+ if (u2SubId == 0x3) { -+ prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_DISABLED; -+ } -+ if (u2SubId == 0x4) { -+ //prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; -+ prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_OPTIONAL; -+ } -+ if (u2SubId == 0x5) { -+ //prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; -+ prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_REQUIRED; -+ } -+ */ -+ break; -+#endif -+ case 0xFFFF: -+ { -+/* CMD_ACCESS_REG rCmdAccessReg; */ -+#if 1 /* CFG_MT6573_SMT_TEST */ -+ if (u2SubId == 0x0123) { -+ -+ DBGLOG(HAL, TRACE, "set smt fixed rate: %u\n", u4Data); -+ -+ if ((ENUM_REGISTRY_FIXED_RATE_T) (u4Data) < FIXED_RATE_NUM) -+ prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (u4Data); -+ else -+ prAdapter->rWifiVar.eRateSetting = FIXED_RATE_NONE; -+ -+ if (prAdapter->rWifiVar.eRateSetting == FIXED_RATE_NONE) -+ /* Enable Auto (Long/Short) Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_AUTO; -+ else if ((prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_20M_400NS && -+ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS7_20M_400NS) -+ || (prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_40M_400NS && -+ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS32_400NS)) -+ /* Force Short Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_SHORT; -+ else -+ /* Force Long Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_LONG; -+ -+ /* abort to re-connect */ -+#if 1 -+ DBGLOG(OID, TRACE, "DisBySwC\n"); -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+#else -+ aisBssBeaconTimeout(prAdapter); -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+ -+ } else if (u2SubId == 0x1234) { -+ /* 1. Disable On-Lin Scan */ -+ /* 3. Disable FIFO FULL no ack */ -+ /* 4. Disable Roaming */ -+ /* Disalbe auto tx power */ -+ /* 2. Keep at CAM mode */ -+ /* 5. Disable Beacon Timeout Detection */ -+ rWlanStatus = nicEnterCtiaMode(prAdapter, TRUE, TRUE); -+ } else if (u2SubId == 0x1235) { -+ /* 1. Enaable On-Lin Scan */ -+ /* 3. Enable FIFO FULL no ack */ -+ /* 4. Enable Roaming */ -+ /* Enable auto tx power */ -+ /* 2. Keep at Fast PS */ -+ /* 5. Enable Beacon Timeout Detection */ -+ rWlanStatus = nicEnterCtiaMode(prAdapter, FALSE, TRUE); -+ } -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ else if (u2SubId == 0x1240) { -+ DBGLOG(P2P, TRACE, "Disable Hotspot Optimization!\n"); -+ -+ arHotspotOptimizationCfg.fgHotspotOptimizationEn = FALSE; -+ arHotspotOptimizationCfg.u4Level = 0; -+ wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_HOTSPOT_OPTIMIZATION, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ NULL, -+ sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG), -+ (PUINT_8) &arHotspotOptimizationCfg, NULL, 0); -+ } else if (u2SubId == 0x1241) { -+ DBGLOG(P2P, TRACE, "Enable Hotspot Optimization!\n"); -+ -+ arHotspotOptimizationCfg.fgHotspotOptimizationEn = TRUE; -+ arHotspotOptimizationCfg.u4Level = 5; -+ wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_HOTSPOT_OPTIMIZATION, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ NULL, -+ sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG), -+ (PUINT_8) &arHotspotOptimizationCfg, NULL, 0); -+ } -+#endif /* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */ -+ else if (u2SubId == 0x1250) { -+ DBGLOG(OID, TRACE, "LTE_COEX: SW SET DUAL BAND\n"); -+ prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_NULL; -+ } else if (u2SubId == 0x1251) { -+ DBGLOG(OID, TRACE, "LTE_COEX: SW SET 2.4G BAND\n"); -+ prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_2G4; -+ } else if (u2SubId == 0x1252) { -+ DBGLOG(OID, TRACE, "LTE_COEX: SW SET 5G BAND\n"); -+ prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_5G; -+ } -+#endif -+ } -+ break; -+ -+ case 0x9000: -+ default: -+ { -+ rCmdSwCtrl.u4Id = prSwCtrlInfo->u4Id; -+ rCmdSwCtrl.u4Data = prSwCtrlInfo->u4Data; -+ rWlanStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_SW_DBG_CTRL_T), -+ (PUINT_8) &rCmdSwCtrl, pvSetBuffer, u4SetBufferLen); -+ } -+ } /* switch(u2Id) */ -+ -+ return rWlanStatus; -+} -+ -+ /* wlanoidSetSwCtrlWrite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query EEPROM value. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryEepromRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRwInfo; -+ CMD_ACCESS_EEPROM rCmdAccessEeprom; -+ -+ DEBUGFUNC("wlanoidQueryEepromRead"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prEepromRwInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) pvQueryBuffer; -+ -+ kalMemZero(&rCmdAccessEeprom, sizeof(CMD_ACCESS_EEPROM)); -+ rCmdAccessEeprom.u2Offset = prEepromRwInfo->ucEepromIndex; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_EEPROM, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryEepromRead, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_EEPROM), -+ (PUINT_8) &rCmdAccessEeprom, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryEepromRead */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to write EEPROM value. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetEepromWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRwInfo; -+ CMD_ACCESS_EEPROM rCmdAccessEeprom; -+ -+ DEBUGFUNC("wlanoidSetEepromWrite"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prEepromRwInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdAccessEeprom, sizeof(CMD_ACCESS_EEPROM)); -+ rCmdAccessEeprom.u2Offset = prEepromRwInfo->ucEepromIndex; -+ rCmdAccessEeprom.u2Data = prEepromRwInfo->u2EepromData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_EEPROM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_EEPROM), -+ (PUINT_8) &rCmdAccessEeprom, pvSetBuffer, u4SetBufferLen); -+ -+} /* wlanoidSetEepromWrite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of the successfully transmitted -+* packets. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryXmitOk(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryXmitOk"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rTransmittedFragmentCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rTransmittedFragmentCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryXmitOk, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryXmitOk */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of the successfully received -+* packets. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRcvOk(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRcvOk"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rReceivedFragmentCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rReceivedFragmentCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryRecvOk, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryRcvOk */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of frames that the driver -+* fails to transmit. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryXmitError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryXmitError"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFailedCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFailedCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryXmitError, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryXmitError */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of frames successfully -+* transmitted after exactly one collision. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryXmitOneCollision"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) -+ (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart - -+ prAdapter->rStatStruct.rRetryCount.QuadPart); -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) -+ (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart - -+ prAdapter->rStatStruct.rRetryCount.QuadPart); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryXmitOneCollision, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryXmitOneCollision */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of frames successfully -+* transmitted after more than one collision. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryXmitMoreCollisions"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart); -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryXmitMoreCollisions, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+} /* wlanoidQueryXmitMoreCollisions */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of frames -+* not transmitted due to excessive collisions. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryXmitMaxCollisions"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFailedCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFailedCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryXmitMaxCollisions, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+} /* wlanoidQueryXmitMaxCollisions */ -+ -+#define MTK_CUSTOM_OID_INTERFACE_VERSION 0x00006620 /* for WPDWifi DLL */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current the OID interface version, -+* which is the interface between the application and driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryOidInterfaceVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryOidInterfaceVersion"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *(PUINT_32) pvQueryBuffer = MTK_CUSTOM_OID_INTERFACE_VERSION; -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ DBGLOG(OID, WARN, "Custom OID interface version: %#08X\n", *(PUINT_32) pvQueryBuffer); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryOidInterfaceVersion */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current Multicast Address List. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMulticastList(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+#ifndef LINUX -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_MAC_MCAST_ADDR, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryMcastAddr, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+#else -+ return WLAN_STATUS_SUCCESS; -+#endif -+} /* end of wlanoidQueryMulticastList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set Multicast Address List. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetMulticastList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_8 ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; /* Caller should provide this information */ -+ CMD_MAC_MCAST_ADDR rCmdMacMcastAddr; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ /* The data must be a multiple of the Ethernet address size. */ -+ if ((u4SetBufferLen % MAC_ADDR_LEN)) { -+ DBGLOG(OID, WARN, "Invalid MC list length %u\n", u4SetBufferLen); -+ -+ *pu4SetInfoLen = (((u4SetBufferLen + MAC_ADDR_LEN) - 1) / MAC_ADDR_LEN) * MAC_ADDR_LEN; -+ -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ /* Verify if we can support so many multicast addresses. */ -+ if ((u4SetBufferLen / MAC_ADDR_LEN) > MAX_NUM_GROUP_ADDR) { -+ DBGLOG(OID, WARN, "Too many MC addresses\n"); -+ -+ return WLAN_STATUS_MULTICAST_FULL; -+ } -+ -+ /* NOTE(Kevin): Windows may set u4SetBufferLen == 0 && -+ * pvSetBuffer == NULL to clear exist Multicast List. -+ */ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set multicast list! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ rCmdMacMcastAddr.u4NumOfGroupAddr = u4SetBufferLen / MAC_ADDR_LEN; -+ rCmdMacMcastAddr.ucNetTypeIndex = ucNetTypeIndex; -+ kalMemCopy(rCmdMacMcastAddr.arAddress, pvSetBuffer, u4SetBufferLen); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_MAC_MCAST_ADDR, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_MAC_MCAST_ADDR), -+ (PUINT_8) &rCmdMacMcastAddr, pvSetBuffer, u4SetBufferLen); -+} /* end of wlanoidSetMulticastList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set Packet Filter. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_NOT_SUPPORTED -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetCurrentPacketFilter(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_32 u4NewPacketFilter; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) { -+ *pu4SetInfoLen = sizeof(UINT_32); -+ DBGLOG(OID, INFO, "iput buffer is too small"); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ ASSERT(pvSetBuffer); -+ -+ /* Set the new packet filter. */ -+ u4NewPacketFilter = *(PUINT_32) pvSetBuffer; -+ -+ DBGLOG(OID, TRACE, "New packet filter: %#08x\n", u4NewPacketFilter); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set current packet filter! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ do { -+ /* Verify the bits of the new packet filter. If any bits are set that -+ we don't support, leave. */ -+ if (u4NewPacketFilter & ~(PARAM_PACKET_FILTER_SUPPORTED)) { -+ rStatus = WLAN_STATUS_NOT_SUPPORTED; -+ break; -+ } -+#if DBG -+ /* Need to enable or disable promiscuous support depending on the new -+ filter. */ -+ if (u4NewPacketFilter & PARAM_PACKET_FILTER_PROMISCUOUS) -+ DBGLOG(OID, TRACE, "Enable promiscuous mode\n"); -+ else -+ DBGLOG(OID, TRACE, "Disable promiscuous mode\n"); -+ -+ if (u4NewPacketFilter & PARAM_PACKET_FILTER_ALL_MULTICAST) -+ DBGLOG(OID, TRACE, "Enable all-multicast mode\n"); -+ else if (u4NewPacketFilter & PARAM_PACKET_FILTER_MULTICAST) -+ DBGLOG(OID, TRACE, "Enable multicast\n"); -+ else -+ DBGLOG(OID, TRACE, "Disable multicast\n"); -+ -+ if (u4NewPacketFilter & PARAM_PACKET_FILTER_BROADCAST) -+ DBGLOG(OID, TRACE, "Enable Broadcast\n"); -+ else -+ DBGLOG(OID, TRACE, "Disable Broadcast\n"); -+#endif -+ } while (FALSE); -+ -+ if (rStatus == WLAN_STATUS_SUCCESS) { -+ /* Store the packet filter */ -+ -+ prAdapter->u4OsPacketFilter &= PARAM_PACKET_FILTER_P2P_MASK; -+ prAdapter->u4OsPacketFilter |= u4NewPacketFilter; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_RX_FILTER, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(UINT_32), -+ (PUINT_8) &prAdapter->u4OsPacketFilter, pvSetBuffer, u4SetBufferLen); -+ } else { -+ return rStatus; -+ } -+} /* wlanoidSetCurrentPacketFilter */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current packet filter. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryCurrentPacketFilter(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryCurrentPacketFilter"); -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ if (u4QueryBufferLen >= sizeof(UINT_32)) { -+ ASSERT(pvQueryBuffer); -+ *(PUINT_32) pvQueryBuffer = prAdapter->u4OsPacketFilter; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryCurrentPacketFilter */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query ACPI device power state. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+#if DBG -+ PPARAM_DEVICE_POWER_STATE prPowerState; -+#endif -+ -+ DEBUGFUNC("wlanoidQueryAcpiDevicePowerState"); -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_DEVICE_POWER_STATE); -+ -+#if DBG -+ prPowerState = (PPARAM_DEVICE_POWER_STATE) pvQueryBuffer; -+ switch (*prPowerState) { -+ case ParamDeviceStateD0: -+ DBGLOG(OID, INFO, "Query Power State: D0\n"); -+ break; -+ case ParamDeviceStateD1: -+ DBGLOG(OID, INFO, "Query Power State: D1\n"); -+ break; -+ case ParamDeviceStateD2: -+ DBGLOG(OID, INFO, "Query Power State: D2\n"); -+ break; -+ case ParamDeviceStateD3: -+ DBGLOG(OID, INFO, "Query Power State: D3\n"); -+ break; -+ default: -+ break; -+ } -+#endif -+ -+ /* Since we will disconnect the newwork, therefore we do not -+ need to check queue empty */ -+ *(PPARAM_DEVICE_POWER_STATE) pvQueryBuffer = ParamDeviceStateD3; -+ /* WARNLOG(("Ready to transition to D3\n")); */ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* pwrmgtQueryPower */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set ACPI device power state. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PPARAM_DEVICE_POWER_STATE prPowerState; -+ BOOLEAN fgRetValue = TRUE; -+ -+ DEBUGFUNC("wlanoidSetAcpiDevicePowerState"); -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_DEVICE_POWER_STATE); -+ -+ ASSERT(pvSetBuffer); -+ prPowerState = (PPARAM_DEVICE_POWER_STATE) pvSetBuffer; -+ switch (*prPowerState) { -+ case ParamDeviceStateD0: -+ DBGLOG(OID, INFO, "Set Power State: D0\n"); -+ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD0); -+ fgRetValue = nicpmSetAcpiPowerD0(prAdapter); -+ break; -+ case ParamDeviceStateD1: -+ DBGLOG(OID, INFO, "Set Power State: D1\n"); -+ /* no break here */ -+ case ParamDeviceStateD2: -+ DBGLOG(OID, INFO, "Set Power State: D2\n"); -+ /* no break here */ -+ case ParamDeviceStateD3: -+ DBGLOG(OID, INFO, "Set Power State: D3\n"); -+ fgRetValue = nicpmSetAcpiPowerD3(prAdapter); -+ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3); -+ break; -+ default: -+ break; -+ } -+ -+ if (fgRetValue == TRUE) -+ return WLAN_STATUS_SUCCESS; -+ else -+ return WLAN_STATUS_FAILURE; -+} /* end of wlanoidSetAcpiDevicePowerState() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current fragmentation threshold. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryFragThreshold(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryFragThreshold"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ DBGLOG(OID, LOUD, "\n"); -+ -+#if CFG_TX_FRAGMENT -+ -+ return WLAN_STATUS_SUCCESS; -+ -+#else -+ -+ return WLAN_STATUS_NOT_SUPPORTED; -+#endif /* CFG_TX_FRAGMENT */ -+ -+} /* end of wlanoidQueryFragThreshold() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a new fragmentation threshold to the -+* driver. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetFragThreshold(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+#if CFG_TX_FRAGMENT -+ -+ return WLAN_STATUS_SUCCESS; -+ -+#else -+ -+ return WLAN_STATUS_NOT_SUPPORTED; -+#endif /* CFG_TX_FRAGMENT */ -+ -+} /* end of wlanoidSetFragThreshold() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current RTS threshold. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRtsThreshold(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRtsThreshold"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ DBGLOG(OID, LOUD, "\n"); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_RTS_THRESHOLD)) { -+ *pu4QueryInfoLen = sizeof(PARAM_RTS_THRESHOLD); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ *((PARAM_RTS_THRESHOLD *) pvQueryBuffer) = prAdapter->rWlanInfo.eRtsThreshold; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidQueryRtsThreshold */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a new RTS threshold to the driver. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRtsThreshold(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PARAM_RTS_THRESHOLD *prRtsThreshold; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_RTS_THRESHOLD); -+ if (u4SetBufferLen < sizeof(PARAM_RTS_THRESHOLD)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prRtsThreshold = (PARAM_RTS_THRESHOLD *) pvSetBuffer; -+ *prRtsThreshold = prAdapter->rWlanInfo.eRtsThreshold; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidSetRtsThreshold */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to turn radio off. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetDisassociate(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ -+ DEBUGFUNC("wlanoidSetDisassociate"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 0; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set disassociate! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ /* prepare message to AIS */ -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; -+ -+ /* Send AIS Abort Message */ -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ /* indicate for disconnection */ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ DBGLOG(OID, INFO, "DisconnectByOid\n"); -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY, NULL, 0); -+ } -+#if !defined(LINUX) -+ prAdapter->fgIsRadioOff = TRUE; -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidSetDisassociate */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to query the power save profile. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQuery802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQuery802dot11PowerSaveProfile"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen != 0) { -+ ASSERT(pvQueryBuffer); -+ -+/* *(PPARAM_POWER_MODE) pvQueryBuffer = (PARAM_POWER_MODE)(prAdapter->rWlanInfo.ePowerSaveMode.ucPsProfile); */ -+ *(PPARAM_POWER_MODE) pvQueryBuffer = -+ (PARAM_POWER_MODE) (prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_AIS_INDEX].ucPsProfile); -+ *pu4QueryInfoLen = sizeof(PARAM_POWER_MODE); -+ -+ /* hack for CTIA power mode setting function */ -+ if (prAdapter->fgEnCtiaPowerMode) { -+ /* set to non-zero value (to prevent MMI query 0, before it intends to set 0, */ -+ /* which will skip its following state machine) */ -+ *(PPARAM_POWER_MODE) pvQueryBuffer = (PARAM_POWER_MODE) 2; -+ } -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set the power save profile. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSet802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS status; -+ PARAM_POWER_MODE ePowerMode; -+ -+ DEBUGFUNC("wlanoidSet802dot11PowerSaveProfile"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_POWER_MODE); -+ if (u4SetBufferLen < sizeof(PARAM_POWER_MODE)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (*(PPARAM_POWER_MODE) pvSetBuffer >= Param_PowerModeMax) { -+ /* WARNLOG(("Invalid power mode %d\n", */ -+ /* *(PPARAM_POWER_MODE) pvSetBuffer)); */ -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ ePowerMode = *(PPARAM_POWER_MODE) pvSetBuffer; -+ -+ if (prAdapter->fgEnCtiaPowerMode) { -+ if (ePowerMode == Param_PowerModeCAM) -+ ; -+ else { -+ /* User setting to PS mode (Param_PowerModeMAX_PSP or Param_PowerModeFast_PSP) */ -+ -+ if (prAdapter->u4CtiaPowerMode == 0) -+ /* force to keep in CAM mode */ -+ ePowerMode = Param_PowerModeCAM; -+ else if (prAdapter->u4CtiaPowerMode == 1) -+ ePowerMode = Param_PowerModeMAX_PSP; -+ else if (prAdapter->u4CtiaPowerMode == 2) -+ ePowerMode = Param_PowerModeFast_PSP; -+ } -+ } -+ -+ status = nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, ePowerMode, TRUE); -+ -+ switch (ePowerMode) { -+ case Param_PowerModeCAM: -+ DBGLOG(OID, INFO, "Set Wi-Fi PS mode to CAM (%d)\n", ePowerMode); -+ break; -+ case Param_PowerModeMAX_PSP: -+ DBGLOG(OID, INFO, "Set Wi-Fi PS mode to MAX PS (%d)\n", ePowerMode); -+ break; -+ case Param_PowerModeFast_PSP: -+ DBGLOG(OID, INFO, "Set Wi-Fi PS mode to FAST PS (%d)\n", ePowerMode); -+ break; -+ default: -+ DBGLOG(OID, INFO, "invalid Wi-Fi PS mode setting (%d)\n", ePowerMode); -+ break; -+ } -+ -+ return status; -+ -+} /* end of wlanoidSetAcpiDevicePowerStateMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current status of AdHoc Mode. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryAdHocMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidQueryAdHocMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set AdHoc Mode. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAdHocMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetAdHocMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query RF frequency. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryFrequency(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryFrequency"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) { -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ *(PUINT_32) pvQueryBuffer = -+ nicChannelNum2Freq(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].ucPrimaryChannel); -+ } else { -+ *(PUINT_32) pvQueryBuffer = 0; -+ } -+ } else { -+ *(PUINT_32) pvQueryBuffer = nicChannelNum2Freq(prAdapter->rWifiVar.rConnSettings.ucAdHocChannelNum); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidQueryFrequency() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set RF frequency by User Settings. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetFrequency(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_32 pu4FreqInKHz; -+ -+ DEBUGFUNC("wlanoidSetFrequency"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ pu4FreqInKHz = (PUINT_32) pvSetBuffer; -+ -+ prAdapter->rWifiVar.rConnSettings.ucAdHocChannelNum = (UINT_8) nicFreq2ChannelNum(*pu4FreqInKHz); -+ prAdapter->rWifiVar.rConnSettings.eAdHocBand = *pu4FreqInKHz < 5000000 ? BAND_2G4 : BAND_5G; -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetFrequency() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set 802.11 channel of the radio frequency. -+* This is a proprietary function call to Lunux currently. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetChannel(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ASSERT(0); /* // */ -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the Beacon Interval from User Settings. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBeaconInterval(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryBeaconInterval"); -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) -+ *(PUINT_32) pvQueryBuffer = prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod; -+ else -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2BeaconPeriod; -+ } else { -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) -+ *(PUINT_32) pvQueryBuffer = 0; -+ else -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2BeaconPeriod; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidQueryBeaconInterval() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the Beacon Interval to User Settings. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBeaconInterval(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_32 pu4BeaconInterval; -+ -+ DEBUGFUNC("wlanoidSetBeaconInterval"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ if (u4SetBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ pu4BeaconInterval = (PUINT_32) pvSetBuffer; -+ -+ if ((*pu4BeaconInterval < DOT11_BEACON_PERIOD_MIN) || (*pu4BeaconInterval > DOT11_BEACON_PERIOD_MAX)) { -+ DBGLOG(OID, TRACE, "Invalid Beacon Interval = %u\n", *pu4BeaconInterval); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ prAdapter->rWlanInfo.u2BeaconPeriod = (UINT_16) *pu4BeaconInterval; -+ -+ DBGLOG(OID, INFO, "Set beacon interval: %d\n", prAdapter->rWlanInfo.u2BeaconPeriod); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetBeaconInterval() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the ATIM window from User Settings. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryAtimWindow(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryAtimWindow"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) -+ *(PUINT_32) pvQueryBuffer = 0; -+ else -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2AtimWindow; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of wlanoidQueryAtimWindow() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the ATIM window to User Settings. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAtimWindow(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_32 pu4AtimWindow; -+ -+ DEBUGFUNC("wlanoidSetAtimWindow"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ pu4AtimWindow = (PUINT_32) pvSetBuffer; -+ -+ prAdapter->rWlanInfo.u2AtimWindow = (UINT_16) *pu4AtimWindow; -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetAtimWindow() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to Set the MAC address which is currently used by the NIC. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetCurrentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ASSERT(0); /* // */ -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetCurrentAddr() */ -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Setting the checksum offload function. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetCSUMOffload(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_32 i, u4CSUMFlags; -+ CMD_BASIC_CONFIG rCmdBasicConfig; -+ -+ DEBUGFUNC("wlanoidSetCSUMOffload"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ u4CSUMFlags = *(PUINT_32) pvSetBuffer; -+ -+ kalMemZero(&rCmdBasicConfig, sizeof(CMD_BASIC_CONFIG)); -+ -+ for (i = 0; i < 6; i++) { /* set to broadcast address for not-specified */ -+ rCmdBasicConfig.rMyMacAddr[i] = 0xff; -+ } -+ -+ rCmdBasicConfig.ucNative80211 = 0; /* @FIXME: for Vista */ -+ -+ if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP) -+ rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(2); -+ -+ if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP) -+ rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(1); -+ -+ if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_IP) -+ rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(0); -+ -+ if (u4CSUMFlags & CSUM_OFFLOAD_EN_RX_TCP) -+ rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(2); -+ -+ if (u4CSUMFlags & CSUM_OFFLOAD_EN_RX_UDP) -+ rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(1); -+ -+ if (u4CSUMFlags & (CSUM_OFFLOAD_EN_RX_IPv4 | CSUM_OFFLOAD_EN_RX_IPv6)) -+ rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(0); -+ -+ prAdapter->u4CSUMFlags = u4CSUMFlags; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_BASIC_CONFIG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_BASIC_CONFIG), (PUINT_8) &rCmdBasicConfig, pvSetBuffer, u4SetBufferLen); -+} -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Setting the IP address for pattern search function. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_ADAPTER_NOT_READY -+* \return WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 i, j; -+ P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList; -+ P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer; -+ P_PARAM_NETWORK_ADDRESS prNetworkAddress; -+ P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp; -+ UINT_32 u4IpAddressCount, u4CmdSize; -+ PUINT_8 pucBuf = (PUINT_8) pvSetBuffer; -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ UINT_32 u4IpV4AddrListSize; -+ P_BSS_INFO_T prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+#endif -+ -+ DEBUGFUNC("wlanoidSetNetworkAddress"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 4; -+ -+ if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST)) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ *pu4SetInfoLen = 0; -+ u4IpAddressCount = 0; -+ -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ u4IpAddressCount++; -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) (prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); -+ } -+ -+ /* construct payload of command packet */ -+ u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + -+ sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount; -+ if (u4IpAddressCount == 0) -+ u4CmdSize = sizeof(CMD_SET_NETWORK_ADDRESS_LIST); -+ -+ prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); -+ -+ if (prCmdNetworkAddressList == NULL) -+ return WLAN_STATUS_FAILURE; -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ u4IpV4AddrListSize = OFFSET_OF(IPV4_NETWORK_ADDRESS_LIST, arNetAddr) + -+ (u4IpAddressCount * sizeof(IPV4_NETWORK_ADDRESS)); -+ if (prBssInfo->prIpV4NetAddrList) -+ FREE_IPV4_NETWORK_ADDR_LIST(prBssInfo->prIpV4NetAddrList); -+ prBssInfo->prIpV4NetAddrList = (P_IPV4_NETWORK_ADDRESS_LIST) kalMemAlloc(u4IpV4AddrListSize, VIR_MEM_TYPE); -+ if (prBssInfo->prIpV4NetAddrList == NULL) { -+ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); -+ return WLAN_STATUS_FAILURE; -+ } -+ prBssInfo->prIpV4NetAddrList->ucAddrCount = (UINT_8) u4IpAddressCount; -+#endif -+ -+ /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ -+ prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ -+ /* only to set IP address to FW once ARP filter is enabled */ -+ if (prAdapter->fgEnArpFilter) { -+ prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount; -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ -+ DBGLOG(OID, INFO, "u4IpAddressCount (%u)\n", u4IpAddressCount); -+ -+ for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress; -+ -+ kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr, -+ &(prNetAddrIp->in_addr), sizeof(UINT_32)); -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ kalMemCopy(prBssInfo->prIpV4NetAddrList->arNetAddr[j].aucIpAddr, -+ &(prNetAddrIp->in_addr), sizeof(UINT_32)); -+#endif -+ -+ j++; -+ -+ pucBuf = (PUINT_8) &prNetAddrIp->in_addr; -+ DBGLOG(OID, INFO, -+ "prNetAddrIp->in_addr:%d:%d:%d:%d\n", pucBuf[0], pucBuf[1], pucBuf[2], -+ pucBuf[3]); -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) (prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, -+ aucAddress))); -+ } -+ -+ } else { -+ prCmdNetworkAddressList->ucAddressCount = 0; -+ } -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_IP_ADDRESS, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetIpAddress, -+ nicOidCmdTimeoutCommon, -+ u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen); -+ -+ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Set driver to switch into RF test mode -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set, -+* should be NULL -+* \param[in] u4SetBufferLen The length of the set buffer, should be 0 -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_ADAPTER_NOT_READY -+* \return WLAN_STATUS_INVALID_DATA -+* \return WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidRftestSetTestMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus; -+ CMD_TEST_CTRL_T rCmdTestCtrl; -+ -+ DEBUGFUNC("wlanoidRftestSetTestMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 0; -+ -+ if (u4SetBufferLen == 0) { -+ if (prAdapter->fgTestMode == FALSE) { -+ /* switch to RF Test mode */ -+ rCmdTestCtrl.ucAction = 0; /* Switch mode */ -+ rCmdTestCtrl.u.u4OpMode = 1; /* RF test mode */ -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_TEST_MODE, -+ TRUE, -+ TRUE, -+ TRUE, -+ nicCmdEventEnterRfTest, -+ nicOidCmdEnterRFTestTimeout, -+ sizeof(CMD_TEST_CTRL_T), -+ (PUINT_8) &rCmdTestCtrl, pvSetBuffer, u4SetBufferLen); -+ } else { -+ /* already in test mode .. */ -+ rStatus = WLAN_STATUS_SUCCESS; -+ } -+ } else { -+ rStatus = WLAN_STATUS_INVALID_DATA; -+ } -+ DBGLOG(OID, INFO, "Enter TestMode, setBufLen %u, InTestMode %d, rStatus %u\n", -+ u4SetBufferLen, prAdapter->fgTestMode, rStatus); -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Set driver to switch into normal operation mode from RF test mode -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* should be NULL -+* \param[in] u4SetBufferLen The length of the set buffer, should be 0 -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_ADAPTER_NOT_READY -+* \return WLAN_STATUS_INVALID_DATA -+* \return WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidRftestSetAbortTestMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus; -+ CMD_TEST_CTRL_T rCmdTestCtrl; -+ -+ DEBUGFUNC("wlanoidRftestSetTestMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 0; -+ -+ if (u4SetBufferLen == 0) { -+ if (prAdapter->fgTestMode == TRUE) { -+ /* switch to normal mode */ -+ rCmdTestCtrl.ucAction = 0; /* Switch mode */ -+ rCmdTestCtrl.u.u4OpMode = 0; /* normal mode */ -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_TEST_MODE, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventLeaveRfTest, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_TEST_CTRL_T), -+ (PUINT_8) &rCmdTestCtrl, pvSetBuffer, u4SetBufferLen); -+ } else { -+ /* already in normal mode .. */ -+ rStatus = WLAN_STATUS_SUCCESS; -+ } -+ } else { -+ rStatus = WLAN_STATUS_INVALID_DATA; -+ } -+ DBGLOG(OID, INFO, "Abort TestMode, setBufLen %u, InTestMode %d, rStatus %u\n", -+ u4SetBufferLen, prAdapter->fgTestMode, rStatus); -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief query for RF test parameter -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+* \retval WLAN_STATUS_NOT_SUPPORTED -+* \retval WLAN_STATUS_NOT_ACCEPTED -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidRftestQueryAutoTest(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_MTK_WIFI_TEST_STRUCT_T prRfATInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidRftestQueryAutoTest"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T); -+ -+ if (u4QueryBufferLen != sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T)) { -+ DBGLOG(OID, ERROR, "Invalid data. QueryBufferLen: %u.\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prRfATInfo = (P_PARAM_MTK_WIFI_TEST_STRUCT_T) pvQueryBuffer; -+ rStatus = rftestQueryATInfo(prAdapter, -+ prRfATInfo->u4FuncIndex, prRfATInfo->u4FuncData, pvQueryBuffer, u4QueryBufferLen); -+ -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Set RF test parameter -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_ADAPTER_NOT_READY -+* \return WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidRftestSetAutoTest(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_MTK_WIFI_TEST_STRUCT_T prRfATInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidRftestSetAutoTest"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T); -+ -+ if (u4SetBufferLen != sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T)) { -+ DBGLOG(OID, ERROR, "Invalid data. SetBufferLen: %u.\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prRfATInfo = (P_PARAM_MTK_WIFI_TEST_STRUCT_T) pvSetBuffer; -+ rStatus = rftestSetATInfo(prAdapter, prRfATInfo->u4FuncIndex, prRfATInfo->u4FuncData); -+ -+ return rStatus; -+} -+ -+/* RF test OID set handler */ -+WLAN_STATUS rftestSetATInfo(IN P_ADAPTER_T prAdapter, UINT_32 u4FuncIndex, UINT_32 u4FuncData) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_CMD_TEST_CTRL_T pCmdTestCtrl; -+ UINT_8 ucCmdSeqNum; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T))); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_TEST_MODE; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_TEST_CTRL_T); -+ prCmdInfo->pvInformationBuffer = NULL; -+ prCmdInfo->u4InformationBufferLength = 0; -+ -+ /* Setup WIFI_CMD_T (payload = CMD_TEST_CTRL_T) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ pCmdTestCtrl = (P_CMD_TEST_CTRL_T) (prWifiCmd->aucBuffer); -+ pCmdTestCtrl->ucAction = 1; /* Set ATInfo */ -+ pCmdTestCtrl->u.rRfATInfo.u4FuncIndex = u4FuncIndex; -+ pCmdTestCtrl->u.rRfATInfo.u4FuncData = u4FuncData; -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prAdapter->prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+} -+ -+WLAN_STATUS -+rftestQueryATInfo(IN P_ADAPTER_T prAdapter, -+ UINT_32 u4FuncIndex, UINT_32 u4FuncData, OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_CMD_TEST_CTRL_T pCmdTestCtrl; -+ UINT_8 ucCmdSeqNum; -+ P_EVENT_TEST_STATUS prTestStatus; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (u4FuncIndex == RF_AT_FUNCID_FW_INFO) { -+ /* driver implementation */ -+ prTestStatus = (P_EVENT_TEST_STATUS) pvQueryBuffer; -+ -+ prTestStatus->rATInfo.u4FuncData = -+ (prAdapter->rVerInfo.u2FwProductID << 16) | (prAdapter->rVerInfo.u2FwOwnVersion); -+ u4QueryBufferLen = sizeof(EVENT_TEST_STATUS); -+ -+ return WLAN_STATUS_SUCCESS; -+ } else if (u4FuncIndex == RF_AT_FUNCID_DRV_INFO) { -+ /* driver implementation */ -+ prTestStatus = (P_EVENT_TEST_STATUS) pvQueryBuffer; -+ -+ prTestStatus->rATInfo.u4FuncData = CFG_DRV_OWN_VERSION; -+ u4QueryBufferLen = sizeof(EVENT_TEST_STATUS); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T))); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventQueryRfTestATInfo; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_TEST_MODE; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = TRUE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_TEST_CTRL_T); -+ prCmdInfo->pvInformationBuffer = pvQueryBuffer; -+ prCmdInfo->u4InformationBufferLength = u4QueryBufferLen; -+ -+ /* Setup WIFI_CMD_T (payload = CMD_TEST_CTRL_T) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ pCmdTestCtrl = (P_CMD_TEST_CTRL_T) (prWifiCmd->aucBuffer); -+ pCmdTestCtrl->ucAction = 2; /* Get ATInfo */ -+ pCmdTestCtrl->u.rRfATInfo.u4FuncIndex = u4FuncIndex; -+ pCmdTestCtrl->u.rRfATInfo.u4FuncData = u4FuncData; -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prAdapter->prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+} -+ -+WLAN_STATUS rftestSetFrequency(IN P_ADAPTER_T prAdapter, IN UINT_32 u4FreqInKHz, IN PUINT_32 pu4SetInfoLen) -+{ -+ CMD_TEST_CTRL_T rCmdTestCtrl; -+ -+ ASSERT(prAdapter); -+ -+ rCmdTestCtrl.ucAction = 5; /* Set Channel Frequency */ -+ rCmdTestCtrl.u.u4ChannelFreq = u4FreqInKHz; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_TEST_MODE, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, sizeof(CMD_TEST_CTRL_T), (PUINT_8) &rCmdTestCtrl, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command packet generation utility -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] ucCID Command ID -+* \param[in] fgSetQuery Set or Query -+* \param[in] fgNeedResp Need for response -+* \param[in] pfCmdDoneHandler Function pointer when command is done -+* \param[in] u4SetQueryInfoLen The length of the set/query buffer -+* \param[in] pucInfoBuffer Pointer to set/query buffer -+* -+* -+* \retval WLAN_STATUS_PENDING -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanSendSetQueryCmd(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucCID, -+ BOOLEAN fgSetQuery, -+ BOOLEAN fgNeedResp, -+ BOOLEAN fgIsOid, -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ UINT_32 u4SetQueryInfoLen, -+ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_8 ucCmdSeqNum; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen)); -+ -+ DEBUGFUNC("wlanSendSetQueryCmd"); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(OID, TRACE, "ucCmdSeqNum =%d, ucCID =%d\n", ucCmdSeqNum, ucCID); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen); -+ prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; -+ prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; -+ prCmdInfo->fgIsOid = fgIsOid; -+ prCmdInfo->ucCID = ucCID; -+ prCmdInfo->fgSetQuery = fgSetQuery; -+ prCmdInfo->fgNeedResp = fgNeedResp; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; -+ prCmdInfo->pvInformationBuffer = pvSetQueryBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen; -+ -+ /* Setup WIFI_CMD_T (no payload) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) -+ kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen); -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ return WLAN_STATUS_PENDING; -+} -+ -+#if CFG_SUPPORT_WAPI -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by WAPI ui to set wapi mode, which is needed to info the the driver -+* to operation at WAPI mode while driver initialize. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetWapiMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ DEBUGFUNC("wlanoidSetWapiMode"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ ASSERT(pvSetBuffer); -+ -+ /* Todo:: For support WAPI and Wi-Fi at same driver, use the set wapi assoc ie at the check point */ -+ /* The Adapter Connection setting fgUseWapi will cleat whil oid set mode (infra), */ -+ /* And set fgUseWapi True while set wapi assoc ie */ -+ /* policay selection, add key all depend on this flag, */ -+ /* The fgUseWapi may remove later */ -+ if (*(PUINT_32) pvSetBuffer) -+ prAdapter->fgUseWapi = TRUE; -+ else -+ prAdapter->fgUseWapi = FALSE; -+ -+#if 0 -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + 4)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + 4; -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = NULL; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_WAPI_MODE; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetBufferLen; -+ prCmdInfo->pvInformationBuffer = pvSetBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ cp = (PUINT_8) (prWifiCmd->aucBuffer); -+ -+ kalMemCopy(cp, (PUINT_8) pvSetBuffer, 4); -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+#else -+ return WLAN_STATUS_SUCCESS; -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by WAPI to set the assoc info, which is needed to add to -+* Association request frame while join WAPI AP. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetWapiAssocInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_WAPI_INFO_ELEM_T prWapiInfo; -+ PUINT_8 cp; -+ UINT_16 u2AuthSuiteCount = 0; -+ UINT_16 u2PairSuiteCount = 0; -+ UINT_32 u4AuthKeyMgtSuite = 0; -+ UINT_32 u4PairSuite = 0; -+ UINT_32 u4GroupSuite = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ DEBUGFUNC("wlanoidSetWapiAssocInfo"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ if (u4SetBufferLen < 20 /* From EID to Group cipher */) { -+ prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; -+ DBGLOG(SEC, INFO, "fgWapiMode = FALSE due to u4SetBufferLen %u < 20!\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prAdapter->rWifiVar.rConnSettings.fgWapiMode = TRUE; -+ -+ /* if (prWapiInfo->ucElemId != ELEM_ID_WAPI) */ -+ /* DBGLOG(SEC, TRACE, ("Not WAPI IE ?!\n")); */ -+ -+ /* if (prWapiInfo->ucLength < 18) */ -+ /* return WLAN_STATUS_INVALID_LENGTH; */ -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ prWapiInfo = (P_WAPI_INFO_ELEM_T) pvSetBuffer; -+ -+ if (prWapiInfo->ucElemId != ELEM_ID_WAPI) { -+ DBGLOG(SEC, INFO, "Not WAPI IE ?! u4SetBufferLen = %u\n", u4SetBufferLen); -+ prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ if (prWapiInfo->ucLength < 18) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ /* Skip Version check */ -+ cp = (PUINT_8) &prWapiInfo->u2AuthKeyMgtSuiteCount; -+ -+ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); -+ -+ if (u2AuthSuiteCount > 1) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ cp = (PUINT_8) &prWapiInfo->aucAuthKeyMgtSuite1[0]; -+ WLAN_GET_FIELD_32(cp, &u4AuthKeyMgtSuite); -+ -+ DBGLOG(SEC, TRACE, "WAPI: Assoc Info auth mgt suite [%d]: %02x-%02x-%02x-%02x\n", -+ u2AuthSuiteCount, -+ (UCHAR) (u4AuthKeyMgtSuite & 0x000000FF), -+ (UCHAR) ((u4AuthKeyMgtSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4AuthKeyMgtSuite >> 16) & 0x000000FF), -+ (UCHAR) ((u4AuthKeyMgtSuite >> 24) & 0x000000FF)); -+ -+ if (u4AuthKeyMgtSuite != WAPI_AKM_SUITE_802_1X && u4AuthKeyMgtSuite != WAPI_AKM_SUITE_PSK) -+ ASSERT(FALSE); -+ -+ cp += 4; -+ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); -+ if (u2PairSuiteCount > 1) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ cp += 2; -+ WLAN_GET_FIELD_32(cp, &u4PairSuite); -+ DBGLOG(SEC, TRACE, "WAPI: Assoc Info pairwise cipher suite [%d]: %02x-%02x-%02x-%02x\n", -+ u2PairSuiteCount, -+ (UCHAR) (u4PairSuite & 0x000000FF), -+ (UCHAR) ((u4PairSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4PairSuite >> 16) & 0x000000FF), (UCHAR) ((u4PairSuite >> 24) & 0x000000FF)); -+ -+ if (u4PairSuite != WAPI_CIPHER_SUITE_WPI) -+ ASSERT(FALSE); -+ -+ cp += 4; -+ WLAN_GET_FIELD_32(cp, &u4GroupSuite); -+ DBGLOG(SEC, TRACE, "WAPI: Assoc Info group cipher suite : %02x-%02x-%02x-%02x\n", -+ (UCHAR) (u4GroupSuite & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); -+ -+ if (u4GroupSuite != WAPI_CIPHER_SUITE_WPI) -+ ASSERT(FALSE); -+ -+ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedAKMSuite = u4AuthKeyMgtSuite; -+ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedPairwiseCipher = u4PairSuite; -+ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedGroupCipher = u4GroupSuite; -+ -+ kalMemCopy(prAdapter->prGlueInfo->aucWapiAssocInfoIEs, pvSetBuffer, u4SetBufferLen); -+ prAdapter->prGlueInfo->u2WapiAssocInfoIESz = (UINT_16) u4SetBufferLen; -+ DBGLOG(SEC, TRACE, "Assoc Info IE sz %u\n", u4SetBufferLen); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the wpi key to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer P_PARAM_WPI_KEY, which is set by NDIS, is unpacked. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetWapiKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_PARAM_WPI_KEY_T prNewKey; -+ P_CMD_802_11_KEY prCmdKey; -+ PUINT_8 pc; -+ UINT_8 ucCmdSeqNum; -+ -+ DEBUGFUNC("wlanoidSetWapiKey"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\r\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ prNewKey = (P_PARAM_WPI_KEY_T) pvSetBuffer; -+ -+ DBGLOG_MEM8(OID, TRACE, (PUINT_8) pvSetBuffer, 560); -+ pc = (PUINT_8) pvSetBuffer; -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ /* Exception check */ -+ if (prNewKey->ucKeyID != 0x1 || prNewKey->ucKeyID != 0x0) { -+ prNewKey->ucKeyID = prNewKey->ucKeyID & BIT(0); -+ /* DBGLOG(SEC, INFO, ("Invalid WAPI key ID (%d)\r\n", prNewKey->ucKeyID)); */ -+ } -+ -+ /* Dump P_PARAM_WPI_KEY_T content. */ -+ DBGLOG(OID, TRACE, "Set: Dump P_PARAM_WPI_KEY_T content\r\n"); -+ DBGLOG(OID, TRACE, "TYPE : %d\r\n", prNewKey->eKeyType); -+ DBGLOG(OID, TRACE, "Direction : %d\r\n", prNewKey->eDirection); -+ DBGLOG(OID, TRACE, "KeyID : %d\r\n", prNewKey->ucKeyID); -+ DBGLOG(OID, TRACE, "AddressIndex:\r\n"); -+ DBGLOG_MEM8(OID, TRACE, prNewKey->aucAddrIndex, 12); -+ prNewKey->u4LenWPIEK = 16; -+ -+ DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucWPIEK, (UINT_8) prNewKey->u4LenWPIEK); -+ prNewKey->u4LenWPICK = 16; -+ -+ DBGLOG(OID, TRACE, "CK Key(%d):\r\n", (UINT_8) prNewKey->u4LenWPICK); -+ DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucWPICK, (UINT_8) prNewKey->u4LenWPICK); -+ DBGLOG(OID, TRACE, "PN:\r\n"); -+ if (prNewKey->eKeyType == 0) { -+ prNewKey->aucPN[0] = 0x5c; -+ prNewKey->aucPN[1] = 0x36; -+ prNewKey->aucPN[2] = 0x5c; -+ prNewKey->aucPN[3] = 0x36; -+ prNewKey->aucPN[4] = 0x5c; -+ prNewKey->aucPN[5] = 0x36; -+ prNewKey->aucPN[6] = 0x5c; -+ prNewKey->aucPN[7] = 0x36; -+ prNewKey->aucPN[8] = 0x5c; -+ prNewKey->aucPN[9] = 0x36; -+ prNewKey->aucPN[10] = 0x5c; -+ prNewKey->aucPN[11] = 0x36; -+ prNewKey->aucPN[12] = 0x5c; -+ prNewKey->aucPN[13] = 0x36; -+ prNewKey->aucPN[14] = 0x5c; -+ prNewKey->aucPN[15] = 0x36; -+ } -+ -+ DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucPN, 16); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetBufferLen)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_ID_ADD_REMOVE_KEY cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetBufferLen; -+ prCmdInfo->pvInformationBuffer = pvSetBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); -+ -+ kalMemZero(prCmdKey, sizeof(CMD_802_11_KEY)); -+ -+ prCmdKey->ucAddRemove = 1; /* Add */ -+ -+ if (prNewKey->eKeyType == ENUM_WPI_PAIRWISE_KEY) { -+ prCmdKey->ucTxKey = 1; -+ prCmdKey->ucKeyType = 1; -+ } -+ -+ kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prNewKey->aucAddrIndex, MAC_ADDR_LEN); -+ -+ prCmdKey->ucNetType = 0; /* AIS */ -+ -+ prCmdKey->ucKeyId = prNewKey->ucKeyID; -+ -+ prCmdKey->ucKeyLen = 32; -+ -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WPI; -+ -+ kalMemCopy(prCmdKey->aucKeyMaterial, (PUINT_8) prNewKey->aucWPIEK, 16); -+ -+ kalMemCopy(prCmdKey->aucKeyMaterial + 16, (PUINT_8) prNewKey->aucWPICK, 16); -+ -+ kalMemCopy(prCmdKey->aucKeyRsc, (PUINT_8) prNewKey->aucPN, 16); -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+} /* wlanoidSetAddKey */ -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by WSC to set the assoc info, which is needed to add to -+* Association request frame while join WPS AP. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetWSCAssocInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ DEBUGFUNC("wlanoidSetWSCAssocInfo"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ if (u4SetBufferLen == 0) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ kalMemCopy(prAdapter->prGlueInfo->aucWSCAssocInfoIE, pvSetBuffer, u4SetBufferLen); -+ prAdapter->prGlueInfo->u2WSCAssocInfoIELen = (UINT_16) u4SetBufferLen; -+ DBGLOG(SEC, TRACE, "Assoc Info IE sz %u\n", u4SetBufferLen); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} -+#endif -+ -+#if CFG_ENABLE_WAKEUP_ON_LAN -+WLAN_STATUS -+wlanoidSetAddWakeupPattern(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_PM_PACKET_PATTERN prPacketPattern; -+ -+ DEBUGFUNC("wlanoidSetAddWakeupPattern"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_PM_PACKET_PATTERN); -+ -+ if (u4SetBufferLen < sizeof(PARAM_PM_PACKET_PATTERN)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prPacketPattern = (P_PARAM_PM_PACKET_PATTERN) pvSetBuffer; -+ -+ /* FIXME: -+ * Send the struct to firmware */ -+ -+ return WLAN_STATUS_FAILURE; -+} -+ -+WLAN_STATUS -+wlanoidSetRemoveWakeupPattern(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_PM_PACKET_PATTERN prPacketPattern; -+ -+ DEBUGFUNC("wlanoidSetAddWakeupPattern"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_PM_PACKET_PATTERN); -+ -+ if (u4SetBufferLen < sizeof(PARAM_PM_PACKET_PATTERN)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prPacketPattern = (P_PARAM_PM_PACKET_PATTERN) pvSetBuffer; -+ -+ /* FIXME: -+ * Send the struct to firmware */ -+ -+ return WLAN_STATUS_FAILURE; -+} -+ -+WLAN_STATUS -+wlanoidQueryEnableWakeup(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ PUINT_32 pu4WakeupEventEnable; -+ -+ DEBUGFUNC("wlanoidQueryEnableWakeup"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ pu4WakeupEventEnable = (PUINT_32) pvQueryBuffer; -+ -+ *pu4WakeupEventEnable = prAdapter->u4WakeupEventEnable; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS -+wlanoidSetEnableWakeup(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_32 pu4WakeupEventEnable; -+ -+ DEBUGFUNC("wlanoidSetEnableWakup"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ pu4WakeupEventEnable = (PUINT_32) pvSetBuffer; -+ prAdapter->u4WakeupEventEnable = *pu4WakeupEventEnable; -+ -+ /* FIXME: -+ * Send Command Event for setting wakeup-pattern / Magic Packet to firmware -+ * */ -+ -+ return WLAN_STATUS_FAILURE; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to configure PS related settings for WMM-PS test. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetWiFiWmmPsTest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T prWmmPsTestInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ CMD_SET_WMM_PS_TEST_STRUCT_T rSetWmmPsTestParam; -+ UINT_16 u2CmdBufLen; -+ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ DEBUGFUNC("wlanoidSetWiFiWmmPsTest"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T); -+ -+ prWmmPsTestInfo = (P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T) pvSetBuffer; -+ -+ rSetWmmPsTestParam.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ rSetWmmPsTestParam.bmfgApsdEnAc = prWmmPsTestInfo->bmfgApsdEnAc; -+ rSetWmmPsTestParam.ucIsEnterPsAtOnce = prWmmPsTestInfo->ucIsEnterPsAtOnce; -+ rSetWmmPsTestParam.ucIsDisableUcTrigger = prWmmPsTestInfo->ucIsDisableUcTrigger; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[rSetWmmPsTestParam.ucNetTypeIndex]); -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ prPmProfSetupInfo->ucBmpDeliveryAC = (rSetWmmPsTestParam.bmfgApsdEnAc >> 4) & BITS(0, 3); -+ prPmProfSetupInfo->ucBmpTriggerAC = rSetWmmPsTestParam.bmfgApsdEnAc & BITS(0, 3); -+ -+ u2CmdBufLen = sizeof(CMD_SET_WMM_PS_TEST_STRUCT_T); -+ -+#if 0 -+ /* it will apply the disable trig or not immediately */ -+ if (prPmInfo->ucWmmPsDisableUcPoll && prPmInfo->ucWmmPsConnWithTrig) -+ ; /* NIC_PM_WMM_PS_DISABLE_UC_TRIG(prAdapter, TRUE); */ -+ else -+ ; /* NIC_PM_WMM_PS_DISABLE_UC_TRIG(prAdapter, FALSE); */ -+#endif -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, CMD_ID_SET_WMM_PS_TEST_PARMS, TRUE, FALSE, TRUE, NULL, /* TODO? */ -+ NULL, u2CmdBufLen, (PUINT_8) &rSetWmmPsTestParam, NULL, 0); -+ -+ return rStatus; -+} /* wlanoidSetWiFiWmmPsTest */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to configure enable/disable TX A-MPDU feature. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetTxAmpdu(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ CMD_TX_AMPDU_T rTxAmpdu; -+ UINT_16 u2CmdBufLen; -+ PBOOLEAN pfgEnable; -+ -+ DEBUGFUNC("wlanoidSetTxAmpdu"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(BOOLEAN); -+ -+ pfgEnable = (PBOOLEAN) pvSetBuffer; -+ -+ rTxAmpdu.fgEnable = *pfgEnable; -+ -+ u2CmdBufLen = sizeof(CMD_TX_AMPDU_T); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_TX_AMPDU, -+ TRUE, FALSE, TRUE, NULL, NULL, u2CmdBufLen, (PUINT_8) &rTxAmpdu, NULL, 0); -+ -+ return rStatus; -+} /* wlanoidSetTxAmpdu */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to configure reject/accept ADDBA Request. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAddbaReject(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ CMD_ADDBA_REJECT_T rAddbaReject; -+ UINT_16 u2CmdBufLen; -+ PBOOLEAN pfgEnable; -+ -+ DEBUGFUNC("wlanoidSetAddbaReject"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(BOOLEAN); -+ -+ pfgEnable = (PBOOLEAN) pvSetBuffer; -+ -+ rAddbaReject.fgEnable = *pfgEnable; -+ -+ u2CmdBufLen = sizeof(CMD_ADDBA_REJECT_T); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ADDBA_REJECT, -+ TRUE, FALSE, TRUE, NULL, NULL, u2CmdBufLen, (PUINT_8) &rAddbaReject, NULL, 0); -+ -+ return rStatus; -+} /* wlanoidSetAddbaReject */ -+ -+#if CFG_SLT_SUPPORT -+ -+WLAN_STATUS -+wlanoidQuerySLTStatus(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_PARAM_MTK_SLT_TEST_STRUCT_T prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) NULL; -+ P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL; -+ -+ DEBUGFUNC("wlanoidQuerySLTStatus"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_MTK_SLT_TEST_STRUCT_T); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_MTK_SLT_TEST_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvQueryBuffer); -+ -+ prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) pvQueryBuffer; -+ -+ prSltInfo = &(prAdapter->rWifiVar.rSltInfo); -+ -+ switch (prMtkSltInfo->rSltFuncIdx) { -+ case ENUM_MTK_SLT_FUNC_LP_SET: -+ { -+ P_PARAM_MTK_SLT_LP_TEST_STRUCT_T prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) NULL; -+ -+ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_LP_TEST_STRUCT_T)); -+ -+ prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; -+ -+ prLpSetting->u4BcnRcvNum = prSltInfo->u4BeaconReceiveCnt; -+ } -+ break; -+ default: -+ /* TBD... */ -+ break; -+ } -+ -+ return rWlanStatus; -+} /* wlanoidQuerySLTStatus */ -+ -+WLAN_STATUS -+wlanoidUpdateSLTMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_PARAM_MTK_SLT_TEST_STRUCT_T prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) NULL; -+ P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL; -+ -+ /* 1. Action: Update or Initial Set -+ * 2. Role. -+ * 3. Target MAC address. -+ * 4. RF BW & Rate Settings -+ */ -+ -+ DEBUGFUNC("wlanoidUpdateSLTMode"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_MTK_SLT_TEST_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_MTK_SLT_TEST_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) pvSetBuffer; -+ -+ prSltInfo = &(prAdapter->rWifiVar.rSltInfo); -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ -+ switch (prMtkSltInfo->rSltFuncIdx) { -+ case ENUM_MTK_SLT_FUNC_INITIAL: /* Initialize */ -+ { -+ P_PARAM_MTK_SLT_INITIAL_STRUCT_T prMtkSltInit = (P_PARAM_MTK_SLT_INITIAL_STRUCT_T) NULL; -+ -+ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_INITIAL_STRUCT_T)); -+ -+ prMtkSltInit = (P_PARAM_MTK_SLT_INITIAL_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; -+ -+ if (prSltInfo->prPseudoStaRec != NULL) { -+ /* The driver has been initialized. */ -+ prSltInfo->prPseudoStaRec = NULL; -+ } -+ -+ prSltInfo->prPseudoBssDesc = scanSearchExistingBssDesc(prAdapter, -+ BSS_TYPE_IBSS, -+ prMtkSltInit->aucTargetMacAddr, -+ prMtkSltInit->aucTargetMacAddr); -+ -+ prSltInfo->u2SiteID = prMtkSltInit->u2SiteID; -+ -+ /* Bandwidth 2.4G: Channel 1~14 -+ * Bandwidth 5G: *36, 40, 44, 48, 52, 56, 60, 64, -+ * *100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, -+ * 149, 153, *157, 161, -+ * 184, 188, 192, 196, 200, 204, 208, 212, *216 -+ */ -+ prSltInfo->ucChannel2G4 = 1 + (prSltInfo->u2SiteID % 4) * 5; -+ -+ switch (prSltInfo->ucChannel2G4) { -+ case 1: -+ prSltInfo->ucChannel5G = 36; -+ break; -+ case 6: -+ prSltInfo->ucChannel5G = 52; -+ break; -+ case 11: -+ prSltInfo->ucChannel5G = 104; -+ break; -+ case 16: -+ prSltInfo->ucChannel2G4 = 14; -+ prSltInfo->ucChannel5G = 161; -+ break; -+ default: -+ ASSERT(FALSE); -+ } -+ -+ if (prSltInfo->prPseudoBssDesc == NULL) { -+ do { -+ prSltInfo->prPseudoBssDesc = scanAllocateBssDesc(prAdapter); -+ -+ if (prSltInfo->prPseudoBssDesc == NULL) { -+ rWlanStatus = WLAN_STATUS_FAILURE; -+ break; -+ } -+ prBssDesc = prSltInfo->prPseudoBssDesc; -+ } while (FALSE); -+ } else { -+ prBssDesc = prSltInfo->prPseudoBssDesc; -+ } -+ -+ if (prBssDesc) { -+ prBssDesc->eBSSType = BSS_TYPE_IBSS; -+ -+ COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prMtkSltInit->aucTargetMacAddr); -+ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr); -+ -+ prBssDesc->u2BeaconInterval = 100; -+ prBssDesc->u2ATIMWindow = 0; -+ prBssDesc->ucDTIMPeriod = 1; -+ -+ prBssDesc->u2IELength = 0; -+ -+ prBssDesc->fgIsERPPresent = TRUE; -+ prBssDesc->fgIsHTPresent = TRUE; -+ -+ prBssDesc->u2OperationalRateSet = BIT(RATE_36M_INDEX); -+ prBssDesc->u2BSSBasicRateSet = BIT(RATE_36M_INDEX); -+ prBssDesc->fgIsUnknownBssBasicRate = FALSE; -+ -+ prBssDesc->fgIsLargerTSF = TRUE; -+ -+ prBssDesc->eBand = BAND_2G4; -+ -+ prBssDesc->ucChannelNum = prSltInfo->ucChannel2G4; -+ -+ prBssDesc->ucPhyTypeSet = PHY_TYPE_SET_802_11ABGN; -+ -+ GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime); -+ } -+ } -+ break; -+ case ENUM_MTK_SLT_FUNC_RATE_SET: /* Update RF Settings. */ -+ if (prSltInfo->prPseudoStaRec == NULL) { -+ rWlanStatus = WLAN_STATUS_FAILURE; -+ break; -+ } -+ -+ P_PARAM_MTK_SLT_TR_TEST_STRUCT_T prTRSetting = (P_PARAM_MTK_SLT_TR_TEST_STRUCT_T) NULL; -+ -+ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_TR_TEST_STRUCT_T)); -+ -+ prStaRec = prSltInfo->prPseudoStaRec; -+ prTRSetting = (P_PARAM_MTK_SLT_TR_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; -+ -+ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) { -+ prBssInfo->eBand = BAND_5G; -+ prBssInfo->ucPrimaryChannel = prSltInfo->ucChannel5G; -+ } -+ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM24) { -+ prBssInfo->eBand = BAND_2G4; -+ prBssInfo->ucPrimaryChannel = prSltInfo->ucChannel2G4; -+ } -+ -+ if ((prTRSetting->u4FixedRate & FIXED_BW_DL40) != 0) { -+ /* RF 40 */ -+ /* It would controls RFBW capability in WTBL. */ -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ /* This controls RF BW, RF BW would be 40 only if */ -+ /* 1. PHY_TYPE_BIT_HT is TRUE. */ -+ /* 2. SCO is SCA/SCB. */ -+ prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ -+ /* U20/L20 Control. */ -+ switch (prTRSetting->u4FixedRate & 0xC000) { -+ case FIXED_EXT_CHNL_U20: -+ prBssInfo->eBssSCO = CHNL_EXT_SCB; /* +2 */ -+ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) -+ prBssInfo->ucPrimaryChannel += 2; -+ else { -+ /* For channel 1, testing L20 at channel 8. */ -+ if (prBssInfo->ucPrimaryChannel < 5) -+ prBssInfo->ucPrimaryChannel = 8; -+ } -+ break; -+ case FIXED_EXT_CHNL_L20: -+ default: /* 40M */ -+ prBssInfo->eBssSCO = CHNL_EXT_SCA; /* -2 */ -+ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) { -+ prBssInfo->ucPrimaryChannel -= 2; -+ } else { -+ /* For channel 11 / 14. testing U20 at channel 3. */ -+ if (prBssInfo->ucPrimaryChannel > 10) -+ prBssInfo->ucPrimaryChannel = 3; -+ } -+ break; -+ } -+ } else { -+ /* RF 20 */ -+ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; -+ prBssInfo->eBssSCO = CHNL_EXT_SCN; -+ } -+ -+ prBssInfo->fgErpProtectMode = FALSE; -+ prBssInfo->eHtProtectMode = HT_PROTECT_MODE_NONE; -+ prBssInfo->eGfOperationMode = GF_MODE_NORMAL; -+ -+ nicUpdateBss(prAdapter, prBssInfo->ucNetTypeIndex); -+ -+ prStaRec->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); -+ -+ switch (prTRSetting->u4FixedRate & 0xFF) { -+ case RATE_OFDM_54M: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_54M_INDEX); -+ break; -+ case RATE_OFDM_48M: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_48M_INDEX); -+ break; -+ case RATE_OFDM_36M: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_36M_INDEX); -+ break; -+ case RATE_OFDM_24M: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_24M_INDEX); -+ break; -+ case RATE_OFDM_6M: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_6M_INDEX); -+ break; -+ case RATE_CCK_11M_LONG: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_11M_INDEX); -+ break; -+ case RATE_CCK_1M_LONG: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_1M_INDEX); -+ break; -+ case RATE_GF_MCS_0: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX); -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; -+ break; -+ case RATE_MM_MCS_7: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX); -+ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_HT_GF; -+#if 0 /* Only for Current Measurement Mode. */ -+ prStaRec->u2HtCapInfo |= (HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); -+#endif -+ break; -+ case RATE_GF_MCS_7: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX); -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; -+ break; -+ default: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_36M_INDEX); -+ break; -+ } -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+ break; -+ case ENUM_MTK_SLT_FUNC_LP_SET: /* Reset LP Test Result. */ -+ { -+ P_PARAM_MTK_SLT_LP_TEST_STRUCT_T prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) NULL; -+ -+ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_LP_TEST_STRUCT_T)); -+ -+ prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; -+ -+ if (prSltInfo->prPseudoBssDesc == NULL) { -+ /* Please initial SLT Mode first. */ -+ break; -+ } -+ prBssDesc = prSltInfo->prPseudoBssDesc; -+ -+ switch (prLpSetting->rLpTestMode) { -+ case ENUM_MTK_LP_TEST_NORMAL: -+ /* In normal mode, we would use target MAC address to be the BSSID. */ -+ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr); -+ prSltInfo->fgIsDUT = FALSE; -+ break; -+ case ENUM_MTK_LP_TEST_GOLDEN_SAMPLE: -+ /* 1. Lower AIFS of BCN queue. -+ * 2. Fixed Random Number tobe 0. -+ */ -+ prSltInfo->fgIsDUT = FALSE; -+ /* In LP test mode, we would use MAC address of Golden Sample to be the BSSID. */ -+ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr); -+ break; -+ case ENUM_MTK_LP_TEST_DUT: -+ /* 1. Enter Sleep Mode. -+ * 2. Fix random number a large value & enlarge AIFN of BCN queue. -+ */ -+ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssDesc->aucSrcAddr); -+ prSltInfo->u4BeaconReceiveCnt = 0; -+ prSltInfo->fgIsDUT = TRUE; -+ break; -+ } -+ -+ } -+ -+ break; -+ default: -+ break; -+ } -+ -+ return WLAN_STATUS_FAILURE; -+ -+ return rWlanStatus; -+} /* wlanoidUpdateSLTMode */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query NVRAM value. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryNvramRead(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T prNvramRwInfo; -+ UINT_16 u2Data; -+ BOOLEAN fgStatus; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidQueryNvramRead"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prNvramRwInfo = (P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T) pvQueryBuffer; -+ -+ if (prNvramRwInfo->ucEepromMethod == PARAM_EEPROM_READ_METHOD_READ) { -+ /* change to byte offset */ -+ fgStatus = kalCfgDataRead16(prAdapter->prGlueInfo, -+ prNvramRwInfo->ucEepromIndex << 1, -+ &u2Data); -+ -+ if (fgStatus) { -+ prNvramRwInfo->u2EepromData = u2Data; -+ DBGLOG(OID, INFO, "NVRAM Read: index=%#X, data=%#02X\r\n", -+ prNvramRwInfo->ucEepromIndex, u2Data); -+ } else { -+ DBGLOG(OID, ERROR, "NVRAM Read Failed: index=%#x.\r\n", prNvramRwInfo->ucEepromIndex); -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } else if (prNvramRwInfo->ucEepromMethod == PARAM_EEPROM_READ_METHOD_GETSIZE) { -+ prNvramRwInfo->u2EepromData = CFG_FILE_WIFI_REC_SIZE; -+ DBGLOG(OID, INFO, "EEPROM size =%d\r\n", prNvramRwInfo->u2EepromData); -+ } -+ -+ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); -+ -+ return rStatus; -+} /* wlanoidQueryNvramRead */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to write NVRAM value. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetNvramWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T prNvramRwInfo; -+ BOOLEAN fgStatus; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidSetNvramWrite"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prNvramRwInfo = (P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T) pvSetBuffer; -+ -+ /* change to byte offset */ -+ fgStatus = kalCfgDataWrite16(prAdapter->prGlueInfo, -+ prNvramRwInfo->ucEepromIndex << 1, -+ prNvramRwInfo->u2EepromData); -+ -+ if (fgStatus == FALSE) { -+ DBGLOG(OID, ERROR, "NVRAM Write Failed.\r\n"); -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ -+ return rStatus; -+} /* wlanoidSetNvramWrite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get the config data source type. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryCfgSrcType(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ ASSERT(prAdapter); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_CFG_SRC_TYPE_T); -+ -+ if (kalIsConfigurationExist(prAdapter->prGlueInfo) == TRUE) -+ *(P_ENUM_CFG_SRC_TYPE_T) pvQueryBuffer = CFG_SRC_TYPE_NVRAM; -+ else -+ *(P_ENUM_CFG_SRC_TYPE_T) pvQueryBuffer = CFG_SRC_TYPE_EEPROM; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get the config data source type. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryEepromType(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ ASSERT(prAdapter); -+ -+ *pu4QueryInfoLen = sizeof(P_ENUM_EEPROM_TYPE_T); -+ -+#if CFG_SUPPORT_NIC_CAPABILITY -+ if (prAdapter->fgIsEepromUsed == TRUE) -+ *(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_PRESENT; -+ else -+ *(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_NO; -+#else -+ *(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_NO; -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get the config data source type. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetCountryCode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_8 pucCountry; -+ UINT_16 u2CountryCode; -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(u4SetBufferLen == 2); -+ -+ *pu4SetInfoLen = 2; -+ -+ pucCountry = pvSetBuffer; -+ u2CountryCode = (((UINT_16) pucCountry[0]) << 8) | ((UINT_16) pucCountry[1]); -+ -+ /* previous country code == FF : ignore country code, current country code == FE : resume */ -+ if (prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup == COUNTRY_CODE_FF) { -+ if (u2CountryCode != COUNTRY_CODE_FE) { -+ DBGLOG(OID, INFO, "Skip country code cmd (0x%04x)\n", u2CountryCode); -+ return WLAN_STATUS_SUCCESS; -+ } -+ DBGLOG(OID, INFO, "Resume handle country code cmd (0x%04x)\n", u2CountryCode); -+ } -+ -+ prAdapter->rWifiVar.rConnSettings.u2CountryCode = u2CountryCode; -+ prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup = prAdapter->rWifiVar.rConnSettings.u2CountryCode; -+ DBGLOG(OID, LOUD, "u2CountryCodeBakup=0x%04x\n", prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup); -+ -+ /* Force to re-search country code in country domains */ -+ prAdapter->prDomainInfo = NULL; -+ rlmDomainSendCmd(prAdapter, TRUE); -+ -+ /* Update supported channel list in channel table based on current country domain */ -+ wlanUpdateChannelTable(prAdapter->prGlueInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if 0 -+WLAN_STATUS -+wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam; -+ CMD_CUSTOM_NOA_PARAM_STRUCT_T rCmdNoaParam; -+ -+ DEBUGFUNC("wlanoidSetNoaParam"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdNoaParam, sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T)); -+ rCmdNoaParam.u4NoaDurationMs = prNoaParam->u4NoaDurationMs; -+ rCmdNoaParam.u4NoaIntervalMs = prNoaParam->u4NoaIntervalMs; -+ rCmdNoaParam.u4NoaCount = prNoaParam->u4NoaCount; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_NOA_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen); -+} -+ -+WLAN_STATUS -+wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam; -+ CMD_CUSTOM_OPPPS_PARAM_STRUCT_T rCmdOppPsParam; -+ -+ DEBUGFUNC("wlanoidSetOppPsParam"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdOppPsParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); -+ rCmdOppPsParam.u4CTwindowMs = prOppPsParam->u4CTwindowMs; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_OPPPS_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen); -+} -+ -+WLAN_STATUS -+wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T prUapsdParam; -+ CMD_CUSTOM_UAPSD_PARAM_STRUCT_T rCmdUapsdParam; -+ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ DEBUGFUNC("wlanoidSetUApsdParam"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ -+ prUapsdParam = (P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdUapsdParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); -+ rCmdUapsdParam.fgEnAPSD = prUapsdParam->fgEnAPSD; -+ prAdapter->rWifiVar.fgSupportUAPSD = prUapsdParam->fgEnAPSD; -+ -+ rCmdUapsdParam.fgEnAPSD_AcBe = prUapsdParam->fgEnAPSD_AcBe; -+ rCmdUapsdParam.fgEnAPSD_AcBk = prUapsdParam->fgEnAPSD_AcBk; -+ rCmdUapsdParam.fgEnAPSD_AcVo = prUapsdParam->fgEnAPSD_AcVo; -+ rCmdUapsdParam.fgEnAPSD_AcVi = prUapsdParam->fgEnAPSD_AcVi; -+ prPmProfSetupInfo->ucBmpDeliveryAC = -+ ((prUapsdParam->fgEnAPSD_AcBe << 0) | -+ (prUapsdParam->fgEnAPSD_AcBk << 1) | -+ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); -+ prPmProfSetupInfo->ucBmpTriggerAC = -+ ((prUapsdParam->fgEnAPSD_AcBe << 0) | -+ (prUapsdParam->fgEnAPSD_AcBk << 1) | -+ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); -+ -+ rCmdUapsdParam.ucMaxSpLen = prUapsdParam->ucMaxSpLen; -+ prPmProfSetupInfo->ucUapsdSp = prUapsdParam->ucMaxSpLen; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_UAPSD_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen); -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set BT profile or BT information and the -+* driver will set the built-in PTA configuration into chip. -+* -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBT(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ -+ P_PTA_IPC_T prPtaIpc; -+ -+ DEBUGFUNC("wlanoidSetBT.\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PTA_IPC_T); -+ if (u4SetBufferLen != sizeof(PTA_IPC_T)) { -+ WARNLOG(("Invalid length %u\n", u4SetBufferLen)); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail to set BT profile because of ACPI_D3\n"); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pvSetBuffer); -+ prPtaIpc = (P_PTA_IPC_T) pvSetBuffer; -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG -+ DBGLOG(OID, INFO, -+ "BCM BWCS CMD: BTPParams[0]=%02x, BTPParams[1]=%02x, BTPParams[2]=%02x, BTPParams[3]=%02x.\n", -+ prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], prPtaIpc->u.aucBTPParams[2], -+ prPtaIpc->u.aucBTPParams[3]; -+ -+#endif -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_BWCS, -+ TRUE, FALSE, FALSE, NULL, NULL, sizeof(PTA_IPC_T), (PUINT_8) prPtaIpc, NULL, 0); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current BT profile and BTCR values -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBT(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+/* P_PARAM_PTA_IPC_T prPtaIpc; */ -+/* UINT_32 u4QueryBuffLen; */ -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PTA_IPC_T); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen != sizeof(PTA_IPC_T)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ ASSERT(pvQueryBuffer); -+/* prPtaIpc = (P_PTA_IPC_T)pvQueryBuffer; */ -+/* prPtaIpc->ucCmd = BT_CMD_PROFILE; */ -+/* prPtaIpc->ucLen = sizeof(prPtaIpc->u); */ -+/* nicPtaGetProfile(prAdapter, (PUINT_8)&prPtaIpc->u, &u4QueryBuffLen); */ -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if 0 -+WLAN_STATUS -+wlanoidQueryBtSingleAntenna(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PTA_INFO_T prPtaInfo; -+ PUINT_32 pu4SingleAntenna; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen != sizeof(UINT_32)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ ASSERT(pvQueryBuffer); -+ -+ prPtaInfo = &prAdapter->rPtaInfo; -+ pu4SingleAntenna = (PUINT_32) pvQueryBuffer; -+ -+ if (prPtaInfo->fgSingleAntenna) { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Q Single Ant = 1\r\n")); */ -+ *pu4SingleAntenna = 1; -+ } else { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Q Single Ant = 0\r\n")); */ -+ *pu4SingleAntenna = 0; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS -+wlanoidSetBtSingleAntenna(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ -+ PUINT_32 pu4SingleAntenna; -+ UINT_32 u4SingleAntenna; -+ P_PTA_INFO_T prPtaInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ prPtaInfo = &prAdapter->rPtaInfo; -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ if (u4SetBufferLen != sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ if (IS_ARB_IN_RFTEST_STATE(prAdapter)) -+ return WLAN_STATUS_SUCCESS; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail to set antenna because of ACPI_D3\n"); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pvSetBuffer); -+ pu4SingleAntenna = (PUINT_32) pvSetBuffer; -+ u4SingleAntenna = *pu4SingleAntenna; -+ -+ if (u4SingleAntenna == 0) { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Single Ant = 0\r\n")); */ -+ prPtaInfo->fgSingleAntenna = FALSE; -+ } else { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Single Ant = 1\r\n")); */ -+ prPtaInfo->fgSingleAntenna = TRUE; -+ } -+ ptaFsmRunEventSetConfig(prAdapter, &prPtaInfo->rPtaParam); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+WLAN_STATUS -+wlanoidQueryPta(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PTA_INFO_T prPtaInfo; -+ PUINT_32 pu4Pta; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen != sizeof(UINT_32)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ ASSERT(pvQueryBuffer); -+ -+ prPtaInfo = &prAdapter->rPtaInfo; -+ pu4Pta = (PUINT_32) pvQueryBuffer; -+ -+ if (prPtaInfo->fgEnabled) { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"PTA = 1\r\n")); */ -+ *pu4Pta = 1; -+ } else { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"PTA = 0\r\n")); */ -+ *pu4Pta = 0; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS -+wlanoidSetPta(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_32 pu4PtaCtrl; -+ UINT_32 u4PtaCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ if (u4SetBufferLen != sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ if (IS_ARB_IN_RFTEST_STATE(prAdapter)) -+ return WLAN_STATUS_SUCCESS; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail to set BT setting because of ACPI_D3\n"); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pvSetBuffer); -+ pu4PtaCtrl = (PUINT_32) pvSetBuffer; -+ u4PtaCtrl = *pu4PtaCtrl; -+ -+ if (u4PtaCtrl == 0) { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Pta= 0\r\n")); */ -+ nicPtaSetFunc(prAdapter, FALSE); -+ } else { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Pta= 1\r\n")); */ -+ nicPtaSetFunc(prAdapter, TRUE); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+#endif -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set Tx power profile. -+* -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetTxPower(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ /* P_SET_TXPWR_CTRL_T pTxPwr = (P_SET_TXPWR_CTRL_T)pvSetBuffer; */ -+ /* UINT_32 i; */ -+ WLAN_STATUS rStatus; -+ -+ DEBUGFUNC("wlanoidSetTxPower"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ -+#if 0 -+ DBGLOG(OID, INFO, "c2GLegacyStaPwrOffset=%d\n", pTxPwr->c2GLegacyStaPwrOffset); -+ DBGLOG(OID, INFO, "c2GHotspotPwrOffset=%d\n", pTxPwr->c2GHotspotPwrOffset); -+ DBGLOG(OID, INFO, "c2GP2pPwrOffset=%d\n", pTxPwr->c2GP2pPwrOffset); -+ DBGLOG(OID, INFO, "c2GBowPwrOffset=%d\n", pTxPwr->c2GBowPwrOffset); -+ DBGLOG(OID, INFO, "c5GLegacyStaPwrOffset=%d\n", pTxPwr->c5GLegacyStaPwrOffset); -+ DBGLOG(OID, INFO, "c5GHotspotPwrOffset=%d\n", pTxPwr->c5GHotspotPwrOffset); -+ DBGLOG(OID, INFO, "c5GP2pPwrOffset=%d\n", pTxPwr->c5GP2pPwrOffset); -+ DBGLOG(OID, INFO, "c5GBowPwrOffset=%d\n", pTxPwr->c5GBowPwrOffset); -+ DBGLOG(OID, INFO, "ucConcurrencePolicy=%d\n", pTxPwr->ucConcurrencePolicy); -+ -+ for (i = 0; i < 14; i++) -+ DBGLOG(OID, INFO, "acTxPwrLimit2G[%d]=%d\n", i, pTxPwr->acTxPwrLimit2G[i]); -+ -+ for (i = 0; i < 4; i++) -+ DBGLOG(OID, INFO, "acTxPwrLimit5G[%d]=%d\n", i, pTxPwr->acTxPwrLimit5G[i]); -+#endif -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_TXPWR_CTRL, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ TRUE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ u4SetBufferLen, /* u4SetQueryInfoLen */ -+ (PUINT_8) pvSetBuffer, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+ return rStatus; -+ -+} -+ -+WLAN_STATUS wlanSendMemDumpCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen) -+{ -+ P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo; -+ P_CMD_DUMP_MEM prCmdDumpMem; -+ CMD_DUMP_MEM rCmdDumpMem; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4MemSize = PARAM_MEM_DUMP_MAX_SIZE; -+ -+ UINT_32 u4RemainLeng = 0; -+ UINT_32 u4CurAddr = 0; -+ UINT_8 ucFragNum = 0; -+ -+ prCmdDumpMem = &rCmdDumpMem; -+ prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) pvQueryBuffer; -+ -+ u4RemainLeng = prMemDumpInfo->u4RemainLength; -+ u4CurAddr = prMemDumpInfo->u4Address + prMemDumpInfo->u4Length; -+ ucFragNum = prMemDumpInfo->ucFragNum + 1; -+ -+ /* Query. If request length is larger than max length, do it as ping pong. -+ * Send a command and wait for a event. Send next command while the event is received. -+ * -+ */ -+ do { -+ UINT_32 u4CurLeng = 0; -+ -+ if (u4RemainLeng > u4MemSize) { -+ u4CurLeng = u4MemSize; -+ u4RemainLeng -= u4MemSize; -+ } else { -+ u4CurLeng = u4RemainLeng; -+ u4RemainLeng = 0; -+ } -+ -+ prCmdDumpMem->u4Address = u4CurAddr; -+ prCmdDumpMem->u4Length = u4CurLeng; -+ prCmdDumpMem->u4RemainLength = u4RemainLeng; -+ prCmdDumpMem->ucFragNum = ucFragNum; -+ -+ DBGLOG(OID, TRACE, "[%d] 0x%X, len %u, remain len %u\n", -+ ucFragNum, -+ prCmdDumpMem->u4Address, prCmdDumpMem->u4Length, prCmdDumpMem->u4RemainLength); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_DUMP_MEM, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryMemDump, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_DUMP_MEM), -+ (PUINT_8) prCmdDumpMem, pvQueryBuffer, u4QueryBufferLen); -+ -+ } while (FALSE); -+ -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to dump memory. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMemDump(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo; -+ -+ DEBUGFUNC("wlanoidQueryMemDump"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) pvQueryBuffer; -+ DBGLOG(OID, TRACE, "Dump 0x%X, len %u\n", prMemDumpInfo->u4Address, prMemDumpInfo->u4Length); -+ -+ prMemDumpInfo->u4RemainLength = prMemDumpInfo->u4Length; -+ prMemDumpInfo->u4Length = 0; -+ prMemDumpInfo->ucFragNum = 0; -+ -+ return wlanSendMemDumpCmd(prAdapter, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* end of wlanoidQueryMcrRead() */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set the p2p mode. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2pMode(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS status = WLAN_STATUS_SUCCESS; -+ P_PARAM_CUSTOM_P2P_SET_STRUCT_T prSetP2P = (P_PARAM_CUSTOM_P2P_SET_STRUCT_T) NULL; -+ /* P_MSG_P2P_NETDEV_REGISTER_T prP2pNetdevRegMsg = (P_MSG_P2P_NETDEV_REGISTER_T)NULL; */ -+ DEBUGFUNC("wlanoidSetP2pMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T); -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prSetP2P = (P_PARAM_CUSTOM_P2P_SET_STRUCT_T) pvSetBuffer; -+ -+ DBGLOG(P2P, INFO, "Set P2P enable %p [%u] mode[%u]\n", prSetP2P, prSetP2P->u4Enable, prSetP2P->u4Mode); -+ -+ /* -+ * enable = 1, mode = 0 => init P2P network -+ * enable = 1, mode = 1 => init Soft AP network -+ * enable = 0 => uninit P2P/AP network -+ */ -+ -+ if (prSetP2P->u4Enable) { -+ p2pSetMode((prSetP2P->u4Mode == 1) ? TRUE : FALSE); -+ -+ if (p2pLaunch(prAdapter->prGlueInfo)) -+ ASSERT(prAdapter->fgIsP2PRegistered); -+ -+ } else { -+ DBGLOG(P2P, TRACE, "prAdapter->fgIsP2PRegistered = %d\n", prAdapter->fgIsP2PRegistered); -+ -+ if (prAdapter->fgIsP2PRegistered) { -+ DBGLOG(P2P, INFO, "p2pRemove\n"); -+ p2pRemove(prAdapter->prGlueInfo); -+ } -+ -+ } -+ -+#if 0 -+ prP2pNetdevRegMsg = (P_MSG_P2P_NETDEV_REGISTER_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, -+ (sizeof(MSG_P2P_NETDEV_REGISTER_T))); -+ -+ if (prP2pNetdevRegMsg == NULL) { -+ ASSERT(FALSE); -+ status = WLAN_STATUS_RESOURCES; -+ return status; -+ } -+ -+ prP2pNetdevRegMsg->rMsgHdr.eMsgId = MID_MNY_P2P_NET_DEV_REGISTER; -+ prP2pNetdevRegMsg->fgIsEnable = (prSetP2P->u4Enable == 1) ? TRUE : FALSE; -+ prP2pNetdevRegMsg->ucMode = (UINT_8) prSetP2P->u4Mode; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pNetdevRegMsg, MSG_SEND_METHOD_BUF); -+#endif -+ -+ return status; -+} -+#endif -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to query build date code information from firmware -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBuildDateCode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ CMD_GET_BUILD_DATE_CODE rCmdGetBuildDateCode; -+ -+ DEBUGFUNC("wlanoidQueryBuildDateCode"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_8) * 16; -+ -+ if (u4QueryBufferLen < sizeof(UINT_8) * 16) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_BUILD_DATE_CODE, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventBuildDateCode, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_GET_BUILD_DATE_CODE), -+ (PUINT_8) &rCmdGetBuildDateCode, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* end of wlanoidQueryBuildDateCode() */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to query BSS info from firmware -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBSSInfo(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ EVENT_AIS_BSS_INFO_T rCmdBSSInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(EVENT_AIS_BSS_INFO_T); -+ -+ if (u4QueryBufferLen < sizeof(EVENT_AIS_BSS_INFO_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ kalMemZero(&rCmdBSSInfo, sizeof(EVENT_AIS_BSS_INFO_T)); -+ /* -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_BSS_INFO, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventGetBSSInfo, -+ nicOidCmdTimeoutCommon, -+ sizeof(P_EVENT_AIS_BSS_INFO_T), -+ (PUINT_8) &rCmdBSSInfo, pvQueryBuffer, u4QueryBufferLen); -+ */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_BSS_INFO, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventGetBSSInfo, -+ nicOidCmdTimeoutCommon, -+ sizeof(EVENT_AIS_BSS_INFO_T), -+ (PUINT_8) & rCmdBSSInfo, pvQueryBuffer, u4QueryBufferLen); -+ -+ return rStatus; -+} /* wlanoidSetWiFiWmmPsTest */ -+ -+#if CFG_SUPPORT_BATCH_SCAN -+ -+#define CMD_WLS_BATCHING "WLS_BATCHING" -+ -+#define BATCHING_SET "SET" -+#define BATCHING_GET "GET" -+#define BATCHING_STOP "STOP" -+ -+#define PARAM_SCANFREQ "SCANFREQ" -+#define PARAM_MSCAN "MSCAN" -+#define PARAM_BESTN "BESTN" -+#define PARAM_CHANNEL "CHANNEL" -+#define PARAM_RTT "RTT" -+ -+WLAN_STATUS -+batchSetCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4WritenLen) -+{ -+ P_CHANNEL_INFO_T prRfChannelInfo; -+ CMD_BATCH_REQ_T rCmdBatchReq; -+ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ PCHAR head, p, p2; -+ UINT_32 tokens; -+ INT_32 scanfreq, mscan, bestn, rtt; -+ -+ DBGLOG(SCN, TRACE, "[BATCH] command=%s, len=%u\n", (PCHAR) pvSetBuffer, (UINT_32) u4SetBufferLen); -+ -+ if (!pu4WritenLen) -+ return -EINVAL; -+ *pu4WritenLen = 0; -+ -+ if (u4SetBufferLen < kalStrLen(CMD_WLS_BATCHING)) { -+ DBGLOG(SCN, TRACE, "[BATCH] invalid len %u\n", (UINT_32) u4SetBufferLen); -+ return -EINVAL; -+ } -+ -+ head = pvSetBuffer + kalStrLen(CMD_WLS_BATCHING) + 1; -+ kalMemSet(&rCmdBatchReq, 0, sizeof(CMD_BATCH_REQ_T)); -+ -+ if (!kalStrnCmp(head, BATCHING_SET, kalStrLen(BATCHING_SET))) { -+ -+ DBGLOG(SCN, TRACE, "XXX Start Batch Scan XXX\n"); -+ -+ head += kalStrLen(BATCHING_SET) + 1; -+ -+ /* SCANFREQ, MSCAN, BESTN */ -+ tokens = kalSScanf(head, "SCANFREQ=%d MSCAN=%d BESTN=%d", &scanfreq, &mscan, &bestn); -+ if (tokens != 3) { -+ DBGLOG(SCN, TRACE, "[BATCH] Parse fail: tokens=%u, SCANFREQ=%d MSCAN=%d BESTN=%d\n", -+ (UINT_32) tokens, scanfreq, mscan, bestn); -+ return -EINVAL; -+ } -+ /* RTT */ -+ p = kalStrStr(head, PARAM_RTT); -+ if (!p) { -+ DBGLOG(SCN, TRACE, "[BATCH] Parse RTT fail. head=%s\n", head); -+ return -EINVAL; -+ } -+ tokens = kalSScanf(p, "RTT=%d", &rtt); -+ if (tokens != 1) { -+ DBGLOG(SCN, TRACE, "[BATCH] Parse fail: tokens=%u, rtt=%d\n", (UINT_32) tokens, rtt); -+ return -EINVAL; -+ } -+ /* CHANNEL */ -+ p = kalStrStr(head, PARAM_CHANNEL); -+ if (!p) { -+ DBGLOG(SCN, TRACE, "[BATCH] Parse CHANNEL fail(1)\n"); -+ return -EINVAL; -+ } -+ head = p; -+ p = kalStrChr(head, '>'); -+ if (!p) { -+ DBGLOG(SCN, TRACE, "[BATCH] Parse CHANNEL fail(2)\n"); -+ return -EINVAL; -+ } -+ /* else { -+ *p = '.'; // remove '>' because sscanf can not parse <%s> -+ }*/ -+ /*tokens = kalSScanf(head, "CHANNEL=<%s", c_channel); -+ if (tokens != 1) { -+ DBGLOG(SCN, TRACE, ("[BATCH] Parse fail: tokens=%d, CHANNEL=<%s>\n", -+ tokens, c_channel)); -+ return -EINVAL; -+ } */ -+ rCmdBatchReq.ucChannelType = SCAN_CHANNEL_SPECIFIED; -+ rCmdBatchReq.ucChannelListNum = 0; -+ prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; -+ p = head + kalStrLen(PARAM_CHANNEL) + 2; /* c_channel; */ -+ while ((p2 = kalStrSep((char **)&p, ",")) != NULL) { -+ if (p2 == NULL || *p2 == 0) -+ break; -+ if (*p2 == '\0') -+ continue; -+ if (*p2 == 'A') { -+ rCmdBatchReq.ucChannelType = -+ rCmdBatchReq.ucChannelType == -+ SCAN_CHANNEL_2G4 ? SCAN_CHANNEL_FULL : SCAN_CHANNEL_5G; -+ } else if (*p2 == 'B') { -+ rCmdBatchReq.ucChannelType = -+ rCmdBatchReq.ucChannelType == -+ SCAN_CHANNEL_5G ? SCAN_CHANNEL_FULL : SCAN_CHANNEL_2G4; -+ } else { -+ -+ /* Translate Freq from MHz to channel number. */ -+ prRfChannelInfo->ucChannelNum = kalStrtol(p2, NULL, 0); -+ DBGLOG(SCN, TRACE, "Scanning Channel:%u, freq: %d\n", -+ (UINT_32) prRfChannelInfo->ucChannelNum, -+ (UINT_32) nicChannelNum2Freq(prRfChannelInfo->ucChannelNum)); -+ prRfChannelInfo->ucBand = prRfChannelInfo->ucChannelNum < 15 ? BAND_2G4 : BAND_5G; -+ -+ rCmdBatchReq.ucChannelListNum++; -+ if (rCmdBatchReq.ucChannelListNum >= 32) -+ break; -+ prRfChannelInfo++; -+ } -+ } -+ -+ /* set channel for test */ -+#if 0 -+ rCmdBatchReq.ucChannelType = 4; /* SCAN_CHANNEL_SPECIFIED; */ -+ rCmdBatchReq.ucChannelListNum = 0; -+ prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; -+ for (i = 1; i <= 14; i++) { -+ -+ /* filter out some */ -+ if (i == 1 || i == 5 || i == 11) -+ continue; -+ -+ /* Translate Freq from MHz to channel number. */ -+ prRfChannelInfo->ucChannelNum = i; -+ DBGLOG(SCN, TRACE, "Scanning Channel:%d, freq: %d\n", -+ prRfChannelInfo->ucChannelNum, -+ nicChannelNum2Freq(prRfChannelInfo->ucChannelNum)); -+ prRfChannelInfo->ucBand = BAND_2G4; -+ -+ rCmdBatchReq.ucChannelListNum++; -+ prRfChannelInfo++; -+ } -+#endif -+#if 0 -+ rCmdBatchReq.ucChannelType = 0; /* SCAN_CHANNEL_FULL; */ -+#endif -+ -+ rCmdBatchReq.u4Scanfreq = scanfreq; -+ rCmdBatchReq.ucMScan = mscan > CFG_BATCH_MAX_MSCAN ? CFG_BATCH_MAX_MSCAN : mscan; -+ rCmdBatchReq.ucBestn = bestn; -+ rCmdBatchReq.ucRtt = rtt; -+ DBGLOG(SCN, TRACE, "[BATCH] SCANFREQ=%u MSCAN=%u BESTN=%u RTT=%u\n", -+ (UINT_32) rCmdBatchReq.u4Scanfreq, -+ (UINT_32) rCmdBatchReq.ucMScan, -+ (UINT_32) rCmdBatchReq.ucBestn, (UINT_32) rCmdBatchReq.ucRtt; -+ -+ if (rCmdBatchReq.ucChannelType != SCAN_CHANNEL_SPECIFIED) { -+ DBGLOG(SCN, TRACE, "[BATCH] CHANNELS = %s\n", -+ rCmdBatchReq.ucChannelType == SCAN_CHANNEL_FULL ? "FULL" : -+ rCmdBatchReq.ucChannelType == SCAN_CHANNEL_2G4 ? "2.4G all" : "5G all"); -+ } else { -+ DBGLOG(SCN, TRACE, "[BATCH] CHANNEL list\n"); -+ prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; -+ for (tokens = 0; tokens < rCmdBatchReq.ucChannelListNum; tokens++) { -+ DBGLOG(SCN, TRACE, "[BATCH] %s, %d\n", -+ prRfChannelInfo->ucBand == BAND_2G4 ? "2.4G" : "5G", -+ prRfChannelInfo->ucChannelNum); -+ prRfChannelInfo++; -+ } -+ } -+ -+ rCmdBatchReq.ucSeqNum = 1; -+ rCmdBatchReq.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_START; -+ -+ *pu4WritenLen = kalSnprintf(pvSetBuffer, 3, "%d", rCmdBatchReq.ucMScan); -+ -+ } else if (!kalStrnCmp(head, BATCHING_STOP, kalStrLen(BATCHING_STOP))) { -+ -+ DBGLOG(SCN, TRACE, "XXX Stop Batch Scan XXX\n"); -+ -+ rCmdBatchReq.ucSeqNum = 1; -+ rCmdBatchReq.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_STOP; -+ } else { -+ return -EINVAL; -+ } -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_BATCH_REQ, -+ TRUE, FALSE, TRUE, NULL, NULL, sizeof(CMD_BATCH_REQ_T), (PUINT_8) &rCmdBatchReq, NULL, 0); -+ -+ /* kalMemSet(pvSetBuffer, 0, u4SetBufferLen); */ -+ /* rStatus = kalSnprintf(pvSetBuffer, 2, "%s", "OK"); */ -+ -+ return rStatus; -+} -+ -+WLAN_STATUS -+batchGetCmd(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ CMD_BATCH_REQ_T rCmdBatchReq; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_EVENT_BATCH_RESULT_T prEventBatchResult; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ prEventBatchResult = (P_EVENT_BATCH_RESULT_T) pvQueryBuffer; -+ -+ DBGLOG(SCN, TRACE, "XXX Get Batch Scan Result (%u) XXX\n", (UINT_32) prEventBatchResult->ucScanCount); -+ -+ *pu4QueryInfoLen = sizeof(EVENT_BATCH_RESULT_T); -+ -+ rCmdBatchReq.ucSeqNum = 2; -+ rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_RESULT; -+ rCmdBatchReq.ucMScan = prEventBatchResult->ucScanCount; /* Get which round result */ -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_BATCH_REQ, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventBatchScanResult, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_BATCH_REQ_T), -+ (PUINT_8) &rCmdBatchReq, (PVOID) pvQueryBuffer, u4QueryBufferLen); -+ -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBatchScanReq(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ return batchSetCmd(prAdapter, pvSetBuffer, u4SetBufferLen, pu4SetInfoLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBatchScanResult(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ return batchGetCmd(prAdapter, pvQueryBuffer, u4QueryBufferLen, pu4QueryInfoLen); -+ -+} /* end of wlanoidQueryBatchScanResult() */ -+ -+#endif /* CFG_SUPPORT_BATCH_SCAN */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request starting of schedule scan -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetStartSchedScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_SCHED_SCAN_REQUEST prSchedScanRequest; -+ -+ DEBUGFUNC("wlanoidSetStartSchedScan()"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(SCN, WARN, "Fail in set scheduled scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pu4SetInfoLen); -+ *pu4SetInfoLen = 0; -+ -+ if (u4SetBufferLen != sizeof(PARAM_SCHED_SCAN_REQUEST)) { -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (pvSetBuffer == NULL) { -+ return WLAN_STATUS_INVALID_DATA; -+ } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED && -+ prAdapter->fgEnOnlineScan == FALSE) { -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(SCN, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ prSchedScanRequest = (P_PARAM_SCHED_SCAN_REQUEST) pvSetBuffer; -+ -+ if (scnFsmSchedScanRequest(prAdapter, -+ (UINT_8) (prSchedScanRequest->u4SsidNum), -+ prSchedScanRequest->arSsid, -+ prSchedScanRequest->u4IELength, -+ prSchedScanRequest->pucIE, prSchedScanRequest->u2ScanInterval) == TRUE) { -+ return WLAN_STATUS_SUCCESS; -+ } else { -+ return WLAN_STATUS_FAILURE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request termination of schedule scan -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetStopSchedScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ASSERT(prAdapter); -+ -+ /* ask SCN module to stop scan request */ -+ if (scnFsmSchedScanStopRequest(prAdapter) == TRUE) -+ return WLAN_STATUS_SUCCESS; -+ else -+ return WLAN_STATUS_FAILURE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a periodically scan action -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetGSCNAction(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_CMD_SET_PSCAN_ENABLE prCmdPscnAction; -+ P_SCAN_INFO_T prScanInfo; -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ DBGLOG(SCN, TRACE, "wlanoidSetGSCNAction\n"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ if (u4SetBufferLen != sizeof(CMD_SET_PSCAN_ENABLE)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ else if (pvSetBuffer == NULL) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(SCN, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ prCmdPscnAction = (P_CMD_SET_PSCAN_ENABLE) pvSetBuffer; -+ -+ if (prCmdPscnAction->ucPscanAct == ENABLE) { -+#if 0 -+ DBGLOG(OID, INFO, "set PCSN ENABLE\n"); -+ if (scnFsmPSCNAction(prAdapter, (UINT_8) (prCmdPscnAction->ucPscanAct)) == TRUE) { -+ -+ DBGLOG(OID, INFO, "wlanoidSetGSCNAction < ---\n"); -+ return WLAN_STATUS_PENDING; -+ } -+ DBGLOG(OID, INFO, "wlanoidSetGSCNAction < ---\n"); -+ return WLAN_STATUS_FAILURE; -+ -+#endif -+ scnPSCNFsm(prAdapter, PSCN_SCANNING, NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, TRUE); -+ } else if (prCmdPscnAction->ucPscanAct == DISABLE) { -+#if 0 -+ DBGLOG(OID, INFO, "disable PCSN\n"); -+ scnFsmPSCNAction(prAdapter, (UINT_8) DISABLE); -+ -+ DBGLOG(OID, TRACE, "set new PCSN\n"); -+ scnCombineParamsIntoPSCN(prAdapter, NULL, NULL, NULL, NULL, FALSE, FALSE, TRUE); -+ -+ DBGLOG(OID, INFO, "ENABLE or disable PCSN\n"); -+ if (!prScanInfo->fgPscnOnnning) { -+ DBGLOG(OID, INFO, "ENABLE PCSN\n"); -+ scnFsmPSCNAction(prAdapter, ENABLE); -+ } else { -+ DBGLOG(OID, INFO, "All PCSN is disabled...\n"); -+ } -+#endif -+ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, NULL, FALSE, FALSE, TRUE, FALSE); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a periodically scan action -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetGSCNAParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam; -+ /*UINT_8 i, j = 0;*/ -+ DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam v1\n"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)) { -+ DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(P_PARAM_WIFI_GSCAN_CMD_PARAMS))\n"); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (pvSetBuffer == NULL) { -+ DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n"); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ prCmdGscnParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer; -+ /* KC-XXX memcpy(prCmdGscnParam, */ -+ /* (P_PARAM_WIFI_GSCAN_CMD_PARAMS)pvSetBuffer, */ -+ /* sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS) ); */ -+ DBGLOG(SCN, INFO, -+ "prCmdGscnParam : base_period[%u], max_ap_per_scan[%u] num_buckets[%u], report_threshold[%u]\n", -+ prCmdGscnParam->base_period, prCmdGscnParam->max_ap_per_scan, prCmdGscnParam->num_buckets, -+ prCmdGscnParam->report_threshold); -+#if 0 -+ for (i = 0; i < prCmdGscnParam->num_buckets; i++) { -+ -+ DBGLOG(OID, INFO, -+ "prCmdGscnParam->buckets : band[%u], bucket[%u] num_buckets[%u], period[%u] report_events[%u]\n", -+ prCmdGscnParam->buckets[i].band, prCmdGscnParam->buckets[i].bucket, -+ prCmdGscnParam->buckets[i].num_channels, prCmdGscnParam->buckets[i].period, -+ prCmdGscnParam->buckets[i].report_events)); -+ DBGLOG(OID, INFO, "prCmdGscnParam->buckets[%d] has channel: ", i); -+ for (j = 0; j < prCmdGscnParam->buckets[i].num_channels; j++) -+ DBGLOG(OID, INFO, " %d, ", prCmdGscnParam->buckets[i].channels[j].channel); -+ DBGLOG(OID, INFO, "\n"); -+ } -+#endif -+ if (scnSetGSCNParam(prAdapter, prCmdGscnParam) == TRUE) { -+ DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam --->scnSetGSCNParam\n"); -+ return WLAN_STATUS_PENDING; -+ } else { -+ return WLAN_STATUS_FAILURE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set configure gscan PARAMs -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS -+wlanoidSetGSCNAConfig(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnScnConfigParam; -+ CMD_GSCN_SCN_COFIG_T rCmdGscnScnConfig; -+ -+ DBGLOG(SCN, INFO, "wlanoidSetGSCNAConfig v1\n"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)) { -+ DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(CMD_GSCN_SCN_COFIG_T))\n"); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (pvSetBuffer == NULL) { -+ DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n"); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ DBGLOG(SCN, INFO, "prCmdGscnScnConfigParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS)pvSetBuffer\n"); -+ prCmdGscnScnConfigParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer; -+ memcpy(prCmdGscnScnConfigParam, (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer, -+ sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ DBGLOG(SCN, INFO, "prCmdGscnScnConfigParam assign prCmdGscnScnConfig\n"); -+ rCmdGscnScnConfig.u4BufferThreshold = prCmdGscnScnConfigParam->report_threshold; -+ rCmdGscnScnConfig.ucNumApPerScn = prCmdGscnScnConfigParam->max_ap_per_scan; -+ rCmdGscnScnConfig.u4NumScnToCache = prCmdGscnScnConfigParam->num_scans; -+ DBGLOG(SCN, INFO, " report_threshold %d report_threshold %d num_scans %d\n", -+ rCmdGscnScnConfig.u4BufferThreshold, -+ rCmdGscnScnConfig.ucNumApPerScn, rCmdGscnScnConfig.u4NumScnToCache); -+ if (scnFsmSetGSCNConfig(prAdapter, &rCmdGscnScnConfig) == TRUE) { -+ DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam --->scnSetGSCNParam\n"); -+ return WLAN_STATUS_PENDING; -+ } else { -+ return WLAN_STATUS_FAILURE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get a gscan result -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidGetGSCNResult(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS prGetGscnScnResultParm; -+ CMD_GET_GSCAN_RESULT_T rGetGscnScnResultCmd; -+ -+ DEBUGFUNC("wlanoidGetGSCNResult()"); -+ DBGLOG(SCN, INFO, "wlanoidGetGSCNResult v1\n"); -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS)) { -+ DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(CMD_GSCN_SCN_COFIG_T))\n"); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (pvSetBuffer == NULL) { -+ DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n"); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ prGetGscnScnResultParm = (P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS) pvSetBuffer; -+ /* memcpy(&rGetGscnScnResultCmd, prGetGscnScnResultParm, sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS) ); */ -+ -+ rGetGscnScnResultCmd.u4Num = prGetGscnScnResultParm->get_num; -+ rGetGscnScnResultCmd.ucFlush = prGetGscnScnResultParm->flush; -+ rGetGscnScnResultCmd.ucVersion = PSCAN_VERSION; -+ kalMemZero(rGetGscnScnResultCmd.aucReserved, sizeof(rGetGscnScnResultCmd.aucReserved)); -+ -+ if (scnFsmGetGSCNResult(prAdapter, &rGetGscnScnResultCmd) == TRUE) { -+ DBGLOG(SCN, INFO, "wlanoidGetGSCNResult --->scnFsmGetGSCNResult\n"); -+ return WLAN_STATUS_PENDING; -+ } else { -+ return WLAN_STATUS_FAILURE; -+ } -+ -+} -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by HS2.0 to set the assoc info, which is needed to add to -+* Association request frame while join HS2.0 AP. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetHS20Info(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_IE_HS20_INDICATION_T prHS20IndicationIe; -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ DEBUGFUNC("wlanoidSetHS20AssocInfo"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ if (u4SetBufferLen == 0) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ prHS20IndicationIe = (P_IE_HS20_INDICATION_T) pvSetBuffer; -+ -+ prAdapter->prGlueInfo->ucHotspotConfig = prHS20IndicationIe->ucHotspotConfig; -+ prAdapter->prGlueInfo->fgConnectHS20AP = TRUE; -+ -+ DBGLOG(SEC, TRACE, "HS20 IE sz %u\n", u4SetBufferLen); -+ -+ kalMemCopy(prAdapter->prGlueInfo->aucHS20AssocInfoIE, pvSetBuffer, u4SetBufferLen); -+ prAdapter->prGlueInfo->u2HS20AssocInfoIELen = (UINT_16) u4SetBufferLen; -+ DBGLOG(SEC, TRACE, "HS20 Assoc Info IE sz %u\n", u4SetBufferLen); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by WSC to set the assoc info, which is needed to add to -+* Association request frame while join WPS AP. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetInterworkingInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+#if 0 -+ P_HS20_INFO_T prHS20Info = NULL; -+ P_IE_INTERWORKING_T prInterWorkingIe; -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); -+ -+ DEBUGFUNC("wlanoidSetInterworkingInfo"); -+ DBGLOG(OID, TRACE, "\r\n"); -+ -+ if (u4SetBufferLen == 0) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ prInterWorkingIe = (P_IE_INTERWORKING_T) pvSetBuffer; -+ -+ prHS20Info->ucAccessNetworkOptions = prInterWorkingIe->ucAccNetOpt; -+ prHS20Info->ucVenueGroup = prInterWorkingIe->ucVenueGroup; -+ prHS20Info->ucVenueType = prInterWorkingIe->ucVenueType; -+ COPY_MAC_ADDR(prHS20Info->aucHESSID, prInterWorkingIe->aucHESSID); -+ -+ DBGLOG(SEC, TRACE, "IW IE sz %ld\n", u4SetBufferLen); -+#endif -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by WSC to set the Roaming Consortium IE info, which is needed to -+* add to Association request frame while join WPS AP. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRoamingConsortiumIEInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+#if 0 -+ P_HS20_INFO_T prHS20Info = NULL; -+ P_PARAM_HS20_ROAMING_CONSORTIUM_INFO prRCInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); -+ -+ /* DEBUGFUNC("wlanoidSetRoamingConsortiumInfo"); */ -+ /* DBGLOG(HS2, TRACE, ("\r\n")); */ -+ -+ if (u4SetBufferLen == 0) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ prRCInfo = (P_PARAM_HS20_ROAMING_CONSORTIUM_INFO) pvSetBuffer; -+ -+ kalMemCopy(&(prHS20Info->rRCInfo), prRCInfo, sizeof(PARAM_HS20_ROAMING_CONSORTIUM_INFO)); -+ -+ /* DBGLOG(HS2, TRACE, ("RoamingConsortium IE sz %ld\n", u4SetBufferLen)); */ -+#endif -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set_bssid_pool -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetHS20BssidPool(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ if (u4SetBufferLen < sizeof(PARAM_HS20_SET_BSSID_POOL)) { -+ *pu4SetInfoLen = sizeof(PARAM_HS20_SET_BSSID_POOL); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ rWlanStatus = hs20SetBssidPool(prAdapter, pvSetBuffer, NETWORK_TYPE_AIS_INDEX); -+ -+ return rWlanStatus; -+} /* end of wlanoidSendHS20GASRequest() */ -+ -+#endif -+ -+#if CFG_SUPPORT_ROAMING_ENC -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the MAC address the NIC is currently using. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRoamingInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ CMD_ROAMING_INFO_T *prCmdRoamingInfo; -+ -+ DEBUGFUNC("wlanoidSetRoamingInfo"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(CMD_ROAMING_INFO_T); -+ -+ if (u4SetBufferLen < sizeof(CMD_ROAMING_INFO_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ prCmdRoamingInfo = (CMD_ROAMING_INFO_T *) pvSetBuffer; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_ROAMING_INFO, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ROAMING_INFO_T), (PUINT_8) prCmdRoamingInfo, NULL, 0); -+} -+#endif /* CFG_SUPPORT_ROAMING_ENC */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set chip -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetChipConfig(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T prChipConfigInfo; -+ CMD_CHIP_CONFIG_T rCmdChipConfig; -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(prChipConfigInfo->aucCmd) == CHIP_CONFIG_RESP_SIZE); -+ DEBUGFUNC("wlanoidSetChipConfig"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prChipConfigInfo = (P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T) pvSetBuffer; -+ kalMemZero(&rCmdChipConfig, sizeof(rCmdChipConfig)); -+ -+ rCmdChipConfig.u2Id = prChipConfigInfo->u2Id; -+ rCmdChipConfig.ucType = prChipConfigInfo->ucType; -+ rCmdChipConfig.ucRespType = prChipConfigInfo->ucRespType; -+ rCmdChipConfig.u2MsgSize = prChipConfigInfo->u2MsgSize; -+ if (rCmdChipConfig.u2MsgSize > CHIP_CONFIG_RESP_SIZE) { -+ DBGLOG(OID, INFO, "Chip config Msg Size %u is not valid (set)\n", rCmdChipConfig.u2MsgSize); -+ rCmdChipConfig.u2MsgSize = CHIP_CONFIG_RESP_SIZE; -+ } -+ kalMemCopy(rCmdChipConfig.aucCmd, prChipConfigInfo->aucCmd, rCmdChipConfig.u2MsgSize); -+ -+ DBGLOG(OID, TRACE, "rCmdChipConfig.aucCmd=%s\n", rCmdChipConfig.aucCmd); -+#if 1 -+ rWlanStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_CHIP_CONFIG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CHIP_CONFIG_T), -+ (PUINT_8) &rCmdChipConfig, pvSetBuffer, u4SetBufferLen); -+#endif -+ return rWlanStatus; -+} /* wlanoidSetChipConfig */ -+ -+WLAN_STATUS -+wlanoidSetWfdDebugMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_CMD_WFD_DEBUG_MODE_INFO_T prCmdWfdDebugModeInfo; -+ -+ DEBUGFUNC("wlanoidSetWFDDebugMode"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(CMD_WFD_DEBUG_MODE_INFO_T); -+ -+ if (u4SetBufferLen < sizeof(CMD_WFD_DEBUG_MODE_INFO_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ prCmdWfdDebugModeInfo = (CMD_WFD_DEBUG_MODE_INFO_T *) pvSetBuffer; -+ -+ DBGLOG(OID, INFO, "New WFD Debug: %d mode and period=0x%x\n", prCmdWfdDebugModeInfo->ucDebugMode, -+ prCmdWfdDebugModeInfo->u2PeriodInteval); -+ -+ prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.ucWfdDebugMode = (UINT_8) prCmdWfdDebugModeInfo->ucDebugMode; -+ prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.u2WfdSNShowPeiroid = -+ (UINT_16) prCmdWfdDebugModeInfo->u2PeriodInteval; -+ -+ return WLAN_STATUS_SUCCESS; -+} /*wlanoidSetWfdDebugMode */ -+ -+ -+#if (CFG_SUPPORT_TXR_ENC == 1) -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the MAC address the NIC is currently using. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetTxRateInfo( -+ IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, -+ OUT PUINT_32 pu4SetInfoLen) -+{ -+ CMD_RLM_INFO_T *prCmdTxRInfo; -+ -+ DEBUGFUNC("wlanoidSetTxRateInfo"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(CMD_RLM_INFO_T); -+ -+ if (u4SetBufferLen < sizeof(CMD_RLM_INFO_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ prCmdTxRInfo = (CMD_RLM_INFO_T *)pvSetBuffer; -+ -+ DBGLOG(OID, INFO, " command = %u %u %u %u %d %u %u\n", -+ prCmdTxRInfo->u4Version, -+ prCmdTxRInfo->fgIsErrRatioEnhanceApplied, -+ prCmdTxRInfo->ucErrRatio2LimitMinRate, -+ prCmdTxRInfo->ucMinLegacyRateIdx, -+ prCmdTxRInfo->cMinRssiThreshold, -+ prCmdTxRInfo->fgIsRtsApplied, -+ prCmdTxRInfo->ucRecoverTime)); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_TX_AR_ERR_CONFIG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_RLM_INFO_T), -+ (PUINT_8)prCmdTxRInfo, -+ NULL, -+ 0 -+ ); -+} -+#endif /* CFG_SUPPORT_TXR_ENC */ -+ -+WLAN_STATUS -+wlanoidNotifyFwSuspend(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WIFI_SYSTEM_SUSPEND_CMD_T rSuspendCmd; -+ -+ if (!prAdapter || !pvSetBuffer) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ rSuspendCmd.fgIsSystemSuspend = *(PBOOLEAN)pvSetBuffer; -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_SYSTEM_SUSPEND, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(BOOLEAN), -+ (PUINT_8)&rSuspendCmd, -+ NULL, -+ 0); -+} -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c -new file mode 100644 -index 0000000000000..7ca7ee48922e1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c -@@ -0,0 +1,1654 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/common/wlan_p2p.c#8 -+*/ -+ -+/*! \file wlan_bow.c -+ \brief This file contains the Wi-Fi Direct commands processing routines for -+ MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_p2p.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 11 24 2011 yuche.tsai -+ * NULL -+ * Fix P2P IOCTL of multicast address bug, add low power driver stop control. -+ * -+ * 11 22 2011 yuche.tsai -+ * NULL -+ * Update RSSI link quality of P2P Network query method. (Bug fix) -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Add RSSI support for P2P network. -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support -+ * for service discovery version check. -+ * Add support for driver version query & p2p supplicant verseion set. -+ * For new service discovery mechanism sync. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * Support Channel Query. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 08 23 2011 yuche.tsai -+ * NULL -+ * Fix Multicast Issue of P2P. -+ * -+ * 04 27 2011 george.huang -+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter -+ * Support P2P ARP filter setting on early suspend/ late resume -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 17 2011 wh.su -+ * [WCXRP00000571] [MT6620 Wi-Fi] [Driver] Not check the p2p role during set key -+ * Skip the p2p role for adding broadcast key issue. -+ * -+ * 03 16 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * fixed compiling error while enable dbg. -+ * -+ * 03 08 2011 yuche.tsai -+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format -+ * issue[WCXRP00000509] [Volunteer Patch][MT6620][Driver] Kernal panic when remove p2p module. -+ * . -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add Security check related code. -+ * -+ * 03 02 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Fix SD Request Query Length issue. -+ * -+ * 03 02 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Service Discovery Request. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Update Service Discovery Wlan OID related function. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Update Service Discovery Related wlanoid function. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Indication Related code. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Function. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface -+ * for supporting Wi-Fi Direct Service Discovery ioctl implementations for P2P Service Discovery -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to -+ * ease physically continuous memory demands separate kalMemAlloc() into virtually-continuous -+ * and physically-continuous type to ease slab system pressure -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface -+ * for supporting Wi-Fi Direct Service Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T -+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add subroutines for P2P to set multicast list. -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * . -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * support wlanoidSetP2pPowerSaveProfile() in P2P -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * Support wlanoidSetNetworkAddress() for P2P -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+** -+*/ -+ -+/****************************************************************************** -+* C O M P I L E R F L A G S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************* -+*/ -+#include "precomp.h" -+#include "gl_p2p_ioctl.h" -+ -+/****************************************************************************** -+* C O N S T A N T S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* D A T A T Y P E S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* P U B L I C D A T A -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* P R I V A T E D A T A -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* M A C R O S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N S -+******************************************************************************* -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command packet generation utility -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] ucCID Command ID -+* \param[in] fgSetQuery Set or Query -+* \param[in] fgNeedResp Need for response -+* \param[in] pfCmdDoneHandler Function pointer when command is done -+* \param[in] u4SetQueryInfoLen The length of the set/query buffer -+* \param[in] pucInfoBuffer Pointer to set/query buffer -+* -+* -+* \retval WLAN_STATUS_PENDING -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendSetQueryP2PCmd(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucCID, -+ BOOLEAN fgSetQuery, -+ BOOLEAN fgNeedResp, -+ BOOLEAN fgIsOid, -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ UINT_32 u4SetQueryInfoLen, -+ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_8 ucCmdSeqNum; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ ASSERT(prGlueInfo); -+ -+ DEBUGFUNC("wlanoidSendSetQueryP2PCmd"); -+ DBGLOG(REQ, TRACE, "Command ID = 0x%08X\n", ucCID); -+ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(P2P, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_P2P_INDEX; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen); -+ prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; -+ prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; -+ prCmdInfo->fgIsOid = fgIsOid; -+ prCmdInfo->ucCID = ucCID; -+ prCmdInfo->fgSetQuery = fgSetQuery; -+ prCmdInfo->fgNeedResp = fgNeedResp; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; -+ prCmdInfo->pvInformationBuffer = pvSetQueryBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen; -+ -+ /* Setup WIFI_CMD_T (no payload) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) -+ kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen); -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ return WLAN_STATUS_PENDING; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a key to Wi-Fi Direct driver -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAddP2PKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ CMD_802_11_KEY rCmdKey; -+ P_PARAM_KEY_T prNewKey; -+ -+ DEBUGFUNC("wlanoidSetAddP2PKey"); -+ DBGLOG(REQ, INFO, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ prNewKey = (P_PARAM_KEY_T) pvSetBuffer; -+ -+ /* Verify the key structure length. */ -+ if (prNewKey->u4Length > u4SetBufferLen) { -+ DBGLOG(REQ, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", -+ (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ /* Verify the key material length for key material buffer */ -+ else if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) { -+ DBGLOG(REQ, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength); -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ /* Exception check */ -+ else if (prNewKey->u4KeyIndex & 0x0fffff00) -+ return WLAN_STATUS_INVALID_DATA; -+ /* Exception check, pairwise key must with transmit bit enabled */ -+ else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) { -+ return WLAN_STATUS_INVALID_DATA; -+ } else if (!(prNewKey->u4KeyLength == CCMP_KEY_LEN) && !(prNewKey->u4KeyLength == TKIP_KEY_LEN)) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ /* Exception check, pairwise key must with transmit bit enabled */ -+ else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { -+ if (((prNewKey->u4KeyIndex & 0xff) != 0) || -+ ((prNewKey->arBSSID[0] == 0xff) && (prNewKey->arBSSID[1] == 0xff) && (prNewKey->arBSSID[2] == 0xff) -+ && (prNewKey->arBSSID[3] == 0xff) && (prNewKey->arBSSID[4] == 0xff) -+ && (prNewKey->arBSSID[5] == 0xff))) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ /* fill CMD_802_11_KEY */ -+ kalMemZero(&rCmdKey, sizeof(CMD_802_11_KEY)); -+ rCmdKey.ucAddRemove = 1; /* add */ -+ rCmdKey.ucTxKey = ((prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) == IS_TRANSMIT_KEY) ? 1 : 0; -+ rCmdKey.ucKeyType = ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) ? 1 : 0; -+ if (kalP2PGetRole(prAdapter->prGlueInfo) == 1) { /* group client */ -+ rCmdKey.ucIsAuthenticator = 0; -+ } else { /* group owner */ -+ rCmdKey.ucIsAuthenticator = 1; -+ } -+ COPY_MAC_ADDR(rCmdKey.aucPeerAddr, prNewKey->arBSSID); -+ rCmdKey.ucNetType = NETWORK_TYPE_P2P_INDEX; -+ if (prNewKey->u4KeyLength == CCMP_KEY_LEN) -+ rCmdKey.ucAlgorithmId = CIPHER_SUITE_CCMP; /* AES */ -+ else if (prNewKey->u4KeyLength == TKIP_KEY_LEN) -+ rCmdKey.ucAlgorithmId = CIPHER_SUITE_TKIP; /* TKIP */ -+ rCmdKey.ucKeyId = (UINT_8) (prNewKey->u4KeyIndex & 0xff); -+ rCmdKey.ucKeyLen = (UINT_8) prNewKey->u4KeyLength; -+ kalMemCopy(rCmdKey.aucKeyMaterial, (PUINT_8) prNewKey->aucKeyMaterial, rCmdKey.ucKeyLen); -+ -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_ADD_REMOVE_KEY, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ NULL, -+ sizeof(CMD_802_11_KEY), (PUINT_8) &rCmdKey, pvSetBuffer, u4SetBufferLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request Wi-Fi Direct driver to remove keys -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRemoveP2PKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ CMD_802_11_KEY rCmdKey; -+ P_PARAM_REMOVE_KEY_T prRemovedKey; -+ -+ DEBUGFUNC("wlanoidSetRemoveP2PKey"); -+ ASSERT(prAdapter); -+ -+ if (u4SetBufferLen < sizeof(PARAM_REMOVE_KEY_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ prRemovedKey = (P_PARAM_REMOVE_KEY_T) pvSetBuffer; -+ -+ /* Check bit 31: this bit should always 0 */ -+ if (prRemovedKey->u4KeyIndex & IS_TRANSMIT_KEY) { -+ /* Bit 31 should not be set */ -+ DBGLOG(REQ, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Check bits 8 ~ 29 should always be 0 */ -+ if (prRemovedKey->u4KeyIndex & BITS(8, 29)) { -+ /* Bit 31 should not be set */ -+ DBGLOG(REQ, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* There should not be any key operation for P2P Device */ -+ if (kalP2PGetRole(prAdapter->prGlueInfo) == 0) -+ ; /* return WLAN_STATUS_NOT_ACCEPTED; */ -+ -+ kalMemZero((PUINT_8) &rCmdKey, sizeof(CMD_802_11_KEY)); -+ -+ rCmdKey.ucAddRemove = 0; /* remove */ -+ if (kalP2PGetRole(prAdapter->prGlueInfo) == 1) { /* group client */ -+ rCmdKey.ucIsAuthenticator = 0; -+ } else { /* group owner */ -+ rCmdKey.ucIsAuthenticator = 1; -+ } -+ kalMemCopy(rCmdKey.aucPeerAddr, (PUINT_8) prRemovedKey->arBSSID, MAC_ADDR_LEN); -+ rCmdKey.ucNetType = NETWORK_TYPE_P2P_INDEX; -+ rCmdKey.ucKeyId = (UINT_8) (prRemovedKey->u4KeyIndex & 0x000000ff); -+ -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_ADD_REMOVE_KEY, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ NULL, -+ sizeof(CMD_802_11_KEY), (PUINT_8) &rCmdKey, pvSetBuffer, u4SetBufferLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Setting the IP address for pattern search function. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_ADAPTER_NOT_READY -+* \return WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2pNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 i, j; -+ P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList; -+ P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer; -+ P_PARAM_NETWORK_ADDRESS prNetworkAddress; -+ P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp; -+ UINT_32 u4IpAddressCount, u4CmdSize; -+ -+ DEBUGFUNC("wlanoidSetP2pNetworkAddress"); -+ DBGLOG(P2P, TRACE, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 4; -+ -+ if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST)) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ *pu4SetInfoLen = 0; -+ u4IpAddressCount = 0; -+ -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ u4IpAddressCount++; -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); -+ } -+ -+ /* construct payload of command packet */ -+ u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + -+ sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount; -+ -+ prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); -+ -+ if (prCmdNetworkAddressList == NULL) -+ return WLAN_STATUS_FAILURE; -+ -+ /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ -+ prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount; -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress; -+ -+ kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr, -+ &(prNetAddrIp->in_addr), sizeof(UINT_32)); -+ -+ j++; -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); -+ } -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_IP_ADDRESS, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetIpAddress, -+ nicOidCmdTimeoutCommon, -+ u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen); -+ -+ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to query the power save profile. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryP2pPowerSaveProfile"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen != 0) { -+ ASSERT(pvQueryBuffer); -+ -+ *(PPARAM_POWER_MODE) pvQueryBuffer = -+ (PARAM_POWER_MODE) (prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucPsProfile); -+ *pu4QueryInfoLen = sizeof(PARAM_POWER_MODE); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set the power save profile. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS status; -+ PARAM_POWER_MODE ePowerMode; -+ -+ DEBUGFUNC("wlanoidSetP2pPowerSaveProfile"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_POWER_MODE); -+ if (u4SetBufferLen < sizeof(PARAM_POWER_MODE)) { -+ DBGLOG(REQ, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (*(PPARAM_POWER_MODE) pvSetBuffer >= Param_PowerModeMax) { -+ WARNLOG(("Invalid power mode %d\n", *(PPARAM_POWER_MODE) pvSetBuffer)); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ ePowerMode = *(PPARAM_POWER_MODE) pvSetBuffer; -+ -+ if (prAdapter->fgEnCtiaPowerMode) { -+ if (ePowerMode == Param_PowerModeCAM) { -+ /*Todo:: Nothing*/ -+ /*Todo:: Nothing*/ -+ } else { -+ /* User setting to PS mode (Param_PowerModeMAX_PSP or Param_PowerModeFast_PSP) */ -+ -+ if (prAdapter->u4CtiaPowerMode == 0) { -+ /* force to keep in CAM mode */ -+ ePowerMode = Param_PowerModeCAM; -+ } else if (prAdapter->u4CtiaPowerMode == 1) { -+ ePowerMode = Param_PowerModeMAX_PSP; -+ } else if (prAdapter->u4CtiaPowerMode == 2) { -+ ePowerMode = Param_PowerModeFast_PSP; -+ } -+ } -+ } -+ -+ status = nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_P2P_INDEX, ePowerMode, TRUE); -+ return status; -+} /* end of wlanoidSetP2pPowerSaveProfile() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set the power save profile. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2pSetNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 i, j; -+ P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList; -+ P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer; -+ P_PARAM_NETWORK_ADDRESS prNetworkAddress; -+ P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp; -+ UINT_32 u4IpAddressCount, u4CmdSize; -+ PUINT_8 pucBuf = (PUINT_8) pvSetBuffer; -+ -+ DEBUGFUNC("wlanoidSetP2pSetNetworkAddress"); -+ DBGLOG(P2P, TRACE, "\n"); -+ DBGLOG(P2P, INFO, "wlanoidSetP2pSetNetworkAddress (%d)\n", (INT_16) u4SetBufferLen); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 4; -+ -+ if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST)) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ *pu4SetInfoLen = 0; -+ u4IpAddressCount = 0; -+ -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ u4IpAddressCount++; -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); -+ } -+ -+ /* construct payload of command packet */ -+ u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + -+ sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount; -+ -+ if (u4IpAddressCount == 0) -+ u4CmdSize = sizeof(CMD_SET_NETWORK_ADDRESS_LIST); -+ -+ prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); -+ -+ if (prCmdNetworkAddressList == NULL) -+ return WLAN_STATUS_FAILURE; -+ -+ /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ -+ prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ -+ /* only to set IP address to FW once ARP filter is enabled */ -+ if (prAdapter->fgEnArpFilter) { -+ prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount; -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ -+ DBGLOG(P2P, INFO, "u4IpAddressCount (%u)\n", u4IpAddressCount); -+ for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress; -+ -+ kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr, -+ &(prNetAddrIp->in_addr), sizeof(UINT_32)); -+ -+ j++; -+ -+ pucBuf = (PUINT_8) &prNetAddrIp->in_addr; -+ DBGLOG(P2P, INFO, "prNetAddrIp->in_addr:%d:%d:%d:%d\n", -+ (UINT_8) pucBuf[0], (UINT_8) pucBuf[1], -+ (UINT_8) pucBuf[2], (UINT_8) pucBuf[3]); -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, -+ aucAddress))); -+ } -+ -+ } else { -+ prCmdNetworkAddressList->ucAddressCount = 0; -+ } -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_IP_ADDRESS, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetIpAddress, -+ nicOidCmdTimeoutCommon, -+ u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen); -+ -+ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); -+ return rStatus; -+} /* end of wlanoidSetP2pSetNetworkAddress() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set Multicast Address List. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2PMulticastList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ CMD_MAC_MCAST_ADDR rCmdMacMcastAddr; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ /* The data must be a multiple of the Ethernet address size. */ -+ if ((u4SetBufferLen % MAC_ADDR_LEN)) { -+ DBGLOG(REQ, WARN, "Invalid MC list length %u\n", u4SetBufferLen); -+ -+ *pu4SetInfoLen = (((u4SetBufferLen + MAC_ADDR_LEN) - 1) / MAC_ADDR_LEN) * MAC_ADDR_LEN; -+ -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ /* Verify if we can support so many multicast addresses. */ -+ if ((u4SetBufferLen / MAC_ADDR_LEN) > MAX_NUM_GROUP_ADDR) { -+ DBGLOG(REQ, WARN, "Too many MC addresses\n"); -+ -+ return WLAN_STATUS_MULTICAST_FULL; -+ } -+ -+ /* NOTE(Kevin): Windows may set u4SetBufferLen == 0 && -+ * pvSetBuffer == NULL to clear exist Multicast List. -+ */ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(REQ, WARN, "Fail in set multicast list! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ rCmdMacMcastAddr.u4NumOfGroupAddr = u4SetBufferLen / MAC_ADDR_LEN; -+ rCmdMacMcastAddr.ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ kalMemCopy(rCmdMacMcastAddr.arAddress, pvSetBuffer, u4SetBufferLen); -+ -+ /* This CMD response is no need to complete the OID. Or the event would unsync. */ -+ return wlanoidSendSetQueryP2PCmd(prAdapter, CMD_ID_MAC_MCAST_ADDR, TRUE, FALSE, FALSE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_MAC_MCAST_ADDR), -+ (PUINT_8) &rCmdMacMcastAddr, pvSetBuffer, u4SetBufferLen); -+ -+} /* end of wlanoidSetP2PMulticastList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to send GAS frame for P2P Service Discovery Request -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendP2PSDRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ if (u4SetBufferLen < sizeof(PARAM_P2P_SEND_SD_REQUEST)) { -+ *pu4SetInfoLen = sizeof(PARAM_P2P_SEND_SD_REQUEST); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+/* rWlanStatus = p2pFsmRunEventSDRequest(prAdapter, (P_PARAM_P2P_SEND_SD_REQUEST)pvSetBuffer); */ -+ -+ return rWlanStatus; -+} /* end of wlanoidSendP2PSDRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to send GAS frame for P2P Service Discovery Response -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendP2PSDResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ if (u4SetBufferLen < sizeof(PARAM_P2P_SEND_SD_RESPONSE)) { -+ *pu4SetInfoLen = sizeof(PARAM_P2P_SEND_SD_RESPONSE); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+/* rWlanStatus = p2pFsmRunEventSDResponse(prAdapter, (P_PARAM_P2P_SEND_SD_RESPONSE)pvSetBuffer); */ -+ -+ return rWlanStatus; -+} /* end of wlanoidGetP2PSDRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get GAS frame for P2P Service Discovery Request -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidGetP2PSDRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ /*PUINT_8 pucPacketBuffer = NULL, pucTA = NULL;*/ -+/* PUINT_8 pucChannelNum = NULL; */ -+ /*PUINT_16 pu2PacketLength = NULL;*/ -+ /*P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL;*/ -+ /*UINT_8 ucVersionNum = 0;*/ -+/* UINT_8 ucChannelNum = 0, ucSeqNum = 0; */ -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_P2P_GET_SD_REQUEST)) { -+ *pu4QueryInfoLen = sizeof(PARAM_P2P_GET_SD_REQUEST); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ DBGLOG(P2P, TRACE, "Get Service Discovery Request\n"); -+#if 0 -+ ucVersionNum = p2pFuncGetVersionNumOfSD(prAdapter); -+ if (ucVersionNum == 0) { -+ P_PARAM_P2P_GET_SD_REQUEST prP2pGetSdReq = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer; -+ -+ pucPacketBuffer = prP2pGetSdReq->aucPacketContent; -+ pu2PacketLength = &prP2pGetSdReq->u2PacketLength; -+ pucTA = &prP2pGetSdReq->rTransmitterAddr; -+ } else { -+ P_PARAM_P2P_GET_SD_REQUEST_EX prP2pGetSdReqEx = (P_PARAM_P2P_GET_SD_REQUEST_EX) NULL; -+ -+ prP2pGetSdReqEx = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer; -+ pucPacketBuffer = prP2pGetSdReqEx->aucPacketContent; -+ pu2PacketLength = &prP2pGetSdReqEx->u2PacketLength; -+ pucTA = &prP2pGetSdReqEx->rTransmitterAddr; -+ pucChannelNum = &prP2pGetSdReqEx->ucChannelNum; -+ ucSeqNum = prP2pGetSdReqEx->ucSeqNum; -+ } -+ -+ rWlanStatus = p2pFuncGetServiceDiscoveryFrame(prAdapter, -+ pucPacketBuffer, -+ (u4QueryBufferLen - sizeof(PARAM_P2P_GET_SD_REQUEST)), -+ (PUINT_32) pu2PacketLength, pucChannelNum, ucSeqNum); -+#else -+ *pu4QueryInfoLen = 0; -+ return rWlanStatus; -+#endif -+ /* -+ prWlanHdr = (P_WLAN_MAC_HEADER_T) pucPacketBuffer; -+ -+ kalMemCopy(pucTA, prWlanHdr->aucAddr2, MAC_ADDR_LEN); -+ -+ if (pu4QueryInfoLen) { -+ if (ucVersionNum == 0) -+ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_REQUEST) + (*pu2PacketLength)); -+ else -+ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_REQUEST_EX) + (*pu2PacketLength)); -+ -+ } -+ -+ return rWlanStatus; -+ */ -+} /* end of wlanoidGetP2PSDRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get GAS frame for P2P Service Discovery Response -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidGetP2PSDResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ /*P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL;*/ -+ /* UINT_8 ucSeqNum = 0, */ -+ /*UINT_8 ucVersionNum = 0;*/ -+ /*PUINT_8 pucPacketContent = (PUINT_8) NULL, pucTA = (PUINT_8) NULL;*/ -+ /*PUINT_16 pu2PacketLength = (PUINT_16) NULL;*/ -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_P2P_GET_SD_RESPONSE)) { -+ *pu4QueryInfoLen = sizeof(PARAM_P2P_GET_SD_RESPONSE); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ DBGLOG(P2P, TRACE, "Get Service Discovery Response\n"); -+ -+#if 0 -+ ucVersionNum = p2pFuncGetVersionNumOfSD(prAdapter); -+ if (ucVersionNum == 0) { -+ P_PARAM_P2P_GET_SD_RESPONSE prP2pGetSdRsp = (P_PARAM_P2P_GET_SD_RESPONSE) NULL; -+ -+ prP2pGetSdRsp = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer; -+ pucPacketContent = prP2pGetSdRsp->aucPacketContent; -+ pucTA = &prP2pGetSdRsp->rTransmitterAddr; -+ pu2PacketLength = &prP2pGetSdRsp->u2PacketLength; -+ } else { -+ P_PARAM_P2P_GET_SD_RESPONSE_EX prP2pGetSdRspEx = (P_PARAM_P2P_GET_SD_RESPONSE_EX) NULL; -+ -+ prP2pGetSdRspEx = (P_PARAM_P2P_GET_SD_RESPONSE_EX) pvQueryBuffer; -+ pucPacketContent = prP2pGetSdRspEx->aucPacketContent; -+ pucTA = &prP2pGetSdRspEx->rTransmitterAddr; -+ pu2PacketLength = &prP2pGetSdRspEx->u2PacketLength; -+ ucSeqNum = prP2pGetSdRspEx->ucSeqNum; -+ } -+ -+/* rWlanStatus = p2pFuncGetServiceDiscoveryFrame(prAdapter, */ -+/* pucPacketContent, */ -+/* (u4QueryBufferLen - sizeof(PARAM_P2P_GET_SD_RESPONSE)), */ -+/* (PUINT_32)pu2PacketLength, */ -+/* NULL, */ -+/* ucSeqNum); */ -+#else -+ *pu4QueryInfoLen = 0; -+ return rWlanStatus; -+#endif -+ /* -+ prWlanHdr = (P_WLAN_MAC_HEADER_T) pucPacketContent; -+ -+ kalMemCopy(pucTA, prWlanHdr->aucAddr2, MAC_ADDR_LEN); -+ -+ if (pu4QueryInfoLen) { -+ if (ucVersionNum == 0) -+ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_RESPONSE) + *pu2PacketLength); -+ else -+ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_RESPONSE_EX) + *pu2PacketLength); -+ } -+ -+ return rWlanStatus; -+ */ -+} /* end of wlanoidGetP2PSDResponse() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to terminate P2P Service Discovery Phase -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2PTerminateSDPhase(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_PARAM_P2P_TERMINATE_SD_PHASE prP2pTerminateSD = (P_PARAM_P2P_TERMINATE_SD_PHASE) NULL; -+ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; -+ -+ do { -+ if ((prAdapter == NULL) || (pu4SetInfoLen == NULL)) -+ break; -+ -+ if ((u4SetBufferLen) && (pvSetBuffer == NULL)) -+ break; -+ -+ if (u4SetBufferLen < sizeof(PARAM_P2P_TERMINATE_SD_PHASE)) { -+ *pu4SetInfoLen = sizeof(PARAM_P2P_TERMINATE_SD_PHASE); -+ rWlanStatus = WLAN_STATUS_BUFFER_TOO_SHORT; -+ break; -+ } -+ -+ prP2pTerminateSD = (P_PARAM_P2P_TERMINATE_SD_PHASE) pvSetBuffer; -+ -+ if (EQUAL_MAC_ADDR(prP2pTerminateSD->rPeerAddr, aucNullAddr)) { -+ DBGLOG(P2P, TRACE, "Service Discovery Version 2.0\n"); -+/* p2pFuncSetVersionNumOfSD(prAdapter, 2); */ -+ } -+ /* rWlanStatus = p2pFsmRunEventSDAbort(prAdapter); */ -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* end of wlanoidSetP2PTerminateSDPhase() */ -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetSecCheckRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SEC_CHECK, -+ FALSE, -+ TRUE, -+ TRUE, -+ NULL, -+ nicOidCmdTimeoutCommon, -+ u4SetBufferLen, (PUINT_8) pvSetBuffer, pvSetBuffer, u4SetBufferLen); -+ -+} /* end of wlanoidSetSecCheckRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidGetSecCheckResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ /* P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T)NULL; */ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen > 256) -+ u4QueryBufferLen = 256; -+ -+ *pu4QueryInfoLen = u4QueryBufferLen; -+ -+#if DBG -+ DBGLOG_MEM8(SEC, LOUD, prGlueInfo->prP2PInfo->aucSecCheckRsp, u4QueryBufferLen); -+#endif -+ kalMemCopy((PUINT_8) (pvQueryBuffer + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer)), -+ prGlueInfo->prP2PInfo->aucSecCheckRsp, u4QueryBufferLen); -+ -+ return rWlanStatus; -+} /* end of wlanoidGetSecCheckResponse() */ -+#endif -+ -+WLAN_STATUS -+wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam; -+ CMD_CUSTOM_NOA_PARAM_STRUCT_T rCmdNoaParam; -+ -+ DEBUGFUNC("wlanoidSetNoaParam"); -+ DBGLOG(P2P, TRACE, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdNoaParam, sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T)); -+ rCmdNoaParam.u4NoaDurationMs = prNoaParam->u4NoaDurationMs; -+ rCmdNoaParam.u4NoaIntervalMs = prNoaParam->u4NoaIntervalMs; -+ rCmdNoaParam.u4NoaCount = prNoaParam->u4NoaCount; -+ -+#if 0 -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_NOA_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen); -+#else -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_NOA_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen); -+ -+#endif -+ -+} -+ -+WLAN_STATUS -+wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam; -+ CMD_CUSTOM_OPPPS_PARAM_STRUCT_T rCmdOppPsParam; -+ -+ DEBUGFUNC("wlanoidSetOppPsParam"); -+ DBGLOG(P2P, TRACE, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdOppPsParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); -+ rCmdOppPsParam.u4CTwindowMs = prOppPsParam->u4CTwindowMs; -+ -+#if 0 -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_OPPPS_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen); -+#else -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_NOA_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen); -+ -+#endif -+ -+} -+ -+WLAN_STATUS -+wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T prUapsdParam; -+ CMD_CUSTOM_UAPSD_PARAM_STRUCT_T rCmdUapsdParam; -+ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ DEBUGFUNC("wlanoidSetUApsdParam"); -+ DBGLOG(P2P, TRACE, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ -+ prUapsdParam = (P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdUapsdParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); -+ rCmdUapsdParam.fgEnAPSD = prUapsdParam->fgEnAPSD; -+ prAdapter->rWifiVar.fgSupportUAPSD = prUapsdParam->fgEnAPSD; -+ -+ rCmdUapsdParam.fgEnAPSD_AcBe = prUapsdParam->fgEnAPSD_AcBe; -+ rCmdUapsdParam.fgEnAPSD_AcBk = prUapsdParam->fgEnAPSD_AcBk; -+ rCmdUapsdParam.fgEnAPSD_AcVo = prUapsdParam->fgEnAPSD_AcVo; -+ rCmdUapsdParam.fgEnAPSD_AcVi = prUapsdParam->fgEnAPSD_AcVi; -+ prPmProfSetupInfo->ucBmpDeliveryAC = -+ ((prUapsdParam->fgEnAPSD_AcBe << 0) | -+ (prUapsdParam->fgEnAPSD_AcBk << 1) | -+ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); -+ prPmProfSetupInfo->ucBmpTriggerAC = -+ ((prUapsdParam->fgEnAPSD_AcBe << 0) | -+ (prUapsdParam->fgEnAPSD_AcBk << 1) | -+ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); -+ -+ rCmdUapsdParam.ucMaxSpLen = prUapsdParam->ucMaxSpLen; -+ prPmProfSetupInfo->ucUapsdSp = prUapsdParam->ucMaxSpLen; -+ -+#if 0 -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_UAPSD_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen); -+#else -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_UAPSD_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen); -+ -+#endif -+} -+ -+WLAN_STATUS -+wlanoidQueryP2pOpChannel(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ -+ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; -+/* PUINT_8 pucOpChnl = (PUINT_8)pvQueryBuffer; */ -+ -+ do { -+ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) -+ break; -+ -+ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) -+ break; -+ -+ if (u4QueryBufferLen < sizeof(UINT_8)) { -+ *pu4QueryInfoLen = sizeof(UINT_8); -+ rResult = WLAN_STATUS_BUFFER_TOO_SHORT; -+ break; -+ } -+#if 0 -+ if (!p2pFuncGetCurrentOpChnl(prAdapter, pucOpChnl)) { -+ rResult = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+#else -+ rResult = WLAN_STATUS_INVALID_DATA; -+ break; -+#endif -+ /* -+ *pu4QueryInfoLen = sizeof(UINT_8); -+ rResult = WLAN_STATUS_SUCCESS; -+ */ -+ -+ } while (FALSE); -+ -+ return rResult; -+} /* wlanoidQueryP2pOpChannel */ -+ -+WLAN_STATUS -+wlanoidQueryP2pVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; -+/* PUINT_8 pucVersionNum = (PUINT_8)pvQueryBuffer; */ -+ -+ do { -+ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) -+ break; -+ -+ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) -+ break; -+ -+ if (u4QueryBufferLen < sizeof(UINT_8)) { -+ *pu4QueryInfoLen = sizeof(UINT_8); -+ rResult = WLAN_STATUS_BUFFER_TOO_SHORT; -+ break; -+ } -+ -+ } while (FALSE); -+ -+ return rResult; -+} /* wlanoidQueryP2pVersion */ -+ -+WLAN_STATUS -+wlanoidSetP2pSupplicantVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; -+ UINT_8 ucVersionNum; -+ -+ do { -+ if ((prAdapter == NULL) || (pu4SetInfoLen == NULL)) { -+ -+ rResult = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ if ((u4SetBufferLen) && (pvSetBuffer == NULL)) { -+ rResult = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ *pu4SetInfoLen = sizeof(UINT_8); -+ -+ if (u4SetBufferLen < sizeof(UINT_8)) { -+ rResult = WLAN_STATUS_INVALID_LENGTH; -+ break; -+ } -+ -+ ucVersionNum = *((PUINT_8) pvSetBuffer); -+ -+ rResult = WLAN_STATUS_SUCCESS; -+ } while (FALSE); -+ -+ return rResult; -+} /* wlanoidSetP2pSupplicantVersion */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set the WPS mode. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2pWPSmode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS status; -+ UINT_32 u4IsWPSmode = 0; -+ -+ DEBUGFUNC("wlanoidSetP2pWPSmode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (pvSetBuffer) -+ u4IsWPSmode = *(PUINT_32) pvSetBuffer; -+ else -+ u4IsWPSmode = 0; -+ -+ if (u4IsWPSmode) -+ prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = 1; -+ else -+ prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = 0; -+ -+ status = nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ return status; -+} /* end of wlanoidSetP2pWPSmode() */ -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+WLAN_STATUS -+wlanoidQueryP2pRssi(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryP2pRssi"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_RSSI); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(REQ, WARN, "Too short length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ if (prAdapter->fgIsP2pLinkQualityValid == TRUE && -+ (kalGetTimeTick() - prAdapter->rP2pLinkQualityUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) { -+ PARAM_RSSI rRssi; -+ -+ rRssi = (PARAM_RSSI) prAdapter->rP2pLinkQuality.cRssi; /* ranged from (-128 ~ 30) in unit of dBm */ -+ -+ if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) -+ rRssi = PARAM_WHQL_RSSI_MAX_DBM; -+ else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) -+ rRssi = PARAM_WHQL_RSSI_MIN_DBM; -+ -+ kalMemCopy(pvQueryBuffer, &rRssi, sizeof(PARAM_RSSI)); -+ return WLAN_STATUS_SUCCESS; -+ } -+#ifdef LINUX -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryLinkQuality, -+ nicOidCmdTimeoutCommon, -+ *pu4QueryInfoLen, pvQueryBuffer, pvQueryBuffer, u4QueryBufferLen); -+#else -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryLinkQuality, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+#endif -+} /* wlanoidQueryP2pRssi */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h -new file mode 100644 -index 0000000000000..89de18c89c1cc ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h -@@ -0,0 +1,238 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/CFG_Wifi_File.h#1 -+*/ -+ -+/*! \file CFG_Wifi_File.h -+ \brief Collection of NVRAM structure used for YuSu project -+ -+ In this file we collect all compiler flags and detail the driver behavior if -+ enable/disable such switch or adjust numeric parameters. -+*/ -+ -+/* -+** Log: CFG_Wifi_File.h -+ * -+ * 09 08 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 08 09 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * add CCK-DSSS TX-PWR control field in NVRAM and CMD definition for MT5931-MP -+ * -+ * 05 27 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * update NVRAM data structure definition. -+ * -+ * 03 10 2011 cp.wu -+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 -+ * deprecate configuration used by MT6620 E2 -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 25 2010 cp.wu -+ * [WCXRP00000133] [MT6620 Wi-Fi] [FW][Driver] Change TX power offset band definition -+ * follow-up for CMD_5G_PWR_OFFSET_T definition change -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+*/ -+ -+#ifndef _CFG_WIFI_FILE_H -+#define _CFG_WIFI_FILE_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_typedef.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+/* duplicated from nic_cmd_event.h to avoid header dependency */ -+typedef struct _TX_PWR_PARAM_T { -+ INT_8 cTxPwr2G4Cck; /* signed, in unit of 0.5dBm */ -+ INT_8 acReserved[3]; /* form MT6628 acReserved[0]=cTxPwr2G4Dsss */ -+ INT_8 cTxPwr2G4OFDM_BPSK; -+ INT_8 cTxPwr2G4OFDM_QPSK; -+ INT_8 cTxPwr2G4OFDM_16QAM; -+ INT_8 cTxPwr2G4OFDM_Reserved; -+ INT_8 cTxPwr2G4OFDM_48Mbps; -+ INT_8 cTxPwr2G4OFDM_54Mbps; -+ -+ INT_8 cTxPwr2G4HT20_BPSK; -+ INT_8 cTxPwr2G4HT20_QPSK; -+ INT_8 cTxPwr2G4HT20_16QAM; -+ INT_8 cTxPwr2G4HT20_MCS5; -+ INT_8 cTxPwr2G4HT20_MCS6; -+ INT_8 cTxPwr2G4HT20_MCS7; -+ -+ INT_8 cTxPwr2G4HT40_BPSK; -+ INT_8 cTxPwr2G4HT40_QPSK; -+ INT_8 cTxPwr2G4HT40_16QAM; -+ INT_8 cTxPwr2G4HT40_MCS5; -+ INT_8 cTxPwr2G4HT40_MCS6; -+ INT_8 cTxPwr2G4HT40_MCS7; -+ -+ INT_8 cTxPwr5GOFDM_BPSK; -+ INT_8 cTxPwr5GOFDM_QPSK; -+ INT_8 cTxPwr5GOFDM_16QAM; -+ INT_8 cTxPwr5GOFDM_Reserved; -+ INT_8 cTxPwr5GOFDM_48Mbps; -+ INT_8 cTxPwr5GOFDM_54Mbps; -+ -+ INT_8 cTxPwr5GHT20_BPSK; -+ INT_8 cTxPwr5GHT20_QPSK; -+ INT_8 cTxPwr5GHT20_16QAM; -+ INT_8 cTxPwr5GHT20_MCS5; -+ INT_8 cTxPwr5GHT20_MCS6; -+ INT_8 cTxPwr5GHT20_MCS7; -+ -+ INT_8 cTxPwr5GHT40_BPSK; -+ INT_8 cTxPwr5GHT40_QPSK; -+ INT_8 cTxPwr5GHT40_16QAM; -+ INT_8 cTxPwr5GHT40_MCS5; -+ INT_8 cTxPwr5GHT40_MCS6; -+ INT_8 cTxPwr5GHT40_MCS7; -+} TX_PWR_PARAM_T, *P_TX_PWR_PARAM_T; -+ -+typedef struct _PWR_5G_OFFSET_T { -+ INT_8 cOffsetBand0; /* 4.915-4.980G */ -+ INT_8 cOffsetBand1; /* 5.000-5.080G */ -+ INT_8 cOffsetBand2; /* 5.160-5.180G */ -+ INT_8 cOffsetBand3; /* 5.200-5.280G */ -+ INT_8 cOffsetBand4; /* 5.300-5.340G */ -+ INT_8 cOffsetBand5; /* 5.500-5.580G */ -+ INT_8 cOffsetBand6; /* 5.600-5.680G */ -+ INT_8 cOffsetBand7; /* 5.700-5.825G */ -+} PWR_5G_OFFSET_T, *P_PWR_5G_OFFSET_T; -+ -+typedef struct _PWR_PARAM_T { -+ UINT_32 au4Data[28]; -+ UINT_32 u4RefValue1; -+ UINT_32 u4RefValue2; -+} PWR_PARAM_T, *P_PWR_PARAM_T; -+ -+typedef struct _MT6620_CFG_PARAM_STRUCT { -+ /* 256 bytes of MP data */ -+ UINT_16 u2Part1OwnVersion; -+ UINT_16 u2Part1PeerVersion; -+ UINT_8 aucMacAddress[6]; -+ UINT_8 aucCountryCode[2]; -+ TX_PWR_PARAM_T rTxPwr; -+ UINT_8 aucEFUSE[144]; -+ UINT_8 ucTxPwrValid; -+ UINT_8 ucSupport5GBand; -+ UINT_8 fg2G4BandEdgePwrUsed; -+ INT_8 cBandEdgeMaxPwrCCK; -+ INT_8 cBandEdgeMaxPwrOFDM20; -+ INT_8 cBandEdgeMaxPwrOFDM40; -+ -+ UINT_8 ucRegChannelListMap; -+ UINT_8 ucRegChannelListIndex; -+ UINT_8 aucRegSubbandInfo[36]; -+ -+ UINT_8 aucReserved2[256 - 240]; -+ -+ /* 256 bytes of function data */ -+ UINT_16 u2Part2OwnVersion; -+ UINT_16 u2Part2PeerVersion; -+ UINT_8 uc2G4BwFixed20M; -+ UINT_8 uc5GBwFixed20M; -+ UINT_8 ucEnable5GBand; -+ UINT_8 aucPreTailReserved; -+ UINT_8 uc2GRssiCompensation; -+ UINT_8 uc5GRssiCompensation; -+ UINT_8 fgRssiCompensationValidbit; -+ UINT_8 ucRxAntennanumber; -+ UINT_8 aucTailReserved[256 - 12]; -+} MT6620_CFG_PARAM_STRUCT, *P_MT6620_CFG_PARAM_STRUCT, WIFI_CFG_PARAM_STRUCT, *P_WIFI_CFG_PARAM_STRUCT; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifndef DATA_STRUCT_INSPECTING_ASSERT -+#define DATA_STRUCT_INSPECTING_ASSERT(expr) \ -+{ \ -+ switch (0) {case 0: case (expr): default:; } \ -+} -+#endif -+ -+#define CFG_FILE_WIFI_REC_SIZE sizeof(WIFI_CFG_PARAM_STRUCT) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#ifndef _lint -+/* We don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ * We'll need this to guarantee the same member order in different structures -+ * to simply handling effort in some functions. -+ */ -+static inline VOID nvramOffsetCheck(VOID) -+{ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2OwnVersion) == 256); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(WIFI_CFG_PARAM_STRUCT) == 512); -+ -+ DATA_STRUCT_INSPECTING_ASSERT((OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) & 0x0001) == 0); -+ -+ DATA_STRUCT_INSPECTING_ASSERT((OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo) & 0x0001) == 0); -+} -+#endif -+ -+#endif /* _CFG_WIFI_FILE_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h -new file mode 100644 -index 0000000000000..a52053d5752db ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h -@@ -0,0 +1,1628 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/config.h#2 -+*/ -+ -+/*! \file "config.h" -+ \brief This file includes the various configurable parameters for customers -+ -+ This file ncludes the configurable parameters except the parameters indicate the turning-on/off of some features -+*/ -+ -+/* -+** Log: config.h -+ * -+ * 07 13 2012 cp.wu -+ * [WCXRP00001259] [MT6620 Wi-Fi][Driver][Firmware] Send a signal to firmware for -+ * termination after SDIO error has happened -+ * [driver domain] add force reset by host-to-device interrupt mechanism -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 06 05 2012 tsaiyuan.hsu -+ * [WCXRP00001249] [ALPS.ICS] Daily build warning on "wlan/mgmt/swcr.c#1" -+ * resolve build waring for "WNM_UNIT_TEST not defined".. -+ * -+ * 06 04 2012 cp.wu -+ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development -+ * discussed with WH, privacy bit in associate response is not necessary to be checked, -+ * and identified as association failure when mismatching with beacon/probe response -+ * -+ * 05 11 2012 cp.wu -+ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience -+ * show MAC address & source while initiliazation -+ * -+ * 04 20 2012 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * correct macro -+ * -+ * 04 12 2012 terry.wu -+ * NULL -+ * Add AEE message support -+ * 1) Show AEE warning(red screen) if SDIO access error occurs -+ * -+ * 03 29 2012 eason.tsai -+ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define -+ * add conditional define. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Enable CFG80211 Support. -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 11 23 2011 cp.wu -+ * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection -+ * add compile option to disable beacon content change detection. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 10 28 2011 cp.wu -+ * [MT6620 Wi-Fi][Win32 Driver] Enable 5GHz support as default -+ * enable 5GHz as default for DaVinci trunk and V2.1 driver release . -+ * -+ * 10 18 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * surpress compiler warning for MT6628 build -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * enable divided firmware downloading. -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware download path in divided scatters. -+ * -+ * 10 03 2011 cp.wu -+ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware downloading aggregated path. -+ * -+ * 09 28 2011 tsaiyuan.hsu -+ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX -+ * enlarge window size only by 4. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * reuse firmware download logic of MT6620 for MT6628. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms. -+ * -+ * 08 12 2011 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * load WIFI_RAM_CODE_E6 for MT6620 E6 ASIC. -+ * -+ * 08 09 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS definition for MT6620. -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 22 2011 jeffrey.chang -+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time -+ * modify driver to set OSC stable time after f/w download -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Refine compile flag. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Add wifi direct connection enhancement method I, II & VI. -+ * -+ * 06 24 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * increase RX buffer number to have a 2:1 ping-pong ratio -+ * -+ * 06 23 2011 eddie.chen -+ * [WCXRP00000810] [MT5931][DRV/FW] Adjust TxRx Buffer number and Rx buffer size -+ * 1. Different TX RX buffer -+ * 2. Enlarge RX buffer and increase the number 8->11 -+ * 3. Separate the WINSZIE and RX buffer number -+ * 4. Fix RX maximum size in MAC -+ * -+ * 06 20 2011 terry.wu -+ * NULL -+ * Add BoW Rate Limitation. -+ * -+ * 06 17 2011 terry.wu -+ * NULL -+ * . -+ * -+ * 06 17 2011 terry.wu -+ * NULL -+ * Add BoW 11N support. -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Add compile flag for persistent group support. -+ * -+ * 06 01 2011 cm.chang -+ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function -+ * Limit AIS to fixed channel same with BOW -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * Enable RX STBC capability -+ * -+ * 04 11 2011 george.huang -+ * [WCXRP00000628] [MT6620 Wi-Fi][FW][Driver] Modify U-APSD setting to default OFF -+ * . -+ * -+ * 04 08 2011 pat.lu -+ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver -+ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver -+ * -+ * 04 08 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * 1. correction: RX aggregation is not limited to SDIO but for all host interface options -+ * 2. add forward declarations for DBG-only symbols -+ * -+ * 04 06 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * 1. do not check for pvData inside wlanNetCreate() due to it is NULL for eHPI port -+ * 2. update perm_addr as well for MAC address -+ * 3. not calling check_mem_region() anymore for eHPI -+ * 4. correct MSC_CS macro for 0-based notation -+ * -+ * 04 01 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * 1. simplify config.h due to aggregation options could be also applied for eHPI/SPI interface -+ * 2. use spin-lock instead of semaphore for protecting eHPI access because of possible access from ISR -+ * 3. request_irq() API has some changes between linux kernel 2.6.12 and 2.6.26 -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with -+ * user space process for RESET_START and RESET_END events -+ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism -+ * -+ * 03 22 2011 pat.lu -+ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build -+ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. -+ * -+ * 03 18 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * enable the Anti_piracy check at driver . -+ * -+ * 03 17 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * enable roaming feature. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one -+ * to reduce physically continuous memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 06 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Sync BOW Driver to latest person development branch version.. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add security check code. -+ * -+ * 03 01 2011 george.huang -+ * [WCXRP00000495] [MT6620 Wi-Fi][FW] Support pattern filter for unwanted ARP frames -+ * Fix compile issue -+ * -+ * 02 25 2011 george.huang -+ * [WCXRP00000497] [MT6620 Wi-Fi][FW] Change default UAPSD AC assignment -+ * Assign all AC default to be U-APSD enabled. -+ * -+ * 02 14 2011 wh.su -+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode -+ * Let the privacy check at hotspot mode default enable. -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode -+ * adding the code for check STA privacy bit at AP mode, . -+ * -+ * 02 08 2011 cp.wu -+ * [WCXRP00000427] [MT6620 Wi-Fi][Driver] Modify veresion information to match with release revision number -+ * change version number to v1.2.0.0 for preparing v1.2 software package release. -+ * -+ * 02 01 2011 yarco.yang -+ * [WCXRP00000417] [MT6620 Driver] Change CFG_HANDLE_IST_IN_SDIO_CALLBACK from 1 to 0 for Interoperability -+ * . -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 19 2011 wh.su -+ * [WCXRP00000370] [MT6620 Wi-Fi][Driver] Disable Rx RDG for workaround pre-N ccmp issue -+ * Not announce support Rx RDG for wokaround pre-N ccmp construct AAD issue.. -+ * -+ * 01 15 2011 puff.wen -+ * NULL -+ * Add Stress test -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause -+ * hardware header translation needs such information -+ * fill mac header length information for 802.1x frames. -+ * -+ * 01 11 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support BOW only for Linux. -+ * -+ * 01 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Enable BOW and 4 physical links. -+ * -+ * 01 08 2011 yuche.tsai -+ * [WCXRP00000345] [MT6620][Volunteer Patch] P2P may issue a SSID specified scan request, -+ * but the SSID length is still invalid. -+ * Modify CFG_SLT_SUPPORT default value. -+ * -+ * 01 08 2011 yuche.tsai -+ * [WCXRP00000341] [MT6620][SLT] Create Branch for SLT SW. -+ * Update configure flag. -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * report EEPROM used flag via NIC_CAPABILITY -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools -+ * -+ * 12 15 2010 yuche.tsai -+ * NULL -+ * Update SLT Descriptor number configure in driver. -+ * -+ * 12 13 2010 chinglan.wang -+ * NULL -+ * Add WPS 1.0 feature flag to enable the WPS 1.0 function. -+ * -+ * 11 23 2010 george.huang -+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB -+ * Enable PM function by default -+ * -+ * 11 15 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * use config.mk WAPI config define. -+ * -+ * 11 08 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * use the config.mk define. -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add code to run WlanIST in SDIO callback. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 25 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add option for enable/disable TX PWR gain adjustment (default: off) -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function -+ * enable the WAPI compiling flag as default -+ * -+ * 10 19 2010 cp.wu -+ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration -+ * remove HIF_SDIO_ONE flags because the settings could be merged for runtime detection instead of compile-time. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion -+ * 2. shorten polling count for shorter response time -+ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android -+ * Add a define CFG_TEST_ANDROID_DIRECT_GO compiling flag -+ * -+ * 10 08 2010 cm.chang -+ * NULL -+ * Remove unused compiling flags (TX_RDG and TX_SGI) -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 10 05 2010 yarco.yang -+ * [WCXRP00000082] [MT6620 Wi-Fi][Driver]High throughput performance tuning -+ * Change CFG_IST_LOOP_COUNT from 2 to 1 to reduce unnecessary SDIO bus access -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature -+ * Modify online scan as a run-time adjustable option (for Windows, in registry) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE -+ * -+ * 09 20 2010 cm.chang -+ * NULL -+ * Disable RX STBC by BB HEC based on MT6620E1_PHY_BUG v05.docx -+ * -+ * 09 17 2010 chinglan.wang -+ * NULL -+ * Add performance test option -+ * -+ * 09 10 2010 chinglan.wang -+ * NULL -+ * Modify for Software Migration Phase 2.10 for E2 FPGA -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Add a CFG for max common IE buffer size. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * restore configuration as before. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * HIFSYS Clock Source Workaround -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 30 2010 chinglan.wang -+ * NULL -+ * Enable the MT6620_FPGA_BWCS value. -+ * -+ * 08 30 2010 chinglan.wang -+ * NULL -+ * Disable the FW encryption. -+ * -+ * 08 27 2010 chinglan.wang -+ * NULL -+ * Update configuration for MT6620_E1_PRE_ALPHA_1832_0827_2010 -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add AT GO test configure mode under WinXP. -+ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * add option for enabling AIS 5GHz scan -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cp.wu -+ * NULL -+ * 1) initialize variable for enabling short premable/short time slot. -+ * 2) add compile option for disabling online scan -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Disable BOW Test. -+ * -+ * 08 23 2010 jeffrey.chang -+ * NULL -+ * fix config.h typo -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 21 2010 jeffrey.chang -+ * NULL -+ * 1) add sdio two setting -+ * 2) bug fix of sdio glue -+ * -+ * 08 09 2010 wh.su -+ * NULL -+ * let the firmware download default enabled. -+ * -+ * 08 07 2010 wh.su -+ * NULL -+ * adding the privacy related code for P2P network -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Add a configure flag for P2P unitest. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) re-enable AIS-FSM beacon timeout handling. -+ * 2) scan done API revised -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) enable Ad-Hoc -+ * 2) disable beacon timeout handling temporally due to unexpected beacon timeout event. -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Add for SLT support. -+ * -+ * 07 16 2010 cp.wu -+ * -+ * remove work-around in case SCN is not available. -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor -+ * underflow under concurrent network operation -+ * -+ * 07 09 2010 yarco.yang -+ * -+ * [MT6620 and MT5931] SW Migration: Add ADDBA support -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * for first connection, if connecting failed do not enter into scan state. -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * modify Beacon/ProbeResp to complete parsing, -+ * because host software has looser memory usage restriction -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add SCN compilation option. -+ * 2) when SCN is not turned on, BSSID_SCAN will generate a fake entry for 1st connection -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * set default compiling flag for security disable. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable RX management frame handling. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan_fsm into building. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan.c. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add bss.c. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add config option for cfg80211. -+ * -+ * 05 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * set ATIMwindow default value to zero. -+ * -+ * 05 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add option for FPGA_BWCS & FPGA_V5 -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) enable CMD/EVENT ver 0.9 definition. -+ * 2) abandon use of ENUM_MEDIA_STATE -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add CFG_STARTUP_DEBUG for debugging starting up issue. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic handling framework for wireless extension ioctls. -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change firmware name to WIFI_RAM_CODE. -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * disable bt-over-wifi configuration, turn it on after firmware finished implementation -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * re-enable power management -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * -+ * 1) modify rx path code for supporting Wi-Fi direct -+ * 2) modify config.h since Linux dont need to consider retaining packet -+ * -+ * 04 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * enable TCP/IP checksum offloading by default. -+ * -+ * 04 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * set CFG_ENABLE_FULL_PM to 1 as default to -+ * 1) acquire own before hardware access -+ * 2) set own back after hardware access -+ * -+ * 04 15 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * change firmware name -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver -+ * disable RX-enhanced response temporally, it seems the CQ is not resolved yet. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver -+ * re-enable RX enhanced mode as WPD00003827 is resolved. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * turn off RX_ENHANCE mode by default. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) eliminate unused definitions -+ * * 2) ready bit will be polled for limited iteration -+ * -+ * 04 02 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * firmware download: Linux uses different firmware path -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change to use WIFI_TCM_ALWAYS_ON as firmware image -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add a temporary flag for integration with CMD/EVENT v0.9. -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * firmware download load address & start address are now configured from config.h -+ * * due to the different configurations on FPGA and ASIC -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add options for full PM support. -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * turn on FW-DOWNLOAD as default for release. -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * build up basic data structure and definitions to support BT-over-WiFi -+ * -+ * 03 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add two option for ACK and ENCRYPTION for firmware download -+ * -+ * 03 11 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING -+ * -+ * 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 03 05 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * change CFG_NUM_OF_QM_RX_PKT_NUM to 120 -+ * -+ * 03 04 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * . -+ * -+ * 03 04 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * increase RX buffer number to avoid RX buffer starvation. -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Changed the number of STA_RECs to 20 -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add checksum offloading support. -+ * -+ * 02 11 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. add logic for firmware download -+ * * 2. firmware image filename and start/load address are now retrieved from registry -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * and result is retrieved by get ATInfo instead -+ * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-12-16 22:12:28 GMT mtk02752 -+** enable interrupt enhanced response, TX/RX Aggregation as default -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:38:43 GMT mtk02752 -+** eliminate compile options which are obsolete or for emulation purpose -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-12-09 13:56:26 GMT MTK02468 -+** Added RX buffer reordering configurations -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-12-04 12:09:09 GMT mtk02752 -+** once enhanced intr/rx response is taken, RX must be access in aggregated basis -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-23 17:54:50 GMT mtk02752 -+** correct a typo -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-17 22:40:47 GMT mtk01084 -+** add defines -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-17 17:33:37 GMT mtk02752 -+** add coalescing buffer definition for SD1_SD3_DATAPATH_INTEGRATION -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-16 20:32:40 GMT mtk02752 -+** add CFG_TX_MAX_PKT_NUM for limiting queued TX packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 13:34:44 GMT mtk02752 -+** add SD1_SD3_DATAPATH_INTEGRATION define for source control -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-13 13:54:11 GMT mtk01084 -+** enable INT enhance mode by default -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-10-30 18:17:14 GMT mtk01084 -+** add new define -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-10-29 19:47:36 GMT mtk01084 -+** not use HIF loopback mode -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-10-13 21:58:33 GMT mtk01084 -+** update for new macro define -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-09-09 17:26:08 GMT mtk01084 -+** add CFG_TEST_WITH_MT5921 -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-18 21:02:30 GMT mtk01426 -+** Update CFG_RX_COALESCING_BUFFER_SIZE -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-21 09:35:51 GMT mtk01461 -+** Add CFG_TX_DBG_MGT_BUF to debug MGMT Buffer depth -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-14 15:52:21 GMT mtk01426 -+** Add OOB_DATA_PRE_FIXED_LEN define -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-08 16:51:08 GMT mtk01084 -+** update for FW download part -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-01 10:33:37 GMT mtk01461 -+** Add SW pre test flag CFG_HIF_LOOPBACK_PRETEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 00:29:18 GMT mtk01461 -+** Fix CFG_COALESCING_BUFFER_SIZE if enable the CFG_TX_FRAGMENT -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-18 20:58:34 GMT mtk01426 -+** Add CFG_HIF_LOOPBACK and CFG_SDIO_RX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-17 20:17:36 GMT mtk01426 -+** Add CMD/Response related configure -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:21 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:21 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _CONFIG_H -+#define _CONFIG_H -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#ifdef MT6620 -+#undef MT6620 -+#endif -+ -+#ifndef MT6628 -+#define MT6628 -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* 2 Flags for OS capability */ -+ -+#define MTK_WCN_SINGLE_MODULE 0 /* 1: without WMT */ -+ -+#ifdef LINUX -+#ifdef CONFIG_X86 -+#define MTK_WCN_HIF_SDIO 0 -+#else -+#define MTK_WCN_HIF_SDIO 0 /* samp */ -+#endif -+#else -+#define MTK_WCN_HIF_SDIO 0 -+#endif -+ -+#if (CFG_SUPPORT_AEE == 1) -+#define CFG_ENABLE_AEE_MSG 1 -+#else -+#define CFG_ENABLE_AEE_MSG 0 -+#endif -+ -+#if CFG_ENABLE_AEE_MSG -+#include -+#endif -+ -+/* 2 Flags for Driver Features */ -+#define CFG_TX_FRAGMENT 1 /*!< 1: Enable TX fragmentation -+ 0: Disable */ -+#define CFG_SUPPORT_PERFORMANCE_TEST 0 /*Only for performance Test */ -+ -+#define CFG_COUNTRY_CODE NULL /* "US" */ -+ -+#ifndef LINUX -+#define CFG_FW_FILENAME L"WIFI_RAM_CODE" -+#define CFG_FW_FILENAME_E6 L"WIFI_RAM_CODE_E6" -+#else -+#define CFG_FW_FILENAME "WIFI_RAM_CODE" -+#endif -+#ifndef LINUX -+#define CFG_SUPPORT_CFG_FILE 0 -+#else -+#define CFG_SUPPORT_CFG_FILE 1 -+#endif -+ -+#define CFG_SUPPORT_CE_FCC_TXPWR_LIMIT 0 /* Support CE FCC Tx Power limit */ -+ -+#define CFG_SUPPORT_802_11D 1 /*!< 1(default): Enable 802.11d -+ 0: Disable */ -+ -+#define CFG_SUPPORT_RRM 0 /* Radio Reasource Measurement (802.11k) */ -+#define CFG_SUPPORT_DFS 1 /* DFS (802.11h) */ -+ -+#if (CFG_SUPPORT_DFS == 1) /* Add by Enlai */ -+#define CFG_SUPPORT_QUIET 1 /* Quiet (802.11h) */ -+#define CFG_SUPPORT_SPEC_MGMT 1 /* Spectrum Management (802.11h): TPC and DFS */ -+#else -+#define CFG_SUPPORT_QUIET 0 /* Quiet (802.11h) */ -+#define CFG_SUPPORT_SPEC_MGMT 0 /* Spectrum Management (802.11h): TPC and DFS */ -+#endif -+ -+#define CFG_SUPPORT_RX_RDG 0 /* 11n feature. RX RDG capability */ -+#define CFG_SUPPORT_MFB 0 /* 802.11n MCS Feedback responder */ -+#define CFG_SUPPORT_RX_STBC 1 /* 802.11n RX STBC (1SS) */ -+#define CFG_SUPPORT_RX_SGI 1 /* 802.11n RX short GI for both 20M and 40M BW */ -+#define CFG_SUPPORT_RX_HT_GF 1 /* 802.11n RX HT green-field capability */ -+ -+#define CFG_SUPPORT_ROAMING_ENC 0 /* enahnced roaming */ -+ -+#define CFG_SUPPORT_TDLS 1 /* IEEE802.11z TDLS */ -+#define CFG_SUPPORT_TDLS_DBG 0 /* TDLS debug */ -+#define CFG_SUPPORT_STATISTICS 1 -+#define CFG_SUPPORT_DBG_POWERMODE 1 /* for debugging power always active mode */ -+ -+#define CFG_SUPPORT_GSCN 1 -+ -+#define CFG_SUPPORT_TXR_ENC 0 /* enhanced tx rate switch */ -+ -+#define CFG_SUPPORT_PERSIST_NETDEV 0 /* create NETDEV when system bootup */ -+ -+#define CFG_FORCE_USE_20BW 1 -+/*------------------------------------------------------------------------------ -+ * SLT Option -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SLT_SUPPORT 0 -+ -+#define MTK_AUTO_CHANNEL_SEL_SUPPORT_ENABLE 0 -+ -+#if defined(MTK_AUTO_CHANNEL_SEL_SUPPORT_ENABLE) -+#define CFG_AUTO_CHANNEL_SEL_SUPPORT 1 -+#else -+#define CFG_AUTO_CHANNEL_SEL_SUPPORT 0 -+#endif -+ -+#ifdef NDIS60_MINIPORT -+#define CFG_NATIVE_802_11 1 -+ -+#define CFG_TX_MAX_PKT_SIZE 2304 -+#define CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 0 /* !< 1: Enable TCP/IP header checksum offload -+ 0: Disable */ -+#define CFG_TCP_IP_CHKSUM_OFFLOAD 0 -+#define CFG_WHQL_DOT11_STATISTICS 1 -+#define CFG_WHQL_ADD_REMOVE_KEY 1 -+#define CFG_WHQL_CUSTOM_IE 1 -+#define CFG_WHQL_SAFE_MODE_ENABLED 1 -+ -+#else -+#define CFG_TCP_IP_CHKSUM_OFFLOAD 1 /* !< 1: Enable TCP/IP header checksum offload -+ 0: Disable */ -+#define CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 0 -+#define CFG_TX_MAX_PKT_SIZE 1600 -+#define CFG_NATIVE_802_11 0 -+#endif -+ -+/* 2 Flags for Driver Parameters */ -+/*------------------------------------------------------------------------------ -+ * Flags for EHPI Interface in Colibri Platform -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_EHPI_FASTER_BUS_TIMING 0 /*!< 1: Do workaround for faster bus timing -+ 0(default): Disable */ -+ -+/*------------------------------------------------------------------------------ -+ * Flags for HIFSYS Interface -+ *------------------------------------------------------------------------------ -+ */ -+#ifdef _lint -+#define _HIF_SDIO 0 /* samp */ -+#endif -+ -+#define CFG_SDIO_INTR_ENHANCE 1 /*!< 1(default): Enable SDIO ISR & TX/RX status enhance mode -+ 0: Disable */ -+#define CFG_SDIO_RX_ENHANCE 0 /*!< 1(default): Enable SDIO ISR & TX/RX status enhance mode -+ 0: Disable */ -+#define CFG_SDIO_TX_AGG 1 /*!< 1: Enable SDIO TX enhance -+ mode(Multiple frames in single BLOCK CMD) -+ 0(default): Disable */ -+ -+#define CFG_SDIO_RX_AGG 1 /*!< 1: Enable SDIO RX enhance -+ mode(Multiple frames in single BLOCK CMD) -+ 0(default): Disable */ -+ -+#if (CFG_SDIO_RX_AGG == 1) && (CFG_SDIO_INTR_ENHANCE == 0) -+#error "CFG_SDIO_INTR_ENHANCE should be 1 once CFG_SDIO_RX_AGG equals to 1" -+#elif (CFG_SDIO_INTR_ENHANCE == 1 || CFG_SDIO_RX_ENHANCE == 1) && (CFG_SDIO_RX_AGG == 0) -+#error "CFG_SDIO_RX_AGG should be 1 once CFG_SDIO_INTR_ENHANCE and/or CFG_SDIO_RX_ENHANCE equals to 1" -+#endif -+ -+#define CFG_SDIO_MAX_RX_AGG_NUM 0 /*!< 1: Setting the maximum RX aggregation number -+ 0(default): no limited */ -+ -+#ifdef WINDOWS_CE -+#define CFG_SDIO_PATHRU_MODE 1 /*!< 1: Support pass through (PATHRU) mode -+ 0: Disable */ -+#else -+#define CFG_SDIO_PATHRU_MODE 0 /*!< 0: Always disable if WINDOWS_CE is not defined */ -+#endif -+ -+#define CFG_MAX_RX_ENHANCE_LOOP_COUNT 3 -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Integration -+ *------------------------------------------------------------------------------ -+ */ -+#if defined(MT6620) -+#define MT6620_FPGA_BWCS 0 -+#define MT6620_FPGA_V5 0 -+ -+#if (MT6620_FPGA_BWCS == 1) && (MT6620_FPGA_V5 == 1) -+#error -+#endif -+ -+#if (MTK_WCN_HIF_SDIO == 1) -+#define CFG_MULTI_ECOVER_SUPPORT 1 -+#elif !defined(LINUX) -+#define CFG_MULTI_ECOVER_SUPPORT 1 -+#else -+#define CFG_MULTI_ECOVER_SUPPORT 0 -+#endif -+ -+#define CFG_ENABLE_CAL_LOG 0 -+#define CFG_REPORT_RFBB_VERSION 0 -+ -+#elif defined(MT6628) -+ -+#define CFG_MULTI_ECOVER_SUPPORT 0 -+ -+#define CFG_ENABLE_CAL_LOG 1 -+#define CFG_REPORT_RFBB_VERSION 1 -+ -+#endif -+ -+#define CFG_CHIP_RESET_SUPPORT 1 -+ -+#if defined(MT6628) -+#define CFG_EMBED_FIRMWARE_BUILD_DATE_CODE 1 -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * Flags for workaround -+ *------------------------------------------------------------------------------ -+ */ -+#if defined(MT6620) && (MT6620_FPGA_BWCS == 0) && (MT6620_FPGA_V5 == 0) -+#define MT6620_E1_ASIC_HIFSYS_WORKAROUND 0 -+#else -+#define MT6620_E1_ASIC_HIFSYS_WORKAROUND 0 -+#endif -+ -+/* SPM issue: suspend current is higher than deep idle */ -+#define CFG_SPM_WORKAROUND_FOR_HOTSPOT 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags for driver version -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_DRV_OWN_VERSION \ -+ ((UINT_16)((NIC_DRIVER_MAJOR_VERSION << 8) | (NIC_DRIVER_MINOR_VERSION))) -+#define CFG_DRV_PEER_VERSION ((UINT_16)0x0000) -+ -+/*------------------------------------------------------------------------------ -+ * Flags for TX path which are OS dependent -+ *------------------------------------------------------------------------------ -+ */ -+/*! NOTE(Kevin): If the Network buffer is non-scatter-gather like structure(without -+ * NETIF_F_FRAGLIST in LINUX), then we can set CFG_TX_BUFFER_IS_SCATTER_LIST to "0" -+ * for zero copy TX packets. -+ * For scatter-gather like structure, we set "1", driver will do copy frame to -+ * internal coalescing buffer before write it to FIFO. -+ */ -+#if defined(LINUX) -+#define CFG_TX_BUFFER_IS_SCATTER_LIST 1 /*!< 1: Do frame copy before write to TX FIFO. -+ Used when Network buffer is scatter-gather. -+ 0(default): Do not copy frame */ -+#else /* WINDOWS/WINCE */ -+#define CFG_TX_BUFFER_IS_SCATTER_LIST 1 -+#endif /* LINUX */ -+ -+#if CFG_SDIO_TX_AGG || CFG_TX_BUFFER_IS_SCATTER_LIST -+#define CFG_COALESCING_BUFFER_SIZE (CFG_TX_MAX_PKT_SIZE * NIC_TX_BUFF_SUM) -+#else -+#define CFG_COALESCING_BUFFER_SIZE (CFG_TX_MAX_PKT_SIZE) -+#endif /* CFG_SDIO_TX_AGG || CFG_TX_BUFFER_IS_SCATTER_LIST */ -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for TX path -+ *------------------------------------------------------------------------------ -+ */ -+ -+/*! Maximum number of SW TX packet queue */ -+#define CFG_TX_MAX_PKT_NUM 512 /* 256 must >= CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD * 2; -+ or wmm will fail when queue is full */ -+ -+/*! Maximum number of SW TX CMD packet buffer */ -+#define CFG_TX_MAX_CMD_PKT_NUM 32 -+ -+/*! Maximum number of associated STAs */ -+#define CFG_NUM_OF_STA_RECORD 20 -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for RX path -+ *------------------------------------------------------------------------------ -+ */ -+ -+/*! Max. descriptor number - sync. with firmware */ -+#if CFG_SLT_SUPPORT -+#define CFG_NUM_OF_RX0_HIF_DESC 42 -+#else -+#define CFG_NUM_OF_RX0_HIF_DESC 16 -+#endif -+#define CFG_NUM_OF_RX1_HIF_DESC 2 -+ -+/*! Max. buffer hold by QM */ -+#define CFG_NUM_OF_QM_RX_PKT_NUM 120 -+ -+/*! Maximum number of SW RX packet buffer */ -+#define CFG_RX_MAX_PKT_NUM ((CFG_NUM_OF_RX0_HIF_DESC + CFG_NUM_OF_RX1_HIF_DESC) * 3 \ -+ + CFG_NUM_OF_QM_RX_PKT_NUM) -+ -+#define CFG_RX_REORDER_Q_THRESHOLD 8 -+ -+#ifndef LINUX -+#define CFG_RX_RETAINED_PKT_THRESHOLD \ -+ (CFG_NUM_OF_RX0_HIF_DESC + CFG_NUM_OF_RX1_HIF_DESC + CFG_NUM_OF_QM_RX_PKT_NUM) -+#else -+#define CFG_RX_RETAINED_PKT_THRESHOLD 0 -+#endif -+ -+/*! Maximum RX packet size, if exceed this value, drop incoming packet */ -+/* 7.2.3 Maganement frames */ -+#define CFG_RX_MAX_PKT_SIZE (28 + 2312 + 12 /*HIF_RX_HEADER_T*/) /* TODO: it should be -+ 4096 under emulation mode */ -+ -+/*! Minimum RX packet size, if lower than this value, drop incoming packet */ -+#define CFG_RX_MIN_PKT_SIZE 10 /*!< 802.11 Control Frame is 10 bytes */ -+ -+#if CFG_SDIO_RX_AGG -+ /* extra size for CS_STATUS and enhanced response */ -+#define CFG_RX_COALESCING_BUFFER_SIZE ((CFG_NUM_OF_RX0_HIF_DESC + 1) \ -+ * CFG_RX_MAX_PKT_SIZE) -+#else -+#define CFG_RX_COALESCING_BUFFER_SIZE (CFG_RX_MAX_PKT_SIZE) -+#endif -+ -+/*! RX BA capability */ -+#define CFG_NUM_OF_RX_BA_AGREEMENTS 8 -+#define CFG_RX_BA_MAX_WINSIZE 16 -+#define CFG_RX_BA_INC_SIZE 4 -+#define CFG_RX_MAX_BA_TID_NUM 8 -+#define CFG_RX_REORDERING_ENABLED 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for CMD/RESPONSE -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_RESPONSE_POLLING_TIMEOUT 512 -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Protocol Stack -+ *------------------------------------------------------------------------------ -+ */ -+/*! Maximum number of BSS in the SCAN list */ -+#define CFG_MAX_NUM_BSS_LIST 64 -+ -+#define CFG_MAX_COMMON_IE_BUF_LEN ((1500 * CFG_MAX_NUM_BSS_LIST) / 3) -+ -+/*! Maximum size of Header buffer of each SCAN record */ -+#define CFG_RAW_BUFFER_SIZE 1024 -+ -+/*! Maximum size of IE buffer of each SCAN record */ -+#define CFG_IE_BUFFER_SIZE 512 -+ -+/*! Maximum number of STA records */ -+#define CFG_MAX_NUM_STA_RECORD 32 -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Power management -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_ENABLE_FULL_PM 1 -+#define CFG_ENABLE_WAKEUP_ON_LAN 0 -+#if defined(CONFIG_ARCH_MT6755) || defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || \ -+ defined(CONFIG_ARCH_MT6753) || defined(CONFIG_ARCH_MT6580) -+#define CFG_SUPPORT_WAKEUP_REASON_DEBUG 1 /* debug which packet wake up host */ -+#else -+#define CFG_SUPPORT_WAKEUP_REASON_DEBUG 0 /* debug which packet wake up host */ -+#endif -+#define CFG_INIT_POWER_SAVE_PROF ENUM_PSP_FAST_SWITCH -+ -+#define CFG_INIT_ENABLE_PATTERN_FILTER_ARP 0 -+ -+#define CFG_INIT_UAPSD_AC_BMP 0 /* (BIT(3) | BIT(2) | BIT(1) | BIT(0)) */ -+ -+/* #define CFG_SUPPORT_WAPI 0 */ -+#define CFG_SUPPORT_WPS 1 -+#define CFG_SUPPORT_WPS2 1 -+ -+/*------------------------------------------------------------------------------ -+ * 802.11i RSN Pre-authentication PMKID cahce maximun number -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_MAX_PMKID_CACHE 16 /*!< max number of PMKID cache -+ 16(default) : The Max PMKID cache */ -+/*------------------------------------------------------------------------------ -+ * Auto Channel Selection Maximun Channel Number -+ *------------------------------------------------------------------------------ -+ */ -+ -+#define MAX_AUTO_CHAL_NUM 23 /* Ch1~Ch14,Ch36,Ch40,Ch44, -+ Ch48,Ch149,Ch153,Ch157,Ch161 */ -+/*------------------------------------------------------------------------------ -+ * FAST SCAN -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_ENABLE_FAST_SCAN 0 -+#define CFG_CN_SUPPORT_CLASS121 0 /* Add Class 121, 5470-5725MHz, support for China domain */ -+#if CFG_ENABLE_FAST_SCAN -+ #define CFG_FAST_SCAN_DWELL_TIME 40 -+ #define CFG_FAST_SCAN_REG_DOMAIN_DEF_IDX 10 -+#endif -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Ad-Hoc -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_INIT_ADHOC_FREQ (2462000) -+#define CFG_INIT_ADHOC_MODE AD_HOC_MODE_MIXED_11BG -+#define CFG_INIT_ADHOC_BEACON_INTERVAL (100) -+#define CFG_INIT_ADHOC_ATIM_WINDOW (0) -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Maximum Scan SSID number -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SCAN_SSID_MAX_NUM (4) -+#define CFG_SCAN_SSID_MATCH_MAX_NUM (16) -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Load Setup Default -+ *------------------------------------------------------------------------------ -+ */ -+ -+/*------------------------------------------------------------------------------ -+ * Flags for enable 802.11A Band setting -+ *------------------------------------------------------------------------------ -+ */ -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Interrupt Process -+ *------------------------------------------------------------------------------ -+ */ -+#if defined(_HIF_SDIO) && defined(WINDOWS_CE) -+#define CFG_IST_LOOP_COUNT 8 -+#else -+#define CFG_IST_LOOP_COUNT 8 -+#endif /* _HIF_SDIO */ -+ -+#define CFG_INT_WRITE_CLEAR 0 -+ -+#if defined(LINUX) -+#define CFG_DBG_GPIO_PINS 0 /* if 1, use MT6516 GPIO pin to log TX behavior */ -+#endif -+ -+/* 2 Flags for Driver Debug Options */ -+/*------------------------------------------------------------------------------ -+ * Flags of TX Debug Option. NOTE(Kevin): Confirm with SA before modifying following flags. -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_DBG_MGT_BUF 1 /*!< 1: Debug statistics usage of MGMT Buffer -+ 0: Disable */ -+ -+#define CFG_HIF_STATISTICS 0 -+ -+#define CFG_HIF_RX_STARVATION_WARNING 0 -+ -+#define CFG_STARTUP_DEBUG 0 -+ -+#define CFG_RX_PKTS_DUMP 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Firmware Download Option. -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_ENABLE_FW_DOWNLOAD 1 -+ -+#define CFG_ENABLE_FW_DOWNLOAD_ACK 1 -+#define CFG_ENABLE_FW_ENCRYPTION 1 -+ -+#if defined(MT6628) -+#define CFG_ENABLE_FW_DOWNLOAD_AGGREGATION 0 -+#define CFG_ENABLE_FW_DIVIDED_DOWNLOAD 1 -+#endif -+ -+#if defined(MT6620) -+#if MT6620_FPGA_BWCS -+#define CFG_FW_LOAD_ADDRESS 0x10014000 -+#define CFG_OVERRIDE_FW_START_ADDRESS 0 -+#define CFG_FW_START_ADDRESS 0x10014001 -+#elif MT6620_FPGA_V5 -+#define CFG_FW_LOAD_ADDRESS 0x10008000 -+#define CFG_OVERRIDE_FW_START_ADDRESS 0 -+#define CFG_FW_START_ADDRESS 0x10008001 -+#else -+#define CFG_FW_LOAD_ADDRESS 0x10008000 -+#define CFG_OVERRIDE_FW_START_ADDRESS 0 -+#define CFG_FW_START_ADDRESS 0x10008001 -+#endif -+#elif defined(MT6628) -+#define CFG_FW_LOAD_ADDRESS 0x00060000 -+#define CFG_OVERRIDE_FW_START_ADDRESS 1 -+#define CFG_FW_START_ADDRESS 0x00060000 -+#define CFG_START_ADDRESS_IS_1ST_SECTION_ADDR 1 -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Bluetooth-over-WiFi (BT 3.0 + HS) support -+ *------------------------------------------------------------------------------ -+ */ -+ -+#ifdef LINUX -+#ifdef CONFIG_X86 -+#define CFG_ENABLE_BT_OVER_WIFI 0 -+#else -+#define CFG_ENABLE_BT_OVER_WIFI 1 -+#endif -+#else -+#define CFG_ENABLE_BT_OVER_WIFI 0 -+#endif -+ -+#define CFG_BOW_SEPARATE_DATA_PATH 1 -+ -+#define CFG_BOW_PHYSICAL_LINK_NUM 4 -+ -+#define CFG_BOW_TEST 0 -+ -+#define CFG_BOW_LIMIT_AIS_CHNL 1 -+ -+#define CFG_BOW_SUPPORT_11N 0 -+ -+#define CFG_BOW_RATE_LIMITATION 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Wi-Fi Direct support -+ *------------------------------------------------------------------------------ -+ */ -+#ifdef LINUX -+#ifdef CONFIG_X86 -+#define CFG_ENABLE_WIFI_DIRECT 0 -+#define CFG_SUPPORT_802_11W 0 -+#else -+#define CFG_ENABLE_WIFI_DIRECT 1 -+#define CFG_SUPPORT_802_11W 0 /*!< 0(default): Disable 802.11W */ -+#endif -+#else -+#define CFG_ENABLE_WIFI_DIRECT 0 -+#define CFG_SUPPORT_802_11W 0 /* Not support at WinXP */ -+#endif -+ -+#define CFG_SUPPORT_PERSISTENT_GROUP 0 -+ -+#define CFG_TEST_WIFI_DIRECT_GO 0 -+ -+#define CFG_TEST_ANDROID_DIRECT_GO 0 -+ -+#define CFG_UNITEST_P2P 0 -+ -+/* -+ * Enable cfg80211 option after Android 2.2(Froyo) is suggested, -+ * cfg80211 on linux 2.6.29 is not mature yet -+ */ -+#define CFG_ENABLE_WIFI_DIRECT_CFG_80211 1 -+ -+#define CFG_SUPPORT_HOTSPOT_OPTIMIZATION 1 -+#define CFG_HOTSPOT_OPTIMIZATION_BEACON_INTERVAL 300 -+#define CFG_HOTSPOT_OPTIMIZATION_DTIM 1 -+ -+/*------------------------------------------------------------------------------ -+ * Configuration Flags (Linux Only) -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_EXT_CONFIG 0 -+ -+/*------------------------------------------------------------------------------ -+ * Statistics Buffering Mechanism -+ *------------------------------------------------------------------------------ -+ */ -+#if CFG_SUPPORT_PERFORMANCE_TEST -+#define CFG_ENABLE_STATISTICS_BUFFERING 1 -+#else -+#define CFG_ENABLE_STATISTICS_BUFFERING 0 -+#endif -+#define CFG_STATISTICS_VALID_CYCLE 2000 -+#define CFG_LINK_QUALITY_VALID_PERIOD 5000 -+ -+/*------------------------------------------------------------------------------ -+ * Migration Option -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_ADHOC 0 -+#define CFG_SUPPORT_AAA 1 -+ -+#define CFG_SUPPORT_BCM 0 -+#define CFG_SUPPORT_BCM_BWCS 0 -+#define CFG_SUPPORT_BCM_BWCS_DEBUG 0 -+ -+#define CFG_SUPPORT_RDD_TEST_MODE 0 -+ -+#define CFG_SUPPORT_PWR_MGT 1 -+ -+#define CFG_RSN_MIGRATION 1 -+ -+#define CFG_PRIVACY_MIGRATION 1 -+ -+#define CFG_ENABLE_HOTSPOT_PRIVACY_CHECK 1 -+ -+#define CFG_MGMT_FRAME_HANDLING 1 -+ -+#define CFG_MGMT_HW_ACCESS_REPLACEMENT 0 -+ -+#if CFG_SUPPORT_PERFORMANCE_TEST -+ -+#else -+ -+#endif -+ -+#define CFG_SUPPORT_AIS_5GHZ 1 -+#define CFG_SUPPORT_BEACON_CHANGE_DETECTION 0 -+ -+/*------------------------------------------------------------------------------ -+ * Option for NVRAM and Version Checking -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_NVRAM 1 -+#define CFG_NVRAM_EXISTENCE_CHECK 1 -+#define CFG_SW_NVRAM_VERSION_CHECK 1 -+#define CFG_SUPPORT_NIC_CAPABILITY 1 -+ -+/*------------------------------------------------------------------------------ -+ * CONFIG_TITLE : Stress Test Option -+ * OWNER : Puff Wen -+ * Description : For stress test only. DO NOT enable it while normal operation -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_STRESS_TEST_SUPPORT 0 -+ -+/*------------------------------------------------------------------------------ -+ * Flags for LINT -+ *------------------------------------------------------------------------------ -+ */ -+#define LINT_SAVE_AND_DISABLE /*lint -save -e* */ -+ -+#define LINT_RESTORE /*lint -restore */ -+ -+#define LINT_EXT_HEADER_BEGIN LINT_SAVE_AND_DISABLE -+ -+#define LINT_EXT_HEADER_END LINT_RESTORE -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Features -+ *------------------------------------------------------------------------------ -+ */ -+ -+#define CFG_SUPPORT_QOS 1 /* Enable/disable QoS TX, AMPDU */ -+#define CFG_SUPPORT_AMPDU_TX 1 -+#define CFG_SUPPORT_AMPDU_RX 1 -+#define CFG_SUPPORT_TSPEC 0 /* Enable/disable TS-related Action frames handling */ -+#define CFG_SUPPORT_UAPSD 1 -+#define CFG_SUPPORT_UL_PSMP 0 -+ -+#define CFG_SUPPORT_ROAMING 1 /* Roaming System */ -+#define CFG_SUPPORT_SWCR 1 -+ -+#define CFG_SUPPORT_ANTI_PIRACY 1 -+ -+#define CFG_SUPPORT_OSC_SETTING 1 -+ -+#define CFG_SUPPORT_P2P_RSSI_QUERY 0 -+ -+#define CFG_SHOW_MACADDR_SOURCE 1 -+ -+#define CFG_SUPPORT_802_11V 0 /* Support 802.11v Wireless Network Management */ -+#define CFG_SUPPORT_802_11V_TIMING_MEASUREMENT 0 -+#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (CFG_SUPPORT_802_11V == 0) -+#error "CFG_SUPPORT_802_11V should be 1 once CFG_SUPPORT_802_11V_TIMING_MEASUREMENT equals to 1" -+#endif -+#if (CFG_SUPPORT_802_11V == 0) -+#define WNM_UNIT_TEST 0 -+#endif -+ -+#define CFG_DRIVER_COMPOSE_ASSOC_REQ 1 -+ -+#define CFG_STRICT_CHECK_CAPINFO_PRIVACY 0 -+ -+#define CFG_SUPPORT_WFD 1 -+ -+#define CFG_SUPPORT_WFD_COMPOSE_IE 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Packet Lifetime Profiling Mechanism -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_ENABLE_PKT_LIFETIME_PROFILE 1 -+ -+#define CFG_ENABLE_PER_STA_STATISTICS 1 -+ -+#define CFG_PRINT_RTP_PROFILE 0 /* If want to enable WFD Debug, please change it to 1. */ -+#define CFG_PRINT_RTP_SN_SKIP 0 -+ -+#define CFG_SUPPORT_PWR_LIMIT_COUNTRY 1 -+/*------------------------------------------------------------------------------ -+ * Flags of bus error tolerance -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_FORCE_RESET_UNDER_BUS_ERROR 0 -+ -+/*------------------------------------------------------------------------------ -+ * Build Date Code Integration -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_BUILD_DATE_CODE 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags for prepare the FW compile flag -+ *------------------------------------------------------------------------------ -+ */ -+#define COMPILE_FLAG0_GET_STA_LINK_STATUS (1<<0) -+#define COMPILE_FLAG0_WFD_ENHANCEMENT_PROTECT (1<<1) -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Batch Scan SUPPORT -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_BATCH_SCAN 0 -+#define CFG_BATCH_MAX_MSCAN 2 -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Channel Environment SUPPORT -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_GET_CH_ENV 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags of THERMO_THROTTLING SUPPORT -+ *------------------------------------------------------------------------------ -+ */ -+ -+#define CFG_SUPPORT_THERMO_THROTTLING 1 -+#define WLAN_INCLUDE_PROC 1 -+ -+#define CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE 1 -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _CONFIG_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h -new file mode 100644 -index 0000000000000..af586063c21af ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h -@@ -0,0 +1,466 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/debug.h#1 -+*/ -+ -+/*! \file debug.h -+ \brief Definition of SW debugging level. -+ -+ In this file, it describes the definition of various SW debugging levels and -+ assert functions. -+*/ -+ -+/* -+** Log: debug.h -+ * -+ * 12 16 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * fixed the Windows DDK free build compiling error. -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Using the new XLOG define for dum Memory. -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Add dumpMemory8 at XLOG support. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 07 2011 wh.su -+ * [WCXRP00000326] [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!! -+ * . -+ * -+ * 09 23 2010 cp.wu -+ * NULL -+ * add BOW index for debugging message and passing compilation -+ * -+ * 07 20 2010 wh.su -+ * -+ * adding the wapi code. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add one more debug moduel for P2P. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add bss.c. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add debug module index for cnm and ais. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add CFG_STARTUP_DEBUG for debugging starting up issue. -+ * -+ * 04 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) surpress compiler warning -+ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-10-29 19:47:50 GMT mtk01084 -+** add emu category -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-17 18:12:04 GMT mtk01426 -+** Don't use dynamic memory allocate for debug message -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:29 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _DEBUG_H -+#define _DEBUG_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#ifndef BUILD_QA_DBG -+#define BUILD_QA_DBG 0 -+#endif -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_typedef.h" -+ -+extern UINT_8 aucDebugModule[]; -+extern UINT_32 u4DebugModule; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Define debug category (class): -+ * (1) ERROR (2) WARN (3) STATE (4) EVENT (5) TRACE (6) INFO (7) LOUD (8) TEMP -+ */ -+#define DBG_CLASS_ERROR BIT(0) -+#define DBG_CLASS_WARN BIT(1) -+#define DBG_CLASS_STATE BIT(2) -+#define DBG_CLASS_EVENT BIT(3) -+#define DBG_CLASS_TRACE BIT(4) -+#define DBG_CLASS_INFO BIT(5) -+#define DBG_CLASS_LOUD BIT(6) -+#define DBG_CLASS_TEMP BIT(7) -+#define DBG_CLASS_MASK BITS(0, 7) -+ -+#if defined(LINUX) -+#define DBG_PRINTF_64BIT_DEC "lld" -+ -+#else /* Windows */ -+#define DBG_PRINTF_64BIT_DEC "I64d" -+ -+#endif -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Define debug module index */ -+typedef enum _ENUM_DBG_MODULE_T { -+ DBG_INIT_IDX = 0, /* For driver initial */ -+ DBG_HAL_IDX, /* For HAL(HW) Layer */ -+ DBG_INTR_IDX, /* For Interrupt */ -+ DBG_REQ_IDX, -+ DBG_TX_IDX, -+ DBG_RX_IDX, -+ DBG_RFTEST_IDX, /* For RF test mode */ -+ DBG_EMU_IDX, /* Developer specific */ -+ -+ DBG_SW1_IDX, /* Developer specific */ -+ DBG_SW2_IDX, /* Developer specific */ -+ DBG_SW3_IDX, /* Developer specific */ -+ DBG_SW4_IDX, /* Developer specific */ -+ -+ DBG_HEM_IDX, /* HEM */ -+ DBG_AIS_IDX, /* AIS */ -+ DBG_RLM_IDX, /* RLM */ -+ DBG_MEM_IDX, /* RLM */ -+ DBG_CNM_IDX, /* CNM */ -+ DBG_RSN_IDX, /* RSN */ -+ DBG_BSS_IDX, /* BSS */ -+ DBG_SCN_IDX, /* SCN */ -+ DBG_SAA_IDX, /* SAA */ -+ DBG_AAA_IDX, /* AAA */ -+ DBG_P2P_IDX, /* P2P */ -+ DBG_QM_IDX, /* QUE_MGT */ -+ DBG_SEC_IDX, /* SEC */ -+ DBG_BOW_IDX, /* BOW */ -+ DBG_WAPI_IDX, /* WAPI */ -+ DBG_ROAMING_IDX, /* ROAMING */ -+ DBG_TDLS_IDX, /* TDLS *//* CFG_SUPPORT_TDLS */ -+ DBG_OID_IDX, -+ DBG_NIC_IDX, -+ -+ DBG_MODULE_NUM /* Notice the XLOG check */ -+} ENUM_DBG_MODULE_T; -+ -+/* XLOG */ -+/* #define XLOG_DBG_MODULE_IDX 28 */ /* DBG_MODULE_NUM */ -+/* #if (XLOG_DBG_MODULE_IDX != XLOG_DBG_MODULE_IDX) */ -+/* #error "Please modify the DBG_MODULE_NUM and make sure this include at XLOG" */ -+/* #endif */ -+ -+/* Define who owns developer specific index */ -+#define DBG_YARCO_IDX DBG_SW1_IDX -+#define DBG_KEVIN_IDX DBG_SW2_IDX -+#define DBG_CMC_IDX DBG_SW3_IDX -+#define DBG_GEORGE_IDX DBG_SW4_IDX -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* Debug print format string for the OS system time */ -+#define OS_SYSTIME_DBG_FORMAT "0x%08x" -+ -+/* Debug print argument for the OS system time */ -+#define OS_SYSTIME_DBG_ARGUMENT(systime) (systime) -+ -+/* Debug print format string for the MAC Address */ -+#define MACSTR "%pM" -+/* "%02x:%02x:%02x:%02x:%02x:%02x" */ -+ -+/* Debug print argument for the MAC Address */ -+#define MAC2STR(a) a -+/* ((PUINT_8)a)[0], ((PUINT_8)a)[1], ((PUINT_8)a)[2], ((PUINT_8)a)[3], ((PUINT_8)a)[4], ((PUINT_8)a)[5] */ -+ -+/* The pre-defined format to dump the value of a varaible with its name shown. */ -+#define DUMPVAR(variable, format) (#variable " = " format "\n", variable) -+ -+/* The pre-defined format to dump the MAC type value with its name shown. */ -+#define DUMPMACADDR(addr) (#addr " = %pM\n", (addr)) -+ -+/* Basiclly, we just do renaming of KAL functions although they should -+ * be defined as "Nothing to do" if DBG=0. But in some compiler, the macro -+ * syntax does not support #define LOG_FUNC(x,...) -+ * -+ * A caller shall not invoke these three macros when DBG=0. -+ */ -+ -+/*LOG_FUNC("[wlan]%s:(" #_Module " " #_Class ") "_Fmt, __func__, ##__VA_ARGS__);*/ -+ -+#define LOG_FUNC kalPrint -+ -+#if defined(LINUX) -+#define DBGLOG(_Module, _Class, _Fmt, ...) \ -+ do { \ -+ if ((aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) == 0) \ -+ break; \ -+ LOG_FUNC("%s:(" #_Module " " #_Class ")"_Fmt, __func__, ##__VA_ARGS__); \ -+ } while (0) -+#else -+#define DBGLOG(_Module, _Class, _Fmt) -+#endif -+ -+#if DBG -+ -+#define TMP_BUF_LEN 256 -+#define TMP_WBUF_LEN (TMP_BUF_LEN * 2) -+ -+extern PINT_16 g_wbuf_p; -+extern PINT_8 g_buf_p; -+ -+ /* If __FUNCTION__ is already defined by compiler, we just use it. */ -+#if defined(__func__) -+#define DEBUGFUNC(_Func) -+#else -+#define DEBUGFUNC(_Func) \ -+ static const char __func__[] = _Func -+#endif -+ -+#define DBGLOG_MEM8(_Module, _Class, _StartAddr, _Length) \ -+ { \ -+ if (aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) { \ -+ LOG_FUNC("%s: (" #_Module " " #_Class ")\n", __func__); \ -+ dumpMemory8((PUINT_8) (_StartAddr), (UINT_32) (_Length)); \ -+ } \ -+ } -+ -+#define DBGLOG_MEM32(_Module, _Class, _StartAddr, _Length) \ -+ { \ -+ if (aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) { \ -+ LOG_FUNC("%s: (" #_Module " " #_Class ")\n", __func__); \ -+ dumpMemory32((PUINT_32) (_StartAddr), (UINT_32) (_Length)); \ -+ } \ -+ } -+ /*lint -restore */ -+ -+ /*lint -save -e961 use of '#undef' is discouraged */ -+#undef ASSERT -+ /*lint -restore */ -+ -+#ifdef _lint -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp)) { \ -+ do {} while (1); \ -+ } \ -+ } -+#else -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Assertion failed: %s:%d %s\n", __FILE__, __LINE__, #_exp); \ -+ kalBreakPoint(); \ -+ } \ -+ } -+#endif /* _lint */ -+ -+#define ASSERT_REPORT(_exp, _fmt) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Assertion failed: %s:%d %s\n", __FILE__, __LINE__, #_exp); \ -+ LOG_FUNC _fmt; \ -+ kalBreakPoint(); \ -+ } \ -+ } -+ -+#define DISP_STRING(_str) _str -+ -+#else /* !DBG */ -+ -+#define DEBUGFUNC(_Func) -+#define INITLOG(_Fmt) -+#define ERRORLOG(_Fmt) -+#define WARNLOG(_Fmt) -+ -+#define DBGLOG_MEM8(_Module, _Class, _StartAddr, _Length) -+#define DBGLOG_MEM32(_Module, _Class, _StartAddr, _Length) -+ -+#undef ASSERT -+ -+#if BUILD_QA_DBG -+#if defined(LINUX) /* For debugging in Linux w/o GDB */ -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Assertion failed: %s:%d (%s)\n", __FILE__, __LINE__, #_exp); \ -+ kalBreakPoint(); \ -+ } \ -+ } -+ -+#define ASSERT_REPORT(_exp, _fmt) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Assertion failed: %s:%d (%s)\n", __FILE__, __LINE__, #_exp); \ -+ LOG_FUNC _fmt; \ -+ kalBreakPoint(); \ -+ } \ -+ } -+#else -+#ifdef WINDOWS_CE -+#define UNICODE_TEXT(_msg) TEXT(_msg) -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ TCHAR rUbuf[256]; \ -+ kalBreakPoint(); \ -+ _stprintf(rUbuf, TEXT("Assertion failed: %s:%d %s\n"), \ -+ UNICODE_TEXT(__FILE__), \ -+ __LINE__, \ -+ UNICODE_TEXT(#_exp)); \ -+ MessageBox(NULL, rUbuf, TEXT("ASSERT!"), MB_OK); \ -+ } \ -+ } -+ -+#define ASSERT_REPORT(_exp, _fmt) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ TCHAR rUbuf[256]; \ -+ kalBreakPoint(); \ -+ _stprintf(rUbuf, TEXT("Assertion failed: %s:%d %s\n"), \ -+ UNICODE_TEXT(__FILE__), \ -+ __LINE__, \ -+ UNICODE_TEXT(#_exp)); \ -+ MessageBox(NULL, rUbuf, TEXT("ASSERT!"), MB_OK); \ -+ } \ -+ } -+#else -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ kalBreakPoint(); \ -+ } \ -+ } -+ -+#define ASSERT_REPORT(_exp, _fmt) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ kalBreakPoint(); \ -+ } \ -+ } -+#endif /* WINDOWS_CE */ -+#endif /* LINUX */ -+#else -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Warning at %s:%d (%s)\n", __func__, __LINE__, #_exp); \ -+ } \ -+ } -+ -+#define ASSERT_REPORT(_exp, _fmt) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Warning at %s:%d (%s)\n", __func__, __LINE__, #_exp); \ -+ LOG_FUNC _fmt; \ -+ } \ -+ } -+#endif /* BUILD_QA_DBG */ -+ -+#define DISP_STRING(_str) "" -+ -+#endif /* DBG */ -+ -+#if CFG_STARTUP_DEBUG -+#if defined(LINUX) -+#define DBGPRINTF kalPrint -+#else -+#define DBGPRINTF DbgPrint -+#endif -+#else -+#define DBGPRINTF(...) -+#endif -+ -+/* The following macro is used for debugging packed structures. */ -+#ifndef DATA_STRUCT_INSPECTING_ASSERT -+#define DATA_STRUCT_INSPECTING_ASSERT(expr) \ -+{ \ -+ switch (0) {case 0: case (expr): default:; } \ -+} -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID dumpMemory8(IN PUINT_8 pucStartAddr, IN UINT_32 u4Length); -+ -+VOID dumpMemory32(IN PUINT_32 pu4StartAddr, IN UINT_32 u4Length); -+ -+VOID wlanDebugInit(VOID); -+VOID wlanDebugUninit(VOID); -+VOID wlanTraceReleaseTcRes(P_ADAPTER_T prAdapter, PUINT_8 aucTxRlsCnt, UINT_8 ucAvailable); -+VOID wlanTraceTxCmd(P_CMD_INFO_T prCmd); -+VOID wlanDumpTcResAndTxedCmd(PUINT_8 pucBuf, UINT_32 maxLen); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _DEBUG_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h -new file mode 100644 -index 0000000000000..108860c80e2d4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h -@@ -0,0 +1,368 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/link.h#1 -+*/ -+ -+/*! \file link.h -+ \brief Definition for simple doubly linked list operations. -+ -+ In this file we define the simple doubly linked list data structure and its -+ operation MACROs and INLINE functions. -+*/ -+ -+/* -+** Log: link.h -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Modify a MACRO of LINK_FOR_EACH_SAFE for compile error. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * [WPD00003833] [MT6620 and MT5931] Driver migration -+ * . -+ * -+ * -+ * -+ * -+ * May 4 2009 mtk01084 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * add WIFI to BORA source control -+** \main\maintrunk.MT5921\8 2008-10-16 15:57:11 GMT mtk01461 -+** Update driver to fix lint warning -+** \main\maintrunk.MT5921\7 2008-08-10 18:47:53 GMT mtk01461 -+** Update for Driver Review -+** \main\maintrunk.MT5921\6 2007-12-11 00:09:00 GMT mtk01461 -+** Add macro for checking valid list -+** \main\maintrunk.MT5921\5 2007-11-13 14:27:01 GMT mtk01461 -+** Add LINK_IS_INVALID macro -+** Revision 1.1.1.1 2007/06/22 08:09:05 MTK01461 -+** no message -+** -+*/ -+ -+#ifndef _LINK_H -+#define _LINK_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_typedef.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* May cause page fault & unalignment issue (data abort) */ -+#define INVALID_LINK_POISON1 ((VOID *) 0x00100101) -+/* Used to verify that nonbody uses non-initialized link entries. */ -+#define INVALID_LINK_POISON2 ((VOID *) 0x00100201) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Simple Doubly Linked List Structures - Entry Part */ -+typedef struct _LINK_ENTRY_T { -+ struct _LINK_ENTRY_T *prNext, *prPrev; -+} LINK_ENTRY_T, *P_LINK_ENTRY_T; -+ -+/* Simple Doubly Linked List Structures - List Part */ -+typedef struct _LINK_T { -+ P_LINK_ENTRY_T prNext; -+ P_LINK_ENTRY_T prPrev; -+ UINT_32 u4NumElem; -+} LINK_T, *P_LINK_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#if 0 /* No one use it, temporarily mark it for [Lint - Info 773] */ -+#define LINK_ADDR(rLink) { (P_LINK_ENTRY_T)(&(rLink)), (P_LINK_ENTRY_T)(&(rLink)), 0 } -+ -+#define LINK_DECLARATION(rLink) \ -+ struct _LINK_T rLink = LINK_ADDR(rLink) -+#endif -+ -+#define LINK_INITIALIZE(prLink) \ -+ do { \ -+ ((P_LINK_T)(prLink))->prNext = (P_LINK_ENTRY_T)(prLink); \ -+ ((P_LINK_T)(prLink))->prPrev = (P_LINK_ENTRY_T)(prLink); \ -+ ((P_LINK_T)(prLink))->u4NumElem = 0; \ -+ } while (0) -+ -+#define LINK_ENTRY_INITIALIZE(prEntry) \ -+ do { \ -+ ((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)NULL; \ -+ ((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)NULL; \ -+ } while (0) -+ -+#define LINK_ENTRY_INVALID(prEntry) \ -+ do { \ -+ ((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)INVALID_LINK_POISON1; \ -+ ((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)INVALID_LINK_POISON2; \ -+ } while (0) -+ -+#define LINK_IS_EMPTY(prLink) (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)(prLink)) -+ -+/* NOTE: We should do memory zero before any LINK been initiated, so we can check -+ * if it is valid before parsing the LINK. -+ */ -+#define LINK_IS_INVALID(prLink) (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)NULL) -+ -+#define LINK_IS_VALID(prLink) (((P_LINK_T)(prLink))->prNext != (P_LINK_ENTRY_T)NULL) -+ -+#define LINK_ENTRY(ptr, type, member) ENTRY_OF(ptr, type, member) -+ -+/* Insert an entry into a link list's head */ -+#define LINK_INSERT_HEAD(prLink, prEntry) \ -+ { \ -+ linkAdd(prEntry, prLink); \ -+ ((prLink)->u4NumElem)++; \ -+ } -+ -+/* Append an entry into a link list's tail */ -+#define LINK_INSERT_TAIL(prLink, prEntry) \ -+ { \ -+ linkAddTail(prEntry, prLink); \ -+ ((prLink)->u4NumElem)++; \ -+ } -+ -+/* Peek head entry, but keep still in link list */ -+#define LINK_PEEK_HEAD(prLink, _type, _member) \ -+ ( \ -+ LINK_IS_EMPTY(prLink) ? \ -+ NULL : LINK_ENTRY((prLink)->prNext, _type, _member) \ -+ ) -+ -+/* Peek tail entry, but keep still in link list */ -+#define LINK_PEEK_TAIL(prLink, _type, _member) \ -+ ( \ -+ LINK_IS_EMPTY(prLink) ? \ -+ NULL : LINK_ENTRY((prLink)->prPrev, _type, _member) \ -+ ) -+ -+/* Get first entry from a link list */ -+/* NOTE: We assume the link entry located at the beginning of "prEntry Type", -+ * so that we can cast the link entry to other data type without doubts. -+ * And this macro also decrease the total entry count at the same time. -+ */ -+#define LINK_REMOVE_HEAD(prLink, prEntry, _P_TYPE) \ -+ { \ -+ ASSERT(prLink); \ -+ if (LINK_IS_EMPTY(prLink)) { \ -+ prEntry = (_P_TYPE)NULL; \ -+ } \ -+ else { \ -+ prEntry = (_P_TYPE)(((P_LINK_T)(prLink))->prNext); \ -+ linkDel((P_LINK_ENTRY_T)prEntry); \ -+ ((prLink)->u4NumElem)--; \ -+ } \ -+ } -+ -+/* Assume the link entry located at the beginning of prEntry Type. -+ * And also decrease the total entry count. -+ */ -+#define LINK_REMOVE_KNOWN_ENTRY(prLink, prEntry) \ -+ { \ -+ ASSERT(prLink); \ -+ ASSERT(prEntry); \ -+ linkDel((P_LINK_ENTRY_T)prEntry); \ -+ ((prLink)->u4NumElem)--; \ -+ } -+ -+/* Iterate over a link list */ -+#define LINK_FOR_EACH(prEntry, prLink) \ -+ for (prEntry = (prLink)->prNext; \ -+ prEntry != (P_LINK_ENTRY_T)(prLink); \ -+ prEntry = (P_LINK_ENTRY_T)prEntry->prNext) -+ -+/* Iterate over a link list backwards */ -+#define LINK_FOR_EACH_PREV(prEntry, prLink) \ -+ for (prEntry = (prLink)->prPrev; \ -+ prEntry != (P_LINK_ENTRY_T)(prLink); \ -+ prEntry = (P_LINK_ENTRY_T)prEntry->prPrev) -+ -+/* Iterate over a link list safe against removal of link entry */ -+#define LINK_FOR_EACH_SAFE(prEntry, prNextEntry, prLink) \ -+ for (prEntry = (prLink)->prNext, prNextEntry = prEntry->prNext; \ -+ prEntry != (P_LINK_ENTRY_T)(prLink); \ -+ prEntry = prNextEntry, prNextEntry = prEntry->prNext) -+ -+/* Iterate over a link list of given type */ -+#define LINK_FOR_EACH_ENTRY(prObj, prLink, rMember, _TYPE) \ -+ for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember); \ -+ &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \ -+ prObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember)) -+ -+/* Iterate backwards over a link list of given type */ -+#define LINK_FOR_EACH_ENTRY_PREV(prObj, prLink, rMember, _TYPE) \ -+ for (prObj = LINK_ENTRY((prLink)->prPrev, _TYPE, rMember); \ -+ &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \ -+ prObj = LINK_ENTRY(prObj->rMember.prPrev, _TYPE, rMember)) -+ -+/* Iterate over a link list of given type safe against removal of link entry */ -+#define LINK_FOR_EACH_ENTRY_SAFE(prObj, prNextObj, prLink, rMember, _TYPE) \ -+ for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember), \ -+ prNextObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember); \ -+ &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \ -+ prObj = prNextObj, \ -+ prNextObj = LINK_ENTRY(prNextObj->rMember.prNext, _TYPE, rMember)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is only for internal link list manipulation. -+* -+* \param[in] prNew Pointer of new link head -+* \param[in] prPrev Pointer of previous link head -+* \param[in] prNext Pointer of next link head -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID __linkAdd(IN P_LINK_ENTRY_T prNew, IN P_LINK_ENTRY_T prPrev, IN P_LINK_ENTRY_T prNext) -+{ -+ prNext->prPrev = prNew; -+ prNew->prNext = prNext; -+ prNew->prPrev = prPrev; -+ prPrev->prNext = prNew; -+ -+} /* end of __linkAdd() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will add a new entry after the specified link head. -+* -+* \param[in] prNew New entry to be added -+* \param[in] prHead Specified link head to add it after -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID linkAdd(IN P_LINK_ENTRY_T prNew, IN P_LINK_T prLink) -+{ -+ __linkAdd(prNew, (P_LINK_ENTRY_T) prLink, prLink->prNext); -+ -+} /* end of linkAdd() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will add a new entry before the specified link head. -+* -+* \param[in] prNew New entry to be added -+* \param[in] prHead Specified link head to add it before -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID linkAddTail(IN P_LINK_ENTRY_T prNew, IN P_LINK_T prLink) -+{ -+ __linkAdd(prNew, prLink->prPrev, (P_LINK_ENTRY_T) prLink); -+ -+} /* end of linkAddTail() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is only for internal link list manipulation. -+* -+* \param[in] prPrev Pointer of previous link head -+* \param[in] prNext Pointer of next link head -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID __linkDel(IN P_LINK_ENTRY_T prPrev, IN P_LINK_ENTRY_T prNext) -+{ -+ prNext->prPrev = prPrev; -+ prPrev->prNext = prNext; -+ -+} /* end of __linkDel() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will delete a specified entry from link list. -+* NOTE: the entry is in an initial state. -+* -+* \param prEntry Specified link head(entry) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID linkDel(IN P_LINK_ENTRY_T prEntry) -+{ -+ __linkDel(prEntry->prPrev, prEntry->prNext); -+ -+ LINK_ENTRY_INITIALIZE(prEntry); -+ -+} /* end of linkDel() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will delete a specified entry from link list and then add it -+* after the specified link head. -+* -+* \param[in] prEntry Specified link head(entry) -+* \param[in] prOtherHead Another link head to add it after -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID linkMove(IN P_LINK_ENTRY_T prEntry, IN P_LINK_T prLink) -+{ -+ __linkDel(prEntry->prPrev, prEntry->prNext); -+ linkAdd(prEntry, prLink); -+ -+} /* end of linkMove() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will delete a specified entry from link list and then add it -+* before the specified link head. -+* -+* \param[in] prEntry Specified link head(entry) -+* \param[in] prOtherHead Another link head to add it before -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID linkMoveTail(IN P_LINK_ENTRY_T prEntry, IN P_LINK_T prLink) -+{ -+ __linkDel(prEntry->prPrev, prEntry->prNext); -+ linkAddTail(prEntry, prLink); -+ -+} /* end of linkMoveTail() */ -+ -+#endif /* _LINK_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h -new file mode 100644 -index 0000000000000..fd83c79ffe103 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h -@@ -0,0 +1,188 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/aa_fsm.h#1 -+*/ -+ -+/*! \file aa_fsm.h -+ \brief Declaration of functions and finite state machine for SAA/AAA Module. -+ -+ Declaration of functions and finite state machine for SAA/AAA Module. -+*/ -+ -+/* -+** Log: aa_fsm.h -+ * -+ * 10 13 2011 cp.wu -+ * [MT6620 Wi-Fi][Driver] Reduce join failure count limit to 2 for faster re-join for other BSS -+ * 1. short join failure count limit to 2 -+ * 2. treat join timeout as kind of join failure as well -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * refine TX-DONE callback. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise MGMT Handler with Retain Status -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+#ifndef _AA_FSM_H -+#define _AA_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Retry interval for retransmiting authentication-request MMPDU. */ -+#define TX_AUTHENTICATION_RETRY_TIMEOUT_TU 100 /* TU. */ -+ -+/* Retry interval for retransmiting association-request MMPDU. */ -+#define TX_ASSOCIATION_RETRY_TIMEOUT_TU 100 /* TU. */ -+ -+/* Wait for a response to a transmitted authentication-request MMPDU. */ -+#define DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU 512 /* TU. */ -+ -+/* Wait for a response to a transmitted association-request MMPDU. */ -+#define DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU 512 /* TU. */ -+ -+/* The maximum time to wait for JOIN process complete. */ -+#define JOIN_FAILURE_TIMEOUT_BEACON_INTERVAL 20 /* Beacon Interval, 20 * 100TU = 2 sec. */ -+ -+/* Retry interval for next JOIN request. */ -+#define JOIN_RETRY_INTERVAL_SEC 10 /* Seconds */ -+ -+/* Maximum Retry Count for accept a JOIN request. */ -+#define JOIN_MAX_RETRY_FAILURE_COUNT 2 /* Times */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_AA_STATE_T { -+ AA_STATE_IDLE = 0, -+ SAA_STATE_SEND_AUTH1, -+ SAA_STATE_WAIT_AUTH2, -+ SAA_STATE_SEND_AUTH3, -+ SAA_STATE_WAIT_AUTH4, -+ SAA_STATE_SEND_ASSOC1, -+ SAA_STATE_WAIT_ASSOC2, -+ AAA_STATE_SEND_AUTH2, -+ AAA_STATE_SEND_AUTH4, /* We may not use, because P2P GO didn't support WEP and 11r */ -+ AAA_STATE_SEND_ASSOC2, -+ AA_STATE_RESOURCE, /* A state for debugging the case of out of msg buffer. */ -+ AA_STATE_NUM -+} ENUM_AA_STATE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in saa_fsm.c */ -+/*----------------------------------------------------------------------------*/ -+VOID -+saaFsmSteps(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN ENUM_AA_STATE_T eNextState, IN P_SW_RFB_T prRetainedSwRfb); -+ -+WLAN_STATUS -+saaFsmSendEventJoinComplete(IN P_ADAPTER_T prAdapter, -+ WLAN_STATUS rJoinStatus, P_STA_RECORD_T prStaRec, P_SW_RFB_T prSwRfb); -+ -+VOID saaFsmRunEventStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+WLAN_STATUS -+saaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID saaFsmRunEventTxReqTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+VOID saaFsmRunEventRxRespTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+VOID saaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS saaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS saaFsmRunEventRxDeauth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS saaFsmRunEventRxDisassoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID saaFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines in aaa_fsm.c */ -+/*----------------------------------------------------------------------------*/ -+VOID aaaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS aaaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS -+aaaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _AA_FSM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h -new file mode 100644 -index 0000000000000..b771bdacf2c62 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h -@@ -0,0 +1,573 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/ais_fsm.h#1 -+*/ -+ -+/*! \file ais_fsm.h -+ \brief Declaration of functions and finite state machine for AIS Module. -+ -+ Declaration of functions and finite state machine for AIS Module. -+*/ -+ -+/* -+** Log: ais_fsm.h -+ * -+ * 11 22 2011 cp.wu -+ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition -+ * from synchronous to asynchronous approach to avoid incomplete state termination -+ * 1. change RDD related compile option brace position. -+ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS -+ * is in Normal TR state without join timeout timer ticking -+ * 3. otherwise, insert AIS_REQUEST into pending request queue -+ * -+ * 04 25 2011 cp.wu -+ * [WCXRP00000676] [MT6620 Wi-Fi][Driver] AIS to reduce request channel period from 5 seconds to 2 seconds -+ * channel interval for joining is shortened to 2 seconds to avoid interruption of concurrent operating network. -+ * -+ * 02 26 2011 tsaiyuan.hsu -+ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support -+ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. -+ * -+ * 02 22 2011 cp.wu -+ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with -+ * a queue-based approach to improve response time for scanning request -+ * handle SCAN and RECONNECT with a FIFO approach. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 14 2011 cp.wu -+ * [WCXRP00000359] [MT6620 Wi-Fi][Driver] add an extra state to ensure DEAUTH frame is always sent -+ * Add an extra state to guarantee DEAUTH frame is sent then connect to new BSS. -+ * This change is due to WAPI AP needs DEAUTH frame as a necessary step in handshaking protocol. -+ * -+ * 11 25 2010 cp.wu -+ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM -+ * add scanning with specified SSID facility to AIS-FSM -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * 1) initialize for correct parameter even for disassociation. -+ * 2) AIS-FSM should have a limit on trials to build connection -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * [AIS-FSM] IBSS no longer needs to acquire channel for beaconing, RLM/CNM will handle -+ * the channel switching when BSS information is updated -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 26 2010 cp.wu -+ * -+ * AIS-FSM: when scan request is coming in the 1st 5 seconds of channel privilege period, -+ * just pend it til 5-sec. period finishes -+ * -+ * 07 26 2010 cp.wu -+ * -+ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet -+ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found -+ * -+ * 07 23 2010 cp.wu -+ * -+ * add AIS-FSM handling for beacon timeout event. -+ * -+ * 07 21 2010 cp.wu -+ * -+ * separate AIS-FSM states into different cases of channel request. -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Refine AIS-FSM by divided into more states -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, -+ * other request will be directly dropped by returning BUSY -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add definitions for module migration. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 23 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * reduce the background ssid idle time min and max value -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support -+ * * and will send Null frame to diagnose connection -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Remove CFG_TEST_VIRTUAL_CMD and add support of Driver STA_RECORD_T activation -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Support dynamic channel selection -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add Media disconnect indication and related postpone functions -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add aisFsmRunEventJoinComplete() -+ * -+ * Nov 25 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add Virtual CMD & RESP for testing CMD PATH -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * add aisFsmInitializeConnectionSettings() -+ * -+ * Nov 20 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add CFG_TEST_MGMT_FSM for aisFsmTest() -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add function prototype of aisFsmInit() -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+#ifndef _AIS_FSM_H -+#define _AIS_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define AIS_BG_SCAN_INTERVAL_MIN_SEC 2 /* 30 // exponential to 960 */ -+#define AIS_BG_SCAN_INTERVAL_MAX_SEC 2 /* 960 // 16min */ -+ -+#define AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4 2 /* 2.4G scan need about 0.5s, so delay 2s to reconnect is enough */ -+#define AIS_DELAY_TIME_OF_DISC_SEC_DUALBAND 5 /* 2.4G scan need about 3.3s, so delay 5s to reconnect is enough */ -+ -+#define AIS_IBSS_ALONE_TIMEOUT_SEC 20 /* seconds */ -+ -+#define AIS_BEACON_TIMEOUT_COUNT_ADHOC 30 -+#define AIS_BEACON_TIMEOUT_COUNT_INFRA 10 -+#define AIS_BEACON_TIMEOUT_GUARD_TIME_SEC 1 /* Second */ -+ -+#define AIS_BEACON_MAX_TIMEOUT_TU 100 -+#define AIS_BEACON_MIN_TIMEOUT_TU 5 -+#define AIS_BEACON_MAX_TIMEOUT_VALID TRUE -+#define AIS_BEACON_MIN_TIMEOUT_VALID TRUE -+ -+#define AIS_BMC_MAX_TIMEOUT_TU 100 -+#define AIS_BMC_MIN_TIMEOUT_TU 5 -+#define AIS_BMC_MAX_TIMEOUT_VALID TRUE -+#define AIS_BMC_MIN_TIMEOUT_VALID TRUE -+ -+#define AIS_JOIN_CH_GRANT_THRESHOLD 10 -+#define AIS_JOIN_CH_REQUEST_INTERVAL 3000 -+ -+#define AIS_SCN_DONE_TIMEOUT_SEC 30 /* 15 for 2.4G + 5G */ /* 5 */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_AIS_STATE_T { -+ AIS_STATE_IDLE = 0, -+ AIS_STATE_SEARCH, -+ AIS_STATE_SCAN, -+ AIS_STATE_ONLINE_SCAN, -+ AIS_STATE_LOOKING_FOR, -+ AIS_STATE_WAIT_FOR_NEXT_SCAN, -+ AIS_STATE_REQ_CHANNEL_JOIN, -+ AIS_STATE_JOIN, -+ AIS_STATE_IBSS_ALONE, -+ AIS_STATE_IBSS_MERGE, -+ AIS_STATE_NORMAL_TR, -+ AIS_STATE_DISCONNECTING, -+ AIS_STATE_REQ_REMAIN_ON_CHANNEL, -+ AIS_STATE_REMAIN_ON_CHANNEL, -+ AIS_STATE_NUM -+} ENUM_AIS_STATE_T; -+ -+typedef struct _MSG_AIS_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucReasonOfDisconnect; -+ BOOLEAN fgDelayIndication; -+} MSG_AIS_ABORT_T, *P_MSG_AIS_ABORT_T; -+ -+typedef struct _MSG_AIS_IBSS_PEER_FOUND_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+ BOOLEAN fgIsMergeIn; /* TRUE: Merge In, FALSE: Merge Out */ -+ P_STA_RECORD_T prStaRec; -+} MSG_AIS_IBSS_PEER_FOUND_T, *P_MSG_AIS_IBSS_PEER_FOUND_T; -+ -+typedef enum _ENUM_AIS_REQUEST_TYPE_T { -+ AIS_REQUEST_SCAN, -+ AIS_REQUEST_RECONNECT, -+ AIS_REQUEST_ROAMING_SEARCH, -+ AIS_REQUEST_ROAMING_CONNECT, -+ AIS_REQUEST_REMAIN_ON_CHANNEL, -+ AIS_REQUEST_NUM -+} ENUM_AIS_REQUEST_TYPE_T; -+ -+typedef struct _AIS_REQ_HDR_T { -+ LINK_ENTRY_T rLinkEntry; -+ ENUM_AIS_REQUEST_TYPE_T eReqType; -+} AIS_REQ_HDR_T, *P_AIS_REQ_HDR_T; -+ -+typedef struct _AIS_REQ_CHNL_INFO { -+ ENUM_BAND_T eBand; -+ ENUM_CHNL_EXT_T eSco; -+ UINT_8 ucChannelNum; -+ UINT_32 u4DurationMs; -+ UINT_64 u8Cookie; -+} AIS_REQ_CHNL_INFO, *P_AIS_REQ_CHNL_INFO; -+ -+typedef struct _AIS_MGMT_TX_REQ_INFO_T { -+ BOOLEAN fgIsMgmtTxRequested; -+ P_MSDU_INFO_T prMgmtTxMsdu; -+ UINT_64 u8Cookie; -+} AIS_MGMT_TX_REQ_INFO_T, *P_AIS_MGMT_TX_REQ_INFO_T; -+ -+typedef struct _AIS_FSM_INFO_T { -+ ENUM_AIS_STATE_T ePreviousState; -+ ENUM_AIS_STATE_T eCurrentState; -+ -+ BOOLEAN fgTryScan; -+ -+ BOOLEAN fgIsInfraChannelFinished; -+ BOOLEAN fgIsChannelRequested; -+ BOOLEAN fgIsChannelGranted; -+ -+#if CFG_SUPPORT_ROAMING -+ BOOLEAN fgIsRoamingScanPending; -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ UINT_8 ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ -+ -+ P_BSS_DESC_T prTargetBssDesc; /* For destination */ -+ -+ P_STA_RECORD_T prTargetStaRec; /* For JOIN Abort */ -+ -+ UINT_32 u4SleepInterval; -+ -+ TIMER_T rBGScanTimer; -+ -+ TIMER_T rIbssAloneTimer; -+ -+ TIMER_T rIndicationOfDisconnectTimer; -+ -+ TIMER_T rJoinTimeoutTimer; -+ -+ TIMER_T rChannelTimeoutTimer; -+ -+ TIMER_T rScanDoneTimer; -+ -+ TIMER_T rDeauthDoneTimer; -+ -+ UINT_8 ucSeqNumOfReqMsg; -+ UINT_8 ucSeqNumOfChReq; -+ UINT_8 ucSeqNumOfScanReq; -+ -+ UINT_32 u4ChGrantedInterval; -+ -+ UINT_8 ucConnTrialCount; -+ -+ UINT_8 ucScanSSIDLen; -+ UINT_8 aucScanSSID[ELEM_MAX_LEN_SSID]; -+ -+ UINT_32 u4ScanIELength; -+ UINT_8 aucScanIEBuf[MAX_IE_LENGTH]; -+ -+ /* Pending Request List */ -+ LINK_T rPendingReqList; -+ -+ /* Join Request Timestamp */ -+ OS_SYSTIME rJoinReqTime; -+ -+ /* for cfg80211 REMAIN_ON_CHANNEL support */ -+ AIS_REQ_CHNL_INFO rChReqInfo; -+ -+ /* Mgmt tx related. */ -+ AIS_MGMT_TX_REQ_INFO_T rMgmtTxInfo; -+ -+ /* Packet filter for AIS module. */ -+ UINT_32 u4AisPacketFilter; -+ -+} AIS_FSM_INFO_T, *P_AIS_FSM_INFO_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define aisChangeMediaState(_prAdapter, _eNewMediaState) \ -+ (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState = (_eNewMediaState)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID aisInitializeConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo); -+ -+VOID aisFsmInit(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmUninit(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmStateInit_JOIN(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); -+ -+BOOLEAN aisFsmStateInit_RetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+VOID aisFsmStateInit_IBSS_ALONE(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmStateInit_IBSS_MERGE(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); -+ -+VOID aisFsmStateAbort(IN P_ADAPTER_T prAdapter, UINT_8 ucReasonOfDisconnect, BOOLEAN fgDelayIndication); -+ -+VOID aisFsmStateAbort_JOIN(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmStateAbort_SCAN(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmStateAbort_NORMAL_TR(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmStateAbort_IBSS(IN P_ADAPTER_T prAdapter); -+#if 0 -+VOID aisFsmSetChannelInfo(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ ScanReqMsg, IN ENUM_AIS_STATE_T CurrentState); -+#endif -+VOID aisFsmSteps(IN P_ADAPTER_T prAdapter, ENUM_AIS_STATE_T eNextState); -+ -+/*----------------------------------------------------------------------------*/ -+/* Mailbox Message Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFsmRunEventFoundIBSSPeer(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFsmRunEventRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFsmRunEventCancelRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+/*----------------------------------------------------------------------------*/ -+/* Handling for Ad-Hoc Network */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmCreateIBSS(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+/*----------------------------------------------------------------------------*/ -+/* Handling of Incoming Mailbox Message from CNM */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+/*----------------------------------------------------------------------------*/ -+/* Generating Outgoing Mailbox Message to CNM */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmReleaseCh(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Event Indication */ -+/*----------------------------------------------------------------------------*/ -+VOID -+aisIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, -+ ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication); -+ -+VOID aisPostponedEventOfDisconnTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, P_SW_RFB_T prAssocRspSwRfb); -+ -+VOID aisUpdateBssInfoForCreateIBSS(IN P_ADAPTER_T prAdapter); -+ -+VOID aisUpdateBssInfoForMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+BOOLEAN aisValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); -+ -+WLAN_STATUS -+aisFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+/*----------------------------------------------------------------------------*/ -+/* Disconnection Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmDisconnect(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgDelayIndication); -+ -+/*----------------------------------------------------------------------------*/ -+/* Event Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID aisBssBeaconTimeout(IN P_ADAPTER_T prAdapter); -+ -+VOID aisBssSecurityChanged(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS -+aisDeauthXmitComplete(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+#if CFG_SUPPORT_ROAMING -+VOID aisFsmRunEventRoamingDiscovery(IN P_ADAPTER_T prAdapter, UINT_32 u4ReqScan); -+ -+ENUM_AIS_STATE_T aisFsmRoamingScanResultsUpdate(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmRoamingDisconnectPrevAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prTargetStaRec); -+ -+VOID aisUpdateBssInfoForRoamingAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb); -+#endif /*CFG_SUPPORT_ROAMING */ -+ -+/*----------------------------------------------------------------------------*/ -+/* Timeout Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventBGSleepTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisFsmRunEventIbssAloneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisFsmRunEventJoinTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisFsmRunEventChannelTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisFsmRunEventScanDoneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisFsmRunEventDeauthTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+/*----------------------------------------------------------------------------*/ -+/* OID/IOCTL Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmScanRequest(IN P_ADAPTER_T prAdapter, IN P_PARAM_SSID_T prSsid, IN PUINT_8 pucIe, IN UINT_32 u4IeLength); -+ -+/*----------------------------------------------------------------------------*/ -+/* Internal State Checking */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN aisFsmIsRequestPending(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType, IN BOOLEAN bRemove); -+ -+P_AIS_REQ_HDR_T aisFsmGetNextRequest(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN aisFsmInsertRequest(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType); -+ -+VOID aisFsmFlushRequest(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS -+aisFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, -+ IN P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie); -+ -+VOID aisFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+#if defined(CFG_TEST_MGMT_FSM) && (CFG_TEST_MGMT_FSM != 0) -+VOID aisTest(VOID); -+#endif /* CFG_TEST_MGMT_FSM */ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _AIS_FSM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h -new file mode 100644 -index 0000000000000..70b32bca102bc ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h -@@ -0,0 +1,112 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/assoc.h#1 -+*/ -+ -+/*! \file assoc.h -+ \brief This file contains the ASSOC REQ/RESP of -+ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: assoc.h -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add assocCheckTxReAssocRespFrame() proto type for P2P usage. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+*/ -+ -+#ifndef _ASSOC_H -+#define _ASSOC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in assoc.c */ -+/*----------------------------------------------------------------------------*/ -+UINT_16 assocBuildCapabilityInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS assocSendReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS assocCheckTxReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+WLAN_STATUS assocCheckTxReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+WLAN_STATUS -+assocCheckRxReAssocRspFrameStatus(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); -+ -+WLAN_STATUS assocSendDisAssocFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2ReasonCode); -+ -+WLAN_STATUS -+assocProcessRxDisassocFrame(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode); -+ -+WLAN_STATUS assocProcessRxAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); -+ -+WLAN_STATUS assocSendReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _ASSOC_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h -new file mode 100644 -index 0000000000000..4f76f03324dde ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h -@@ -0,0 +1,125 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/auth.h#1 -+*/ -+ -+/*! \file auth.h -+ \brief This file contains the authentication REQ/RESP of -+ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: auth.h -+ * -+ * 04 21 2011 terry.wu -+ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame -+ * Add network type parameter to authSendAuthFrame. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+*/ -+ -+#ifndef _AUTH_H -+#define _AUTH_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in auth.c */ -+/*----------------------------------------------------------------------------*/ -+VOID authAddIEChallengeText(IN P_ADAPTER_T prAdapter, IN OUT P_MSDU_INFO_T prMsduInfo); -+ -+#if !CFG_SUPPORT_AAA -+WLAN_STATUS authSendAuthFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2TransactionSeqNum); -+#else -+WLAN_STATUS -+authSendAuthFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN P_SW_RFB_T prFalseAuthSwRfb, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode); -+#endif /* CFG_SUPPORT_AAA */ -+ -+WLAN_STATUS authCheckTxAuthFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN UINT_16 u2TransactionSeqNum); -+ -+WLAN_STATUS authCheckRxAuthFrameTransSeq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS -+authCheckRxAuthFrameStatus(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN UINT_16 u2TransactionSeqNum, OUT PUINT_16 pu2StatusCode); -+ -+VOID authHandleIEChallengeText(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, P_IE_HDR_T prIEHdr); -+ -+WLAN_STATUS authProcessRxAuth2_Auth4Frame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS -+authSendDeauthFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN P_SW_RFB_T prClassErrSwRfb, IN UINT_16 u2ReasonCode, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); -+ -+WLAN_STATUS authProcessRxDeauthFrame(IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode); -+ -+WLAN_STATUS -+authProcessRxAuth1Frame(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, -+ IN UINT_8 aucExpectedBSSID[], -+ IN UINT_16 u2ExpectedAuthAlgNum, -+ IN UINT_16 u2ExpectedTransSeqNum, OUT PUINT_16 pu2ReturnStatusCode); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _AUTH_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h -new file mode 100644 -index 0000000000000..5995d133a6cdf ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h -@@ -0,0 +1,184 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/bow_fsm.h#1 -+*/ -+ -+/*! \file bow_fsm.h -+ \brief Declaration of functions and finite state machine for BOW Module. -+ -+ Declaration of functions and finite state machine for BOW Module. -+*/ -+ -+/* -+** Log: bow_fsm.h -+ * -+ * 05 22 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Submit missing BoW header files. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support multiple physical link. -+ * -+ * 02 16 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add bowNotifyAllLinkDisconnected interface and change channel grant procedure for bow starting.. -+ * -+ * 02 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add channel previledge into _BOW_FSM_INFO_T. -+ * -+ * 09 16 2010 chinghwa.yu -+ * NULL -+ * update bowChangeMediaState. -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update BOW for the 1st time. -+ */ -+ -+#ifndef _BOW_FSM_H -+#define _BOW_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define BOW_BG_SCAN_INTERVAL_MIN_SEC 2 /* 30 // exponential to 960 */ -+#define BOW_BG_SCAN_INTERVAL_MAX_SEC 2 /* 960 // 16min */ -+ -+#define BOW_DELAY_TIME_OF_DISCONNECT_SEC 10 -+ -+#define BOW_BEACON_TIMEOUT_COUNT_STARTING 10 -+#define BOW_BEACON_TIMEOUT_GUARD_TIME_SEC 1 /* Second */ -+ -+#define BOW_BEACON_MAX_TIMEOUT_TU 100 -+#define BOW_BEACON_MIN_TIMEOUT_TU 5 -+#define BOW_BEACON_MAX_TIMEOUT_VALID TRUE -+#define BOW_BEACON_MIN_TIMEOUT_VALID TRUE -+ -+#define BOW_BMC_MAX_TIMEOUT_TU 100 -+#define BOW_BMC_MIN_TIMEOUT_TU 5 -+#define BOW_BMC_MAX_TIMEOUT_VALID TRUE -+#define BOW_BMC_MIN_TIMEOUT_VALID TRUE -+ -+#define BOW_JOIN_CH_GRANT_THRESHOLD 10 -+#define BOW_JOIN_CH_REQUEST_INTERVAL 2000 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _ENUM_BOW_STATE_T { -+ BOW_STATE_IDLE = 0, -+ BOW_STATE_SEARCH, -+ BOW_STATE_SCAN, -+ BOW_STATE_ONLINE_SCAN, -+ BOW_STATE_LOOKING_FOR, -+ BOW_STATE_WAIT_FOR_NEXT_SCAN, -+ BOW_STATE_REQ_CHANNEL_JOIN, -+ BOW_STATE_REQ_CHANNEL_ALONE, -+ BOW_STATE_REQ_CHANNEL_MERGE, -+ BOW_STATE_JOIN, -+ BOW_STATE_IBSS_ALONE, -+ BOW_STATE_IBSS_MERGE, -+ BOW_STATE_NORMAL_TR, -+ BOW_STATE_NUM -+} ENUM_BOW_STATE_T; -+ -+typedef struct _BOW_FSM_INFO_T { -+ ENUM_BOW_STATE_T ePreviousState; -+ ENUM_BOW_STATE_T eCurrentState; -+ -+ BOOLEAN fgTryScan; -+ -+ /* Channel Privilege */ -+ -+ BOOLEAN fgIsInfraChannelFinished; -+ BOOLEAN fgIsChannelRequested; -+ BOOLEAN fgIsChannelGranted; -+ BOOLEAN fgIsScanPending; -+ UINT_32 u4ChGrantedInterval; -+ -+ UINT_8 ucPrimaryChannel; -+ ENUM_BAND_T eBand; -+ UINT_16 u2BeaconInterval; -+ -+ ENUM_BOW_STATE_T eReturnState; /* Return state after current activity finished or abort. */ -+ ENUM_BOW_STATE_T eForwardState; /* Step to next state if ACTION frame is TX successfully. */ -+ -+ P_BSS_DESC_T prTargetBss; /* BSS of target P2P Device. For Connection/Service Discovery */ -+ -+ P_STA_RECORD_T prTargetStaRec; -+ P_BSS_DESC_T prTargetBssDesc; /* For destination */ -+ -+ UINT_8 aucPeerAddress[6]; -+ -+ UINT_8 ucRole; -+ -+ BOOLEAN fgSupportQoS; -+ -+ BOOLEAN fgIsRsponseProbe; /* Indicate if BOW can response probe request frame. */ -+ -+ /* Sequence number of requested message. */ -+ UINT_8 ucSeqNumOfChReq; -+ UINT_8 ucSeqNumOfReqMsg; -+ UINT_8 ucSeqNumOfScnMsg; -+ UINT_8 ucSeqNumOfScanReq; -+ -+ UINT_8 ucSeqNumOfCancelMsg; -+ -+ UINT_8 ucDialogToken; -+ -+ /* Timer */ -+ TIMER_T rStartingBeaconTimer; /* For device discovery time of each discovery request from user. */ -+ TIMER_T rStartingDiscoveryTimer; -+ TIMER_T rOperationListenTimer; /* For Find phase under operational state. */ -+ TIMER_T rFSMTimer; /* A timer used for Action frame timeout usage. */ -+ TIMER_T rIndicationOfDisconnectTimer; -+ TIMER_T rChGrantedTimer; -+ -+ UINT_8 ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ -+ -+} BOW_FSM_INFO_T, *P_BOW_FSM_INFO_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define bowChangeMediaState(_prAdapter, _eNewMediaState) \ -+ (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX].eConnectionState = (_eNewMediaState)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h -new file mode 100644 -index 0000000000000..0597132b970ef ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h -@@ -0,0 +1,265 @@ -+/* -+** Id: @(#) bss.h -+*/ -+ -+/*! \file "bss.h" -+ \brief In this file we define the function prototype used in BSS/IBSS. -+ -+ The file contains the function declarations and defines for used in BSS/IBSS. -+*/ -+ -+/* -+** Log: bss.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 09 14 2011 yuche.tsai -+ * NULL -+ * Add P2P IE in assoc response. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Make assoc req to append P2P IE if wifi direct is enabled. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * Add code to send beacon and probe response WSC IE at Auto GO. -+ * -+ * 02 23 2011 eddie.chen -+ * [WCXRP00000463] [MT6620 Wi-Fi][FW/Driver][Hotspot] Cannot update WMM PS STA's partital bitmap -+ * Fix parsing WMM INFO and bmp delivery bitmap definition. -+ * -+ * 01 31 2011 george.huang -+ * [WCXRP00000333] [MT5931][FW] support SRAM power control drivers -+ * Extend TIM PVB, from 2 to 3 octets. -+ * -+ * 11 29 2010 cp.wu -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for -+ * initial TX rate selection of auto-rate algorithm -+ * update ucRcpi of STA_RECORD_T for AIS when -+ * 1) Beacons for IBSS merge is received -+ * 2) Associate Response for a connecting peer is received -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Update bssProcessProbeRequest() and bssSendBeaconProbeResponse() declarations -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * when IBSS is being merged-in, send command packet to PM for connected indication -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 25 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Create beacon update path, with expose bssUpdateBeaconContent() -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add CTRL FLAGS for Probe Response. -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add necessary changes to driver data paths. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 06 04 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * [PM] Support U-APSD for STA mode -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Remove unused typedef. -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Fix file merge error -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support -+ * * * and will send Null frame to diagnose connection -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add DTIM count update while TX Beacon -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+*/ -+ -+#ifndef _BSS_H -+#define _BSS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* NOTE(Kevin): change define for george */ -+/* #define MAX_LEN_TIM_PARTIAL_BMP (((MAX_ASSOC_ID + 1) + 7) / 8) */ /* Required bits = (MAX_ASSOC_ID + 1) */ -+#define MAX_LEN_TIM_PARTIAL_BMP ((CFG_STA_REC_NUM + 7) / 8) -+/* reserve length greater than maximum size of STA_REC */ /* obsoleted: Assume we only use AID:1~15 */ -+ -+/* CTRL FLAGS for Probe Response */ -+#define BSS_PROBE_RESP_USE_P2P_DEV_ADDR BIT(0) -+#define BSS_PROBE_RESP_INCLUDE_P2P_IE BIT(1) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define bssAssignAssocID(_prStaRec) ((_prStaRec)->ucIndex + 1) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines for all Operation Modes */ -+/*----------------------------------------------------------------------------*/ -+P_STA_RECORD_T -+bssCreateStaRecFromBssDesc(IN P_ADAPTER_T prAdapter, -+ IN ENUM_STA_TYPE_T eStaType, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_BSS_DESC_T prBssDesc); -+ -+VOID bssComposeNullFrame(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec); -+ -+VOID -+bssComposeQoSNullFrame(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN BOOLEAN fgSetEOSP); -+ -+WLAN_STATUS -+bssSendNullFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); -+ -+WLAN_STATUS -+bssSendQoSNullFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines for both IBSS(AdHoc) and BSS(AP) */ -+/*----------------------------------------------------------------------------*/ -+VOID bssGenerateExtSuppRate_IE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID -+bssBuildBeaconProbeRespFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo, IN PUINT_8 pucDestAddr); -+ -+VOID -+bssComposeBeaconProbeRespFrameHeaderAndFF(IN PUINT_8 pucBuffer, -+ IN PUINT_8 pucDestAddr, -+ IN PUINT_8 pucOwnMACAddress, -+ IN PUINT_8 pucBSSID, IN UINT_16 u2BeaconInterval, IN UINT_16 u2CapInfo); -+ -+WLAN_STATUS -+bssSendBeaconProbeResponse(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN PUINT_8 pucDestAddr, IN UINT_32 u4ControlFlags); -+ -+WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID bssClearClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo); -+ -+VOID bssAddStaRecToClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec); -+ -+VOID bssRemoveStaRecFromClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines for IBSS(AdHoc) only */ -+/*----------------------------------------------------------------------------*/ -+VOID -+ibssProcessMatchedBeacon(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prBssInfo, IN P_BSS_DESC_T prBssDesc, IN UINT_8 ucRCPI); -+ -+WLAN_STATUS ibssCheckCapabilityForAdHocMode(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+VOID ibssInitForAdHoc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo); -+ -+WLAN_STATUS bssUpdateBeaconContent(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines for BSS(AP) only */ -+/*----------------------------------------------------------------------------*/ -+VOID bssInitForAP(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN BOOLEAN fgIsRateUpdate); -+ -+VOID bssUpdateDTIMCount(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+VOID bssSetTIMBitmap(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN UINT_16 u2AssocId); -+ -+P_STA_RECORD_T bssGetClientByAddress(IN P_BSS_INFO_T prBssInfo, PUINT_8 pucMacAddr); -+ -+/*link function to p2p module for txBcnIETable*/ -+ -+/* WMM-2.2.2 WMM ACI to AC coding */ -+typedef enum _ENUM_ACI_T { -+ ACI_BE = 0, -+ ACI_BK = 1, -+ ACI_VI = 2, -+ ACI_VO = 3, -+ ACI_NUM -+} ENUM_ACI_T, *P_ENUM_ACI_T; -+ -+typedef enum _ENUM_AC_PRIORITY_T { -+ AC_BK_PRIORITY = 0, -+ AC_BE_PRIORITY, -+ AC_VI_PRIORITY, -+ AC_VO_PRIORITY -+} ENUM_AC_PRIORITY_T, *P_ENUM_AC_PRIORITY_T; -+ -+#endif /* _BSS_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h -new file mode 100644 -index 0000000000000..81b16b5888672 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h -@@ -0,0 +1,258 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm.h#1 -+*/ -+ -+/*! \file "cnm.h" -+ \brief -+*/ -+ -+/* -+** Log: cnm.h -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 03 10 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Provide function to decide if BSS can be activated or not -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 13 2010 cm.chang -+ * -+ * Rename MSG_CH_RELEASE_T to MSG_CH_ABORT_T -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Need bandwidth info when requesting channel privilege -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Modify CNM message handler for new flow -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add a new function to send abort message -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 08 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support partial part about cmd basic configuration -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add prototype of cnmFsmEventInit() -+ * -+ * Nov 2 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+#ifndef _CNM_H -+#define _CNM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _ENUM_CH_REQ_TYPE_T { -+ CH_REQ_TYPE_JOIN, -+ CH_REQ_TYPE_P2P_LISTEN, -+ -+ CH_REQ_TYPE_NUM -+} ENUM_CH_REQ_TYPE_T, *P_ENUM_CH_REQ_TYPE_T; -+ -+typedef struct _MSG_CH_REQ_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+ UINT_8 ucPrimaryChannel; -+ ENUM_CHNL_EXT_T eRfSco; -+ ENUM_BAND_T eRfBand; -+ ENUM_CH_REQ_TYPE_T eReqType; -+ UINT_32 u4MaxInterval; /* In unit of ms */ -+ UINT_8 aucBSSID[6]; -+ UINT_8 aucReserved[2]; -+} MSG_CH_REQ_T, *P_MSG_CH_REQ_T; -+ -+typedef struct _MSG_CH_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+} MSG_CH_ABORT_T, *P_MSG_CH_ABORT_T; -+ -+typedef struct _MSG_CH_GRANT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+ UINT_8 ucPrimaryChannel; -+ ENUM_CHNL_EXT_T eRfSco; -+ ENUM_BAND_T eRfBand; -+ ENUM_CH_REQ_TYPE_T eReqType; -+ UINT_32 u4GrantInterval; /* In unit of ms */ -+} MSG_CH_GRANT_T, *P_MSG_CH_GRANT_T; -+ -+typedef struct _MSG_CH_REOCVER_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+ UINT_8 ucPrimaryChannel; -+ ENUM_CHNL_EXT_T eRfSco; -+ ENUM_BAND_T eRfBand; -+ ENUM_CH_REQ_TYPE_T eReqType; -+} MSG_CH_RECOVER_T, *P_MSG_CH_RECOVER_T; -+ -+typedef struct _CNM_INFO_T { -+ UINT_32 u4Reserved; -+} CNM_INFO_T, *P_CNM_INFO_T; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+/* Moved from p2p_fsm.h */ -+typedef struct _DEVICE_TYPE_T { -+ UINT_16 u2CategoryId; /* Category ID */ -+ UINT_8 aucOui[4]; /* OUI */ -+ UINT_16 u2SubCategoryId; /* Sub Category ID */ -+} __KAL_ATTRIB_PACKED__ DEVICE_TYPE_T, *P_DEVICE_TYPE_T; -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID cnmInit(P_ADAPTER_T prAdapter); -+ -+VOID cnmUninit(P_ADAPTER_T prAdapter); -+ -+VOID cnmChMngrRequestPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); -+ -+VOID cnmChMngrAbortPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); -+ -+VOID cnmChMngrHandleChEvent(P_ADAPTER_T prAdapter, P_WIFI_EVENT_T prEvent); -+ -+BOOLEAN -+cnmPreferredChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel, P_ENUM_CHNL_EXT_T prBssSCO); -+ -+BOOLEAN cnmAisInfraChannelFixed(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel); -+ -+VOID cnmAisInfraConnectNotify(P_ADAPTER_T prAdapter); -+ -+BOOLEAN cnmAisIbssIsPermitted(P_ADAPTER_T prAdapter); -+ -+BOOLEAN cnmP2PIsPermitted(P_ADAPTER_T prAdapter); -+ -+BOOLEAN cnmBowIsPermitted(P_ADAPTER_T prAdapter); -+ -+BOOLEAN cnmBss40mBwPermitted(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx); -+#if CFG_P2P_LEGACY_COEX_REVISE -+BOOLEAN cnmAisDetectP2PChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel); -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#ifndef _lint -+/* We don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ * We'll need this to guarantee the same member order in different structures -+ * to simply handling effort in some functions. -+ */ -+static inline VOID cnmMsgDataTypeCheck(VOID) -+{ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, rMsgHdr) == 0); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, rMsgHdr) == OFFSET_OF(MSG_CH_RECOVER_T, rMsgHdr)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucNetTypeIndex) == -+ OFFSET_OF(MSG_CH_RECOVER_T, ucNetTypeIndex)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucTokenID) == OFFSET_OF(MSG_CH_RECOVER_T, ucTokenID)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucPrimaryChannel) == -+ OFFSET_OF(MSG_CH_RECOVER_T, ucPrimaryChannel)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eRfSco) == OFFSET_OF(MSG_CH_RECOVER_T, eRfSco)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eRfBand) == OFFSET_OF(MSG_CH_RECOVER_T, eRfBand)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eReqType) == OFFSET_OF(MSG_CH_RECOVER_T, eReqType)); -+ -+} -+#endif /* _lint */ -+ -+#endif /* _CNM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h -new file mode 100644 -index 0000000000000..c8f25b1b29a9f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h -@@ -0,0 +1,1164 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm_mem.h#1 -+*/ -+ -+/*! \file "cnm_mem.h" -+ \brief In this file we define the structure of the control unit of -+ packet buffer and MGT/MSG Memory Buffer. -+*/ -+ -+/* -+** Log: cnm_mem.h -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 03 17 2011 yuche.tsai -+ * NULL -+ * Resize the Secondary Device Type array when WiFi Direct is enabled. -+ * -+ * 03 16 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * enable the protected while at P2P start GO, and skip some security check . -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 11 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Add per STA flow control when STA is in PS mode -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 23 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * 1. update WMM IE parsing, with ASSOC REQ handling -+ * 2. extend U-APSD parameter passing from driver to FW -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 11 29 2010 cm.chang -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for -+ * initial TX rate selection of auto-rate algorithm -+ * Sync RCPI of STA_REC to FW as reference of initial TX rate -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD -+ * when entering RF test with AIS associated -+ * 1. remove redundant variables in STA_REC structure -+ * 2. add STA-REC uninitialization routine for clearing pending events -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 12 2010 cp.wu -+ * -+ * SAA will take a record for tracking request sequence number. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 07 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support state of STA record change from 1 to 1 -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support sync command of STA_REC -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix compile error for P2P related defination. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P related fields. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * saa_fsm.c is migrated. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * restore utility function invoking via hem_mbox to direct calls -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * hem_mbox is migrated. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration -+ * -+ * 06 04 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * [BORA00000678] [MT6620]WiFi LP integration -+ * 1. add u8TimeStamp in MSDU_INFO -+ * 2. move fgIsRxTSFUpdated/fgIsTxTSFUpdated from static to BSS_INFO -+ * 3. add new member for supporting PM in STA_RECORD, which is for AP PS mode -+ * -+ * 05 31 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling -+ * -+ * 05 28 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support checking of duplicated buffer free -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Move define of STA_REC_NUM to config.h and rename to CFG_STA_REC_NUM -+ * -+ * 05 21 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set -+ * -+ * 05 19 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fixed MAC RX Desc be overwritten issue -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 05 10 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support Rx header translation for A-MSDU subframe -+ * -+ * 05 07 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * add more sanity check about setting timer -+ * -+ * 04 29 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * modify the compiling flag for RAM usage -+ * -+ * 04 28 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Modified some MQM-related data structures (SN counter, TX/RX BA table) -+ * -+ * 04 27 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Added new TX/RX BA tables in STA_REC -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support and will send Null frame to diagnose connection -+ * -+ * 04 09 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * [BORA00000644] WiFi phase 4 integration -+ * Added per-TID SN cache in STA_REC -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support power control -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 11 2010 yuche.tsai -+ * [BORA00000343][MT6620] Emulation For TX -+ * . -+ * -+ * 03 05 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Remove Emulation definition -+ * -+ * 03 04 2010 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * eliminate HIF_EMULATION in cnm_mem.h -+ * -+ * 03 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add cnmStaRecChangeState() declaration. -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Remove compiling warning for some emulation flags -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, -+ * and modify the security related callback function prototype. -+ * -+ * 03 01 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * To store field AMPDU Parameters in STA_REC -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added fgIsWmmSupported in STA_RECORD_T. -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added fgIsUapsdSupported in STA_RECORD_T -+ * -+ * 02 13 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added arTspecTable in STA_REC for TSPEC management -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Enable mgmt buffer debug by default -+ * -+ * 02 12 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added BUFFER_SOURCE_BCN -+ * -+ * 02 10 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Renamed MSDU_INFO.ucFixedRateIndex as MSDU_INFO.ucFixedRateCode -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 02 02 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added SN info in MSDU_INFO_T -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 08 2010 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * 1) separate wifi_var_emu.c/.h from wifi_var.c/.h -+ * 2) eliminate HIF_EMULATION code sections appeared in wifi_var/cnm_mem -+ * 3) use cnmMemAlloc() instead to allocate SRAM buffer -+ * -+ * 12 31 2009 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * 1) surpress debug message emitted from hal_hif.c -+ * 2) add two set of field for recording buffer process time -+ * -+ * 12 31 2009 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * 1. move wifi task initialization from wifi_task.c(rom) to wifi_init.c (TCM) for integrating F/W download later -+ * * * * * 2. WIFI_Event_Dispatcher() prototype changed to return to suspend mode from normal operation mode -+ * * * * * 2. HIF emulation logic revised -+ * -+ * 12 29 2009 yuche.tsai -+ * [BORA00000343][MT6620] Emulation For TX -+ * .Using global buffer declaring by SD1 instead of using another one. -+ * -+ * 12 25 2009 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM) -+ * * MQM: BA handling -+ * * TXM: Macros updates -+ * * RXM: Macros/Duplicate Removal updates -+ * -+ * 12 24 2009 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * 12 23 2009 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * allocating SRAM for emulation purpose by ruducing MEM_BANK3_BUF_SZ -+ * -+ * 12 21 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Remove individual DATA_BUF_BLOCK_NUM definition for emulation compiling flagsu1rwduu`wvpghlqg|fh+fmdkb -+ * -+ * 12 21 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support several data buffer banks. -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * .For new FPGA memory size -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * 12 17 2009 george.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 17 2009 MTK02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Modified the DATA_BLOCK_SIZE from 1620 to 2048 -+ * -+ * Dec 16 2009 mtk01426 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add CFG_TEST_SEC_EMULATION flag -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add HT cap to sta record -+ * -+ * Dec 9 2009 mtk02752 -+ * [BORA00000368] Integrate HIF part into BORA -+ * add cnmDataPktFree() for emulation loopback purpose -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * add the buffer for key handshake 1x and cmd key order issue -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * move the tx call back function proto type to typedef.h -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add cnmGetStaRecByAddress() and modify variable in STA_RECORD_T -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * rename the port block flag -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add variables to STA_RECORD_T for assoc/auth -+ * -+ * Nov 23 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Fixed the value of STA_WAIT_QUEUE_NUM (from 7 to 5) -+ * -+ * Nov 20 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Removed u2FrameLength from SW_RFB -+ * -+ * Nov 20 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Fixed indenting -+ * -+ * Nov 20 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Updated MSDU_INFO and SW_RFB -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * update the variable for security -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * remove the variable to make the compiler ok -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * add the variable for security module -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix typo in define of MSG_BUF_BLOCK_SIZE -+ * -+ * Nov 13 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Let typedef STA_REC_T precede typedef MSDU_INFO_T and SW_RFB_T -+ * -+ * Nov 13 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Modified MSDU_INFO and STA_REC for TXM and MQM -+ * -+ * Nov 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Rename STA_REC_T to STA_RECORD_T and add ucIndex member -+ * -+ * Nov 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Make sure ucBufferSource the same offset in MSDU_INFO and SW_RFB -+ * -+ * Nov 6 2009 mtk01426 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Nov 5 2009 mtk01426 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update comment -+ * -+ * Oct 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add draft content of MSDU_INFO_T and SW_RFB_T -+ * -+ * Oct 30 2009 mtk01084 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Oct 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix lint warning -+ * -+ * Oct 21 2009 mtk01426 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add CFG_TEST_RX_EMULATION flag -+ * -+ * Oct 20 2009 mtk01426 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Oct 9 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Added field ucTC to MSDU_INFO_T and field pucHifRxPacket to SW_RFB_T -+ * -+ * Oct 8 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+#ifndef _CNM_MEM_H -+#define _CNM_MEM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#ifndef POWER_OF_2 -+#define POWER_OF_2(n) BIT(n) -+#endif -+ -+/* Size of a basic management buffer block in power of 2 */ -+#define MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2 7 /* 7 to the power of 2 = 128 */ -+#define MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2 5 /* 5 to the power of 2 = 32 */ -+ -+/* Size of a basic management buffer block */ -+#define MGT_BUF_BLOCK_SIZE POWER_OF_2(MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2) -+#define MSG_BUF_BLOCK_SIZE POWER_OF_2(MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2) -+ -+/* Total size of (n) basic management buffer blocks */ -+#define MGT_BUF_BLOCKS_SIZE(n) ((UINT_32)(n) << MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2) -+#define MSG_BUF_BLOCKS_SIZE(n) ((UINT_32)(n) << MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2) -+ -+/* Number of management buffer block */ -+#define MAX_NUM_OF_BUF_BLOCKS 32 /* Range: 1~32 */ -+ -+/* Size of overall management frame buffer */ -+#define MGT_BUFFER_SIZE (MAX_NUM_OF_BUF_BLOCKS * MGT_BUF_BLOCK_SIZE) -+#define MSG_BUFFER_SIZE (MAX_NUM_OF_BUF_BLOCKS * MSG_BUF_BLOCK_SIZE) -+ -+/* STA_REC related definitions */ -+#define STA_REC_INDEX_BMCAST 0xFF -+#define STA_REC_INDEX_NOT_FOUND 0xFE -+#define STA_WAIT_QUEUE_NUM 5 /* Number of SW queues in each STA_REC: AC0~AC4 */ -+#define SC_CACHE_INDEX_NUM 5 /* Number of SC caches in each STA_REC: AC0~AC4 */ -+ -+/* P2P related definitions */ -+#ifdef CFG_ENABLE_WIFI_DIRECT -+/* Moved from p2p_fsm.h */ -+#define WPS_ATTRI_MAX_LEN_DEVICE_NAME 32 /* 0x1011 */ -+#define P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT 8 /* NOTE(Kevin): Shall <= 16 */ -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#if ((MAX_NUM_OF_BUF_BLOCKS > 32) || (MAX_NUM_OF_BUF_BLOCKS <= 0)) -+#error > #define MAX_NUM_OF_MGT_BUF_BLOCKS : Out of boundary ! -+#elif MAX_NUM_OF_BUF_BLOCKS > 16 -+typedef UINT_32 BUF_BITMAP; -+#elif MAX_NUM_OF_BUF_BLOCKS > 8 -+typedef UINT_16 BUF_BITMAP; -+#else -+typedef UINT_8 BUF_BITMAP; -+#endif /* MAX_NUM_OF_MGT_BUF_BLOCKS */ -+ -+/* Control variable of TX management memory pool */ -+typedef struct _BUF_INFO_T { -+ PUINT_8 pucBuf; -+ -+#if CFG_DBG_MGT_BUF -+ UINT_32 u4AllocCount; -+ UINT_32 u4FreeCount; -+ UINT_32 u4AllocNullCount; -+#endif /* CFG_DBG_MGT_BUF */ -+ -+ BUF_BITMAP rFreeBlocksBitmap; -+ UINT_8 aucAllocatedBlockNum[MAX_NUM_OF_BUF_BLOCKS]; -+} BUF_INFO_T, *P_BUF_INFO_T; -+ -+/* Wi-Fi divides RAM into three types -+ * MSG: Mailbox message (Small size) -+ * BUF: HW DMA buffers (HIF/MAC) -+ */ -+typedef enum _ENUM_RAM_TYPE_T { -+ RAM_TYPE_MSG = 0, -+ RAM_TYPE_BUF -+} ENUM_RAM_TYPE_T, P_ENUM_RAM_TYPE_T; -+ -+typedef enum _ENUM_BUFFER_SOURCE_T { -+ BUFFER_SOURCE_HIF_TX0 = 0, -+ BUFFER_SOURCE_HIF_TX1, -+ BUFFER_SOURCE_MAC_RX, -+ BUFFER_SOURCE_MNG, -+ BUFFER_SOURCE_BCN, -+ BUFFER_SOURCE_NUM -+} ENUM_BUFFER_SOURCE_T, *P_ENUM_BUFFER_SOURCE_T; -+ -+typedef enum _ENUM_SEC_STATE_T { -+ SEC_STATE_INIT, -+ SEC_STATE_INITIATOR_PORT_BLOCKED, -+ SEC_STATE_RESPONDER_PORT_BLOCKED, -+ SEC_STATE_CHECK_OK, -+ SEC_STATE_SEND_EAPOL, -+ SEC_STATE_SEND_DEAUTH, -+ SEC_STATE_COUNTERMEASURE, -+ SEC_STATE_NUM -+} ENUM_SEC_STATE_T; -+ -+typedef struct _TSPEC_ENTRY_T { -+ UINT_8 ucStatus; -+ UINT_8 ucToken; /* Dialog Token in ADDTS_REQ or ADDTS_RSP */ -+ UINT_16 u2MediumTime; -+ UINT_32 u4TsInfo; -+ /* PARAM_QOS_TS_INFO rParamTsInfo; */ -+ /* Add other retained QoS parameters below */ -+} TSPEC_ENTRY_T, *P_TSPEC_ENTRY_T, TSPEC_TABLE_ENTRY_T, *P_TSPEC_TABLE_ENTRY_T; -+ -+typedef struct _SEC_INFO_T { -+ -+ ENUM_SEC_STATE_T ePreviousState; -+ ENUM_SEC_STATE_T eCurrentState; -+ -+ BOOLEAN fg2nd1xSend; -+ BOOLEAN fgKeyStored; -+ -+ UINT_8 aucStoredKey[64]; -+ -+ BOOLEAN fgAllowOnly1x; -+} SEC_INFO_T, *P_SEC_INFO_T; -+ -+#define MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS 3 -+ -+#define UPDATE_BSS_RSSI_INTERVAL_SEC 3 /* Seconds */ -+ -+/* Fragment information structure */ -+typedef struct _FRAG_INFO_T { -+ UINT_16 u2NextFragSeqCtrl; -+ PUINT_8 pucNextFragStart; -+ P_SW_RFB_T pr1stFrag; -+ OS_SYSTIME rReceiveLifetimeLimit; /* The receive time of 1st fragment */ -+} FRAG_INFO_T, *P_FRAG_INFO_T; -+ -+typedef struct _STAT_CNT_INFO_FW_T { -+ UINT32 u4NumOfTx; /* number of packets sent from host */ -+ UINT32 u4NumOfTxOK; /* number of packets sent to air OK */ -+ UINT32 u4NumOfTxRetry; /* number of packets sent to air RETRY */ -+ UINT32 u4TxDoneAirTimeMax; /* maximum tx done air time */ -+ -+ UINT32 u4NumOfPtiRspTxOk; /* number of PTI RSP sent to air OK */ -+ UINT32 u4NumOfPtiRspTxErr; /* number of PTI RSP sent to air ERROR */ -+ -+ UINT32 u4NumOfTxErr; /* number of packets sent to air ERROR */ -+ -+ UINT32 u4NumOfRx; /* number of received packets */ -+ UINT32 u4NumOfPtiRspRx; /* number of PTI RSP rcv */ -+ -+#define STAT_CNT_INFO_TX_ERR_FLUSHED 0x00000001 -+#define STAT_CNT_INFO_TX_ERR_AGE_TIMEOUT 0x00000002 -+#define STAT_CNT_INFO_TX_ERR_MPDU 0x00000004 -+#define STAT_CNT_INFO_TX_ERR_RTS 0x00000010 -+#define STAT_CNT_INFO_TX_ERR_LIFETIME 0x00000020 -+#define STAT_CNT_INFO_TX_ERR_UNKNOWN 0x80000000 -+ UINT32 u4TxErrBitmap; /* TX error type */ -+ -+#define STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM 10 /* TX OK history */ -+ UINT8 aucTxRateOkHis[STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM][2]; -+ UINT32 u4TxRateOkHisId; -+ -+#define STAT_CNT_INFO_MAX_RATE_ID (32) /* MCS0 ~ MCS31 */ -+ UINT32 aucTxRateMap[STAT_CNT_INFO_MAX_RATE_ID]; -+ UINT32 aucRxRateMap[STAT_CNT_INFO_MAX_RATE_ID]; -+ -+ UINT8 aucStateHis[100][3]; /* State history */ -+ UINT32 u4StateHisId; /* history ID */ -+} STAT_CNT_INFO_FW_T; -+ -+typedef struct _STAT_CNT_INFO_DRV_T { -+ -+ UINT32 u4NumOfTxFromOs; /* number of packets sent from OS */ -+ UINT32 u4NumOfTxQueFull; /* number of packets dropped due to queue full */ -+ UINT32 u4NumOfTxToFw; /* number of packets sent to firmware */ -+ -+ STAT_CNT_INFO_FW_T rFw; -+} STAT_CNT_INFO_DRV_T; -+ -+/* Define STA record structure */ -+struct _STA_RECORD_T { -+ LINK_ENTRY_T rLinkEntry; -+ UINT_8 ucIndex; /* Not modify it except initializing */ -+ -+ BOOLEAN fgIsInUse; /* Indicate if this entry is in use or not */ -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; /* MAC address */ -+ -+ /* SAA/AAA */ -+ ENUM_AA_STATE_T eAuthAssocState; /* Store STATE Value used in SAA/AAA */ -+ UINT_8 ucAuthAssocReqSeqNum; -+ -+ ENUM_STA_TYPE_T eStaType; /* Indicate the role of this STA in -+ * the network (for example, P2P GO) -+ */ -+ -+ UINT_8 ucNetTypeIndex; /* ENUM_NETWORK_TYPE_INDEX_T */ -+ -+ UINT_8 ucStaState; /* STATE_1,2,3 */ -+ -+ UINT_8 ucPhyTypeSet; /* Available PHY Type Set of this peer -+ * (may deduced from received BSS_DESC_T) -+ */ -+ UINT_8 ucDesiredPhyTypeSet; /* The match result by AND operation of peer's -+ * PhyTypeSet and ours. -+ */ -+ BOOLEAN fgHasBasicPhyType; /* A flag to indicate a Basic Phy Type which -+ * is used to generate some Phy Attribute IE -+ * (e.g. capability, MIB) during association. -+ */ -+ UINT_8 ucNonHTBasicPhyType; /* The Basic Phy Type chosen among the -+ * ucDesiredPhyTypeSet. -+ */ -+ -+ UINT_16 u2CapInfo; /* For Infra Mode, to store Capability Info. from Association Resp(SAA). -+ * For AP Mode, to store Capability Info. from Association Req(AAA). -+ */ -+ UINT_16 u2AssocId; /* For Infra Mode, to store AID from Association Resp(SAA). -+ * For AP Mode, to store the Assigned AID(AAA). -+ */ -+ -+ UINT_16 u2ListenInterval; /* Listen Interval from STA(AAA) */ -+ -+ UINT_16 u2DesiredNonHTRateSet; /* Our Current Desired Rate Set after -+ * match with STA's Operational Rate Set -+ */ -+ -+ UINT_16 u2OperationalRateSet; /* Operational Rate Set of peer BSS */ -+ UINT_16 u2BSSBasicRateSet; /* Basic Rate Set of peer BSS */ -+ -+ BOOLEAN fgIsMerging; /* For IBSS Mode, to indicate that Merge is ongoing */ -+ -+ BOOLEAN fgDiagnoseConnection; /* For Infra/AP Mode, to diagnose the Connection with -+ * this peer by sending ProbeReq/Null frame */ -+ -+ /*------------------------------------------------------------------------------------------*/ -+ /* 802.11n HT capabilities when (prStaRec->ucPhyTypeSet & PHY_TYPE_BIT_HT) is true */ -+ /* They have the same definition with fields of information element */ -+ /*------------------------------------------------------------------------------------------*/ -+ UINT_8 ucMcsSet; /* MCS0~7 rate set of peer BSS */ -+ BOOLEAN fgSupMcs32; /* MCS32 is supported by peer BSS */ -+ UINT_16 u2HtCapInfo; /* HT cap info field by HT cap IE */ -+ UINT_8 ucAmpduParam; /* Field A-MPDU Parameters in HT cap IE */ -+ UINT_16 u2HtExtendedCap; /* HT extended cap field by HT cap IE */ -+ UINT_32 u4TxBeamformingCap; /* TX beamforming cap field by HT cap IE */ -+ UINT_8 ucAselCap; /* ASEL cap field by HT cap IE */ -+ -+ UINT_8 ucRCPI; /* RCPI of peer */ -+ -+ UINT_8 ucDTIMPeriod; /* Target BSS's DTIM Period, we use this -+ * value for setup Listen Interval -+ * TODO(Kevin): TBD -+ */ -+ UINT_8 ucAuthAlgNum; /* For Infra/AP Mode, the Auth Algorithm Num used in Authentication(SAA/AAA) */ -+ BOOLEAN fgIsReAssoc; /* For Infra/AP Mode, to indicate ReAssoc Frame was in used(SAA/AAA) */ -+ -+ UINT_8 ucTxAuthAssocRetryCount; /* For Infra Mode, the Retry Count of TX Auth/Assod Frame(SAA) */ -+ UINT_8 ucTxAuthAssocRetryLimit; /* For Infra Mode, the Retry Limit of TX Auth/Assod Frame(SAA) */ -+ -+ UINT_16 u2StatusCode; /* Status of Auth/Assoc Req */ -+ UINT_16 u2ReasonCode; /* Reason that been Deauth/Disassoc */ -+ -+ P_IE_CHALLENGE_TEXT_T prChallengeText; /* Point to an allocated buffer for storing Challenge Text -+ * for Shared Key Authentication -+ */ -+ -+ TIMER_T rTxReqDoneOrRxRespTimer; /* For Infra Mode, a timer used to send a timeout event -+ * while waiting for TX request done or RX response. -+ */ -+ -+ /*------------------------------------------------------------------------------------------*/ -+ /* Power Management related fields (for STA/ AP/ P2P/ BOW power saving mode) */ -+ /*------------------------------------------------------------------------------------------*/ -+ BOOLEAN fgSetPwrMgtBit; /* For Infra Mode, to indicate that outgoing frame need toggle -+ * the Pwr Mgt Bit in its Frame Control Field. -+ */ -+ -+ BOOLEAN fgIsInPS; /* For AP Mode, to indicate the client PS state(PM). -+ * TRUE: In PS Mode; FALSE: In Active Mode. */ -+ -+ BOOLEAN fgIsInPsPollSP; /* For Infra Mode, to indicate we've sent a PS POLL to AP and start -+ * the PS_POLL Service Period(LP) -+ */ -+ -+ BOOLEAN fgIsInTriggerSP; /* For Infra Mode, to indicate we've sent a Trigger Frame to AP and start -+ * the Delivery Service Period(LP) -+ */ -+ -+ UINT_8 ucBmpDeliveryAC; /* 0: AC0, 1: AC1, 2: AC2, 3: AC3 */ -+ -+ UINT_8 ucBmpTriggerAC; /* 0: AC0, 1: AC1, 2: AC2, 3: AC3 */ -+ -+ UINT_8 ucUapsdSp; /* Max SP length */ -+ -+ /*------------------------------------------------------------------------------------------*/ -+ -+ BOOLEAN fgIsRtsEnabled; -+ -+ OS_SYSTIME rUpdateTime; /* (4) System Timestamp of Successful TX and RX */ -+ -+ OS_SYSTIME rLastJoinTime; /* (4) System Timestamp of latest JOIN process */ -+ -+ UINT_8 ucJoinFailureCount; /* Retry Count of JOIN process */ -+ -+ LINK_T arStaWaitQueue[STA_WAIT_QUEUE_NUM]; /* For TXM to defer pkt forwarding to MAC TX DMA */ -+ -+ UINT_16 au2CachedSeqCtrl[TID_NUM + 1]; /* Duplicate removal for HT STA on a per-TID basis -+ * ("+1" is for MMPDU and non-QoS) -+ */ -+ -+#if 0 -+ /* RXM */ -+ P_RX_BA_ENTRY_T aprRxBaTable[TID_NUM]; -+ -+ /* TXM */ -+ P_TX_BA_ENTRY_T aprTxBaTable[TID_NUM]; -+#endif -+ -+ FRAG_INFO_T rFragInfo[MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS]; -+ -+ SEC_INFO_T rSecInfo; /* The security state machine */ -+ -+ BOOLEAN fgPortBlock; /* The 802.1x Port Control flag */ -+ -+ BOOLEAN fgTransmitKeyExist; /* Unicast key exist for this STA */ -+ -+ UINT_8 ucWTEntry; -+ -+ BOOLEAN fgTxAmpduEn; /* Enable TX AMPDU for this Peer */ -+ BOOLEAN fgRxAmpduEn; /* Enable RX AMPDU for this Peer */ -+ -+ PUINT_8 pucAssocReqIe; -+ UINT_16 u2AssocReqIeLen; -+ /*------------------------------------------------------------------------------------------*/ -+ /* WMM/QoS related fields */ -+ /*------------------------------------------------------------------------------------------*/ -+ BOOLEAN fgIsQoS; /* If the STA is associated as a QSTA or QAP (for TX/RX) */ -+ BOOLEAN fgIsWmmSupported; /* If the peer supports WMM, set to TRUE (for association) */ -+ BOOLEAN fgIsUapsdSupported; /* Set according to the scan result (for association) */ -+ -+ /*------------------------------------------------------------------------------------------*/ -+ /* P2P related fields */ -+ /*------------------------------------------------------------------------------------------*/ -+#if CFG_ENABLE_WIFI_DIRECT -+ UINT_8 u2DevNameLen; -+ UINT_8 aucDevName[WPS_ATTRI_MAX_LEN_DEVICE_NAME]; -+ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+ -+ UINT_16 u2ConfigMethods; -+ -+ UINT_8 ucDeviceCap; -+ -+ UINT_8 ucSecondaryDevTypeCount; -+ -+ DEVICE_TYPE_T rPrimaryDevTypeBE; -+ -+ DEVICE_TYPE_T arSecondaryDevTypeBE[P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT]; -+#endif /* CFG_SUPPORT_P2P */ -+ -+ /*------------------------------------------------------------------------------------------*/ -+ /* QM related fields */ -+ /*------------------------------------------------------------------------------------------*/ -+ -+ UINT_8 ucFreeQuota; /* Per Sta flow controal. Valid when fgIsInPS is TRUE. -+ Change it for per Queue flow control */ -+ /* UINT_8 aucFreeQuotaPerQueue[NUM_OF_PER_STA_TX_QUEUES]; */ /* used in future */ -+ UINT_8 ucFreeQuotaForDelivery; -+ UINT_8 ucFreeQuotaForNonDelivery; -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE && CFG_ENABLE_PER_STA_STATISTICS -+ UINT_32 u4TotalTxPktsNumber; -+ UINT_32 u4TotalTxPktsTime; -+ UINT_32 u4TotalTxPktsHifTime; -+ -+ UINT_32 u4MaxTxPktsTime; -+ UINT_32 u4MaxTxPktsHifTime; -+ -+ UINT_32 u4ThresholdCounter; -+ UINT_32 u4EnqeueuCounter; -+ UINT_32 u4DeqeueuCounter; -+ UINT_32 u4PrevIntCount; -+ UINT_32 u4ThisIntCount; -+ UINT_32 u4NoTcResource; -+#endif -+ -+#if 1 -+ /*------------------------------------------------------------------------------------------*/ -+ /* To be removed, this is to make que_mgt compilation success only */ -+ /*------------------------------------------------------------------------------------------*/ -+ /* When this STA_REC is in use, set to TRUE. */ -+ BOOLEAN fgIsValid; -+ -+ /* Per-STA Queues: [0] AC0, [1] AC1, [2] AC2, [3] AC3, [4] 802.1x */ -+ QUE_T arTxQueue[NUM_OF_PER_STA_TX_QUEUES]; -+ -+ /* When this STA is in PS Mode, set to TRUE. */ -+ /* BOOLEAN fgIsPS; */ -+ -+ /* When this STA enters Power-Saving, FW will notify the driver with a Session ID */ -+ UINT_8 ucPsSessionID; -+ -+ BOOLEAN fgIsAp; -+ -+ /* Reorder Parameter reference table */ -+ P_RX_BA_ENTRY_T aprRxReorderParamRefTbl[CFG_RX_MAX_BA_TID_NUM]; -+#endif -+ -+#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT -+ TIMINGMSMT_PARAM_T rWNMTimingMsmt; -+#endif -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ BOOLEAN fgTdlsIsProhibited; /* TRUE: AP prohibits TDLS links */ -+ BOOLEAN fgTdlsIsChSwProhibited; /* TRUE: AP prohibits TDLS chan switch */ -+ -+ BOOLEAN flgTdlsIsInitiator; /* TRUE: the peer is the initiator */ -+ IE_HT_CAP_T rTdlsHtCap; /* temp to queue HT capability element */ -+ BOOLEAN fgTdlsInSecurityMode; /* TRUE: security mode */ -+ PARAM_KEY_T rTdlsKeyTemp; /* temp to queue the key information */ -+ -+#define TDLS_SETUP_TIMEOUT_SEC 5 /* unit: second */ -+ OS_SYSTIME rTdlsSetupStartTime; /* time when link setup is started */ -+ -+ OS_SYSTIME rTdlsTxQuotaEmptyTime; /* time when TX quota is 0 */ -+ -+ STAT_CNT_INFO_DRV_T rTdlsStatistics; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+#if (CFG_SUPPORT_STATISTICS == 1) -+#define STATS_ENV_TIMEOUT_SEC 10 /* unit: second */ -+ OS_SYSTIME rStatsEnvTxPeriodLastTime; -+ -+#define STATS_ENV_TX_CNT_REPORT_TRIGGER 2500 /* 6Mbps */ -+#define STATS_ENV_TX_CNT_REPORT_TRIGGER_SEC 5 /* unit: second */ -+ OS_SYSTIME rStatsEnvTxLastTime; -+ UINT32 u4StatsEnvTxCnt; -+ -+ UINT32 u4NumOfNoTxQuota; -+ -+ UINT32 u4RxReorderFallAheadCnt; -+ UINT32 u4RxReorderFallBehindCnt; -+ UINT32 u4RxReorderHoleCnt; -+ UINT32 u4RxReorderHoleTimeoutCnt; -+ -+ UINT32 u4StatsRxPassToOsCnt; -+ -+ /* delay from HIF to pass to OS: us */ -+#define STATS_STAY_INT_BYTE_THRESHOLD 500 -+ UINT32 u4StayIntMaxRx[3], u4StayIntMinRx[3], u4StayIntAvgRx[3]; -+ -+ UINT8 ucStatsGenDisplayCnt; -+#endif /* CFG_SUPPORT_STATISTICS */ -+}; -+ -+#if 0 -+/* use nic_tx.h instead */ -+/* MSDU_INFO and SW_RFB structure */ -+typedef struct _MSDU_INFO_T { -+ -+ /* 4 ----------------MSDU_INFO and SW_RFB Common Fields------------------ */ -+ -+ LINK_ENTRY_T rLinkEntry; -+ PUINT_8 pucBuffer; /* Pointer to the associated buffer */ -+ -+ UINT_8 ucBufferSource; /* HIF TX0, HIF TX1, MAC RX, or MNG Pool */ -+ UINT_8 ucNetworkTypeIndex; /* Network type index that this TX packet is assocaited with */ -+ UINT_8 ucTC; /* 0 to 5 (used by HIF TX to increment the corresponding TC counter) */ -+ UINT_8 ucTID; /* Traffic Identification */ -+ -+ BOOLEAN fgIs802_11Frame; /* Set to TRUE for 802.11 frame */ -+ UINT_8 ucMacHeaderLength; -+ UINT_16 u2PayloadLength; -+ PUINT_8 pucMacHeader; /* 802.11 header */ -+ PUINT_8 pucPayload; /* 802.11 payload */ -+ -+ OS_SYSTIME rArrivalTime; /* System Timestamp (4) */ -+ P_STA_RECORD_T prStaRec; -+ -+#if CFG_PROFILE_BUFFER_TRACING -+ ENUM_BUFFER_ACTIVITY_TYPE_T eActivity[2]; -+ UINT_32 rActivityTime[2]; -+#endif -+#if DBG && CFG_BUFFER_FREE_CHK -+ BOOLEAN fgBufferInSource; -+#endif -+ -+ UINT_8 ucControlFlag; /* For specify some Control Flags, e.g. Basic Rate */ -+ -+ /* 4 -----------------------Non-Common ------------------------- */ -+ /* TODO: move flags to ucControlFlag */ -+ -+ BOOLEAN fgIs1xFrame; /* Set to TRUE for 802.1x frame */ -+ -+ /* TXM: For TX Done handling, callback function & parameter (5) */ -+ BOOLEAN fgIsTxFailed; /* Set to TRUE if transmission failure */ -+ -+ PFN_TX_DONE_HANDLER pfTxDoneHandler; -+ -+ UINT_64 u8TimeStamp; /* record the TX timestamp */ -+ -+ /* TXM: For PS forwarding control (per-STA flow control) */ -+ UINT_8 ucPsForwardingType; /* Delivery-enabled, non-delivery-enabled, non-PS */ -+ UINT_8 ucPsSessionID; /* The Power Save session id for PS forwarding control */ -+ -+ /* TXM: For MAC TX DMA operations */ -+ UINT_8 ucMacTxQueIdx; /* MAC TX queue: AC0-AC6, BCM, or BCN */ -+ BOOLEAN fgNoAck; /* Set to true if Ack is not required for this packet */ -+ BOOLEAN fgBIP; /* Set to true if BIP is used for this packet */ -+ UINT_8 ucFragTotalCount; -+ UINT_8 ucFragFinishedCount; -+ UINT_16 u2FragThreshold; /* Fragmentation threshold without WLAN Header & FCS */ -+ BOOLEAN fgFixedRate; /* If a fixed rate is used, set to TRUE. */ -+ UINT_8 ucFixedRateCode; /* The rate code copied to MAC TX Desc */ -+ UINT_8 ucFixedRateRetryLimit; /* The retry limit when a fixed rate is used */ -+ BOOLEAN fgIsBmcQueueEnd; /* Set to true if this packet is the end of BMC */ -+ -+ /* TXM: For flushing ACL frames */ -+ UINT_16 u2PalLLH; /* 802.11 PAL LLH */ -+ /* UINT_16 u2LLH; */ -+ UINT_16 u2ACLSeq; /* u2LLH+u2ACLSeq for AM HCI flush ACL frame */ -+ -+ /* TXM for retransmitting a flushed packet */ -+ BOOLEAN fgIsSnAssigned; -+ UINT_16 u2SequenceNumber; /* To remember the Sequence Control field of this MPDU */ -+ -+} MSDU_INFO_T, *P_MSDU_INFO_T; -+#endif -+ -+#if 0 -+/* nic_rx.h */ -+typedef struct _SW_RFB_T { -+ -+ /* 4 ----------------MSDU_INFO and SW_RFB Common Fields------------------ */ -+ -+ LINK_ENTRY_T rLinkEntry; -+ PUINT_8 pucBuffer; /* Pointer to the associated buffer */ -+ -+ UINT_8 ucBufferSource; /* HIF TX0, HIF TX1, MAC RX, or MNG Pool */ -+ UINT_8 ucNetworkTypeIndex; /* Network type index that this TX packet is assocaited with */ -+ UINT_8 ucTC; /* 0 to 5 (used by HIF TX to increment the corresponding TC counter) */ -+ UINT_8 ucTID; /* Traffic Identification */ -+ -+ BOOLEAN fgIs802_11Frame; /* Set to TRUE for 802.11 frame */ -+ UINT_8 ucMacHeaderLength; -+ UINT_16 u2PayloadLength; -+ PUINT_8 pucMacHeader; /* 802.11 header */ -+ PUINT_8 pucPayload; /* 802.11 payload */ -+ -+ OS_SYSTIME rArrivalTime; /* System Timestamp (4) */ -+ P_STA_RECORD_T prStaRec; -+ -+#if CFG_PROFILE_BUFFER_TRACING -+ ENUM_BUFFER_ACTIVITY_TYPE_T eActivity[2]; -+ UINT_32 rActivityTime[2]; -+#endif -+#if DBG && CFG_BUFFER_FREE_CHK -+ BOOLEAN fgBufferInSource; -+#endif -+ -+ UINT_8 ucControlFlag; /* For specify some Control Flags, e.g. Basic Rate */ -+ -+ /* 4 -----------------------Non-Common ------------------------- */ -+ -+ /* For composing the HIF RX Header (TODO: move flags to ucControlFlag) */ -+ PUINT_8 pucHifRxPacket; /* Pointer to the Response packet to HIF RX0 or RX1 */ -+ UINT_16 u2HifRxPacketLength; -+ UINT_8 ucHeaderOffset; -+ UINT_8 ucHifRxPortIndex; -+ -+ UINT_16 u2SequenceControl; -+ BOOLEAN fgIsA4Frame; /* (For MAC RX packet parsing) set to TRUE if 4 addresses are present */ -+ BOOLEAN fgIsBAR; -+ BOOLEAN fgIsQoSData; -+ BOOLEAN fgIsAmsduSubframe; /* Set to TRUE for A-MSDU Subframe */ -+ -+ /* For HIF RX DMA Desc */ -+ BOOLEAN fgTUChecksumCheckRequired; -+ BOOLEAN fgIPChecksumCheckRequired; -+ UINT_8 ucEtherTypeOffset; -+ -+} SW_RFB_T, *P_SW_RFB_T; -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+P_MSDU_INFO_T cnmMgtPktAlloc(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length); -+ -+VOID cnmMgtPktFree(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID cnmMemInit(IN P_ADAPTER_T prAdapter); -+ -+PVOID cnmMemAlloc(IN P_ADAPTER_T prAdapter, IN ENUM_RAM_TYPE_T eRamType, IN UINT_32 u4Length); -+ -+VOID cnmMemFree(IN P_ADAPTER_T prAdapter, IN PVOID pvMemory); -+ -+VOID cnmStaRecInit(IN P_ADAPTER_T prAdapter); -+ -+VOID cnmStaRecUninit(IN P_ADAPTER_T prAdapter); -+ -+P_STA_RECORD_T cnmStaRecAlloc(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIndex); -+ -+VOID cnmStaRecFree(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSyncToChip); -+ -+VOID cnmStaFreeAllStaByNetType(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, BOOLEAN fgSyncToChip); -+ -+P_STA_RECORD_T cnmGetStaRecByIndex(IN P_ADAPTER_T prAdapter, IN UINT_8 ucIndex); -+ -+P_STA_RECORD_T cnmGetStaRecByAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIndex, IN UINT_8 aucPeerMACAddress[]); -+ -+VOID cnmStaRecResetStatus(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+VOID cnmStaRecChangeState(IN P_ADAPTER_T prAdapter, IN OUT P_STA_RECORD_T prStaRec, IN UINT_8 ucNewState); -+ -+P_STA_RECORD_T -+cnmStaTheTypeGet(P_ADAPTER_T prAdapter, -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ENUM_STA_TYPE_T eStaType, UINT32 *pu4StartIdx); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#ifndef _lint -+/* Kevin: we don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ * We'll need this for porting driver to different RTOS. -+ */ -+static inline VOID cnmMemDataTypeCheck(VOID) -+{ -+#if 0 -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rLinkEntry) == 0); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rLinkEntry) == OFFSET_OF(SW_RFB_T, rLinkEntry)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucBuffer) == OFFSET_OF(SW_RFB_T, pucBuffer)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucBufferSource) == OFFSET_OF(SW_RFB_T, ucBufferSource)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucMacHeader) == OFFSET_OF(SW_RFB_T, pucMacHeader)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucMacHeaderLength) == -+ OFFSET_OF(SW_RFB_T, ucMacHeaderLength)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucPayload) == OFFSET_OF(SW_RFB_T, pucPayload)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, u2PayloadLength) == OFFSET_OF(SW_RFB_T, u2PayloadLength)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, prStaRec) == OFFSET_OF(SW_RFB_T, prStaRec)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucNetworkTypeIndex) == -+ OFFSET_OF(SW_RFB_T, ucNetworkTypeIndex)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucTID) == OFFSET_OF(SW_RFB_T, ucTID)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, fgIs802_11Frame) == OFFSET_OF(SW_RFB_T, fgIs802_11Frame)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucControlFlag) == OFFSET_OF(SW_RFB_T, ucControlFlag)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rArrivalTime) == OFFSET_OF(SW_RFB_T, rArrivalTime)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucTC) == OFFSET_OF(SW_RFB_T, ucTC)); -+ -+#if CFG_PROFILE_BUFFER_TRACING -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, eActivity[0]) == OFFSET_OF(SW_RFB_T, eActivity[0])); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rActivityTime[0]) == -+ OFFSET_OF(SW_RFB_T, rActivityTime[0])); -+#endif -+ -+#if DBG && CFG_BUFFER_FREE_CHK -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, fgBufferInSource) == -+ OFFSET_OF(SW_RFB_T, fgBufferInSource)); -+#endif -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(STA_RECORD_T, rLinkEntry) == 0); -+ -+ return; -+#endif -+} -+#endif /* _lint */ -+ -+#endif /* _CNM_MEM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h -new file mode 100644 -index 0000000000000..cc5d0fa1adfca ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h -@@ -0,0 +1,169 @@ -+/* -+** Id: @(#) -+*/ -+ -+/*! \file "cnm_scan.h" -+ \brief -+ -+*/ -+ -+/* -+** Log: cnm_scan.h -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * remove unused definitions. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge cnm_scan.h and hem_mbox.h -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add function prototype of cnmScanInit() -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+#ifndef _CNM_SCAN_H -+#define _CNM_SCAN_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define SCN_CHANNEL_DWELL_TIME_MIN_MSEC 12 -+#define SCN_CHANNEL_DWELL_TIME_EXT_MSEC 98 -+ -+#define SCN_TOTAL_PROBEREQ_NUM_FOR_FULL 3 -+#define SCN_SPECIFIC_PROBEREQ_NUM_FOR_FULL 1 -+ -+#define SCN_TOTAL_PROBEREQ_NUM_FOR_PARTIAL 2 -+#define SCN_SPECIFIC_PROBEREQ_NUM_FOR_PARTIAL 1 -+ -+#define SCN_INTERLACED_CHANNEL_GROUPS_NUM 3 /* Used by partial scan */ -+ -+#define SCN_PARTIAL_SCAN_NUM 3 -+ -+#define SCN_PARTIAL_SCAN_IDLE_MSEC 100 -+ -+#define MAXIMUM_OPERATION_CHANNEL_LIST 46 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* The type of Scan Source */ -+typedef enum _ENUM_SCN_REQ_SOURCE_T { -+ SCN_REQ_SOURCE_HEM = 0, -+ SCN_REQ_SOURCE_NET_FSM, -+ SCN_REQ_SOURCE_ROAMING, /* ROAMING Module is independent of AIS FSM */ -+ SCN_REQ_SOURCE_OBSS, /* 2.4G OBSS scan */ -+ SCN_REQ_SOURCE_NUM -+} ENUM_SCN_REQ_SOURCE_T, *P_ENUM_SCN_REQ_SOURCE_T; -+ -+typedef enum _ENUM_SCAN_PROFILE_T { -+ SCAN_PROFILE_FULL = 0, -+ SCAN_PROFILE_PARTIAL, -+ SCAN_PROFILE_VOIP, -+ SCAN_PROFILE_FULL_2G4, -+ SCAN_PROFILE_NUM -+} ENUM_SCAN_PROFILE_T, *P_ENUM_SCAN_PROFILE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#if 0 -+VOID cnmScanInit(VOID); -+ -+VOID cnmScanRunEventScanRequest(IN P_MSG_HDR_T prMsgHdr); -+ -+BOOLEAN cnmScanRunEventScanAbort(IN P_MSG_HDR_T prMsgHdr); -+ -+VOID cnmScanProfileSelection(VOID); -+ -+VOID cnmScanProcessStart(VOID); -+ -+VOID cnmScanProcessStop(VOID); -+ -+VOID cnmScanRunEventReqAISAbsDone(IN P_MSG_HDR_T prMsgHdr); -+ -+VOID cnmScanRunEventCancelAISAbsDone(IN P_MSG_HDR_T prMsgHdr); -+ -+VOID cnmScanPartialScanTimeout(UINT_32 u4Param); -+ -+VOID cnmScanRunEventScnFsmComplete(IN P_MSG_HDR_T prMsgHdr); -+#endif -+ -+#endif /* _CNM_SCAN_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h -new file mode 100644 -index 0000000000000..a2ed9cd02fedf ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h -@@ -0,0 +1,235 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm_timer.h#1 -+*/ -+ -+/*! \file cnm_timer.h -+ \brief Declaration of timer obj and related timer macro for setup time out -+ event. -+ -+ In this file we declare the timer object and provide several macro for -+ Protocol functional blocks to setup their own time out event. -+*/ -+ -+/* -+** Log: cnm_timer.h -+ * -+ * 12 13 2011 cm.chang -+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer -+ * Add wake lock if timer timeout value is smaller than 5 seconds -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge cnm_scan.h and hem_mbox.h -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 04 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * [PM] Support U-APSD for STA mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Return timer token back to COS when entering wait off state -+ * -+ * 01 08 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support longer timeout interval to 45 days from 65secu1rwduu`wvpghlqg|fh+fmdkb -+ * -+ * 01 06 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fix system time is 32KHz instead of 1ms -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * add the copy time function -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix LINT warnning -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+#ifndef _CNM_TIMER_H -+#define _CNM_TIMER_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#undef MSEC_PER_SEC -+#define MSEC_PER_SEC 1000 -+#undef USEC_PER_MSEC -+#define USEC_PER_MSEC 1000 -+#define USEC_PER_TU 1024 /* microsecond */ -+ -+#define MSEC_PER_MIN (60 * MSEC_PER_SEC) -+ -+#define MGMT_MAX_TIMEOUT_INTERVAL ((UINT_32)0x7fffffff) -+ -+#define WAKE_LOCK_MAX_TIME 5 /* Unit: sec */ -+ -+/* If WAKE_LOCK_MAX_TIME is too large, the whole system may always keep awake -+ * because of periodic timer of OBSS scanning -+ */ -+#if (WAKE_LOCK_MAX_TIME >= OBSS_SCAN_MIN_INTERVAL) -+#error WAKE_LOCK_MAX_TIME is too large -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef VOID(*PFN_MGMT_TIMEOUT_FUNC) (P_ADAPTER_T, ULONG); -+ -+typedef struct _TIMER_T { -+ LINK_ENTRY_T rLinkEntry; -+ OS_SYSTIME rExpiredSysTime; -+ UINT_16 u2Minutes; -+ UINT_16 u2Reserved; -+ ULONG ulData; -+ PFN_MGMT_TIMEOUT_FUNC pfMgmtTimeOutFunc; -+} TIMER_T, *P_TIMER_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* Check if time "a" is before time "b" */ -+/* In 32-bit variable, 0x00000001~0x7fffffff -> positive number, -+ * 0x80000000~0xffffffff -> negative number -+ */ -+#define TIME_BEFORE_64bit(a, b) (a < b) -+ -+#define TIME_BEFORE(a, b) ((UINT_32)((UINT_32)(a) - (UINT_32)(b)) > 0x7fffffff) -+ -+/* #define TIME_BEFORE(a,b) ((INT_32)((INT_32)(b) - (INT_32)(a)) > 0) -+ * may cause UNexpect result between Free build and Check build for WinCE -+ */ -+ -+#define TIME_AFTER(a, b) TIME_BEFORE(b, a) -+ -+#define SYSTIME_TO_SEC(_systime) ((_systime) / KAL_HZ) -+#define SEC_TO_SYSTIME(_sec) ((_sec) * KAL_HZ) -+ -+/* The macros to convert second & millisecond */ -+#define MSEC_TO_SEC(_msec) ((_msec) / MSEC_PER_SEC) -+#define SEC_TO_MSEC(_sec) ((UINT_32)(_sec) * MSEC_PER_SEC) -+ -+/* The macros to convert millisecond & microsecond */ -+#define USEC_TO_MSEC(_usec) ((_usec) / USEC_PER_MSEC) -+#define MSEC_TO_USEC(_msec) ((UINT_32)(_msec) * USEC_PER_MSEC) -+ -+/* The macros to convert TU & microsecond, TU & millisecond */ -+#define TU_TO_USEC(_tu) ((_tu) * USEC_PER_TU) -+#define TU_TO_MSEC(_tu) USEC_TO_MSEC(TU_TO_USEC(_tu)) -+ -+/* The macros to convert TU & & OS system time, round up by 0.5 */ -+#define TU_TO_SYSTIME(_tu) MSEC_TO_SYSTIME(TU_TO_MSEC(_tu)) -+#define SYSTIME_TO_TU(_systime) \ -+ ((SYSTIME_TO_USEC(_systime) + ((USEC_PER_TU / 2) - 1)) / USEC_PER_TU) -+ -+/* The macros to convert OS system time & microsecond */ -+#define SYSTIME_TO_USEC(_systime) (SYSTIME_TO_MSEC(_systime) * USEC_PER_MSEC) -+ -+/* The macro to get the current OS system time */ -+#define GET_CURRENT_SYSTIME(_systime_p) {*(_systime_p) = kalGetTimeTick(); } -+ -+/* The macro to copy the system time */ -+#define COPY_SYSTIME(_destTime, _srcTime) {(_destTime) = (_srcTime); } -+ -+/* The macro to get the system time difference between t1 and t2 (t1 - t2) */ -+/* #define GET_SYSTIME_DIFFERENCE(_time1, _time2, _diffTime) \ -+ (_diffTime) = (_time1) - (_time2) */ -+ -+/* The macro to check for the expiration, if TRUE means _currentTime >= _expirationTime */ -+#define CHECK_FOR_EXPIRATION(_currentTime, _expirationTime) \ -+ (((UINT_32)(_currentTime) - (UINT_32)(_expirationTime)) <= 0x7fffffffUL) -+ -+/* The macro to check for the timeout */ -+#define CHECK_FOR_TIMEOUT(_currentTime, _timeoutStartingTime, _timeout) \ -+ CHECK_FOR_EXPIRATION((_currentTime), ((_timeoutStartingTime) + (_timeout))) -+ -+/* The macro to set the expiration time with a specified timeout *//* Watch out for round up. */ -+#define SET_EXPIRATION_TIME(_expirationTime, _timeout) \ -+ { \ -+ GET_CURRENT_SYSTIME(&(_expirationTime)); \ -+ (_expirationTime) += (OS_SYSTIME)(_timeout); \ -+ } -+ -+#define timerRenewTimer(adapter, tmr, interval) \ -+ timerStartTimer(adapter, tmr, interval, (tmr)->function, (tmr)->data) -+ -+#define MGMT_INIT_TIMER(_adapter_p, _timer, _callbackFunc) \ -+ timerInitTimer(_adapter_p, &(_timer), (ULONG)(_callbackFunc)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID cnmTimerInitialize(IN P_ADAPTER_T prAdapter); -+ -+VOID cnmTimerDestroy(IN P_ADAPTER_T prAdapter); -+ -+VOID -+cnmTimerInitTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN PFN_MGMT_TIMEOUT_FUNC pfFunc, IN ULONG ulData); -+ -+VOID cnmTimerStopTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer); -+ -+VOID cnmTimerStartTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN UINT_32 u4TimeoutMs); -+ -+VOID cnmTimerDoTimeOutCheck(IN P_ADAPTER_T prAdapter); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+static inline INT_32 timerPendingTimer(IN P_TIMER_T prTimer) -+{ -+ ASSERT(prTimer); -+ -+ return prTimer->rLinkEntry.prNext != NULL; -+} -+ -+#endif /* _CNM_TIMER_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h -new file mode 100644 -index 0000000000000..868de4a6c40ac ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h -@@ -0,0 +1,446 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/hem_mbox.h#2 -+*/ -+ -+/*! \file hem_mbox.h -+ \brief -+ -+*/ -+ -+/* -+** Log: hem_mbox.h -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for -+ * more than one SSID in a single scanning request -+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID -+ * support as well as uProbeDelay in NDIS 6.x driver model -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000696] [Volunteer Patch][MT6620][Driver] Infinite loop issue when RX invitation response. -+ * cnm_timer[WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Add invitation support. -+ * -+ * 06 02 2011 cp.wu -+ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction -+ * eliminate unused parameters for SAA-FSM -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * Allocate system RAM if fixed message or mgmt buffer is not available -+ * -+ * 11 08 2010 cm.chang -+ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID -+ * Remove CNM channel reover message ID -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Remove unused message ID -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add interface for RLM to trigger OBSS-SCAN. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add some message ID for P2P FSM under provisioning phase. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add Message Event ID for P2P Module. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Check-in P2P Device Discovery Feature. -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * remove unused mailbox message definitions. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * message table should not be commented out by compilation option without modifying header file -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Modify CNM message handler for new flow -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * restore utility function invoking via hem_mbox to direct calls -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add definitions for module migration. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * hem_mbox is migrated. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge cnm_scan.h and hem_mbox.h -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 29 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed MID_RXM_MQM_QOS_ACTION_FRAME -+ * -+ * 04 29 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed MID_RXM_MQM_BA_ACTION_FRAME -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 03 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Develop partial DPD code -+ * -+ * 02 11 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added MID_RXM_MQM_QOS_ACTION_FRAME for RXM to indicate QoS Action frames to MQM -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * Dec 7 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Rename the parameter of mboxDummy() -+ * -+ * Dec 2 2009 MTK02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Added MID_RXM_MQM_BA_ACTION_FRAME -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove Dummy MSG ID -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add JOIN REQ related MSG ID -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add AIS ABORT MSG ID -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add SCN MSG IDs -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+#ifndef _HEM_MBOX_H -+#define _HEM_MBOX_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Message IDs */ -+typedef enum _ENUM_MSG_ID_T { -+ MID_MNY_CNM_CH_REQ, /* MANY notify CNM to obtain channel privilege */ -+ MID_MNY_CNM_CH_ABORT, /* MANY notify CNM to abort/release channel privilege */ -+ -+ MID_CNM_AIS_CH_GRANT, /* CNM notify AIS for indicating channel granted */ -+ MID_CNM_P2P_CH_GRANT, /* CNM notify P2P for indicating channel granted */ -+ MID_CNM_BOW_CH_GRANT, /* CNM notify BOW for indicating channel granted */ -+ -+ /*--------------------------------------------------*/ -+ /* SCN Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ MID_AIS_SCN_SCAN_REQ, /* AIS notify SCN for starting scan */ -+ MID_AIS_SCN_SCAN_REQ_V2, /* AIS notify SCN for starting scan with multiple SSID support */ -+ MID_AIS_SCN_SCAN_CANCEL, /* AIS notify SCN for cancelling scan */ -+ MID_P2P_SCN_SCAN_REQ, /* P2P notify SCN for starting scan */ -+ MID_P2P_SCN_SCAN_REQ_V2, /* P2P notify SCN for starting scan with multiple SSID support */ -+ MID_P2P_SCN_SCAN_CANCEL, /* P2P notify SCN for cancelling scan */ -+ MID_BOW_SCN_SCAN_REQ, /* BOW notify SCN for starting scan */ -+ MID_BOW_SCN_SCAN_REQ_V2, /* BOW notify SCN for starting scan with multiple SSID support */ -+ MID_BOW_SCN_SCAN_CANCEL, /* BOW notify SCN for cancelling scan */ -+ MID_RLM_SCN_SCAN_REQ, /* RLM notify SCN for starting scan (OBSS-SCAN) */ -+ MID_RLM_SCN_SCAN_REQ_V2, /* RLM notify SCN for starting scan (OBSS-SCAN) with multiple SSID support */ -+ MID_RLM_SCN_SCAN_CANCEL, /* RLM notify SCN for cancelling scan (OBSS-SCAN) */ -+ MID_SCN_AIS_SCAN_DONE, /* SCN notify AIS for scan completion */ -+ MID_SCN_P2P_SCAN_DONE, /* SCN notify P2P for scan completion */ -+ MID_SCN_BOW_SCAN_DONE, /* SCN notify BOW for scan completion */ -+ MID_SCN_RLM_SCAN_DONE, /* SCN notify RLM for scan completion (OBSS-SCAN) */ -+ -+ /*--------------------------------------------------*/ -+ /* AIS Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ MID_OID_AIS_FSM_JOIN_REQ, /* OID/IOCTL notify AIS for join */ -+ MID_OID_AIS_FSM_ABORT, /* OID/IOCTL notify AIS for abort */ -+ MID_AIS_SAA_FSM_START, /* AIS notify SAA for Starting authentication/association fsm */ -+ MID_AIS_SAA_FSM_ABORT, /* AIS notify SAA for Aborting authentication/association fsm */ -+ MID_SAA_AIS_JOIN_COMPLETE, /* SAA notify AIS for indicating join complete */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ /*--------------------------------------------------*/ -+ /* BOW Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ MID_BOW_SAA_FSM_START, /* BOW notify SAA for Starting authentication/association fsm */ -+ MID_BOW_SAA_FSM_ABORT, /* BOW notify SAA for Aborting authentication/association fsm */ -+ MID_SAA_BOW_JOIN_COMPLETE, /* SAA notify BOW for indicating join complete */ -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /*--------------------------------------------------*/ -+ /* P2P Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ MID_P2P_SAA_FSM_START, /* P2P notify SAA for Starting authentication/association fsm */ -+ MID_P2P_SAA_FSM_ABORT, /* P2P notify SAA for Aborting authentication/association fsm */ -+ MID_SAA_P2P_JOIN_COMPLETE, /* SAA notify P2P for indicating join complete */ -+ -+ MID_MNY_P2P_FUN_SWITCH, /* Enable P2P FSM. */ -+ MID_MNY_P2P_DEVICE_DISCOVERY, /* Start device discovery. */ -+ MID_MNY_P2P_CONNECTION_REQ, /* Connection request. */ -+ MID_MNY_P2P_CONNECTION_ABORT, /* Abort connection request, P2P FSM return to IDLE. */ -+ MID_MNY_P2P_BEACON_UPDATE, -+ MID_MNY_P2P_STOP_AP, -+ MID_MNY_P2P_CHNL_REQ, -+ MID_MNY_P2P_CHNL_ABORT, -+ MID_MNY_P2P_MGMT_TX, -+ MID_MNY_P2P_GROUP_DISSOLVE, -+ MID_MNY_P2P_MGMT_FRAME_REGISTER, -+ MID_MNY_P2P_NET_DEV_REGISTER, -+ MID_MNY_P2P_START_AP, -+ MID_MNY_P2P_MGMT_FRAME_UPDATE, -+ MID_MNY_P2P_EXTEND_LISTEN_INTERVAL, -+#if CFG_SUPPORT_WFD -+ MID_MNY_P2P_WFD_CFG_UPDATE, -+#endif -+#endif -+ -+#if CFG_SUPPORT_ADHOC -+ MID_SCN_AIS_FOUND_IBSS, /* SCN notify AIS that an IBSS Peer has been found and can merge into */ -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ MID_SAA_AIS_FSM_ABORT, /* SAA notify AIS for indicating deauthentication/disassociation */ -+ -+ /*--------------------------------------------------*/ -+ /* AIS MGMT-TX Support */ -+ /*--------------------------------------------------*/ -+ MID_MNY_AIS_REMAIN_ON_CHANNEL, -+ MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL, -+ MID_MNY_AIS_MGMT_TX, -+ -+ MID_TOTAL_NUM -+} ENUM_MSG_ID_T, *P_ENUM_MSG_ID_T; -+ -+/* Message header of inter-components */ -+struct _MSG_HDR_T { -+ LINK_ENTRY_T rLinkEntry; -+ ENUM_MSG_ID_T eMsgId; -+}; -+ -+typedef VOID(*PFN_MSG_HNDL_FUNC) (P_ADAPTER_T, P_MSG_HDR_T); -+ -+typedef struct _MSG_HNDL_ENTRY { -+ ENUM_MSG_ID_T eMsgId; -+ PFN_MSG_HNDL_FUNC pfMsgHndl; -+} MSG_HNDL_ENTRY_T, *P_MSG_HNDL_ENTRY_T; -+ -+typedef enum _EUNM_MSG_SEND_METHOD_T { -+ MSG_SEND_METHOD_BUF = 0, /* Message is put in the queue and will be -+ executed when mailbox is checked. */ -+ MSG_SEND_METHOD_UNBUF /* The handler function is called immediately -+ in the same context of the sender */ -+} EUNM_MSG_SEND_METHOD_T, *P_EUNM_MSG_SEND_METHOD_T; -+ -+typedef enum _ENUM_MBOX_ID_T { -+ MBOX_ID_0 = 0, -+ MBOX_ID_TOTAL_NUM -+} ENUM_MBOX_ID_T, *P_ENUM_MBOX_ID_T; -+ -+/* Define Mailbox structure */ -+typedef struct _MBOX_T { -+ LINK_T rLinkHead; -+} MBOX_T, *P_MBOX_T; -+ -+typedef struct _MSG_SAA_FSM_START_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ P_STA_RECORD_T prStaRec; -+} MSG_SAA_FSM_START_T, *P_MSG_SAA_FSM_START_T; -+ -+typedef struct _MSG_SAA_FSM_COMP_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ WLAN_STATUS rJoinStatus; -+ P_STA_RECORD_T prStaRec; -+ P_SW_RFB_T prSwRfb; -+} MSG_SAA_FSM_COMP_T, *P_MSG_SAA_FSM_COMP_T; -+ -+typedef struct _MSG_SAA_FSM_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ P_STA_RECORD_T prStaRec; -+} MSG_SAA_FSM_ABORT_T, *P_MSG_SAA_FSM_ABORT_T; -+ -+typedef struct _MSG_CONNECTION_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+} MSG_CONNECTION_ABORT_T, *P_MSG_CONNECTION_ABORT_T; -+ -+typedef struct _MSG_REMAIN_ON_CHANNEL_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ ENUM_BAND_T eBand; -+ ENUM_CHNL_EXT_T eSco; -+ UINT_8 ucChannelNum; -+ UINT_32 u4DurationMs; -+ UINT_64 u8Cookie; -+} MSG_REMAIN_ON_CHANNEL_T, *P_MSG_REMAIN_ON_CHANNEL_T; -+ -+typedef struct _MSG_CANCEL_REMAIN_ON_CHANNEL_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_64 u8Cookie; -+} MSG_CANCEL_REMAIN_ON_CHANNEL_T, *P_MSG_CANCEL_REMAIN_ON_CHANNEL_T; -+ -+typedef struct _MSG_MGMT_TX_REQUEST_T { -+ MSG_HDR_T rMsgHdr; -+ P_MSDU_INFO_T prMgmtMsduInfo; -+ UINT_64 u8Cookie; /* For indication. */ -+ BOOLEAN fgNoneCckRate; -+ BOOLEAN fgIsWaitRsp; -+} MSG_MGMT_TX_REQUEST_T, *P_MSG_MGMT_TX_REQUEST_T; -+ -+/* specific message data types */ -+typedef MSG_SAA_FSM_START_T MSG_JOIN_REQ_T, *P_MSG_JOIN_REQ_T; -+typedef MSG_SAA_FSM_COMP_T MSG_JOIN_COMP_T, *P_MSG_JOIN_COMP_T; -+typedef MSG_SAA_FSM_ABORT_T MSG_JOIN_ABORT_T, *P_MSG_JOIN_ABORT_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID mboxSetup(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId); -+ -+VOID -+mboxSendMsg(IN P_ADAPTER_T prAdapter, -+ IN ENUM_MBOX_ID_T eMboxId, IN P_MSG_HDR_T prMsg, IN EUNM_MSG_SEND_METHOD_T eMethod); -+ -+VOID mboxRcvAllMsg(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId); -+ -+VOID mboxInitialize(IN P_ADAPTER_T prAdapter); -+ -+VOID mboxDestroy(IN P_ADAPTER_T prAdapter); -+ -+VOID mboxDummy(IN P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _HEM_MBOX_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h -new file mode 100644 -index 0000000000000..88b99222133f4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h -@@ -0,0 +1,148 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/HS2_DEV_SW/MT6620_WIFI_DRIVER_V2_1_HS_2_0/include/mgmt/hs20.h#2 -+*/ -+ -+/*! \file hs20.h -+ \brief This file contains the function declaration for hs20.c. -+*/ -+ -+/* -+** Log: -+ * -+ */ -+ -+#ifndef _HS20_H -+#define _HS20_H -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define BSSID_POOL_MAX_SIZE 8 -+#define HS20_SIGMA_SCAN_RESULT_TIMEOUT 30 /* sec */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+/*For GTK Frame Filter*/ -+typedef struct _IPV4_NETWORK_ADDRESS_LIST { -+ UINT_8 ucAddrCount; -+ IPV4_NETWORK_ADDRESS arNetAddr[1]; -+} IPV4_NETWORK_ADDRESS_LIST, *P_IPV4_NETWORK_ADDRESS_LIST; -+#endif -+ -+/* Entry of BSSID Pool - For SIGMA Test */ -+typedef struct _BSSID_ENTRY_T { -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+} BSSID_ENTRY_T, P_HS20_BSSID_POOL_ENTRY_T; -+ -+struct _HS20_INFO_T { -+ -+ /*Hotspot 2.0 Information */ -+ UINT_8 aucHESSID[MAC_ADDR_LEN]; -+ UINT_8 ucAccessNetworkOptions; -+ UINT_8 ucVenueGroup; /* VenueInfo - Group */ -+ UINT_8 ucVenueType; -+ UINT_8 ucHotspotConfig; -+ -+ /*Roaming Consortium Information */ -+ /* PARAM_HS20_ROAMING_CONSORTIUM_INFO rRCInfo; */ -+ -+ /*Hotspot 2.0 dummy AP Info */ -+ -+ /*Time Advertisement Information */ -+ /* UINT_32 u4UTCOffsetTime; */ -+ /* UINT_8 aucTimeZone[ELEM_MAX_LEN_TIME_ZONE]; */ -+ /* UINT_8 ucLenTimeZone; */ -+ -+ /* For SIGMA Test */ -+ /* BSSID Pool */ -+ BSSID_ENTRY_T arBssidPool[BSSID_POOL_MAX_SIZE]; -+ UINT_8 ucNumBssidPoolEntry; -+ BOOLEAN fgIsHS2SigmaMode; -+ -+}; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/*For GTK Frame Filter*/ -+#if DBG -+#define FREE_IPV4_NETWORK_ADDR_LIST(_prAddrList) \ -+ { \ -+ UINT_32 u4Size = OFFSET_OF(IPV4_NETWORK_ADDRESS_LIST, arNetAddr) + \ -+ (((_prAddrList)->ucAddrCount) * sizeof(IPV4_NETWORK_ADDRESS)); \ -+ kalMemFree((_prAddrList), VIR_MEM_TYPE, u4Size); \ -+ (_prAddrList) = NULL; \ -+ } -+#else -+#define FREE_IPV4_NETWORK_ADDR_LIST(_prAddrList) \ -+ { \ -+ kalMemFree((_prAddrList), VIR_MEM_TYPE, 0); \ -+ (_prAddrList) = NULL; \ -+ } -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+VOID hs20GenerateInterworkingIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo); -+ -+VOID hs20GenerateRoamingConsortiumIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo); -+ -+VOID hs20GenerateHS20IE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo); -+ -+VOID hs20FillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); -+ -+VOID hs20FillProreqExtCapIE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE); -+ -+VOID hs20FillHS20IE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE); -+ -+UINT_32 hs20CalculateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID); -+ -+WLAN_STATUS hs20GenerateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID, OUT PUINT_8 prIE); -+ -+BOOLEAN hs20IsGratuitousArp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb); -+ -+BOOLEAN hs20IsUnsolicitedNeighborAdv(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb); -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+BOOLEAN hs20IsForgedGTKFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb); -+#endif -+ -+BOOLEAN hs20IsUnsecuredFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb); -+ -+BOOLEAN hs20IsFrameFilterEnabled(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo); -+ -+WLAN_STATUS hs20SetBssidPool(IN P_ADAPTER_T prAdapter, IN PVOID pvBuffer, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx); -+ -+#endif -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h -new file mode 100644 -index 0000000000000..cb89fd8793ee4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h -@@ -0,0 +1,153 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/mib.h#1 -+*/ -+ -+/*! \file mib.h -+ \brief This file contains the IEEE 802.11 family related MIB definition -+ for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: mib.h -+ * -+ * 11 08 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * add the message check code from mt5921. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+#ifndef _MIB_H -+#define _MIB_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Entry in SMT AuthenticationAlgorithms Table: dot11AuthenticationAlgorithmsEntry */ -+typedef struct _DOT11_AUTHENTICATION_ALGORITHMS_ENTRY { -+ BOOLEAN dot11AuthenticationAlgorithmsEnable; /* dot11AuthenticationAlgorithmsEntry 3 */ -+} DOT11_AUTHENTICATION_ALGORITHMS_ENTRY, *P_DOT11_AUTHENTICATION_ALGORITHMS_ENTRY; -+ -+/* Entry in SMT dot11RSNAConfigPairwiseCiphersTalbe Table: dot11RSNAConfigPairwiseCiphersEntry */ -+typedef struct _DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY { -+ UINT_32 dot11RSNAConfigPairwiseCipher; /* dot11RSNAConfigPairwiseCiphersEntry 2 */ -+ BOOLEAN dot11RSNAConfigPairwiseCipherEnabled; /* dot11RSNAConfigPairwiseCiphersEntry 3 */ -+} DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY, *P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY; -+ -+/* Entry in SMT dot11RSNAConfigAuthenticationSuitesTalbe Table: dot11RSNAConfigAuthenticationSuitesEntry */ -+typedef struct _DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY { -+ UINT_32 dot11RSNAConfigAuthenticationSuite; /* dot11RSNAConfigAuthenticationSuitesEntry 2 */ -+ BOOLEAN dot11RSNAConfigAuthenticationSuiteEnabled; /* dot11RSNAConfigAuthenticationSuitesEntry 3 */ -+} DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY, *P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY; -+ -+/* ----- IEEE 802.11 MIB Major sections ----- */ -+typedef struct _IEEE_802_11_MIB_T { -+ /* dot11PrivacyTable (dot11smt 5) */ -+ UINT_8 dot11WEPDefaultKeyID; /* dot11PrivacyEntry 2 */ -+ BOOLEAN dot11TranmitKeyAvailable; -+ UINT_32 dot11WEPICVErrorCount; /* dot11PrivacyEntry 5 */ -+ UINT_32 dot11WEPExcludedCount; /* dot11PrivacyEntry 6 */ -+ -+ /* dot11RSNAConfigTable (dot11smt 8) */ -+ UINT_32 dot11RSNAConfigGroupCipher; /* dot11RSNAConfigEntry 4 */ -+ -+ /* dot11RSNAConfigPairwiseCiphersTable (dot11smt 9) */ -+ DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY dot11RSNAConfigPairwiseCiphersTable[MAX_NUM_SUPPORTED_CIPHER_SUITES]; -+ -+ /* dot11RSNAConfigAuthenticationSuitesTable (dot11smt 10) */ -+ DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY -+ dot11RSNAConfigAuthenticationSuitesTable[MAX_NUM_SUPPORTED_AKM_SUITES]; -+ -+#if 0 /* SUPPORT_WAPI */ -+ BOOLEAN fgWapiKeyInstalled; -+ PARAM_WPI_KEY_T rWapiPairwiseKey[2]; -+ BOOLEAN fgPairwiseKeyUsed[2]; -+ UINT_8 ucWpiActivedPWKey; /* Must be 0 or 1, by wapi spec */ -+ PARAM_WPI_KEY_T rWapiGroupKey[2]; -+ BOOLEAN fgGroupKeyUsed[2]; -+#endif -+} IEEE_802_11_MIB_T, *P_IEEE_802_11_MIB_T; -+ -+/* ------------------ IEEE 802.11 non HT PHY characteristics ---------------- */ -+typedef const struct _NON_HT_PHY_ATTRIBUTE_T { -+ UINT_16 u2SupportedRateSet; -+ -+ BOOLEAN fgIsShortPreambleOptionImplemented; -+ -+ BOOLEAN fgIsShortSlotTimeOptionImplemented; -+ -+} NON_HT_PHY_ATTRIBUTE_T, *P_NON_HT_PHY_ATTRIBUTE_T; -+ -+typedef const struct _NON_HT_ADHOC_MODE_ATTRIBUTE_T { -+ -+ ENUM_PHY_TYPE_INDEX_T ePhyTypeIndex; -+ -+ UINT_16 u2BSSBasicRateSet; -+ -+} NON_HT_ADHOC_MODE_ATTRIBUTE_T, *P_NON_HT_ADHOC_MODE_ATTRIBUTE_T; -+ -+typedef NON_HT_ADHOC_MODE_ATTRIBUTE_T NON_HT_AP_MODE_ATTRIBUTE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern NON_HT_PHY_ATTRIBUTE_T rNonHTPhyAttributes[]; -+extern NON_HT_ADHOC_MODE_ATTRIBUTE_T rNonHTAdHocModeAttributes[]; -+extern NON_HT_AP_MODE_ATTRIBUTE_T rNonHTApModeAttributes[]; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _MIB_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h -new file mode 100644 -index 0000000000000..11145c31dbfae ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h -@@ -0,0 +1,55 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_assoc.h#1 -+*/ -+ -+/*! \file p2p_assoc.h -+ \brief This file contains the Wi-Fi Direct ASSOC REQ/RESP of -+ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+#ifndef _P2P_ASSOC_H -+#define _P2P_ASSOC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+PUINT_8 p2pBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h -new file mode 100644 -index 0000000000000..869d7bf0ee614 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h -@@ -0,0 +1,56 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_bss.h#2 -+*/ -+ -+/*! \file "p2p_bss.h" -+ \brief In this file we define the function prototype used in p2p BSS/IBSS. -+ -+ The file contains the function declarations and defines for used in BSS/IBSS. -+*/ -+ -+#ifndef _P2P_BSS_H -+#define _P2P_BSS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+UINT_32 p2pGetTxProbRspIeTableSize(VOID); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h -new file mode 100644 -index 0000000000000..2541e1d2883e8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h -@@ -0,0 +1,2190 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_fsm.h#23 -+*/ -+ -+/*! \file p2p_fsm.h -+ \brief Declaration of functions and finite state machine for P2P Module. -+ -+ Declaration of functions and finite state machine for P2P Module. -+*/ -+ -+/* -+** Log: p2p_fsm.h -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 14 2012 yuche.tsai -+** NULL -+** Fix compile error. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 18 2012 yuche.tsai -+ * NULL -+ * add one file. -+ * -+ * 12 02 2011 yuche.tsai -+ * NULL -+ * Resolve class 3 error issue under AP mode. -+ * -+ * data frame may TX before Assoc Response TX. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix default device name issue. -+ * -+ * 11 09 2011 yuche.tsai -+ * [WCXRP00001093] [Need Patch][Volunteer Patch] Service Discovery 2.0 state transition issue. -+ * Fix SD2.0 issue which may cause KE. (Monkey test) -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version -+ * query & set support for service discovery version check. -+ * Add support for driver version query & p2p supplicant verseion set. -+ * For new service discovery mechanism sync. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * Support Channel Query. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 09 01 2011 yuche.tsai -+ * NULL -+ * Fix channel stay interval. -+ * Sync channel stay interval & channel request interval under AP mode.. -+ * -+ * 08 30 2011 yuche.tsai -+ * [WCXRP00000953] [Volunteer Patch][Driver] Hot Spot Channel ASSERT issue. -+ * Fix hot spot FW assert issue when under concurrent case. (DBG enable only) -+ * -+ * 08 16 2011 cp.wu -+ * [WCXRP00000934] [MT6620 Wi-Fi][Driver][P2P] Wi-Fi hot spot with auto sparse channel residence -+ * auto channel decision for 2.4GHz hot spot mode -+ * -+ * 08 16 2011 yuche.tsai -+ * NULL -+ * Fix scan policy for Active LISTEN scan. -+ * -+ * 08 09 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Invitation Feature add on. -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, -+ * TX deauth to a disconnecting device issue. -+ * Support TX Deauth Issue. -+ * -+ * 07 26 2011 yuche.tsai -+ * [WCXRP00000875] [Volunteer Patch][WiFi Direct][Driver] MT6620 IOT issue with realtek test bed solution. -+ * Turn off persistent group support for V2.0 release. -+ * -+ * 07 18 2011 yuche.tsai -+ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution. -+ * Fix compile error. -+ * -+ * 07 18 2011 yuche.tsai -+ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution. -+ * Fix MT6620 WiFi Direct IOT Issue with BCM solution. -+ * -+ * 07 11 2011 yuche.tsai -+ * [WCXRP00000845] [Volunteer Patch][WiFi Direct] WiFi Direct Device Connection Robustness -+ * Enhance Connection Robustness. -+ * -+ * 07 08 2011 yuche.tsai -+ * [WCXRP00000841] [Volunteer Patch][WiFi Direct] Group Owner Setting. -+ * Update GO configure parameter. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Disable enhancement II for debugging. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Refine compile flag. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Add wifi direct connection enhancement method I, II & VI. -+ * -+ * 06 20 2011 yuche.tsai -+ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. -+ * Fix connection indication twice issue. -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Fix RX SD request under AP mode issue. -+ * -+ * 05 04 2011 yuche.tsai -+ * NULL -+ * Support partial persistent group function. -+ * -+ * 04 20 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discoverability support. -+ * -+ * 03 25 2011 yuche.tsai -+ * NULL -+ * Improve some error handleing. -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * 1.Shorten the LISTEN interval. -+ * 2. Fix IF address issue when we are GO -+ * 3. Fix LISTEN channel issue. -+ * -+ * 03 21 2011 yuche.tsai -+ * NULL -+ * Change P2P Connection Request Flow. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Add beacon timeout support. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Append P2P IE in Assoc Req, so that GC can be discovered in probe response of GO. -+ * -+ * 03 18 2011 yuche.tsai -+ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow -+ * Modify connection flow after Group Formation Complete, or device connect to a GO. -+ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN. -+ * -+ * 03 15 2011 yuche.tsai -+ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue -+ * Fix some configure method issue. -+ * -+ * 03 10 2011 yuche.tsai -+ * NULL -+ * Add P2P API. -+ * -+ * 03 07 2011 yuche.tsai -+ * [WCXRP00000502] [Volunteer Patch][MT6620][Driver] Fix group ID issue when doing Group Formation. -+ * . -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation -+ * Update channel issue when doing GO formation.. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Update Service Discovery Related wlanoid function. -+ * -+ * 02 18 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * fixed the ioctl setting that index not map to spec defined config method. -+ * -+ * 02 18 2011 yuche.tsai -+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue -+ * Fix WSC IE BE format issue. -+ * -+ * 02 17 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * append the WSC IE config method attribute at provision discovery request. -+ * -+ * 02 11 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add two function prototype. -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Support Disassoc & Deauthentication for Hot-Spot. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+ -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Indication Related code. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add Support for MLME deauthentication for Hot-Spot. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue -+ * Fix Client Limit Issue. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+ -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Function. -+ * -+ * 01 25 2011 terry.wu -+ * [WCXRP00000393] [MT6620 Wi-Fi][Driver] Add new module insert parameter -+ * Add a new module parameter to indicate current runnig mode, P2P or AP. -+ * -+ * 01 19 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Null NOA attribute setting when no related parameters. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Modify some behavior of AP mode. -+ * -+ * 12 22 2010 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Fix Compile Error. -+ * -+ * 12 15 2010 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Refine Connection Flow. -+ * -+ * 12 08 2010 yuche.tsai -+ * [WCXRP00000244] [MT6620][Driver] Add station record type for each client when in AP mode. -+ * Change STA Type under AP mode. We would tell if client is a P2P device or a legacy client -+ * by checking the P2P IE in assoc req frame. -+ * -+ * 12 02 2010 yuche.tsai -+ * NULL -+ * Update P2P Connection Policy for Invitation. -+ * -+ * 12 02 2010 yuche.tsai -+ * NULL -+ * Update P2P Connection Policy for Invitation & Provision Discovery. -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Invitation & Provision Discovery Indication. -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Update Configure Method indication & selection for Provision Discovery & GO_NEGO_REQ -+ * -+ * 11 29 2010 yuche.tsai -+ * NULL -+ * Update P2P related function for INVITATION & PROVISION DISCOVERY. -+ * -+ * 11 26 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * Update P2P PS for NOA function. -+ * -+ * 11 25 2010 yuche.tsai -+ * NULL -+ * Update Code for Invitation Related Function. -+ * -+ * 11 17 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] -+ * Set the Tx lowest rate at wlan table for normal operation -+ * fixed some ASSERT check. -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * update the frog's new p2p state machine. -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * fixed compiling error while enable p2p. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 09 10 2010 wh.su -+ * NULL -+ * fixed the compiling error at WinXP. -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add connection abort message event prototype. -+ * -+ * 08 20 2010 kevin.huang -+ * NULL -+ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete() -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Fix P2P Intended Interface Address Bug. -+ * Extend GO Nego Timeout Time. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Extend Listen Interval default value & remove deprecated variable. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Add function prototype for join complete. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add some function proto type for P2P FSM under provisioning phase.. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Change P2P data structure for supporting -+ * 1. P2P Device discovery. -+ * 2. P2P Group Negotiation. -+ * 3. P2P JOIN -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Check-in P2P Device Discovery Feature. -+ * -+ * 08 03 2010 george.huang -+ * NULL -+ * handle event for updating NOA parameters indicated from FW -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Update P2P FSM header file. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * P2P/RSN/WAPI IEs need to be declared with compact structure. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add for P2P Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Update P2P FSM header file. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix some P2P function prototype. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * First draft for migration P2P FSM from FW to Driver. -+ * -+ * 03 18 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Rename CFG flag for P2P -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Modify parameter of p2pStartGO -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add Wi-Fi Direct SSID and P2P GO Test Mode -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+*/ -+ -+#ifndef _P2P_FSM_H -+#define _P2P_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#define CID52_53_54 0 -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_P2P_STATE_T { -+ P2P_STATE_IDLE = 0, -+ P2P_STATE_SCAN, -+ P2P_STATE_AP_CHANNEL_DETECT, -+ P2P_STATE_REQING_CHANNEL, -+ P2P_STATE_CHNL_ON_HAND, /* Requesting Channel to Send Specific Frame. */ -+ P2P_STATE_GC_JOIN, /* Sending Specific Frame. May extending channel by other event. */ -+ P2P_STATE_NUM -+} ENUM_P2P_STATE_T, *P_ENUM_P2P_STATE_T; -+ -+enum _ENUM_P2P_DEV_EXT_LISTEN_T { -+ P2P_DEV_NOT_EXT_LISTEN, -+ P2P_DEV_EXT_LISTEN_ING, -+ P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT, -+ P2P_DEV_EXT_LISTEN_NUM -+}; -+ -+typedef enum _ENUM_CHANNEL_REQ_TYPE_T { -+ CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL, -+ CHANNEL_REQ_TYPE_GC_JOIN_REQ, -+ CHANNEL_REQ_TYPE_GO_START_BSS -+} ENUM_CHANNEL_REQ_TYPE_T, *P_ENUM_CHANNEL_REQ_TYPE_T; -+ -+typedef enum _ENUM_BUFFER_TYPE_T { -+ ENUM_FRAME_TYPE_EXTRA_IE_BEACON, -+ ENUM_FRAME_TYPE_EXTRA_IE_ASSOC_RSP, -+ ENUM_FRAME_TYPE_EXTRA_IE_PROBE_RSP, -+ ENUM_FRAME_TYPE_PROBE_RSP_TEMPLATE, -+ ENUM_FRAME_TYPE_BEACON_TEMPLATE, -+ ENUM_FRAME_IE_NUM -+} ENUM_BUFFER_TYPE_T, *P_ENUM_BUFFER_TYPE_T; -+ -+typedef enum _ENUM_HIDDEN_SSID_TYPE_T { -+ ENUM_HIDDEN_SSID_NONE, -+ ENUM_HIDDEN_SSID_LEN, -+ ENUM_HIDDEN_SSID_ZERO_CONTENT, -+ ENUM_HIDDEN_SSID_NUM -+} ENUM_HIDDEN_SSID_TYPE_T, *P_ENUM_HIDDEN_SSID_TYPE_T; -+ -+typedef struct _P2P_SSID_STRUCT_T { -+ UINT_8 aucSsid[32]; -+ UINT_8 ucSsidLen; -+} P2P_SSID_STRUCT_T, *P_P2P_SSID_STRUCT_T; -+ -+typedef struct _P2P_STATION_INFO_T { -+ UINT_32 u4InactiveTime; -+ UINT_32 u4RxBytes; /* TODO: */ -+ UINT_32 u4TxBytes; /* TODO: */ -+ UINT_32 u4RxPackets; /* TODO: */ -+ UINT_32 u4TxPackets; /* TODO: */ -+ /* TODO: Add more for requirement. */ -+} P2P_STATION_INFO_T, *P_P2P_STATION_INFO_T; -+ -+typedef struct _AP_CRYPTO_SETTINGS_T { -+ UINT_32 u4WpaVersion; -+ UINT_32 u4CipherGroup; -+ INT_32 i4NumOfCiphers; -+ UINT_32 aucCiphersPairwise[5]; -+ INT_32 i4NumOfAkmSuites; -+ UINT_32 aucAkmSuites[2]; -+ BOOLEAN fgIsControlPort; -+ UINT_16 u2ControlPortBE; -+ BOOLEAN fgIsControlPortEncrypt; -+} AP_CRYPTO_SETTINGS_T, *P_AP_CRYPTO_SETTINGS_T; -+ -+/*-------------------- P2P FSM ACTION STRUCT ---------------------*/ -+typedef struct _P2P_CHNL_REQ_INFO_T { -+ BOOLEAN fgIsChannelRequested; -+ UINT_8 ucSeqNumOfChReq; -+ UINT_64 u8Cookie; -+ UINT_8 ucReqChnlNum; -+ ENUM_BAND_T eBand; -+ ENUM_CHNL_EXT_T eChnlSco; -+ UINT_32 u4MaxInterval; -+ ENUM_CHANNEL_REQ_TYPE_T eChannelReqType; -+ -+ UINT_8 ucOriChnlNum; -+ ENUM_BAND_T eOriBand; -+ ENUM_CHNL_EXT_T eOriChnlSco; -+ UINT_32 NFC_BEAM; /*NFC Beam + Indication */ -+} P2P_CHNL_REQ_INFO_T, *P_P2P_CHNL_REQ_INFO_T; -+ -+typedef struct _P2P_SCAN_REQ_INFO_T { -+ ENUM_SCAN_TYPE_T eScanType; -+ ENUM_SCAN_CHANNEL eChannelSet; -+ UINT_16 u2PassiveDewellTime; -+ UINT_8 ucSeqNumOfScnMsg; -+ BOOLEAN fgIsAbort; -+ BOOLEAN fgIsScanRequest; -+ UINT_8 ucNumChannelList; -+ RF_CHANNEL_INFO_T arScanChannelList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ UINT_32 u4BufLength; -+ UINT_8 aucIEBuf[MAX_IE_LENGTH]; -+ P2P_SSID_STRUCT_T rSsidStruct; /* Currently we can only take one SSID scan request */ -+ BOOLEAN fgIsGOInitialDone; -+} P2P_SCAN_REQ_INFO_T, *P_P2P_SCAN_REQ_INFO_T; -+ -+typedef struct _P2P_CONNECTION_REQ_INFO_T { -+ -+ BOOLEAN fgIsConnRequest; -+ P2P_SSID_STRUCT_T rSsidStruct; -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ /* For ASSOC Req. */ -+ UINT_32 u4BufLength; -+ UINT_8 aucIEBuf[MAX_IE_LENGTH]; -+} P2P_CONNECTION_REQ_INFO_T, *P_P2P_CONNECTION_REQ_INFO_T; -+ -+typedef struct _P2P_MGMT_TX_REQ_INFO_T { -+ BOOLEAN fgIsMgmtTxRequested; -+ P_MSDU_INFO_T prMgmtTxMsdu; -+ UINT_64 u8Cookie; -+} P2P_MGMT_TX_REQ_INFO_T, *P_P2P_MGMT_TX_REQ_INFO_T; -+ -+struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T { -+ MSG_HDR_T rMsgHdr; -+ UINT_32 wait; /* interval supplicant expected to stay in listen interval */ -+}; -+ -+typedef struct _P2P_BEACON_UPDATE_INFO_T { -+ PUINT_8 pucBcnHdr; -+ UINT_32 u4BcnHdrLen; -+ PUINT_8 pucBcnBody; -+ UINT_32 u4BcnBodyLen; -+} P2P_BEACON_UPDATE_INFO_T, *P_P2P_BEACON_UPDATE_INFO_T; -+ -+typedef struct _P2P_PROBE_RSP_UPDATE_INFO_T { -+ P_MSDU_INFO_T prProbeRspMsduTemplate; -+} P2P_PROBE_RSP_UPDATE_INFO_T, *P_P2P_PROBE_RSP_UPDATE_INFO_T; -+ -+typedef struct _P2P_ASSOC_RSP_UPDATE_INFO_T { -+ PUINT_8 pucAssocRspExtIE; -+ UINT_16 u2AssocIELen; -+} P2P_ASSOC_RSP_UPDATE_INFO_T, *P_P2P_ASSOC_RSP_UPDATE_INFO_T; -+ -+typedef struct _P2P_JOIN_INFO_T { -+ UINT_32 ucSeqNumOfReqMsg; -+ UINT_8 ucAvailableAuthTypes; -+ P_STA_RECORD_T prTargetStaRec; -+ P2P_SSID_STRUCT_T rSsidStruct; -+ BOOLEAN fgIsJoinComplete; -+ /* For ASSOC Rsp. */ -+ UINT_32 u4BufLength; -+ UINT_8 aucIEBuf[MAX_IE_LENGTH]; -+} P2P_JOIN_INFO_T, *P_P2P_JOIN_INFO_T; -+ -+#if CFG_SUPPORT_WFD -+ -+#define WFD_FLAGS_DEV_INFO_VALID BIT(0) /* 1. WFD_DEV_INFO, 2. WFD_CTRL_PORT, 3. WFD_MAT_TP. */ -+#define WFD_FLAGS_SINK_INFO_VALID BIT(1) /* 1. WFD_SINK_STATUS, 2. WFD_SINK_MAC. */ -+#define WFD_FLAGS_ASSOC_MAC_VALID BIT(2) /* 1. WFD_ASSOC_MAC. */ -+#define WFD_FLAGS_EXT_CAPABILITY_VALID BIT(3) /* 1. WFD_EXTEND_CAPABILITY. */ -+ -+struct _WFD_CFG_SETTINGS_T { -+ UINT_32 u4WfdCmdType; -+ UINT_8 ucWfdEnable; -+ UINT_8 ucWfdCoupleSinkStatus; -+ UINT_8 ucWfdSessionAvailable; /* 0: NA 1:Set 2:Clear */ -+ UINT_8 ucWfdSigmaMode; -+ UINT_16 u2WfdDevInfo; -+ UINT_16 u2WfdControlPort; -+ UINT_16 u2WfdMaximumTp; -+ UINT_16 u2WfdExtendCap; -+ UINT_8 aucWfdCoupleSinkAddress[MAC_ADDR_LEN]; -+ UINT_8 aucWfdAssociatedBssid[MAC_ADDR_LEN]; -+ UINT_8 aucWfdVideoIp[4]; -+ UINT_8 aucWfdAudioIp[4]; -+ UINT_16 u2WfdVideoPort; -+ UINT_16 u2WfdAudioPort; -+ UINT_32 u4WfdFlag; -+ UINT_32 u4WfdPolicy; -+ UINT_32 u4WfdState; -+ UINT_8 aucWfdSessionInformationIE[24 * 8]; -+ UINT_16 u2WfdSessionInformationIELen; -+ UINT_8 aucReserved1[2]; -+ UINT_8 aucWfdPrimarySinkMac[MAC_ADDR_LEN]; -+ UINT_8 aucWfdSecondarySinkMac[MAC_ADDR_LEN]; -+ UINT_32 u4WfdAdvancedFlag; -+ /* Group 1 64 bytes */ -+ UINT_8 aucWfdLocalIp[4]; -+ UINT_16 u2WfdLifetimeAc2; /* Unit is 2 TU */ -+ UINT_16 u2WfdLifetimeAc3; /* Unit is 2 TU */ -+ UINT_16 u2WfdCounterThreshold; /* Unit is ms */ -+ UINT_8 aucReverved2[54]; -+ /* Group 2 64 bytes */ -+ UINT_8 aucReverved3[64]; -+ /* Group 3 64 bytes */ -+ UINT_8 aucReverved4[64]; -+ -+}; -+ -+struct _WFD_DBG_CFG_SETTINGS_T { -+ UINT_8 ucWfdDebugMode; -+ UINT_16 u2WfdSNShowPeiroid; -+ UINT_8 Reserved; -+ -+}; -+ -+#endif -+ -+struct _P2P_FSM_INFO_T { -+ /* State related. */ -+ ENUM_P2P_STATE_T ePreviousState; -+ ENUM_P2P_STATE_T eCurrentState; -+ -+ /* Channel related. */ -+ P2P_CHNL_REQ_INFO_T rChnlReqInfo; -+ -+ /* Scan related. */ -+ P2P_SCAN_REQ_INFO_T rScanReqInfo; -+ -+ /* Connection related. */ -+ P2P_CONNECTION_REQ_INFO_T rConnReqInfo; -+ -+ /* Mgmt tx related. */ -+ P2P_MGMT_TX_REQ_INFO_T rMgmtTxInfo; -+ -+ /* Beacon related. */ -+ P2P_BEACON_UPDATE_INFO_T rBcnContentInfo; -+ -+ /* Probe Response related. */ -+ P2P_PROBE_RSP_UPDATE_INFO_T rProbeRspContentInfo; -+ -+ /* Assoc Rsp related. */ -+ P2P_ASSOC_RSP_UPDATE_INFO_T rAssocRspContentInfo; -+ -+ /* GC Join related. */ -+ P2P_JOIN_INFO_T rJoinInfo; -+ -+ /* FSM Timer */ -+/* TIMER_T rP2pFsmTimeoutTimer; */ -+ -+ /* GC Target BSS. */ -+ P_BSS_DESC_T prTargetBss; -+ -+ /* GC Connection Request. */ -+ BOOLEAN fgIsConnectionRequested; -+ -+ BOOLEAN fgIsApMode; -+ -+ /* Channel grant interval. */ -+ UINT_32 u4GrantInterval; -+ -+ /* Packet filter for P2P module. */ -+ UINT_32 u4P2pPacketFilter; -+ -+ /* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Prepare for use vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ -+ /* Msg event queue. */ -+ LINK_T rMsgEventQueue; -+ -+#if CFG_SUPPORT_WFD -+ WFD_CFG_SETTINGS_T rWfdConfigureSettings; -+ WFD_DBG_CFG_SETTINGS_T rWfdDebugSetting; -+#endif -+ -+ BOOLEAN fgIsWPSMode; -+ -+ enum _ENUM_P2P_DEV_EXT_LISTEN_T eListenExted; -+}; -+ -+/*---------------- Messages -------------------*/ -+typedef struct _MSG_P2P_SCAN_REQUEST_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ P_P2P_SSID_STRUCT_T prSSID; -+ INT_32 i4SsidNum; -+ UINT_32 u4NumChannel; -+ PUINT_8 pucIEBuf; -+ UINT_32 u4IELen; -+ BOOLEAN fgIsAbort; -+ RF_CHANNEL_INFO_T arChannelListInfo[1]; -+} MSG_P2P_SCAN_REQUEST_T, *P_MSG_P2P_SCAN_REQUEST_T; -+ -+typedef struct _MSG_P2P_CHNL_REQUEST_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_64 u8Cookie; -+ UINT_32 u4Duration; -+ ENUM_CHNL_EXT_T eChnlSco; -+ RF_CHANNEL_INFO_T rChannelInfo; -+} MSG_P2P_CHNL_REQUEST_T, *P_MSG_P2P_CHNL_REQUEST_T; -+ -+typedef struct _MSG_P2P_CHNL_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_64 u8Cookie; -+} MSG_P2P_CHNL_ABORT_T, *P_MSG_P2P_CHNL_ABORT_T; -+ -+typedef struct _MSG_P2P_CONNECTION_REQUEST_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ P2P_SSID_STRUCT_T rSsid; -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ ENUM_CHNL_EXT_T eChnlSco; -+ RF_CHANNEL_INFO_T rChannelInfo; -+ UINT_32 u4IELen; -+ UINT_8 aucIEBuf[1]; -+ /* TODO: Auth Type, OPEN, SHARED, FT, EAP... */ -+} MSG_P2P_CONNECTION_REQUEST_T, *P_MSG_P2P_CONNECTION_REQUEST_T; -+ -+typedef struct _MSG_P2P_CONNECTION_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member. */ -+ UINT_8 aucTargetID[MAC_ADDR_LEN]; -+ UINT_16 u2ReasonCode; -+ BOOLEAN fgSendDeauth; -+} MSG_P2P_CONNECTION_ABORT_T, *P_MSG_P2P_CONNECTION_ABORT_T; -+ -+typedef struct _MSG_P2P_MGMT_TX_REQUEST_T { -+ MSG_HDR_T rMsgHdr; -+ P_MSDU_INFO_T prMgmtMsduInfo; -+ UINT_64 u8Cookie; /* For indication. */ -+ BOOLEAN fgNoneCckRate; -+ BOOLEAN fgIsWaitRsp; -+} MSG_P2P_MGMT_TX_REQUEST_T, *P_MSG_P2P_MGMT_TX_REQUEST_T; -+ -+typedef struct _MSG_P2P_START_AP_T { -+ MSG_HDR_T rMsgHdr; -+ UINT_32 u4DtimPeriod; -+ UINT_32 u4BcnInterval; -+ UINT_8 aucSsid[32]; -+ UINT_16 u2SsidLen; -+ UINT_8 ucHiddenSsidType; -+ BOOLEAN fgIsPrivacy; -+ AP_CRYPTO_SETTINGS_T rEncryptionSettings; -+ INT_32 i4InactiveTimeout; -+} MSG_P2P_START_AP_T, *P_MSG_P2P_START_AP_T; -+ -+typedef struct _MSG_P2P_BEACON_UPDATE_T { -+ MSG_HDR_T rMsgHdr; -+ UINT_32 u4BcnHdrLen; -+ UINT_32 u4BcnBodyLen; -+ PUINT_8 pucBcnHdr; -+ PUINT_8 pucBcnBody; -+ UINT_8 aucBuffer[1]; /* Header & Body are put here. */ -+} MSG_P2P_BEACON_UPDATE_T, *P_MSG_P2P_BEACON_UPDATE_T; -+ -+typedef struct _MSG_P2P_MGMT_FRAME_UPDATE_T { -+ MSG_HDR_T rMsgHdr; -+ ENUM_BUFFER_TYPE_T eBufferType; -+ UINT_32 u4BufferLen; -+ UINT_8 aucBuffer[1]; -+} MSG_P2P_MGMT_FRAME_UPDATE_T, *P_MSG_P2P_MGMT_FRAME_UPDATE_T; -+ -+typedef struct _MSG_P2P_SWITCH_OP_MODE_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ ENUM_OP_MODE_T eOpMode; -+} MSG_P2P_SWITCH_OP_MODE_T, *P_MSG_P2P_SWITCH_OP_MODE_T; -+ -+typedef struct _MSG_P2P_MGMT_FRAME_REGISTER_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_16 u2FrameType; -+ BOOLEAN fgIsRegister; -+} MSG_P2P_MGMT_FRAME_REGISTER_T, *P_MSG_P2P_MGMT_FRAME_REGISTER_T; -+ -+typedef struct _MSG_P2P_NETDEV_REGISTER_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ BOOLEAN fgIsEnable; -+ UINT_8 ucMode; -+} MSG_P2P_NETDEV_REGISTER_T, *P_MSG_P2P_NETDEV_REGISTER_T; -+ -+#if CFG_SUPPORT_WFD -+typedef struct _MSG_WFD_CONFIG_SETTINGS_CHANGED_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings; -+} MSG_WFD_CONFIG_SETTINGS_CHANGED_T, *P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T; -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID p2pFsmStateTransition(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID p2pFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+VOID p2pFsmRunEventScanRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventStartAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventNetDeviceRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventUpdateMgmtFrame(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventExtendListen(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventBeaconUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventStopAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventChannelRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventChannelAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventDissolve(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventSwitchOPMode(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+WLAN_STATUS -+p2pFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID p2pFsmRunEventMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+#if CFG_SUPPORT_WFD -+VOID p2pFsmRunEventWfdSettingUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+#endif -+ -+#if 0 -+/* ////////////////////////////////////////////////////////////////////////////////////////////////////// */ -+/* ///////////////////////////////////////////////////////////////////////////////////// */ -+/* ///////////////////////////////////////////////////////////////////////////////////// */ -+/* ///////////////////////////////////////////////////////////////////////////////////// */ -+/* ///////////////////////////////////////////////////////////////////////////////////// */ -+/* ////////////////////////////////////////////////////////////////////////////////////////////////////// */ -+#endif -+ -+/* 3 --------------- WFA P2P DEFAULT PARAMETERS --------------- */ -+#define P2P_WILDCARD_SSID "DIRECT-" -+#define P2P_WILDCARD_SSID_LEN 7 -+#define P2P_GROUP_ID_LEN 9 -+ -+#define P2P_DRIVER_VERSION 2 /* Update when needed. */ -+ -+#define P2P_DEFAULT_DEV_NAME "Wireless Client" -+#define P2P_DEFAULT_DEV_NAME_LEN 15 -+#define P2P_DEFAULT_PRIMARY_CATEGORY_ID 10 -+#define P2P_DEFAULT_PRIMARY_SUB_CATEGORY_ID 5 -+#define P2P_DEFAULT_CONFIG_METHOD \ -+ (WPS_ATTRI_CFG_METHOD_PUSH_BUTTON | WPS_ATTRI_CFG_METHOD_KEYPAD | WPS_ATTRI_CFG_METHOD_DISPLAY) -+#define P2P_DEFAULT_LISTEN_CHANNEL 1 -+ -+#define P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT 0 /* NOTE(Kevin): Shall <= 16 */ -+#define P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT 13 -+ -+#define P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE 51 /* Contains 6 sub-band. */ -+ -+#define P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT 8 /* NOTE(Kevin): Shall <= 16 */ -+ -+#define P2P_MAXIMUM_CLIENT_COUNT 8 -+#define P2P_MAXIMUM_NOA_COUNT 8 -+ -+#define P2P_MAXIMUM_ATTRIBUTE_LEN 251 -+ -+#define P2P_CTWINDOW_DEFAULT 25 /* in TU=(1024usec) */ -+ -+#define P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE 768 -+ -+/* P2P 3.1.2.1.3 - Find Phase */ -+#define P2P_MAX_DISCOVERABLE_INTERVAL 8 /* 3 */ -+#define P2P_MIN_DISCOVERABLE_INTERVAL 5 /* 1 */ -+ -+#define P2P_LISTEN_SCAN_UNIT 100 /* MS */ -+ -+/* FSM Time Related constrain. */ -+#define P2P_SERACH_STATE_PERIOD_MS 1000 /* Deprecated. */ -+ -+#define P2P_GO_CHANNEL_STAY_INTERVAL 1000 -+ -+#define P2P_GO_NEGO_TIMEOUT_MS 500 -+#define P2P_CONNECTION_TIMEOUT_SEC 120 -+ -+#define P2P_INVITAION_TIMEOUT_MS 500 /* Timeout Wait Invitation Resonse. */ -+#define P2P_PROVISION_DISCOVERY_TIMEOUT_MS 500 /* Timeout Wait Provision Discovery Resonse. */ -+ -+/* 3 --------------- WFA P2P IE --------------- */ -+/* P2P 4.1.1 - P2P IE format */ -+#define P2P_OUI_TYPE_LEN 4 -+#define P2P_IE_OUI_HDR (ELEM_HDR_LEN + P2P_OUI_TYPE_LEN) /* == OFFSET_OF(IE_P2P_T, -+ aucP2PAttributes[0]) */ -+ -+/* P2P 4.1.1 - General P2P Attribute */ -+#define P2P_ATTRI_HDR_LEN 3 /* ID(1 octet) + Length(2 octets) */ -+#define P2P_ATTRI_LEN_NOTICE_OF_ABSENCE (P2P_ATTRI_HDR_LEN + 2) /* 5 */ -+ -+/* P2P 4.1.1 - P2P Attribute ID definitions */ -+#define P2P_ATTRI_ID_STATUS 0 -+#define P2P_ATTRI_ID_REASON_CODE 1 -+#define P2P_ATTRI_ID_P2P_CAPABILITY 2 -+#define P2P_ATTRI_ID_P2P_DEV_ID 3 -+#define P2P_ATTRI_ID_GO_INTENT 4 -+#define P2P_ATTRI_ID_CFG_TIMEOUT 5 -+#define P2P_ATTRI_ID_LISTEN_CHANNEL 6 -+#define P2P_ATTRI_ID_P2P_GROUP_BSSID 7 -+#define P2P_ATTRI_ID_EXT_LISTEN_TIMING 8 -+#define P2P_ATTRI_ID_INTENDED_P2P_IF_ADDR 9 -+#define P2P_ATTRI_ID_P2P_MANAGEABILITY 10 -+#define P2P_ATTRI_ID_CHANNEL_LIST 11 -+#define P2P_ATTRI_ID_NOTICE_OF_ABSENCE 12 -+#define P2P_ATTRI_ID_P2P_DEV_INFO 13 -+#define P2P_ATTRI_ID_P2P_GROUP_INFO 14 -+#define P2P_ATTRI_ID_P2P_GROUP_ID 15 -+#define P2P_ATTRI_ID_P2P_INTERFACE 16 -+#define P2P_ATTRI_ID_OPERATING_CHANNEL 17 -+#define P2P_ATTRI_ID_INVITATION_FLAG 18 -+#define P2P_ATTRI_ID_VENDOR_SPECIFIC 221 -+ -+/* Maximum Length of P2P Attributes */ -+#define P2P_ATTRI_MAX_LEN_STATUS 1 /* 0 */ -+#define P2P_ATTRI_MAX_LEN_REASON_CODE 1 /* 1 */ -+#define P2P_ATTRI_MAX_LEN_P2P_CAPABILITY 2 /* 2 */ -+#define P2P_ATTRI_MAX_LEN_P2P_DEV_ID 6 /* 3 */ -+#define P2P_ATTRI_MAX_LEN_GO_INTENT 1 /* 4 */ -+#define P2P_ATTRI_MAX_LEN_CFG_TIMEOUT 2 /* 5 */ -+#if CID52_53_54 -+#define P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL 5 /* 6 */ -+#else -+#define P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL 5 /* 6 */ -+#endif -+#define P2P_ATTRI_MAX_LEN_P2P_GROUP_BSSID 6 /* 7 */ -+#define P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING 4 /* 8 */ -+#define P2P_ATTRI_MAX_LEN_INTENDED_P2P_IF_ADDR 6 /* 9 */ -+#define P2P_ATTRI_MAX_LEN_P2P_MANAGEABILITY 1 /* 10 */ -+/* #define P2P_ATTRI_MAX_LEN_CHANNEL_LIST 3 + (n* (2 + num_of_ch)) */ /* 11 */ -+#define P2P_ATTRI_LEN_CHANNEL_LIST 3 /* 11 */ -+#define P2P_ATTRI_LEN_CHANNEL_ENTRY 2 /* 11 */ -+ -+/* #define P2P_ATTRI_MAX_LEN_NOTICE_OF_ABSENCE 2 + (n* (13)) */ /* 12 */ -+#define P2P_ATTRI_MAX_LEN_NOTICE_OF_ABSENCE (2 + (P2P_MAXIMUM_NOA_COUNT*(13))) /* 12 */ -+ -+#define P2P_ATTRI_MAX_LEN_P2P_DEV_INFO (17 + (8 * (8)) + 36) /* 13 */ -+/* #define P2P_ATTRI_MAX_LEN_P2P_GROUP_INFO n* (25 + (m* (8)) + 32) */ /* 14 */ -+#define P2P_ATTRI_MAX_LEN_P2P_GROUP_ID 38 /* 15 */ -+#define P2P_ATTRI_MAX_LEN_P2P_INTERFACE 253 /* 7 + 6* [0~41] */ /* 16 */ -+#if CID52_53_54 -+#define P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL 5 /* 17 */ -+#else -+#define P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL 5 /* 17 */ -+#endif -+#define P2P_ATTRI_MAX_LEN_INVITATION_FLAGS 1 /* 18 */ -+ -+/* P2P 4.1.2 - P2P Status definitions */ -+#define P2P_STATUS_SUCCESS 0 -+#define P2P_STATUS_FAIL_INFO_IS_CURRENTLY_UNAVAILABLE 1 -+#define P2P_STATUS_FAIL_INCOMPATIBLE_PARAM 2 -+#define P2P_STATUS_FAIL_LIMIT_REACHED 3 -+#define P2P_STATUS_FAIL_INVALID_PARAM 4 -+#define P2P_STATUS_FAIL_UNABLE_ACCOMMODATE_REQ 5 -+#define P2P_STATUS_FAIL_PREVIOUS_PROTOCOL_ERR 6 -+#define P2P_STATUS_FAIL_NO_COMMON_CHANNELS 7 -+#define P2P_STATUS_FAIL_UNKNOWN_P2P_GROUP 8 -+#define P2P_STATUS_FAIL_SAME_INTENT_VALUE_15 9 -+#define P2P_STATUS_FAIL_INCOMPATIBLE_PROVISION_METHOD 10 -+#define P2P_STATUS_FAIL_REJECTED_BY_USER 11 -+ -+/* P2P 4.1.3 - P2P Minor Reason Code definitions */ -+#define P2P_REASON_SUCCESS 0 -+#define P2P_REASON_DISASSOCIATED_DUE_CROSS_CONNECTION 1 -+#define P2P_REASON_DISASSOCIATED_DUE_UNMANAGEABLE 2 -+#define P2P_REASON_DISASSOCIATED_DUE_NO_P2P_COEXIST_PARAM 3 -+#define P2P_REASON_DISASSOCIATED_DUE_MANAGEABLE 4 -+ -+/* P2P 4.1.4 - Device Capability Bitmap definitions */ -+#define P2P_DEV_CAPABILITY_SERVICE_DISCOVERY BIT(0) -+#define P2P_DEV_CAPABILITY_CLIENT_DISCOVERABILITY BIT(1) -+#define P2P_DEV_CAPABILITY_CONCURRENT_OPERATION BIT(2) -+#define P2P_DEV_CAPABILITY_P2P_INFRA_MANAGED BIT(3) -+#define P2P_DEV_CAPABILITY_P2P_DEVICE_LIMIT BIT(4) -+#define P2P_DEV_CAPABILITY_P2P_INVITATION_PROCEDURE BIT(5) -+ -+/* P2P 4.1.4 - Group Capability Bitmap definitions */ -+#define P2P_GROUP_CAPABILITY_P2P_GROUP_OWNER BIT(0) -+#define P2P_GROUP_CAPABILITY_PERSISTENT_P2P_GROUP BIT(1) -+#define P2P_GROUP_CAPABILITY_P2P_GROUP_LIMIT BIT(2) -+#define P2P_GROUP_CAPABILITY_INTRA_BSS_DISTRIBUTION BIT(3) -+#define P2P_GROUP_CAPABILITY_CROSS_CONNECTION BIT(4) -+#define P2P_GROUP_CAPABILITY_PERSISTENT_RECONNECT BIT(5) -+#define P2P_GROUP_CAPABILITY_GROUP_FORMATION BIT(6) -+ -+/* P2P 4.1.6 - GO Intent field definitions */ -+#define P2P_GO_INTENT_TIE_BREAKER_FIELD BIT(0) -+#define P2P_GO_INTENT_VALUE_MASK BITS(1, 7) -+#define P2P_GO_INTENT_VALUE_OFFSET 1 -+ -+/* P2P 4.1.12 - Manageability Bitmap definitions */ -+#define P2P_DEVICE_MANAGEMENT BIT(0) -+ -+/* P2P 4.1.14 - CTWindow and OppPS Parameters definitions */ -+#define P2P_CTW_OPPPS_PARAM_OPPPS_FIELD BIT(7) -+#define P2P_CTW_OPPPS_PARAM_CTWINDOW_MASK BITS(0, 6) -+ -+#define ELEM_MAX_LEN_P2P_FOR_PROBE_REQ \ -+ (P2P_OUI_TYPE_LEN + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_CAPABILITY) + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_DEV_ID) + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL) + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL)) -+ -+#define ELEM_MAX_LEN_P2P_FOR_ASSOC_REQ \ -+ (P2P_OUI_TYPE_LEN + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_CAPABILITY) + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING) + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_DEV_INFO)) -+ -+/* P2P 4.1.16 - P2P Client Infor Descriptor */ -+#define P2P_CLIENT_INFO_DESC_HDR_LEN 1 /* Length(1 octets) */ -+ -+/* P2P 4.1.20 - P2P Invitation Flags Attribute*/ -+#define P2P_INVITATION_FLAGS_INVITATION_TYPE BIT(0) -+#define P2P_INVITATION_TYPE_INVITATION 0 -+#define P2P_INVITATION_TYPE_REINVOKE 1 -+/* 3 --------------- WPS Data Element Definitions --------------- */ -+/* P2P 4.2.2 - General WSC Attribute */ -+#define WSC_ATTRI_HDR_LEN 4 /* ID(2 octet) + Length(2 octets) */ -+#define WSC_ATTRI_MAX_LEN_VERSION 1 -+#define WSC_ATTRI_MAX_LEN_DEVICE_PASSWORD_ID 2 -+#define WSC_ATTRI_LEN_CONFIG_METHOD 2 -+ -+/* WPS 11 - Data Element Definitions */ -+#define WPS_ATTRI_ID_VERSION 0x104A -+#define WPS_ATTRI_ID_CONFIGURATION_METHODS 0x1008 -+#define WPS_ATTRI_ID_DEVICE_PASSWORD 0x1012 -+#define WPS_ATTRI_ID_DEVICE_NAME 0x1011 -+#define WPS_ATTRI_ID_PRI_DEVICE_TYPE 0x1054 -+#define WPS_ATTRI_ID_SEC_DEVICE_TYPE 0x1055 -+ -+#define WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE 300 -+ -+#define WPS_ATTRI_MAX_LEN_DEVICE_NAME 32 /* 0x1011 */ -+ -+#define WPS_ATTRI_CFG_METHOD_USBA BIT(0) -+#define WPS_ATTRI_CFG_METHOD_ETHERNET BIT(1) -+#define WPS_ATTRI_CFG_METHOD_LABEL BIT(2) -+#define WPS_ATTRI_CFG_METHOD_DISPLAY BIT(3) -+#define WPS_ATTRI_CFG_METHOD_EXT_NFC BIT(4) -+#define WPS_ATTRI_CFG_METHOD_INT_NFC BIT(5) -+#define WPS_ATTRI_CFG_METHOD_NFC_IF BIT(6) -+#define WPS_ATTRI_CFG_METHOD_PUSH_BUTTON BIT(7) -+#define WPS_ATTRI_CFG_METHOD_KEYPAD BIT(8) -+ -+#define P2P_FLAGS_PROVISION_COMPLETE 0x00000001 -+#define P2P_FLAGS_PROVISION_DISCOVERY_COMPLETE 0x00000002 -+#define P2P_FLAGS_PROVISION_DISCOVERY_WAIT_RESPONSE 0x00000004 -+#define P2P_FLAGS_PROVISION_DISCOVERY_RESPONSE_WAIT 0x00000008 -+#define P2P_FLAGS_MASK_PROVISION 0x00000017 -+#define P2P_FLAGS_MASK_PROVISION_COMPLETE 0x00000015 -+#define P2P_FLAGS_PROVISION_DISCOVERY_INDICATED 0x00000010 -+#define P2P_FLAGS_INVITATION_TOBE_GO 0x00000100 -+#define P2P_FLAGS_INVITATION_TOBE_GC 0x00000200 -+#define P2P_FLAGS_INVITATION_SUCCESS 0x00000400 -+#define P2P_FLAGS_INVITATION_WAITING_TARGET 0x00000800 -+#define P2P_FLAGS_MASK_INVITATION 0x00000F00 -+#define P2P_FLAGS_FORMATION_ON_GOING 0x00010000 -+#define P2P_FLAGS_FORMATION_LOCAL_PWID_RDY 0x00020000 -+#define P2P_FLAGS_FORMATION_TARGET_PWID_RDY 0x00040000 -+#define P2P_FLAGS_FORMATION_COMPLETE 0x00080000 -+#define P2P_FLAGS_MASK_FORMATION 0x000F0000 -+#define P2P_FLAGS_DEVICE_DISCOVER_REQ 0x00100000 -+#define P2P_FLAGS_DEVICE_DISCOVER_DONE 0x00200000 -+#define P2P_FLAGS_DEVICE_INVITATION_WAIT 0x00400000 -+#define P2P_FLAGS_DEVICE_SERVICE_DISCOVER_WAIT 0x00800000 -+#define P2P_FLAGS_MASK_DEVICE_DISCOVER 0x00F00000 -+ -+#define P2P_FLAGS_DEVICE_FORMATION_REQUEST 0x01000000 -+ -+/* MACRO for flag operation */ -+#define SET_FLAGS(_FlagsVar, _BitsToSet) \ -+ {(_FlagsVar) = ((_FlagsVar) | (_BitsToSet))} -+ -+#define TEST_FLAGS(_FlagsVar, _BitsToCheck) \ -+ (((_FlagsVar) & (_BitsToCheck)) == (_BitsToCheck)) -+ -+#define CLEAR_FLAGS(_FlagsVar, _BitsToClear) \ -+ {(_FlagsVar) &= ~(_BitsToClear)} -+ -+#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_I 0 -+ -+#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_II 0 -+ -+#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_III 0 -+ -+#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_IV 0 -+ -+#define CFG_DISABLE_DELAY_PROVISION_DISCOVERY 0 -+ -+#define CFG_CONNECTION_POLICY_2_0 0 -+ -+/* Device Password ID */ -+enum wps_dev_password_id { -+ DEV_PW_DEFAULT = 0x0000, -+ DEV_PW_USER_SPECIFIED = 0x0001, -+ DEV_PW_MACHINE_SPECIFIED = 0x0002, -+ DEV_PW_REKEY = 0x0003, -+ DEV_PW_PUSHBUTTON = 0x0004, -+ DEV_PW_REGISTRAR_SPECIFIED = 0x0005 -+}; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) -+#pragma pack(1) -+#endif -+ -+/* 3 --------------- WFA P2P IE and Attributes --------------- */ -+ -+/* P2P 4.1.1 - P2P Information Element */ -+typedef struct _IE_P2P_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 aucP2PAttributes[1]; /* P2P Attributes */ -+} __KAL_ATTRIB_PACKED__ IE_P2P_T, *P_IE_P2P_T; -+ -+/* P2P 4.1.1 - General P2P Attribute */ -+typedef struct _P2P_ATTRIBUTE_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucBody[1]; /* Body field */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRIBUTE_T, ATTRIBUTE_HDR_T, *P_P2P_ATTRIBUTE_T, *P_ATTRIBUTE_HDR_T; -+ -+/* P2P 4.1.2 - P2P Status Attribute */ -+typedef struct _P2P_ATTRI_STATUS_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucStatusCode; /* Status Code */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_STATUS_T, *P_P2P_ATTRI_STATUS_T; -+ -+/* P2P 4.1.3 - P2P Minor Reason Code Attribute */ -+typedef struct _P2P_ATTRI_REASON_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucMinorReasonCode; /* Minor Reason Code */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_REASON_T, *P_P2P_ATTRI_REASON_T; -+ -+/* P2P 4.1.4 - P2P Capability Attribute */ -+typedef struct _P2P_ATTRI_CAPABILITY_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucDeviceCap; /* Device Capability Bitmap */ -+ UINT_8 ucGroupCap; /* Group Capability Bitmap */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CAPABILITY_T, *P_P2P_ATTRI_CAPABILITY_T; -+ -+/* P2P 4.1.5 - P2P Device ID Attribute */ -+typedef struct _P2P_ATTRI_DEV_ID_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_DEV_ID_T, *P_P2P_ATTRI_DEV_ID_T; -+ -+/* P2P 4.1.6 - Group Owner Intent Attribute */ -+typedef struct _P2P_ATTRI_GO_INTENT_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucGOIntent; /* Group Owner Intent */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GO_INTENT_T, *P_P2P_ATTRI_GO_INTENT_T; -+ -+/* P2P 4.1.7 - Configuration Timeout Attribute */ -+typedef struct _P2P_ATTRI_CFG_TIMEOUT_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucGOCfgTimeout; /* GO Configuration Timeout */ -+ UINT_8 ucClientCfgTimeout; /* Client Configuration Timeout */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CFG_TIMEOUT_T, *P_P2P_ATTRI_CFG_TIMEOUT_T; -+ -+/* P2P 4.1.8 - Listen Channel Attribute */ -+typedef struct _P2P_ATTRI_LISTEN_CHANNEL_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucCountryString[3]; /* Country String */ -+ UINT_8 ucOperatingClass; /* Operating Class from 802.11 Annex J/P802.11 REVmb 3.0 */ -+ UINT_8 ucChannelNumber; /* Channel Number */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_LISTEN_CHANNEL_T, *P_P2P_ATTRI_LISTEN_CHANNEL_T; -+ -+/* P2P 4.1.9 - P2P Group BSSID Attribute */ -+typedef struct _P2P_ATTRI_GROUP_BSSID_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucBssid[MAC_ADDR_LEN]; /* P2P Group BSSID */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_BSSID_T, *P_P2P_ATTRI_GROUP_BSSID_T; -+ -+/* P2P 4.1.10 - Extended Listen Timing Attribute */ -+typedef struct _P2P_ATTRI_EXT_LISTEN_TIMING_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_16 u2AvailPeriod; /* Availability Period */ -+ UINT_16 u2AvailInterval; /* Availability Interval */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_EXT_LISTEN_TIMING_T, *P_P2P_ATTRI_EXT_LISTEN_TIMING_T; -+ -+/* P2P 4.1.11 - Intended P2P Interface Address Attribute */ -+typedef struct _P2P_ATTRI_INTENDED_IF_ADDR_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucIfAddr[MAC_ADDR_LEN]; /* P2P Interface Address */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INTENDED_IF_ADDR_T, *P_P2P_ATTRI_INTENDED_IF_ADDR_T; -+ -+/* P2P 4.1.12 - P2P Manageability Attribute */ -+typedef struct _P2P_ATTRI_MANAGEABILITY_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucManageability; /* P2P Manageability Bitmap */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_MANAGEABILITY_T, *P_P2P_ATTRI_MANAGEABILITY_T; -+ -+/* P2P 4.1.13 - Channel List Attribute */ -+typedef struct _P2P_ATTRI_CHANNEL_LIST_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucCountryString[3]; /* Country String */ -+ UINT_8 aucChannelEntry[1]; /* Channel Entry List */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CHANNEL_T, *P_P2P_ATTRI_CHANNEL_T; -+ -+typedef struct _CHANNEL_ENTRY_FIELD_T { -+ UINT_8 ucRegulatoryClass; /* Regulatory Class */ -+ UINT_8 ucNumberOfChannels; /* Number Of Channels */ -+ UINT_8 aucChannelList[1]; /* Channel List */ -+} __KAL_ATTRIB_PACKED__ CHANNEL_ENTRY_FIELD_T, *P_CHANNEL_ENTRY_FIELD_T; -+ -+/* P2P 4.1.14 - Notice of Absence Attribute */ -+typedef struct _P2P_ATTRI_NOA_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucIndex; /* Index */ -+ UINT_8 ucCTWOppPSParam; /* CTWindow and OppPS Parameters */ -+ UINT_8 aucNoADesc[1]; /* NoA Descriptor */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_NOA_T, *P_P2P_ATTRI_NOA_T; -+ -+typedef struct _NOA_DESCRIPTOR_T { -+ UINT_8 ucCountType; /* Count/Type */ -+ UINT_32 u4Duration; /* Duration */ -+ UINT_32 u4Interval; /* Interval */ -+ UINT_32 u4StartTime; /* Start Time */ -+} __KAL_ATTRIB_PACKED__ NOA_DESCRIPTOR_T, *P_NOA_DESCRIPTOR_T; -+ -+typedef struct _P2P_ATTRI_DEV_INFO_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+ UINT_16 u2ConfigMethodsBE; /* Config Method */ -+ DEVICE_TYPE_T rPrimaryDevTypeBE; /* Primary Device Type */ -+ UINT_8 ucNumOfSecondaryDevType; /* Number of Secondary Device Types */ -+ DEVICE_TYPE_T arSecondaryDevTypeListBE[1]; /* Secondary Device Type List */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_DEV_INFO_T, *P_P2P_ATTRI_DEV_INFO_T; -+ -+/* WPS 7.1 & 11 WPS TLV Data Format - Device Name */ -+typedef struct _DEVICE_NAME_TLV_T { -+ UINT_16 u2Id; /* WPS Attribute Type */ -+ UINT_16 u2Length; /* Data Length */ -+ UINT_8 aucName[32]; /* Device Name */ /* TODO: Fixme */ -+} __KAL_ATTRIB_PACKED__ DEVICE_NAME_TLV_T, *P_DEVICE_NAME_TLV_T; -+ -+/* P2P 4.1.16 - P2P Group Info Attribute */ -+typedef struct _P2P_CLIENT_INFO_DESC_T { -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+ UINT_8 aucIfAddr[MAC_ADDR_LEN]; /* P2P Interface Address */ -+ UINT_8 ucDeviceCap; /* Device Capability Bitmap */ -+ UINT_16 u2ConfigMethodsBE; /* Config Method */ -+ DEVICE_TYPE_T rPrimaryDevTypeBE; /* Primary Device Type */ -+ UINT_8 ucNumOfSecondaryDevType; /* Number of Secondary Device Types */ -+ DEVICE_TYPE_T arSecondaryDevTypeListBE[1]; /* Secondary Device Type List */ -+} __KAL_ATTRIB_PACKED__ P2P_CLIENT_INFO_DESC_T, *P_P2P_CLIENT_INFO_DESC_T; -+ -+typedef struct _P2P_ATTRI_GROUP_INFO_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ P2P_CLIENT_INFO_DESC_T arClientDesc[1]; /* P2P Client Info Descriptors */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_INFO_T, *P_P2P_ATTRI_GROUP_INFO_T; -+ -+/* P2P 4.1.17 - P2P Group ID Attribute */ -+typedef struct _P2P_ATTRI_GROUP_ID_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; /* SSID */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_ID_T, *P_P2P_ATTRI_GROUP_ID_T; -+ -+/* P2P 4.1.18 - P2P Interface Attribute */ -+typedef struct _P2P_ATTRI_INTERFACE_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+ UINT_8 ucIfAddrCount; /* P2P Interface Address Count */ -+ UINT_8 aucIfAddrList[MAC_ADDR_LEN]; /* P2P Interface Address List */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INTERFACE_T, *P_P2P_ATTRI_INTERFACE_T; -+ -+/* P2P 4.1.19 - Operating Channel Attribute */ -+typedef struct _P2P_ATTRI_OPERATING_CHANNEL_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucCountryString[3]; /* Country String */ -+ UINT_8 ucOperatingClass; /* Operating Class from 802.11 Annex J/P802.11 REVmb 3.0 */ -+ UINT_8 ucChannelNumber; /* Channel Number */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_OPERATING_CHANNEL_T, *P_P2P_ATTRI_OPERATING_CHANNEL_T; -+ -+/* P2P 4.1.20 - Invitation Flags Attribute */ -+typedef struct _P2P_ATTRI_INVITATION_FLAG_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucInviteFlagsBitmap; /* Invitation Flags Bitmap */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INVITATION_FLAG_T, *P_P2P_ATTRI_INVITATION_FLAG_T; -+ -+/* P2P 4.1.1 - General WSC Attribute */ -+typedef struct _WSC_ATTRIBUTE_T { -+ UINT_16 u2Id; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucBody[1]; /* Body field */ -+} __KAL_ATTRIB_PACKED__ WSC_ATTRIBUTE_T, *P_WSC_ATTRIBUTE_T; -+ -+/* WSC 1.0 Table 28 */ -+typedef struct _WSC_ATTRI_VERSION_T { -+ UINT_16 u2Id; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucVersion; /* Version 1.0 or 1.1 */ -+} __KAL_ATTRIB_PACKED__ WSC_ATTRI_VERSION_T, *P_WSC_ATTRI_VERSION_T; -+ -+typedef struct _WSC_ATTRI_DEVICE_PASSWORD_ID_T { -+ UINT_16 u2Id; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_16 u2DevPasswordId; /* Device Password ID */ -+} __KAL_ATTRIB_PACKED__ WSC_ATTRI_DEVICE_PASSWORD_ID_T, *P_WSC_ATTRI_DEVICE_PASSWORD_ID_T; -+ -+typedef struct _WSC_ATTRI_CONFIGURATION_METHOD_T { -+ UINT_16 u2Id; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_16 u2ConfigMethods; /* Configure Methods */ -+} __KAL_ATTRIB_PACKED__ WSC_ATTRI_CONFIGURATION_METHOD_T, *P_WSC_ATTRI_CONFIGURATION_METHOD_T; -+ -+#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) -+#pragma pack() -+#endif -+ -+/* 3 --------------- WFA P2P Attributes Handler prototype --------------- */ -+typedef UINT_32(*PFN_APPEND_ATTRI_FUNC) (P_ADAPTER_T, BOOLEAN, PUINT_16, PUINT_8, UINT_16); -+ -+typedef VOID(*PFN_HANDLE_ATTRI_FUNC) (P_SW_RFB_T, P_P2P_ATTRIBUTE_T); -+ -+typedef VOID(*PFN_VERIFY_ATTRI_FUNC) (P_SW_RFB_T, P_P2P_ATTRIBUTE_T, PUINT_16); -+ -+typedef UINT_32(*PFN_CALCULATE_VAR_ATTRI_LEN_FUNC) (P_ADAPTER_T, P_STA_RECORD_T); -+ -+typedef struct _APPEND_VAR_ATTRI_ENTRY_T { -+ UINT_16 u2EstimatedFixedAttriLen; /* For fixed length */ -+ PFN_CALCULATE_VAR_ATTRI_LEN_FUNC pfnCalculateVariableAttriLen; -+ PFN_APPEND_ATTRI_FUNC pfnAppendAttri; -+} APPEND_VAR_ATTRI_ENTRY_T, *P_APPEND_VAR_ATTRI_ENTRY_T; -+ -+typedef enum _ENUM_CONFIG_METHOD_SEL { -+ ENUM_CONFIG_METHOD_SEL_AUTO, -+ ENUM_CONFIG_METHOD_SEL_USER, -+ ENUM_CONFIG_METHOD_SEL_NUM -+} ENUM_CONFIG_METHOD_SEL, *P_ENUM_CONFIG_METHOD_SEL; -+ -+typedef enum _ENUM_P2P_FORMATION_POLICY { -+ ENUM_P2P_FORMATION_POLICY_AUTO = 0, -+ ENUM_P2P_FORMATION_POLICY_PASSIVE, /* Device would wait GO NEGO REQ instead of sending it actively. */ -+ ENUM_P2P_FORMATION_POLICY_NUM -+} ENUM_P2P_FORMATION_POLICY, P_ENUM_P2P_FORMATION_POLICY; -+ -+typedef enum _ENUM_P2P_INVITATION_POLICY { -+ ENUM_P2P_INVITATION_POLICY_USER = 0, -+ ENUM_P2P_INVITATION_POLICY_ACCEPT_FIRST, -+ ENUM_P2P_INVITATION_POLICY_DENY_ALL, -+ ENUM_P2P_INVITATION_POLICY_NUM -+} ENUM_P2P_INVITATION_POLICY, P_ENUM_P2P_INVITATION_POLICY; -+ -+/* 3 --------------- Data Structure for P2P Operation --------------- */ -+/* 3 Session for CONNECTION SETTINGS of P2P */ -+struct _P2P_CONNECTION_SETTINGS_T { -+ UINT_8 ucDevNameLen; -+ UINT_8 aucDevName[WPS_ATTRI_MAX_LEN_DEVICE_NAME]; -+ -+ DEVICE_TYPE_T rPrimaryDevTypeBE; -+ -+ ENUM_P2P_FORMATION_POLICY eFormationPolicy; /* Formation Policy. */ -+ -+ /*------------WSC Related Param---------------*/ -+ UINT_16 u2ConfigMethodsSupport; /* Preferred configure method. -+ * Some device may not have keypad. -+ */ -+ ENUM_CONFIG_METHOD_SEL eConfigMethodSelType; -+ UINT_16 u2TargetConfigMethod; /* Configure method selected by user or auto. */ -+ UINT_16 u2LocalConfigMethod; /* Configure method of target. */ -+ BOOLEAN fgIsPasswordIDRdy; -+ /*------------WSC Related Param---------------*/ -+ -+ UINT_8 ucClientConfigTimeout; -+ UINT_8 ucGoConfigTimeout; -+ -+ UINT_8 ucSecondaryDevTypeCount; -+#if P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT -+ DEVICE_TYPE_T arSecondaryDevTypeBE[P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT]; -+#endif -+ -+#if 0 -+ UINT_8 ucRfChannelListCount; -+#if P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT -+ UINT_8 aucChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT]; /* Channel Numbering -+ depends on 802.11mb Annex J. */ -+ -+#endif -+#else -+ UINT_8 ucRfChannelListSize; -+#if P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE -+ UINT_8 aucChannelEntriesField[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE]; -+#endif -+#endif -+ -+ /* Go Intent */ -+ UINT_8 ucTieBreaker; -+ UINT_8 ucGoIntent; -+ -+ /* For Device Capability */ -+ BOOLEAN fgSupportServiceDiscovery; -+ BOOLEAN fgSupportClientDiscoverability; -+ BOOLEAN fgSupportConcurrentOperation; -+ BOOLEAN fgSupportInfraManaged; -+ BOOLEAN fgSupportInvitationProcedure; -+ -+ /* For Group Capability */ -+ BOOLEAN fgSupportPersistentP2PGroup; -+ BOOLEAN fgSupportIntraBSSDistribution; -+ BOOLEAN fgSupportCrossConnection; -+ BOOLEAN fgSupportPersistentReconnect; -+ -+ BOOLEAN fgP2pGroupLimit; -+ -+ BOOLEAN fgSupportOppPS; -+ UINT_16 u2CTWindow; -+ -+ BOOLEAN fgIsScanReqIssued; -+ BOOLEAN fgIsServiceDiscoverIssued; -+ -+ /*============ Target Device Connection Settings ============*/ -+ -+ /* Discover Target Device Info. */ -+ BOOLEAN fgIsDevId; -+ BOOLEAN fgIsDevType; -+ -+ /* Encryption mode of Target Device */ -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ -+ /* SSID -+ * 1. AP Mode, this is the desired SSID user specified. -+ * 2. Client Mode, this is the target SSID to be connected to. -+ */ -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+ UINT_8 ucSSIDLen; -+ -+ /* Operating channel requested. */ -+ UINT_8 ucOperatingChnl; -+ ENUM_BAND_T eBand; -+ -+ /* Linten channel requested. */ -+ UINT_8 ucListenChnl; -+ -+ /* For device discover address/type. */ -+ UINT_8 aucTargetDevAddr[MAC_ADDR_LEN]; /* P2P Device Address, for P2P Device Discovery & P2P Connection. */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ P_P2P_DEVICE_DESC_T prTargetP2pDesc; -+#endif -+ -+ UINT_8 ucLastStatus; /* P2P FSM would append status attribute according to this field. */ -+ -+#if !CFG_DISABLE_DELAY_PROVISION_DISCOVERY -+ UINT_8 ucLastDialogToken; -+ UINT_8 aucIndicateDevAddr[MAC_ADDR_LEN]; -+#endif -+ -+#if 0 -+ UINT_8 ucTargetRfChannelListCount; -+#if P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT -+ UINT_8 aucTargetChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT]; /* Channel Numbering -+ depends on 802.11mb Annex J. */ -+#endif -+#endif -+ -+}; -+ -+typedef struct _NOA_TIMING_T { -+ BOOLEAN fgIsInUse; /* Indicate if this entry is in use or not */ -+ UINT_8 ucCount; /* Count */ -+ -+ UINT_8 aucReserved[2]; -+ -+ UINT_32 u4Duration; /* Duration */ -+ UINT_32 u4Interval; /* Interval */ -+ UINT_32 u4StartTime; /* Start Time */ -+} NOA_TIMING_T, *P_NOA_TIMING_T; -+ -+typedef enum _ENUM_P2P_IOCTL_T { -+ P2P_IOCTL_IDLE = 0, -+ P2P_IOCTL_DEV_DISCOVER, -+ P2P_IOCTL_INVITATION_REQ, -+ P2P_IOCTL_SERV_DISCOVER, -+ P2P_IOCTL_WAITING, -+ P2P_IOCTL_NUM -+} ENUM_P2P_IOCTL_T; -+ -+/*---------------- Service Discovery Related -------------------*/ -+typedef enum _ENUM_SERVICE_TX_TYPE_T { -+ ENUM_SERVICE_TX_TYPE_BY_DA, -+ ENUM_SERVICE_TX_TYPE_BY_CHNL, -+ ENUM_SERVICE_TX_TYPE_NUM -+} ENUM_SERVICE_TX_TYPE_T; -+ -+typedef struct _SERVICE_DISCOVERY_FRAME_DATA_T { -+ QUE_ENTRY_T rQueueEntry; -+ P_MSDU_INFO_T prSDFrame; -+ ENUM_SERVICE_TX_TYPE_T eServiceType; -+ UINT_8 ucSeqNum; -+ union { -+ -+ UINT_8 ucChannelNum; -+ UINT_8 aucPeerAddr[MAC_ADDR_LEN]; -+ } uTypeData; -+ BOOLEAN fgIsTxDoneIndicate; -+} SERVICE_DISCOVERY_FRAME_DATA_T, *P_SERVICE_DISCOVERY_FRAME_DATA_T; -+ -+struct _P2P_FSM_INFO_T_DEPRECATED { -+ /* P2P FSM State */ -+ ENUM_P2P_STATE_T eCurrentState; -+ -+ /* Channel */ -+ BOOLEAN fgIsChannelRequested; -+ -+ ENUM_P2P_STATE_T ePreviousState; -+ -+ ENUM_P2P_STATE_T eReturnState; /* Return state after current activity finished or abort. */ -+ -+ UINT_8 aucTargetIfAddr[PARAM_MAC_ADDR_LEN]; -+ P_BSS_DESC_T prTargetBss; /* BSS of target P2P Device. For Connection/Service Discovery */ -+ -+ P_STA_RECORD_T prTargetStaRec; -+ -+ BOOLEAN fgIsRsponseProbe; /* Indicate if P2P FSM can response probe request frame. */ -+ -+ /* Sequence number of requested message. */ -+ UINT_8 ucSeqNumOfReqMsg; /* Used for SAA FSM request message. */ -+ -+ /* Channel Privilege */ -+ UINT_8 ucSeqNumOfChReq; /* Used for Channel Request message. */ -+ -+ UINT_8 ucSeqNumOfScnMsg; /* Used for SCAN FSM request message. */ -+ UINT_8 ucSeqNumOfCancelMsg; -+ -+ UINT_8 ucDialogToken; -+ UINT_8 ucRxDialogToken; -+ -+ /* Timer */ -+ TIMER_T rDeviceDiscoverTimer; /* For device discovery time of each discovery request from user. */ -+ TIMER_T rOperationListenTimer; /* For Find phase under operational state. */ -+ TIMER_T rFSMTimer; /* A timer used for Action frame timeout usage. */ -+ -+ TIMER_T rRejoinTimer; /* A timer used for Action frame timeout usage. */ -+ -+ /* Flag to indicate Provisioning */ -+ BOOLEAN fgIsConnectionRequested; -+ -+ /* Current IOCTL. */ -+ ENUM_P2P_IOCTL_T eP2pIOCTL; -+ -+ UINT_8 ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ -+ -+ /*--------SERVICE DISCOVERY--------*/ -+ QUE_T rQueueGASRx; /* Input Request/Response. */ -+ QUE_T rQueueGASTx; /* Output Response. */ -+ P_SERVICE_DISCOVERY_FRAME_DATA_T prSDRequest; -+ UINT_8 ucVersionNum; /* GAS packet sequence number for...Action Frame? */ -+ UINT_8 ucGlobalSeqNum; /* Sequence Number of RX SD packet. */ -+ /*--------Service DISCOVERY--------*/ -+ -+ /*--------DEVICE DISCOVERY---------*/ -+ UINT_8 aucTargetGroupID[PARAM_MAC_ADDR_LEN]; -+ UINT_16 u2TargetGroupSsidLen; -+ UINT_8 aucTargetSsid[32]; -+ UINT_8 aucSearchingP2pDevice[PARAM_MAC_ADDR_LEN]; -+ UINT_8 ucDLToken; -+ /*----------------------------------*/ -+ -+ /* Indicating Peer Status. */ -+ UINT_32 u4Flags; -+ -+ /*Indicating current running mode. */ -+ BOOLEAN fgIsApMode; -+ -+ /*------------INVITATION------------*/ -+ ENUM_P2P_INVITATION_POLICY eInvitationRspPolicy; -+ /*----------------------------------*/ -+ -+}; -+ -+struct _P2P_SPECIFIC_BSS_INFO_T { -+ /* For GO(AP) Mode - Compose TIM IE */ -+ UINT_16 u2SmallestAID; -+ UINT_16 u2LargestAID; -+ UINT_8 ucBitmapCtrl; -+ /* UINT_8 aucPartialVirtualBitmap[MAX_LEN_TIM_PARTIAL_BMP]; */ -+ -+ /* For GC/GO OppPS */ -+ BOOLEAN fgEnableOppPS; -+ UINT_16 u2CTWindow; -+ -+ /* For GC/GO NOA */ -+ UINT_8 ucNoAIndex; -+ UINT_8 ucNoATimingCount; /* Number of NoA Timing */ -+ NOA_TIMING_T arNoATiming[P2P_MAXIMUM_NOA_COUNT]; -+ -+ BOOLEAN fgIsNoaAttrExisted; -+ -+ /* For P2P Device */ -+ UINT_8 ucRegClass; /* Regulatory Class for channel. */ -+ UINT_8 ucListenChannel; /* Linten Channel only on channels 1, 6 and 11 in the 2.4 GHz. */ -+ -+ UINT_8 ucPreferredChannel; /* Operating Channel, should be one of channel list -+ in p2p connection settings. */ -+ ENUM_CHNL_EXT_T eRfSco; -+ ENUM_BAND_T eRfBand; -+ -+ /* Extended Listen Timing. */ -+ UINT_16 u2AvailabilityPeriod; -+ UINT_16 u2AvailabilityInterval; -+ -+#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ -+ UINT_16 u2IELenForBCN; -+ UINT_8 aucBeaconIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; -+ -+/* UINT_16 u2IELenForProbeRsp; */ -+/* UINT_8 aucProbeRspIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; */ -+ -+ UINT_16 u2IELenForAssocRsp; -+ UINT_8 aucAssocRspIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; -+ -+#else -+ UINT_16 u2AttributeLen; -+ UINT_8 aucAttributesCache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; -+ -+ UINT_16 u2WscAttributeLen; -+ UINT_8 aucWscAttributesCache[WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; -+#endif -+ UINT_8 aucGroupID[MAC_ADDR_LEN]; -+ UINT_16 u2GroupSsidLen; -+ UINT_8 aucGroupSsid[ELEM_MAX_LEN_SSID]; -+ -+ PARAM_CUSTOM_NOA_PARAM_STRUCT_T rNoaParam; -+ PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T rOppPsParam; -+ -+ UINT_16 u2WpaIeLen; -+ UINT_8 aucWpaIeBuffer[ELEM_HDR_LEN + ELEM_MAX_LEN_WPA]; -+}; -+ -+typedef struct _MSG_P2P_DEVICE_DISCOVER_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_32 u4DevDiscoverTime; /* 0: Infinite, 1~X: in unit of MS. */ -+ BOOLEAN fgIsSpecificType; -+#if CFG_ENABLE_WIFI_DIRECT -+ P2P_DEVICE_TYPE_T rTargetDeviceType; -+#endif -+ UINT_8 aucTargetDeviceID[MAC_ADDR_LEN]; -+} MSG_P2P_DEVICE_DISCOVER_T, *P_MSG_P2P_DEVICE_DISCOVER_T; -+ -+typedef struct _MSG_P2P_INVITATION_REQUEST_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 aucDeviceID[MAC_ADDR_LEN]; /* Target Device ID to be invited. */ -+} MSG_P2P_INVITATION_REQUEST_T, *P_MSG_P2P_INVITATION_REQUEST_T; -+ -+typedef struct _MSG_P2P_FUNCTION_SWITCH_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ BOOLEAN fgIsFuncOn; -+} MSG_P2P_FUNCTION_SWITCH_T, *P_MSG_P2P_FUNCTION_SWITCH_T; -+ -+typedef struct _MSG_P2P_SERVICE_DISCOVERY_REQUEST_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 aucDeviceID[MAC_ADDR_LEN]; -+ BOOLEAN fgNeedTxDoneIndicate; -+ UINT_8 ucSeqNum; -+} MSG_P2P_SERVICE_DISCOVERY_REQUEST_T, *P_MSG_P2P_SERVICE_DISCOVERY_REQUEST_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define p2pChangeMediaState(_prAdapter, _eNewMediaState) \ -+do { \ -+ (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState = (_eNewMediaState));\ -+ wfdChangeMediaState((_prAdapter), NETWORK_TYPE_P2P_INDEX, (_eNewMediaState)); \ -+} while (0) -+ -+#define ATTRI_ID(_fp) (((P_P2P_ATTRIBUTE_T) _fp)->ucId) -+#define ATTRI_LEN(_fp) \ -+ (((UINT_16) ((PUINT_8)&((P_P2P_ATTRIBUTE_T) _fp)->u2Length)[0]) | \ -+ ((UINT_16) ((PUINT_8)&((P_P2P_ATTRIBUTE_T) _fp)->u2Length)[1] << 8)) -+ -+#define ATTRI_SIZE(_fp) (P2P_ATTRI_HDR_LEN + ATTRI_LEN(_fp)) -+ -+#define P2P_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ -+ for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ -+ (_u2Offset) += ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += ATTRI_SIZE(_pucAttriBuf))) -+ -+#define P2P_IE(_fp) ((P_IE_P2P_T) _fp) -+ -+#define WSC_ATTRI_ID(_fp) \ -+ (((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Id)[0] << 8) | \ -+ ((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Id)[1])) -+ -+#define WSC_ATTRI_LEN(_fp) \ -+ (((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Length)[0] << 8) | \ -+ ((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Length)[1])) -+ -+#define WSC_ATTRI_SIZE(_fp) (WSC_ATTRI_HDR_LEN + WSC_ATTRI_LEN(_fp)) -+ -+#define WSC_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ -+ for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ -+ (_u2Offset) += WSC_ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += WSC_ATTRI_SIZE(_pucAttriBuf))) -+ -+#define WSC_IE(_fp) ((P_IE_P2P_T) _fp) -+ -+#define WFD_ATTRI_ID(_fp) (((P_WFD_ATTRIBUTE_T) _fp)->ucElemID) -+ -+#define WFD_ATTRI_LEN(_fp) \ -+ (((UINT_16) ((PUINT_8)&((P_WFD_ATTRIBUTE_T) _fp)->u2Length)[0] << 8) | \ -+ ((UINT_16) ((PUINT_8)&((P_WFD_ATTRIBUTE_T) _fp)->u2Length)[1])) -+ -+#define WFD_ATTRI_SIZE(_fp) (WFD_ATTRI_HDR_LEN + WFD_ATTRI_LEN(_fp)) -+ -+#define WFD_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ -+ for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ -+ (_u2Offset) += WFD_ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += WFD_ATTRI_SIZE(_pucAttriBuf))) -+ -+#if DBG -+#define ASSERT_BREAK(_exp) \ -+ { \ -+ if (!(_exp)) { \ -+ ASSERT(FALSE); \ -+ break; \ -+ } \ -+ } -+ -+#else -+#define ASSERT_BREAK(_exp) -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/*======P2P State======*/ -+VOID -+p2pStateInit_LISTEN(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_P2P_SPECIFIC_BSS_INFO_T prSP2pBssInfo, IN UINT_8 ucListenChannel); -+ -+VOID p2pStateAbort_LISTEN(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtenstion); -+ -+VOID p2pStateAbort_SEARCH_SCAN(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtenstion); -+ -+VOID p2pStateAbort_GO_OPERATION(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pStateAbort_GC_OPERATION(IN P_ADAPTER_T prAdapter); -+ -+VOID -+p2pStateInit_CONFIGURATION(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecBssInfo); -+ -+VOID p2pStateAbort_CONFIGURATION(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pStateInit_JOIN(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pStateAbort_JOIN(IN P_ADAPTER_T prAdapter); -+ -+/*====== P2P Functions ======*/ -+ -+VOID p2pFuncInitGO(IN P_ADAPTER_T prAdapter); -+ -+VOID -+p2pFuncDisconnect(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode); -+ -+VOID -+p2pFuncSwitchOPMode(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_OP_MODE_T eOpMode, IN BOOLEAN fgSyncToFW); -+ -+VOID p2pFuncRunEventProvisioningComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+WLAN_STATUS p2pFuncSetGroupID(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucGroupID, IN PUINT_8 pucSsid, IN UINT_8 ucSsidLen); -+ -+WLAN_STATUS -+p2pFuncSendDeviceDiscoverabilityReqFrame(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDestAddr[], IN UINT_8 ucDialogToken); -+ -+WLAN_STATUS -+p2pFuncSendDeviceDiscoverabilityRspFrame(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDestAddr[], IN UINT_8 ucDialogToken); -+ -+UINT_8 p2pFuncGetVersionNumOfSD(IN P_ADAPTER_T prAdapter); -+ -+/*====== P2P FSM ======*/ -+VOID p2pFsmRunEventConnectionRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventDeviceDiscoveryRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventDeviceDiscoveryAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventRxGroupNegotiationReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS -+p2pFsmRunEventGroupNegotiationRequestTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+WLAN_STATUS -+p2pFsmRunEventGroupNegotiationResponseTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+WLAN_STATUS -+p2pFsmRunEventGroupNegotiationConfirmTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+WLAN_STATUS -+p2pFsmRunEventProvisionDiscoveryRequestTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+WLAN_STATUS -+p2pFsmRunEventProvisionDiscoveryResponseTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+WLAN_STATUS -+p2pFsmRunEventInvitationRequestTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID p2pFsmRunEventRxDeauthentication(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); -+ -+VOID p2pFsmRunEventRxDisassociation(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); -+ -+VOID p2pFsmRunEventBeaconTimeout(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS -+p2pFsmRunEventDeauthTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+#if 1 -+#endif -+ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/*======Mail Box Event Message=====*/ -+ -+VOID p2pFsmRunEventConnectionAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventConnectionTrigger(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventP2PFunctionSwitch(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventConnectionPause(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID -+p2pIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, -+ IN ENUM_PARAM_MEDIA_STATE_T eConnectionState, IN UINT_8 aucTargetAddr[]); -+ -+VOID p2pUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb); -+ -+/*======Mail Box Event Message=====*/ -+ -+VOID p2pFsmInit(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pFsmUninit(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID p2pStartGO(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 pucSsidLen); -+ -+VOID p2pFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventIOReqTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param); -+ -+VOID p2pFsmRunEventSearchPeriodTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param); -+ -+VOID p2pFsmRunEventFsmTimeout(IN P_ADAPTER_T prAdapter, IN ULONG u4Param); -+ -+VOID p2pFsmRunEventRejoinTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Parm); -+ -+/*=============== P2P Function Related ================*/ -+ -+/*=============== P2P Function Related ================*/ -+ -+#if CFG_TEST_WIFI_DIRECT_GO -+VOID p2pTest(IN P_ADAPTER_T prAdapter); -+#endif /* CFG_TEST_WIFI_DIRECT_GO */ -+ -+VOID p2pGenerateP2P_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID p2pGenerateP2P_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID p2pGenerateP2P_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID -+p2pGenerateP2P_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pCalculateP2P_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pCalculateP2P_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pCalculateP2P_IELenForProbeReq(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pGenerateWSC_IEForProbeResp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID -+p2pGenerateWSC_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_16 p2pCalculateWSC_IELenForProbeReq(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+UINT_32 -+p2pCalculateWSC_IELenForProbeResp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pAppendAttriStatus(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriCapability(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriGoIntent(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriCfgTimeout(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriGroupBssid(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriDeviceIDForBeacon(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriDeviceIDForProbeReq(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriDeviceIDForDeviceDiscoveryReq(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriListenChannel(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriIntendP2pIfAddr(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriChannelList(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 p2pCalculateAttriLenChannelList(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pAppendAttriNoA(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriDeviceInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 p2pCalculateAttriLenDeviceInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pAppendAttriGroupInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 p2pCalculateAttriLenGroupInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pAppendAttriP2pGroupID(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriOperatingChannel(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriInvitationFlag(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+VOID -+p2pGenerateWscIE(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, -+ IN PUINT_8 pucBuf, -+ IN UINT_16 u2BufSize, IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize); -+ -+UINT_32 -+p2pAppendAttriWSCConfigMethod(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriWSCVersion(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriWSCGONegReqDevPasswordId(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriWSCGONegRspDevPasswordId(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+WLAN_STATUS -+p2pGetWscAttriList(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, -+ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen); -+ -+WLAN_STATUS -+p2pGetAttriList(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, -+ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen); -+ -+VOID p2pRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS p2pRunEventAAASuccess(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS p2pRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS p2pSendProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+BOOLEAN p2pFsmRunEventRxProbeRequestFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID p2pFsmRunEventRxProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_BSS_DESC_T prBssDesc); -+ -+WLAN_STATUS p2pRxPublicActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS p2pRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID p2pFsmRunEventRxGroupNegotiationRspFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID p2pFsmRunEventRxGroupNegotiationCfmFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+#if 0 /* frog */ -+BOOLEAN scanMatchFilterOfP2P(IN P_SW_RFB_T prSWRfb, IN PP_BSS_DESC_T pprBssDesc); -+#endif /* frog */ -+ -+VOID -+p2pProcessEvent_UpdateNOAParam(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucNetTypeIndex, P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam); -+ -+VOID p2pFuncCompleteIOCTL(IN P_ADAPTER_T prAdapter, IN WLAN_STATUS rWlanStatus); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#ifndef _lint -+/* Kevin: we don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ * We'll need this for porting driver to different RTOS. -+ */ -+static inline VOID p2pDataTypeCheck(VOID) -+{ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(IE_P2P_T) == (2 + 4 + 1)); /* all UINT_8 */ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRIBUTE_T) == (3 + 1)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_STATUS_T) == (3 + 1)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_REASON_T) == (3 + 1)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CAPABILITY_T) == (3 + 2)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_DEV_ID_T) == (3 + 6)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GO_INTENT_T) == (3 + 1)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CFG_TIMEOUT_T) == (3 + 2)); -+#if CID52_53_54 -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_LISTEN_CHANNEL_T) == (3 + 5)); -+#else -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_LISTEN_CHANNEL_T) == (3 + 5)); -+#endif -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_BSSID_T) == (3 + 6)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_EXT_LISTEN_TIMING_T) == (3 + 4)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_INTENDED_IF_ADDR_T) == (3 + 6)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_MANAGEABILITY_T) == (3 + 1)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CHANNEL_T) == (3 + 4)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(CHANNEL_ENTRY_FIELD_T) == 3); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_NOA_T) == (3 + 3)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(NOA_DESCRIPTOR_T) == 13); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(DEVICE_TYPE_T) == 8); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_DEV_INFO_T) == (3 + 6 + 2 + 8 + 1 + 8)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(DEVICE_NAME_TLV_T) == (4 + 32)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_CLIENT_INFO_DESC_T) == (1 + 6 + 6 + 1 + 2 + 8 + 1 + 8)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_INFO_T) == (3 + (1 + 6 + 6 + 1 + 2 + 8 + 1 + 8))); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_ID_T) == (3 + 38)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_INTERFACE_T) == (3 + 13)); -+#if CID52_53_54 -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_OPERATING_CHANNEL_T) == (3 + 5)); -+#else -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_OPERATING_CHANNEL_T) == (3 + 5)); -+#endif -+ -+} -+#endif /* _lint */ -+ -+#endif /* _P2P_FSM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h -new file mode 100644 -index 0000000000000..1ac1770debcab ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h -@@ -0,0 +1,155 @@ -+#ifndef _P2P_FUNC_H -+#define _P2P_FUNC_H -+ -+#define P2P_EXT_LISTEN_TIME_MS 600 -+#define P2P_OFF_CHNL_TX_DEFAULT_TIME_MS 1000 -+ -+VOID p2pFuncRequestScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo); -+ -+VOID p2pFuncCancelScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo); -+ -+VOID -+p2pFuncStartGO(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prBssInfo, -+ IN PUINT_8 pucSsidBuf, -+ IN UINT_8 ucSsidLen, -+ IN UINT_8 ucChannelNum, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN BOOLEAN fgIsPureAP); -+ -+VOID p2pFuncAcquireCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo); -+ -+VOID p2pFuncReleaseCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo); -+ -+VOID p2pFuncSetChannel(IN P_ADAPTER_T prAdapter, IN P_RF_CHANNEL_INFO_T prRfChannelInfo); -+ -+BOOLEAN p2pFuncRetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_P2P_JOIN_INFO_T prJoinInfo); -+ -+VOID -+p2pFuncUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_DESC_T prBssDesc, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb); -+ -+WLAN_STATUS -+p2pFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie); -+ -+WLAN_STATUS -+p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, -+ IN P_P2P_BEACON_UPDATE_INFO_T prBcnUpdateInfo, -+ IN PUINT_8 pucNewBcnHdr, IN UINT_32 u4NewHdrLen, IN PUINT_8 pucNewBcnBody, IN UINT_32 u4NewBodyLen); -+ -+BOOLEAN -+p2pFuncValidateAuth(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode); -+ -+BOOLEAN p2pFuncValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); -+ -+VOID p2pFuncResetStaRecStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncInitConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings); -+ -+BOOLEAN p2pFuncParseCheckForP2PInfoElem(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType); -+ -+BOOLEAN p2pFuncValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); -+ -+VOID p2pFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+BOOLEAN p2pFuncIsAPMode(IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+VOID -+p2pFuncParseBeaconContent(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN PUINT_8 pucIEInfo, IN UINT_32 u4IELen); -+ -+P_BSS_DESC_T -+p2pFuncKeepOnConnection(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo, -+ IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo); -+ -+VOID p2pFuncStoreAssocRspIEBuffer(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID -+p2pFuncMgmtFrameRegister(IN P_ADAPTER_T prAdapter, -+ IN UINT_16 u2FrameType, IN BOOLEAN fgIsRegistered, OUT PUINT_32 pu4P2pPacketFilter); -+ -+VOID p2pFuncUpdateMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN UINT_32 u4OsFilter); -+ -+VOID p2pFuncGetStationInfo(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucMacAddr, OUT P_P2P_STATION_INFO_T prStaInfo); -+ -+BOOLEAN -+p2pFuncGetAttriList(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, -+ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen); -+ -+P_MSDU_INFO_T p2pFuncProcessP2pProbeRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMgmtTxMsdu); -+ -+#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ -+UINT_32 -+p2pFuncCalculateExtra_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateExtra_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+#else -+UINT_32 -+p2pFuncCalculateP2p_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateP2p_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+p2pFuncCalculateWSC_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateWSC_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+#endif -+UINT_32 -+p2pFuncCalculateP2p_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateP2p_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+p2pFuncCalculateWSC_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateWSC_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+p2pFuncCalculateP2P_IELen(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN P_STA_RECORD_T prStaRec, -+ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize); -+ -+VOID -+p2pFuncGenerateP2P_IE(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, -+ IN PUINT_8 pucBuf, -+ IN UINT_16 u2BufSize, -+ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize); -+ -+UINT_32 -+p2pFuncAppendAttriStatusForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pFuncAppendAttriExtListenTiming(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+VOID -+p2pFuncDissolve(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode); -+ -+P_IE_HDR_T -+p2pFuncGetSpecIE(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_8 ucElemID, IN PBOOLEAN pfgIsMore); -+ -+P_ATTRIBUTE_HDR_T -+p2pFuncGetSpecAttri(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_16 u2AttriID); -+ -+WLAN_STATUS wfdChangeMediaState(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx, -+ IN ENUM_PARAM_MEDIA_STATE_T eConnectionState); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h -new file mode 100644 -index 0000000000000..efb75855695f9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h -@@ -0,0 +1,156 @@ -+#ifndef _P2P_IE_H -+#define _P2P_IE_H -+ -+#if CFG_SUPPORT_WFD -+ -+#define ELEM_MAX_LEN_WFD 62 /* TODO: Move to appropriate place */ -+ -+/*---------------- WFD Data Element Definitions ----------------*/ -+/* WFD 4.1.1 - WFD IE format */ -+#define WFD_OUI_TYPE_LEN 4 -+#define WFD_IE_OUI_HDR (ELEM_HDR_LEN + WFD_OUI_TYPE_LEN) /* == OFFSET_OF(IE_P2P_T, -+ aucP2PAttributes[0]) */ -+ -+/* WFD 4.1.1 - General WFD Attribute */ -+#define WFD_ATTRI_HDR_LEN 3 /* ID(1 octet) + Length(2 octets) */ -+ -+/* WFD Attribute Code */ -+#define WFD_ATTRI_ID_DEV_INFO 0 -+#define WFD_ATTRI_ID_ASSOC_BSSID 1 -+#define WFD_ATTRI_ID_COUPLED_SINK_INFO 6 -+#define WFD_ATTRI_ID_EXT_CAPABILITY 7 -+#define WFD_ATTRI_ID_SESSION_INFO 9 -+#define WFD_ATTRI_ID_ALTER_MAC_ADDRESS 10 -+ -+/* Maximum Length of WFD Attributes */ -+#define WFD_ATTRI_MAX_LEN_DEV_INFO 6 /* 0 */ -+#define WFD_ATTRI_MAX_LEN_ASSOC_BSSID 6 /* 1 */ -+#define WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO 7 /* 6 */ -+#define WFD_ATTRI_MAX_LEN_EXT_CAPABILITY 2 /* 7 */ -+#define WFD_ATTRI_MAX_LEN_SESSION_INFO 0 /* 9 */ /* 24 * #Clients */ -+#define WFD_ATTRI_MAX_LEN_ALTER_MAC_ADDRESS 6 /* 10 */ -+ -+/* WFD 1.10 5.1.1 */ -+typedef struct _IE_WFD_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 aucWFDAttributes[1]; /* WFD Subelement */ -+} __KAL_ATTRIB_PACKED__ IE_WFD_T, *P_IE_WFD_T; -+ -+typedef struct _WFD_ATTRIBUTE_T { -+ UINT_8 ucElemID; /* Subelement ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucBody[1]; /* Body field */ -+} __KAL_ATTRIB_PACKED__ WFD_ATTRIBUTE_T, *P_WFD_ATTRIBUTE_T; -+ -+typedef struct _WFD_DEVICE_INFORMATION_IE_T { -+ UINT_8 ucElemID; -+ UINT_16 u2Length; -+ UINT_16 u2WfdDevInfo; -+ UINT_16 u2SessionMgmtCtrlPort; -+ UINT_16 u2WfdDevMaxSpeed; -+} __KAL_ATTRIB_PACKED__ WFD_DEVICE_INFORMATION_IE_T, *P_WFD_DEVICE_INFORMATION_IE_T; -+ -+typedef struct _WFD_ASSOCIATED_BSSID_IE_T { -+ UINT_8 ucElemID; -+ UINT_16 u2Length; -+ UINT_8 aucAssocBssid[MAC_ADDR_LEN]; -+} __KAL_ATTRIB_PACKED__ WFD_ASSOCIATED_BSSID_IE_T, *P_WFD_ASSOCIATED_BSSID_IE_T; -+ -+typedef struct _WFD_COUPLE_SINK_INFORMATION_IE_T { -+ UINT_8 ucElemID; -+ UINT_16 u2Length; -+ UINT_8 ucCoupleSinkStatusBp; -+ UINT_8 aucCoupleSinkMac[MAC_ADDR_LEN]; -+} __KAL_ATTRIB_PACKED__ WFD_COUPLE_SINK_INFORMATION_IE_T, *P_WFD_COUPLE_SINK_INFORMATION_IE_T; -+ -+typedef struct _WFD_EXTENDED_CAPABILITY_IE_T { -+ UINT_8 ucElemID; -+ UINT_16 u2Length; -+ UINT_16 u2WfdExtCapabilityBp; -+} __KAL_ATTRIB_PACKED__ WFD_EXTENDED_CAPABILITY_IE_T, *P_WFD_EXTENDED_CAPABILITY_IE_T; -+ -+typedef struct _WFD_SESSION_INFORMATION_IE_T { -+ UINT_8 ucElemID; -+ UINT_16 u2Length; -+ PUINT_8 pucWfdDevInfoDesc[1]; -+} __KAL_ATTRIB_PACKED__ WFD_SESSION_INFORMATION_IE_T, *P_WFD_SESSION_INFORMATION_IE_T; -+ -+typedef struct _WFD_DEVICE_INFORMATION_DESCRIPTOR_T { -+ UINT_8 ucLength; -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; -+ UINT_8 aucAssocBssid[MAC_ADDR_LEN]; -+ UINT_16 u2WfdDevInfo; -+ UINT_16 u2WfdDevMaxSpeed; -+ UINT_8 ucCoupleSinkStatusBp; -+ UINT_8 aucCoupleSinkMac[MAC_ADDR_LEN]; -+} __KAL_ATTRIB_PACKED__ WFD_DEVICE_INFORMATION_DESCRIPTOR_T, *P_WFD_DEVICE_INFORMATION_DESCRIPTOR_T; -+ -+#endif -+ -+UINT_32 -+p2pCalculate_IEForAssocReq(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pGenerate_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+#if CFG_SUPPORT_WFD -+ -+UINT_32 -+wfdFuncAppendAttriDevInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+wfdFuncAppendAttriAssocBssid(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+wfdFuncAppendAttriCoupledSinkInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+wfdFuncAppendAttriExtCapability(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 wfdFuncCalculateAttriLenSessionInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+wfdFuncAppendAttriSessionInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+wfdFuncCalculateWfdIELenForProbeResp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID wfdFuncGenerateWfdIEForProbeResp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+wfdFuncCalculateWfdIELenForAssocReq(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID wfdFuncGenerateWfdIEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+wfdFuncCalculateWfdIELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID wfdFuncGenerateWfdIEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+wfdFuncCalculateWfdIELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID wfdFuncGenerateWfdIEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+#endif -+ -+UINT_32 p2pFuncCalculateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN UINT_32 ucBssIdx, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h -new file mode 100644 -index 0000000000000..32bc14c109591 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h -@@ -0,0 +1,74 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_rlm.h#1 -+*/ -+ -+/*! \file "rlm.h" -+ \brief -+*/ -+ -+#ifndef _P2P_RLM_H -+#define _P2P_RLM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID rlmBssInitForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+BOOLEAN rlmUpdateBwByChListForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+VOID rlmUpdateParamsForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon); -+ -+VOID rlmFuncInitialChannelList(IN P_ADAPTER_T prAdapter); -+ -+VOID -+rlmFuncCommonChannelList(IN P_ADAPTER_T prAdapter, -+ IN P_CHANNEL_ENTRY_FIELD_T prChannelEntryII, IN UINT_8 ucChannelListSize); -+ -+UINT_8 rlmFuncFindOperatingClass(IN P_ADAPTER_T prAdapter, IN UINT_8 ucChannelNum); -+ -+BOOLEAN -+rlmFuncFindAvailableChannel(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucCheckChnl, -+ IN PUINT_8 pucSuggestChannel, IN BOOLEAN fgIsSocialChannel, IN BOOLEAN fgIsDefaultChannel); -+ -+ENUM_CHNL_EXT_T rlmDecideScoForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h -new file mode 100644 -index 0000000000000..5b6e756f48dd4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h -@@ -0,0 +1,64 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_rlm_obss.h#1 -+*/ -+ -+/*! \file "rlm_obss.h" -+ \brief -+*/ -+ -+#ifndef _P2P_RLM_OBSS_H -+#define _P2P_RLM_OBSS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID rlmRspGenerateObssScanIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmProcessPublicAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+ -+VOID rlmProcessHtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+ -+VOID rlmHandleObssStatusEventPkt(P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus); -+ -+UINT_8 rlmObssChnlLevel(P_BSS_INFO_T prBssInfo, ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); -+ -+VOID rlmObssScanExemptionRsp(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h -new file mode 100644 -index 0000000000000..8db6aa5c31e0c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h -@@ -0,0 +1,81 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_scan.h#1 -+*/ -+ -+/*! \file "scan.h" -+ \brief -+ -+*/ -+ -+#ifndef _P2P_SCAN_H -+#define _P2P_SCAN_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+WLAN_STATUS scanSendDeviceDiscoverEvent(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb); -+ -+P_P2P_DEVICE_DESC_T -+scanSearchTargetP2pDesc(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDeviceID[], IN PP_BSS_DESC_T pprBssDesc); -+ -+P_P2P_DEVICE_DESC_T -+scanFindP2pDeviceDesc(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_DESC_T prBssDesc, -+ IN UINT_8 aucMacAddr[], IN BOOLEAN fgIsDeviceAddr, IN BOOLEAN fgAddIfNoFound); -+ -+P_P2P_DEVICE_DESC_T scanGetP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+VOID scnEventReturnChannel(IN P_ADAPTER_T prAdapter, IN UINT_8 ucScnSeqNum); -+ -+BOOLEAN scanUpdateP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+VOID -+scanP2pProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, -+ IN P_WLAN_STATUS prStatus, -+ IN P_BSS_DESC_T prBssDesc, IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame); -+ -+VOID scanRemoveAllP2pBssDesc(P_ADAPTER_T prAdapter); -+ -+VOID scanRemoveP2pBssDesc(P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); -+ -+P_BSS_DESC_T -+scanP2pSearchDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h -new file mode 100644 -index 0000000000000..8f0c4c1564a85 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h -@@ -0,0 +1,43 @@ -+#ifndef _P2P_STATE_H -+#define _P2P_STATE_H -+ -+BOOLEAN -+p2pStateInit_IDLE(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_BSS_INFO_T prP2pBssInfo, OUT P_ENUM_P2P_STATE_T peNextState); -+ -+VOID p2pStateAbort_IDLE(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID p2pStateInit_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+VOID p2pStateAbort_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID p2pStateInit_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+VOID -+p2pStateAbort_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID -+p2pStateInit_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+VOID -+p2pStateAbort_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID -+p2pStateAbort_REQING_CHANNEL(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID -+p2pStateInit_GC_JOIN(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN P_BSS_DESC_T prBssDesc); -+ -+VOID -+p2pStateAbort_GC_JOIN(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_P2P_JOIN_INFO_T prJoinInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h -new file mode 100644 -index 0000000000000..c80430ae4eb54 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h -@@ -0,0 +1,230 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/privacy.h#1 -+*/ -+ -+/*! \file privacy.h -+ \brief This file contains the function declaration for privacy.c. -+*/ -+ -+/* -+** Log: privacy.h -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Refine the variable and parameter for security. -+ * -+ * 02 25 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * For support the WHQL test, do the remove key code refine. -+ * -+ * Dec 10 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * change the cmd return type -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the function declaration for auth mode and encryption status setting from build connection command -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the function declaration for wapi -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the tx done callback handle function -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the function declaration for mac header privacy bit setting -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the structure for parsing the EAPoL frame -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the class error function parameter -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some security function declaration -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the ap selection structure -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** -+*/ -+ -+#ifndef _PRIVACY_H -+#define _PRIVACY_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define MAX_KEY_NUM 4 -+#define WEP_40_LEN 5 -+#define WEP_104_LEN 13 -+#define LEGACY_KEY_MAX_LEN 16 -+#define CCMP_KEY_LEN 16 -+#define TKIP_KEY_LEN 32 -+#define MAX_KEY_LEN 32 -+#define MIC_RX_KEY_OFFSET 16 -+#define MIC_TX_KEY_OFFSET 24 -+#define MIC_KEY_LEN 8 -+ -+#define WEP_KEY_ID_FIELD BITS(0, 29) -+#define KEY_ID_FIELD BITS(0, 7) -+ -+#define IS_TRANSMIT_KEY BIT(31) -+#define IS_UNICAST_KEY BIT(30) -+#define IS_AUTHENTICATOR BIT(28) -+ -+#define CIPHER_SUITE_NONE 0 -+#define CIPHER_SUITE_WEP40 1 -+#define CIPHER_SUITE_TKIP 2 -+#define CIPHER_SUITE_TKIP_WO_MIC 3 -+#define CIPHER_SUITE_CCMP 4 -+#define CIPHER_SUITE_WEP104 5 -+#define CIPHER_SUITE_BIP 6 -+#define CIPHER_SUITE_WEP128 7 -+#define CIPHER_SUITE_WPI 8 -+ -+#define WPA_KEY_INFO_KEY_TYPE BIT(3) /* 1 = Pairwise, 0 = Group key */ -+#define WPA_KEY_INFO_MIC BIT(8) -+#define WPA_KEY_INFO_SECURE BIT(9) -+ -+#define MASK_2ND_EAPOL (WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef struct _IEEE_802_1X_HDR { -+ UINT_8 ucVersion; -+ UINT_8 ucType; -+ UINT_16 u2Length; -+ /* followed by length octets of data */ -+} IEEE_802_1X_HDR, *P_IEEE_802_1X_HDR; -+ -+typedef struct _EAPOL_KEY { -+ UINT_8 ucType; -+ /* Note: key_info, key_length, and key_data_length are unaligned */ -+ UINT_8 aucKeyInfo[2]; /* big endian */ -+ UINT_8 aucKeyLength[2]; /* big endian */ -+ UINT_8 aucReplayCounter[8]; -+ UINT_8 aucKeyNonce[16]; -+ UINT_8 aucKeyIv[16]; -+ UINT_8 aucKeyRsc[8]; -+ UINT_8 aucKeyId[8]; /* Reserved in IEEE 802.11i/RSN */ -+ UINT_8 aucKeyMic[16]; -+ UINT_8 aucKeyDataLength[2]; /* big endian */ -+ /* followed by key_data_length bytes of key_data */ -+} EAPOL_KEY, *P_EAPOL_KEY; -+ -+/* WPA2 PMKID candicate structure */ -+typedef struct _PMKID_CANDICATE_T { -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ UINT_32 u4PreAuthFlags; -+} PMKID_CANDICATE_T, *P_PMKID_CANDICATE_T; -+ -+#if 0 -+/* WPA2 PMKID cache structure */ -+typedef struct _PMKID_ENTRY_T { -+ PARAM_BSSID_INFO_T rBssidInfo; -+ BOOLEAN fgPmkidExist; -+} PMKID_ENTRY_T, *P_PMKID_ENTRY_T; -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID secInit(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIdx); -+ -+VOID secSetPortBlocked(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgPort); -+ -+BOOLEAN secCheckClassError(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_STA_RECORD_T prStaRec); -+ -+BOOLEAN secTxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec); -+ -+BOOLEAN secRxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb); -+ -+VOID secSetCipherSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4CipherSuitesFlags); -+ -+BOOLEAN -+secProcessEAPOL(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, -+ IN P_STA_RECORD_T prStaRec, IN PUINT_8 pucPayload, IN UINT_16 u2PayloadLen); -+ -+VOID -+secHandleTxDoneCallback(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T pMsduInfo, IN P_STA_RECORD_T prStaRec, IN WLAN_STATUS rStatus); -+ -+BOOLEAN secIsProtectedFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsdu, IN P_STA_RECORD_T prStaRec); -+ -+VOID secClearPmkid(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN secRsnKeyHandshakeEnabled(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN secTransmitKeyExist(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+BOOLEAN secEnabledInAis(IN P_ADAPTER_T prAdapter); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _PRIVACY_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h -new file mode 100644 -index 0000000000000..123dbebdacaf2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h -@@ -0,0 +1,93 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rate.h#1 -+*/ -+ -+/*! \file rate.h -+ \brief This file contains the rate utility function of -+ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: rate.h -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+*/ -+ -+#ifndef _RATE_H -+#define _RATE_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in rate.c */ -+/*----------------------------------------------------------------------------*/ -+VOID -+rateGetRateSetFromIEs(IN P_IE_SUPPORTED_RATE_T prIeSupportedRate, -+ IN P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate, -+ OUT PUINT_16 pu2OperationalRateSet, -+ OUT PUINT_16 pu2BSSBasicRateSet, OUT PBOOLEAN pfgIsUnknownBSSBasicRate); -+ -+VOID -+rateGetDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet, -+ IN UINT_16 u2BSSBasicRateSet, OUT PUINT_8 pucDataRates, OUT PUINT_8 pucDataRatesLen); -+ -+BOOLEAN rateGetHighestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucHighestRateIndex); -+ -+BOOLEAN rateGetLowestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucLowestRateIndex); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RATE_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h -new file mode 100644 -index 0000000000000..1af3841ecec25 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h -@@ -0,0 +1,396 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm.h#2 -+*/ -+ -+/*! \file "rlm.h" -+ \brief -+*/ -+ -+/* -+** Log: rlm.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 09 30 2011 cm.chang -+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band -+ * . -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 01 13 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Refine function when rcv a 20/40M public action frame -+ * -+ * 01 13 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * Use SCO of BSS_INFO to replace user-defined setting variables -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 10 18 2010 cm.chang -+ * [WCXRP00000114] [MT6620 Wi-Fi] [Driver] Fix compiling warning in Linux about RLM network index checking -+ * Enum member cannot be used as compiling option decision in Linux -+ * -+ * 09 10 2010 cm.chang -+ * NULL -+ * Always update Beacon content if FW sync OBSS info -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 06 02 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add RX HT GF compiling option -+ * -+ * 06 02 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Roll back to remove CFG_SUPPORT_BCM_TEST. -+ * -+ * 06 01 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Update BCM Test and RW configuration. -+ * -+ * 05 31 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add some compiling options to control 11n functions -+ * -+ * 05 18 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Ad-hoc Beacon should not carry HT OP and OBSS IEs -+ * -+ * 05 17 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * MT6620 does not support L-SIG TXOP -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft support for 20/40M bandwidth for AP mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Different invoking order for WTBL entry of associated AP -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Not carry HT cap when being associated with b/g only AP -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Move default value of HT capability to rlm.h -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 01 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+ * -+ * 01 08 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * -+ * Modify the prototype of rlmRecAssocRspHtInfo() -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add several function prototypes for HT operation -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+** -+*/ -+ -+#ifndef _RLM_H -+#define _RLM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define ELEM_EXT_CAP_DEFAULT_VAL \ -+ (ELEM_EXT_CAP_20_40_COEXIST_SUPPORT /*| ELEM_EXT_CAP_PSMP_CAP*/) -+ -+#if CFG_SUPPORT_RX_STBC -+#define FIELD_HT_CAP_INFO_RX_STBC HT_CAP_INFO_RX_STBC_1_SS -+#else -+#define FIELD_HT_CAP_INFO_RX_STBC HT_CAP_INFO_RX_STBC_NO_SUPPORTED -+#endif -+ -+#if CFG_SUPPORT_RX_SGI -+#define FIELD_HT_CAP_INFO_SGI_20M HT_CAP_INFO_SHORT_GI_20M -+#define FIELD_HT_CAP_INFO_SGI_40M HT_CAP_INFO_SHORT_GI_40M -+#else -+#define FIELD_HT_CAP_INFO_SGI_20M 0 -+#define FIELD_HT_CAP_INFO_SGI_40M 0 -+#endif -+ -+#if CFG_SUPPORT_RX_HT_GF -+#define FIELD_HT_CAP_INFO_HT_GF HT_CAP_INFO_HT_GF -+#else -+#define FIELD_HT_CAP_INFO_HT_GF 0 -+#endif -+ -+#define HT_CAP_INFO_DEFAULT_VAL \ -+ (HT_CAP_INFO_SUP_CHNL_WIDTH | FIELD_HT_CAP_INFO_HT_GF | \ -+ FIELD_HT_CAP_INFO_SGI_20M | FIELD_HT_CAP_INFO_SGI_40M | \ -+ FIELD_HT_CAP_INFO_RX_STBC | HT_CAP_INFO_DSSS_CCK_IN_40M) -+ -+#define AMPDU_PARAM_DEFAULT_VAL \ -+ (AMPDU_PARAM_MAX_AMPDU_LEN_64K | AMPDU_PARAM_MSS_NO_RESTRICIT) -+ -+#define SUP_MCS_TX_DEFAULT_VAL \ -+ SUP_MCS_TX_SET_DEFINED /* TX defined and TX/RX equal (TBD) */ -+ -+#if CFG_SUPPORT_MFB -+#define FIELD_HT_EXT_CAP_MFB HT_EXT_CAP_MCS_FEEDBACK_BOTH -+#else -+#define FIELD_HT_EXT_CAP_MFB HT_EXT_CAP_MCS_FEEDBACK_NO_FB -+#endif -+ -+#if CFG_SUPPORT_RX_RDG -+#define FIELD_HT_EXT_CAP_RDR HT_EXT_CAP_RD_RESPONDER -+#else -+#define FIELD_HT_EXT_CAP_RDR 0 -+#endif -+ -+#if CFG_SUPPORT_MFB || CFG_SUPPORT_RX_RDG -+#define FIELD_HT_EXT_CAP_HTC HT_EXT_CAP_HTC_SUPPORT -+#else -+#define FIELD_HT_EXT_CAP_HTC 0 -+#endif -+ -+#define HT_EXT_CAP_DEFAULT_VAL \ -+ (HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE | \ -+ FIELD_HT_EXT_CAP_MFB | FIELD_HT_EXT_CAP_HTC | \ -+ FIELD_HT_EXT_CAP_RDR) -+ -+#define TX_BEAMFORMING_CAP_DEFAULT_VAL 0 -+#define ASEL_CAP_DEFAULT_VAL 0 -+ -+/* Define bandwidth from user setting */ -+#define CONFIG_BW_20_40M 0 -+#define CONFIG_BW_20M 1 /* 20MHz only */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/* It is used for RLM module to judge if specific network is valid -+ * Note: Ad-hoc mode of AIS is not included now. (TBD) -+ */ -+#define RLM_NET_PARAM_VALID(_prBssInfo) \ -+ (IS_BSS_ACTIVE(_prBssInfo) && \ -+ ((_prBssInfo)->eConnectionState == PARAM_MEDIA_STATE_CONNECTED || \ -+ (_prBssInfo)->eCurrentOPMode == OP_MODE_ACCESS_POINT || \ -+ (_prBssInfo)->eCurrentOPMode == OP_MODE_IBSS || \ -+ RLM_NET_IS_BOW(_prBssInfo)) \ -+ ) -+ -+#define RLM_NET_IS_11N(_prBssInfo) \ -+ ((_prBssInfo)->ucPhyTypeSet & PHY_TYPE_SET_802_11N) -+#define RLM_NET_IS_11GN(_prBssInfo) \ -+ ((_prBssInfo)->ucPhyTypeSet & PHY_TYPE_SET_802_11GN) -+ -+/* This macro is used to sweep all 3 networks */ -+#define RLM_NET_FOR_EACH(_ucNetIdx) \ -+ for ((_ucNetIdx) = 0; \ -+ (_ucNetIdx) < NETWORK_TYPE_INDEX_NUM; \ -+ (_ucNetIdx)++) -+ -+/* This macro is used to sweep all networks excluding BOW */ -+#if CFG_ENABLE_BT_OVER_WIFI -+ /* Note: value of enum NETWORK_TYPE_BOW_INDEX is validated in -+ * rlmStuctureCheck(). -+ */ -+#define RLM_NET_FOR_EACH_NO_BOW(_ucNetIdx) \ -+ for ((_ucNetIdx) = 0; \ -+ (_ucNetIdx) < NETWORK_TYPE_BOW_INDEX; \ -+ (_ucNetIdx)++) -+ -+#define RLM_NET_IS_BOW(_prBssInfo) \ -+ ((_prBssInfo)->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) -+ -+#else -+#define RLM_NET_FOR_EACH_NO_BOW(_ucNetIdx) RLM_NET_FOR_EACH(_ucNetIdx) -+#define RLM_NET_IS_BOW(_prBssInfo) (FALSE) -+ -+#endif /* end of CFG_ENABLE_BT_OVER_WIFI */ -+ -+/* The bandwidth modes are not used anymore. They represent if AP -+ * can use 20/40 bandwidth, not all modes. (20110411) -+ */ -+#define RLM_AP_IS_BW_40_ALLOWED(_prAdapter, _prBssInfo) \ -+ (((_prBssInfo)->eBand == BAND_2G4 && \ -+ (_prAdapter)->rWifiVar.rConnSettings.uc2G4BandwidthMode \ -+ == CONFIG_BW_20_40M) || \ -+ ((_prBssInfo)->eBand == BAND_5G && \ -+ (_prAdapter)->rWifiVar.rConnSettings.uc5GBandwidthMode \ -+ == CONFIG_BW_20_40M)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID rlmFsmEventInit(P_ADAPTER_T prAdapter); -+ -+VOID rlmFsmEventUninit(P_ADAPTER_T prAdapter); -+ -+VOID rlmReqGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmReqGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmRspGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmRspGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmRspGenerateHtOpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmRspGenerateErpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmProcessBcn(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+VOID rlmProcessAssocRsp(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+VOID rlmFillSyncCmdParam(P_CMD_SET_BSS_RLM_PARAM_T prCmdBody, P_BSS_INFO_T prBssInfo); -+ -+VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+VOID rlmBssInitForAPandIbss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+VOID rlmProcessAssocReq(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+VOID rlmBssAborted(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+UINT32 -+rlmFillHtCapIEByParams(BOOLEAN fg40mAllowed, -+ BOOLEAN fgShortGIDisabled, -+ UINT_8 u8SupportRxSgi20, -+ UINT_8 u8SupportRxSgi40, -+ UINT_8 u8SupportRxGf, UINT_8 u8SupportRxSTBC, ENUM_OP_MODE_T eCurrentOPMode, UINT_8 *pOutBuf); -+ -+UINT32 rlmFillHtOpIeBody(P_BSS_INFO_T prBssInfo, UINT_8 *pFme); -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+VOID rlmProcessSpecMgtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+ -+VOID rlmProcessChannelSwitchIE(P_ADAPTER_T prAdapter, P_IE_CHANNEL_SWITCH_T prChannelSwitchIE); -+#endif -+ -+VOID -+rlmTxRateEnhanceConfig( -+ P_ADAPTER_T prAdapter -+ ); -+ -+VOID -+rlmCmd( -+ P_GLUE_INFO_T prGlueInfo, -+ UINT_8 *prInBuf, -+ UINT_32 u4InBufLen -+ ); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#ifndef _lint -+static inline VOID rlmDataTypeCheck(VOID) -+{ -+#if CFG_ENABLE_BT_OVER_WIFI -+ DATA_STRUCT_INSPECTING_ASSERT(NETWORK_TYPE_AIS_INDEX < NETWORK_TYPE_BOW_INDEX); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ DATA_STRUCT_INSPECTING_ASSERT(NETWORK_TYPE_P2P_INDEX < NETWORK_TYPE_BOW_INDEX); -+#endif -+#endif -+ -+} -+#endif /* _lint */ -+ -+#endif /* _RLM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h -new file mode 100644 -index 0000000000000..65e907041a28b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h -@@ -0,0 +1,557 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_domain.h#1 -+*/ -+ -+/*! \file "rlm_domain.h" -+ \brief -+*/ -+ -+/* -+** Log: rlm_domain.h -+ * -+ * 09 29 2011 cm.chang -+ * NULL -+ * Change the function prototype of rlmDomainGetChnlList() -+ * -+ * 09 08 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 06 01 2011 cm.chang -+ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function -+ * Provide legal channel function based on domain -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb -+ * -+ * 01 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Provide query function about full channel list. -+ * -+ * Dec 1 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Declare public rDomainInfo -+ * -+** -+*/ -+ -+#ifndef _RLM_DOMAIN_H -+#define _RLM_DOMAIN_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define MAX_SUBBAND_NUM 6 -+#define MAX_SUBBAND_NUM_5G 8 -+ -+#define COUNTRY_CODE_NULL ((UINT_16)0x0) -+ -+/* ISO/IEC 3166-1 two-character country codes */ -+ -+#define COUNTRY_CODE_AD (((UINT_16) 'A' << 8) | (UINT_16) 'D') /* Andorra */ -+#define COUNTRY_CODE_AE (((UINT_16) 'A' << 8) | (UINT_16) 'E') /* UAE */ -+#define COUNTRY_CODE_AF (((UINT_16) 'A' << 8) | (UINT_16) 'F') /* Afghanistan */ -+#define COUNTRY_CODE_AG (((UINT_16) 'A' << 8) | (UINT_16) 'G') /* Antigua & Barbuda */ -+#define COUNTRY_CODE_AI (((UINT_16) 'A' << 8) | (UINT_16) 'I') /* Anguilla */ -+#define COUNTRY_CODE_AL (((UINT_16) 'A' << 8) | (UINT_16) 'L') /* Albania */ -+#define COUNTRY_CODE_AM (((UINT_16) 'A' << 8) | (UINT_16) 'M') /* Armenia */ -+#define COUNTRY_CODE_AN (((UINT_16) 'A' << 8) | (UINT_16) 'N') /* Netherlands Antilles */ -+#define COUNTRY_CODE_AO (((UINT_16) 'A' << 8) | (UINT_16) 'O') /* Angola */ -+#define COUNTRY_CODE_AR (((UINT_16) 'A' << 8) | (UINT_16) 'R') /* Argentina */ -+#define COUNTRY_CODE_AS (((UINT_16) 'A' << 8) | (UINT_16) 'S') /* American Samoa (USA) */ -+#define COUNTRY_CODE_AT (((UINT_16) 'A' << 8) | (UINT_16) 'T') /* Austria */ -+#define COUNTRY_CODE_AU (((UINT_16) 'A' << 8) | (UINT_16) 'U') /* Australia */ -+#define COUNTRY_CODE_AW (((UINT_16) 'A' << 8) | (UINT_16) 'W') /* Aruba */ -+#define COUNTRY_CODE_AZ (((UINT_16) 'A' << 8) | (UINT_16) 'Z') /* Azerbaijan */ -+#define COUNTRY_CODE_BA (((UINT_16) 'B' << 8) | (UINT_16) 'A') /* Bosnia and Herzegovina */ -+#define COUNTRY_CODE_BB (((UINT_16) 'B' << 8) | (UINT_16) 'B') /* Barbados */ -+#define COUNTRY_CODE_BD (((UINT_16) 'B' << 8) | (UINT_16) 'D') /* Bangladesh */ -+#define COUNTRY_CODE_BE (((UINT_16) 'B' << 8) | (UINT_16) 'E') /* Belgium */ -+#define COUNTRY_CODE_BF (((UINT_16) 'B' << 8) | (UINT_16) 'F') /* Burkina Faso */ -+#define COUNTRY_CODE_BG (((UINT_16) 'B' << 8) | (UINT_16) 'G') /* Bulgaria */ -+#define COUNTRY_CODE_BH (((UINT_16) 'B' << 8) | (UINT_16) 'H') /* Bahrain */ -+#define COUNTRY_CODE_BI (((UINT_16) 'B' << 8) | (UINT_16) 'I') /* Burundi */ -+#define COUNTRY_CODE_BJ (((UINT_16) 'B' << 8) | (UINT_16) 'J') /* Benin */ -+#define COUNTRY_CODE_BM (((UINT_16) 'B' << 8) | (UINT_16) 'M') /* Bermuda */ -+#define COUNTRY_CODE_BN (((UINT_16) 'B' << 8) | (UINT_16) 'N') /* Brunei */ -+#define COUNTRY_CODE_BO (((UINT_16) 'B' << 8) | (UINT_16) 'O') /* Bolivia */ -+#define COUNTRY_CODE_BR (((UINT_16) 'B' << 8) | (UINT_16) 'R') /* Brazil */ -+#define COUNTRY_CODE_BS (((UINT_16) 'B' << 8) | (UINT_16) 'S') /* Bahamas */ -+#define COUNTRY_CODE_BT (((UINT_16) 'B' << 8) | (UINT_16) 'T') /* Bhutan */ -+#define COUNTRY_CODE_BW (((UINT_16) 'B' << 8) | (UINT_16) 'W') /* Botswana */ -+#define COUNTRY_CODE_BY (((UINT_16) 'B' << 8) | (UINT_16) 'Y') /* Belarus */ -+#define COUNTRY_CODE_BZ (((UINT_16) 'B' << 8) | (UINT_16) 'Z') /* Belize */ -+#define COUNTRY_CODE_CA (((UINT_16) 'C' << 8) | (UINT_16) 'A') /* Canada */ -+#define COUNTRY_CODE_CD (((UINT_16) 'C' << 8) | (UINT_16) 'D') /* Congo. Democratic Republic of the */ -+#define COUNTRY_CODE_CF (((UINT_16) 'C' << 8) | (UINT_16) 'F') /* Central African Republic */ -+#define COUNTRY_CODE_CG (((UINT_16) 'C' << 8) | (UINT_16) 'G') /* Congo. Republic of the */ -+#define COUNTRY_CODE_CH (((UINT_16) 'C' << 8) | (UINT_16) 'H') /* Switzerland */ -+#define COUNTRY_CODE_CI (((UINT_16) 'C' << 8) | (UINT_16) 'I') /* Cote d'lvoire */ -+#define COUNTRY_CODE_CK (((UINT_16) 'C' << 8) | (UINT_16) 'K') /* Cook Island */ -+#define COUNTRY_CODE_CL (((UINT_16) 'C' << 8) | (UINT_16) 'L') /* Chile */ -+#define COUNTRY_CODE_CM (((UINT_16) 'C' << 8) | (UINT_16) 'M') /* Cameroon */ -+#define COUNTRY_CODE_CN (((UINT_16) 'C' << 8) | (UINT_16) 'N') /* China */ -+#define COUNTRY_CODE_CO (((UINT_16) 'C' << 8) | (UINT_16) 'O') /* Columbia */ -+#define COUNTRY_CODE_CR (((UINT_16) 'C' << 8) | (UINT_16) 'R') /* Costa Rica */ -+#define COUNTRY_CODE_CU (((UINT_16) 'C' << 8) | (UINT_16) 'U') /* Cuba */ -+#define COUNTRY_CODE_CV (((UINT_16) 'C' << 8) | (UINT_16) 'V') /* Cape Verde */ -+#define COUNTRY_CODE_CX (((UINT_16) 'C' << 8) | (UINT_16) 'X') /* "Christmas Island(Australia) */ -+#define COUNTRY_CODE_CY (((UINT_16) 'C' << 8) | (UINT_16) 'Y') /* Cyprus */ -+#define COUNTRY_CODE_CZ (((UINT_16) 'C' << 8) | (UINT_16) 'Z') /* Czech */ -+#define COUNTRY_CODE_DE (((UINT_16) 'D' << 8) | (UINT_16) 'E') /* Germany */ -+#define COUNTRY_CODE_DJ (((UINT_16) 'D' << 8) | (UINT_16) 'J') /* Djibouti */ -+#define COUNTRY_CODE_DK (((UINT_16) 'D' << 8) | (UINT_16) 'K') /* Denmark */ -+#define COUNTRY_CODE_DM (((UINT_16) 'D' << 8) | (UINT_16) 'M') /* Dominica */ -+#define COUNTRY_CODE_DO (((UINT_16) 'D' << 8) | (UINT_16) 'O') /* Dominican Republic */ -+#define COUNTRY_CODE_DZ (((UINT_16) 'D' << 8) | (UINT_16) 'Z') /* Algeria */ -+#define COUNTRY_CODE_EC (((UINT_16) 'E' << 8) | (UINT_16) 'C') /* Ecuador */ -+#define COUNTRY_CODE_EE (((UINT_16) 'E' << 8) | (UINT_16) 'E') /* Estonia */ -+#define COUNTRY_CODE_EG (((UINT_16) 'E' << 8) | (UINT_16) 'G') /* Egypt */ -+#define COUNTRY_CODE_EH (((UINT_16) 'E' << 8) | (UINT_16) 'H') /* Western Sahara (Morocco) */ -+#define COUNTRY_CODE_ER (((UINT_16) 'E' << 8) | (UINT_16) 'R') /* Eritrea */ -+#define COUNTRY_CODE_ES (((UINT_16) 'E' << 8) | (UINT_16) 'S') /* Spain */ -+#define COUNTRY_CODE_ET (((UINT_16) 'E' << 8) | (UINT_16) 'T') /* Ethiopia */ -+#define COUNTRY_CODE_EU (((UINT_16) 'E' << 8) | (UINT_16) 'U') /* Europe */ -+#define COUNTRY_CODE_FI (((UINT_16) 'F' << 8) | (UINT_16) 'I') /* Finland */ -+#define COUNTRY_CODE_FJ (((UINT_16) 'F' << 8) | (UINT_16) 'J') /* Fiji */ -+#define COUNTRY_CODE_FK (((UINT_16) 'F' << 8) | (UINT_16) 'K') /* Falkland Island */ -+#define COUNTRY_CODE_FM (((UINT_16) 'F' << 8) | (UINT_16) 'M') /* Micronesia */ -+#define COUNTRY_CODE_FO (((UINT_16) 'F' << 8) | (UINT_16) 'O') /* Faroe Island */ -+#define COUNTRY_CODE_FR (((UINT_16) 'F' << 8) | (UINT_16) 'R') /* France */ -+#define COUNTRY_CODE_FR (((UINT_16) 'F' << 8) | (UINT_16) 'R') /* Wallis and Futuna (France) */ -+#define COUNTRY_CODE_GA (((UINT_16) 'G' << 8) | (UINT_16) 'A') /* Gabon */ -+#define COUNTRY_CODE_GB (((UINT_16) 'G' << 8) | (UINT_16) 'B') /* United Kingdom */ -+#define COUNTRY_CODE_GD (((UINT_16) 'G' << 8) | (UINT_16) 'D') /* Grenada */ -+#define COUNTRY_CODE_GE (((UINT_16) 'G' << 8) | (UINT_16) 'E') /* Georgia */ -+#define COUNTRY_CODE_GF (((UINT_16) 'G' << 8) | (UINT_16) 'F') /* French Guiana */ -+#define COUNTRY_CODE_GG (((UINT_16) 'G' << 8) | (UINT_16) 'G') /* Guernsey */ -+#define COUNTRY_CODE_GH (((UINT_16) 'G' << 8) | (UINT_16) 'H') /* Ghana */ -+#define COUNTRY_CODE_GI (((UINT_16) 'G' << 8) | (UINT_16) 'I') /* Gibraltar */ -+#define COUNTRY_CODE_GM (((UINT_16) 'G' << 8) | (UINT_16) 'M') /* Gambia */ -+#define COUNTRY_CODE_GN (((UINT_16) 'G' << 8) | (UINT_16) 'N') /* Guinea */ -+#define COUNTRY_CODE_GP (((UINT_16) 'G' << 8) | (UINT_16) 'P') /* Guadeloupe */ -+#define COUNTRY_CODE_GQ (((UINT_16) 'G' << 8) | (UINT_16) 'Q') /* Equatorial Guinea */ -+#define COUNTRY_CODE_GR (((UINT_16) 'G' << 8) | (UINT_16) 'R') /* Greece */ -+#define COUNTRY_CODE_GT (((UINT_16) 'G' << 8) | (UINT_16) 'T') /* Guatemala */ -+#define COUNTRY_CODE_GU (((UINT_16) 'G' << 8) | (UINT_16) 'U') /* Guam */ -+#define COUNTRY_CODE_GW (((UINT_16) 'G' << 8) | (UINT_16) 'W') /* Guinea-Bissau */ -+#define COUNTRY_CODE_GY (((UINT_16) 'G' << 8) | (UINT_16) 'Y') /* Guyana */ -+#define COUNTRY_CODE_HK (((UINT_16) 'H' << 8) | (UINT_16) 'K') /* Hong Kong */ -+#define COUNTRY_CODE_HN (((UINT_16) 'H' << 8) | (UINT_16) 'N') /* Honduras */ -+#define COUNTRY_CODE_HR (((UINT_16) 'H' << 8) | (UINT_16) 'R') /* Croatia */ -+#define COUNTRY_CODE_HT (((UINT_16) 'H' << 8) | (UINT_16) 'T') /* Haiti */ -+#define COUNTRY_CODE_HU (((UINT_16) 'H' << 8) | (UINT_16) 'U') /* Hungary */ -+#define COUNTRY_CODE_ID (((UINT_16) 'I' << 8) | (UINT_16) 'D') /* Indonesia */ -+#define COUNTRY_CODE_IE (((UINT_16) 'I' << 8) | (UINT_16) 'E') /* Ireland */ -+#define COUNTRY_CODE_IL (((UINT_16) 'I' << 8) | (UINT_16) 'L') /* Israel */ -+#define COUNTRY_CODE_IM (((UINT_16) 'I' << 8) | (UINT_16) 'M') /* Isle of Man */ -+#define COUNTRY_CODE_IN (((UINT_16) 'I' << 8) | (UINT_16) 'N') /* India */ -+#define COUNTRY_CODE_IQ (((UINT_16) 'I' << 8) | (UINT_16) 'Q') /* Iraq */ -+#define COUNTRY_CODE_IR (((UINT_16) 'I' << 8) | (UINT_16) 'R') /* Iran */ -+#define COUNTRY_CODE_IS (((UINT_16) 'I' << 8) | (UINT_16) 'S') /* Iceland */ -+#define COUNTRY_CODE_IT (((UINT_16) 'I' << 8) | (UINT_16) 'T') /* Italy */ -+#define COUNTRY_CODE_JE (((UINT_16) 'J' << 8) | (UINT_16) 'E') /* Jersey */ -+#define COUNTRY_CODE_JM (((UINT_16) 'J' << 8) | (UINT_16) 'M') /* Jameica */ -+#define COUNTRY_CODE_JO (((UINT_16) 'J' << 8) | (UINT_16) 'O') /* Jordan */ -+#define COUNTRY_CODE_JP (((UINT_16) 'J' << 8) | (UINT_16) 'P') /* Japan */ -+#define COUNTRY_CODE_KE (((UINT_16) 'K' << 8) | (UINT_16) 'E') /* Kenya */ -+#define COUNTRY_CODE_KG (((UINT_16) 'K' << 8) | (UINT_16) 'G') /* Kyrgyzstan */ -+#define COUNTRY_CODE_KH (((UINT_16) 'K' << 8) | (UINT_16) 'H') /* Cambodia */ -+#define COUNTRY_CODE_KI (((UINT_16) 'K' << 8) | (UINT_16) 'I') /* Kiribati */ -+#define COUNTRY_CODE_KM (((UINT_16) 'K' << 8) | (UINT_16) 'M') /* Comoros */ -+#define COUNTRY_CODE_KN (((UINT_16) 'K' << 8) | (UINT_16) 'N') /* Saint Kitts and Nevis */ -+#define COUNTRY_CODE_KP (((UINT_16) 'K' << 8) | (UINT_16) 'P') /* North Korea */ -+#define COUNTRY_CODE_KR (((UINT_16) 'K' << 8) | (UINT_16) 'R') /* South Korea */ -+#define COUNTRY_CODE_KW (((UINT_16) 'K' << 8) | (UINT_16) 'W') /* Kuwait */ -+#define COUNTRY_CODE_KY (((UINT_16) 'K' << 8) | (UINT_16) 'Y') /* Cayman Islands */ -+#define COUNTRY_CODE_KZ (((UINT_16) 'K' << 8) | (UINT_16) 'Z') /* Kazakhstan */ -+#define COUNTRY_CODE_LA (((UINT_16) 'L' << 8) | (UINT_16) 'A') /* Laos */ -+#define COUNTRY_CODE_LB (((UINT_16) 'L' << 8) | (UINT_16) 'B') /* Lebanon */ -+#define COUNTRY_CODE_LC (((UINT_16) 'L' << 8) | (UINT_16) 'C') /* Saint Lucia */ -+#define COUNTRY_CODE_LI (((UINT_16) 'L' << 8) | (UINT_16) 'I') /* Liechtenstein */ -+#define COUNTRY_CODE_LK (((UINT_16) 'L' << 8) | (UINT_16) 'K') /* Sri Lanka */ -+#define COUNTRY_CODE_LR (((UINT_16) 'L' << 8) | (UINT_16) 'R') /* Liberia */ -+#define COUNTRY_CODE_LS (((UINT_16) 'L' << 8) | (UINT_16) 'S') /* Lesotho */ -+#define COUNTRY_CODE_LT (((UINT_16) 'L' << 8) | (UINT_16) 'T') /* Lithuania */ -+#define COUNTRY_CODE_LU (((UINT_16) 'L' << 8) | (UINT_16) 'U') /* Luxemburg */ -+#define COUNTRY_CODE_LV (((UINT_16) 'L' << 8) | (UINT_16) 'V') /* Latvia */ -+#define COUNTRY_CODE_LY (((UINT_16) 'L' << 8) | (UINT_16) 'Y') /* Libya */ -+#define COUNTRY_CODE_MA (((UINT_16) 'M' << 8) | (UINT_16) 'A') /* Morocco */ -+#define COUNTRY_CODE_MC (((UINT_16) 'M' << 8) | (UINT_16) 'C') /* Monaco */ -+#define COUNTRY_CODE_MD (((UINT_16) 'M' << 8) | (UINT_16) 'D') /* Moldova */ -+#define COUNTRY_CODE_ME (((UINT_16) 'M' << 8) | (UINT_16) 'E') /* Montenegro */ -+#define COUNTRY_CODE_MF (((UINT_16) 'M' << 8) | (UINT_16) 'F') /* Saint Martin / Sint Marteen -+ (Added on window's list) */ -+#define COUNTRY_CODE_MG (((UINT_16) 'M' << 8) | (UINT_16) 'G') /* Madagascar */ -+#define COUNTRY_CODE_MH (((UINT_16) 'M' << 8) | (UINT_16) 'H') /* Marshall Islands */ -+#define COUNTRY_CODE_MK (((UINT_16) 'M' << 8) | (UINT_16) 'K') /* Macedonia */ -+#define COUNTRY_CODE_ML (((UINT_16) 'M' << 8) | (UINT_16) 'L') /* Mali */ -+#define COUNTRY_CODE_MM (((UINT_16) 'M' << 8) | (UINT_16) 'M') /* Myanmar */ -+#define COUNTRY_CODE_MN (((UINT_16) 'M' << 8) | (UINT_16) 'N') /* Mongolia */ -+#define COUNTRY_CODE_MO (((UINT_16) 'M' << 8) | (UINT_16) 'O') /* Macao */ -+#define COUNTRY_CODE_MP (((UINT_16) 'M' << 8) | (UINT_16) 'P') /* Northern Mariana Islands (Rota Island. -+ Saipan and Tinian Island) */ -+#define COUNTRY_CODE_MQ (((UINT_16) 'M' << 8) | (UINT_16) 'Q') /* Martinique (France) */ -+#define COUNTRY_CODE_MR (((UINT_16) 'M' << 8) | (UINT_16) 'R') /* Mauritania */ -+#define COUNTRY_CODE_MS (((UINT_16) 'M' << 8) | (UINT_16) 'S') /* Montserrat (UK) */ -+#define COUNTRY_CODE_MT (((UINT_16) 'M' << 8) | (UINT_16) 'T') /* Malta */ -+#define COUNTRY_CODE_MU (((UINT_16) 'M' << 8) | (UINT_16) 'U') /* Mauritius */ -+#define COUNTRY_CODE_MV (((UINT_16) 'M' << 8) | (UINT_16) 'V') /* Maldives */ -+#define COUNTRY_CODE_MW (((UINT_16) 'M' << 8) | (UINT_16) 'W') /* Malawi */ -+#define COUNTRY_CODE_MX (((UINT_16) 'M' << 8) | (UINT_16) 'X') /* Mexico */ -+#define COUNTRY_CODE_MY (((UINT_16) 'M' << 8) | (UINT_16) 'Y') /* Malaysia */ -+#define COUNTRY_CODE_MZ (((UINT_16) 'M' << 8) | (UINT_16) 'Z') /* Mozambique */ -+#define COUNTRY_CODE_NA (((UINT_16) 'N' << 8) | (UINT_16) 'A') /* Namibia */ -+#define COUNTRY_CODE_NC (((UINT_16) 'N' << 8) | (UINT_16) 'C') /* New Caledonia */ -+#define COUNTRY_CODE_NE (((UINT_16) 'N' << 8) | (UINT_16) 'E') /* Niger */ -+#define COUNTRY_CODE_NF (((UINT_16) 'N' << 8) | (UINT_16) 'F') /* Norfolk Island */ -+#define COUNTRY_CODE_NG (((UINT_16) 'N' << 8) | (UINT_16) 'G') /* Nigeria */ -+#define COUNTRY_CODE_NI (((UINT_16) 'N' << 8) | (UINT_16) 'I') /* Nicaragua */ -+#define COUNTRY_CODE_NL (((UINT_16) 'N' << 8) | (UINT_16) 'L') /* Netherlands */ -+#define COUNTRY_CODE_NO (((UINT_16) 'N' << 8) | (UINT_16) 'O') /* Norway */ -+#define COUNTRY_CODE_NP (((UINT_16) 'N' << 8) | (UINT_16) 'P') /* Nepal */ -+#define COUNTRY_CODE_NR (((UINT_16) 'N' << 8) | (UINT_16) 'R') /* Nauru */ -+#define COUNTRY_CODE_NU (((UINT_16) 'N' << 8) | (UINT_16) 'U') /* Niue */ -+#define COUNTRY_CODE_NZ (((UINT_16) 'N' << 8) | (UINT_16) 'Z') /* New Zealand */ -+#define COUNTRY_CODE_OM (((UINT_16) 'O' << 8) | (UINT_16) 'M') /* Oman */ -+#define COUNTRY_CODE_PA (((UINT_16) 'P' << 8) | (UINT_16) 'A') /* Panama */ -+#define COUNTRY_CODE_PE (((UINT_16) 'P' << 8) | (UINT_16) 'E') /* Peru */ -+#define COUNTRY_CODE_PF (((UINT_16) 'P' << 8) | (UINT_16) 'F') /* "French Polynesia */ -+#define COUNTRY_CODE_PG (((UINT_16) 'P' << 8) | (UINT_16) 'G') /* Papua New Guinea */ -+#define COUNTRY_CODE_PH (((UINT_16) 'P' << 8) | (UINT_16) 'H') /* Philippines */ -+#define COUNTRY_CODE_PK (((UINT_16) 'P' << 8) | (UINT_16) 'K') /* Pakistan */ -+#define COUNTRY_CODE_PL (((UINT_16) 'P' << 8) | (UINT_16) 'L') /* Poland */ -+#define COUNTRY_CODE_PM (((UINT_16) 'P' << 8) | (UINT_16) 'M') /* Saint Pierre and Miquelon */ -+#define COUNTRY_CODE_PN (((UINT_16) 'P' << 8) | (UINT_16) 'N') /* Pitcairn Islands */ -+#define COUNTRY_CODE_PR (((UINT_16) 'P' << 8) | (UINT_16) 'R') /* Puerto Rico (USA) */ -+#define COUNTRY_CODE_PS (((UINT_16) 'P' << 8) | (UINT_16) 'S') /* Palestinian Authority */ -+#define COUNTRY_CODE_PT (((UINT_16) 'P' << 8) | (UINT_16) 'T') /* Portugal */ -+#define COUNTRY_CODE_PW (((UINT_16) 'P' << 8) | (UINT_16) 'W') /* Palau */ -+#define COUNTRY_CODE_PY (((UINT_16) 'P' << 8) | (UINT_16) 'Y') /* Paraguay */ -+#define COUNTRY_CODE_QA (((UINT_16) 'Q' << 8) | (UINT_16) 'A') /* Qatar */ -+#define COUNTRY_CODE_RE (((UINT_16) 'R' << 8) | (UINT_16) 'E') /* Reunion (France) */ -+#define COUNTRY_CODE_RKS (((UINT_16) 'R' << 8) | (UINT_16) 'K') /* Kosvo (Added on window's list) */ -+#define COUNTRY_CODE_RO (((UINT_16) 'R' << 8) | (UINT_16) 'O') /* Romania */ -+#define COUNTRY_CODE_RS (((UINT_16) 'R' << 8) | (UINT_16) 'S') /* Serbia */ -+#define COUNTRY_CODE_RU (((UINT_16) 'R' << 8) | (UINT_16) 'U') /* Russia */ -+#define COUNTRY_CODE_RW (((UINT_16) 'R' << 8) | (UINT_16) 'W') /* Rwanda */ -+#define COUNTRY_CODE_SA (((UINT_16) 'S' << 8) | (UINT_16) 'A') /* Saudi Arabia */ -+#define COUNTRY_CODE_SB (((UINT_16) 'S' << 8) | (UINT_16) 'B') /* Solomon Islands */ -+#define COUNTRY_CODE_SC (((UINT_16) 'S' << 8) | (UINT_16) 'C') /* Seychelles */ -+#define COUNTRY_CODE_SD (((UINT_16) 'S' << 8) | (UINT_16) 'D') /* Sudan */ -+#define COUNTRY_CODE_SE (((UINT_16) 'S' << 8) | (UINT_16) 'E') /* Sweden */ -+#define COUNTRY_CODE_SG (((UINT_16) 'S' << 8) | (UINT_16) 'G') /* Singapole */ -+#define COUNTRY_CODE_SI (((UINT_16) 'S' << 8) | (UINT_16) 'I') /* Slovenia */ -+#define COUNTRY_CODE_SK (((UINT_16) 'S' << 8) | (UINT_16) 'K') /* Slovakia */ -+#define COUNTRY_CODE_SL (((UINT_16) 'S' << 8) | (UINT_16) 'L') /* Sierra Leone */ -+#define COUNTRY_CODE_SM (((UINT_16) 'S' << 8) | (UINT_16) 'M') /* San Marino */ -+#define COUNTRY_CODE_SN (((UINT_16) 'S' << 8) | (UINT_16) 'N') /* Senegal */ -+#define COUNTRY_CODE_SO (((UINT_16) 'S' << 8) | (UINT_16) 'O') /* Somalia */ -+#define COUNTRY_CODE_SR (((UINT_16) 'S' << 8) | (UINT_16) 'R') /* Suriname */ -+#define COUNTRY_CODE_SS (((UINT_16) 'S' << 8) | (UINT_16) 'S') /* South_Sudan */ -+#define COUNTRY_CODE_ST (((UINT_16) 'S' << 8) | (UINT_16) 'T') /* Sao Tome and Principe */ -+#define COUNTRY_CODE_SV (((UINT_16) 'S' << 8) | (UINT_16) 'V') /* El Salvador */ -+#define COUNTRY_CODE_SY (((UINT_16) 'S' << 8) | (UINT_16) 'Y') /* Syria */ -+#define COUNTRY_CODE_SZ (((UINT_16) 'S' << 8) | (UINT_16) 'Z') /* Swaziland */ -+#define COUNTRY_CODE_TC (((UINT_16) 'T' << 8) | (UINT_16) 'C') /* Turks and Caicos Islands (UK) */ -+#define COUNTRY_CODE_TD (((UINT_16) 'T' << 8) | (UINT_16) 'D') /* Chad */ -+#define COUNTRY_CODE_TF (((UINT_16) 'T' << 8) | (UINT_16) 'F') /* French Southern and Antarctic Lands */ -+#define COUNTRY_CODE_TG (((UINT_16) 'T' << 8) | (UINT_16) 'G') /* Togo */ -+#define COUNTRY_CODE_TH (((UINT_16) 'T' << 8) | (UINT_16) 'H') /* Thailand */ -+#define COUNTRY_CODE_TJ (((UINT_16) 'T' << 8) | (UINT_16) 'J') /* Tajikistan */ -+#define COUNTRY_CODE_TL (((UINT_16) 'T' << 8) | (UINT_16) 'L') /* East Timor */ -+#define COUNTRY_CODE_TM (((UINT_16) 'T' << 8) | (UINT_16) 'M') /* Turkmenistan */ -+#define COUNTRY_CODE_TN (((UINT_16) 'T' << 8) | (UINT_16) 'N') /* Tunisia */ -+#define COUNTRY_CODE_TO (((UINT_16) 'T' << 8) | (UINT_16) 'O') /* Tonga */ -+#define COUNTRY_CODE_TR (((UINT_16) 'T' << 8) | (UINT_16) 'R') /* Turkey */ -+#define COUNTRY_CODE_TT (((UINT_16) 'T' << 8) | (UINT_16) 'T') /* Trinidad and Tobago */ -+#define COUNTRY_CODE_TV (((UINT_16) 'T' << 8) | (UINT_16) 'V') /* Tuvalu */ -+#define COUNTRY_CODE_TW (((UINT_16) 'T' << 8) | (UINT_16) 'W') /* Taiwan */ -+#define COUNTRY_CODE_TZ (((UINT_16) 'T' << 8) | (UINT_16) 'Z') /* Tanzania */ -+#define COUNTRY_CODE_UA (((UINT_16) 'U' << 8) | (UINT_16) 'A') /* Ukraine */ -+#define COUNTRY_CODE_UG (((UINT_16) 'U' << 8) | (UINT_16) 'G') /* Ugnada */ -+#define COUNTRY_CODE_US (((UINT_16) 'U' << 8) | (UINT_16) 'S') /* US */ -+#define COUNTRY_CODE_UY (((UINT_16) 'U' << 8) | (UINT_16) 'Y') /* Uruguay */ -+#define COUNTRY_CODE_UZ (((UINT_16) 'U' << 8) | (UINT_16) 'Z') /* Uzbekistan */ -+#define COUNTRY_CODE_VA (((UINT_16) 'V' << 8) | (UINT_16) 'A') /* Vatican (Holy See) */ -+#define COUNTRY_CODE_VC (((UINT_16) 'V' << 8) | (UINT_16) 'C') /* Saint Vincent and the Grenadines */ -+#define COUNTRY_CODE_VE (((UINT_16) 'V' << 8) | (UINT_16) 'E') /* Venezuela */ -+#define COUNTRY_CODE_VG (((UINT_16) 'V' << 8) | (UINT_16) 'G') /* British Virgin Islands */ -+#define COUNTRY_CODE_VI (((UINT_16) 'V' << 8) | (UINT_16) 'I') /* US Virgin Islands */ -+#define COUNTRY_CODE_VN (((UINT_16) 'V' << 8) | (UINT_16) 'N') /* Vietnam */ -+#define COUNTRY_CODE_VU (((UINT_16) 'V' << 8) | (UINT_16) 'U') /* Vanuatu */ -+#define COUNTRY_CODE_WS (((UINT_16) 'W' << 8) | (UINT_16) 'S') /* Samoa */ -+#define COUNTRY_CODE_YE (((UINT_16) 'Y' << 8) | (UINT_16) 'E') /* Yemen */ -+#define COUNTRY_CODE_YT (((UINT_16) 'Y' << 8) | (UINT_16) 'T') /* Mayotte (France) */ -+#define COUNTRY_CODE_ZA (((UINT_16) 'Z' << 8) | (UINT_16) 'A') /* South Africa */ -+#define COUNTRY_CODE_ZM (((UINT_16) 'Z' << 8) | (UINT_16) 'M') /* Zambia */ -+#define COUNTRY_CODE_ZW (((UINT_16) 'Z' << 8) | (UINT_16) 'W') /* Zimbabwe */ -+ -+#define COUNTRY_CODE_DF (((UINT_16) 'D' << 8) | (UINT_16) 'F') /* Default country domain */ -+#define COUNTRY_CODE_UDF (((UINT_16) 'U' << 8) | (UINT_16) 'D') /* User defined supported channel list -+ and passive scan channel list */ -+ -+#define COUNTRY_CODE_FF (((UINT_16) 'F' << 8) | (UINT_16) 'F') /* enable open for all channel for Certification */ -+#define COUNTRY_CODE_FE (((UINT_16) 'F' << 8) | (UINT_16) 'E') /* disable open for all channel for Certification */ -+ -+/* dot11RegDomainsSupportValue */ -+#define MIB_REG_DOMAIN_FCC 0x10 /* FCC (US) */ -+#define MIB_REG_DOMAIN_IC 0x20 /* IC or DOC (Canada) */ -+#define MIB_REG_DOMAIN_ETSI 0x30 /* ETSI (Europe) */ -+#define MIB_REG_DOMAIN_SPAIN 0x31 /* Spain */ -+#define MIB_REG_DOMAIN_FRANCE 0x32 /* France */ -+#define MIB_REG_DOMAIN_JAPAN 0x40 /* MPHPT (Japan) */ -+#define MIB_REG_DOMAIN_OTHER 0x00 /* other */ -+ -+/*2.4G*/ -+#define BAND_2G4_LOWER_BOUND 1 -+#define BAND_2G4_UPPER_BOUND 14 -+/*5G SubBand FCC spec*/ -+#define UNII1_LOWER_BOUND 36 -+#define UNII1_UPPER_BOUND 48 -+#define UNII2A_LOWER_BOUND 52 -+#define UNII2A_UPPER_BOUND 64 -+#define UNII2C_LOWER_BOUND 100 -+#define UNII2C_UPPER_BOUND 144 -+#define UNII3_LOWER_BOUND 149 -+#define UNII3_UPPER_BOUND 173 -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+#define POWER_LIMIT_TABLE_NULL 0xFFFF -+#define MAX_TX_POWER 63 -+#define MIN_TX_POWER -64 -+#define MAX_CMD_SUPPORT_CHANNEL_NUM 64 -+ -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+typedef enum _ENUM_POWER_LIMIT_T { -+ PWR_LIMIT_CCK, -+ PWR_LIMIT_20M, -+ PWR_LIMIT_40M, -+ PWR_LIMIT_80M, -+ PWR_LIMIT_160M, -+ PWR_LIMIT_NUM -+} ENUM_POWER_LIMIT_T, *P_ENUM_POWER_LIMIT_T; -+ -+#endif -+ -+typedef enum _ENUM_POWER_LIMIT_SUBBAND_T { -+ POWER_LIMIT_2G4, -+ POWER_LIMIT_UNII1, -+ POWER_LIMIT_UNII2A, -+ POWER_LIMIT_UNII2C, -+ POWER_LIMIT_UNII3, -+ POWER_LIMIT_SUBAND_NUM -+} ENUM_POWER_LIMIT_SUBBAND_T, *P_ENUM_POWER_LIMIT_SUBBAND_T; -+ -+/* Define channel offset in unit of 5MHz bandwidth */ -+typedef enum _ENUM_CHNL_SPAN_T { -+ CHNL_SPAN_5 = 1, -+ CHNL_SPAN_10 = 2, -+ CHNL_SPAN_20 = 4, -+ CHNL_SPAN_40 = 8 -+} ENUM_CHNL_SPAN_T, *P_ENUM_CHNL_SPAN_T; -+ -+/* Define BSS operating bandwidth */ -+typedef enum _ENUM_CHNL_BW_T { -+ CHNL_BW_20, -+ CHNL_BW_20_40, -+ CHNL_BW_10, -+ CHNL_BW_5 -+} ENUM_CHNL_BW_T, *P_ENUM_CHNL_BW_T; -+ -+/* In all bands, the first channel will be SCA and the second channel is SCB, -+ * then iteratively. -+ * Note the final channel will not be SCA. -+ */ -+typedef struct _DOMAIN_SUBBAND_INFO { -+ /* Note1: regulation class depends on operation bandwidth and RF band. -+ * For example: 2.4GHz, 1~13, 20MHz ==> regulation class = 81 -+ * 2.4GHz, 1~13, SCA ==> regulation class = 83 -+ * 2.4GHz, 1~13, SCB ==> regulation class = 84 -+ * Note2: TX power limit is not specified here because path loss is unknown -+ */ -+ UINT_8 ucRegClass; /* Regulation class for 20MHz */ -+ UINT_8 ucBand; /* Type: ENUM_BAND_T */ -+ UINT_8 ucChannelSpan; /* Type: ENUM_CHNL_SPAN_T */ -+ UINT_8 ucFirstChannelNum; -+ UINT_8 ucNumChannels; -+ UINT_8 fgDfs; /* Type: BOOLEAN */ -+} DOMAIN_SUBBAND_INFO, *P_DOMAIN_SUBBAND_INFO; -+ -+/* Use it as all available channel list for STA */ -+typedef struct _DOMAIN_INFO_ENTRY { -+ PUINT_16 pu2CountryGroup; -+ UINT_32 u4CountryNum; -+ -+ /* If different attributes, put them into different rSubBands. -+ * For example, DFS shall be used or not. -+ */ -+ DOMAIN_SUBBAND_INFO rSubBand[MAX_SUBBAND_NUM]; -+} DOMAIN_INFO_ENTRY, *P_DOMAIN_INFO_ENTRY; -+ -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+typedef struct _CHANNEL_POWER_LIMIT { -+ UINT_8 ucCentralCh; -+ INT_8 cPwrLimitCCK; -+ INT_8 cPwrLimit20; -+ INT_8 cPwrLimit40; -+ INT_8 cPwrLimit80; -+ INT_8 cPwrLimit160; -+ UINT_8 ucFlag; -+ UINT_8 aucReserved[1]; -+} CHANNEL_POWER_LIMIT, *P_CHANNEL_POWER_LIMIT; -+ -+typedef struct _COUNTRY_CHANNEL_POWER_LIMIT { -+ UINT_8 aucCountryCode[2]; -+ UINT_8 ucCountryFlag; -+ UINT_8 ucChannelNum; -+ UINT_8 aucReserved[4]; -+ CHANNEL_POWER_LIMIT rChannelPowerLimit[80]; -+} COUNTRY_CHANNEL_POWER_LIMIT, *P_COUNTRY_CHANNEL_POWER_LIMIT; -+ -+#define CHANNEL_PWR_LIMIT(_channel, _pwrLimit_cck, _pwrLimit_bw20, \ -+ _pwrLimit_bw40, _pwrLimit_bw80, _pwrLimit_bw160, _ucFlag) \ -+ { \ -+ .ucCentralCh = (_channel), \ -+ .cPwrLimitCCK = (_pwrLimit_cck), \ -+ .cPwrLimit20 = (_pwrLimit_bw20), \ -+ .cPwrLimit40 = (_pwrLimit_bw40), \ -+ .cPwrLimit80 = (_pwrLimit_bw80), \ -+ .cPwrLimit160 = (_pwrLimit_bw160), \ -+ .ucFlag = (_ucFlag), \ -+ .aucReserved = {0} \ -+} -+ -+typedef struct _COUNTRY_POWER_LIMIT_TABLE_DEFAULT { -+ UINT_8 aucCountryCode[2]; -+ /* 0: ch 1 ~14 , 1: ch 36 ~48, 2: ch 52 ~64, 3: ch 100 ~144, 4: ch 149 ~165 */ -+ INT_8 aucPwrLimitSubBand[POWER_LIMIT_SUBAND_NUM]; -+ /* bit0: cPwrLimit2G4, bit1: cPwrLimitUnii1; bit2: cPwrLimitUnii2A; -+ * bit3: cPwrLimitUnii2C; bit4: cPwrLimitUnii3; mW: 0, mW\MHz : 1 */ -+ UINT_8 ucPwrUnit; -+} COUNTRY_POWER_LIMIT_TABLE_DEFAULT, *P_COUNTRY_POWER_LIMIT_TABLE_DEFAULT; -+ -+typedef struct _COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION { -+ UINT_8 aucCountryCode[2]; -+ UINT_8 ucCentralCh; -+ INT_8 aucPwrLimit[PWR_LIMIT_NUM]; -+} COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION, *P_COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION; -+ -+typedef struct _SUBBAND_CHANNEL_T { -+ UINT_8 ucStartCh; -+ UINT_8 ucEndCh; -+ UINT_8 ucInterval; -+ UINT_8 ucReserved; -+} SUBBAND_CHANNEL_T, *P_SUBBAND_CHANNEL_T; -+ -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define CAL_CH_OFFSET_80M(_PRIMARY_CH, _CENTRAL_CH) \ -+ (((_PRIMARY_CH - _CENTRAL_CH) + 6) >> 2) -+ -+#define CAL_CH_OFFSET_160M(_PRIMARY_CH, _CENTRAL_CH) \ -+ (((_PRIMARY_CH - _CENTRAL_CH) + 14) >> 2) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+P_DOMAIN_INFO_ENTRY rlmDomainGetDomainInfo(P_ADAPTER_T prAdapter); -+ -+VOID -+rlmDomainGetChnlList(P_ADAPTER_T prAdapter, -+ ENUM_BAND_T eSpecificBand, BOOLEAN fgNoDfs, -+ UINT_8 ucMaxChannelNum, PUINT_8 pucNumOfChannel, P_RF_CHANNEL_INFO_T paucChannelList); -+ -+VOID rlmDomainSendCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid); -+ -+VOID rlmDomainSendDomainInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid); -+ -+VOID rlmDomainSendPassiveScanInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid); -+ -+BOOLEAN rlmDomainIsLegalChannel(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, UINT_8 ucChannel); -+ -+UINT_32 rlmDomainSupOperatingClassIeFill(PUINT_8 pBuf); -+ -+BOOLEAN rlmDomainCheckChannelEntryValid(P_ADAPTER_T prAdapter, UINT_8 ucCentralCh); -+ -+UINT_8 rlmDomainGetCenterChannel(ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); -+ -+BOOLEAN rlmDomainIsValidRfSetting(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, -+ UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend, -+ ENUM_CHANNEL_WIDTH_T eChannelWidth, UINT_8 ucChannelS1, UINT_8 ucChannelS2); -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+BOOLEAN -+rlmDomainCheckPowerLimitValid(P_ADAPTER_T prAdapter, -+ COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION rPowerLimitTableConfiguration, -+ UINT_8 ucPwrLimitNum); -+ -+VOID rlmDomainCheckCountryPowerLimitTable(P_ADAPTER_T prAdapter); -+ -+UINT_16 rlmDomainPwrLimitDefaultTableDecision(P_ADAPTER_T prAdapter, UINT_16 u2CountryCode); -+ -+VOID rlmDomainSendPwrLimitCmd(P_ADAPTER_T prAdapter); -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RLM_DOMAIN_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h -new file mode 100644 -index 0000000000000..7f29dba4ce069 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h -@@ -0,0 +1,150 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_obss.h#1 -+*/ -+ -+/*! \file "rlm_obss.h" -+ \brief -+*/ -+ -+/* -+** Log: rlm_obss.h -+ * -+ * 01 24 2011 cm.chang -+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode and stop -+ * ampdu timer when sta_rec is freed -+ * Process received 20/40 coexistence action frame for AP mode -+ * -+ * 01 13 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Refine function when rcv a 20/40M public action frame -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 05 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Process 20/40 coexistence public action frame in AP mode -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft support for 20/40M bandwidth for AP mode -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add virtual test for OBSS scan -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 02 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support PCO in STA mode -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 01 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+*/ -+ -+#ifndef _RLM_OBSS_H -+#define _RLM_OBSS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define CHNL_LIST_SZ_2G 14 -+#define CHNL_LIST_SZ_5G 14 -+ -+#define CHNL_LEVEL0 0 -+#define CHNL_LEVEL1 1 -+#define CHNL_LEVEL2 2 -+ -+#define AFFECTED_CHNL_OFFSET 5 -+ -+#define OBSS_SCAN_MIN_INTERVAL 10 /* In unit of sec */ -+ -+#define PUBLIC_ACTION_MAX_LEN 200 /* In unit of byte */ -+ -+/* P2P GO only */ -+/* Define default OBSS Scan parameters (from MIB in spec.) */ -+#define dot11OBSSScanPassiveDwell 20 -+#define dot11OBSSScanActiveDwell 10 -+#define dot11OBSSScanPassiveTotalPerChannel 200 -+#define dot11OBSSScanActiveTotalPerChannel 20 -+#define dot11BSSWidthTriggerScanInterval 300 /* Unit: sec */ -+#define dot11BSSWidthChannelTransitionDelayFactor 5 -+#define dot11OBSSScanActivityThreshold 25 -+ -+#define OBSS_20_40M_TIMEOUT (dot11BSSWidthTriggerScanInterval + 10) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/* Control MAC PCO function */ -+typedef enum _ENUM_SYS_PCO_PHASE_T { -+ SYS_PCO_PHASE_DISABLED = 0, -+ SYS_PCO_PHASE_20M, -+ SYS_PCO_PHASE_40M -+} ENUM_SYS_PCO_PHASE_T, *P_ENUM_SYS_PCO_PHASE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID rlmObssInit(P_ADAPTER_T prAdapter); -+ -+VOID rlmObssScanDone(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); -+ -+VOID rlmObssTriggerScan(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RLM_OBSS_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h -new file mode 100644 -index 0000000000000..8665e48569bad ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h -@@ -0,0 +1,122 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_protection.h#1 -+*/ -+ -+/*! \file "rlm_protection.h" -+ \brief -+*/ -+ -+/* -+** Log: rlm_protection.h -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 02 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support PCO in STA mode -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 01 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+*/ -+ -+#ifndef _RLM_PROTECTION_H -+#define _RLM_PROTECTION_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_SYS_PROTECT_MODE_T { -+ SYS_PROTECT_MODE_NONE = 0, /* Mode 0 */ -+ SYS_PROTECT_MODE_ERP, /* Mode 1 */ -+ SYS_PROTECT_MODE_NON_HT, /* Mode 2 */ -+ SYS_PROTECT_MODE_20M, /* Mode 3 */ -+ -+ SYS_PROTECT_MODE_NUM -+} ENUM_SYS_PROTECT_MODE_T, *P_ENUM_SYS_PROTECT_MODE_T; -+ -+/* This definition follows HT Protection field of HT Operation IE */ -+typedef enum _ENUM_HT_PROTECT_MODE_T { -+ HT_PROTECT_MODE_NONE = 0, -+ HT_PROTECT_MODE_NON_MEMBER, -+ HT_PROTECT_MODE_20M, -+ HT_PROTECT_MODE_NON_HT, -+ -+ HT_PROTECT_MODE_NUM -+} ENUM_HT_PROTECT_MODE_T, *P_ENUM_HT_PROTECT_MODE_T; -+ -+typedef enum _ENUM_GF_MODE_T { -+ GF_MODE_NORMAL = 0, -+ GF_MODE_PROTECT, -+ GF_MODE_DISALLOWED, -+ -+ GF_MODE_NUM -+} ENUM_GF_MODE_T, *P_ENUM_GF_MODE_T; -+ -+typedef enum _ENUM_RIFS_MODE_T { -+ RIFS_MODE_NORMAL = 0, -+ RIFS_MODE_DISALLOWED, -+ -+ RIFS_MODE_NUM -+} ENUM_RIFS_MODE_T, *P_ENUM_RIFS_MODE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RLM_PROTECTION_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h -new file mode 100644 -index 0000000000000..d01c6e01e83f5 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h -@@ -0,0 +1,1213 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_txpwr_init.h#1 -+*/ -+ -+/*! \file "rlm_txpwr_init.h" -+ \brief -+*/ -+ -+/* -+** Log: rlm_txpwr_init.h -+*/ -+ -+ -+#ifndef _RLM_TXPWR_INIT_H -+#define _RLM_TXPWR_INIT_H -+ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/*Support Tx Power Range : 63~ -64 (unit : 0.5dBm)*/ -+ -+#define PWR_LIMIT_2G4_IN_MW_MHZ BIT(0) -+#define PWR_LIMIT_UNII1_IN_MW_MHZ BIT(1) -+#define PWR_LIMIT_UNII2A_IN_MW_MHZ BIT(2) -+#define PWR_LIMIT_UNII2C_IN_MW_MHZ BIT(3) -+#define PWR_LIMIT_UNII3_IN_MW_MHZ BIT(4) -+ -+#if CFG_SUPPORT_CE_FCC_TXPWR_LIMIT -+#define CE_FCC_TXPWR_LIMIT_CCK 30 /* 15 dBm */ -+#define CE_FCC_TXPWR_LIMIT_OFDM 20 /* 10 dBm */ -+#define CE_FCC_TXPWR_LIMIT_HT40 18 /* 9 dBm */ -+#endif -+ -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+COUNTRY_POWER_LIMIT_TABLE_DEFAULT g_rRlmPowerLimitDefault[] = { -+ -+ {{'A', 'O'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'B', 'Z'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'B', 'J'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'B', 'T'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'B', 'O'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'B', 'I'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'M'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'F'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'D'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'K', 'M'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'D'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'G'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'I'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'D', 'J'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'Q'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'E', 'R'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'F', 'J'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'A'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'M'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'N'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'W'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'R', 'K'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'K', 'G'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'L', 'Y'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'M', 'G'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'M', 'L'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'N', 'R'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'N', 'C'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'T'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'C'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'L'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'B'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'O'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'R'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'Z'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'J'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'G'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'O'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'M'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'V'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'V', 'U'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'Y', 'E'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'A', 'S'} -+ , {60, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'A', 'I'} -+ , {60, 34, 48, 60, 60} -+ , 0} -+ , -+ {{'B', 'M'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'C', 'A'} -+ , {60, 46, 48, 48, 60} -+ , 0} -+ , -+ {{'K', 'Y'} -+ , {60, 34, 48, 60, 60} -+ , 0} -+ , -+ {{'G', 'U'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'F', 'M'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'P', 'R'} -+ , {60, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'U', 'S'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'V', 'I'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'A', 'R'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'A', 'U'} -+ , {63, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'A', 'Z'} -+ , {40, 34, 48, 60, 60} -+ , 0} -+ , -+ {{'B', 'W'} -+ , {40, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'K', 'H'} -+ , {40, 46, 46, 48, 60} -+ , 0} -+ , -+ {{'C', 'X'} -+ , {63, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'C', 'O'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'C', 'R'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'E', 'C'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'G', 'D'} -+ , {40, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'G', 'T'} -+ , {40, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'H', 'K'} -+ , {63, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'K', 'I'} -+ , {63, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'B'} -+ , {40, 46, 46, 46, 46} -+ , 0} -+ , -+ {{'L', 'R'} -+ , {60, 46, 60, 63, 63} -+ , 0} -+ , -+ {{'M', 'N'} -+ , {46, 32, 46, 46, 58} -+ , 0} -+ , -+ {{'A', 'N'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'N', 'Z'} -+ , {63, 46, 60, 48, 63} -+ , 0} -+ , -+ {{'N', 'I'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'P', 'W'} -+ , {60, 60, 60, 60, 60} -+ , 0} -+ , -+ {{'P', 'Y'} -+ , {60, 46, 46, 48, 60} -+ , 0} -+ , -+ {{'P', 'E'} -+ , {54, 46, 48, 42, 48} -+ , 0} -+ , -+ {{'P', 'H'} -+ , {40, 46, 46, 48, 48} -+ , 0} -+ , -+ {{'W', 'S'} -+ , {40, 40, 40, 40, 60} -+ , 0} -+ , -+ {{'S', 'G'} -+ , {46, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'L', 'K'} -+ , {46, 46, 46, 46, 46} -+ , 0} -+ , -+ {{'T', 'H'} -+ , {40, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'T', 'T'} -+ , {60, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'U', 'Y'} -+ , {63, 46, 46, 46, 46} -+ , 0} -+ , -+ {{'V', 'N'} -+ , {46, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'A', 'W'} -+ , {60, 46, 60, 60, 63} -+ , 0} -+ , -+ {{'L', 'A'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'A'} -+ , {40, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'A', 'E'} -+ , {40, 46, 46, 60, 46} -+ , 0} -+ , -+ {{'U', 'G'} -+ , {40, 46, 46, 48, 60} -+ , 0} -+ , -+ {{'M', 'M'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'A', 'L'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'D', 'Z'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'A', 'D'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'A', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'B', 'Y'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'B', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'B', 'A'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'V', 'G'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'B', 'G'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'C', 'V'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'H', 'R'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'C', 'Y'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'C', 'Z'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'D', 'K'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'E', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'E', 'T'} -+ , {40, 40, 40, 40, 63} -+ , 0} -+ , -+ {{'F', 'I'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'F', 'R'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'G', 'F'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'P', 'F'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'T', 'F'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'G', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'D', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'G', 'H'} -+ , {40, 34, 48, 60, 63} -+ , 0} -+ , -+ {{'G', 'R'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'G', 'P'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'H', 'U'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'I', 'S'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'I', 'Q'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'I', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'I', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'K', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'V'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'S'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'I'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'U'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'K'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'Q'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'R'} -+ , {40, 46, 46, 46, 63} -+ , 0} -+ , -+ {{'M', 'U'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'Y', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'D'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'C'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'S'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'N', 'L'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'N', 'O'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'O', 'M'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'P', 'L'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'P', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'R', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'R', 'O'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'F'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'M'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'N'} -+ , {40, 40, 40, 60, 63} -+ , 0} -+ , -+ {{'R', 'S'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'K'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'I'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'Z', 'A'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'E', 'S'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'C', 'H'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'T', 'R'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'T', 'C'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'G', 'B'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'V', 'A'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'A', 'M'} -+ , {40, 40, 40, 63, 63} -+ , 0} -+ , -+ {{'I', 'L'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'K', 'W'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'M', 'A'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'N', 'E'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'T', 'N'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'E', 'H'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'N', 'P'} -+ , {60, 46, 46, 63, 60} -+ , 0} -+ , -+ {{'A', 'F'} -+ , {40, 46, 63, 63, 63} -+ , 0} -+ , -+ {{'A', 'G'} -+ , {40, 46, 48, 63, 54} -+ , 0} -+ , -+ {{'B', 'S'} -+ , {63, 46, 60, 63, 63} -+ , 0} -+ , -+ {{'B', 'H'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'B', 'B'} -+ , {40, 46, 48, 63, 54} -+ , 0} -+ , -+ {{'B', 'N'} -+ , {46, 46, 46, 63, 60} -+ , 0} -+ , -+ {{'C', 'L'} -+ , {40, 44, 44, 63, 44} -+ , 0} -+ , -+ {{'C', 'N'} -+ , {40, 46, 46, 63, 54} -+ , 0} -+ , -+ {{'E', 'G'} -+ , {40, 46, 46, 63, 46} -+ , 0} -+ , -+ {{'S', 'V'} -+ , {60, 34, 48, 63, 60} -+ , 0} -+ , -+ {{'I', 'N'} -+ , {60, 46, 46, 63, 60} -+ , 0} -+ , -+ {{'M', 'Y'} -+ , {54, 60, 60, 63, 60} -+ , 0} -+ , -+ {{'M', 'V'} -+ , {40, 46, 46, 63, 40} -+ , 0} -+ , -+ {{'P', 'A'} -+ , {60, 34, 48, 63, 60} -+ , 0} -+ , -+ {{'V', 'E'} -+ , {60, 46, 46, 63, 60} -+ , 0} -+ , -+ {{'Z', 'M'} -+ , {60, 46, 46, 63, 60} -+ , 0} -+ , -+ {{'J', 'O'} -+ , {40, 46, 63, 63, 46} -+ , 0} -+ , -+ {{'P', 'G'} -+ , {40, 46, 63, 63, 60} -+ , 0} -+ , -+ {{'B', 'F'} -+ , {40, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'G', 'Y'} -+ , {60, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'H', 'T'} -+ , {40, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'H', 'N'} -+ , {60, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'J', 'M'} -+ , {54, 63, 63, 63, 57} -+ , 0} -+ , -+ {{'M', 'O'} -+ , {40, 63, 63, 63, 40} -+ , 0} -+ , -+ {{'M', 'W'} -+ , {60, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'P', 'K'} -+ , {40, 63, 63, 63, 40} -+ , 0} -+ , -+ {{'Q', 'A'} -+ , {40, 63, 63, 63, 40} -+ , 0} -+ , -+ {{'R', 'W'} -+ , {40, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'K', 'N'} -+ , {40, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'T', 'Z'} -+ , {40, 63, 63, 63, 40} -+ , 0} -+ , -+ {{'I', 'D'} -+ , {46, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'N', 'G'} -+ , {40, 63, 46, 63, 60} -+ , 0} -+ , -+ {{'B', 'D'} -+ , {40, 46, 46, 60, 28} -+ , 0} -+ , -+ {{'B', 'R'} -+ , {52, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'D', 'M'} -+ , {60, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'D', 'O'} -+ , {63, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'F', 'K'} -+ , {40, 46, 46, 60, 28} -+ , 0} -+ , -+ {{'K', 'Z'} -+ , {40, 34, 48, 60, 60} -+ , 0} -+ , -+ {{'M', 'X'} -+ , {60, 34, 48, 60, 63} -+ , 0} -+ , -+ {{'M', 'Z'} -+ , {40, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'N', 'A'} -+ , {40, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'R', 'U'} -+ , {40, 34, 48, 60, 60} -+ , 0} -+ , -+ {{'L', 'C'} -+ , {40, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'V', 'C'} -+ , {40, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'U', 'A'} -+ , {40, 46, 46, 46, 48} -+ , 0} -+ , -+ {{'U', 'Z'} -+ , {40, 48, 48, 48, 60} -+ , 0} -+ , -+ {{'Z', 'W'} -+ , {40, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'M', 'P'} -+ , {60, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'T', 'W'} -+ , {60, 63, 34, 48, 60} -+ , 0} -+ , -+ {{'C', 'K'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'U'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'L'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'F', 'O'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'I'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'G'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'I', 'R'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'I', 'M'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'J', 'E'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'K', 'P'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'M', 'H'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'N', 'U'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'N', 'F'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'P', 'S'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'P', 'N'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'P', 'M'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'S'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'D'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'Y'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'J', 'P'} -+ , {46, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'K', 'R'} -+ , {46, 34, 46, 46, 46} -+ , PWR_LIMIT_UNII1_IN_MW_MHZ} -+ , -+ -+/*Default*/ -+ {{0, 0} -+ , {63, 63, 63, 63, 63} -+ , 0} -+}; -+ -+COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION g_rRlmPowerLimitConfiguration[] = { -+ -+ {{'A', 'I'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'A', 'Z'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'B', 'W'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'G', 'D'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'L', 'B'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'L', 'R'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'W', 'S'} -+ , 165, {40, 40, 40, 40, 40} -+ } -+ , -+ {{'V', 'N'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 1, {38, 30, 60, 60, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 3, {60, 60, 26, 60, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 9, {60, 60, 26, 60, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 11, {38, 30, 60, 60, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 36, {34, 34, 34, 34, 34} -+ } -+ , -+ {{'U', 'S'} -+ , 38, {34, 34, 34, 34, 34} -+ } -+ , -+ {{'U', 'S'} -+ , 42, {34, 34, 34, 31, 34} -+ } -+ , -+ {{'U', 'S'} -+ , 58, {48, 48, 48, 31, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 62, {48, 48, 34, 48, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 64, {37, 37, 48, 48, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 100, {37, 37, 48, 48, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 102, {48, 48, 34, 48, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 106, {48, 48, 48, 31, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 155, {60, 60, 60, 31, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 159, {60, 60, 34, 60, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 165, {37, 37, 60, 60, 60} -+ } -+ , -+ -+/*Default*/ -+ {{0, 0} -+ , 165, {63, 63, 63, 63, 63} -+ } -+}; -+ -+#if 0 -+COUNTRY_CHANNEL_POWER_LIMIT g_rRlmCountryPowerLimitTable[] = { -+ { -+ {'A', 'O'} -+ , 0, 0, {0, 0, 0, 0} -+ , -+ { -+ CHANNEL_PWR_LIMIT(1, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(2, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(3, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(4, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(5, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(6, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(7, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(8, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(9, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(10, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(11, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(12, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(13, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(14, 40, 40, 40, 40, 40, 0), -+ -+ CHANNEL_PWR_LIMIT(36, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(38, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(40, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(42, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(44, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(46, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(48, 63, 63, 63, 63, 63, 0), -+ -+ CHANNEL_PWR_LIMIT(52, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(54, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(56, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(58, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(60, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(62, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(64, 63, 63, 63, 63, 63, 0), -+ -+ CHANNEL_PWR_LIMIT(100, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(102, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(104, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(106, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(108, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(110, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(112, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(114, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(116, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(118, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(120, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(122, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(124, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(126, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(128, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(130, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(132, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(134, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(136, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(138, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(140, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(142, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(144, 63, 63, 63, 63, 63, 0), -+ -+ CHANNEL_PWR_LIMIT(149, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(151, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(153, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(155, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(157, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(159, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(161, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(163, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(165, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(167, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(169, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(171, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(173, 63, 63, 63, 63, 63, 0) -+ } -+ } -+ , -+ { -+ /*Used to check the end of country entry */ -+ {0, 0} -+ , 0, 0, {0, 0, 0, 0} -+ , -+ { -+ /*Used to check the end of channel power limit */ -+ CHANNEL_PWR_LIMIT(ENDCH, 0, 0, 0, 0, 0, 0) -+ } -+ } /*end of CountryTable */ -+}; -+#endif -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RLM_TXPWR_INIT_H */ -+ -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h -new file mode 100644 -index 0000000000000..0df4ec3e08282 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h -@@ -0,0 +1,171 @@ -+/* -+** Id: -+*/ -+ -+/*! \file "roaming_fsm.h" -+ \brief This file defines the FSM for Roaming MODULE. -+ -+ This file defines the FSM for Roaming MODULE. -+*/ -+ -+/* -+** Log: roaming_fsm.h -+ * -+ * 08 31 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * remove obsolete code. -+ * -+ * 08 15 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * add swcr in driver reg, 0x9fxx0000, to disable roaming . -+ * -+ * 03 16 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * remove obsolete definition and unused variables. -+ * -+ * 02 26 2011 tsaiyuan.hsu -+ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support -+ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+*/ -+ -+#ifndef _ROAMING_FSM_H -+#define _ROAMING_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Roaming Discovery interval, SCAN result need to be updated */ -+#define ROAMING_DISCOVERY_TIMEOUT_SEC 5 /* Seconds. */ -+ -+/* #define ROAMING_NO_SWING_RCPI_STEP 5 //rcpi */ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_ROAMING_FAIL_REASON_T { -+ ROAMING_FAIL_REASON_CONNLIMIT = 0, -+ ROAMING_FAIL_REASON_NOCANDIDATE, -+ ROAMING_FAIL_REASON_NUM -+} ENUM_ROAMING_FAIL_REASON_T; -+ -+/* events of roaming between driver and firmware */ -+typedef enum _ENUM_ROAMING_EVENT_T { -+ ROAMING_EVENT_START = 0, -+ ROAMING_EVENT_DISCOVERY, -+ ROAMING_EVENT_ROAM, -+ ROAMING_EVENT_FAIL, -+ ROAMING_EVENT_ABORT, -+ ROAMING_EVENT_NUM -+} ENUM_ROAMING_EVENT_T; -+ -+#define ROAMING_EVENT_REASON_TX_ERR BIT(0) -+#define ROAMING_EVENT_REASON_RCPI BIT(1) -+ -+typedef struct _ROAMING_PARAM_T { -+ UINT_16 u2Event; -+ UINT_16 u2Data; -+ UINT_16 u2Reason; -+} ROAMING_PARAM_T, *P_ROAMING_PARAM_T; -+ -+ /**/ typedef enum _ENUM_ROAMING_STATE_T { -+ ROAMING_STATE_IDLE = 0, -+ ROAMING_STATE_DECISION, -+ ROAMING_STATE_DISCOVERY, -+ ROAMING_STATE_ROAM, -+ ROAMING_STATE_NUM -+} ENUM_ROAMING_STATE_T; -+ -+typedef struct _ROAMING_INFO_T { -+ BOOLEAN fgIsEnableRoaming; -+ -+ ENUM_ROAMING_STATE_T eCurrentState; -+ -+ OS_SYSTIME rRoamingDiscoveryUpdateTime; -+ -+#define ROAMING_ENTRY_TIMEOUT_SKIP_COUNT_MAX 2 -+ UINT_32 RoamingEntryTimeoutSkipCount; -+ -+} ROAMING_INFO_T, *P_ROAMING_INFO_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#if CFG_SUPPORT_ROAMING -+#define IS_ROAMING_ACTIVE(prAdapter) \ -+ (prAdapter->rWifiVar.rRoamingInfo.eCurrentState == ROAMING_STATE_ROAM) -+#else -+#define IS_ROAMING_ACTIVE(prAdapter) FALSE -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID roamingFsmInit(IN P_ADAPTER_T prAdapter); -+ -+VOID roamingFsmUninit(IN P_ADAPTER_T prAdapter); -+ -+VOID roamingFsmSendCmd(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam); -+ -+VOID roamingFsmScanResultsUpdate(IN P_ADAPTER_T prAdapter); -+ -+VOID roamingFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_ROAMING_STATE_T eNextState); -+ -+VOID roamingFsmRunEventStart(IN P_ADAPTER_T prAdapter); -+ -+VOID roamingFsmRunEventDiscovery(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam); -+ -+VOID roamingFsmRunEventRoam(IN P_ADAPTER_T prAdapter); -+ -+VOID roamingFsmRunEventFail(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Reason); -+ -+VOID roamingFsmRunEventAbort(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS roamingFsmProcessEvent(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _ROAMING_FSM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h -new file mode 100644 -index 0000000000000..20ab14251f65d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h -@@ -0,0 +1,271 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rsn.h#1 -+*/ -+ -+/*! \file rsn.h -+ \brief The wpa/rsn related define, macro and structure are described here. -+*/ -+ -+/* -+** Log: rsn.h -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 06 22 2011 wh.su -+ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h -+ * and let the sw structure not align at byte -+ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte, -+ * Notice needed update P2P.ko. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode -+ * adding the code for check STA privacy bit at AP mode, . -+ * -+ * 11 05 2010 wh.su -+ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value -+ * fixed the.pmkid value mismatch issue -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * add a kal function for set cipher. -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 30 2010 wh.su -+ * NULL -+ * remove non-used code. -+ * -+ * 08 19 2010 wh.su -+ * NULL -+ * adding the tx pkt call back handle for countermeasure. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, and modify -+ * the security related callback function prototype. -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function prototype for generate wap/rsn ie -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function input parameter -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some event function declaration -+ * -+ * Nov 26 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * move the internal data structure for pmkid to rsn.h -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the port control and class error function -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the pmkid candidate -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** -+*/ -+ -+#ifndef _RSN_H -+#define _RSN_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* ----- Definitions for Cipher Suite Selectors ----- */ -+#define RSN_CIPHER_SUITE_USE_GROUP_KEY 0x00AC0F00 -+#define RSN_CIPHER_SUITE_WEP40 0x01AC0F00 -+#define RSN_CIPHER_SUITE_TKIP 0x02AC0F00 -+#define RSN_CIPHER_SUITE_CCMP 0x04AC0F00 -+#define RSN_CIPHER_SUITE_WEP104 0x05AC0F00 -+#if CFG_SUPPORT_802_11W -+#define RSN_CIPHER_SUITE_AES_128_CMAC 0x06AC0F00 -+#endif -+ -+#define WPA_CIPHER_SUITE_NONE 0x00F25000 -+#define WPA_CIPHER_SUITE_WEP40 0x01F25000 -+#define WPA_CIPHER_SUITE_TKIP 0x02F25000 -+#define WPA_CIPHER_SUITE_CCMP 0x04F25000 -+#define WPA_CIPHER_SUITE_WEP104 0x05F25000 -+ -+/* ----- Definitions for Authentication and Key Management Suite Selectors ----- */ -+#define RSN_AKM_SUITE_NONE 0x00AC0F00 -+#define RSN_AKM_SUITE_802_1X 0x01AC0F00 -+#define RSN_AKM_SUITE_PSK 0x02AC0F00 -+#if CFG_SUPPORT_802_11W -+#define RSN_AKM_SUITE_802_1X_SHA256 0x05AC0F00 -+#define RSN_AKM_SUITE_PSK_SHA256 0x06AC0F00 -+#endif -+ -+#define WPA_AKM_SUITE_NONE 0x00F25000 -+#define WPA_AKM_SUITE_802_1X 0x01F25000 -+#define WPA_AKM_SUITE_PSK 0x02F25000 -+ -+#define ELEM_ID_RSN_LEN_FIXED 20 /* The RSN IE len for associate request */ -+ -+#define ELEM_ID_WPA_LEN_FIXED 22 /* The RSN IE len for associate request */ -+ -+#define MASK_RSNIE_CAP_PREAUTH BIT(0) -+ -+#define GET_SELECTOR_TYPE(x) ((UINT_8)(((x) >> 24) & 0x000000FF)) -+#define SET_SELECTOR_TYPE(x, y) {x = (((x) & 0x00FFFFFF) | (((UINT_32)(y) << 24) & 0xFF000000))} -+ -+#define AUTH_CIPHER_CCMP 0x00000008 -+ -+/* Cihpher suite flags */ -+#define CIPHER_FLAG_NONE 0x00000000 -+#define CIPHER_FLAG_WEP40 0x00000001 /* BIT 1 */ -+#define CIPHER_FLAG_TKIP 0x00000002 /* BIT 2 */ -+#define CIPHER_FLAG_CCMP 0x00000008 /* BIT 4 */ -+#define CIPHER_FLAG_WEP104 0x00000010 /* BIT 5 */ -+#define CIPHER_FLAG_WEP128 0x00000020 /* BIT 6 */ -+ -+#define WAIT_TIME_IND_PMKID_CANDICATE_SEC 6 /* seconds */ -+#define TKIP_COUNTERMEASURE_SEC 60 /* seconds */ -+ -+#if CFG_SUPPORT_802_11W -+#define RSN_AUTH_MFP_DISABLED 0 /* MFP disabled */ -+#define RSN_AUTH_MFP_OPTIONAL 1 /* MFP optional */ -+#define RSN_AUTH_MFP_REQUIRED 2 /* MFP required */ -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/* Flags for PMKID Candidate list structure */ -+#define EVENT_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 -+ -+#define CONTROL_FLAG_UC_MGMT_NO_ENC BIT(5) -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define RSN_IE(fp) ((P_RSN_INFO_ELEM_T) fp) -+#define WPA_IE(fp) ((P_WPA_INFO_ELEM_T) fp) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+BOOLEAN rsnParseRsnIE(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prRsnInfo); -+ -+BOOLEAN rsnParseWpaIE(IN P_ADAPTER_T prAdapter, IN P_WPA_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prWpaInfo); -+ -+BOOLEAN rsnSearchSupportedCipher(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Cipher, OUT PUINT_32 pu4Index); -+ -+BOOLEAN rsnSearchAKMSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4AkmSuite, OUT PUINT_32 pu4Index); -+ -+BOOLEAN rsnPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss); -+ -+VOID rsnGenerateWpaNoneIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID rsnGenerateWPAIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID rsnGenerateRSNIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+BOOLEAN -+rsnParseCheckForWFAInfoElem(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType, OUT PUINT_16 pu2SubTypeVersion); -+ -+BOOLEAN rsnIsSuitableBSS(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_T prBssRsnInfo); -+ -+#if CFG_SUPPORT_AAA -+void rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe, PUINT_16 pu2StatusCode); -+#endif -+ -+VOID rsnTkipHandleMICFailure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgErrorKeyType); -+ -+VOID rsnSelectPmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+VOID rsnUpdatePmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+BOOLEAN rsnSearchPmkidEntry(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBssid, OUT PUINT_32 pu4EntryIndex); -+ -+BOOLEAN rsnCheckPmkidCandicate(IN P_ADAPTER_T prAdapter); -+ -+VOID rsnCheckPmkidCache(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss); -+ -+VOID rsnGeneratePmkidIndication(IN P_ADAPTER_T prAdapter); -+ -+VOID rsnIndicatePmkidCand(IN P_ADAPTER_T prAdapter, IN ULONG ulParm); -+#if CFG_SUPPORT_WPS2 -+VOID rsnGenerateWSCIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+#endif -+ -+#if CFG_SUPPORT_802_11W -+UINT_32 rsnCheckBipKeyInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+UINT_8 rsnCheckSaQueryTimeout(IN P_ADAPTER_T prAdapter); -+ -+void rsnStartSaQueryTimer(IN P_ADAPTER_T prAdapter); -+ -+void rsnStartSaQuery(IN P_ADAPTER_T prAdapter); -+ -+void rsnStopSaQuery(IN P_ADAPTER_T prAdapter); -+ -+void rsnSaQueryRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+void rsnSaQueryAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+BOOLEAN rsnCheckRxMgmt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN UINT_8 ucSubtype); -+#endif -+BOOLEAN rsnCheckSecurityModeChanged(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_BSS_DESC_T prBssDesc); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RSN_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h -new file mode 100644 -index 0000000000000..c08b2244be6c4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h -@@ -0,0 +1,988 @@ -+/* -+** Id: @(#) -+*/ -+ -+/*! \file "scan.h" -+ \brief -+ -+*/ -+ -+/* -+** Log: scan.h -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration -+ * with corresponding network configuration -+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting -+ * preferred band configuration corresponding to network type. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for more than one SSID -+ * in a single scanning request -+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID -+ * support as well as uProbeDelay in NDIS 6.x driver model -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings -+ * to work around some tricky AP which use space character as hidden SSID -+ * allow to have a single BSSID with multiple SSID to be presented in scanning result -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module -+ * with structure miss-align pointer issue -+ * always pre-allio WAPI related structure for align p2p module. -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Fix compile error. -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add interface for RLM to trigger OBSS-SCAN. -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Add a functio prototype to find p2p descriptor of a bss descriptor directly. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add function prototype for return channel. -+ * modify data structure for scan specific device ID or TYPE. (Move from P2P Connection Settings to Scan Param) -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Check-in P2P Device Discovery Feature. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add a option for channel time extension in scan abort command. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add for P2P Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Scan status "FIND" is used for P2P FSM find state. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * SCN module is now able to handle multiple concurrent scanning requests -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * pass band with channel number information as scan parameter -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * remove timer in DRV-SCN. -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, other request -+ * will be directly dropped by returning BUSY -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan uninitialization procedure -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * modify Beacon/ProbeResp to complete parsing, -+ * because host software has looser memory usage restriction -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P related field in SCAN_PARAM_T. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * saa_fsm.c is migrated. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * restore utility function invoking via hem_mbox to direct calls -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 13 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * -+ * Add new HW CH macro support -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Modify scanBuildProbeReqFrameCommonIEs() to support P2P SCAN -+ * -+ * 02 23 2010 wh.su -+ * [BORA00000592][MT6620 Wi-Fi] Adding the security related code for driver -+ * refine the scan procedure, reduce the WPA and WAPI IE parsing, and move the parsing to the time for join. -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * Simplify the process of Beacon during SCAN and remove redundant variable in PRE_BSS_DESC_T -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding variable for wapi ap -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * remove non-used secuirty variavle -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Refine data structure of BSS_DESC_T and PRE_BSS_DESC_T -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add eNetType to rScanParam and revise MGMT Handler with Retain Status -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add ucAvailablePhyTypeSet to BSS_DESC_T -+ * -+ * Nov 20 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add aucSrcAddress to SCAN_PARAM_T for P2P's Device Address -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the security related variable -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the security ie filed for scan parsing -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add scanSearchBssDescByPolicy() -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add function declarations of scan_fsm.c -+ * -+ * Oct 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add scan.h to source control -+** -+*/ -+ -+#ifndef _SCAN_H -+#define _SCAN_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "gl_vendor.h" -+ -+/* TDLS test purpose */ -+extern BOOLEAN flgTdlsTestExtCapElm; -+extern UINT8 aucTdlsTestExtCapElm[]; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/*! Maximum buffer size of SCAN list */ -+#define SCN_MAX_BUFFER_SIZE (CFG_MAX_NUM_BSS_LIST * ALIGN_4(sizeof(BSS_DESC_T))) -+ -+#define SCN_RM_POLICY_EXCLUDE_CONNECTED BIT(0) /* Remove SCAN result except the connected one. */ -+#define SCN_RM_POLICY_TIMEOUT BIT(1) /* Remove the timeout one */ -+#define SCN_RM_POLICY_OLDEST_HIDDEN BIT(2) /* Remove the oldest one with hidden ssid */ -+#define SCN_RM_POLICY_SMART_WEAKEST BIT(3) /* If there are more than half BSS which has the -+ * same ssid as connection setting, remove the -+ * weakest one from them -+ * Else remove the weakest one. -+ */ -+#define SCN_RM_POLICY_ENTIRE BIT(4) /* Remove entire SCAN result */ -+ -+#define SCN_BSS_DESC_SAME_SSID_THRESHOLD 3 /* This is used by POLICY SMART WEAKEST, -+ * If exceed this value, remove weakest BSS_DESC_T -+ * with same SSID first in large network. -+ */ -+ -+/* the scan time in WFD mode + 2.4G/5G is about 9s so we need to enlarge the value */ -+#define SCN_BSS_DESC_REMOVE_TIMEOUT_SEC 15 /* Second. */ -+ /* This is used by POLICY TIMEOUT, -+ * If exceed this value, remove timeout BSS_DESC_T. -+ */ -+ -+#define SCN_PROBE_DELAY_MSEC 0 -+ -+#define SCN_ADHOC_BSS_DESC_TIMEOUT_SEC 5 /* Second. */ -+ -+#define SCN_NLO_NETWORK_CHANNEL_NUM (4) -+ -+/*----------------------------------------------------------------------------*/ -+/* MSG_SCN_SCAN_REQ */ -+/*----------------------------------------------------------------------------*/ -+#define SCAN_REQ_SSID_WILDCARD BIT(0) -+#define SCAN_REQ_SSID_P2P_WILDCARD BIT(1) -+#define SCAN_REQ_SSID_SPECIFIED BIT(2) -+ -+/*----------------------------------------------------------------------------*/ -+/* Support Multiple SSID SCAN */ -+/*----------------------------------------------------------------------------*/ -+#define SCN_SSID_MAX_NUM CFG_SCAN_SSID_MAX_NUM -+#define SCN_SSID_MATCH_MAX_NUM CFG_SCAN_SSID_MATCH_MAX_NUM -+ -+#define SWC_NUM_BSSID_THRESHOLD_DEFAULT 8 -+#define SWC_RSSI_WINDSIZE_DEFAULT 8 -+#define LOST_AP_WINDOW 16 -+#define MAX_CHANNEL_NUM_PER_BUCKETS 8 -+ -+#define SCN_BSS_JOIN_FAIL_THRESOLD 4 -+#define SCN_BSS_JOIN_FAIL_CNT_RESET_SEC 15 -+#define SCN_BSS_JOIN_FAIL_RESET_STEP 2 -+ -+#if CFG_SUPPORT_BATCH_SCAN -+/*----------------------------------------------------------------------------*/ -+/* SCAN_BATCH_REQ */ -+/*----------------------------------------------------------------------------*/ -+#define SCAN_BATCH_REQ_START BIT(0) -+#define SCAN_BATCH_REQ_STOP BIT(1) -+#define SCAN_BATCH_REQ_RESULT BIT(2) -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_SCAN_TYPE_T { -+ SCAN_TYPE_PASSIVE_SCAN = 0, -+ SCAN_TYPE_ACTIVE_SCAN, -+ SCAN_TYPE_NUM -+} ENUM_SCAN_TYPE_T, *P_ENUM_SCAN_TYPE_T; -+ -+typedef enum _ENUM_SCAN_STATE_T { -+ SCAN_STATE_IDLE = 0, -+ SCAN_STATE_SCANNING, -+ SCAN_STATE_NUM -+} ENUM_SCAN_STATE_T; -+ -+typedef enum _ENUM_SCAN_CHANNEL_T { -+ SCAN_CHANNEL_FULL = 0, -+ SCAN_CHANNEL_2G4, -+ SCAN_CHANNEL_5G, -+ SCAN_CHANNEL_P2P_SOCIAL, -+ SCAN_CHANNEL_SPECIFIED, -+ SCAN_CHANNEL_NUM -+} ENUM_SCAN_CHANNEL, *P_ENUM_SCAN_CHANNEL; -+ -+typedef struct _MSG_SCN_FSM_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_32 u4Dummy; -+} MSG_SCN_FSM_T, *P_MSG_SCN_FSM_T; -+ -+typedef enum _ENUM_PSCAN_STATE_T { -+ PSCN_IDLE = 1, -+ PSCN_SCANNING, -+ PSCN_RESET, -+ PSCAN_STATE_T_NUM -+} ENUM_PSCAN_STATE_T; -+ -+/*----------------------------------------------------------------------------*/ -+/* BSS Descriptors */ -+/*----------------------------------------------------------------------------*/ -+struct _BSS_DESC_T { -+ LINK_ENTRY_T rLinkEntry; -+ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* For IBSS, the SrcAddr is different from BSSID */ -+ -+ BOOLEAN fgIsConnecting; /* If we are going to connect to this BSS -+ * (JOIN or ROAMING to another BSS), don't -+ * remove this record from BSS List. -+ */ -+ BOOLEAN fgIsConnected; /* If we have connected to this BSS (NORMAL_TR), -+ * don't removed this record from BSS list. -+ */ -+ -+ BOOLEAN fgIsHiddenSSID; /* When this flag is TRUE, means the SSID -+ * of this BSS is not known yet. -+ */ -+ UINT_8 ucSSIDLen; -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+ -+ OS_SYSTIME rUpdateTime; -+ -+ ENUM_BSS_TYPE_T eBSSType; -+ -+ UINT_16 u2CapInfo; -+ -+ UINT_16 u2BeaconInterval; -+ UINT_16 u2ATIMWindow; -+ -+ UINT_16 u2OperationalRateSet; -+ UINT_16 u2BSSBasicRateSet; -+ BOOLEAN fgIsUnknownBssBasicRate; -+ -+ BOOLEAN fgIsERPPresent; -+ BOOLEAN fgIsHTPresent; -+ -+ UINT_8 ucPhyTypeSet; /* Available PHY Type Set of this BSS */ -+ -+ UINT_8 ucChannelNum; -+ -+ ENUM_CHNL_EXT_T eSco; /* Record bandwidth for association process -+ Some AP will send association resp by 40MHz BW */ -+ ENUM_BAND_T eBand; -+ -+ UINT_8 ucDTIMPeriod; -+ -+ BOOLEAN fgIsLargerTSF; /* This BSS's TimeStamp is larger than us(TCL == 1 in RX_STATUS_T) */ -+ -+ UINT_8 ucRCPI; -+ -+ UINT_8 ucWmmFlag; /* A flag to indicate this BSS's WMM capability */ -+ -+ /*! \brief The srbiter Search State will matched the scan result, -+ and saved the selected cipher and akm, and report the score, -+ for arbiter join state, join module will carry this target BSS -+ to rsn generate ie function, for gen wpa/rsn ie */ -+ UINT_32 u4RsnSelectedGroupCipher; -+ UINT_32 u4RsnSelectedPairwiseCipher; -+ UINT_32 u4RsnSelectedAKMSuite; -+ -+ UINT_16 u2RsnCap; -+ -+ RSN_INFO_T rRSNInfo; -+ RSN_INFO_T rWPAInfo; -+#if 1 /* CFG_SUPPORT_WAPI */ -+ WAPI_INFO_T rIEWAPI; -+ BOOLEAN fgIEWAPI; -+#endif -+ BOOLEAN fgIERSN; -+ BOOLEAN fgIEWPA; -+ -+ /*! \brief RSN parameters selected for connection */ -+ /*! \brief The Select score for final AP selection, -+ 0, no sec, 1,2,3 group cipher is WEP, TKIP, CCMP */ -+ UINT_8 ucEncLevel; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgIsP2PPresent; -+ BOOLEAN fgIsP2PReport; /* TRUE: report to upper layer */ -+ P_P2P_DEVICE_DESC_T prP2pDesc; -+ -+ UINT_8 aucIntendIfAddr[MAC_ADDR_LEN]; /* For IBSS, the SrcAddr is different from BSSID */ -+/* UINT_8 ucDevCapabilityBitmap; */ /* Device Capability Attribute. (P2P_DEV_CAPABILITY_XXXX) */ -+/* UINT_8 ucGroupCapabilityBitmap; */ /* Group Capability Attribute. (P2P_GROUP_CAPABILITY_XXXX) */ -+ -+ LINK_T rP2pDeviceList; -+ -+/* P_LINK_T prP2pDeviceList; */ -+ -+ /* For -+ * 1. P2P Capability. -+ * 2. P2P Device ID. ( in aucSrcAddr[] ) -+ * 3. NOA (TODO:) -+ * 4. Extend Listen Timing. (Probe Rsp) (TODO:) -+ * 5. P2P Device Info. (Probe Rsp) -+ * 6. P2P Group Info. (Probe Rsp) -+ */ -+#endif -+ -+ BOOLEAN fgIsIEOverflow; /* The received IE length exceed the maximum IE buffer size */ -+ UINT_16 u2RawLength; /* The byte count of aucRawBuf[] */ -+ UINT_16 u2IELength; /* The byte count of aucIEBuf[] */ -+ -+ ULARGE_INTEGER u8TimeStamp; /* Place u8TimeStamp before aucIEBuf[1] to force DW align */ -+ UINT_8 aucRawBuf[CFG_RAW_BUFFER_SIZE]; -+ UINT_8 aucIEBuf[CFG_IE_BUFFER_SIZE]; -+ UINT_8 ucJoinFailureCount; -+ OS_SYSTIME rJoinFailTime; -+}; -+ -+typedef struct _SCAN_PARAM_T { /* Used by SCAN FSM */ -+ /* Active or Passive */ -+ ENUM_SCAN_TYPE_T eScanType; -+ -+ /* Network Type */ -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ -+ /* Specified SSID Type */ -+ UINT_8 ucSSIDType; -+ UINT_8 ucSSIDNum; -+ -+ /* Length of Specified SSID */ -+ UINT_8 ucSpecifiedSSIDLen[SCN_SSID_MAX_NUM]; -+ -+ /* Specified SSID */ -+ UINT_8 aucSpecifiedSSID[SCN_SSID_MAX_NUM][ELEM_MAX_LEN_SSID]; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgFindSpecificDev; /* P2P: Discovery Protocol */ -+ UINT_8 aucDiscoverDevAddr[MAC_ADDR_LEN]; -+ BOOLEAN fgIsDevType; -+ P2P_DEVICE_TYPE_T rDiscoverDevType; -+ -+ UINT_16 u2PassiveListenInterval; -+ /* TODO: Find Specific Device Type. */ -+#endif /* CFG_SUPPORT_P2P */ -+ -+ BOOLEAN fgIsObssScan; -+ BOOLEAN fgIsScanV2; -+ -+ /* Run time flags */ -+ UINT_16 u2ProbeDelayTime; -+ -+ /* channel information */ -+ ENUM_SCAN_CHANNEL eScanChannel; -+ UINT_8 ucChannelListNum; -+ RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ -+ /* Feedback information */ -+ UINT_8 ucSeqNum; -+ -+ /* Information Element */ -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+ -+} SCAN_PARAM_T, *P_SCAN_PARAM_T; -+ -+typedef struct _NLO_PARAM_T { /* Used by SCAN FSM */ -+ SCAN_PARAM_T rScanParam; -+ -+ /* NLO */ -+ BOOLEAN fgStopAfterIndication; -+ UINT_8 ucFastScanIteration; -+ UINT_16 u2FastScanPeriod; -+ UINT_16 u2SlowScanPeriod; -+ -+ /* Match SSID */ -+ UINT_8 ucMatchSSIDNum; -+ UINT_8 ucMatchSSIDLen[SCN_SSID_MATCH_MAX_NUM]; -+ UINT_8 aucMatchSSID[SCN_SSID_MATCH_MAX_NUM][ELEM_MAX_LEN_SSID]; -+ -+ UINT_8 aucCipherAlgo[SCN_SSID_MATCH_MAX_NUM]; -+ UINT_16 au2AuthAlgo[SCN_SSID_MATCH_MAX_NUM]; -+ UINT_8 aucChannelHint[SCN_SSID_MATCH_MAX_NUM][SCN_NLO_NETWORK_CHANNEL_NUM]; -+ P_BSS_DESC_T aprPendingBssDescToInd[SCN_SSID_MATCH_MAX_NUM]; -+} NLO_PARAM_T, *P_NLO_PARAM_T; -+ -+#if 1 -+ -+typedef struct _GSCN_CHANNEL_INFO_T { -+ UINT_8 ucBand; -+ UINT_8 ucChannel; /* frequency */ -+ UINT_8 ucPassive; /* 0 => active, 1 => passive scan; ignored for DFS */ -+ UINT_8 aucReserved[1]; -+ -+ UINT_32 u4DwellTimeMs; /* dwell time hint */ -+ /* Add channel class */ -+} GSCN_CHANNEL_INFO_T, *P_GSCN_CHANNEL_INFO_T; -+ -+typedef struct _GSCAN_CHANNEL_BUCKET_T { -+ -+ UINT_16 u2BucketIndex; /* bucket index, 0 based */ -+ UINT_8 ucBucketFreqMultiple; /* desired period, in millisecond; -+ * if this is too low, the firmware should choose to generate -+ * results as fast as it can instead of failing the command */ -+ /* report_events semantics - -+ * 0 => report only when scan history is % full -+ * 1 => same as 0 + report a scan completion event after scanning this bucket -+ * 2 => same as 1 + forward scan results (beacons/probe responses + IEs) in real time to HAL -+ * 3 => same as 2 + forward scan results (beacons/probe responses + IEs) in real time to -+ supplicant as well (optional) . */ -+ UINT_8 ucReportFlag; -+ UINT_8 ucNumChannels; -+ UINT_8 aucReserved[3]; -+ WIFI_BAND eBand; /* when UNSPECIFIED, use channel list */ -+ GSCN_CHANNEL_INFO_T arChannelList[GSCAN_MAX_CHANNELS]; /* channels to scan; these may include DFS channels */ -+} GSCAN_CHANNEL_BUCKET_T, *P_GSCAN_CHANNEL_BUCKET_T; -+ -+typedef struct _CMD_GSCN_REQ_T { -+ UINT_8 ucFlags; -+ UINT_8 ucNumScnToCache; -+ UINT_8 aucReserved[2]; -+ UINT_32 u4BufferThreshold; -+ UINT_32 u4BasePeriod; /* base timer period in ms */ -+ UINT_32 u4NumBuckets; -+ UINT_32 u4MaxApPerScan; /* number of APs to store in each scan in the */ -+ /* BSSID/RSSI history buffer (keep the highest RSSI APs) */ -+ -+ GSCAN_CHANNEL_BUCKET_T arChannelBucket[GSCAN_MAX_BUCKETS]; -+} CMD_GSCN_REQ_T, *P_CMD_GSCN_REQ_T; -+ -+#endif -+ -+typedef struct _CMD_GSCN_SCN_COFIG_T { -+ UINT_8 ucNumApPerScn; /* GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN */ -+ UINT_32 u4NumScnToCache; /* GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE */ -+ UINT_32 u4BufferThreshold; /* GSCAN_ATTRIBUTE_REPORT_THRESHOLD */ -+} CMD_GSCN_SCN_COFIG_T, *P_CMD_GSCN_SCN_COFIG_T; -+ -+typedef struct _CMD_GET_GSCAN_RESULT { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved[2]; -+ UINT_8 ucFlush; -+ UINT_32 u4Num; -+} CMD_GET_GSCAN_RESULT_T, *P_CMD_GET_GSCAN_RESULT_T; -+ -+typedef struct _CMD_BATCH_REQ_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucCmd; /* Start/ Stop */ -+ UINT_8 ucMScan; /* an integer number of scans per batch */ -+ UINT_8 ucBestn; /* an integer number of the max AP to remember per scan */ -+ UINT_8 ucRtt; /* an integer number of highest-strength AP for which we'd like -+ approximate distance reported */ -+ UINT_8 ucChannel; /* channels */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ UINT_8 aucReserved[3]; -+ UINT_32 u4Scanfreq; /* an integer number of seconds between scans */ -+ CHANNEL_INFO_T arChannelList[32]; /* channels */ -+} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T; -+ -+typedef struct _PSCN_PARAM_T { -+ UINT_8 ucVersion; -+ CMD_NLO_REQ rCurrentCmdNloReq; -+ CMD_BATCH_REQ_T rCurrentCmdBatchReq; -+ CMD_GSCN_REQ_T rCurrentCmdGscnReq; -+ BOOLEAN fgNLOScnEnable; -+ BOOLEAN fgBatchScnEnable; -+ BOOLEAN fgGScnEnable; -+ UINT_32 u4BasePeriod; /* GSCAN_ATTRIBUTE_BASE_PERIOD */ -+} PSCN_PARAM_T, *P_PSCN_PARAM_T; -+ -+typedef struct _SCAN_INFO_T { -+ ENUM_SCAN_STATE_T eCurrentState; /* Store the STATE variable of SCAN FSM */ -+ -+ OS_SYSTIME rLastScanCompletedTime; -+ -+ SCAN_PARAM_T rScanParam; -+ NLO_PARAM_T rNloParam; -+ -+ UINT_32 u4NumOfBssDesc; -+ -+ UINT_8 aucScanBuffer[SCN_MAX_BUFFER_SIZE]; -+ -+ LINK_T rBSSDescList; -+ -+ LINK_T rFreeBSSDescList; -+ -+ LINK_T rPendingMsgList; -+ -+ /* Sparse Channel Detection */ -+ BOOLEAN fgIsSparseChannelValid; -+ RF_CHANNEL_INFO_T rSparseChannel; -+ -+ /* NLO scanning state tracking */ -+ BOOLEAN fgNloScanning; -+ BOOLEAN fgPscnOnnning; -+ BOOLEAN fgGScnConfigSet; -+ BOOLEAN fgGScnParamSet; -+ P_PSCN_PARAM_T prPscnParam; -+ ENUM_PSCAN_STATE_T eCurrentPSCNState; -+ -+} SCAN_INFO_T, *P_SCAN_INFO_T; -+ -+/* Incoming Mailbox Messages */ -+typedef struct _MSG_SCN_SCAN_REQ_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ ENUM_SCAN_TYPE_T eScanType; -+ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ -+ UINT_8 ucSSIDLength; -+ UINT_8 aucSSID[PARAM_MAX_LEN_SSID]; -+#if CFG_ENABLE_WIFI_DIRECT -+ UINT_16 u2ChannelDwellTime; /* In TU. 1024us. */ -+#endif -+ ENUM_SCAN_CHANNEL eScanChannel; -+ UINT_8 ucChannelListNum; -+ RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} MSG_SCN_SCAN_REQ, *P_MSG_SCN_SCAN_REQ; -+ -+typedef struct _MSG_SCN_SCAN_REQ_V2_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ ENUM_SCAN_TYPE_T eScanType; -+ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ -+ UINT_8 ucSSIDNum; -+ P_PARAM_SSID_T prSsid; -+ UINT_16 u2ProbeDelay; -+ UINT_16 u2ChannelDwellTime; /* In TU. 1024us. */ -+ ENUM_SCAN_CHANNEL eScanChannel; -+ UINT_8 ucChannelListNum; -+ RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} MSG_SCN_SCAN_REQ_V2, *P_MSG_SCN_SCAN_REQ_V2; -+ -+typedef struct _MSG_SCN_SCAN_CANCEL_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgIsChannelExt; -+#endif -+} MSG_SCN_SCAN_CANCEL, *P_MSG_SCN_SCAN_CANCEL; -+ -+/* Outgoing Mailbox Messages */ -+typedef enum _ENUM_SCAN_STATUS_T { -+ SCAN_STATUS_DONE = 0, -+ SCAN_STATUS_CANCELLED, -+ SCAN_STATUS_FAIL, -+ SCAN_STATUS_BUSY, -+ SCAN_STATUS_NUM -+} ENUM_SCAN_STATUS, *P_ENUM_SCAN_STATUS; -+ -+typedef struct _MSG_SCN_SCAN_DONE_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ ENUM_SCAN_STATUS eScanStatus; -+} MSG_SCN_SCAN_DONE, *P_MSG_SCN_SCAN_DONE; -+ -+#if CFG_SUPPORT_AGPS_ASSIST -+typedef enum { -+ AGPS_PHY_A, -+ AGPS_PHY_B, -+ AGPS_PHY_G, -+} AP_PHY_TYPE; -+ -+typedef struct _AGPS_AP_INFO_T { -+ UINT_8 aucBSSID[6]; -+ INT_16 i2ApRssi; /* -127..128 */ -+ UINT_16 u2Channel; /* 0..256 */ -+ AP_PHY_TYPE ePhyType; -+} AGPS_AP_INFO_T, *P_AGPS_AP_INFO_T; -+ -+typedef struct _AGPS_AP_LIST_T { -+ UINT_8 ucNum; -+ AGPS_AP_INFO_T arApInfo[32]; -+} AGPS_AP_LIST_T, *P_AGPS_AP_LIST_T; -+#endif -+ -+typedef struct _CMD_SET_PSCAN_PARAM { -+ UINT_8 ucVersion; -+ CMD_NLO_REQ rCmdNloReq; -+ CMD_BATCH_REQ_T rCmdBatchReq; -+ CMD_GSCN_REQ_T rCmdGscnReq; -+ BOOLEAN fgNLOScnEnable; -+ BOOLEAN fgBatchScnEnable; -+ BOOLEAN fgGScnEnable; -+ UINT_32 u4BasePeriod; -+} CMD_SET_PSCAN_PARAM, *P_CMD_SET_PSCAN_PARAM; -+ -+typedef struct _CMD_SET_PSCAN_ADD_HOTLIST_BSSID { -+ UINT_8 aucMacAddr[6]; -+ UINT_8 ucFlags; -+ UINT_8 aucReserved[5]; -+} CMD_SET_PSCAN_ADD_HOTLIST_BSSID, *P_CMD_SET_PSCAN_ADD_HOTLIST_BSSID; -+ -+typedef struct _CMD_SET_PSCAN_ADD_SWC_BSSID { -+ INT_32 i4RssiLowThreshold; -+ INT_32 i4RssiHighThreshold; -+ UINT_8 aucMacAddr[6]; -+ UINT_8 aucReserved[6]; -+} CMD_SET_PSCAN_ADD_SWC_BSSID, *P_CMD_SET_PSCAN_ADD_SWC_BSSID; -+ -+typedef struct _CMD_SET_PSCAN_MAC_ADDR { -+ UINT_8 ucVersion; -+ UINT_8 ucFlags; -+ UINT_8 aucMacAddr[6]; -+ UINT_8 aucReserved[8]; -+} CMD_SET_PSCAN_MAC_ADDR, *P_CMD_SET_PSCAN_MAC_ADDR; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in scan.c */ -+/*----------------------------------------------------------------------------*/ -+VOID scnInit(IN P_ADAPTER_T prAdapter); -+ -+VOID scnUninit(IN P_ADAPTER_T prAdapter); -+ -+/* BSS-DESC Search */ -+P_BSS_DESC_T scanSearchBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); -+ -+P_BSS_DESC_T -+scanSearchBssDescByBssidAndSsid(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 aucBSSID[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid); -+ -+P_BSS_DESC_T scanSearchBssDescByTA(IN P_ADAPTER_T prAdapter, IN UINT_8 aucSrcAddr[]); -+ -+P_BSS_DESC_T -+scanSearchBssDescByTAAndSsid(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid); -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+P_BSS_DESC_T scanSearchBssDescByBssidAndLatestUpdateTime(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); -+#endif -+ -+/* BSS-DESC Search - Alternative */ -+P_BSS_DESC_T -+scanSearchExistingBssDesc(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BSS_TYPE_T eBSSType, IN UINT_8 aucBSSID[], IN UINT_8 aucSrcAddr[]); -+ -+P_BSS_DESC_T -+scanSearchExistingBssDescWithSsid(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BSS_TYPE_T eBSSType, -+ IN UINT_8 aucBSSID[], -+ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid); -+ -+/* BSS-DESC Allocation */ -+P_BSS_DESC_T scanAllocateBssDesc(IN P_ADAPTER_T prAdapter); -+ -+/* BSS-DESC Removal */ -+VOID scanRemoveBssDescsByPolicy(IN P_ADAPTER_T prAdapter, IN UINT_32 u4RemovePolicy); -+ -+VOID scanRemoveBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); -+ -+VOID -+scanRemoveBssDescByBandAndNetwork(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+/* BSS-DESC State Change */ -+VOID scanRemoveConnFlagOfBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); -+ -+#if 0 -+/* BSS-DESC Insertion */ -+P_BSS_DESC_T scanAddToInternalScanResult(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb, IN P_BSS_DESC_T prBssDesc); -+#endif -+ -+/* BSS-DESC Insertion - ALTERNATIVE */ -+P_BSS_DESC_T scanAddToBssDesc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS scanProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb); -+ -+VOID -+scanBuildProbeReqFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, -+ IN PUINT_8 pucDesiredSsid, IN UINT_32 u4DesiredSsidLen, IN UINT_16 u2SupportedRateSet); -+ -+WLAN_STATUS scanSendProbeReqFrames(IN P_ADAPTER_T prAdapter, IN P_SCAN_PARAM_T prScanParam); -+ -+VOID scanUpdateBssDescForSearch(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+P_BSS_DESC_T scanSearchBssDescByPolicy(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+WLAN_STATUS scanAddScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb); -+ -+VOID scanReportBss2Cfg80211(IN P_ADAPTER_T prAdapter, IN ENUM_BSS_TYPE_T eBSSType, IN P_BSS_DESC_T SpecificprBssDesc); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines in scan_fsm.c */ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_SCAN_STATE_T eNextState); -+ -+/*----------------------------------------------------------------------------*/ -+/* Command Routines */ -+/*----------------------------------------------------------------------------*/ -+VOID scnSendScanReqExtCh(IN P_ADAPTER_T prAdapter); -+ -+VOID scnSendScanReq(IN P_ADAPTER_T prAdapter); -+ -+VOID scnSendScanReqV2ExtCh(IN P_ADAPTER_T prAdapter); -+ -+VOID scnSendScanReqV2(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* RX Event Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID scnEventScanDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_SCAN_DONE prScanDone); -+ -+VOID scnEventNloDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_NLO_DONE_T prNloDone); -+ -+/*----------------------------------------------------------------------------*/ -+/* Mailbox Message Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmMsgStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID scnFsmMsgAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID scnFsmHandleScanMsg(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ prScanReqMsg); -+ -+VOID scnFsmHandleScanMsgV2(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ_V2 prScanReqMsg); -+ -+VOID scnFsmRemovePendingMsg(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex); -+ -+/*----------------------------------------------------------------------------*/ -+/* Mailbox Message Generation */ -+/*----------------------------------------------------------------------------*/ -+VOID -+scnFsmGenerateScanDoneMsg(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex, IN ENUM_SCAN_STATUS eScanStatus); -+ -+/*----------------------------------------------------------------------------*/ -+/* Query for sparse channel */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnQuerySparseChannel(IN P_ADAPTER_T prAdapter, P_ENUM_BAND_T prSparseBand, PUINT_8 pucSparseChannel); -+ -+/*----------------------------------------------------------------------------*/ -+/* OID/IOCTL Handling */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+scnFsmSchedScanRequest(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucSsidNum, -+ IN P_PARAM_SSID_T prSsid, IN UINT_32 u4IeLength, IN PUINT_8 pucIe, IN UINT_16 u2Interval); -+ -+BOOLEAN scnFsmSchedScanStopRequest(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN scnFsmPSCNAction(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPscanAct); -+ -+BOOLEAN scnFsmPSCNSetParam(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam); -+ -+BOOLEAN scnFsmGSCNSetHotlist(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam); -+ -+#if 0 -+ -+BOOLEAN scnFsmGSCNSetRssiSignificatn(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam); -+#endif -+ -+BOOLEAN scnFsmPSCNAddSWCBssId(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_SWC_BSSID prCmdPscnAddSWCBssId); -+ -+BOOLEAN scnFsmPSCNSetMacAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_MAC_ADDR prCmdPscnSetMacAddr); -+ -+#if 1 /* CFG_SUPPORT_GSCN_NONSYNC_BROADCOM */ -+BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam); -+ -+#else -+BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_REQ_T prCmdGscnParam); -+ -+#endif -+ -+BOOLEAN -+scnCombineParamsIntoPSCN(IN P_ADAPTER_T prAdapter, -+ IN P_CMD_NLO_REQ prCmdNloReq, -+ IN P_CMD_BATCH_REQ_T prCmdBatchReq, -+ IN P_CMD_GSCN_REQ_T prCmdGscnReq, -+ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, -+ IN BOOLEAN fgRemoveNLOfromPSCN, -+ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN); -+ -+BOOLEAN scnFsmSetGSCNConfig(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_SCN_COFIG_T prCmdGscnScnConfig); -+ -+BOOLEAN scnFsmGetGSCNResult(IN P_ADAPTER_T prAdapter, IN P_CMD_GET_GSCAN_RESULT_T prGetGscnScnResultCmd); -+ -+VOID -+scnPSCNFsm(IN P_ADAPTER_T prAdapter, -+ ENUM_PSCAN_STATE_T eNextPSCNState, -+ IN P_CMD_NLO_REQ prCmdNloReq, -+ IN P_CMD_BATCH_REQ_T prCmdBatchReq, -+ IN P_CMD_GSCN_REQ_T prCmdGscnReq, -+ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, -+ IN BOOLEAN fgRemoveNLOfromPSCN, -+ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN, IN BOOLEAN fgEnableGSCN); -+ -+#endif /* _SCAN_H */ -+ -+#if CFG_SUPPORT_AGPS_ASSIST -+VOID scanReportScanResultToAgps(P_ADAPTER_T prAdapter); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h -new file mode 100644 -index 0000000000000..c6c468e06c4a5 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h -@@ -0,0 +1,233 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/sec_fsm.h#1 -+*/ -+ -+/*! \file sec_fsm.h -+ \brief Declaration of functions and finite state machine for SECURITY Module. -+ -+ Function declaration for privacy.c and SEC_STATE for SECURITY FSM. -+*/ -+ -+/* -+** Log: sec_fsm.h -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 20 2010 wh.su -+ * NULL -+ * adding the eapol callback setting. -+ * -+ * 08 19 2010 wh.su -+ * NULL -+ * adding the tx pkt call back handle for countermeasure. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 03 04 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Code refine, and remove non-used code. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, and modify the security -+ * related callback function prototype. -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Refine the variable and parameter for security. -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * fixed the deauth Tx done callback parameter -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the reference function declaration -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * delete non-used code -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function prototype -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function declaration -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the security variable -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** \main\maintrunk.MT5921\14 2009-04-06 15:35:47 GMT mtk01088 -+** add the variable to set the disable AP selection for privacy check, for wps open networking. -+** \main\maintrunk.MT5921\13 2008-11-19 11:46:01 GMT mtk01088 -+** rename some variable with pre-fix to avoid the misunderstanding -+** \main\maintrunk.MT5921\12 2008-08-28 20:37:11 GMT mtk01088 -+** remove non-used code -+** -+** \main\maintrunk.MT5921\11 2008-03-18 09:51:52 GMT mtk01088 -+** Add function declaration for timer to indicate pmkid candidate -+** \main\maintrunk.MT5921\10 2008-02-29 15:12:08 GMT mtk01088 -+** add variable for sw port control -+** \main\maintrunk.MT5921\9 2008-02-29 12:37:30 GMT mtk01088 -+** rename the security related function declaration -+** \main\maintrunk.MT5921\8 2007-12-27 13:59:08 GMT mtk01088 -+** adjust the wlan table and sec fsm init timing -+** \main\maintrunk.MT5921\7 2007-11-20 10:39:49 GMT mtk01088 -+** add function timer for wait EAPoL Error timeout -+** \main\maintrunk.MT5921\6 2007-11-06 20:39:08 GMT mtk01088 -+** rename the counter measure timer -+** \main\maintrunk.MT5921\5 2007-11-06 20:14:31 GMT mtk01088 -+** add a abort function -+** Revision 1.5 2007/07/16 02:33:42 MTK01088 -+** change the ENUM declaration structure prefix from r to e -+** -+** Revision 1.4 2007/07/09 06:23:10 MTK01088 -+** update -+** -+** Revision 1.3 2007/07/04 10:09:04 MTK01088 -+** adjust the state for security fsm -+** change function name -+** -+** Revision 1.2 2007/07/03 08:13:22 MTK01088 -+** change the sec fsm state -+** add the event for sec fsm -+** -+** Revision 1.1 2007/06/27 06:20:35 MTK01088 -+** add the sec fsm header file -+** -+** -+*/ -+#ifndef _SEC_FSM_H -+#define _SEC_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* TKIP CounterMeasure interval for Rejoin to Network. */ -+#define COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC 60 -+ -+/* Timeout to wait the EAPoL Error Report frame Send out. */ -+#define EAPOL_REPORT_SEND_TIMEOUT_INTERVAL_SEC 1 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef UINT_32 SEC_STATUS, *P_SEC_STATUS; -+ -+#if 0 -+/* WPA2 PMKID candicate structure */ -+typedef struct _PMKID_CANDICATE_T { -+ UINT_8 aucBssid[MAC_ADDR_LEN]; /* MAC address */ -+ UINT_32 u4PreAuthFlags; -+} PMKID_CANDICATE_T, *P_PMKID_CANDICATE_T; -+#endif -+ -+typedef SEC_STATUS(*PFN_SEC_FSM_STATE_HANDLER) (VOID); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define SEC_STATE_TRANSITION_FLAG fgIsTransition -+#define SEC_NEXT_STATE_VAR eNextState -+ -+#define SEC_STATE_TRANSITION(prAdapter, prSta, eFromState, eToState) \ -+ { secFsmTrans_ ## eFromState ## _to_ ## eToState(prAdapter, prSta); \ -+ SEC_NEXT_STATE_VAR = SEC_STATE_ ## eToState; \ -+ SEC_STATE_TRANSITION_FLAG = (BOOLEAN)TRUE; \ -+ } -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/*--------------------------------------------------------------*/ -+/* Routines to handle the sec check */ -+/*--------------------------------------------------------------*/ -+/***** Routines in sec_fsm.c *****/ -+VOID secFsmInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEventInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEventStart(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEventAbort(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+BOOLEAN secFsmEventPTKInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEvent2ndEapolTx(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEvent4ndEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID -+secFsmEventEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID secFsmEventEapolTxTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParm); -+ -+VOID -+secFsmEventDeauthTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID secFsmEventStartCounterMeasure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEventEndOfCounterMeasure(IN P_ADAPTER_T prAdapter, IN ULONG ulParm); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _SEC_FSM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h -new file mode 100644 -index 0000000000000..1c0f9a76e1192 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h -@@ -0,0 +1,368 @@ -+/* -+** Id: stats.h#1 -+*/ -+ -+/*! \file stats.h -+ \brief This file includes statistics support. -+*/ -+ -+/* -+** Log: stats.h -+ * -+ * 07 17 2014 samp.lin -+ * NULL -+ * Initial version. -+ */ -+ -+/******************************************************************************* -+ * C O M P I L E R F L A G S -+ ******************************************************************************** -+ */ -+ -+/******************************************************************************* -+ * E X T E R N A L R E F E R E N C E S -+ ******************************************************************************** -+ */ -+extern UINT_64 u8DrvOwnStart, u8DrvOwnEnd; -+extern UINT32 u4DrvOwnMax; -+extern BOOLEAN fgIsUnderSuspend; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* Command to TDLS core module */ -+typedef enum _STATS_CMD_CORE_ID { -+ STATS_CORE_CMD_ENV_REQUEST = 0x00 -+} STATS_CMD_CORE_ID; -+ -+typedef enum _STATS_EVENT_HOST_ID { -+ STATS_HOST_EVENT_ENV_REPORT = 0x00, -+ STATS_HOST_EVENT_RX_DROP -+} STATS_EVENT_HOST_ID; -+ -+#define CFG_ARP BIT(0) -+#define CFG_DNS BIT(1) -+#define CFG_TCP BIT(2) -+#define CFG_UDP BIT(3) -+#define CFG_EAPOL BIT(4) -+#define CFG_DHCP BIT(5) -+#define CFG_ICMP BIT(6) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _STATS_CMD_CORE_T { -+ -+ UINT32 u4Command; /* STATS_CMD_CORE_ID */ -+ -+ UINT8 ucStaRecIdx; -+ UINT8 ucReserved[3]; -+ -+ UINT32 u4Reserved[4]; -+ -+#define STATS_CMD_CORE_RESERVED_SIZE 50 -+ union { -+ UINT8 Reserved[STATS_CMD_CORE_RESERVED_SIZE]; -+ } Content; -+ -+} STATS_CMD_CORE_T; -+ -+typedef struct _STATS_INFO_ENV_T { -+ -+ BOOLEAN fgIsUsed; /* TRUE: used */ -+ -+ /* ------------------- TX ------------------- */ -+ BOOLEAN fgTxIsRtsUsed; /* TRUE: we use RTS/CTS currently */ -+ BOOLEAN fgTxIsRtsEverUsed; /* TRUE: we ever use RTS/CTS */ -+ BOOLEAN fgTxIsCtsSelfUsed; /* TRUE: we use CTS-self */ -+ -+#define STATS_INFO_TX_PARAM_HW_BW40_OFFSET 0 -+#define STATS_INFO_TX_PARAM_HW_SHORT_GI20_OFFSET 1 -+#define STATS_INFO_TX_PARAM_HW_SHORT_GI40_OFFSET 2 -+#define STATS_INFO_TX_PARAM_USE_BW40_OFFSET 3 -+#define STATS_INFO_TX_PARAM_USE_SHORT_GI_OFFSET 4 -+#define STATS_INFO_TX_PARAM_NO_ACK_OFFSET 5 -+ UINT_8 ucTxParam; -+ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucReserved1[2]; -+ -+ UINT32 u4TxDataCntAll; /* total tx count from host */ -+ UINT32 u4TxDataCntOK; /* total tx ok count to air */ -+ UINT32 u4TxDataCntErr; /* total tx err count to air */ -+ -+ /* WLAN_STATUS_BUFFER_RETAINED ~ WLAN_STATUS_PACKET_LIFETIME_ERROR */ -+ UINT32 u4TxDataCntErrType[6]; /* total tx err count for different type to air */ -+ -+ UINT_8 ucTxRate1NonHTMax; -+ UINT_8 ucTxRate1HTMax; -+ UINT32 u4TxRateCntNonHT[16]; /* tx done rate */ -+ UINT32 u4TxRateCntHT[16]; /* tx done rate */ -+ -+ UINT_8 ucTxAggBitmap; /* TX BA sessions TID0 ~ TID7 */ -+ UINT_8 ucTxPeerAggMaxSize; -+ -+ /* ------------------- RX ------------------- */ -+ BOOLEAN fgRxIsRtsUsed; /* TRUE: peer uses RTS/CTS currently */ -+ BOOLEAN fgRxIsRtsEverUsed; /* TRUE: peer ever uses RTS/CTS */ -+ -+ UINT_8 ucRcvRcpi; -+ UINT_8 ucHwChanNum; -+ BOOLEAN fgRxIsShortGI; -+ UINT_8 ucReserved2[1]; -+ -+ UINT32 u4RxDataCntAll; /* total rx count from peer */ -+ UINT32 u4RxDataCntErr; /* total rx err count */ -+ UINT32 u4RxRateCnt[3][16]; /* [0]:CCK, [1]:OFDM, [2]:MIXED (skip green mode) */ -+ -+ UINT_8 ucRxAggBitmap; /* RX BA sessions TID0 ~ TID7 */ -+ UINT_8 ucRxAggMaxSize; -+ -+#define STATS_INFO_PHY_MODE_CCK 0 -+#define STATS_INFO_PHY_MODE_OFDM 1 -+#define STATS_INFO_PHY_MODE_HT 2 -+#define STATS_INFO_PHY_MODE_VHT 3 -+ UINT_8 ucBssSupPhyMode; /* CCK, OFDM, HT, or VHT BSS */ -+ -+ UINT_8 ucVersion; /* the version of statistics info environment */ -+ -+ /* ------------------- Delay ------------------- */ -+#define STATS_AIR_DELAY_INT 500 /* 500 byte */ -+ -+ /* delay in firmware from host to MAC */ -+ /* unit: us, for 500B, 1000B, max */ -+ UINT32 u4StayIntMaxH2M[3], u4StayIntMinH2M[3], u4StayIntAvgH2M[3]; -+ -+ /* delay in firmware from MAC to TX done */ -+ /* unit: 32us, for 500B, 1000B, max */ -+ UINT32 u4AirDelayMax[3], u4AirDelayMin[3], u4AirDelayAvg[3]; -+ -+ /* delay in firmware from host to TX done */ -+ /* unit: us, for 500B, 1000B, max */ -+ UINT32 u4StayIntMax[3], u4StayIntMin[3], u4StayIntAvg[3]; -+ UINT32 u4StayIntMaxSysTime[3]; -+ -+ /* delay in firmware from driver to TX done */ -+ /* unit: us, for 500B, 1000B, max */ -+ UINT32 u4StayIntMaxD2T[3], u4StayIntMinD2T[3], u4StayIntAvgD2T[3]; -+ -+ /* delay count in firmware from host to TX done */ -+ /* u4StayIntByConst: divide 4 fix partitions to count each delay in firmware */ -+#define STATS_STAY_INT_CONST 1 /* 1ms */ -+#define STATS_STAY_INT_CONST_2 5 -+#define STATS_STAY_INT_CONST_3 10 -+#define STATS_STAY_INT_CONST_4 15 -+#define STATS_STAY_INT_CONST_NUM 4 -+ UINT32 u4StayIntByConst[STATS_STAY_INT_CONST_NUM]; -+ -+ /* -+ u4StayIntMaxPast: past maximum delay in firmware -+ u4StayIntCnt[]: divide 4 partitions to count each delay in firmware -+ */ -+#define STATS_STAY_INT_NUM 4 -+ UINT32 u4StayIntMaxPast; -+ UINT32 u4StayIntCnt[STATS_STAY_INT_NUM + 1]; -+ -+ /* delay count in firmware from driver to HIF */ -+ /* u4StayIntD2HByConst: divide 4 fix partitions to count each delay in firmware */ -+#define STATS_STAY_INT_D2H_CONST 10 /* 10ms */ -+#define STATS_STAY_INT_D2H_CONST_2 20 -+#define STATS_STAY_INT_D2H_CONST_3 30 -+#define STATS_STAY_INT_D2H_CONST_4 40 -+#define STATS_STAY_INT_D2H_CONST_NUM 4 -+ UINT32 u4StayIntD2HByConst[STATS_STAY_INT_D2H_CONST_NUM]; -+ -+ /* unit: us, for 500B, 1000B, max */ -+ UINT32 u4StayIntMaxRx[3], u4StayIntMinRx[3], u4StayIntAvgRx[3]; -+ -+ /* ------------------- Others ------------------- */ -+ UINT32 u4NumOfChanChange; /* total channel change count */ -+ UINT32 u4NumOfRetryCnt; /* total TX retry count */ -+ UINT32 u4RxFifoFullCnt; /* counter of the number of the packets which -+ pass RFCR but are dropped due to FIFO full. */ -+ UINT32 u4PsIntMax; /* maximum time from ps to active */ -+ UINT_8 ucNumOfPsChange; /* peer power save change count */ -+ UINT_8 ucReserved3[3]; -+ -+ UINT32 u4ReportSysTime; /* firmware system time */ -+ UINT32 u4RxDataCntOk; /* total rx count to hif */ -+ -+ /* V4 */ -+ UINT32 u4RxRateRetryCnt[3][16]; /* [0]:CCK, [1]:OFDM, [2]:MIXED (skip green mode) */ -+ UINT32 au4ChanIdleCnt[10]; /* past Channel idle count in unit of slot */ -+ -+ /* V5 */ -+ UINT32 u4BtContUseTime; /* the air time that BT continuous occypy */ -+ -+ /* V6 */ -+ UINT32 u4LastTxOkTime; /* last time we tx ok to the station */ -+ -+ /* V7 */ -+ UINT_8 ucBtWfCoexGrantCnt[8]; /* [0]:WF Rx Grant Cnt[1]: WF Tx Grant Cnt[2]: WF Grant with Priority1 */ -+ /* [4]:BT Rx Grant Cnt[5]: BT Tx Grant Cnt[6]: BT Grant with Priority1 */ -+ -+ /* V8 */ -+ UINT_32 u4RxMacFreeDescCnt[6]; -+ UINT_32 u4RxHifFreeDescCnt[6]; -+ -+ /* V9 */ -+#define STATS_MAX_RX_DROP_TYPE 20 -+ UINT32 u4NumOfRxDrop[STATS_MAX_RX_DROP_TYPE]; -+ -+ /* V10 */ -+ UINT_32 u4NumOfTxDone; /* number of all packets (data/man/ctrl) tx done */ -+ UINT_32 u4NumOfTxDoneFixRate; /* number of done rate = 0 */ -+ UINT_32 u4NumOfTxDoneErrRate; /* number of error done rate */ -+ UINT_32 u4NumOfNullTxDone; /* number of null tx done */ -+ UINT_32 u4NumOfQoSNullTxDone; /* number of QoS-null tx done */ -+ -+ /* V11 */ -+ /* delay in firmware from HIF RX to HIF RX Done */ -+ /* unit: us, for 500B, 1000B, max */ -+ UINT32 u4StayIntMaxHR2HRD[3], u4StayIntMinHR2HRD[3], u4StayIntAvgHR2HRD[3]; -+ -+ /* V12 */ -+ UINT32 u4AirDelayTotal; /* agg all the air delay */ -+ -+ /* V13 */ -+ UINT32 u4CurrChnlInfo; /* add current channel information */ -+ -+ UINT_8 ucReserved_rate[4]; /* the field must be the last one */ -+} STATS_INFO_ENV_T; -+ -+/******************************************************************************* -+* M A C R O D E C L A R A T I O N S -+******************************************************************************** -+*/ -+#if (CFG_SUPPORT_STATISTICS == 1) -+ -+#define STATS_ENV_REPORT_DETECT statsEnvReportDetect -+ -+#define STATS_RX_REORDER_FALL_AHEAD_INC(__StaRec__) \ -+{ \ -+ (__StaRec__)->u4RxReorderFallAheadCnt++; \ -+} -+ -+#define STATS_RX_REORDER_FALL_BEHIND_INC(__StaRec__) \ -+{ \ -+ (__StaRec__)->u4RxReorderFallBehindCnt++; \ -+} -+ -+#define STATS_RX_REORDER_HOLE_INC(__StaRec__) \ -+{ \ -+ (__StaRec__)->u4RxReorderHoleCnt++; \ -+} -+ -+#define STATS_RX_REORDER_HOLE_TIMEOUT_INC(__StaRec__, __IsTimeout__) \ -+{ \ -+ if ((__IsTimeout__) == TRUE) \ -+ (__StaRec__)->u4RxReorderHoleTimeoutCnt++; \ -+} -+ -+#define STATS_RX_ARRIVE_TIME_RECORD(__SwRfb__) \ -+{ \ -+ (__SwRfb__)->rRxTime = StatsEnvTimeGet(); \ -+} -+ -+#define STATS_RX_PASS2OS_INC StatsEnvRxDone -+ -+#define STATS_RX_PKT_INFO_DISPLAY StatsRxPktInfoDisplay -+ -+#define STATS_TX_TIME_ARRIVE(__Skb__) \ -+do { \ -+ UINT_64 __SysTime; \ -+ __SysTime = StatsEnvTimeGet(); /* us */ \ -+ GLUE_SET_PKT_XTIME(__Skb__, __SysTime); \ -+} while (FALSE) -+ -+#define STATS_TX_TIME_TO_HIF StatsEnvTxTime2Hif -+ -+#define STATS_TX_PKT_CALLBACK StatsTxPktCallBack -+#define STATS_TX_PKT_DONE_INFO_DISPLAY StatsTxPktDoneInfoDisplay -+ -+#define STATS_DRIVER_OWN_RESET() \ -+{ \ -+ u4DrvOwnMax = 0; \ -+} -+#define STATS_DRIVER_OWN_START_RECORD() \ -+{ \ -+ u8DrvOwnStart = StatsEnvTimeGet(); \ -+} -+#define STATS_DRIVER_OWN_END_RECORD() \ -+{ \ -+ u8DrvOwnEnd = StatsEnvTimeGet(); \ -+} -+#define STATS_DRIVER_OWN_STOP() \ -+do { \ -+ UINT32 __Diff; \ -+ __Diff = (UINT32)(u8DrvOwnEnd - u8DrvOwnStart); \ -+ if (__Diff > u4DrvOwnMax) \ -+ u4DrvOwnMax = __Diff; \ -+} while (FALSE) -+ -+#else -+ -+#define STATS_ENV_REPORT_DETECT(__Adapter__, __StaRecIndex__) -+ -+#define STATS_RX_REORDER_FALL_AHEAD_INC(__StaRec__) -+#define STATS_RX_REORDER_FALL_BEHIND_INC(__StaRec__) -+#define STATS_RX_REORDER_HOLE_INC(__StaRec__) -+#define STATS_RX_REORDER_HOLE_TIMEOUT_INC(__StaRec__, __IsTimeout__) -+#define STATS_RX_PASS2OS_INC(__StaRec__, __SwRfb__) -+#define STATS_RX_PKT_INFO_DISPLAY(__Pkt__) -+ -+#define STATS_TX_TIME_ARRIVE(__Skb__) -+#define STATS_TX_TIME_TO_HIF(__MsduInfo__, __HwTxHeader__) -+#define STATS_TX_PKT_CALLBACK(__Pkt__, __fgIsNeedAck__) -+#define STATS_TX_PKT_DONE_INFO_DISPLAY(__Adapter__, __Event__) -+ -+#define STATS_DRIVER_OWN_RESET() -+#define STATS_DRIVER_OWN_START_RECORD() -+#define STATS_DRIVER_OWN_END_RECORD() -+#define STATS_DRIVER_OWN_STOP() -+#endif /* CFG_SUPPORT_STATISTICS */ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C F U N C T I O N S -+******************************************************************************** -+*/ -+ -+VOID statsEnvReportDetect(ADAPTER_T *prAdapter, UINT8 ucStaRecIndex); -+ -+VOID StatsEnvRxDone(STA_RECORD_T *prStaRec, SW_RFB_T *prSwRfb); -+ -+UINT_64 StatsEnvTimeGet(VOID); -+ -+VOID StatsEnvTxTime2Hif(MSDU_INFO_T *prMsduInfo, HIF_TX_HEADER_T *prHwTxHeader); -+ -+VOID statsEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); -+ -+VOID StatsRxPktInfoDisplay(UINT_8 *pPkt); -+ -+VOID StatsTxPktCallBack(UINT_8 *pPkt, P_MSDU_INFO_T prMsduInfo); -+ -+VOID StatsTxPktDoneInfoDisplay(ADAPTER_T *prAdapter, UINT_8 *pucEvtBuf); -+ -+VOID StatsSetCfgTxDone(UINT_16 u2Cfg, BOOLEAN fgSet); -+ -+UINT_16 StatsGetCfgTxDone(VOID); -+ -+/* End of stats.h */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h -new file mode 100644 -index 0000000000000..50c4b558c2cd5 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h -@@ -0,0 +1,187 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/swcr.h#1 -+*/ -+ -+/*! \file "swcr.h" -+ \brief -+*/ -+ -+/* -+ * -+ */ -+ -+#ifndef _SWCR_H -+#define _SWCR_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "nic_cmd_event.h" -+ -+#if 0 -+extern SWCR_MAP_ENTRY_T g_arRlmArSwCrMap[]; -+#endif -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define SWCR_VAR(x) ((VOID *)&x) -+#define SWCR_FUNC(x) ((VOID *)x) -+ -+#define SWCR_T_FUNC BIT(7) -+ -+#define SWCR_L_32 3 -+#define SWCR_L_16 2 -+#define SWCR_L_8 1 -+ -+#define SWCR_READ 0 -+#define SWCR_WRITE 1 -+ -+#define SWCR_MAP_NUM(x) (sizeof(x)/sizeof(x[0])) -+ -+#define SWCR_CR_NUM 7 -+ -+#define SWCR_GET_RW_INDEX(action, rw, index) \ -+do { \ -+ index = action & 0x7F; \ -+ rw = action >> 7; \ -+} while (0) -+ -+extern UINT_32 g_au4SwCr[]; /*: 0: command other: data */ -+ -+typedef VOID(*PFN_SWCR_RW_T) (P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data); -+typedef VOID(*PFN_CMD_RW_T) (P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+ -+typedef struct _SWCR_MAP_ENTRY_T { -+ UINT_16 u2Type; -+ PVOID u4Addr; -+} SWCR_MAP_ENTRY_T, *P_SWCR_MAP_ENTRY_T; -+ -+typedef struct _SWCR_MOD_MAP_ENTRY_T { -+ UINT_8 ucMapNum; -+ P_SWCR_MAP_ENTRY_T prSwCrMap; -+} SWCR_MOD_MAP_ENTRY_T, *P_SWCR_MOD_MAP_ENTRY_T; -+ -+typedef enum _ENUM_SWCR_DBG_TYPE_T { -+ SWCR_DBG_TYPE_ALL = 0, -+ SWCR_DBG_TYPE_TXRX, -+ SWCR_DBG_TYPE_RX_RATES, -+ SWCR_DBG_TYPE_PS, -+ SWCR_DBG_TYPE_NUM -+} ENUM_SWCR_DBG_TYPE_T; -+ -+typedef enum _ENUM_SWCR_DBG_ALL_T { -+ SWCR_DBG_ALL_TX_CNT = 0, -+ SWCR_DBG_ALL_TX_BCN_CNT, -+ SWCR_DBG_ALL_TX_FAILED_CNT, -+ SWCR_DBG_ALL_TX_RETRY_CNT, -+ SWCR_DBG_ALL_TX_AGING_TIMEOUT_CNT, -+ SWCR_DBG_ALL_TX_PS_OVERFLOW_CNT, -+ SWCR_DBG_ALL_TX_MGNT_DROP_CNT, -+ SWCR_DBG_ALL_TX_ERROR_CNT, -+ -+ SWCR_DBG_ALL_RX_CNT, -+ SWCR_DBG_ALL_RX_DROP_CNT, -+ SWCR_DBG_ALL_RX_DUP_DROP_CNT, -+ SWCR_DBG_ALL_RX_TYPE_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_CLASS_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_AMPDU_ERROR_DROP_CNT, -+ -+ SWCR_DBG_ALL_RX_STATUS_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_FORMAT_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_ICV_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_KEY_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_TKIP_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_MIC_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_BIP_ERROR_DROP_CNT, -+ -+ SWCR_DBG_ALL_RX_FCSERR_CNT, -+ SWCR_DBG_ALL_RX_FIFOFULL_CNT, -+ SWCR_DBG_ALL_RX_PFDROP_CNT, -+ -+ SWCR_DBG_ALL_PWR_PS_POLL_CNT, -+ SWCR_DBG_ALL_PWR_TRIGGER_NULL_CNT, -+ SWCR_DBG_ALL_PWR_BCN_IND_CNT, -+ SWCR_DBG_ALL_PWR_BCN_TIMEOUT_CNT, -+ SWCR_DBG_ALL_PWR_PM_STATE0, -+ SWCR_DBG_ALL_PWR_PM_STATE1, -+ SWCR_DBG_ALL_PWR_CUR_PS_PROF0, -+ SWCR_DBG_ALL_PWR_CUR_PS_PROF1, -+ -+ SWCR_DBG_ALL_AR_STA0_RATE, -+ SWCR_DBG_ALL_AR_STA0_BWGI, -+ SWCR_DBG_ALL_AR_STA0_RX_RATE_RCPI, -+ -+ SWCR_DBG_ALL_ROAMING_ENABLE, -+ SWCR_DBG_ALL_ROAMING_ROAM_CNT, -+ SWCR_DBG_ALL_ROAMING_INT_CNT, -+ -+ SWCR_DBG_ALL_BB_RX_MDRDY_CNT, -+ SWCR_DBG_ALL_BB_RX_FCSERR_CNT, -+ SWCR_DBG_ALL_BB_CCK_PD_CNT, -+ SWCR_DBG_ALL_BB_OFDM_PD_CNT, -+ SWCR_DBG_ALL_BB_CCK_SFDERR_CNT, -+ SWCR_DBG_ALL_BB_CCK_SIGERR_CNT, -+ SWCR_DBG_ALL_BB_OFDM_TAGERR_CNT, -+ SWCR_DBG_ALL_BB_OFDM_SIGERR_CNT, -+ -+ SWCR_DBG_ALL_NUM -+} ENUM_SWCR_DBG_ALL_T; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID swCtrlCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+VOID swCtrlCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+VOID testPsCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+VOID testPsCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+void testWNMCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+VOID swCtrlSwCr(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data); -+ -+/* Support Debug */ -+VOID swCrDebugCheck(P_ADAPTER_T prAdapter, P_CMD_SW_DBG_CTRL_T prCmdSwCtrl); -+VOID swCrDebugCheckTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+VOID swCrDebugQuery(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+VOID swCrDebugQueryTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+VOID swCrReadWriteCmd(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data); -+ -+/* Debug Support */ -+VOID swCrFrameCheckEnable(P_ADAPTER_T prAdapter, UINT_32 u4DumpType); -+VOID swCrDebugInit(P_ADAPTER_T prAdapter); -+VOID swCrDebugCheckEnable(P_ADAPTER_T prAdapter, BOOLEAN fgIsEnable, UINT_8 ucType, UINT_32 u4Timeout); -+VOID swCrDebugUninit(P_ADAPTER_T prAdapter); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h -new file mode 100644 -index 0000000000000..3b6991131d058 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h -@@ -0,0 +1,262 @@ -+/* -+** Id: include/tdls.h#1 -+*/ -+ -+/*! \file "tdls.h" -+ \brief This file contains the internal used in TDLS modules -+ for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: tdls.h -+ * -+ * 11 18 2013 vend_samp.lin -+ * NULL -+ * Initial version. -+ * -+ ** -+ */ -+ -+#ifndef _TDLS_H -+#define _TDLS_H -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#define TDLS_CFG_CMD_TEST 1 -+#define TDLS_CFG_HT_SUP 1 -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev); -+extern BOOLEAN flgTdlsTestExtCapElm; -+extern UINT8 aucTdlsTestExtCapElm[]; -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+typedef struct _TDLS_LINK_HIS_OTHERS_T { -+ BOOLEAN fgIsHt; /* TRUE: HT device */ -+ -+} TDLS_LINK_HIS_OTHERS_T; -+ -+/* command */ -+typedef enum _TDLS_CMD_ID { -+ TDLS_CMD_TEST_TX_FRAME = 0x00, -+ TDLS_CMD_TEST_RCV_FRAME = 0x01, -+ TDLS_CMD_TEST_PEER_ADD = 0x02, -+ TDLS_CMD_TEST_PEER_UPDATE = 0x03, -+ TDLS_CMD_TEST_DATA_FRAME = 0x04, -+ TDLS_CMD_TEST_RCV_NULL = 0x05, -+ TDLS_CMD_MIB_UPDATE = 0x06, -+ TDLS_CMD_TEST_SKIP_TX_FAIL = 0x07, -+ TDLS_CMD_UAPSD_CONF = 0x08, -+ TDLS_CMD_CH_SW_CONF = 0x09, -+ TDLS_CMD_TEST_SKIP_KEEP_ALIVE = 0x0a, -+ TDLS_CMD_TEST_SKIP_CHSW_TIMEOUT = 0x0b, -+ TDLS_CMD_TEST_TX_TDLS_FRAME = 0x0c, -+ TDLS_CMD_TEST_PROHIBIT_SET_IN_AP = 0x0d, -+ TDLS_CMD_TEST_SCAN_DISABLE = 0x0e, -+ TDLS_CMD_TEST_DATA_FRAME_CONT = 0x0f, -+ TDLS_CMD_TEST_CH_SW_PROHIBIT_SET_IN_AP = 0x10, -+ TDLS_CMD_SETUP_CONF = 0x11, -+ TDLS_CMD_INFO = 0x12, -+ TDLS_CMD_TEST_DELAY = 0x13, -+ TDLS_CMD_KEY_INFO = 0x14, -+ TDLS_CMD_TEST_PTI_TX_FAIL = 0x15 -+} TDLS_CMD_ID; -+ -+typedef enum _TDLS_EVENT_HOST_ID { -+ TDLS_HOST_EVENT_TEAR_DOWN = 0x00, /* TDLS_EVENT_HOST_SUBID_TEAR_DOWN */ -+ TDLS_HOST_EVENT_TX_DONE, -+ TDLS_HOST_EVENT_FME_STATUS, /* TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME */ -+ TDLS_HOST_EVENT_STATISTICS -+} TDLS_EVENT_HOST_ID; -+ -+typedef enum _TDLS_EVENT_HOST_SUBID_TEAR_DOWN { -+ TDLS_HOST_EVENT_TD_PTI_TIMEOUT = 0x00, -+ TDLS_HOST_EVENT_TD_AGE_TIMEOUT, -+ TDLS_HOST_EVENT_TD_PTI_SEND_FAIL, -+ TDLS_HOST_EVENT_TD_PTI_SEND_MAX_FAIL, -+ TDLS_HOST_EVENT_TD_WRONG_NETWORK_IDX, -+ TDLS_HOST_EVENT_TD_NON_STATE3, -+ TDLS_HOST_EVENT_TD_LOST_TEAR_DOWN -+} TDLS_EVENT_HOST_SUBID_TEAR_DOWN; -+ -+typedef enum _TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME { -+ TDLS_HOST_EVENT_SF_BA, -+ TDLS_HOST_EVENT_SF_BA_OK, -+ TDLS_HOST_EVENT_SF_BA_DECLINE, -+ TDLS_HOST_EVENT_SF_BA_PEER, -+ TDLS_HOST_EVENT_SF_BA_RSP_OK, -+ TDLS_HOST_EVENT_SF_BA_RSP_DECLINE -+} TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME; -+ -+/* payload specific type in the LLC/SNAP header */ -+#define TDLS_FRM_PAYLOAD_TYPE 2 -+ -+#define TDLS_FRM_CATEGORY 12 -+ -+typedef enum _TDLS_FRM_ACTION_ID { -+ TDLS_FRM_ACTION_SETUP_REQ = 0x00, -+ TDLS_FRM_ACTION_SETUP_RSP, -+ TDLS_FRM_ACTION_CONFIRM, -+ TDLS_FRM_ACTION_TEARDOWN, -+ TDLS_FRM_ACTION_PTI, -+ TDLS_FRM_ACTION_CHAN_SWITCH_REQ, -+ TDLS_FRM_ACTION_CHAN_SWITCH_RSP, -+ TDLS_FRM_ACTION_PEER_PSM_REQ, -+ TDLS_FRM_ACTION_PEER_PSM_RSP, -+ TDLS_FRM_ACTION_PTI_RSP, /* 0x09 */ -+ TDLS_FRM_ACTION_DISCOVERY_REQ, -+ -+ TDLS_FRM_ACTION_EVENT_TEAR_DOWN_TO_SUPPLICANT = 0x30, -+ -+ TDLS_FRM_DATA_TEST_DATA = 0x80 -+} TDLS_FRM_ACTION_ID; -+ -+#define TDLS_FRM_ACTION_DISCOVERY_RESPONSE 14 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* 7.3.2.62 Link Identifier element */ -+#define ELEM_ID_LINK_IDENTIFIER 101 -+#define ELEM_LEN_LINK_IDENTIFIER 18 -+ -+typedef struct _IE_LINK_IDENTIFIER_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aBSSID[6]; -+ UINT_8 aInitiator[6]; -+ UINT_8 aResponder[6]; -+} __KAL_ATTRIB_PACKED__ IE_LINK_IDENTIFIER_T; -+ -+#define TDLS_LINK_IDENTIFIER_IE(__ie__) ((IE_LINK_IDENTIFIER_T *)(__ie__)) -+ -+/* test command use */ -+typedef struct _PARAM_CUSTOM_TDLS_CMD_STRUCT_T { -+ -+ UINT_8 ucFmeType; /* TDLS_FRM_ACTION_ID */ -+ -+ UINT_8 ucToken; -+ UINT_16 u2Cap; -+ -+ /* bit0: TDLS, bit1: Peer U-APSD Buffer, bit2: Channel Switching */ -+#define TDLS_EX_CAP_PEER_UAPSD BIT(0) -+#define TDLS_EX_CAP_CHAN_SWITCH BIT(1) -+#define TDLS_EX_CAP_TDLS BIT(2) -+ UINT_8 ucExCap; -+ -+ UINT_8 arSupRate[4]; -+ UINT_8 arSupChan[4]; -+ -+ UINT_32 u4Timeout; -+ -+#define TDLS_FME_MAC_ADDR_LEN 6 -+ UINT_8 arRspAddr[TDLS_FME_MAC_ADDR_LEN]; -+ UINT_8 arBssid[TDLS_FME_MAC_ADDR_LEN]; -+ -+/* -+ Linux Kernel-3.10 -+ struct station_parameters { -+ const u8 *supported_rates; -+ struct net_device *vlan; -+ u32 sta_flags_mask, sta_flags_set; -+ u32 sta_modify_mask; -+ int listen_interval; -+ u16 aid; -+ u8 supported_rates_len; -+ u8 plink_action; -+ u8 plink_state; -+ const struct ieee80211_ht_cap *ht_capa; -+ const struct ieee80211_vht_cap *vht_capa; -+ u8 uapsd_queues; -+ u8 max_sp; -+ enum nl80211_mesh_power_mode local_pm; -+ u16 capability; -+ const u8 *ext_capab; -+ u8 ext_capab_len; -+ }; -+*/ -+ struct ieee80211_ht_cap rHtCapa; -+ struct ieee80211_vht_cap rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */ -+ struct station_parameters rPeerInfo; -+ -+} PARAM_CUSTOM_TDLS_CMD_STRUCT_T; -+ -+typedef struct _TDLS_MGMT_TX_INFO { -+ UINT8 aucPeer[6]; -+ UINT8 ucActionCode; -+ UINT8 ucDialogToken; -+ UINT16 u2StatusCode; -+ UINT32 u4SecBufLen; -+ UINT8 aucSecBuf[1000]; -+} TDLS_MGMT_TX_INFO; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/* check any TDLS link */ -+#define TDLS_IS_NO_LINK_GOING(__GlueInfo__) \ -+ ((__GlueInfo__)->rTdlsLink.cLinkCnt == 0) -+ -+/* increase TDLS link count */ -+#define TDLS_LINK_INCREASE(__GlueInfo__) \ -+ ((__GlueInfo__)->rTdlsLink.cLinkCnt++) -+ -+/* decrease TDLS link count */ -+#define TDLS_LINK_DECREASE(__GlueInfo__) \ -+do { \ -+ if ((__GlueInfo__)->rTdlsLink.cLinkCnt > 0) \ -+ (__GlueInfo__)->rTdlsLink.cLinkCnt--; \ -+} while (0) -+ -+/* get TDLS link count */ -+#define TDLS_LINK_COUNT(__GlueInfo__) \ -+ ((__GlueInfo__)->rTdlsLink.cLinkCnt) -+ -+/* reset TDLS link count */ -+#define TDLS_LINK_COUNT_RESET(__GlueInfo__) \ -+ ((__GlueInfo__)->rTdlsLink.cLinkCnt = 0) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* Note: these functions are used only in tdls module, not other modules */ -+UINT_32 TdlsFrameGeneralIeAppend(ADAPTER_T *prAdapter, STA_RECORD_T *prStaRec, UINT_16 u2StatusCode, UINT_8 *pPkt); -+ -+TDLS_STATUS -+TdlsDataFrameSend(ADAPTER_T *prAdapter, -+ STA_RECORD_T *prStaRec, -+ UINT_8 *pPeerMac, -+ UINT_8 ucActionCode, -+ UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* CFG_SUPPORT_TDLS */ -+ -+#endif /* _TDLS_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h -new file mode 100644 -index 0000000000000..12c9359f2e8f3 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h -@@ -0,0 +1,104 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/wapi.h#1 -+*/ -+ -+/*! \file wapi.h -+ \brief The wapi related define, macro and structure are described here. -+*/ -+ -+/* -+** Log: wapi.h -+ * -+ * 07 20 2010 wh.su -+ * -+ * . -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * change the wapi function name and adding the generate wapi ie function -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some wapi structure define -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** \main\maintrunk.MT5921\1 2009-10-09 17:06:29 GMT mtk01088 -+** -+*/ -+ -+#ifndef _WAPI_H -+#define _WAPI_H -+ -+#if CFG_SUPPORT_WAPI -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define WAPI_CIPHER_SUITE_WPI 0x01721400 /* WPI_SMS4 */ -+#define WAPI_AKM_SUITE_802_1X 0x01721400 /* WAI */ -+#define WAPI_AKM_SUITE_PSK 0x02721400 /* WAI_PSK */ -+ -+#define ELEM_ID_WAPI 68 /* WAPI IE */ -+ -+#define WAPI_IE(fp) ((P_WAPI_INFO_ELEM_T) fp) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID wapiGenerateWAPIIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+BOOLEAN wapiParseWapiIE(IN P_WAPI_INFO_ELEM_T prInfoElem, OUT P_WAPI_INFO_T prWapiInfo); -+ -+BOOLEAN wapiPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss); -+ -+/* BOOLEAN */ -+/* wapiUpdateTxKeyIdx ( */ -+/* IN P_STA_RECORD_T prStaRec, */ -+/* IN UINT_8 ucWlanIdx */ -+/* ); */ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif -+#endif /* _WAPI_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h -new file mode 100644 -index 0000000000000..5dc969f1cc05b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h -@@ -0,0 +1,87 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/wlan_typedef.h#1 -+*/ -+ -+/*! \file wlan_typedef.h -+ \brief Declaration of data type and return values of internal protocol stack. -+ -+ In this file we declare the data type and return values which will be exported -+ to all MGMT Protocol Stack. -+*/ -+ -+/* -+** Log: wlan_typedef.h -+*/ -+ -+#ifndef _WLAN_TYPEDEF_H -+#define _WLAN_TYPEDEF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Type definition for BSS_INFO_T structure, to describe the attributes used in a -+ * common BSS. -+ */ -+typedef struct _BSS_INFO_T BSS_INFO_T, *P_BSS_INFO_T; -+ -+typedef BSS_INFO_T AIS_BSS_INFO_T, *P_AIS_BSS_INFO_T; -+typedef BSS_INFO_T P2P_BSS_INFO_T, *P_P2P_BSS_INFO_T; -+typedef BSS_INFO_T BOW_BSS_INFO_T, *P_BOW_BSS_INFO_T; -+ -+typedef struct _AIS_SPECIFIC_BSS_INFO_T AIS_SPECIFIC_BSS_INFO_T, *P_AIS_SPECIFIC_BSS_INFO_T; -+typedef struct _P2P_SPECIFIC_BSS_INFO_T P2P_SPECIFIC_BSS_INFO_T, *P_P2P_SPECIFIC_BSS_INFO_T; -+typedef struct _BOW_SPECIFIC_BSS_INFO_T BOW_SPECIFIC_BSS_INFO_T, *P_BOW_SPECIFIC_BSS_INFO_T; -+/* CFG_SUPPORT_WFD */ -+typedef struct _WFD_CFG_SETTINGS_T WFD_CFG_SETTINGS_T, *P_WFD_CFG_SETTINGS_T; -+ -+typedef struct _WFD_DBG_CFG_SETTINGS_T WFD_DBG_CFG_SETTINGS_T, *P_WFD_DBG_CFG_SETTINGS_T; -+ -+/* BSS related structures */ -+/* Type definition for BSS_DESC_T structure, to describe parameter sets of a particular BSS */ -+typedef struct _BSS_DESC_T BSS_DESC_T, *P_BSS_DESC_T, **PP_BSS_DESC_T; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+typedef struct _HS20_INFO_T HS20_INFO_T, *P_HS20_INFO_T; -+#endif /* CFG_SUPPORT_HOTSPOT_2_0 */ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _WLAN_TYPEDEF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h -new file mode 100644 -index 0000000000000..09bc0b5d5151b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h -@@ -0,0 +1,95 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/include/mgmt/wnm.h#1 -+*/ -+ -+/*! \file wnm.h -+ \brief This file contains the IEEE 802.11 family related 802.11v network management -+ for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wnm.h -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * -+*/ -+ -+#ifndef _WNM_H -+#define _WNM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef struct _TIMINGMSMT_PARAM_T { -+ BOOLEAN fgInitiator; -+ UINT_8 ucTrigger; -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 ucFollowUpDialogToken; /* Follow Up Dialog Token */ -+ UINT_32 u4ToD; /* Timestamp of Departure [10ns] */ -+ UINT_32 u4ToA; /* Timestamp of Arrival [10ns] */ -+} TIMINGMSMT_PARAM_T, *P_TIMINGMSMT_PARAM_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+WLAN_STATUS -+wnmRunEventTimgingMeasTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID -+wnmComposeTimingMeasFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); -+ -+VOID wnmTimingMeasRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID wnmWNMAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID wnmReportTimingMeas(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIndex, IN UINT_32 u4ToD, IN UINT_32 u4ToA); -+ -+#define WNM_UNIT_TEST 1 -+ -+#if WNM_UNIT_TEST -+VOID wnmTimingMeasUnitTest1(P_ADAPTER_T prAdapter, UINT_8 ucStaRecIndex); -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WNM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h -new file mode 100644 -index 0000000000000..d34f2c9c36a8b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h -@@ -0,0 +1,1506 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/adapter.h#3 -+*/ -+ -+/*! \file adapter.h -+ \brief Definition of internal data structure for driver manipulation. -+ -+ In this file we define the internal data structure - ADAPTER_T which stands -+ for MiniPort ADAPTER(From Windows point of view) or stands for Network ADAPTER. -+*/ -+ -+/* -+** Log: adapter.h -+** -+** 08 31 2012 yuche.tsai -+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have -+** connected to AP previously,one device reboots automatically with KE -+** Fix possible KE when concurrent & disconnect. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration -+ * with corresponding network configuration -+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred band configuration -+ * corresponding to network type. -+ * -+ * 12 13 2011 cm.chang -+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer -+ * Add wake lock if timer timeout value is smaller than 5 seconds -+ * -+ * 12 02 2011 yuche.tsai -+ * NULL -+ * Resolve inorder issue under AP mode. -+ * -+ * data frame may TX before assoc response frame. -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Update RSSI for P2P. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 10 21 2011 eddie.chen -+ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout -+ * Add switch to ignore the STA aging timeout. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 20 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * Remove ERP member in adapter structure -+ * -+ * 09 14 2011 yuche.tsai -+ * NULL -+ * Add P2P IE in assoc response. -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * check with firmware for valid MAC address. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discoverability support. -+ * Action frame callback for GO Device Discoverability Req. -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Add beacon timeout support for WiFi Direct Network. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Make assoc req to append P2P IE if wifi direct is enabled. -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically -+ * continuous memory shortage after system running for a long period -+ * use pre-allocated buffer for storing enhanced interrupt response as well -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce -+ * physically continuous memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 10 2011 yuche.tsai -+ * [WCXRP00000533] [Volunteer Patch][MT6620][Driver] Provide a P2P function API for Legacy WiFi to query AP mode. -+ * Provide an API for Legacy WiFi to query the operation mode.. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * Add code to send beacon and probe response WSC IE at Auto GO. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as -+ * initial RSSI right after connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid -+ * using a uninitialized MAC-RX RCPI. -+ * -+ * 02 21 2011 terry.wu -+ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P -+ * Clean P2P scan list while removing P2P. -+ * -+ * 02 17 2011 eddie.chen -+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel -+ * 1) Change GetFrameAction decision when BSS is absent. -+ * 2) Check channel and resource in processing ProbeRequest -+ * -+ * 02 16 2011 cm.chang -+ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism -+ * . -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add RX deauthentication & disassociation process under Hot-Spot mode. -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module -+ * with structure miss-align pointer issue -+ * always pre-allio WAPI related structure for align p2p module. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect to -+ * target station for AAA module. -+ * Provide disconnect function for AAA module. -+ * -+ * 02 01 2011 cm.chang -+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode -+ * . -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 27 2011 george.huang -+ * [WCXRP00000400] [MT6620 Wi-Fi] support CTIA power mode setting -+ * Support CTIA power mode setting. -+ * -+ * 01 27 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Support current measure mode, assigned by registry (XP only). -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Add WMM parameter for broadcast. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Add CWMin CWMax for AP to generate IE. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * report EEPROM used flag via NIC_CAPABILITY -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 27 2010 george.huang -+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB -+ * Support registry option for disable beacon lost detection. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] -+ * Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature -+ * Modify online scan as a run-time adjustable option (for Windows, in registry) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item -+ * use firmware reported mac address right after wlanAdapterStart() as permanent address -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Add a common IE buffer in P2P INFO structure. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * restore configuration as before. -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Finish SLT TX/RX & Rate Changing Support. -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add an intend mode for BSS info. -+ * It is used to let P2P BSS Info to know which OP Mode it is going to become. -+ * -+ * 08 04 2010 george.huang -+ * NULL -+ * handle change PS mode OID/ CMD -+ * -+ * 08 02 2010 cp.wu -+ * NULL -+ * comment out deprecated members in BSS_INFO, which are only used by firmware rather than driver. -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add for P2P Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Remove BSS info which is redonedent in Wifi Var.. -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 09 2010 george.huang -+ * -+ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 06 29 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * replace g_rQM with Adpater->rQM -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P FSM Info in adapter. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P related field, additional include p2p_fsm.h if p2p is enabled. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan.c. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add definitions for module migration. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * hem_mbox is migrated. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change OID behavior to meet WHQL requirement. -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 05 18 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement Wakeup-on-LAN except firmware integration part -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * reserve field of privacy filter and RTS threshold setting. -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * are done in adapter layer. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_3_MULTICAST_LIST oid handling -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock -+ * * * 2) ensure wlanReleasePendingOid will clear all command queues -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move ucCmdSeqNum as instance variable -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * 4. correct some HAL implementation -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * and result is retrieved by get ATInfo instead -+ * * * 2) add 4 counter for recording aggregation statistics -+ * -+ * 12 28 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate redundant variables for connection_state -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-12-16 18:02:03 GMT mtk02752 -+** add external reference to avoid compilation error -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-12-10 16:40:26 GMT mtk02752 -+** eliminate unused member -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-12-08 17:36:08 GMT mtk02752 -+** add RF test data members into P_ADAPTER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:45 GMT mtk01084 -+** update for new HW architecture design -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-28 10:29:57 GMT mtk01461 -+** Add read WTSR for SDIO_STATUS_ENHANCE mode -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-21 09:37:35 GMT mtk01461 -+** Add prPendingCmdInfoOfOID for temporarily saving the CMD_INFO_T before en-queue to rCmdQueue -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-17 19:57:51 GMT mtk01461 -+** Add MGMT Buffer Info -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:34:12 GMT mtk01461 -+** Add SW pre test CFG_HIF_LOOPBACK_PRETEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 21:41:48 GMT mtk01461 -+** Add fgIsWmmAssoc flag for TC assignment -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:51 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-18 20:51:52 GMT mtk01426 -+** Add #if CFG_SDIO_RX_ENHANCE related data structure -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:17 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _ADAPTER_H -+#define _ADAPTER_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+#include "hs20.h" -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _ENHANCE_MODE_DATA_STRUCT_T SDIO_CTRL_T, *P_SDIO_CTRL_T; -+ -+typedef struct _WLAN_INFO_T { -+ PARAM_BSSID_EX_T rCurrBssId; -+ -+ /* Scan Result */ -+ PARAM_BSSID_EX_T arScanResult[CFG_MAX_NUM_BSS_LIST]; -+ PUINT_8 apucScanResultIEs[CFG_MAX_NUM_BSS_LIST]; -+ UINT_32 u4ScanResultNum; -+ -+ /* IE pool for Scanning Result */ -+ UINT_8 aucScanIEBuf[CFG_MAX_COMMON_IE_BUF_LEN]; -+ UINT_32 u4ScanIEBufferUsage; -+ -+ OS_SYSTIME u4SysTime; -+ -+ /* connection parameter (for Ad-Hoc) */ -+ UINT_16 u2BeaconPeriod; -+ UINT_16 u2AtimWindow; -+ -+ PARAM_RATES eDesiredRates; -+ CMD_LINK_ATTRIB eLinkAttr; -+/* CMD_PS_PROFILE_T ePowerSaveMode; */ -+ CMD_PS_PROFILE_T arPowerSaveMode[NETWORK_TYPE_INDEX_NUM]; -+ -+ /* trigger parameter */ -+ ENUM_RSSI_TRIGGER_TYPE eRssiTriggerType; -+ PARAM_RSSI rRssiTriggerValue; -+ -+ /* Privacy Filter */ -+ ENUM_PARAM_PRIVACY_FILTER_T ePrivacyFilter; -+ -+ /* RTS Threshold */ -+ PARAM_RTS_THRESHOLD eRtsThreshold; -+ -+ /* Network Type */ -+ UINT_8 ucNetworkType; -+ -+ /* Network Type In Use */ -+ UINT_8 ucNetworkTypeInUse; -+ -+} WLAN_INFO_T, *P_WLAN_INFO_T; -+ -+/* Session for CONNECTION SETTINGS */ -+typedef struct _CONNECTION_SETTINGS_T { -+ -+ UINT_8 aucMacAddress[MAC_ADDR_LEN]; -+ -+ UINT_8 ucDelayTimeOfDisconnectEvent; -+ -+ BOOLEAN fgIsConnByBssidIssued; -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+ -+ BOOLEAN fgIsConnReqIssued; -+ BOOLEAN fgIsDisconnectedByNonRequest; -+ -+ UINT_8 ucSSIDLen; -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+ -+ ENUM_PARAM_OP_MODE_T eOPMode; -+ -+ ENUM_PARAM_CONNECTION_POLICY_T eConnectionPolicy; -+ -+ ENUM_PARAM_AD_HOC_MODE_T eAdHocMode; -+ -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; -+ -+ BOOLEAN fgIsScanReqIssued; -+ -+ /* MIB attributes */ -+ UINT_16 u2BeaconPeriod; -+ -+ UINT_16 u2RTSThreshold; /* User desired setting */ -+ -+ UINT_16 u2DesiredNonHTRateSet; /* User desired setting */ -+ -+ UINT_8 ucAdHocChannelNum; /* For AdHoc */ -+ -+ ENUM_BAND_T eAdHocBand; /* For AdHoc */ -+ -+ UINT_32 u4FreqInKHz; /* Center frequency */ -+ -+ /* ATIM windows using for IBSS power saving function */ -+ UINT_16 u2AtimWindow; -+ -+ /* Features */ -+ BOOLEAN fgIsEnableRoaming; -+ -+ BOOLEAN fgIsAdHocQoSEnable; -+ -+ ENUM_PARAM_PHY_CONFIG_T eDesiredPhyConfig; -+ -+ /* Used for AP mode for desired channel and bandwidth */ -+ UINT_16 u2CountryCode; -+ UINT_16 u2CountryCodeBakup; -+ UINT_8 uc2G4BandwidthMode; /* 20/40M or 20M only */ -+ UINT_8 uc5GBandwidthMode; /* 20/40M or 20M only */ -+ -+ BOOLEAN fgTxShortGIDisabled; -+ BOOLEAN fgRxShortGIDisabled; -+ -+#if CFG_SUPPORT_802_11D -+ BOOLEAN fgMultiDomainCapabilityEnabled; -+#endif /* CFG_SUPPORT_802_11D */ -+ -+#if 1 /* CFG_SUPPORT_WAPI */ -+ BOOLEAN fgWapiMode; -+ UINT_32 u4WapiSelectedGroupCipher; -+ UINT_32 u4WapiSelectedPairwiseCipher; -+ UINT_32 u4WapiSelectedAKMSuite; -+#endif -+ -+ /* CR1486, CR1640 */ -+ /* for WPS, disable the privacy check for AP selection policy */ -+ BOOLEAN fgPrivacyCheckDisable; -+ -+ /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ -+ UINT_8 bmfgApsdEnAc; -+ -+ /* for RSN info store, when upper layer set rsn info */ -+ RSN_INFO_T rRsnInfo; -+ -+} CONNECTION_SETTINGS_T, *P_CONNECTION_SETTINGS_T; -+ -+struct _BSS_INFO_T { -+ -+ ENUM_PARAM_MEDIA_STATE_T eConnectionState; /* Connected Flag used in AIS_NORMAL_TR */ -+ ENUM_PARAM_MEDIA_STATE_T eConnectionStateIndicated; /* The Media State that report to HOST */ -+ -+ ENUM_OP_MODE_T eCurrentOPMode; /* Current Operation Mode - Infra/IBSS */ -+#if CFG_ENABLE_WIFI_DIRECT -+ ENUM_OP_MODE_T eIntendOPMode; -+#endif -+ -+ BOOLEAN fgIsNetActive; /* TRUE if this network has been activated */ -+ -+ UINT_8 ucNetTypeIndex; /* ENUM_NETWORK_TYPE_INDEX_T */ -+ -+ UINT_8 ucReasonOfDisconnect; /* Used by media state indication */ -+ -+ UINT_8 ucSSIDLen; /* Length of SSID */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ ENUM_HIDDEN_SSID_TYPE_T eHiddenSsidType; /* For Hidden SSID usage. */ -+#endif -+ -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; /* SSID used in this BSS */ -+ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* The BSSID of the associated BSS */ -+ -+ UINT_8 aucOwnMacAddr[MAC_ADDR_LEN]; /* Owned MAC Address used in this BSS */ -+ -+ P_STA_RECORD_T prStaRecOfAP; /* For Infra Mode, and valid only if -+ * eConnectionState == MEDIA_STATE_CONNECTED -+ */ -+ LINK_T rStaRecOfClientList; /* For IBSS/AP Mode, all known STAs in current BSS */ -+ -+ UINT_16 u2CapInfo; /* Change Detection */ -+ -+ UINT_16 u2BeaconInterval; /* The Beacon Interval of this BSS */ -+ -+ UINT_16 u2ATIMWindow; /* For IBSS Mode */ -+ -+ UINT_16 u2AssocId; /* For Infra Mode, it is the Assoc ID assigned by AP. -+ */ -+ -+ UINT_8 ucDTIMPeriod; /* For Infra/AP Mode */ -+ -+ UINT_8 ucDTIMCount; /* For AP Mode, it is the DTIM value we should carried in -+ * the Beacon of next TBTT. -+ */ -+ -+ UINT_8 ucPhyTypeSet; /* Available PHY Type Set of this peer -+ * (This is deduced from received BSS_DESC_T) -+ */ -+ -+ UINT_8 ucNonHTBasicPhyType; /* The Basic PHY Type Index, used to setup Phy Capability */ -+ -+ UINT_8 ucConfigAdHocAPMode; /* The configuration of AdHoc/AP Mode. e.g. 11g or 11b */ -+ -+ UINT_8 ucBeaconTimeoutCount; /* For Infra/AP Mode, it is a threshold of Beacon Lost Count to -+ confirm connection was lost */ -+ -+ BOOLEAN fgHoldSameBssidForIBSS; /* For IBSS Mode, to keep use same BSSID to extend the life cycle of an IBSS */ -+ -+ BOOLEAN fgIsBeaconActivated; /* For AP/IBSS Mode, it is used to indicate that Beacon is sending */ -+ -+ P_MSDU_INFO_T prBeacon; /* For AP/IBSS Mode - Beacon Frame */ -+ -+ BOOLEAN fgIsIBSSMaster; /* For IBSS Mode - To indicate that we can reply ProbeResp Frame. -+ In current TBTT interval */ -+ -+ BOOLEAN fgIsShortPreambleAllowed; /* From Capability Info. of AssocResp Frame -+ AND of Beacon/ProbeResp Frame */ -+ BOOLEAN fgUseShortPreamble; /* Short Preamble is enabled in current BSS. */ -+ BOOLEAN fgUseShortSlotTime; /* Short Slot Time is enabled in current BSS. */ -+ -+ UINT_16 u2OperationalRateSet; /* Operational Rate Set of current BSS */ -+ UINT_16 u2BSSBasicRateSet; /* Basic Rate Set of current BSS */ -+ -+ UINT_8 ucAllSupportedRatesLen; /* Used for composing Beacon Frame in AdHoc or AP Mode */ -+ UINT_8 aucAllSupportedRates[RATE_NUM]; -+ -+ UINT_8 ucAssocClientCnt; /* TODO(Kevin): Number of associated clients */ -+ -+ BOOLEAN fgIsProtection; -+ BOOLEAN fgIsQBSS; /* fgIsWmmBSS; *//* For Infra/AP/IBSS Mode, it is used to indicate if we support WMM in -+ * current BSS. */ -+ BOOLEAN fgIsNetAbsent; /* TRUE: BSS is absent, FALSE: BSS is present */ -+ -+ UINT_32 u4RsnSelectedGroupCipher; -+ UINT_32 u4RsnSelectedPairwiseCipher; -+ UINT_32 u4RsnSelectedAKMSuite; -+ UINT_16 u2RsnSelectedCapInfo; -+ -+ /*------------------------------------------------------------------------*/ -+ /* Power Management related information */ -+ /*------------------------------------------------------------------------*/ -+ PM_PROFILE_SETUP_INFO_T rPmProfSetupInfo; -+ -+ /*------------------------------------------------------------------------*/ -+ /* WMM/QoS related information */ -+ /*------------------------------------------------------------------------*/ -+ UINT_8 ucWmmParamSetCount; /* Used to detect the change of EDCA parameters. For AP mode, -+ the value is used in WMM IE */ -+ -+ AC_QUE_PARMS_T arACQueParms[WMM_AC_INDEX_NUM]; -+ -+ UINT_8 aucCWminLog2ForBcast[WMM_AC_INDEX_NUM]; /* For AP mode, broadcast the CWminLog2 */ -+ UINT_8 aucCWmaxLog2ForBcast[WMM_AC_INDEX_NUM]; /* For AP mode, broadcast the CWmaxLog2 */ -+ AC_QUE_PARMS_T arACQueParmsForBcast[WMM_AC_INDEX_NUM]; /* For AP mode, broadcast the value */ -+ -+ /*------------------------------------------------------------------------*/ -+ /* 802.11n HT operation IE when (prStaRec->ucPhyTypeSet & PHY_TYPE_BIT_HT) */ -+ /* is true. They have the same definition with fields of */ -+ /* information element (CM) */ -+ /*------------------------------------------------------------------------*/ -+ ENUM_BAND_T eBand; -+ UINT_8 ucPrimaryChannel; -+ UINT_8 ucHtOpInfo1; -+ UINT_16 u2HtOpInfo2; -+ UINT_16 u2HtOpInfo3; -+ -+ /*------------------------------------------------------------------------*/ -+ /* Required protection modes (CM) */ -+ /*------------------------------------------------------------------------*/ -+ BOOLEAN fgErpProtectMode; -+ ENUM_HT_PROTECT_MODE_T eHtProtectMode; -+ ENUM_GF_MODE_T eGfOperationMode; -+ ENUM_RIFS_MODE_T eRifsOperationMode; -+ -+ BOOLEAN fgObssErpProtectMode; /* GO only */ -+ ENUM_HT_PROTECT_MODE_T eObssHtProtectMode; /* GO only */ -+ ENUM_GF_MODE_T eObssGfOperationMode; /* GO only */ -+ BOOLEAN fgObssRifsOperationMode; /* GO only */ -+ -+ /*------------------------------------------------------------------------*/ -+ /* OBSS to decide if 20/40M bandwidth is permitted. */ -+ /* The first member indicates the following channel list length. */ -+ /*------------------------------------------------------------------------*/ -+ BOOLEAN fgAssoc40mBwAllowed; -+ BOOLEAN fg40mBwAllowed; -+ ENUM_CHNL_EXT_T eBssSCO; /* Real setting for HW -+ * 20/40M AP mode will always set 40M, -+ * but its OP IE can be changed. -+ */ -+ UINT_8 auc2G_20mReqChnlList[CHNL_LIST_SZ_2G + 1]; -+ UINT_8 auc2G_NonHtChnlList[CHNL_LIST_SZ_2G + 1]; -+ UINT_8 auc2G_PriChnlList[CHNL_LIST_SZ_2G + 1]; -+ UINT_8 auc2G_SecChnlList[CHNL_LIST_SZ_2G + 1]; -+ -+ UINT_8 auc5G_20mReqChnlList[CHNL_LIST_SZ_5G + 1]; -+ UINT_8 auc5G_NonHtChnlList[CHNL_LIST_SZ_5G + 1]; -+ UINT_8 auc5G_PriChnlList[CHNL_LIST_SZ_5G + 1]; -+ UINT_8 auc5G_SecChnlList[CHNL_LIST_SZ_5G + 1]; -+ -+ TIMER_T rObssScanTimer; -+ UINT_16 u2ObssScanInterval; /* in unit of sec */ -+ -+ BOOLEAN fgObssActionForcedTo20M; /* GO only */ -+ BOOLEAN fgObssBeaconForcedTo20M; /* GO only */ -+ -+ /*------------------------------------------------------------------------*/ -+ /* HW Related Fields (Kevin) */ -+ /*------------------------------------------------------------------------*/ -+ UINT_8 ucHwDefaultFixedRateCode; /* The default rate code copied to MAC TX Desc */ -+ UINT_16 u2HwLPWakeupGuardTimeUsec; -+ -+ UINT_8 ucBssFreeQuota; /* The value is updated from FW */ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ P_IPV4_NETWORK_ADDRESS_LIST prIpV4NetAddrList; -+#endif -+ UINT_16 u2DeauthReason; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ BOOLEAN fgTdlsIsProhibited; /* TRUE: AP prohibits TDLS links */ -+ BOOLEAN fgTdlsIsChSwProhibited; /* TRUE: AP prohibits TDLS chan switch */ -+#endif /* CFG_SUPPORT_TDLS */ -+}; -+ -+struct _AIS_SPECIFIC_BSS_INFO_T { -+ UINT_8 ucRoamingAuthTypes; /* This value indicate the roaming type used in AIS_JOIN */ -+ -+ BOOLEAN fgIsIBSSActive; -+ -+ /*! \brief Global flag to let arbiter stay at standby and not connect to any network */ -+ BOOLEAN fgCounterMeasure; -+ UINT_8 ucWEPDefaultKeyID; -+ BOOLEAN fgTransmitKeyExist; /* Legacy wep Transmit key exist or not */ -+ -+ /* While Do CounterMeasure procedure, check the EAPoL Error report have send out */ -+ BOOLEAN fgCheckEAPoLTxDone; -+ -+ UINT_32 u4RsnaLastMICFailTime; -+ -+ /* Stored the current bss wpa rsn cap filed, used for roaming policy */ -+ /* UINT_16 u2RsnCap; */ -+ TIMER_T rPreauthenticationTimer; -+ -+ /* By the flow chart of 802.11i, -+ wait 60 sec before associating to same AP -+ or roaming to a new AP -+ or sending data in IBSS, -+ keep a timer for handle the 60 sec counterMeasure */ -+ TIMER_T rRsnaBlockTrafficTimer; -+ TIMER_T rRsnaEAPoLReportTimeoutTimer; -+ -+ /* For Keep the Tx/Rx Mic key for TKIP SW Calculate Mic */ -+ /* This is only one for AIS/AP */ -+ UINT_8 aucTxMicKey[8]; -+ UINT_8 aucRxMicKey[8]; -+ -+ /* Buffer for WPA2 PMKID */ -+ /* The PMKID cache lifetime is expire by media_disconnect_indication */ -+ UINT_32 u4PmkidCandicateCount; -+ PMKID_CANDICATE_T arPmkidCandicate[CFG_MAX_PMKID_CACHE]; -+ UINT_32 u4PmkidCacheCount; -+ PMKID_ENTRY_T arPmkidCache[CFG_MAX_PMKID_CACHE]; -+ BOOLEAN fgIndicatePMKID; -+#if CFG_SUPPORT_802_11W -+ BOOLEAN fgMgmtProtection; -+ UINT_32 u4SaQueryStart; -+ UINT_32 u4SaQueryCount; -+ UINT_8 ucSaQueryTimedOut; -+ PUINT_8 pucSaQueryTransId; -+ TIMER_T rSaQueryTimer; -+ BOOLEAN fgBipKeyInstalled; -+#endif -+}; -+ -+struct _BOW_SPECIFIC_BSS_INFO_T { -+ UINT_16 u2Reserved; /* Reserved for Data Type Check */ -+}; -+ -+#if CFG_SLT_SUPPORT -+typedef struct _SLT_INFO_T { -+ -+ P_BSS_DESC_T prPseudoBssDesc; -+ UINT_16 u2SiteID; -+ UINT_8 ucChannel2G4; -+ UINT_8 ucChannel5G; -+ BOOLEAN fgIsDUT; -+ UINT_32 u4BeaconReceiveCnt; -+ /* ///////Deprecated///////// */ -+ P_STA_RECORD_T prPseudoStaRec; -+} SLT_INFO_T, *P_SLT_INFO_T; -+#endif -+ -+/* Major member variables for WiFi FW operation. -+ Variables within this region will be ready for access after WIFI function is enabled. -+*/ -+typedef struct _WIFI_VAR_T { -+ BOOLEAN fgIsRadioOff; -+ -+ BOOLEAN fgIsEnterD3ReqIssued; -+ -+ BOOLEAN fgDebugCmdResp; -+ -+ CONNECTION_SETTINGS_T rConnSettings; -+ -+ SCAN_INFO_T rScanInfo; -+ -+#if CFG_SUPPORT_ROAMING -+ ROAMING_INFO_T rRoamingInfo; -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ AIS_FSM_INFO_T rAisFsmInfo; -+ -+ ENUM_PWR_STATE_T aePwrState[NETWORK_TYPE_INDEX_NUM]; -+ -+ BSS_INFO_T arBssInfo[NETWORK_TYPE_INDEX_NUM]; -+ -+ AIS_SPECIFIC_BSS_INFO_T rAisSpecificBssInfo; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings; -+ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; -+ -+ P_P2P_FSM_INFO_T prP2pFsmInfo; -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ BOW_SPECIFIC_BSS_INFO_T rBowSpecificBssInfo; -+ BOW_FSM_INFO_T rBowFsmInfo; -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+ DEAUTH_INFO_T arDeauthInfo[MAX_DEAUTH_INFO_COUNT]; -+ -+ /* Current Wi-Fi Settings and Flags */ -+ UINT_8 aucPermanentAddress[MAC_ADDR_LEN]; -+ UINT_8 aucMacAddress[MAC_ADDR_LEN]; -+ UINT_8 aucDeviceAddress[MAC_ADDR_LEN]; -+ UINT_8 aucInterfaceAddress[MAC_ADDR_LEN]; -+ -+ UINT_8 ucAvailablePhyTypeSet; -+ -+ ENUM_PHY_TYPE_INDEX_T eNonHTBasicPhyType2G4; /* Basic Phy Type used by SCN according -+ * to the set of Available PHY Types -+ */ -+ -+ ENUM_PARAM_PREAMBLE_TYPE_T ePreambleType; -+ ENUM_REGISTRY_FIXED_RATE_T eRateSetting; -+ -+ BOOLEAN fgIsShortSlotTimeOptionEnable; -+ /* User desired setting, but will honor the capability of AP */ -+ -+ BOOLEAN fgEnableJoinToHiddenSSID; -+ BOOLEAN fgSupportWZCDisassociation; -+ -+ BOOLEAN fgSupportQoS; -+ BOOLEAN fgSupportAmpduTx; -+ BOOLEAN fgSupportAmpduRx; -+ BOOLEAN fgSupportTspec; -+ BOOLEAN fgSupportUAPSD; -+ BOOLEAN fgSupportULPSMP; -+ UINT_8 u8SupportRxSgi20; /* 0: default 1: enable 2:disble */ -+ UINT_8 u8SupportRxSgi40; -+ UINT_8 u8SupportRxGf; -+ UINT_8 u8SupportRxSTBC; -+#if CFG_SUPPORT_CFG_FILE -+ UINT_8 ucApWpsMode; -+ UINT_8 ucCert11nMode; -+#endif -+#if CFG_SUPPORT_CE_FCC_TXPWR_LIMIT -+ UINT_8 ucCeFccTxPwrLimit; -+ UINT_8 ucCeFccTxPwrLimitCck; -+ UINT_8 ucCeFccTxPwrLimitOfdmHt20; -+ UINT_8 ucCeFccTxPwrLimitHt40; -+#endif -+ -+#if CFG_SLT_SUPPORT -+ SLT_INFO_T rSltInfo; -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ HS20_INFO_T rHS20Info; -+#endif -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ PARAM_GET_CHN_LOAD rChnLoadInfo; -+#endif -+ -+} WIFI_VAR_T, *P_WIFI_VAR_T; /* end of _WIFI_VAR_T */ -+ -+/* cnm_timer module */ -+typedef struct { -+ LINK_T rLinkHead; -+ OS_SYSTIME rNextExpiredSysTime; -+ KAL_WAKE_LOCK_T rWakeLock; -+ BOOLEAN fgWakeLocked; -+} ROOT_TIMER, *P_ROOT_TIMER; -+ -+/* FW/DRV/NVRAM version information */ -+typedef struct { -+ -+ /* NVRAM or Registry */ -+ UINT_16 u2Part1CfgOwnVersion; -+ UINT_16 u2Part1CfgPeerVersion; -+ UINT_16 u2Part2CfgOwnVersion; -+ UINT_16 u2Part2CfgPeerVersion; -+ -+ /* Firmware */ -+ UINT_16 u2FwProductID; -+ UINT_16 u2FwOwnVersion; -+ UINT_16 u2FwPeerVersion; -+ -+} WIFI_VER_INFO_T, *P_WIFI_VER_INFO_T; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+/* -+* p2p function pointer structure -+*/ -+ -+typedef struct _P2P_FUNCTION_LINKER { -+ P2P_REMOVE prP2pRemove; -+/* NIC_P2P_MEDIA_STATE_CHANGE prNicP2pMediaStateChange; */ -+/* SCAN_UPDATE_P2P_DEVICE_DESC prScanUpdateP2pDeviceDesc; */ -+/* P2P_FSM_RUN_EVENT_RX_PROBE_RESPONSE_FRAME prP2pFsmRunEventRxProbeResponseFrame; */ -+ P2P_GENERATE_P2P_IE prP2pGenerateWSC_IEForBeacon; -+/* P2P_CALCULATE_WSC_IE_LEN_FOR_PROBE_RSP prP2pCalculateWSC_IELenForProbeRsp; */ -+/* P2P_GENERATE_WSC_IE_FOR_PROBE_RSP prP2pGenerateWSC_IEForProbeRsp; */ -+/* SCAN_REMOVE_P2P_BSS_DESC prScanRemoveP2pBssDesc; */ -+/* P2P_HANDLE_SEC_CHECK_RSP prP2pHandleSecCheckRsp; */ -+ P2P_NET_REGISTER prP2pNetRegister; -+ P2P_NET_UNREGISTER prP2pNetUnregister; -+ P2P_CALCULATE_P2P_IE_LEN prP2pCalculateP2p_IELenForAssocReq; /* All IEs generated from supplicant. */ -+ P2P_GENERATE_P2P_IE prP2pGenerateP2p_IEForAssocReq; /* All IEs generated from supplicant. */ -+} P2P_FUNCTION_LINKER, *P_P2P_FUNCTION_LINKER; -+ -+#endif -+ -+/* -+ *State Machine: -+ *-->STOP: Turn on/off WiFi -+ *-->DISABLE: Screen was off (wlanHandleSystemSuspend) -+ *-->ENABLE: Screen was on (wlanHandleSystemResume) -+ *----->clear DISABLE -+ *-->RUNNING: Screen was on && Tx/Rx was ongoing (wlanHardStartXmit/kalRxIndicatePkts) -+*/ -+struct GL_PER_MON_T { -+ TIMER_T rPerfMonTimer; -+ ULONG ulPerfMonFlag; -+ ULONG ulLastTxBytes; -+ ULONG ulLastRxBytes; -+ ULONG ulP2PLastTxBytes; -+ ULONG ulP2PLastRxBytes; -+ /*in bps*/ -+ ULONG ulThroughput; -+ /*in ms*/ -+ UINT32 u4UpdatePeriod; -+ UINT32 u4TarPerfLevel; -+ UINT32 u4CurrPerfLevel; -+}; -+ -+/* -+ * Major ADAPTER structure -+ * Major data structure for driver operation -+ */ -+struct _ADAPTER_T { -+ UINT_8 ucRevID; -+ -+ UINT_16 u2NicOpChnlNum; -+ -+ BOOLEAN fgIsEnableWMM; -+ BOOLEAN fgIsWmmAssoc; /* This flag is used to indicate that WMM is enable in current BSS */ -+ -+ UINT_32 u4OsPacketFilter; /* packet filter used by OS */ -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ UINT_32 u4CSUMFlags; -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+ ENUM_BAND_T aePreferBand[NETWORK_TYPE_INDEX_NUM]; -+ -+ /* ADAPTER flags */ -+ UINT_32 u4Flags; -+ UINT_32 u4HwFlags; -+ -+ BOOLEAN fgIsRadioOff; -+ -+ BOOLEAN fgIsEnterD3ReqIssued; -+ -+ UINT_8 aucMacAddress[MAC_ADDR_LEN]; -+ -+ ENUM_PHY_TYPE_INDEX_T eCurrentPhyType; /* Current selection basing on the set of Available PHY Types */ -+ -+#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG -+ UINT_32 u4CoalescingBufCachedSize; -+ PUINT_8 pucCoalescingBufCached; -+#endif /* CFG_COALESCING_BUFFER_SIZE */ -+ -+ /* Buffer for CMD_INFO_T, Mgt packet and mailbox message */ -+ BUF_INFO_T rMgtBufInfo; -+ BUF_INFO_T rMsgBufInfo; -+ PUINT_8 pucMgtBufCached; -+ UINT_32 u4MgtBufCachedSize; -+ UINT_8 aucMsgBuf[MSG_BUFFER_SIZE]; -+#if CFG_DBG_MGT_BUF -+ UINT_32 u4MemAllocDynamicCount; /* Debug only */ -+ UINT_32 u4MemFreeDynamicCount; /* Debug only */ -+#endif -+ -+ STA_RECORD_T arStaRec[CFG_STA_REC_NUM]; -+ -+ /* Element for TX PATH */ -+ TX_CTRL_T rTxCtrl; -+ QUE_T rFreeCmdList; -+ CMD_INFO_T arHifCmdDesc[CFG_TX_MAX_CMD_PKT_NUM]; -+ -+ /* Element for RX PATH */ -+ RX_CTRL_T rRxCtrl; -+ -+ P_SDIO_CTRL_T prSDIOCtrl; -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ /* Element for MT6620 E1 HIFSYS workaround */ -+ BOOLEAN fgIsClockGatingEnabled; -+#endif -+ -+ /* Buffer for Authentication Event */ -+ /* Move to glue layer and refine the kal function */ -+ /* Reference to rsnGeneratePmkidIndication function at rsn.c */ -+ UINT_8 aucIndicationEventBuffer[(CFG_MAX_PMKID_CACHE * 20) + 8]; -+ -+ UINT_32 u4IntStatus; -+ -+ ENUM_ACPI_STATE_T rAcpiState; -+ -+ BOOLEAN fgIsIntEnable; -+ BOOLEAN fgIsIntEnableWithLPOwnSet; -+ -+ BOOLEAN fgIsFwOwn; -+ BOOLEAN fgWiFiInSleepyState; -+ -+ UINT_32 u4PwrCtrlBlockCnt; -+ -+ QUE_T rPendingCmdQueue; -+ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ UINT_8 ucCmdSeqNum; -+ UINT_8 ucTxSeqNum; -+ -+#if 1 /* CFG_SUPPORT_WAPI */ -+ BOOLEAN fgUseWapi; -+#endif -+ -+ /* RF Test flags */ -+ BOOLEAN fgTestMode; -+ -+ /* WLAN Info for DRIVER_CORE OID query */ -+ WLAN_INFO_T rWlanInfo; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgIsP2PRegistered; -+ ENUM_NET_REG_STATE_T rP2PNetRegState; -+ BOOLEAN fgIsWlanLaunched; -+ P_P2P_INFO_T prP2pInfo; -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ OS_SYSTIME rP2pLinkQualityUpdateTime; -+ BOOLEAN fgIsP2pLinkQualityValid; -+ EVENT_LINK_QUALITY rP2pLinkQuality; -+#endif -+ -+ /* FSM Timer */ -+ TIMER_T rP2pFsmTimeoutTimer; -+#endif -+ -+ /* Online Scan Option */ -+ BOOLEAN fgEnOnlineScan; -+ -+ /* Online Scan Option */ -+ BOOLEAN fgDisBcnLostDetection; -+ -+ /* MAC address */ -+ PARAM_MAC_ADDRESS rMyMacAddr; -+ -+ /* Wake-up Event for WOL */ -+ UINT_32 u4WakeupEventEnable; -+ -+ /* Event Buffering */ -+ EVENT_STATISTICS rStatStruct; -+ OS_SYSTIME rStatUpdateTime; -+ BOOLEAN fgIsStatValid; -+ -+ EVENT_LINK_QUALITY rLinkQuality; -+ OS_SYSTIME rLinkQualityUpdateTime; -+ BOOLEAN fgIsLinkQualityValid; -+ OS_SYSTIME rLinkRateUpdateTime; -+ BOOLEAN fgIsLinkRateValid; -+ -+ /* WIFI_VAR_T */ -+ WIFI_VAR_T rWifiVar; -+ -+ /* MTK WLAN NIC driver IEEE 802.11 MIB */ -+ IEEE_802_11_MIB_T rMib; -+ -+ /* Mailboxs for inter-module communication */ -+ MBOX_T arMbox[MBOX_ID_TOTAL_NUM]; -+ -+ /* Timers for OID Pending Handling */ -+ TIMER_T rOidTimeoutTimer; -+ -+ TIMER_T rReturnIndicatedRfbListTimer; -+ -+ /* Root Timer for cnm_timer module */ -+ ROOT_TIMER rRootTimer; -+ -+ /* RLM maintenance */ -+ ENUM_CHNL_EXT_T eRfSco; -+ ENUM_SYS_PROTECT_MODE_T eSysProtectMode; -+ ENUM_GF_MODE_T eSysHtGfMode; -+ ENUM_RIFS_MODE_T eSysTxRifsMode; -+ ENUM_SYS_PCO_PHASE_T eSysPcoPhase; -+ -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ -+ /* QM */ -+ QUE_MGT_T rQM; -+ -+ CNM_INFO_T rCnmInfo; -+ -+ UINT_32 u4PowerMode; -+ -+ UINT_32 u4CtiaPowerMode; -+ BOOLEAN fgEnCtiaPowerMode; -+ -+ UINT_32 fgEnArpFilter; -+ -+ UINT_32 u4UapsdAcBmp; -+ -+ UINT_32 u4MaxSpLen; -+ -+ UINT_32 u4PsCurrentMeasureEn; -+ -+ /* Version Information */ -+ WIFI_VER_INFO_T rVerInfo; -+ -+ /* 5GHz support (from F/W) */ -+ BOOLEAN fgIsHw5GBandDisabled; -+ BOOLEAN fgEnable5GBand; -+ BOOLEAN fgIsEepromUsed; -+ BOOLEAN fgIsEfuseValid; -+ BOOLEAN fgIsEmbbededMacAddrValid; -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ BOOLEAN fgIsPowerLimitTableValid; -+#endif -+ -+ /* Packet Forwarding Tracking */ -+ INT_32 i4PendingFwdFrameCount; -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ UINT_8 ucRddStatus; -+#endif -+ -+ BOOLEAN fgDisStaAgingTimeoutDetection; -+#if CFG_SUPPORT_CFG_FILE -+ P_WLAN_CFG_T prWlanCfg; -+ WLAN_CFG_T rWlanCfg; -+#endif -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+ KAL_WAKE_LOCK_T rApWakeLock; -+#endif -+ UINT_32 u4FwCompileFlag0; -+ UINT_32 u4FwCompileFlag1; -+ KAL_WAKE_LOCK_T rTxThreadWakeLock; -+ KAL_WAKE_LOCK_T rAhbIsrWakeLock; -+ -+#if CFG_SUPPORT_ROAMING_ENC -+ BOOLEAN fgIsRoamingEncEnabled; -+#endif /* CFG_SUPPORT_ROAMING_ENC */ -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ BOOLEAN fgTdlsIsSup; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ UINT_8 ucScanTime; -+ -+#if CFG_SUPPORT_DBG_POWERMODE -+ BOOLEAN fgEnDbgPowerMode; /* dbg privilege power mode, always keep in active */ -+#endif -+ -+ UINT_32 u4AirDelayTotal; /* dbg privilege power mode, always keep in active */ -+ ULONG ulSuspendFlag; -+ struct GL_PER_MON_T rPerMonitor; -+}; /* end of _ADAPTER_T */ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define SUSPEND_FLAG_FOR_WAKEUP_REASON (0) -+#define SUSPEND_FLAG_CLEAR_WHEN_RESUME (1) -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros for BSS_INFO_T - Flag of Net Active */ -+/*----------------------------------------------------------------------------*/ -+#define IS_NET_ACTIVE(_prAdapter, _NetTypeIndex) \ -+ (_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive) -+#define IS_BSS_ACTIVE(_prBssInfo) ((_prBssInfo)->fgIsNetActive) -+ -+#define IS_AIS_ACTIVE(_prAdapter) IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_AIS_INDEX) -+#define IS_P2P_ACTIVE(_prAdapter) IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_P2P_INDEX) -+#define IS_BOW_ACTIVE(_prAdapter) IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_BOW_INDEX) -+ -+#define SET_NET_ACTIVE(_prAdapter, _NetTypeIndex) \ -+ {_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive = TRUE; } -+ -+#define UNSET_NET_ACTIVE(_prAdapter, _NetTypeIndex) \ -+ {_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive = FALSE; } -+ -+#define BSS_INFO_INIT(_prAdapter, _NetTypeIndex) \ -+ { UINT_8 _aucZeroMacAddr[] = NULL_MAC_ADDR; \ -+ P_BSS_INFO_T _prBssInfo = &(_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)]); \ -+ \ -+ _prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; \ -+ _prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; \ -+ _prBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; \ -+ _prBssInfo->fgIsNetActive = FALSE; \ -+ _prBssInfo->ucNetTypeIndex = (_NetTypeIndex); \ -+ _prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; \ -+ COPY_MAC_ADDR(_prBssInfo->aucBSSID, _aucZeroMacAddr); \ -+ LINK_INITIALIZE(&_prBssInfo->rStaRecOfClientList); \ -+ _prBssInfo->fgIsBeaconActivated = FALSE; \ -+ _prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; \ -+ _prBssInfo->fgIsNetAbsent = FALSE; \ -+ } -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+#define BOW_BSS_INFO_INIT(_prAdapter, _NetTypeIndex) \ -+ { \ -+ P_BSS_INFO_T _prBssInfo = &(_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)]); \ -+ \ -+ _prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; \ -+ _prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; \ -+ _prBssInfo->eCurrentOPMode = OP_MODE_BOW; \ -+ _prBssInfo->ucNetTypeIndex = (_NetTypeIndex); \ -+ _prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; \ -+ LINK_INITIALIZE(&_prBssInfo->rStaRecOfClientList); \ -+ _prBssInfo->fgIsBeaconActivated = TRUE; \ -+ _prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; \ -+ _prBssInfo->fgIsNetAbsent = FALSE; \ -+ } -+#endif -+ -+#define PERF_MON_DISABLE_BIT_OFF (0) -+#define PERF_MON_STOP_BIT_OFF (1) -+#define PERF_MON_RUNNING_BIT_OFF (2) -+ -+#define THROUGHPUT_L1_THRESHOLD (20*1024*1024) -+#define THROUGHPUT_L2_THRESHOLD (60*1024*1024) -+#define THROUGHPUT_L3_THRESHOLD (135*1024*1024) -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros for Power State */ -+/*----------------------------------------------------------------------------*/ -+#define SET_NET_PWR_STATE_IDLE(_prAdapter, _NetTypeIndex) \ -+ {_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_IDLE; } -+ -+#define SET_NET_PWR_STATE_ACTIVE(_prAdapter, _NetTypeIndex) \ -+ {_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_ACTIVE; } -+ -+#define SET_NET_PWR_STATE_PS(_prAdapter, _NetTypeIndex) \ -+ {_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_PS; } -+ -+#define IS_NET_PWR_STATE_ACTIVE(_prAdapter, _NetTypeIndex) \ -+ (_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] == PWR_STATE_ACTIVE) -+ -+#define IS_NET_PWR_STATE_IDLE(_prAdapter, _NetTypeIndex) \ -+ (_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] == PWR_STATE_IDLE) -+ -+#define IS_SCN_PWR_STATE_ACTIVE(_prAdapter) \ -+ (_prAdapter->rWifiVar.rScanInfo.eScanPwrState == SCAN_PWR_STATE_ACTIVE) -+ -+#define IS_SCN_PWR_STATE_IDLE(_prAdapter) \ -+ (_prAdapter->rWifiVar.rScanInfo.eScanPwrState == SCAN_PWR_STATE_IDLE) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _ADAPTER_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h -new file mode 100644 -index 0000000000000..6c4c1b76622b2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h -@@ -0,0 +1,322 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/bow.h#1 -+*/ -+ -+/* -+** Log: bow.h -+ * -+ * 01 16 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support BOW for 5GHz band. -+ * -+ * 05 25 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add BoW Cancel Scan Request and Turn On deactive network function. -+ * -+ * 05 22 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Submit missing BoW header files. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support multiple physical link. -+ * -+ * 03 06 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Sync BOW Driver to latest person development branch version.. -+ * -+ * 02 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix kernel API change issue. -+ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is -+ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); -+ * After ALPS 2.3, kfifo_alloc() is changed to -+ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); -+ * -+ * 02 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update BOW structure. -+ * -+ * 02 09 2011 cp.wu -+ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3 -+ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031 -+ * with BOW and P2P enabled as default -+ * -+ * 02 08 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in. -+ * Update BOW get MAC status, remove returning event for AIS network type. -+ * -+ * 01 11 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add Activity Report definition. -+ * -+ * 10 18 2010 chinghwa.yu -+ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size -+ * Fix wrong BoW event size. -+ * -+ * 07 15 2010 cp.wu -+ * -+ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * 1) all BT physical handles shares the same RSSI/Link Quality. -+ * 2) simplify BT command composing -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * basic implementation for EVENT_BT_OVER_WIFI -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 09 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * sync. with design document for interface change. -+ * -+ * 04 02 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * Wi-Fi driver no longer needs to implement 802.11 PAL, thus replaced by wrapping command/event definitions -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * correct typo. -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * update for all command/event needed to be supported by 802.11 PAL. -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * build up basic data structure and definitions to support BT-over-WiFi -+ * -+*/ -+ -+#ifndef _BOW_H_ -+#define _BOW_H_ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define BOWDEVNAME "bow0" -+ -+#define MAX_BOW_NUMBER_OF_CHANNEL_2G4 14 -+#define MAX_BOW_NUMBER_OF_CHANNEL_5G 4 -+/* (MAX_BOW_NUMBER_OF_CHANNEL_2G4 + MAX_BOW_NUMBER_OF_CHANNEL_5G) */ -+#define MAX_BOW_NUMBER_OF_CHANNEL 18 -+ -+#define MAX_ACTIVITY_REPORT 2 -+#define MAX_ACTIVITY_REPROT_TIME 660 -+ -+#define ACTIVITY_REPORT_STATUS_SUCCESS 0 -+#define ACTIVITY_REPORT_STATUS_FAILURE 1 -+#define ACTIVITY_REPORT_STATUS_TIME_INVALID 2 -+#define ACTIVITY_REPORT_STATUS_OTHERS 3 -+ -+#define ACTIVITY_REPORT_SCHEDULE_UNKNOWN 0 /* Does not know the schedule of the interference */ -+#define ACTIVITY_REPORT_SCHEDULE_KNOWN 1 -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _BT_OVER_WIFI_COMMAND_HEADER_T { -+ UINT_8 ucCommandId; -+ UINT_8 ucSeqNumber; -+ UINT_16 u2PayloadLength; -+} AMPC_COMMAND_HEADER_T, *P_AMPC_COMMAND_HEADER_T; -+ -+typedef struct _BT_OVER_WIFI_COMMAND { -+ AMPC_COMMAND_HEADER_T rHeader; -+ UINT_8 aucPayload[0]; -+} AMPC_COMMAND, *P_AMPC_COMMAND; -+ -+typedef struct _BT_OVER_WIFI_EVENT_HEADER_T { -+ UINT_8 ucEventId; -+ UINT_8 ucSeqNumber; -+ UINT_16 u2PayloadLength; -+} AMPC_EVENT_HEADER_T, *P_AMPC_EVENT_HEADER_T; -+ -+typedef struct _BT_OVER_WIFI_EVENT { -+ AMPC_EVENT_HEADER_T rHeader; -+ UINT_8 aucPayload[0]; -+} AMPC_EVENT, *P_AMPC_EVENT; -+ -+typedef struct _CHANNEL_DESC_T { -+ UINT_8 ucChannelBand; -+ UINT_8 ucChannelNum; -+} CHANNEL_DESC, P_CHANNEL_DESC; -+ -+/* Command Structures */ -+typedef struct _BOW_SETUP_CONNECTION { -+/* Fixed to 2.4G */ -+ UINT_8 ucChannelNum; -+ UINT_8 ucReserved1; -+ UINT_8 aucPeerAddress[6]; -+ UINT_16 u2BeaconInterval; -+ UINT_8 ucTimeoutDiscovery; -+ UINT_8 ucTimeoutInactivity; -+ UINT_8 ucRole; -+ UINT_8 ucPAL_Capabilities; -+ INT_8 cMaxTxPower; -+ UINT_8 ucReserved2; -+ -+/* Pending, for future BOW 5G supporting. */ -+/* UINT_8 aucPeerAddress[6]; -+ UINT_16 u2BeaconInterval; -+ UINT_8 ucTimeoutDiscovery; -+ UINT_8 ucTimeoutInactivity; -+ UINT_8 ucRole; -+ UINT_8 ucPAL_Capabilities; -+ INT_8 cMaxTxPower; -+ UINT_8 ucChannelListNum; -+ CHANNEL_DESC arChannelList[1]; -+*/ -+} BOW_SETUP_CONNECTION, *P_BOW_SETUP_CONNECTION; -+ -+typedef struct _BOW_DESTROY_CONNECTION { -+ UINT_8 aucPeerAddress[6]; -+ UINT_8 aucReserved[2]; -+} BOW_DESTROY_CONNECTION, *P_BOW_DESTROY_CONNECTION; -+ -+typedef struct _BOW_SET_PTK { -+ UINT_8 aucPeerAddress[6]; -+ UINT_8 aucReserved[2]; -+ UINT_8 aucTemporalKey[16]; -+} BOW_SET_PTK, *P_BOW_SET_PTK; -+ -+typedef struct _BOW_READ_RSSI { -+ UINT_8 aucPeerAddress[6]; -+ UINT_8 aucReserved[2]; -+} BOW_READ_RSSI, *P_BOW_READ_RSSI; -+ -+typedef struct _BOW_READ_LINK_QUALITY { -+ UINT_8 aucPeerAddress[6]; -+ UINT_8 aucReserved[2]; -+} BOW_READ_LINK_QUALITY, *P_BOW_READ_LINK_QUALITY; -+ -+typedef struct _BOW_SHORT_RANGE_MODE { -+ UINT_8 aucPeerAddress[6]; -+ INT_8 cTxPower; -+ UINT_8 ucReserved; -+} BOW_SHORT_RANGE_MODE, *P_BOW_SHORT_RANGE_MODE; -+ -+/* Event Structures */ -+typedef struct _BOW_COMMAND_STATUS { -+ UINT_8 ucStatus; -+ UINT_8 ucReserved[3]; -+} BOW_COMMAND_STATUS, *P_BOW_COMMAND_STATUS; -+ -+typedef struct _BOW_MAC_STATUS { -+ UINT_8 aucMacAddr[6]; -+ UINT_8 ucAvailability; -+ UINT_8 ucNumOfChannel; -+ CHANNEL_DESC arChannelList[MAX_BOW_NUMBER_OF_CHANNEL]; -+} BOW_MAC_STATUS, *P_BOW_MAC_STATUS; -+ -+typedef struct _BOW_LINK_CONNECTED { -+ CHANNEL_DESC rChannel; -+ UINT_8 aucReserved; -+ UINT_8 aucPeerAddress[6]; -+} BOW_LINK_CONNECTED, *P_BOW_LINK_CONNECTED; -+ -+typedef struct _BOW_LINK_DISCONNECTED { -+ UINT_8 ucReason; -+ UINT_8 aucReserved; -+ UINT_8 aucPeerAddress[6]; -+} BOW_LINK_DISCONNECTED, *P_BOW_LINK_DISCONNECTED; -+ -+typedef struct _BOW_RSSI { -+ INT_8 cRssi; -+ UINT_8 aucReserved[3]; -+} BOW_RSSI, *P_BOW_RSSI; -+ -+typedef struct _BOW_LINK_QUALITY { -+ UINT_8 ucLinkQuality; -+ UINT_8 aucReserved[3]; -+} BOW_LINK_QUALITY, *P_BOW_LINK_QUALITY; -+ -+typedef enum _ENUM_BOW_CMD_ID_T { -+ BOW_CMD_ID_GET_MAC_STATUS = 1, -+ BOW_CMD_ID_SETUP_CONNECTION, -+ BOW_CMD_ID_DESTROY_CONNECTION, -+ BOW_CMD_ID_SET_PTK, -+ BOW_CMD_ID_READ_RSSI, -+ BOW_CMD_ID_READ_LINK_QUALITY, -+ BOW_CMD_ID_SHORT_RANGE_MODE, -+ BOW_CMD_ID_GET_CHANNEL_LIST, -+} ENUM_BOW_CMD_ID_T, *P_ENUM_BOW_CMD_ID_T; -+ -+typedef enum _ENUM_BOW_EVENT_ID_T { -+ BOW_EVENT_ID_COMMAND_STATUS = 1, -+ BOW_EVENT_ID_MAC_STATUS, -+ BOW_EVENT_ID_LINK_CONNECTED, -+ BOW_EVENT_ID_LINK_DISCONNECTED, -+ BOW_EVENT_ID_RSSI, -+ BOW_EVENT_ID_LINK_QUALITY, -+ BOW_EVENT_ID_CHANNEL_LIST, -+ BOW_EVENT_ID_CHANNEL_SELECTED, -+} ENUM_BOW_EVENT_ID_T, *P_ENUM_BOW_EVENT_ID_T; -+ -+typedef enum _ENUM_BOW_DEVICE_STATE { -+ BOW_DEVICE_STATE_DISCONNECTED = 0, -+ BOW_DEVICE_STATE_DISCONNECTING, -+ BOW_DEVICE_STATE_ACQUIRING_CHANNEL, -+ BOW_DEVICE_STATE_STARTING, -+ BOW_DEVICE_STATE_SCANNING, -+ BOW_DEVICE_STATE_CONNECTING, -+ BOW_DEVICE_STATE_CONNECTED, -+ BOW_DEVICE_STATE_NUM -+} ENUM_BOW_DEVICE_STATE, *P_ENUM_BOW_DEVICE_STATE; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#endif /*_BOW_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h -new file mode 100644 -index 0000000000000..c1ecb303b877f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h -@@ -0,0 +1,150 @@ -+/* -+** Id: -+*/ -+ -+/*! \file "cmd_buf.h" -+ \brief In this file we define the structure for Command Packet. -+ -+ In this file we define the structure for Command Packet and the control unit -+ of MGMT Memory Pool. -+*/ -+ -+/* -+** Log: cmd_buf.h -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by -+ * ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow -+ * under concurrent network operation -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Enable change log -+*/ -+ -+#ifndef _CMD_BUF_H -+#define _CMD_BUF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _COMMAND_TYPE { -+ COMMAND_TYPE_GENERAL_IOCTL, -+ COMMAND_TYPE_NETWORK_IOCTL, -+ COMMAND_TYPE_SECURITY_FRAME, -+ COMMAND_TYPE_MANAGEMENT_FRAME, -+ COMMAND_TYPE_NUM -+} COMMAND_TYPE, *P_COMMAND_TYPE; -+ -+typedef VOID(*PFN_CMD_DONE_HANDLER) (IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+typedef VOID(*PFN_CMD_TIMEOUT_HANDLER) (IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+struct _CMD_INFO_T { -+ QUE_ENTRY_T rQueEntry; -+ -+ COMMAND_TYPE eCmdType; -+ -+ UINT_16 u2InfoBufLen; /* This is actual CMD buffer length */ -+ PUINT_8 pucInfoBuffer; /* May pointer to structure in prAdapter */ -+ P_NATIVE_PACKET prPacket; /* only valid when it's a security frame */ -+ -+ ENUM_NETWORK_TYPE_INDEX_T eNetworkType; -+ UINT_8 ucStaRecIndex; /* only valid when it's a security frame */ -+ -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler; -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler; -+ -+ BOOLEAN fgIsOid; /* Used to check if we need indicate */ -+ -+ UINT_8 ucCID; -+ BOOLEAN fgSetQuery; -+ BOOLEAN fgNeedResp; -+ BOOLEAN fgDriverDomainMCR; /* Access Driver Domain MCR, for CMD_ID_ACCESS_REG only */ -+ UINT_8 ucCmdSeqNum; -+ UINT_32 u4SetInfoLen; /* Indicate how many byte we read for Set OID */ -+ -+ /* information indicating by OID/ioctl */ -+ PVOID pvInformationBuffer; -+ UINT_32 u4InformationBufferLength; -+ -+ /* private data */ -+ UINT_32 u4PrivateData; -+}; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID cmdBufInitialize(IN P_ADAPTER_T prAdapter); -+ -+P_CMD_INFO_T cmdBufAllocateCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length); -+ -+VOID cmdBufFreeCmdInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines for CMDs */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanSendSetQueryCmd(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucCID, -+ BOOLEAN fgSetQuery, -+ BOOLEAN fgNeedResp, -+ BOOLEAN fgIsOid, -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ UINT_32 u4SetQueryInfoLen, -+ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen); -+VOID cmdBufDumpCmdQueue(P_QUE_T prQueue, CHAR *queName); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _CMD_BUF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h -new file mode 100644 -index 0000000000000..0fdb9dcadeeff ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h -@@ -0,0 +1,618 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hal.h#1 -+*/ -+ -+/*! \file "hal.h" -+ \brief The declaration of hal functions -+ -+ N/A -+*/ -+ -+/* -+** Log: hal.h -+ * -+ * 04 01 2011 tsaiyuan.hsu -+ * [WCXRP00000615] [MT 6620 Wi-Fi][Driver] Fix klocwork issues -+ * fix the klocwork issues, 57500, 57501, 57502 and 57503. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 11 08 2010 cp.wu -+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period -+ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * move HIF CR initialization from where after sdioSetupCardFeature() to wlanAdapterStart() -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change zero-padding for TX port access to HAL. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * 4. correct some HAL implementation -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-12-16 18:02:26 GMT mtk02752 -+** include precomp.h -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-10 16:43:16 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-13 13:54:15 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-11 10:36:01 GMT mtk01084 -+** modify HAL functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-09 22:56:28 GMT mtk01084 -+** modify HW access routines -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-10-29 19:50:09 GMT mtk01084 -+** add new macro HAL_TX_PORT_WR -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-23 16:08:10 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:50 GMT mtk01084 -+** update for new HW architecture design -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-05-18 14:28:10 GMT mtk01084 -+** fix issue in HAL_DRIVER_OWN_BY_SDIO_CMD52() -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-11 17:26:33 GMT mtk01084 -+** modify the bit definition to check driver own status -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-28 10:30:22 GMT mtk01461 -+** Fix typo -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:50:34 GMT mtk01461 -+** Redefine HAL_PORT_RD/WR macro for SW pre test -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-24 09:46:49 GMT mtk01084 -+** fix LINT error -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 16:53:38 GMT mtk01084 -+** add HAL_DRIVER_OWN_BY_SDIO_CMD52() -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-18 20:53:13 GMT mtk01426 -+** Fixed lint warn -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:20 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _HAL_H -+#define _HAL_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/* Macros for flag operations for the Adapter structure */ -+#define HAL_SET_FLAG(_M, _F) ((_M)->u4HwFlags |= (_F)) -+#define HAL_CLEAR_FLAG(_M, _F) ((_M)->u4HwFlags &= ~(_F)) -+#define HAL_TEST_FLAG(_M, _F) ((_M)->u4HwFlags & (_F)) -+#define HAL_TEST_FLAGS(_M, _F) (((_M)->u4HwFlags & (_F)) == (_F)) -+ -+#if defined(_HIF_SDIO) -+#define HAL_MCR_RD(_prAdapter, _u4Offset, _pu4Value) \ -+do { \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevRegRead(_prAdapter->prGlueInfo, _u4Offset, _pu4Value) == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ /* DBGLOG(HAL, ERROR, ("HAL_MCR_RD access fail! 0x%x: 0x%x\n", */ \ -+ /* (UINT32)_u4Offset, (UINT32)*_pu4Value)); */ \ -+ } \ -+ } else { \ -+ /* DBGLOG(HAL, WARN, ("ignore HAL_MCR_RD access! 0x%x\n", (UINT32)_u4Offset)); */ \ -+ } \ -+} while (0) -+ -+#define HAL_MCR_WR(_prAdapter, _u4Offset, _u4Value) \ -+do { \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevRegWrite(_prAdapter->prGlueInfo, _u4Offset, _u4Value) == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ /* DBGLOG(HAL, ERROR, ("HAL_MCR_WR access fail! 0x%x: 0x%x\n", */ \ -+ /* (UINT32)_u4Offset, (UINT32)_u4Value)); */ \ -+ } \ -+ } else { \ -+ /* DBGLOG(HAL, WARN, ("ignore HAL_MCR_WR access! 0x%x: 0x%x\n", */ \ -+ /* (UINT32)_u4Offset, (UINT32)_u4Value)); */ \ -+ } \ -+} while (0) -+ -+#define HAL_PORT_RD(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+{ \ -+ /*fgResult = FALSE; */\ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (kalDevPortRead(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+ == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ DBGLOG(HAL, ERROR, "HAL_PORT_RD access fail! 0x%x\n", _u4Port); \ -+ } \ -+ else { \ -+ /*fgResult = TRUE;*/ } \ -+ } else { \ -+ DBGLOG(HAL, WARN, "ignore HAL_PORT_RD access! 0x%x\n", _u4Port); \ -+ } \ -+} -+ -+#define HAL_PORT_WR(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+{ \ -+ /*fgResult = FALSE; */\ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (kalDevPortWrite(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+ == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ DBGLOG(HAL, ERROR, "HAL_PORT_WR access fail! 0x%x\n", _u4Port); \ -+ } \ -+ else { \ -+ /*fgResult = TRUE;*/ } \ -+ } else { \ -+ DBGLOG(HAL, WARN, "ignore HAL_PORT_WR access! 0x%x\n", _u4Port); \ -+ } \ -+} -+ -+#if 0 /* only for SDIO */ -+#define HAL_BYTE_WR(_prAdapter, _u4Port, _ucBuf) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (kalDevWriteWithSdioCmd52(_prAdapter->prGlueInfo, _u4Port, _ucBuf) == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ DBGLOG(HAL, ERROR, "HAL_BYTE_WR access fail! 0x%x\n", _u4Port); \ -+ } \ -+ else { \ -+ /* Todo:: Nothing*/ \ -+ } \ -+ } \ -+ else { \ -+ DBGLOG(HAL, WARN, "ignore HAL_BYTE_WR access! 0x%x\n", _u4Port); \ -+ } \ -+} -+#endif -+ -+#define HAL_DRIVER_OWN_BY_SDIO_CMD52(_prAdapter, _pfgDriverIsOwnReady) \ -+{ \ -+ UINT_8 ucBuf = BIT(1); \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (kalDevReadAfterWriteWithSdioCmd52(_prAdapter->prGlueInfo, MCR_WHLPCR_BYTE1, &ucBuf, 1) \ -+ == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ DBGLOG(HAL, ERROR, "kalDevReadAfterWriteWithSdioCmd52 access fail!\n"); \ -+ } \ -+ else { \ -+ *_pfgDriverIsOwnReady = (ucBuf & BIT(0)) ? TRUE : FALSE; \ -+ } \ -+ } else { \ -+ DBGLOG(HAL, WARN, "ignore HAL_DRIVER_OWN_BY_SDIO_CMD52 access!\n"); \ -+ } \ -+} -+ -+#else /* #if defined(_HIF_SDIO) */ -+#define HAL_MCR_RD(_prAdapter, _u4Offset, _pu4Value) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevRegRead(_prAdapter->prGlueInfo, _u4Offset, _pu4Value) \ -+ == FALSE) \ -+ fgIsBusAccessFailed = TRUE; \ -+} -+ -+#define HAL_MCR_WR(_prAdapter, _u4Offset, _u4Value) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevRegWrite(_prAdapter->prGlueInfo, _u4Offset, _u4Value) \ -+ == FALSE) \ -+ fgIsBusAccessFailed = TRUE; \ -+} -+ -+#define HAL_PORT_RD(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevPortRead(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+ == FALSE) \ -+ fgIsBusAccessFailed = TRUE; \ -+} -+ -+#define HAL_PORT_WR(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevPortWrite(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+ == FALSE) \ -+ fgIsBusAccessFailed = TRUE; \ -+} -+ -+#if 0 /* only for SDIO */ -+#define HAL_BYTE_WR(_prAdapter, _u4Port, _ucBuf) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+kalDevWriteWithSdioCmd52(_prAdapter->prGlueInfo, _u4Port, _ucBuf); \ -+} -+#endif -+ -+#endif /* #if defined(_HIF_SDIO) */ -+ -+#define HAL_READ_RX_PORT(prAdapter, u4PortId, u4Len, pvBuf, _u4ValidBufSize) \ -+{ \ -+ ASSERT(u4PortId < 2); \ -+ HAL_PORT_RD(prAdapter, \ -+ ((u4PortId == 0) ? MCR_WRDR0 : MCR_WRDR1), \ -+ u4Len, \ -+ pvBuf, \ -+ _u4ValidBufSize/*temp!!*//*4Kbyte*/); \ -+} -+ -+#define HAL_WRITE_TX_PORT(_prAdapter, _ucTxPortIdx, _u4Len, _pucBuf, _u4ValidBufSize) \ -+{ \ -+ ASSERT(_ucTxPortIdx < 2); \ -+ if ((_u4ValidBufSize - _u4Len) >= sizeof(UINT_32)) { \ -+ /* fill with single dword of zero as TX-aggregation termination */ \ -+ *(PUINT_32) (&((_pucBuf)[ALIGN_4(_u4Len)])) = 0; \ -+ } \ -+ HAL_PORT_WR(_prAdapter, \ -+ (_ucTxPortIdx == 0) ? MCR_WTDR0 : MCR_WTDR1, \ -+ _u4Len, \ -+ _pucBuf, \ -+ _u4ValidBufSize/*temp!!*//*4KByte*/); \ -+} -+ -+/* The macro to read the given MCR several times to check if the wait -+ condition come true. */ -+#define HAL_MCR_RD_AND_WAIT(_pAdapter, _offset, _pReadValue, _waitCondition, _waitDelay, _waitCount, _status) \ -+{ \ -+ UINT_32 count; \ -+ (_status) = FALSE; \ -+ for (count = 0; count < (_waitCount); count++) { \ -+ HAL_MCR_RD((_pAdapter), (_offset), (_pReadValue)); \ -+ if ((_waitCondition)) { \ -+ (_status) = TRUE; \ -+ break; \ -+ } \ -+ kalUdelay((_waitDelay)); \ -+ } \ -+} -+ -+/* The macro to write 1 to a R/S bit and read it several times to check if the -+ command is done */ -+#define HAL_MCR_WR_AND_WAIT(_pAdapter, _offset, _writeValue, _busyMask, _waitDelay, _waitCount, _status) \ -+{ \ -+ UINT_32 u4Temp; \ -+ UINT_32 u4Count = _waitCount; \ -+ (_status) = FALSE; \ -+ HAL_MCR_WR((_pAdapter), (_offset), (_writeValue)); \ -+ do { \ -+ kalUdelay((_waitDelay)); \ -+ HAL_MCR_RD((_pAdapter), (_offset), &u4Temp); \ -+ if (!(u4Temp & (_busyMask))) { \ -+ (_status) = TRUE; \ -+ break; \ -+ } \ -+ u4Count--; \ -+ } while (u4Count); \ -+} -+ -+#define HAL_GET_CHIP_ID_VER(_prAdapter, pu2ChipId, pu2Version) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WCIR, \ -+ &u4Value); \ -+ *pu2ChipId = (UINT_16)(u4Value & WCIR_CHIP_ID); \ -+ *pu2Version = (UINT_16)(u4Value & WCIR_REVISION_ID) >> 16; \ -+} -+ -+#define HAL_WAIT_WIFI_FUNC_READY(_prAdapter) \ -+{ \ -+ UINT_32 u4Value; \ -+ UINT_32 i; \ -+ for (i = 0; i < 100; i++) { \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WCIR, \ -+ &u4Value); \ -+ if (u4Value & WCIR_WLAN_READY) { \ -+ break; \ -+ } \ -+ NdisMSleep(10); \ -+ } \ -+} -+ -+#define HAL_INTR_DISABLE(_prAdapter) \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHLPCR, \ -+ WHLPCR_INT_EN_CLR) -+ -+#define HAL_INTR_ENABLE(_prAdapter) \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHLPCR, \ -+ WHLPCR_INT_EN_SET) -+ -+#define HAL_INTR_ENABLE_AND_LP_OWN_SET(_prAdapter) \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHLPCR, \ -+ (WHLPCR_INT_EN_SET | WHLPCR_FW_OWN_REQ_SET)) -+ -+#define HAL_LP_OWN_SET(_prAdapter) \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHLPCR, \ -+ WHLPCR_FW_OWN_REQ_SET) -+ -+#define HAL_LP_OWN_CLR_OK(_prAdapter, _pfgResult) \ -+{ \ -+ UINT_32 i; \ -+ UINT_32 u4RegValue; \ -+ UINT_32 u4LoopCnt = 2048 / 8; \ -+ *_pfgResult = TRUE; \ -+ /* Software get LP ownership */ \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHLPCR, \ -+ WHLPCR_FW_OWN_REQ_CLR) \ -+ for (i = 0; i < u4LoopCnt; i++) { \ -+ HAL_MCR_RD(_prAdapter, MCR_WHLPCR, &u4RegValue); \ -+ if (u4RegValue & WHLPCR_IS_DRIVER_OWN) { \ -+ break; \ -+ } \ -+ else { \ -+ kalUdelay(8); \ -+ } \ -+ } \ -+ if (i == u4LoopCnt) { \ -+ *_pfgResult = FALSE; \ -+ /*ERRORLOG(("LP cannot be own back (%ld)", u4LoopCnt));*/ \ -+ /* check the time of LP instructions need to perform from Sleep to On */ \ -+ /*ASSERT(0); */ \ -+ } \ -+} -+ -+#define HAL_GET_ABNORMAL_INTERRUPT_REASON_CODE(_prAdapter, pu4AbnormalReason) \ -+{ \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WASR, \ -+ pu4AbnormalReason); \ -+} -+ -+#define HAL_DISABLE_RX_ENHANCE_MODE(_prAdapter) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WHCR, \ -+ &u4Value); \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHCR, \ -+ u4Value & ~WHCR_RX_ENHANCE_MODE_EN); \ -+} -+ -+#define HAL_ENABLE_RX_ENHANCE_MODE(_prAdapter) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WHCR, \ -+ &u4Value); \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHCR, \ -+ u4Value | WHCR_RX_ENHANCE_MODE_EN); \ -+} -+ -+#define HAL_CFG_MAX_HIF_RX_LEN_NUM(_prAdapter, _ucNumOfRxLen) \ -+{ \ -+ UINT_32 u4Value, ucNum; \ -+ ucNum = ((_ucNumOfRxLen >= 16) ? 0 : _ucNumOfRxLen); \ -+ u4Value = 0; \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WHCR, \ -+ &u4Value); \ -+ u4Value &= ~WHCR_MAX_HIF_RX_LEN_NUM; \ -+ u4Value |= ((((UINT_32)ucNum) << 4) & WHCR_MAX_HIF_RX_LEN_NUM); \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHCR, \ -+ u4Value); \ -+} -+ -+#define HAL_SET_INTR_STATUS_READ_CLEAR(prAdapter) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(prAdapter, \ -+ MCR_WHCR, \ -+ &u4Value); \ -+ HAL_MCR_WR(prAdapter, \ -+ MCR_WHCR, \ -+ u4Value & ~WHCR_W_INT_CLR_CTRL); \ -+ prAdapter->prGlueInfo->rHifInfo.fgIntReadClear = TRUE;\ -+} -+ -+#define HAL_SET_INTR_STATUS_WRITE_1_CLEAR(prAdapter) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(prAdapter, \ -+ MCR_WHCR, \ -+ &u4Value); \ -+ HAL_MCR_WR(prAdapter, \ -+ MCR_WHCR, \ -+ u4Value | WHCR_W_INT_CLR_CTRL); \ -+ prAdapter->prGlueInfo->rHifInfo.fgIntReadClear = FALSE;\ -+} -+ -+/* Note: enhance mode structure may also carried inside the buffer, -+ if the length of the buffer is long enough */ -+#define HAL_READ_INTR_STATUS(prAdapter, length, pvBuf) \ -+ HAL_PORT_RD(prAdapter, \ -+ MCR_WHISR, \ -+ length, \ -+ pvBuf, \ -+ length) -+ -+#define HAL_READ_TX_RELEASED_COUNT(_prAdapter, aucTxReleaseCount) \ -+{ \ -+ PUINT_32 pu4Value = (PUINT_32)aucTxReleaseCount; \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WTSR0, \ -+ &pu4Value[0]); \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WTSR1, \ -+ &pu4Value[1]); \ -+} -+ -+#define HAL_READ_RX_LENGTH(prAdapter, pu2Rx0Len, pu2Rx1Len) \ -+{ \ -+ UINT_32 u4Value; \ -+ u4Value = 0; \ -+ HAL_MCR_RD(prAdapter, \ -+ MCR_WRPLR, \ -+ &u4Value); \ -+ *pu2Rx0Len = (UINT_16)u4Value; \ -+ *pu2Rx1Len = (UINT_16)(u4Value >> 16); \ -+} -+ -+#define HAL_GET_INTR_STATUS_FROM_ENHANCE_MODE_STRUCT(pvBuf, u2Len, pu4Status) \ -+{ \ -+ PUINT_32 pu4Buf = (PUINT_32)pvBuf; \ -+ *pu4Status = pu4Buf[0]; \ -+} -+ -+#define HAL_GET_TX_STATUS_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu4BufOut, u4LenBufOut) \ -+{ \ -+ PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \ -+ ASSERT(u4LenBufOut >= 8); \ -+ pu4BufOut[0] = pu4Buf[1]; \ -+ pu4BufOut[1] = pu4Buf[2]; \ -+} -+ -+#define HAL_GET_RX_LENGTH_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu2Rx0Num, au2Rx0Len, pu2Rx1Num, au2Rx1Len) \ -+{ \ -+ PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \ -+ ASSERT((sizeof(au2Rx0Len) / sizeof(UINT_16)) >= 16); \ -+ ASSERT((sizeof(au2Rx1Len) / sizeof(UINT_16)) >= 16); \ -+ *pu2Rx0Num = (UINT_16)pu4Buf[3]; \ -+ *pu2Rx1Num = (UINT_16)(pu4Buf[3] >> 16); \ -+ kalMemCopy(au2Rx0Len, &pu4Buf[4], 8); \ -+ kalMemCopy(au2Rx1Len, &pu4Buf[12], 8); \ -+} -+ -+#define HAL_GET_MAILBOX_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu4Mailbox0, pu4Mailbox1) \ -+{ \ -+ PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \ -+ *pu4Mailbox0 = (UINT_16)pu4Buf[21]; \ -+ *pu4Mailbox1 = (UINT_16)pu4Buf[22]; \ -+} -+ -+#define HAL_IS_TX_DONE_INTR(u4IntrStatus) \ -+ ((u4IntrStatus & WHISR_TX_DONE_INT) ? TRUE : FALSE) -+ -+#define HAL_IS_RX_DONE_INTR(u4IntrStatus) \ -+ ((u4IntrStatus & (WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT)) ? TRUE : FALSE) -+ -+#define HAL_IS_ABNORMAL_INTR(u4IntrStatus) \ -+ ((u4IntrStatus & WHISR_ABNORMAL_INT) ? TRUE : FALSE) -+ -+#define HAL_IS_FW_OWNBACK_INTR(u4IntrStatus) \ -+ ((u4IntrStatus & WHISR_FW_OWN_BACK_INT) ? TRUE : FALSE) -+ -+#define HAL_PUT_MAILBOX(prAdapter, u4MboxId, u4Data) \ -+{ \ -+ ASSERT(u4MboxId < 2); \ -+ HAL_MCR_WR(prAdapter, \ -+ ((u4MboxId == 0) ? MCR_H2DSM0R : MCR_H2DSM1R), \ -+ u4Data); \ -+} -+ -+#define HAL_GET_MAILBOX(prAdapter, u4MboxId, pu4Data) \ -+{ \ -+ ASSERT(u4MboxId < 2); \ -+ HAL_MCR_RD(prAdapter, \ -+ ((u4MboxId == 0) ? MCR_D2HRM0R : MCR_D2HRM1R), \ -+ pu4Data); \ -+} -+ -+#define HAL_SET_MAILBOX_READ_CLEAR(prAdapter, fgEnableReadClear) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(prAdapter, MCR_WHCR, &u4Value);\ -+ HAL_MCR_WR(prAdapter, MCR_WHCR, \ -+ (fgEnableReadClear) ? \ -+ (u4Value | WHCR_W_MAILBOX_RD_CLR_EN) : \ -+ (u4Value & ~WHCR_W_MAILBOX_RD_CLR_EN)); \ -+ prAdapter->prGlueInfo->rHifInfo.fgMbxReadClear = fgEnableReadClear;\ -+} -+ -+#define HAL_GET_MAILBOX_READ_CLEAR(prAdapter) (prAdapter->prGlueInfo->rHifInfo.fgMbxReadClear) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _HAL_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h -new file mode 100644 -index 0000000000000..b9aa154b097ef ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h -@@ -0,0 +1,220 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hif_rx.h#1 -+*/ -+ -+/*! \file "hif_rx.h" -+ \brief Provide HIF RX Header Information between F/W and Driver -+ -+ N/A -+*/ -+ -+/* -+** Log: hif_rx.h -+ * -+ * 09 01 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * follow-ups for HIF_RX_HEADER_T update: -+ * 1) add TCL -+ * 2) add RCPI -+ * 3) add ChannelNumber -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add necessary changes to driver data paths. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:44:00 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-09 13:59:20 GMT MTK02468 -+** Added HIF_RX_HDR parsing macros -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-24 19:54:54 GMT mtk02752 -+** adopt HIF_RX_HEADER_T in new data path -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-10-29 19:51:19 GMT mtk01084 -+** modify FW/ driver interface -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-28 10:33:58 GMT mtk01461 -+** Add define of HW_APPENED_LEN -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:51:02 GMT mtk01461 -+** Rename ENUM_HIF_RX_PKT_TYPE_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 12:05:03 GMT mtk01426 -+** Remove __KAL_ATTRIB_PACKED__ and add hifDataTypeCheck() -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:18:52 GMT mtk01426 -+** Add comment to HIF_RX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:23 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _HIF_RX_H -+#define _HIF_RX_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/*! HIF_RX_HEADER_T */ -+/* DW 0, Byte 1 */ -+#define HIF_RX_HDR_PACKET_TYPE_MASK BITS(0, 1) -+#define HIF_RX_HDR_SEC_MODE_MASK BITS(2, 5) -+#define HIF_RX_HDR_SEC_MODE_OFFSET 2 -+ -+/* DW 1, Byte 0 */ -+#define HIF_RX_HDR_HEADER_LEN BITS(2, 7) -+#define HIF_RX_HDR_HEADER_LEN_OFFSET 2 -+#define HIF_RX_HDR_HEADER_OFFSET_MASK BITS(0, 1) -+ -+/* DW 1, Byte 1 */ -+#define HIF_RX_HDR_80211_HEADER_FORMAT BIT(0) -+#define HIF_RX_HDR_DO_REORDER BIT(1) -+#define HIF_RX_HDR_PAL BIT(2) -+#define HIF_RX_HDR_TCL BIT(3) -+#define HIF_RX_HDR_NETWORK_IDX_MASK BITS(4, 7) -+#define HIF_RX_HDR_NETWORK_IDX_OFFSET 4 -+ -+/* DW 1, Byte 2, 3 */ -+#define HIF_RX_HDR_SEQ_NO_MASK BITS(0, 11) -+#define HIF_RX_HDR_TID_MASK BITS(12, 14) -+#define HIF_RX_HDR_TID_OFFSET 12 -+#define HIF_RX_HDR_BAR_FRAME BIT(15) -+ -+#define HIF_RX_HDR_FLAG_AMP_WDS BIT(0) -+#define HIF_RX_HDR_FLAG_802_11_FORMAT BIT(1) -+#define HIF_RX_HDR_FLAG_BAR_FRAME BIT(2) -+#define HIF_RX_HDR_FLAG_DO_REORDERING BIT(3) -+#define HIF_RX_HDR_FLAG_CTRL_WARPPER_FRAME BIT(4) -+ -+#define HIF_RX_HW_APPENDED_LEN 4 -+ -+/* For DW 2, Byte 3 - ucHwChannelNum */ -+#define HW_CHNL_NUM_MAX_2G4 14 -+#define HW_CHNL_NUM_MAX_4G_5G (255 - HW_CHNL_NUM_MAX_2G4) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef struct _HIF_RX_HEADER_T { -+ UINT_16 u2PacketLen; -+ UINT_16 u2PacketType; -+ UINT_8 ucHerderLenOffset; -+ UINT_8 uc80211_Reorder_PAL_TCL; -+ UINT_16 u2SeqNoTid; -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucRcpi; -+ UINT_8 ucHwChannelNum; -+ UINT_8 ucReserved; -+} HIF_RX_HEADER_T, *P_HIF_RX_HEADER_T; -+ -+typedef enum _ENUM_HIF_RX_PKT_TYPE_T { -+ HIF_RX_PKT_TYPE_DATA = 0, -+ HIF_RX_PKT_TYPE_EVENT, -+ HIF_RX_PKT_TYPE_TX_LOOPBACK, -+ HIF_RX_PKT_TYPE_MANAGEMENT, -+ HIF_RX_PKT_TYPE_NUM -+} ENUM_HIF_RX_PKT_TYPE_T, *P_ENUM_HIF_RX_PKT_TYPE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define HIF_RX_HDR_SIZE sizeof(HIF_RX_HEADER_T) -+ -+#define HIF_RX_HDR_GET_80211_FLAG(_prHifRxHdr) \ -+ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_80211_HEADER_FORMAT) ? TRUE : FALSE)) -+#define HIF_RX_HDR_GET_REORDER_FLAG(_prHifRxHdr) \ -+ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_DO_REORDER) ? TRUE : FALSE)) -+#define HIF_RX_HDR_GET_PAL_FLAG(_prHifRxHdr) \ -+ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_PAL) ? TRUE : FALSE)) -+#define HIF_RX_HDR_GET_TCL_FLAG(_prHifRxHdr) \ -+ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_TCL) ? TRUE : FALSE)) -+#define HIF_RX_HDR_GET_NETWORK_IDX(_prHifRxHdr) \ -+ ((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_NETWORK_IDX_MASK)\ -+ >> HIF_RX_HDR_NETWORK_IDX_OFFSET) -+ -+#define HIF_RX_HDR_GET_SEC_MODE(_prHifRxHdr) \ -+ ((((_prHifRxHdr)->u2PacketType) & HIF_RX_HDR_SEC_MODE_MASK) >> HIF_RX_HDR_SEC_MODE_OFFSET) -+ -+#define HIF_RX_HDR_GET_TID(_prHifRxHdr) \ -+ ((((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_TID_MASK)\ -+ >> HIF_RX_HDR_TID_OFFSET) -+#define HIF_RX_HDR_GET_SN(_prHifRxHdr) \ -+ (((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_SEQ_NO_MASK) -+#define HIF_RX_HDR_GET_BAR_FLAG(_prHifRxHdr) \ -+ (((((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_BAR_FRAME) ? TRUE : FALSE)) -+ -+#define HIF_RX_HDR_GET_CHNL_NUM(_prHifRxHdr) \ -+ ((((_prHifRxHdr)->ucHwChannelNum) > HW_CHNL_NUM_MAX_4G_5G) ? \ -+ (((_prHifRxHdr)->ucHwChannelNum) - HW_CHNL_NUM_MAX_4G_5G) : \ -+ ((_prHifRxHdr)->ucHwChannelNum)) -+ -+/* To do: support more bands other than 2.4G and 5G */ -+#define HIF_RX_HDR_GET_RF_BAND(_prHifRxHdr) \ -+ ((((_prHifRxHdr)->ucHwChannelNum) <= HW_CHNL_NUM_MAX_2G4) ? \ -+ BAND_2G4 : BAND_5G) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static inline VOID hifDataTypeCheck(VOID); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/* Kevin: we don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ * We'll need this for porting driver to different RTOS. -+ */ -+static inline VOID hifDataTypeCheck(VOID) -+{ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(HIF_RX_HEADER_T) == 12); -+ -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h -new file mode 100644 -index 0000000000000..17252f2c7760c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h -@@ -0,0 +1,214 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hif_tx.h#1 -+*/ -+ -+/* -+** Log: hif_tx.h -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * fill extra information for revised HIF_TX_HEADER. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add flag on MSDU_INFO_T for indicating BIP frame and forceBasicRate -+ * 2) add packet type for indicating management frames -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the Burst_End Indication mechanism -+ * -+ * 01 13 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * TX: fill ucWlanHeaderLength/ucPktFormtId_Flags according to info provided by prMsduInfo -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-10 16:43:40 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-24 19:55:11 GMT mtk02752 -+** adopt HIF_TX_HEADER_T in new data path -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-23 17:54:13 GMT mtk02752 -+** CMD_HDR_SIZE = (sizeof(WIFI_CMD_T)) to follow up CM's CMD/EVENT documentation -+** -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-17 22:41:10 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-17 17:34:07 GMT mtk02752 -+** remove HIF_TX_BUFF_COUNT_TC0 (move to nic_tx.h) -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-17 12:14:12 GMT mtk02752 -+** add initial value for HIF_TX_BUFF_COUNT_TC5 -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-11-13 13:54:18 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-11-04 14:11:14 GMT mtk01084 -+** modify SW TX data format -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-10-29 19:51:53 GMT mtk01084 -+** modify FW/ driver interface -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-05-20 12:22:46 GMT mtk01461 -+** Add SeqNum field to CMD Header -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-17 19:40:52 GMT mtk01461 -+** Update the Log Sign -+*/ -+ -+#ifndef _HIF_TX_H -+#define _HIF_TX_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Maximum buffer size for individual HIF TCQ Buffer */ -+#define HIF_TX_BUFF_MAX_SIZE 1552 /* Reserved field was not included */ -+ -+/* Maximum buffer count for individual HIF TCQ */ -+#define HIF_TX_BUFF_COUNT_TC0 3 -+#define HIF_TX_BUFF_COUNT_TC1 3 -+#define HIF_TX_BUFF_COUNT_TC2 3 -+#define HIF_TX_BUFF_COUNT_TC3 3 -+#define HIF_TX_BUFF_COUNT_TC4 2 -+ -+#define TX_HDR_SIZE sizeof(HIF_TX_HEADER_T) -+ -+#define CMD_HDR_SIZE sizeof(WIFI_CMD_T) -+ -+#define CMD_PKT_SIZE_FOR_IMAGE 2048 /* !< 2048 Bytes CMD payload buffer */ -+ -+/*! NIC_HIF_TX_HEADER_T */ -+/* DW 0, Byte 0,1 */ -+#define HIF_TX_HDR_TX_BYTE_COUNT_MASK BITS(0, 11) -+#define HIF_TX_HDR_USER_PRIORITY_OFFSET 12 -+ -+/* DW 0, Byte 2 */ -+#define HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK BITS(0, 7) -+ -+/* DW 0, Byte 3 */ -+#define HIF_TX_HDR_IP_CSUM BIT(0) -+#define HIF_TX_HDR_TCP_CSUM BIT(1) -+#define HIF_TX_HDR_RESOURCE_MASK BITS(2, 5) -+#define HIF_TX_HDR_RESOURCE_OFFSET 2 -+#define HIF_TX_HDR_PACKET_TYPE_MASK BITS(6, 7) -+#define HIF_TX_HDR_PACKET_TYPE_OFFSET 6 -+ -+/* DW 1, Byte 0 */ -+#define HIF_TX_HDR_WLAN_HEADER_LEN_MASK BITS(0, 5) -+ -+/* DW 1, Byte 1 */ -+#define HIF_TX_HDR_FORMAT_ID_MASK BITS(0, 2) -+#define HIF_TX_HDR_NETWORK_TYPE_MASK BITS(4, 5) -+#define HIF_TX_HDR_NETWORK_TYPE_OFFSET 4 -+#define HIF_TX_HDR_FLAG_1X_FRAME_MASK BIT(6) -+#define HIF_TX_HDR_FLAG_1X_FRAME_OFFSET 6 -+#define HIF_TX_HDR_FLAG_802_11_FORMAT_MASK BIT(7) -+#define HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET 7 -+ -+/* DW2, Byte 3 */ -+#define HIF_TX_HDR_PS_FORWARDING_TYPE_MASK BITS(0, 1) -+#define HIF_TX_HDR_PS_SESSION_ID_MASK BITS(2, 4) -+#define HIF_TX_HDR_PS_SESSION_ID_OFFSET 2 -+#define HIF_TX_HDR_BURST_END_MASK BIT(5) -+#define HIF_TX_HDR_BURST_END_OFFSET 5 -+ -+/* DW3, Byte 1 */ -+#define HIF_TX_HDR_NEED_ACK BIT(0) -+#define HIF_TX_HDR_BIP BIT(1) -+#define HIF_TX_HDR_BASIC_RATE BIT(2) -+#define HIF_TX_HDR_NEED_TX_DONE_STATUS BIT(3) -+#define HIF_TX_HDR_RTS BIT(4) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _HIF_HW_TX_HEADER_T { -+ UINT_16 u2TxByteCount; -+ UINT_8 ucEtherTypeOffset; -+ UINT_8 ucCSflags; -+ UINT_8 aucBuffer[0]; -+} HIF_HW_TX_HEADER_T, *P_HIF_HW_TX_HEADER_T; -+ -+typedef struct _HIF_TX_HEADER_T { -+ UINT_16 u2TxByteCount_UserPriority; -+ UINT_8 ucEtherTypeOffset; -+ UINT_8 ucResource_PktType_CSflags; -+ UINT_8 ucWlanHeaderLength; -+ UINT_8 ucPktFormtId_Flags; -+ UINT_16 u2LLH; /* for BOW */ -+ UINT_16 u2SeqNo; /* for BOW */ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucForwardingType_SessionID_Reserved; -+ UINT_8 ucPacketSeqNo; -+ UINT_8 ucAck_BIP_BasicRate; -+ UINT_8 aucReserved[2]; -+} HIF_TX_HEADER_T, *P_HIF_TX_HEADER_T; -+ -+typedef enum _ENUM_HIF_TX_PKT_TYPE_T { -+ HIF_TX_PKT_TYPE_DATA = 0, -+ HIF_TX_PKT_TYPE_CMD, -+ HIF_TX_PKT_TYPE_HIF_LOOPBACK, -+ HIF_TX_PKT_TYPE_MANAGEMENT, -+ HIF_TX_PKT_TYPE_NUM -+} ENUM_HIF_TX_PKT_TYPE_T, *P_ENUM_HIF_TX_PKT_TYPE_T; -+ -+typedef enum _ENUM_HIF_OOB_CTRL_PKT_TYPE_T { -+ HIF_OOB_CTRL_PKT_TYPE_LOOPBACK = 1, -+ HIF_OOB_CTRL_PKT_TYP_NUM -+} ENUM_HIF_OOB_CTRL_PKT_TYPE_T, *P_ENUM_HIF_OOB_CTRL_PKT_TYPE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define TFCB_FRAME_PAD_TO_DW(u2Length) ALIGN_4(u2Length) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* Kevin: we don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ */ -+static inline VOID hif_txDataTypeCheck(VOID); -+ -+static inline VOID hif_txDataTypeCheck(VOID) -+{ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(HIF_TX_HEADER_T) == 16); -+ -+} -+ -+#endif /*_HIF_TX_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h -new file mode 100644 -index 0000000000000..ff38d30c3cf2f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h -@@ -0,0 +1,2323 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/mac.h#1 -+*/ -+ -+/*! \file "mac.h" -+ \brief Brief description. -+ -+ Detail description. -+*/ -+ -+/* -+** Log: mac.h -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 06 22 2011 wh.su -+ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h -+ * and let the sw structure not align at byte -+ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte, -+ * Notice needed update P2P.ko. -+ * -+ * 05 06 2011 wh.su -+ * [WCXRP00000699] [MT6620 Wi-Fi][Driver] Add the ie pointer check for avoid TP-LINK AP send -+ * the wrong beacon make driver got incorrect support rate set -+ * Add the length check before access the ie length filed. -+ * -+ * 05 06 2011 wh.su -+ * [WCXRP00000699] [MT6620 Wi-Fi][Driver] Add the ie pointer check for avoid TP-LINK AP send -+ * the wrong beacon make driver got incorrect support rate set -+ * adding the length check before processing next ie.. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discover ability support. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Some action frame define is not belong to P2P. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Add some service discovery MAC define, phase I. -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver -+ * create branch for Wi-Fi driver v1.1 -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000256] [MT6620 Wi-Fi][Driver] Eliminate potential issues which is identified by Klockwork -+ * suppress warning reported by Klockwork. -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration -+ * revert to previous revision. (this file is not necessary to be changed) -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * 1. Add P2P MAC define. -+ * 2. Add scan device found event -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add WFA specific OUI. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P IE ID & Vendor OUI TYPE for P2P. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge MAC.h. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Added OFFSET_BAR_SSC_SN -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-12-09 14:00:24 GMT MTK02468 -+** Added offsets and masks for the BA Parameter Set filed -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:26 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _MAC_H -+#define _MAC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* 3 --------------- Constants for Ethernet/802.11 MAC --------------- */ -+/* MAC Address */ -+#define MAC_ADDR_LEN 6 -+ -+#define MAC_ADDR_LOCAL_ADMIN BIT(1) -+ -+#define ETH_P_IPV4 0x0800 -+#define ETH_P_IPX 0x8137 /* Novell IPX */ -+#define ETH_P_AARP 0x80F3 /* AppleTalk Address Resolution Protocol (AARP) */ -+#define ETH_P_IPV6 0x86DD -+ -+#define IP_VERSION_4 4 -+#define IP_VERSION_6 6 -+ -+#define IP_PROTOCOL_TCP 6 -+#define IP_PROTOCOL_UDP 17 -+ -+#define IPV4_HDR_IP_IDENTIFICATION_OFFSET 4 -+#define IPV4_HDR_IP_PROTOCOL_OFFSET 9 -+#define IPV4_HDR_IP_CSUM_OFFSET 10 -+#define IPV4_HDR_IP_SRC_ADDR_OFFSET 12 -+#define IPV4_HDR_IP_DST_ADDR_OFFSET 16 -+ -+#define IPV6_HDR_IP_PROTOCOL_OFFSET 6 -+#define IPV6_HDR_IP_SRC_ADDR_OFFSET 8 -+#define IPV6_HDR_IP_DST_ADDR_OFFSET 24 -+#define IPV6_HDR_IP_DST_ADDR_MAC_HIGH_OFFSET 32 -+#define IPV6_HDR_IP_DST_ADDR_MAC_LOW_OFFSET 37 -+#define IPV6_PROTOCOL_ICMPV6 0x3A -+#define IPV6_ADDR_LEN 16 -+#define IPV6_HDR_LEN 40 -+ -+#define ARP_OPERATION_OFFSET 6 -+#define ARP_SNEDER_MAC_OFFSET 8 -+#define ARP_SENDER_IP_OFFSET 14 -+#define ARP_TARGET_MAC_OFFSET 18 -+#define ARP_TARGET_IP_OFFSET 24 -+#define ARP_OPERATION_REQUEST 0x0001 -+#define ARP_OPERATION_RESPONSE 0x0002 -+ -+#define ICMPV6_TYPE_OFFSET 0 -+#define ICMPV6_FLAG_OFFSET 4 -+#define ICMPV6_TARGET_ADDR_OFFSET 8 -+#define ICMPV6_TARGET_LL_ADDR_TYPE_OFFSET 24 -+#define ICMPV6_TARGET_LL_ADDR_LEN_OFFSET 25 -+#define ICMPV6_TARGET_LL_ADDR_TA_OFFSET 26 -+ -+#define ICMPV6_FLAG_ROUTER_BIT BIT(7) -+#define ICMPV6_FLAG_SOLICITED_BIT BIT(6) -+#define ICMPV6_FLAG_OVERWRITE_BIT BIT(5) -+#define ICMPV6_TYPE_NEIGHBOR_SOLICITATION 0x87 -+#define ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT 0x88 -+ -+#define TCP_HDR_TCP_CSUM_OFFSET 16 -+#define UDP_HDR_UDP_CSUM_OFFSET 6 -+ -+#define LLC_LEN 8 /* LLC(3) + SNAP(3) + EtherType(2) */ -+ -+#define NULL_MAC_ADDR {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -+#define BC_MAC_ADDR {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} -+ -+/* Ethernet Frame Field Size, in byte */ -+#define ETHER_HEADER_LEN 14 -+#define ETHER_TYPE_LEN 2 -+#define ETHER_MIN_PKT_SZ 60 -+#define ETHER_MAX_PKT_SZ 1514 -+ -+/* IEEE 802.11 WLAN Frame Field Size, in byte */ -+#define WLAN_MAC_HEADER_LEN 24 /* Address 4 excluded */ -+#define WLAN_MAC_HEADER_A4_LEN 30 /* Address 4 included */ -+#define WLAN_MAC_HEADER_QOS_LEN 26 /* QoS Control included */ -+#define WLAN_MAC_HEADER_QOS_HTC_LEN 30 /* QoS Control and HTC included */ -+#define WLAN_MAC_HEADER_A4_QOS_LEN 32 /* Address 4 and QoS Control included */ -+#define WLAN_MAC_HEADER_A4_QOS_HTC_LEN 36 /* Address 4, QoS Control and HTC included */ -+#define WLAN_MAC_MGMT_HEADER_LEN 24 /* Address 4 excluded */ -+#define WLAN_MAC_MGMT_HEADER_HTC_LEN 28 /* HTC included */ -+ -+#define QOS_CTRL_LEN 2 -+#define HT_CTRL_LEN 4 -+ -+#define WLAN_MAC_CTS_ACK_LEN (WLAN_MAC_CTS_ACK_FRAME_HEADER_LEN + FCS_LEN) -+ -+/* 6.2.1.1.2 Semantics of the service primitive */ -+#define MSDU_MAX_LENGTH 2304 -+ -+/* 7.1.3.3.3 Broadcast BSSID */ -+#define BC_BSSID BC_MAC_ADDR -+ -+/* 7.1.3.7 FCS field */ -+#define FCS_LEN 4 -+ -+/* 7.3.1.6 Listen Interval field */ -+#define DEFAULT_LISTEN_INTERVAL_BY_DTIM_PERIOD 2 /* In unit of AP's DTIM interval, */ -+#define DEFAULT_LISTEN_INTERVAL 10 -+ -+/* 7.3.2.1 Broadcast(Wildcard) SSID */ -+#define BC_SSID "" -+#define BC_SSID_LEN 0 -+ -+/* 7.3.2.2 Data Rate Value */ -+#define RATE_1M 2 /* 1M in unit of 500kb/s */ -+#define RATE_2M 4 /* 2M */ -+#define RATE_5_5M 11 /* 5.5M */ -+#define RATE_11M 22 /* 11M */ -+#define RATE_22M 44 /* 22M */ -+#define RATE_33M 66 /* 33M */ -+#define RATE_6M 12 /* 6M */ -+#define RATE_9M 18 /* 9M */ -+#define RATE_12M 24 /* 12M */ -+#define RATE_18M 36 /* 18M */ -+#define RATE_24M 48 /* 24M */ -+#define RATE_36M 72 /* 36M */ -+#define RATE_48M 96 /* 48M */ -+#define RATE_54M 108 /* 54M */ -+/* 7.3.2.14 BSS membership selector */ -+#define RATE_HT_PHY 127 /* BSS Selector - Clause 20. HT PHY */ -+#define RATE_MASK BITS(0, 6) /* mask bits for the rate */ -+#define RATE_BASIC_BIT BIT(7) /* mask bit for the rate belonging to the BSSBasicRateSet */ -+ -+/* 8.3.2.2 TKIP MPDU formats */ -+#define TKIP_MIC_LEN 8 -+ -+/* 9.2.10 DIFS */ -+#define DIFS 2 /* 2 x aSlotTime */ -+ -+/* 11.3 STA Authentication and Association */ -+#define STA_STATE_1 0 /* Accept Class 1 frames */ -+#define STA_STATE_2 1 /* Accept Class 1 & 2 frames */ -+#define STA_STATE_3 2 /* Accept Class 1,2 & 3 frames */ -+ -+/* 15.4.8.5 802.11k RCPI-dBm mapping*/ -+#define NDBM_LOW_BOUND_FOR_RCPI 110 -+#define RCPI_LOW_BOUND 0 -+#define RCPI_HIGH_BOUND 220 -+#define RCPI_MEASUREMENT_NOT_AVAILABLE 255 -+ -+/* PHY characteristics */ -+/* 17.4.4/18.3.3/19.8.4 Slot Time (aSlotTime) */ -+#define SLOT_TIME_LONG 20 /* Long Slot Time */ -+#define SLOT_TIME_SHORT 9 /* Short Slot Time */ -+ -+#define SLOT_TIME_HR_DSSS SLOT_TIME_LONG /* 802.11b aSlotTime */ -+#define SLOT_TIME_OFDM SLOT_TIME_SHORT /* 802.11a aSlotTime(20M Spacing) */ -+#define SLOT_TIME_OFDM_10M_SPACING 13 /* 802.11a aSlotTime(10M Spacing) */ -+#define SLOT_TIME_ERP_LONG SLOT_TIME_LONG /* 802.11g aSlotTime(Long) */ -+#define SLOT_TIME_ERP_SHORT SLOT_TIME_SHORT /* 802.11g aSlotTime(Short) */ -+ -+/* 17.4.4/18.3.3/19.8.4 Contention Window (aCWmin & aCWmax) */ -+#define CWMIN_OFDM 15 /* 802.11a aCWmin */ -+#define CWMAX_OFDM 1023 /* 802.11a aCWmax */ -+ -+#define CWMIN_HR_DSSS 31 /* 802.11b aCWmin */ -+#define CWMAX_HR_DSSS 1023 /* 802.11b aCWmax */ -+ -+#define CWMIN_ERP_0 31 /* 802.11g aCWmin(0) - for only have 1/2/5/11Mbps Rates */ -+#define CWMIN_ERP_1 15 /* 802.11g aCWmin(1) */ -+#define CWMAX_ERP 1023 /* 802.11g aCWmax */ -+ -+/* Short Inter-Frame Space (aSIFSTime) */ -+/* 15.3.3 802.11b aSIFSTime */ -+#define SIFS_TIME_HR_DSSS 10 -+/* 17.4.4 802.11a aSIFSTime */ -+#define SIFS_TIME_OFDM 16 -+/* 19.8.4 802.11g aSIFSTime */ -+#define SIFS_TIME_ERP 10 -+ -+/* 15.4.6.2 Number of operating channels */ -+#define CH_1 0x1 -+#define CH_2 0x2 -+#define CH_3 0x3 -+#define CH_4 0x4 -+#define CH_5 0x5 -+#define CH_6 0x6 -+#define CH_7 0x7 -+#define CH_8 0x8 -+#define CH_9 0x9 -+#define CH_10 0xa -+#define CH_11 0xb -+#define CH_12 0xc -+#define CH_13 0xd -+#define CH_14 0xe -+ -+#define MAXIMUM_OPERATION_CHANNEL_LIST 46 -+ -+/* 3 --------------- IEEE 802.11 PICS --------------- */ -+/* Annex D - dot11OperationEntry 2 */ -+#define DOT11_RTS_THRESHOLD_MIN 0 -+#define DOT11_RTS_THRESHOLD_MAX 2347 /* from Windows DDK */ -+/* #define DOT11_RTS_THRESHOLD_MAX 3000 // from Annex D */ -+ -+#define DOT11_RTS_THRESHOLD_DEFAULT \ -+ DOT11_RTS_THRESHOLD_MAX -+ -+/* Annex D - dot11OperationEntry 5 */ -+#define DOT11_FRAGMENTATION_THRESHOLD_MIN 256 -+#define DOT11_FRAGMENTATION_THRESHOLD_MAX 2346 /* from Windows DDK */ -+/* #define DOT11_FRAGMENTATION_THRESHOLD_MAX 3000 // from Annex D */ -+ -+#define DOT11_FRAGMENTATION_THRESHOLD_DEFAULT \ -+ DOT11_FRAGMENTATION_THRESHOLD_MAX -+ -+/* Annex D - dot11OperationEntry 6 */ -+#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_MIN 1 -+#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_MAX 0xFFFFffff -+#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_DEFAULT 4095 /* 802.11 define 512 */ -+ /* MT5921 only aceept N <= 4095 */ -+ -+/* Annex D - dot11OperationEntry 7 */ -+#define DOT11_RECEIVE_LIFETIME_TU_MIN 1 -+#define DOT11_RECEIVE_LIFETIME_TU_MAX 0xFFFFffff -+#define DOT11_RECEIVE_LIFETIME_TU_DEFAULT 4096 /* 802.11 define 512 */ -+ -+/* Annex D - dot11StationConfigEntry 12 */ -+#define DOT11_BEACON_PERIOD_MIN 1 /* TU. */ -+#define DOT11_BEACON_PERIOD_MAX 0xffff /* TU. */ -+#define DOT11_BEACON_PERIOD_DEFAULT 100 /* TU. */ -+ -+/* Annex D - dot11StationConfigEntry 13 */ -+#define DOT11_DTIM_PERIOD_MIN 1 /* TU. */ -+#define DOT11_DTIM_PERIOD_MAX 255 /* TU. */ -+#define DOT11_DTIM_PERIOD_DEFAULT 1 /* TU. */ -+ -+/* Annex D - dot11RegDomainsSupportValue */ -+#define REGULATION_DOMAIN_FCC 0x10 /* FCC (US) */ -+#define REGULATION_DOMAIN_IC 0x20 /* IC or DOC (Canada) */ -+#define REGULATION_DOMAIN_ETSI 0x30 /* ETSI (Europe) */ -+#define REGULATION_DOMAIN_SPAIN 0x31 /* Spain */ -+#define REGULATION_DOMAIN_FRANCE 0x32 /* France */ -+#define REGULATION_DOMAIN_JAPAN 0x40 /* MKK (Japan) */ -+#define REGULATION_DOMAIN_CHINA 0x50 /* China */ -+#define REGULATION_DOMAIN_OTHER 0x00 /* Other */ -+ -+/* 3 --------------- IEEE 802.11 MAC header fields --------------- */ -+/* 7.1.3.1 Masks for the subfields in the Frame Control field */ -+#define MASK_FC_PROTOCOL_VER BITS(0, 1) -+#define MASK_FC_TYPE BITS(2, 3) -+#define MASK_FC_SUBTYPE BITS(4, 7) -+#define MASK_FC_SUBTYPE_QOS_DATA BIT(7) -+#define MASK_FC_TO_DS BIT(8) -+#define MASK_FC_FROM_DS BIT(9) -+#define MASK_FC_MORE_FRAG BIT(10) -+#define MASK_FC_RETRY BIT(11) -+#define MASK_FC_PWR_MGT BIT(12) -+#define MASK_FC_MORE_DATA BIT(13) -+#define MASK_FC_PROTECTED_FRAME BIT(14) -+#define MASK_FC_ORDER BIT(15) -+ -+#define MASK_FRAME_TYPE (MASK_FC_TYPE | MASK_FC_SUBTYPE) -+#define MASK_TO_DS_FROM_DS (MASK_FC_TO_DS | MASK_FC_FROM_DS) -+ -+#define MAX_NUM_OF_FC_SUBTYPES 16 -+#define OFFSET_OF_FC_SUBTYPE 4 -+ -+/* 7.1.3.1.2 MAC frame types and subtypes */ -+#define MAC_FRAME_TYPE_MGT 0 -+#define MAC_FRAME_TYPE_CTRL BIT(2) -+#define MAC_FRAME_TYPE_DATA BIT(3) -+#define MAC_FRAME_TYPE_QOS_DATA (MAC_FRAME_TYPE_DATA | MASK_FC_SUBTYPE_QOS_DATA) -+ -+#define MAC_FRAME_ASSOC_REQ (MAC_FRAME_TYPE_MGT | 0x0000) -+#define MAC_FRAME_ASSOC_RSP (MAC_FRAME_TYPE_MGT | 0x0010) -+#define MAC_FRAME_REASSOC_REQ (MAC_FRAME_TYPE_MGT | 0x0020) -+#define MAC_FRAME_REASSOC_RSP (MAC_FRAME_TYPE_MGT | 0x0030) -+#define MAC_FRAME_PROBE_REQ (MAC_FRAME_TYPE_MGT | 0x0040) -+#define MAC_FRAME_PROBE_RSP (MAC_FRAME_TYPE_MGT | 0x0050) -+#define MAC_FRAME_BEACON (MAC_FRAME_TYPE_MGT | 0x0080) -+#define MAC_FRAME_ATIM (MAC_FRAME_TYPE_MGT | 0x0090) -+#define MAC_FRAME_DISASSOC (MAC_FRAME_TYPE_MGT | 0x00A0) -+#define MAC_FRAME_AUTH (MAC_FRAME_TYPE_MGT | 0x00B0) -+#define MAC_FRAME_DEAUTH (MAC_FRAME_TYPE_MGT | 0x00C0) -+#define MAC_FRAME_ACTION (MAC_FRAME_TYPE_MGT | 0x00D0) -+#define MAC_FRAME_ACTION_NO_ACK (MAC_FRAME_TYPE_MGT | 0x00E0) -+ -+#define MAC_FRAME_CONTRL_WRAPPER (MAC_FRAME_TYPE_CTRL | 0x0070) -+#define MAC_FRAME_BLOCK_ACK_REQ (MAC_FRAME_TYPE_CTRL | 0x0080) -+#define MAC_FRAME_BLOCK_ACK (MAC_FRAME_TYPE_CTRL | 0x0090) -+#define MAC_FRAME_PS_POLL (MAC_FRAME_TYPE_CTRL | 0x00A0) -+#define MAC_FRAME_RTS (MAC_FRAME_TYPE_CTRL | 0x00B0) -+#define MAC_FRAME_CTS (MAC_FRAME_TYPE_CTRL | 0x00C0) -+#define MAC_FRAME_ACK (MAC_FRAME_TYPE_CTRL | 0x00D0) -+#define MAC_FRAME_CF_END (MAC_FRAME_TYPE_CTRL | 0x00E0) -+#define MAC_FRAME_CF_END_CF_ACK (MAC_FRAME_TYPE_CTRL | 0x00F0) -+ -+#define MAC_FRAME_DATA (MAC_FRAME_TYPE_DATA | 0x0000) -+#define MAC_FRAME_DATA_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0010) -+#define MAC_FRAME_DATA_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0020) -+#define MAC_FRAME_DATA_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0030) -+#define MAC_FRAME_NULL (MAC_FRAME_TYPE_DATA | 0x0040) -+#define MAC_FRAME_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0050) -+#define MAC_FRAME_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0060) -+#define MAC_FRAME_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0070) -+#define MAC_FRAME_QOS_DATA (MAC_FRAME_TYPE_DATA | 0x0080) -+#define MAC_FRAME_QOS_DATA_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0090) -+#define MAC_FRAME_QOS_DATA_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00A0) -+#define MAC_FRAME_QOS_DATA_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00B0) -+#define MAC_FRAME_QOS_NULL (MAC_FRAME_TYPE_DATA | 0x00C0) -+#define MAC_FRAME_QOS_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00E0) -+#define MAC_FRAME_QOS_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00F0) -+ -+/* 7.1.3.2 Mask for the AID value in the Duration/ID field */ -+#define MASK_DI_DURATION BITS(0, 14) -+#define MASK_DI_AID BITS(0, 13) -+#define MASK_DI_AID_MSB BITS(14, 15) -+#define MASK_DI_CFP_FIXED_VALUE BIT(15) -+ -+/* 7.1.3.4 Masks for the subfields in the Sequence Control field */ -+#define MASK_SC_SEQ_NUM BITS(4, 15) -+#define MASK_SC_SEQ_NUM_OFFSET 4 -+#define MASK_SC_FRAG_NUM BITS(0, 3) -+#define INVALID_SEQ_CTRL_NUM 0x000F /* According to 6.2.1.1.2 -+ * FRAG_NUM won't equal to 15 -+ */ -+ -+/* 7.1.3.5 QoS Control field */ -+#define TID_NUM 16 -+#define TID_MASK BITS(0, 3) -+#define EOSP BIT(4) -+#define ACK_POLICY BITS(5, 6) -+#define A_MSDU_PRESENT BIT(7) -+ -+#define MASK_QC_TID BITS(0, 3) -+#define MASK_QC_EOSP BIT(4) -+#define MASK_QC_EOSP_OFFSET 4 -+#define MASK_QC_ACK_POLICY BITS(5, 6) -+#define MASK_QC_ACK_POLICY_OFFSET 5 -+#define MASK_QC_A_MSDU_PRESENT BIT(7) -+ -+/* 7.1.3.5a HT Control field */ -+#define HT_CTRL_LINK_ADAPTATION_CTRL BITS(0, 15) -+#define HT_CTRL_CALIBRATION_POSITION BITS(16, 17) -+#define HT_CTRL_CALIBRATION_SEQUENCE BITS(18, 19) -+#define HT_CTRL_CSI_STEERING BITS(22, 23) -+#define HT_CTRL_NDP_ANNOUNCEMENT BIT(24) -+#define HT_CTRL_AC_CONSTRAINT BIT(30) -+#define HT_CTRL_RDG_MORE_PPDU BIT(31) -+ -+#define LINK_ADAPTATION_CTRL_TRQ BIT(1) -+#define LINK_ADAPTATION_CTRL_MAI_MRQ BIT(2) -+#define LINK_ADAPTATION_CTRL_MAI_MSI BITS(3, 5) -+#define LINK_ADAPTATION_CTRL_MFSI BITS(6, 8) -+#define LINK_ADAPTATION_CTRL_MFB_ASELC_CMD BITS(9, 11) -+#define LINK_ADAPTATION_CTRL_MFB_ASELC_DATA BITS(12, 15) -+ -+/* 7.1.3.5.3 Ack Policy subfield*/ -+#define ACK_POLICY_NORMAL_ACK_IMPLICIT_BA_REQ 0 -+#define ACK_POLICY_NO_ACK 1 -+#define ACK_POLICY_NO_EXPLICIT_ACK_PSMP_ACK 2 -+#define ACK_POLICY_BA 3 -+ -+/* 7.1.3.7 FCS field */ -+#define FCS_LEN 4 -+ -+/* 7.2.1.4 WLAN Control Frame - PS-POLL Frame */ -+#define PSPOLL_FRAME_LEN 16 /* w/o FCS */ -+ -+/* 7.2.7.1 BAR */ -+#define OFFSET_BAR_SSC_SN 4 -+ -+/* 8.3.2.2 TKIP MPDU formats */ -+#define TKIP_MIC_LEN 8 -+ -+/* 2009.11.30 mtk02468: Moved these definitions to the right place */ -+#if 0 -+/* Block Ack Parameter Set field */ -+#define BA_PARM_BA_POLICY BIT(1) -+#define BA_PARM_TID BITS(2, 5) -+#define BA_PARM_BUFFER_SIZE BITS(6, 15) -+#endif -+ -+#define BA_POLICY_IMMEDIATE BIT(1) -+ -+/* Block Ack Starting Sequence Control field */ -+#define BA_START_SEQ_CTL_FRAG_NUM BITS(0, 3) -+#define BA_START_SEQ_CTL_SSN BITS(4, 15) -+ -+/* BAR Control field */ -+#define BAR_CONTROL_NO_ACK_POLICY BIT(0) -+#define BAR_CONTROL_MULTI_TID BIT(1) -+#define BAR_CONTROL_COMPRESSED_BA BIT(2) -+#define BAR_CONTROL_TID_INFO BITS(12, 15) -+#define BAR_CONTROL_TID_INFO_OFFSET 12 -+ -+/* TID Value */ -+#define BAR_INFO_TID_VALUE BITS(12, 15) -+ -+#define BAR_COMPRESSED_VARIANT_FRAME_LEN (16 + 4) -+ -+/* 3 --------------- IEEE 802.11 frame body fields --------------- */ -+/* 3 Management frame body components (I): Fixed Fields. */ -+/* 7.3.1.1 Authentication Algorithm Number field */ -+#define AUTH_ALGORITHM_NUM_FIELD_LEN 2 -+ -+#define AUTH_ALGORITHM_NUM_OPEN_SYSTEM 0 /* Open System */ -+#define AUTH_ALGORITHM_NUM_SHARED_KEY 1 /* Shared Key */ -+#define AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION 2 /* Fast BSS Transition */ -+ -+/* 7.3.1.2 Authentication Transaction Sequence Number field */ -+#define AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN 2 -+#define AUTH_TRANSACTION_SEQ_1 1 -+#define AUTH_TRANSACTION_SEQ_2 2 -+#define AUTH_TRANSACTION_SEQ_3 3 -+#define AUTH_TRANSACTION_SEQ_4 4 -+ -+/* 7.3.1.3 Beacon Interval field */ -+#define BEACON_INTERVAL_FIELD_LEN 2 -+ -+/* 7.3.1.4 Capability Information field */ -+#define CAP_INFO_FIELD_LEN 2 -+#define CAP_INFO_ESS BIT(0) -+#define CAP_INFO_IBSS BIT(1) -+#define CAP_INFO_BSS_TYPE (CAP_INFO_ESS | CAP_INFO_IBSS) -+#define CAP_INFO_CF_POLLABLE BIT(2) -+#define CAP_INFO_CF_POLL_REQ BIT(3) -+#define CAP_INFO_CF (CAP_INFO_CF_POLLABLE | CAP_INFO_CF_POLL_REQ) -+#define CAP_INFO_PRIVACY BIT(4) -+#define CAP_INFO_SHORT_PREAMBLE BIT(5) -+#define CAP_INFO_PBCC BIT(6) -+#define CAP_INFO_CH_AGILITY BIT(7) -+#define CAP_INFO_SPEC_MGT BIT(8) -+#define CAP_INFO_QOS BIT(9) -+#define CAP_INFO_SHORT_SLOT_TIME BIT(10) -+#define CAP_INFO_APSD BIT(11) -+#define CAP_INFO_RESERVED BIT(12) -+#define CAP_INFO_DSSS_OFDM BIT(13) -+#define CAP_INFO_DELAYED_BLOCK_ACK BIT(14) -+#define CAP_INFO_IMM_BLOCK_ACK BIT(15) -+/* STA usage of CF-Pollable and CF-Poll Request subfields */ -+/* STA: not CF-Pollable */ -+#define CAP_CF_STA_NOT_POLLABLE 0x0000 -+/* STA: CF-Pollable, not requesting on the CF-Polling list */ -+#define CAP_CF_STA_NOT_ON_LIST CAP_INFO_CF_POLL_REQ -+/* STA: CF-Pollable, requesting on the CF-Polling list */ -+#define CAP_CF_STA_ON_LIST CAP_INFO_CF_POLLABLE -+/* STA: CF-Pollable, requesting never to be polled */ -+#define CAP_CF_STA_NEVER_POLLED (CAP_INFO_CF_POLLABLE | CAP_INFO_CF_POLL_REQ) -+ -+/* AP usage of CF-Pollable and CF-Poll Request subfields */ -+/* AP: No point coordinator (PC) */ -+#define CAP_CF_AP_NO_PC 0x0000 -+/* AP: PC at AP for delivery only (no polling) */ -+#define CAP_CF_AP_DELIVERY_ONLY CAP_INFO_CF_POLL_REQ -+/* AP: PC at AP for delivery and polling */ -+#define CAP_CF_AP_DELIVERY_POLLING CAP_INFO_CF_POLLABLE -+ -+/* 7.3.1.5 Current AP Address field */ -+#define CURR_AP_ADDR_FIELD_LEN MAC_ADDR_LEN -+ -+/* 7.3.1.6 Listen Interval field */ -+#define LISTEN_INTERVAL_FIELD_LEN 2 -+ -+/* 7.3.1.7 Reason Code field */ -+#define REASON_CODE_FIELD_LEN 2 -+ -+#define REASON_CODE_RESERVED 0 /* Reseved */ -+#define REASON_CODE_UNSPECIFIED 1 /* Unspecified reason */ -+#define REASON_CODE_PREV_AUTH_INVALID 2 /* Previous auth no longer valid */ -+#define REASON_CODE_DEAUTH_LEAVING_BSS 3 /* Deauth because sending STA is leaving BSS */ -+#define REASON_CODE_DISASSOC_INACTIVITY 4 /* Disassoc due to inactivity */ -+#define REASON_CODE_DISASSOC_AP_OVERLOAD 5 /* Disassoc because AP is unable to handle all assoc STAs */ -+#define REASON_CODE_CLASS_2_ERR 6 /* Class 2 frame rx from nonauth STA */ -+#define REASON_CODE_CLASS_3_ERR 7 /* Class 3 frame rx from nonassoc STA */ -+#define REASON_CODE_DISASSOC_LEAVING_BSS 8 /* Disassoc because sending STA is leaving BSS */ -+#define REASON_CODE_ASSOC_BEFORE_AUTH 9 /* STA requesting (re)assoc is not auth with responding STA */ -+#define REASON_CODE_DISASSOC_PWR_CAP_UNACCEPTABLE 10 /* Disassoc because the info in Power Capability is -+ unacceptable */ -+#define REASON_CODE_DISASSOC_SUP_CHS_UNACCEPTABLE 11 /* Disassoc because the info in Supported Channels is -+ unacceptable */ -+#define REASON_CODE_INVALID_INFO_ELEM 13 /* Invalid information element */ -+#define REASON_CODE_MIC_FAILURE 14 /* MIC failure */ -+#define REASON_CODE_4_WAY_HANDSHAKE_TIMEOUT 15 /* 4-way handshake timeout */ -+#define REASON_CODE_GROUP_KEY_UPDATE_TIMEOUT 16 /* Group key update timeout */ -+#define REASON_CODE_DIFFERENT_INFO_ELEM 17 /* Info element in 4-way handshake different from -+ (Re-)associate request/Probe response/Beacon */ -+#define REASON_CODE_MULTICAST_CIPHER_NOT_VALID 18 /* Multicast Cipher is not valid */ -+#define REASON_CODE_UNICAST_CIPHER_NOT_VALID 19 /* Unicast Cipher is not valid */ -+#define REASON_CODE_AKMP_NOT_VALID 20 /* AKMP is not valid */ -+#define REASON_CODE_UNSUPPORTED_RSNE_VERSION 21 /* Unsupported RSNE version */ -+#define REASON_CODE_INVALID_RSNE_CAPABILITIES 22 /* Invalid RSNE Capabilities */ -+#define REASON_CODE_IEEE_802_1X_AUTH_FAILED 23 /* IEEE 802.1X Authentication failed */ -+#define REASON_CODE_CIPHER_REJECT_SEC_POLICY 24 /* Cipher suite rejected because of the security policy */ -+#define REASON_CODE_DISASSOC_UNSPECIFIED_QOS 32 /* Disassoc for unspecified, QoS-related reason */ -+#define REASON_CODE_DISASSOC_LACK_OF_BANDWIDTH 33 /* Disassoc because QAP lacks sufficient bandwidth -+ for this QSTA */ -+#define REASON_CODE_DISASSOC_ACK_LOST_POOR_CHANNEL 34 /* Disassoc because of too many ACKs lost for AP transmissions -+ and/or poor channel conditions */ -+#define REASON_CODE_DISASSOC_TX_OUTSIDE_TXOP_LIMIT 35 /* Disassoc because QSTA is transmitting outside the limits of -+ its TXOPs */ -+#define REASON_CODE_PEER_WHILE_LEAVING 36 /* QSTA is leaving the QBSS or resetting */ -+#define REASON_CODE_PEER_REFUSE_DLP 37 /* Peer does not want to use this mechanism */ -+#define REASON_CODE_PEER_SETUP_REQUIRED 38 /* Frames received but a setup is reqired */ -+#define REASON_CODE_PEER_TIME_OUT 39 /* Time out */ -+#define REASON_CODE_PEER_CIPHER_UNSUPPORTED 45 /* Peer does not support the requested cipher suite */ -+#define REASON_CODE_BEACON_TIMEOUT 100 /* for beacon timeout, defined by mediatek */ -+#define REASON_CODE_BSS_SECURITY_CHANGE 101 /* for BSS security change, defined by mediatek */ -+/* 7.3.1.8 AID field */ -+#define AID_FIELD_LEN 2 -+#define AID_MASK BITS(0, 13) -+#define AID_MSB BITS(14, 15) -+#define AID_MIN_VALUE 1 -+#define AID_MAX_VALUE 2007 -+ -+/* 7.3.1.9 Status Code field */ -+#define STATUS_CODE_FIELD_LEN 2 -+ -+#define STATUS_CODE_RESERVED 0 /* Reserved - Used by TX Auth */ -+#define STATUS_CODE_SUCCESSFUL 0 /* Successful */ -+#define STATUS_CODE_UNSPECIFIED_FAILURE 1 /* Unspecified failure */ -+#define STATUS_CODE_CAP_NOT_SUPPORTED 10 /* Cannot support all requested cap in the Cap Info field */ -+#define STATUS_CODE_REASSOC_DENIED_WITHOUT_ASSOC 11 /* Reassoc denied due to inability to confirm that -+ assoc exists */ -+#define STATUS_CODE_ASSOC_DENIED_OUTSIDE_STANDARD 12 /* Assoc denied due to reason outside the scope of this std. */ -+#define STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED 13 /* Responding STA does not support the specified -+ auth algorithm */ -+#define STATUS_CODE_AUTH_OUT_OF_SEQ 14 /* Rx an auth frame with auth transaction seq num -+ out of expected seq */ -+#define STATUS_CODE_AUTH_REJECTED_CHAL_FAIL 15 /* Auth rejected because of challenge failure */ -+#define STATUS_CODE_AUTH_REJECTED_TIMEOUT 16 /* Auth rejected due to timeout waiting for next frame -+ in sequence */ -+#define STATUS_CODE_ASSOC_DENIED_AP_OVERLOAD 17 /* Assoc denied because AP is unable to handle additional -+ assoc STAs */ -+#define STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED 18 /* Assoc denied due to requesting STA not supporting -+ all of basic rates */ -+#define STATUS_CODE_ASSOC_DENIED_NO_SHORT_PREAMBLE 19 /* Assoc denied due to requesting STA not supporting short -+ preamble */ -+#define STATUS_CODE_ASSOC_DENIED_NO_PBCC 20 /* Assoc denied due to requesting STA not supporting PBCC */ -+#define STATUS_CODE_ASSOC_DENIED_NO_CH_AGILITY 21 /* Assoc denied due to requesting STA not supporting channel -+ agility */ -+#define STATUS_CODE_ASSOC_REJECTED_NO_SPEC_MGT 22 /* Assoc rejected because Spectrum Mgt capability is required */ -+#define STATUS_CODE_ASSOC_REJECTED_PWR_CAP 23 /* Assoc rejected because the info in Power Capability -+ is unacceptable */ -+#define STATUS_CODE_ASSOC_REJECTED_SUP_CHS 24 /* Assoc rejected because the info in Supported Channels -+ is unacceptable */ -+#define STATUS_CODE_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25 /* Assoc denied due to requesting STA not supporting -+ short slot time */ -+#define STATUS_CODE_ASSOC_DENIED_NO_DSSS_OFDM 26 /* Assoc denied due to requesting STA not supporting -+ DSSS-OFDM */ -+#if CFG_SUPPORT_802_11W -+#define STATUS_CODE_ASSOC_REJECTED_TEMPORARILY 30 /* IEEE 802.11w, Assoc denied due to the SA query */ -+#define STATUS_CODE_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31 /* IEEE 802.11w, Assoc denied due to the MFP select -+ policy */ -+#endif -+#define STATUS_CODE_UNSPECIFIED_QOS_FAILURE 32 /* Unspecified, QoS-related failure */ -+#define STATUS_CODE_ASSOC_DENIED_BANDWIDTH 33 /* Assoc denied due to insufficient bandwidth to handle another -+ QSTA */ -+#define STATUS_CODE_ASSOC_DENIED_POOR_CHANNEL 34 /* Assoc denied due to excessive frame loss rates and/or poor -+ channel conditions */ -+#define STATUS_CODE_ASSOC_DENIED_NO_QOS_FACILITY 35 /* Assoc denied due to requesting STA not supporting QoS -+ facility */ -+#define STATUS_CODE_REQ_DECLINED 37 /* Request has been declined */ -+#define STATUS_CODE_REQ_INVALID_PARAMETER_VALUE 38 /* Request has not been successful as one or more parameters -+ have invalid values */ -+#define STATUS_CODE_REQ_NOT_HONORED_TSPEC 39 /* TS not created because request cannot be honored. -+ Suggested TSPEC provided. */ -+#define STATUS_CODE_INVALID_INFO_ELEMENT 40 /* Invalid information element */ -+#define STATUS_CODE_INVALID_GROUP_CIPHER 41 /* Invalid group cipher */ -+#define STATUS_CODE_INVALID_PAIRWISE_CIPHER 42 /* Invalid pairwise cipher */ -+#define STATUS_CODE_INVALID_AKMP 43 /* Invalid AKMP */ -+#define STATUS_CODE_UNSUPPORTED_RSN_IE_VERSION 44 /* Unsupported RSN information element version */ -+#define STATUS_CODE_INVALID_RSN_IE_CAP 45 /* Invalid RSN information element capabilities */ -+#define STATUS_CODE_CIPHER_SUITE_REJECTED 46 /* Cipher suite rejected because of security policy */ -+#define STATUS_CODE_REQ_NOT_HONORED_TS_DELAY 47 /* TS not created because request cannot be honored. -+ Attempt to create a TS later. */ -+#define STATUS_CODE_DIRECT_LINK_NOT_ALLOWED 48 /* Direct Link is not allowed in the BSS by policy */ -+#define STATUS_CODE_DESTINATION_STA_NOT_PRESENT 49 /* Destination STA is not present within this QBSS */ -+#define STATUS_CODE_DESTINATION_STA_NOT_QSTA 50 /* Destination STA is not a QSTA */ -+#define STATUS_CODE_ASSOC_DENIED_LARGE_LIS_INTERVAL 51 /* Association denied because the ListenInterval is too large */ -+ -+/* proprietary definition of reserved field of Status Code */ -+#define STATUS_CODE_JOIN_FAILURE 0xFFF0 /* Join failure */ -+#define STATUS_CODE_JOIN_TIMEOUT 0xFFF1 /* Join timeout */ -+#define STATUS_CODE_AUTH_TIMEOUT 0xFFF2 /* Authentication timeout */ -+#define STATUS_CODE_ASSOC_TIMEOUT 0xFFF3 /* (Re)Association timeout */ -+#define STATUS_CODE_CCX_CCKM_REASSOC_FAILURE 0xFFF4 /* CCX CCKM reassociation failure */ -+ -+/* 7.3.1.10 Timestamp field */ -+#define TIMESTAMP_FIELD_LEN 8 -+ -+/* 7.3.1.11 Category of Action field */ -+#define CATEGORY_SPEC_MGT 0 -+#define CATEGORY_QOS_ACTION 1 /* QoS action */ -+#define CATEGORY_DLS_ACTION 2 /* Direct Link Protocol (DLP) action */ -+#define CATEGORY_BLOCK_ACK_ACTION 3 /* Block ack action */ -+#define CATEGORY_PUBLIC_ACTION 4 /* Public action */ -+#define CATEGORY_RM_ACTION 5 /* Radio measurement action */ -+#define CATEGORY_HT_ACTION 7 -+#if CFG_SUPPORT_802_11W -+#define CATEGORY_SA_QUERT_ACTION 8 -+#endif -+#define CATEGORY_WNM_ACTION 10 /* 802.11v Wireless Network Management */ -+#define CATEGORY_UNPROTECTED_WNM_ACTION 11 /* 802.11v Wireless Network Management */ -+#define CATEGORY_WME_MGT_NOTIFICATION 17 /* WME management notification */ -+#define CATEGORY_VENDOR_SPECIFIC_ACTION 127 -+ -+/* 7.3.1.14 Block Ack Parameter Set field */ -+#define BA_PARAM_SET_ACK_POLICY_MASK BIT(1) -+#define BA_PARAM_SET_ACK_POLICY_MASK_OFFSET 1 -+#define BA_PARAM_SET_TID_MASK BITS(2, 5) -+#define BA_PARAM_SET_TID_MASK_OFFSET 2 -+#define BA_PARAM_SET_BUFFER_SIZE_MASK BITS(6, 15) -+#define BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET 6 -+ -+#define BA_PARAM_SET_ACK_POLICY_IMMEDIATE_BA 1 -+#define BA_PARAM_SET_ACK_POLICY_DELAYED_BA 0 -+ -+/* 3 Management frame body components (II): Information Elements. */ -+/* 7.3.2 Element IDs of information elements */ -+#define ELEM_HDR_LEN 2 -+ -+#define ELEM_ID_SSID 0 /* SSID */ -+#define ELEM_ID_SUP_RATES 1 /* Supported rates */ -+#define ELEM_ID_FH_PARAM_SET 2 /* FH parameter set */ -+#define ELEM_ID_DS_PARAM_SET 3 /* DS parameter set */ -+#define ELEM_ID_CF_PARAM_SET 4 /* CF parameter set */ -+#define ELEM_ID_TIM 5 /* TIM */ -+#define ELEM_ID_IBSS_PARAM_SET 6 /* IBSS parameter set */ -+#define ELEM_ID_COUNTRY_INFO 7 /* Country information */ -+#define ELEM_ID_HOPPING_PATTERN_PARAM 8 /* Hopping pattern parameters */ -+#define ELEM_ID_HOPPING_PATTERN_TABLE 9 /* Hopping pattern table */ -+#define ELEM_ID_REQUEST 10 /* Request */ -+#define ELEM_ID_BSS_LOAD 11 /* BSS load */ -+#define ELEM_ID_EDCA_PARAM_SET 12 /* EDCA parameter set */ -+#define ELEM_ID_TSPEC 13 /* Traffic specification (TSPEC) */ -+#define ELEM_ID_TCLAS 14 /* Traffic classification (TCLAS) */ -+#define ELEM_ID_SCHEDULE 15 /* Schedule */ -+#define ELEM_ID_CHALLENGE_TEXT 16 /* Challenge text */ -+ -+#define ELEM_ID_PWR_CONSTRAINT 32 /* Power constraint */ -+#define ELEM_ID_PWR_CAP 33 /* Power capability */ -+#define ELEM_ID_TPC_REQ 34 /* TPC request */ -+#define ELEM_ID_TPC_REPORT 35 /* TPC report */ -+#define ELEM_ID_SUP_CHS 36 /* Supported channels */ -+#define ELEM_ID_CH_SW_ANNOUNCEMENT 37 /* Channel switch announcement */ -+#define ELEM_ID_MEASUREMENT_REQ 38 /* Measurement request */ -+#define ELEM_ID_MEASUREMENT_REPORT 39 /* Measurement report */ -+#define ELEM_ID_QUIET 40 /* Quiet */ -+#define ELEM_ID_IBSS_DFS 41 /* IBSS DFS */ -+#define ELEM_ID_ERP_INFO 42 /* ERP information */ -+#define ELEM_ID_TS_DELAY 43 /* TS delay */ -+#define ELEM_ID_TCLAS_PROCESSING 44 /* TCLAS processing */ -+#define ELEM_ID_HT_CAP 45 /* HT Capabilities subelement */ -+#define ELEM_ID_QOS_CAP 46 /* QoS capability */ -+#define ELEM_ID_RSN 48 /* RSN IE */ -+#define ELEM_ID_EXTENDED_SUP_RATES 50 /* Extended supported rates */ -+#define ELEM_ID_TIMEOUT_INTERVAL 56 /* 802.11w SA Timeout interval */ -+#define ELEM_ID_SUP_OPERATING_CLASS 59 /* Supported Operating Classes */ -+#define ELEM_ID_HT_OP 61 /* HT Operation */ -+#define ELEM_ID_SCO 62 /* Secondary Channel Offset */ -+#define ELEM_ID_RRM_ENABLED_CAP 70 /* Radio Resource Management Enabled Capabilities */ -+#define ELEM_ID_20_40_BSS_COEXISTENCE 72 /* 20/40 BSS Coexistence */ -+#define ELEM_ID_20_40_INTOLERANT_CHNL_REPORT 73 /* 20/40 BSS Intolerant Channel Report */ -+#define ELEM_ID_OBSS_SCAN_PARAMS 74 /* Overlapping BSS Scan Parameters */ -+#define ELEM_ID_INTERWORKING 107 /* Interworking with External Network */ -+#define ELEM_ID_ADVERTISEMENT_PROTOCOL 108 /* Advertisement Protocol */ -+#define ELEM_ID_ROAMING_CONSORTIUM 111 /* Roaming Consortium */ -+#define ELEM_ID_EXTENDED_CAP 127 /* Extended capabilities */ -+ -+#define ELEM_ID_VENDOR 221 /* Vendor specific IE */ -+#define ELEM_ID_WPA ELEM_ID_VENDOR /* WPA IE */ -+#define ELEM_ID_WMM ELEM_ID_VENDOR /* WMM IE */ -+#define ELEM_ID_P2P ELEM_ID_VENDOR /* WiFi Direct */ -+#define ELEM_ID_WFD ELEM_ID_VENDOR /* WiFi Direct */ -+#define ELEM_ID_WSC ELEM_ID_VENDOR /* WSC IE */ -+ -+#define ELEM_ID_RESERVED 255 /* Reserved */ -+ -+/* 7.3.2.1 SSID element */ -+#define ELEM_MAX_LEN_SSID 32 -+ -+/* 7.3.2.2 Supported Rates */ -+#define ELEM_MAX_LEN_SUP_RATES 8 -+ -+/* 7.3.2.4 DS Parameter Set */ -+#define ELEM_MAX_LEN_DS_PARAMETER_SET 1 -+ -+/* 7.3.2.5 CF Parameter Set */ -+#define ELEM_CF_PARM_LEN 8 -+ -+/* 7.3.2.6 TIM */ -+#define ELEM_MIX_LEN_TIM 4 -+#define ELEM_MAX_LEN_TIM 254 -+ -+/* 7.3.2.7 IBSS Parameter Set element */ -+#define ELEM_MAX_LEN_IBSS_PARAMETER_SET 2 -+ -+/* 7.3.2.8 Challenge Text element */ -+#define ELEM_MIN_LEN_CHALLENGE_TEXT 1 -+#define ELEM_MAX_LEN_CHALLENGE_TEXT 253 -+ -+/* 7.3.2.9 Country Information element */ -+/* Country IE should contain at least 3-bytes country code string and one subband triplet. */ -+#define ELEM_MIN_LEN_COUNTRY_INFO 6 -+ -+#define ELEM_ID_COUNTRY_INFO_TRIPLET_LEN_FIXED 3 -+#define ELEM_ID_COUNTRY_INFO_SUBBAND_TRIPLET_LEN_FIXED 3 -+#define ELEM_ID_COUNTRY_INFO_REGULATORY_TRIPLET_LEN_FIXED 3 -+ -+/* 7.3.2.13 ERP Information element */ -+#define ELEM_MAX_LEN_ERP 1 -+/* -- bits in the ERP Information element */ -+#define ERP_INFO_NON_ERP_PRESENT BIT(0) /* NonERP_Present bit */ -+#define ERP_INFO_USE_PROTECTION BIT(1) /* Use_Protection bit */ -+#define ERP_INFO_BARKER_PREAMBLE_MODE BIT(2) /* Barker_Preamble_Mode bit */ -+ -+/* 7.3.2.14 Extended Supported Rates */ -+#define ELEM_MAX_LEN_EXTENDED_SUP_RATES 255 -+ -+#if CFG_SUPPORT_DFS -+/* 7.3.2.19 Supported Channels element */ -+#define ELEM_MAX_LEN_SUPPORTED_CHANNELS 7 -+#endif -+ -+/* 7.3.2.21 Measurement Request element */ -+#define ELEM_RM_TYPE_BASIC_REQ 0 -+#define ELEM_RM_TYPE_CCA_REQ 1 -+#define ELEM_RM_TYPE_RPI_HISTOGRAM_REQ 2 -+#define ELEM_RM_TYPE_CHNL_LOAD_REQ 3 -+#define ELEM_RM_TYPE_NOISE_HISTOGRAM_REQ 4 -+#define ELEM_RM_TYPE_BEACON_REQ 5 -+#define ELEM_RM_TYPE_FRAME_REQ 6 -+#define ELEM_RM_TYPE_STA_STATISTICS_REQ 7 -+#define ELEM_RM_TYPE_LCI_REQ 8 -+#define ELEM_RM_TYPE_TS_REQ 9 -+#define ELEM_RM_TYPE_MEASURE_PAUSE_REQ 255 -+ -+/* 7.3.2.22 Measurement Report element */ -+#define ELEM_RM_TYPE_BASIC_REPORT 0 -+#define ELEM_RM_TYPE_CCA_REPORT 1 -+#define ELEM_RM_TYPE_RPI_HISTOGRAM_REPORT 2 -+#define ELEM_RM_TYPE_CHNL_LOAD_REPORT 3 -+#define ELEM_RM_TYPE_NOISE_HISTOGRAM_REPORT 4 -+#define ELEM_RM_TYPE_BEACON_REPORT 5 -+#define ELEM_RM_TYPE_FRAME_REPORT 6 -+#define ELEM_RM_TYPE_STA_STATISTICS_REPORT 7 -+#define ELEM_RM_TYPE_LCI_REPORT 8 -+#define ELEM_RM_TYPE_TS_REPORT 9 -+/*Auto Channel Selection*/ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+#define ELEM_RM_TYPE_ACS_CHN 1 -+#define ELEM_RM_TYPE_LTE_CHN 2 -+#endif -+ -+/* 7.3.2.25 RSN information element */ -+#define ELEM_MAX_LEN_WPA 34 /* one pairwise, one AKM suite, one PMKID */ -+#define ELEM_MAX_LEN_RSN 38 /* one pairwise, one AKM suite, one PMKID */ -+#define ELEM_MAX_LEN_WAPI 38 /* one pairwise, one AKM suite, one BKID */ -+#define ELEM_MAX_LEN_WSC 200 /* one pairwise, one AKM suite, one BKID */ -+ -+#if CFG_SUPPORT_802_11W -+#define ELEM_WPA_CAP_MFPR BIT(6) -+#define ELEM_WPA_CAP_MFPC BIT(7) -+#endif -+ -+/* 7.3.2.27 Extended Capabilities information element */ -+#define ELEM_EXT_CAP_20_40_COEXIST_SUPPORT BIT(0) -+#define ELEM_EXT_CAP_PSMP_CAP BIT(4) -+#define ELEM_EXT_CAP_SERVICE_INTERVAL_GRANULARITY BIT(5) -+#define ELEM_EXT_CAP_SCHEDULE_PSMP BIT(6) -+ -+#define ELEM_EXT_CAP_BSS_TRANSITION_BIT 19 -+#define ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT 27 -+#define ELEM_EXT_CAP_INTERWORKING_BIT 31 -+#define ELEM_EXT_CAP_WNM_NOTIFICATION_BIT 46 -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+#define ELEM_MAX_LEN_EXT_CAP (6) -+#else -+#define ELEM_MAX_LEN_EXT_CAP (3 - ELEM_HDR_LEN) -+#endif -+ -+/* 7.3.2.30 TSPEC element */ -+#define TS_INFO_TRAFFIC_TYPE_MASK BIT(0) /* WMM: 0 (Asynchronous TS of low-duty cycles) */ -+#define TS_INFO_TID_OFFSET 1 -+#define TS_INFO_TID_MASK BITS(1, 4) -+#define TS_INFO_DIRECTION_OFFSET 5 -+#define TS_INFO_DIRECTION_MASK BITS(5, 6) -+#define TS_INFO_ACCESS_POLICY_OFFSET 7 -+#define TS_INFO_ACCESS_POLICY_MASK BITS(7, 8) -+#define TS_INFO_AGGREGATION_MASK BIT(9) /* WMM: 0 */ -+#define TS_INFO_APSD_MASK BIT(10) -+#define TS_INFO_UP_OFFSET 11 -+#define TS_INFO_UP_MASK BITS(11, 13) -+#define TS_INFO_ACK_POLICY_OFFSET 14 -+#define TS_INFO_ACK_POLICY_MASK BITS(14, 15) -+#define TS_INFO_SCHEDULE_MASK 16 -+ -+/* 7.3.2.56 HT capabilities element */ -+#define ELEM_MAX_LEN_HT_CAP (28 - ELEM_HDR_LEN) /* sizeof(IE_HT_CAP_T)-2 */ -+ -+/* 7.3.2.56.2 HT capabilities Info field */ -+#define HT_CAP_INFO_LDPC_CAP BIT(0) -+#define HT_CAP_INFO_SUP_CHNL_WIDTH BIT(1) -+#define HT_CAP_INFO_SM_POWER_SAVE BITS(2, 3) -+#define HT_CAP_INFO_HT_GF BIT(4) -+#define HT_CAP_INFO_SHORT_GI_20M BIT(5) -+#define HT_CAP_INFO_SHORT_GI_40M BIT(6) -+#define HT_CAP_INFO_TX_STBC BIT(7) -+#define HT_CAP_INFO_RX_STBC BITS(8, 9) -+#define HT_CAP_INFO_HT_DELAYED_BA BIT(10) -+#define HT_CAP_INFO_MAX_AMSDU_LEN BIT(11) -+#define HT_CAP_INFO_DSSS_CCK_IN_40M BIT(12) -+#define HT_CAP_INFO_40M_INTOLERANT BIT(14) -+#define HT_CAP_INFO_LSIG_TXOP_SUPPORT BIT(15) -+ -+#define HT_CAP_INFO_RX_STBC_NO_SUPPORTED 0 -+#define HT_CAP_INFO_RX_STBC_1_SS BIT(8) -+#define HT_CAP_INFO_RX_STBC_2_SS BIT(9) -+#define HT_CAP_INFO_RX_STBC_3_SS HT_CAP_INFO_RX_STBC -+ -+/* 7.3.2.56.3 A-MPDU Parameters field */ -+#define AMPDU_PARAM_MAX_AMPDU_LEN_EXP BITS(0, 1) -+#define AMPDU_PARAM_MIN_START_SPACING BITS(2, 4) -+ -+#define AMPDU_PARAM_MAX_AMPDU_LEN_8K 0 -+#define AMPDU_PARAM_MAX_AMPDU_LEN_16K BIT(0) -+#define AMPDU_PARAM_MAX_AMPDU_LEN_32K BIT(1) -+#define AMPDU_PARAM_MAX_AMPDU_LEN_64K BITS(0, 1) -+ -+#define AMPDU_PARAM_MSS_NO_RESTRICIT 0 -+#define AMPDU_PARAM_MSS_1_4_US BIT(2) -+#define AMPDU_PARAM_MSS_1_2_US BIT(3) -+#define AMPDU_PARAM_MSS_1_US BITS(2, 3) -+#define AMPDU_PARAM_MSS_2_US BIT(4) -+#define AMPDU_PARAM_MSS_4_US (BIT(4) | BIT(2)) -+#define AMPDU_PARAM_MSS_8_US (BIT(4) | BIT(3)) -+#define AMPDU_PARAM_MSS_16_US BITS(2, 4) -+ -+/* 7.3.2.56.4 Supported MCS Set field (TX rate: octects 12~15) */ -+#define SUP_MCS_TX_SET_DEFINED BIT(0) -+#define SUP_MCS_TX_RX_SET_NOT_EQUAL BIT(1) -+#define SUP_MCS_TX_MAX_NUM_SS BITS(2, 3) -+#define SUP_MCS_TX_UNEQUAL_MODULATION BIT(4) -+ -+#define SUP_MCS_TX_MAX_NUM_1_SS 0 -+#define SUP_MCS_TX_MAX_NUM_2_SS BIT(2) -+#define SUP_MCS_TX_MAX_NUM_3_SS BIT(3) -+#define SUP_MCS_TX_MAX_NUM_4_SS BITS(2, 3) -+ -+#define SUP_MCS_RX_BITMASK_OCTET_NUM 10 -+#define SUP_MCS_RX_DEFAULT_HIGHEST_RATE 0 /* Not specify */ -+ -+/* 7.3.2.56.5 HT Extended Capabilities field */ -+#define HT_EXT_CAP_PCO BIT(0) -+#define HT_EXT_CAP_PCO_TRANSITION_TIME BITS(1, 2) -+#define HT_EXT_CAP_MCS_FEEDBACK BITS(8, 9) -+#define HT_EXT_CAP_HTC_SUPPORT BIT(10) -+#define HT_EXT_CAP_RD_RESPONDER BIT(11) -+ -+#define HT_EXT_CAP_PCO_TRANS_TIME_NONE 0 -+#define HT_EXT_CAP_PCO_TRANS_TIME_400US BIT(1) -+#define HT_EXT_CAP_PCO_TRANS_TIME_1_5MS BIT(2) -+#define HT_EXT_CAP_PCO_TRANS_TIME_5MS BITS(1, 2) -+ -+#define HT_EXT_CAP_MCS_FEEDBACK_NO_FB 0 -+#define HT_EXT_CAP_MCS_FEEDBACK_UNSOLICITED BIT(9) -+#define HT_EXT_CAP_MCS_FEEDBACK_BOTH BITS(8, 9) -+ -+/* 7.3.2.56.6 Transmit Beamforming Capabilities field */ -+ -+/* 7.3.2.56.7 Antenna Selection Capability field */ -+#define ASEL_CAP_CAPABLE BIT(0) -+#define ASEL_CAP_CSI_FB_BY_TX_ASEL_CAPABLE BIT(1) -+#define ASEL_CAP_ANT_INDICES_FB_BY_TX_ASEL_CAPABLE BIT(2) -+#define ASEL_CAP_EXPLICIT_CSI_FB_CAPABLE BIT(3) -+#define ASEL_CAP_ANT_INDICES_CAPABLE BIT(4) -+#define ASEL_CAP_RX_ASEL_CAPABLE BIT(5) -+#define ASEL_CAP_TX_SOUNDING_CAPABLE BIT(6) -+ -+/* 7.3.2.57 HT Operation element */ -+#define ELEM_MAX_LEN_HT_OP (24 - ELEM_HDR_LEN) /* sizeof(IE_HT_OP_T)-2 */ -+ -+#define HT_OP_INFO1_SCO BITS(0, 1) -+#define HT_OP_INFO1_STA_CHNL_WIDTH BIT(2) -+#define HT_OP_INFO1_RIFS_MODE BIT(3) -+ -+#define HT_OP_INFO2_HT_PROTECTION BITS(0, 1) -+#define HT_OP_INFO2_NON_GF_HT_STA_PRESENT BIT(2) -+#define HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT BIT(4) -+ -+#define HT_OP_INFO3_DUAL_BEACON BIT(6) -+#define HT_OP_INFO3_DUAL_CTS_PROTECTION BIT(7) -+#define HT_OP_INFO3_STBC_BEACON BIT(8) -+#define HT_OP_INFO3_LSIG_TXOP_FULL_SUPPORT BIT(9) -+#define HT_OP_INFO3_PCO_ACTIVE BIT(10) -+#define HT_OP_INFO3_PCO_PHASE BIT(11) -+ -+/* 7.3.2.59 OBSS Scan Parameter element */ -+#define ELEM_MAX_LEN_OBSS_SCAN (16 - ELEM_HDR_LEN) -+ -+/* 7.3.2.60 20/40 BSS Coexistence element */ -+#define ELEM_MAX_LEN_20_40_BSS_COEXIST (3 - ELEM_HDR_LEN) -+ -+#define BSS_COEXIST_INFO_REQ BIT(0) -+#define BSS_COEXIST_40M_INTOLERANT BIT(1) -+#define BSS_COEXIST_20M_REQ BIT(2) -+#define BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ BIT(3) -+#define BSS_COEXIST_OBSS_SCAN_EXEMPTION_GRANT BIT(4) -+ -+/* 802.11u 7.3.2.92 Interworking IE */ -+#define ELEM_MAX_LEN_INTERWORKING (11 - ELEM_HDR_LEN) -+ -+/* 802.11u 7.3.2.93 Advertisement Protocol IE */ -+#define ELEM_MAX_LEN_ADV_PROTOCOL (4 - ELEM_HDR_LEN) -+ -+/* 802.11u 7.3.2.96 Roaming Consortium IE */ -+#define ELEM_MAX_LEN_ROAMING_CONSORTIUM (19 - ELEM_HDR_LEN) -+ -+#define IW_IE_LENGTH_ANO 1 -+#define IW_IE_LENGTH_ANO_VENUE 3 -+#define IW_IE_LENGTH_ANO_HESSID 7 -+#define IW_IE_LENGTH_ANO_VENUE_HESSID 9 -+ -+/* 3 Management frame body components (III): 7.4 Action frame format details. */ -+/* 7.4.1 Spectrum Measurement Action frame details */ -+#define ACTION_MEASUREMENT_REQ 0 /* Spectrum measurement request */ -+#define ACTION_MEASUREMENT_REPORT 1 /* Spectrum measurement report */ -+#define ACTION_TPC_REQ 2 /* TPC request */ -+#define ACTION_TPC_REPORT 3 /* TPC report */ -+#define ACTION_CHNL_SWITCH 4 /* Channel Switch Announcement */ -+ -+/* 7.4.2 QoS Action frame details */ -+#define ACTION_ADDTS_REQ 0 /* ADDTS request */ -+#define ACTION_ADDTS_RSP 1 /* ADDTS response */ -+#define ACTION_DELTS 2 /* DELTS */ -+#define ACTION_SCHEDULE 3 /* Schedule */ -+ -+#define ACTION_ADDTS_REQ_FRAME_LEN (24+3+63) /* WMM TSPEC IE: 63 */ -+#define ACTION_ADDTS_RSP_FRAME_LEN (24+4+63) /* WMM Status Code: 1; WMM TSPEC IE: 63 */ -+ -+/* 7.4.3 DLS Action frame details */ -+#define ACTION_DLS_REQ 0 /* DLS request */ -+#define ACTION_DLS_RSP 1 /* DLS response */ -+#define ACTION_DLS_TEARDOWN 2 /* DLS teardown */ -+ -+/* 7.4.4 Block ack Action frame details */ -+#define ACTION_ADDBA_REQ 0 /* ADDBA request */ -+#define ACTION_ADDBA_RSP 1 /* ADDBA response */ -+#define ACTION_DELBA 2 /* DELBA */ -+ -+#define ACTION_ADDBA_REQ_FRAME_LEN (24+9) -+#define ACTION_ADDBA_RSP_FRAME_LEN (24+9) -+ -+#define ACTION_DELBA_INITIATOR_MASK BIT(11) -+#define ACTION_DELBA_TID_MASK BITS(12, 15) -+#define ACTION_DELBA_TID_OFFSET 12 -+#define ACTION_DELBA_FRAME_LEN (24+6) -+ -+/* 7.4.6 Radio Measurement Action frame details */ -+#define ACTION_RM_REQ 0 /* Radio measurement request */ -+#define ACTION_RM_REPORT 1 /* Radio measurement report */ -+#define ACTION_LM_REQ 2 /* Link measurement request */ -+#define ACTION_LM_REPORT 3 /* Link measurement report */ -+#define ACTION_NEIGHBOR_REPORT_REQ 4 /* Neighbor report request */ -+#define ACTION_NEIGHBOR_REPORT_RSP 5 /* Neighbor report response */ -+ -+/* 7.4.7 Public Action frame details */ -+#define ACTION_PUBLIC_20_40_COEXIST 0 /* 20/40 BSS coexistence */ -+ -+#if CFG_SUPPORT_802_11W -+/* SA Query Action frame (IEEE 802.11w/D8.0, 7.4.9) */ -+#define ACTION_SA_QUERY_REQUEST 0 -+#define ACTION_SA_QUERY_RESPONSE 1 -+ -+#define ACTION_SA_QUERY_TR_ID_LEN 2 -+ -+/* Timeout Interval Type */ -+#define ACTION_SA_TIMEOUT_REASSOC_DEADLINE 1 -+#define ACTION_SA_TIMEOUT_KEY_LIFETIME 2 -+#define ACTION_SA_TIMEOUT_ASSOC_COMEBACK 3 -+#endif -+ -+/* 7.4.10.1 HT action frame details */ -+#define ACTION_HT_NOTIFY_CHANNEL_WIDTH 0 /* Notify Channel Width */ -+#define ACTION_HT_SM_POWER_SAVE 1 /* SM Power Save */ -+#define ACTION_HT_PSMP 2 /* PSMP */ -+#define ACTION_HT_SET_PCO_PHASE 3 /* Set PCO Phase */ -+#define ACTION_HT_CSI 4 /* CSI */ -+#define ACTION_HT_NON_COMPRESSED_BEAMFORM 5 /* Non-compressed Beamforming */ -+#define ACTION_HT_COMPRESSED_BEAMFORM 6 /* Compressed Beamforming */ -+#define ACTION_HT_ANT_SEL_INDICES_FB 7 /* Antenna Selection Indices Feedback */ -+ -+/* 802.11v Wireless Network Management */ -+#define ACTION_WNM_TIMING_MEASUREMENT_REQUEST 27 -+ -+#define ACTION_UNPROTECTED_WNM_TIM 0 -+#define ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT 1 -+ -+#define ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN 12 -+ -+/* 3 --------------- WFA frame body fields --------------- */ -+#define VENDOR_OUI_WFA { 0x00, 0x50, 0xF2 } -+#define VENDOR_OUI_WFA_SPECIFIC { 0x50, 0x6F, 0x9A } -+#define VENDOR_OUI_TYPE_WPA 1 -+#define VENDOR_OUI_TYPE_WMM 2 -+#define VENDOR_OUI_TYPE_WPS 4 -+#define VENDOR_OUI_TYPE_P2P 9 -+#define VENDOR_OUI_TYPE_WFD 10 -+#define VENDOR_OUI_TYPE_HS20 16 -+ -+#define VENDOR_OUI_TYPE_LEN 4 /* Length of OUI and Type */ -+ -+/* VERSION(2 octets for WPA) / SUBTYPE(1 octet)-VERSION(1 octet) fields for WMM in WFA IE */ -+#define VERSION_WPA 0x0001 /* Little Endian Format */ -+#define VENDOR_OUI_SUBTYPE_VERSION_WMM_INFO 0x0100 -+#define VENDOR_OUI_SUBTYPE_VERSION_WMM_PARAM 0x0101 -+ -+/* SUBTYPE(1 octet) for WMM */ -+#define VENDOR_OUI_SUBTYPE_WMM_INFO 0x00 /* WMM Spec version 1.1 */ -+#define VENDOR_OUI_SUBTYPE_WMM_PARAM 0x01 -+#define VENDOR_OUI_SUBTYPE_WMM_TSPEC 0x02 -+ -+/* VERSION(1 octet) for WMM */ -+#define VERSION_WMM 0x01 /* WMM Spec version 1.1 */ -+ -+/* WMM-2.1.6 QoS Control Field */ -+#define WMM_QC_UP_MASK BITS(0, 2) -+#define WMM_QC_EOSP BIT(4) -+#define WMM_QC_ACK_POLICY_MASK BITS(5, 6) -+#define WMM_QC_ACK_POLICY_OFFSET 5 -+#define WMM_QC_ACK_POLICY_ACKNOWLEDGE 0 -+#define WMM_QC_ACK_POLICY_NOT_ACKNOWLEDGE (1 << WMM_QC_ACK_POLICY_OFFSET) -+ -+/* WMM-2.2.1 WMM Information Element */ -+#define ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE 6 -+ -+/* HOTSPOT 2.0 Indication IE*/ -+#define ELEM_MAX_LEN_HS20_INDICATION 5 -+#define ELEM_MIN_LEN_HS20_INDICATION 4 -+ -+/* Hotspot Configuration*/ -+#define ELEM_HS_CONFIG_DGAF_DISABLED_MASK BIT(0) /* Downstream Group-Addressed Forwarding */ -+ -+/* 3 Control frame body */ -+/* 7.2.1.7 BlockAckReq */ -+#define CTRL_BAR_BAR_CONTROL_OFFSET 16 -+#define CTRL_BAR_BAR_INFORMATION_OFFSET 18 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) -+#pragma pack(1) -+#endif -+ -+typedef struct _LLC_SNAP_HEADER_T { -+ UINT_8 ucDSAP; -+ UINT_8 ucSSAP; -+ UINT_8 ucControl; -+ UINT_8 aucCode[3]; -+ UINT_16 u2Type; -+} __KAL_ATTRIB_PACKED__ LLC_SNAP_HEADER_T, *P_LLC_SNAP_HEADER_T; -+ -+/* 3 MAC Header. */ -+/* Ethernet Frame Header */ -+typedef struct _ETH_FRAME_HEADER_T { -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; -+ UINT_16 u2TypeLen; -+} __KAL_ATTRIB_PACKED__ ETH_FRAME_HEADER_T, *P_ETH_FRAME_HEADER_T; -+ -+/* Ethernet Frame Structure */ -+typedef struct _ETH_FRAME_T { -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; -+ UINT_16 u2TypeLen; -+ UINT_8 aucData[1]; -+} __KAL_ATTRIB_PACKED__ ETH_FRAME_T, *P_ETH_FRAME_T; -+ -+/* IEEE 802.11 WLAN Frame Structure */ -+/* WLAN MAC Header (without Address 4 and QoS Control fields) */ -+typedef struct _WLAN_MAC_HEADER_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_T, *P_WLAN_MAC_HEADER_T; -+ -+/* WLAN MAC Header (QoS Control fields included) */ -+typedef struct _WLAN_MAC_HEADER_QOS_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_16 u2QosCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_QOS_T, *P_WLAN_MAC_HEADER_QOS_T; -+ -+/* WLAN MAC Header (HT Control fields included) */ -+typedef struct _WLAN_MAC_HEADER_HT_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_16 u2QosCtrl; -+ UINT_32 u4HtCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_HT_T, *P_WLAN_MAC_HEADER_HT_T; -+ -+/* WLAN MAC Header (Address 4 included) */ -+typedef struct _WLAN_MAC_HEADER_A4_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_8 aucAddr4[MAC_ADDR_LEN]; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_T, *P_WLAN_MAC_HEADER_A4_T; -+ -+/* WLAN MAC Header (Address 4 and QoS Control fields included) */ -+typedef struct _WLAN_MAC_HEADER_A4_QOS_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_8 aucAddr4[MAC_ADDR_LEN]; -+ UINT_16 u2QosCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_QOS_T, *P_WLAN_MAC_HEADER_A4_QOS_T; -+ -+typedef struct _WLAN_MAC_HEADER_A4_HT_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_8 aucAddr4[MAC_ADDR_LEN]; -+ UINT_16 u2QosCtrl; -+ UINT_32 u4HtCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_HT_T, *P_WLAN_MAC_HEADER_A4_HT_T; -+ -+/* 7.2.3 WLAN MAC Header for Management Frame - MMPDU */ -+typedef struct _WLAN_MAC_MGMT_HEADER_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2Duration; -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_MGMT_HEADER_T, *P_WLAN_MAC_MGMT_HEADER_T; -+ -+/* WLAN MAC Header for Management Frame (HT Control fields included) */ -+typedef struct _WLAN_MAC_MGMT_HEADER_HT_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_32 u4HtCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_MGMT_HEADER_HT_T, *P_WLAN_MAC_MGMT_HEADER_HT_T; -+ -+/* 3 WLAN CONTROL Frame */ -+/* 7.2.1.4 WLAN Control Frame - PS-POLL Frame */ -+typedef struct _CTRL_PSPOLL_FRAME_T { -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2AID; /* AID */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_8 aucTA[MAC_ADDR_LEN]; /* TA */ -+} __KAL_ATTRIB_PACKED__ CTRL_PSPOLL_FRAME_T, *P_CTRL_PSPOLL_FRAME_T; -+ -+/* BAR */ -+typedef struct _CTRL_BAR_FRAME_T { -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* RA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* TA */ -+ UINT_16 u2BarControl; -+ UINT_8 aucBarInfo[2]; /* Variable size */ -+} __KAL_ATTRIB_PACKED__ CTRL_BAR_FRAME_T, *P_CTRL_BAR_FRAME_T; -+ -+/* 3 WLAN Management Frame. */ -+/* 7.2.3.1 WLAN Management Frame - Beacon Frame */ -+typedef struct _WLAN_BEACON_FRAME_T { -+ /* Beacon header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Beacon frame body */ -+ UINT_32 au4Timestamp[2]; /* Timestamp */ -+ UINT_16 u2BeaconInterval; /* Beacon Interval */ -+ UINT_16 u2CapInfo; /* Capability */ -+ UINT_8 aucInfoElem[1]; /* Various IEs, start from SSID */ -+} __KAL_ATTRIB_PACKED__ WLAN_BEACON_FRAME_T, *P_WLAN_BEACON_FRAME_T; -+ -+typedef struct _WLAN_BEACON_FRAME_BODY_T { -+ /* Beacon frame body */ -+ UINT_32 au4Timestamp[2]; /* Timestamp */ -+ UINT_16 u2BeaconInterval; /* Beacon Interval */ -+ UINT_16 u2CapInfo; /* Capability */ -+ UINT_8 aucInfoElem[1]; /* Various IEs, start from SSID */ -+} __KAL_ATTRIB_PACKED__ WLAN_BEACON_FRAME_BODY_T, *P_WLAN_BEACON_FRAME_BODY_T; -+ -+/* 7.2.3.3 WLAN Management Frame - Disassociation Frame */ -+typedef struct _WLAN_DISASSOC_FRAME_T { -+ /* Authentication MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Disassociation frame body */ -+ UINT_16 u2ReasonCode; /* Reason code */ -+ UINT_8 aucInfoElem[1]; /* Various IEs, possible no. */ -+} __KAL_ATTRIB_PACKED__ WLAN_DISASSOC_FRAME_T, *P_WLAN_DISASSOC_FRAME_T; -+ -+/* 7.2.3.4 WLAN Management Frame - Association Request frame */ -+typedef struct _WLAN_ASSOC_REQ_FRAME_T { -+ /* Association Request MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Association Request frame body */ -+ UINT_16 u2CapInfo; /* Capability information */ -+ UINT_16 u2ListenInterval; /* Listen interval */ -+ UINT_8 aucInfoElem[1]; /* Information elements, include WPA IE */ -+} __KAL_ATTRIB_PACKED__ WLAN_ASSOC_REQ_FRAME_T, *P_WLAN_ASSOC_REQ_FRAME_T; -+ -+/* 7.2.3.5 WLAN Management Frame - Association Response frame */ -+typedef struct _WLAN_ASSOC_RSP_FRAME_T { -+ /* Association Response MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Association Response frame body */ -+ UINT_16 u2CapInfo; /* Capability information */ -+ UINT_16 u2StatusCode; /* Status code */ -+ UINT_16 u2AssocId; /* Association ID */ -+ UINT_8 aucInfoElem[1]; /* Information elements, such as -+ supported rates, and etc. */ -+} __KAL_ATTRIB_PACKED__ WLAN_ASSOC_RSP_FRAME_T, *P_WLAN_ASSOC_RSP_FRAME_T; -+ -+/* 7.2.3.6 WLAN Management Frame - Reassociation Request frame */ -+typedef struct _WLAN_REASSOC_REQ_FRAME_T { -+ /* Reassociation Request MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Reassociation Request frame body */ -+ UINT_16 u2CapInfo; /* Capability information */ -+ UINT_16 u2ListenInterval; /* Listen interval */ -+ UINT_8 aucCurrentAPAddr[MAC_ADDR_LEN]; /* Current AP address */ -+ UINT_8 aucInfoElem[1]; /* Information elements, include WPA IE */ -+} __KAL_ATTRIB_PACKED__ WLAN_REASSOC_REQ_FRAME_T, *P_WLAN_REASSOC_REQ_FRAME_T; -+ -+/* 7.2.3.7 WLAN Management Frame - Reassociation Response frame -+ (the same as Association Response frame) */ -+typedef WLAN_ASSOC_RSP_FRAME_T WLAN_REASSOC_RSP_FRAME_T, *P_WLAN_REASSOC_RSP_FRAME_T; -+ -+/* 7.2.3.9 WLAN Management Frame - Probe Response Frame */ -+typedef WLAN_BEACON_FRAME_T WLAN_PROBE_RSP_FRAME_T, *P_WLAN_PROBE_RSP_FRAME_T; -+ -+/* 7.2.3.10 WLAN Management Frame - Authentication Frame */ -+typedef struct _WLAN_AUTH_FRAME_T { -+ /* Authentication MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Authentication frame body */ -+ UINT_16 u2AuthAlgNum; /* Authentication algorithm number */ -+ UINT_16 u2AuthTransSeqNo; /* Authentication transaction sequence number */ -+ UINT_16 u2StatusCode; /* Status code */ -+ UINT_8 aucInfoElem[1]; /* Various IEs for Fast BSS Transition */ -+} __KAL_ATTRIB_PACKED__ WLAN_AUTH_FRAME_T, *P_WLAN_AUTH_FRAME_T; -+ -+/* 7.2.3.11 WLAN Management Frame - Deauthentication Frame */ -+typedef struct _WLAN_DEAUTH_FRAME_T { -+ /* Authentication MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Deauthentication frame body */ -+ UINT_16 u2ReasonCode; /* Reason code */ -+ UINT_8 aucInfoElem[1]; /* Various IEs, possible no. */ -+} __KAL_ATTRIB_PACKED__ WLAN_DEAUTH_FRAME_T, *P_WLAN_DEAUTH_FRAME_T; -+ -+/* 3 Information Elements. */ -+/* 7.3.2 Generic element format */ -+typedef struct _IE_HDR_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucInfo[1]; -+} __KAL_ATTRIB_PACKED__ IE_HDR_T, *P_IE_HDR_T; -+ -+/* 7.3.2.1 SSID element */ -+typedef struct _IE_SSID_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+} __KAL_ATTRIB_PACKED__ IE_SSID_T, *P_IE_SSID_T; -+ -+/* 7.3.2.2 Supported Rates element */ -+typedef struct _IE_SUPPORTED_RATE_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucSupportedRates[ELEM_MAX_LEN_SUP_RATES]; -+} __KAL_ATTRIB_PACKED__ IE_SUPPORTED_RATE_T, *P_IE_SUPPORTED_RATE_T; -+ -+/* 7.3.2.4 DS Parameter Set element */ -+typedef struct _IE_DS_PARAM_SET_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucCurrChnl; -+} __KAL_ATTRIB_PACKED__ IE_DS_PARAM_SET_T, *P_IE_DS_PARAM_SET_T; -+ -+/* 7.3.2.5 CF Parameter Set element */ -+typedef struct _IE_CF_PARAM_SET_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucCFPCount; -+ UINT_8 ucCFPPeriod; -+ UINT_16 u2CFPMaxDur; -+ UINT_16 u2DurRemaining; -+} __KAL_ATTRIB_PACKED__ IE_CF_PARAM_SET_T, *P_IE_CF_PARAM_SET_T; -+ -+/* 7.3.2.6 TIM */ -+typedef struct _IE_TIM_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucDTIMCount; -+ UINT_8 ucDTIMPeriod; -+ UINT_8 ucBitmapControl; -+ UINT_8 aucPartialVirtualMap[1]; -+} __KAL_ATTRIB_PACKED__ IE_TIM_T, *P_IE_TIM_T; -+ -+/* 7.3.2.7 IBSS Parameter Set element */ -+typedef struct _IE_IBSS_PARAM_SET_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_16 u2ATIMWindow; -+} __KAL_ATTRIB_PACKED__ IE_IBSS_PARAM_SET_T, *P_IE_IBSS_PARAM_SET_T; -+ -+/* 7.3.2.8 Challenge Text element */ -+typedef struct _IE_CHALLENGE_TEXT_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucChallengeText[ELEM_MAX_LEN_CHALLENGE_TEXT]; -+} __KAL_ATTRIB_PACKED__ IE_CHALLENGE_TEXT_T, *P_IE_CHALLENGE_TEXT_T; -+ -+/* 7.3.2.9 Country information element */ -+#if CFG_SUPPORT_802_11D -+/*! \brief COUNTRY_INFO_TRIPLET is defined for the COUNTRY_INFO_ELEM structure. */ -+typedef struct _COUNTRY_INFO_TRIPLET_T { -+ UINT_8 ucParam1; /*!< If param1 >= 201, this triplet is referred to as -+ Regulatory Triplet in 802_11J. */ -+ UINT_8 ucParam2; -+ UINT_8 ucParam3; -+} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_TRIPLET_T, *P_COUNTRY_INFO_TRIPLET_T; -+ -+typedef struct _COUNTRY_INFO_SUBBAND_TRIPLET_T { -+ UINT_8 ucFirstChnlNum; /*!< First Channel Number */ -+ UINT_8 ucNumOfChnl; /*!< Number of Channels */ -+ INT_8 cMaxTxPwrLv; /*!< Maximum Transmit Power Level */ -+} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_SUBBAND_TRIPLET_T, *P_COUNTRY_INFO_SUBBAND_TRIPLET_T; -+ -+typedef struct _COUNTRY_INFO_REGULATORY_TRIPLET_T { -+ UINT_8 ucRegExtId; /*!< Regulatory Extension Identifier, should -+ be greater than or equal to 201 */ -+ UINT_8 ucRegClass; /*!< Regulatory Class */ -+ UINT_8 ucCoverageClass; /*!< Coverage Class, unsigned 1-octet value 0~31 -+ , 32~255 reserved */ -+} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_REGULATORY_TRIPLET_T, *P_COUNTRY_INFO_REGULATORY_TRIPLET_T; -+ -+typedef struct _IE_COUNTRY_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucCountryStr[3]; -+ COUNTRY_INFO_SUBBAND_TRIPLET_T arCountryStr[1]; -+} __KAL_ATTRIB_PACKED__ IE_COUNTRY_T, *P_IE_COUNTRY_T; -+#endif /* CFG_SUPPORT_802_11D */ -+ -+/* 7.3.2.13 ERP element */ -+typedef struct _IE_ERP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucERP; -+} __KAL_ATTRIB_PACKED__ IE_ERP_T, *P_IE_ERP_T; -+ -+/* 7.3.2.14 Extended Supported Rates element */ -+typedef struct _IE_EXT_SUPPORTED_RATE_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucExtSupportedRates[ELEM_MAX_LEN_EXTENDED_SUP_RATES]; -+} __KAL_ATTRIB_PACKED__ IE_EXT_SUPPORTED_RATE_T, *P_IE_EXT_SUPPORTED_RATE_T; -+ -+/* 7.3.2.15 Power Constraint element */ -+typedef struct _IE_POWER_CONSTRAINT_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucLocalPowerConstraint; /* Unit: dBm */ -+} __KAL_ATTRIB_PACKED__ IE_POWER_CONSTRAINT_T, *P_IE_POWER_CONSTRAINT_T; -+ -+/* 7.3.2.16 Power Capability element */ -+typedef struct _IE_POWER_CAP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ INT_8 cMinTxPowerCap; /* Unit: dBm */ -+ INT_8 cMaxTxPowerCap; /* Unit: dBm */ -+} __KAL_ATTRIB_PACKED__ IE_POWER_CAP_T, *P_IE_POWER_CAP_T; -+ -+/* 7.3.2.17 TPC request element */ -+typedef struct _IE_TPC_REQ_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+} __KAL_ATTRIB_PACKED__ IE_TPC_REQ_T, *P_IE_TPC_REQ_T; -+ -+/* 7.3.2.18 TPC report element */ -+typedef struct _IE_TPC_REPORT_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ INT_8 cTxPower; /* Unit: dBm */ -+ INT_8 cLinkMargin; /* Unit: dB */ -+} __KAL_ATTRIB_PACKED__ IE_TPC_REPORT_T, *P_IE_TPC_REPORT_T; -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+/* 7.3.2.19 Supported Channels element*/ -+typedef struct _IE_SUPPORTED_CHANNELS_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucChannelNum[ELEM_MAX_LEN_SUPPORTED_CHANNELS * 2]; -+} __KAL_ATTRIB_PACKED__ IE_SUPPORTED_CHANNELS_T, *P_IE_SUPPORTED_CHANNELS_T; -+ -+/* 7.3.2.20 Channel Switch Announcement element*/ -+typedef struct _IE_CHANNEL_SWITCH_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucChannelSwitchMode; -+ UINT_8 ucNewChannelNum; -+ UINT_8 ucChannelSwitchCount; -+} __KAL_ATTRIB_PACKED__ IE_CHANNEL_SWITCH_T, *P_IE_CHANNEL_SWITCH_T; -+#endif -+ -+/* 7.3.2.21 Measurement Request element */ -+typedef struct _IE_MEASUREMENT_REQ_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucToken; -+ UINT_8 ucRequestMode; -+ UINT_8 ucMeasurementType; -+ UINT_8 aucRequestFields[1]; -+} __KAL_ATTRIB_PACKED__ IE_MEASUREMENT_REQ_T, *P_IE_MEASUREMENT_REQ_T; -+ -+typedef struct _SM_BASIC_REQ_T { -+ UINT_8 ucChannel; -+ UINT_32 au4StartTime[2]; -+ UINT_16 u2Duration; -+} __KAL_ATTRIB_PACKED__ SM_BASIC_REQ_T, *P_SM_BASIC_REQ_T; -+ -+/* SM_COMMON_REQ_T is not specified in Spec. Use it as common structure of SM */ -+typedef SM_BASIC_REQ_T SM_REQ_COMMON_T, *P_SM_REQ_COMMON_T; -+typedef SM_BASIC_REQ_T SM_CCA_REQ_T, *P_SM_CCA_REQ_T; -+typedef SM_BASIC_REQ_T SM_RPI_HISTOGRAM_REQ_T, *P_SM_RPI_HISTOGRAM_REQ_T; -+ -+typedef struct _RM_CHNL_LOAD_REQ_T { -+ UINT_8 ucRegulatoryClass; -+ UINT_8 ucChannel; -+ UINT_16 u2RandomInterval; -+ UINT_16 u2Duration; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_CHNL_LOAD_REQ_T, *P_RM_CHNL_LOAD_REQ_T; -+ -+typedef RM_CHNL_LOAD_REQ_T RM_NOISE_HISTOGRAM_REQ_T, *P_RM_NOISE_HISTOGRAM_REQ_T; -+ -+typedef struct _RM_BCN_REQ_T { -+ UINT_8 ucRegulatoryClass; -+ UINT_8 ucChannel; -+ UINT_16 u2RandomInterval; -+ UINT_16 u2Duration; -+ UINT_8 ucMeasurementMode; -+ UINT_8 aucBssid[6]; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_BCN_REQ_T, *P_RM_BCN_REQ_T; -+ -+typedef struct _RM_FRAME_REQ_T { -+ UINT_8 ucRegulatoryClass; -+ UINT_8 ucChannel; -+ UINT_16 u2RandomInterval; -+ UINT_16 u2Duration; -+ UINT_8 ucFrameReqType; -+ UINT_8 aucMacAddr[6]; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_FRAME_REQ_T, *P_RM_FRAME_REQ_T; -+ -+typedef struct _RM_STA_STATS_REQ_T { -+ UINT_8 aucPeerMacAddr[6]; -+ UINT_16 u2RandomInterval; -+ UINT_16 u2Duration; -+ UINT_8 ucGroupID; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_STA_STATS_REQ_T, *P_RM_STA_STATS_REQ_T; -+ -+typedef struct _RM_LCI_REQ_T { -+ UINT_8 ucLocationSubject; -+ UINT_8 ucLatitudeResolution; -+ UINT_8 ucLongitudeResolution; -+ UINT_8 ucAltitudeResolution; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_LCI_REQ_T, *P_RM_LCI_REQ_T; -+ -+typedef struct _RM_TS_MEASURE_REQ_T { -+ UINT_16 u2RandomInterval; -+ UINT_16 u2Duration; -+ UINT_8 aucPeerStaAddr[6]; -+ UINT_8 ucTrafficID; -+ UINT_8 ucBin0Range; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_TS_MEASURE_REQ_T, *P_RM_TS_MEASURE_REQ_T; -+ -+typedef struct _RM_MEASURE_PAUSE_REQ_T { -+ UINT_16 u2PauseTime; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_MEASURE_PAUSE_REQ_T, *P_RM_MEASURE_PAUSE_REQ_T; -+ -+/* 7.3.2.22 Measurement Report element */ -+typedef struct _IE_MEASUREMENT_REPORT_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucToken; -+ UINT_8 ucReportMode; -+ UINT_8 ucMeasurementType; -+ UINT_8 aucReportFields[1]; -+} __KAL_ATTRIB_PACKED__ IE_MEASUREMENT_REPORT_T, *P_IE_MEASUREMENT_REPORT_T; -+ -+typedef struct _SM_BASIC_REPORT_T { -+ UINT_8 ucChannel; -+ UINT_32 u4StartTime[2]; -+ UINT_16 u2Duration; -+ UINT_8 ucMap; -+} __KAL_ATTRIB_PACKED__ SM_BASIC_REPORT_T, *P_SM_BASIC_REPORT_T; -+ -+typedef struct _SM_CCA_REPORT_T { -+ UINT_8 ucChannel; -+ UINT_32 u4StartTime[2]; -+ UINT_16 u2Duration; -+ UINT_8 ucCcaBusyFraction; -+} __KAL_ATTRIB_PACKED__ SM_CCA_REPORT_T, *P_SM_CCA_REPORT_T; -+ -+typedef struct _SM_RPI_REPORT_T { -+ UINT_8 ucChannel; -+ UINT_32 u4StartTime[2]; -+ UINT_16 u2Duration; -+ UINT_8 aucRPI[8]; -+} __KAL_ATTRIB_PACKED__ SM_RPI_REPORT_T, *P_SM_RPI_REPORT_T; -+ -+typedef struct _RM_CHNL_LOAD_REPORT_T { -+ UINT_8 ucRegulatoryClass; -+ UINT_8 ucChannel; -+ UINT_32 u4StartTime[2]; -+ UINT_16 u2Duration; -+ UINT_8 ucChnlLoad; -+} __KAL_ATTRIB_PACKED__ RM_CHNL_LOAD_REPORT_T, *P_RM_CHNL_LOAD_REPORT_T; -+ -+typedef struct _RM_IPI_REPORT_T { -+ UINT_8 ucRegulatoryClass; -+ UINT_8 ucChannel; -+ UINT_32 u4StartTime[2]; -+ UINT_16 u2Duration; -+ UINT_8 ucAntennaId; -+ INT_8 cANPI; -+ UINT_8 aucIPI[11]; -+} __KAL_ATTRIB_PACKED__ RM_IPI_REPORT_T, *P_RM_IPI_REPORT_T; -+ -+/* 7.3.2.23 Quiet element */ -+typedef struct _IE_QUIET_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucCount; -+ UINT_8 ucPeriod; -+ UINT_16 u2Duration; -+ UINT_16 u2Offset; -+} __KAL_ATTRIB_PACKED__ IE_QUIET_T, *P_IE_QUIET_T; -+ -+/* 7.3.2.27 Extended Capabilities element */ -+typedef struct _IE_EXT_CAP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucCapabilities[5]; -+} __KAL_ATTRIB_PACKED__ IE_EXT_CAP_T, *P_EXT_CAP_T; -+ -+/* 7.3.2.27 hs20 Extended Capabilities element */ -+typedef struct _IE_HS20_EXT_CAP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucCapabilities[6]; -+} __KAL_ATTRIB_PACKED__ IE_HS20_EXT_CAP_T, *P_HS20_EXT_CAP_T; -+ -+ -+/* 7.3.2.27 Extended Capabilities element */ -+typedef struct _IE_RRM_ENABLED_CAP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucCap[5]; -+} __KAL_ATTRIB_PACKED__ IE_RRM_ENABLED_CAP_T, *P_IE_RRM_ENABLED_CAP_T; -+ -+/* 7.3.2.51 Timeout Interval element (TIE) */ -+typedef struct _IE_TIMEOUT_INTERVAL_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+#define IE_TIMEOUT_INTERVAL_TYPE_RESERVED 0 -+#define IE_TIMEOUT_INTERVAL_TYPE_REASSOC 1 -+#define IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME 2 -+#define IE_TIMEOUT_INTERVAL_TYPE_ASSOC_COMEBACK 3 -+ UINT_8 ucType; -+ UINT_32 u4Value; -+} __KAL_ATTRIB_PACKED__ IE_TIMEOUT_INTERVAL_T; -+ -+/* 7.3.2.56 HT Capabilities element */ -+typedef struct _SUP_MCS_SET_FIELD { -+ UINT_8 aucRxMcsBitmask[SUP_MCS_RX_BITMASK_OCTET_NUM]; -+ UINT_16 u2RxHighestSupportedRate; -+ UINT_32 u4TxRateInfo; -+} __KAL_ATTRIB_PACKED__ SUP_MCS_SET_FIELD, *P_SUP_MCS_SET_FIELD; -+ -+typedef struct _IE_HT_CAP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_16 u2HtCapInfo; -+ UINT_8 ucAmpduParam; -+ SUP_MCS_SET_FIELD rSupMcsSet; -+ UINT_16 u2HtExtendedCap; -+ UINT_32 u4TxBeamformingCap; -+ UINT_8 ucAselCap; -+} __KAL_ATTRIB_PACKED__ IE_HT_CAP_T, *P_IE_HT_CAP_T; -+ -+/* 7.3.2.57 HT Operation element */ -+typedef struct _IE_HT_OP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucPrimaryChannel; -+ UINT_8 ucInfo1; -+ UINT_16 u2Info2; -+ UINT_16 u2Info3; -+ UINT_8 aucBasicMcsSet[16]; -+} __KAL_ATTRIB_PACKED__ IE_HT_OP_T, *P_IE_HT_OP_T; -+ -+/* 7.3.2.25 RSN Information element format */ -+typedef struct _RSN_INFO_ELEM_T { -+ UCHAR ucElemId; -+ UCHAR ucLength; -+ UINT_16 u2Version; -+ UINT_32 u4GroupKeyCipherSuite; -+ UINT_16 u2PairwiseKeyCipherSuiteCount; -+ UCHAR aucPairwiseKeyCipherSuite1[4]; -+} __KAL_ATTRIB_PACKED__ RSN_INFO_ELEM_T, *P_RSN_INFO_ELEM_T; -+ -+/* 7.3.2.26 WPA Information element format */ -+typedef struct _WPA_INFO_ELEM_T { -+ UCHAR ucElemId; -+ UCHAR ucLength; -+ UCHAR aucOui[3]; -+ UCHAR ucOuiType; -+ UINT_16 u2Version; -+ UINT_32 u4GroupKeyCipherSuite; -+ UINT_16 u2PairwiseKeyCipherSuiteCount; -+ UCHAR aucPairwiseKeyCipherSuite1[4]; -+} __KAL_ATTRIB_PACKED__ WPA_INFO_ELEM_T, *P_WPA_INFO_ELEM_T; -+ -+/* 7.3.2.58 20/40 BSS Intolerant Channel Report element */ -+typedef struct _IE_INTOLERANT_CHNL_REPORT_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucRegulatoryClass; -+ UINT_8 aucChannelList[1]; -+} __KAL_ATTRIB_PACKED__ IE_INTOLERANT_CHNL_REPORT_T, *P_IE_INTOLERANT_CHNL_REPORT_T; -+ -+/* 7.3.2.59 OBSS Scan Parameters element */ -+typedef struct _IE_OBSS_SCAN_PARAM_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_16 u2ScanPassiveDwell; -+ UINT_16 u2ScanActiveDwell; -+ UINT_16 u2TriggerScanInterval; -+ UINT_16 u2ScanPassiveTotalPerChnl; -+ UINT_16 u2ScanActiveTotalPerChnl; -+ UINT_16 u2WidthTransDelayFactor; -+ UINT_16 u2ScanActivityThres; -+} __KAL_ATTRIB_PACKED__ IE_OBSS_SCAN_PARAM_T, *P_IE_OBSS_SCAN_PARAM_T; -+ -+/* 7.3.2.60 20/40 BSS Coexistence element */ -+typedef struct _IE_20_40_COEXIST_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucData; -+} __KAL_ATTRIB_PACKED__ IE_20_40_COEXIST_T, *P_IE_20_40_COEXIST_T; -+ -+/* 7.3.2.60 20/40 BSS Coexistence element */ -+typedef struct _IE_SUP_OPERATING_CLASS_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucCur; -+ UINT_8 ucSup[255]; -+} __KAL_ATTRIB_PACKED__ IE_SUP_OPERATING_CLASS_T, *P_IE_SUP_OPERATING_CLASS_T; -+ -+/* 3 7.4 Action Frame. */ -+/* 7.4 Action frame format */ -+typedef struct _WLAN_ACTION_FRAME { -+ /* Action MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Action frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucActionDetails[1]; /* Action details */ -+} __KAL_ATTRIB_PACKED__ WLAN_ACTION_FRAME, *P_WLAN_ACTION_FRAME; -+ -+/* 7.4.1.1 Spectrum Measurement Request frame format */ -+typedef struct _ACTION_SM_REQ_FRAME { -+ /* ADDTS Request MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* ADDTS Request frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 aucInfoElem[1]; /* Information elements */ -+} __KAL_ATTRIB_PACKED__ ACTION_SM_REQ_FRAME, *P_ACTION_SM_REQ_FRAME; -+ -+/* 7.4.1.2 Spectrum Measurement Report frame format */ -+typedef ACTION_SM_REQ_FRAME ACTION_SM_REPORT_FRAME, *P_ACTION_SM_REPORT_FRAME; -+ -+/* 7.4.1.5 Channel Switch Announcement frame format */ -+typedef struct _ACTION_CHANNEL_SWITCH_FRAME { -+ /* ADDTS Request MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* ADDTS Request frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 aucInfoElem[5]; /* Information elements */ -+} __KAL_ATTRIB_PACKED__ _ACTION_CHANNEL_SWITCH_FRAME, *P_ACTION_CHANNEL_SWITCH_FRAME; -+ -+/* 7.4.2.1 ADDTS Request frame format */ -+typedef struct _ACTION_ADDTS_REQ_FRAME { -+ /* ADDTS Request MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* ADDTS Request frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 aucInfoElem[1]; /* Information elements, such as -+ TS Delay, and etc. */ -+} __KAL_ATTRIB_PACKED__ ACTION_ADDTS_REQ_FRAME, *P_ACTION_ADDTS_REQ_FRAME; -+ -+/* 7.4.2.2 ADDTS Response frame format */ -+typedef struct _ACTION_ADDTS_RSP_FRAME { -+ /* ADDTS Response MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* ADDTS Response frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 ucStatusCode; /* WMM Status Code is of one byte */ -+ UINT_8 aucInfoElem[1]; /* Information elements, such as -+ TS Delay, and etc. */ -+} __KAL_ATTRIB_PACKED__ ACTION_ADDTS_RSP_FRAME, *P_ACTION_ADDTS_RSP_FRAME; -+ -+/* 7.4.2.3 DELTS frame format */ -+typedef struct _ACTION_DELTS_FRAME { -+ /* DELTS MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* DELTS frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 aucTsInfo[3]; /* TS Info */ -+} __KAL_ATTRIB_PACKED__ ACTION_DELTS_FRAME, *P_ACTION_DELTS_FRAME; -+ -+/* 7.4.4.1 ADDBA Request frame format */ -+typedef struct _ACTION_ADDBA_REQ_FRAME_T { -+ /* Action MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Action frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token chosen by the sender */ -+ UINT_8 aucBAParameterSet[2]; /* BA policy, TID, buffer size */ -+ UINT_8 aucBATimeoutValue[2]; -+ UINT_8 aucBAStartSeqCtrl[2]; /* SSN */ -+} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_REQ_FRAME_T, *P_ACTION_ADDBA_REQ_FRAME_T; -+ -+typedef struct _ACTION_ADDBA_REQ_BODY_T { -+ UINT_16 u2BAParameterSet; /* BA policy, TID, buffer size */ -+ UINT_16 u2BATimeoutValue; -+ UINT_16 u2BAStartSeqCtrl; /* SSN */ -+} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_REQ_BODY_T, *P_ACTION_ADDBA_REQ_BODY_T; -+ -+/* 7.4.4.2 ADDBA Response frame format */ -+typedef struct _ACTION_ADDBA_RSP_FRAME_T { -+ /* Action MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Action frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token chosen by the sender */ -+ UINT_8 aucStatusCode[2]; -+ UINT_8 aucBAParameterSet[2]; /* BA policy, TID, buffer size */ -+ UINT_8 aucBATimeoutValue[2]; -+} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_RSP_FRAME_T, *P_ACTION_ADDBA_RSP_FRAME_T; -+ -+typedef struct _ACTION_ADDBA_RSP_BODY_T { -+ UINT_16 u2StatusCode; -+ UINT_16 u2BAParameterSet; /* BA policy, TID, buffer size */ -+ UINT_16 u2BATimeoutValue; -+} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_RSP_BODY_T, *P_ACTION_ADDBA_RSP_BODY_T; -+ -+/* 7.4.4.3 DELBA frame format */ -+typedef struct _ACTION_DELBA_FRAME_T { -+ /* Action MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Action frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_16 u2DelBaParameterSet; /* Bit 11 Initiator, Bits 12-15 TID */ -+ UINT_16 u2ReasonCode; /* 7.3.1.7 */ -+} __KAL_ATTRIB_PACKED__ ACTION_DELBA_FRAME_T, *P_ACTION_DELBA_FRAME_T; -+ -+/* 7.4.6.1 Radio Measurement Request frame format */ -+typedef struct _ACTION_RM_REQ_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Radio Measurement Request frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_16 u2Repetitions; /* Number of repetitions */ -+ UINT_8 aucInfoElem[1]; /* Measurement Request elements, such as -+ channel load request, and etc. */ -+} __KAL_ATTRIB_PACKED__ ACTION_RM_REQ_FRAME, *P_ACTION_RM_REQ_FRAME; -+ -+/* 7.4.6.2 Radio Measurement Report frame format */ -+typedef struct _ACTION_RM_REPORT_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Radio Measurement Report frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 aucInfoElem[1]; /* Measurement Report elements, such as -+ channel load report, and etc. */ -+} __KAL_ATTRIB_PACKED__ ACTION_RM_REPORT_FRAME, *P_ACTION_RM_REPORT_FRAME; -+ -+/* 7.4.7.1a 20/40 BSS Coexistence Management frame format */ -+typedef struct _ACTION_20_40_COEXIST_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* BSS Coexistence Management frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ -+ IE_20_40_COEXIST_T rBssCoexist; /* 20/40 BSS coexistence element */ -+ IE_INTOLERANT_CHNL_REPORT_T rChnlReport; /* Intolerant channel report */ -+ -+} __KAL_ATTRIB_PACKED__ ACTION_20_40_COEXIST_FRAME, *P_ACTION_20_40_COEXIST_FRAME; -+ -+#if CFG_SUPPORT_802_11W -+/* 7.4.9 SA Query Management frame format */ -+typedef struct _ACTION_SA_QUERY_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* BSS Coexistence Management frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ -+ UINT_8 ucTransId[ACTION_SA_QUERY_TR_ID_LEN]; /* Transaction id */ -+ -+} __KAL_ATTRIB_PACKED__ ACTION_SA_QUERY_FRAME, *P_ACTION_SA_QUERY_FRAME; -+#endif -+ -+/* 7.4.10 Notify Channel Width Management frame format */ -+typedef struct _ACTION_NOTIFY_CHNL_WIDTH_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* BSS Coexistence Management frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucChannelWidth; /* Channel Width */ -+} __KAL_ATTRIB_PACKED__ ACTION_NOTIFY_CHNL_WIDTH_FRAME, *P_ACTION_NOTIFY_CHNL_WIDTH_FRAME; -+ -+/* 802.11v Wireless Network Management: Timing Measurement Request */ -+typedef struct _ACTION_WNM_TIMING_MEAS_REQ_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Timing Measurement Request Management frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucTrigger; /* Trigger */ -+} __KAL_ATTRIB_PACKED__ ACTION_WNM_TIMING_MEAS_REQ_FRAME, *P_ACTION_WNM_TIMING_MEAS_REQ_FRAME; -+ -+/* 802.11v Wireless Network Management: Timing Measurement */ -+typedef struct _ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Timing Measurement Management frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 ucFollowUpDialogToken; /* Follow Up Dialog Token */ -+ UINT_32 u4ToD; /* Timestamp of Departure [10ns] */ -+ UINT_32 u4ToA; /* Timestamp of Arrival [10ns] */ -+ UINT_8 ucMaxToDErr; /* Maximum of ToD Error [10ns] */ -+ UINT_8 ucMaxToAErr; /* Maximum of ToA Error [10ns] */ -+} __KAL_ATTRIB_PACKED__ ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME, *P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME; -+ -+/* 3 Information Elements from WFA. */ -+typedef struct _IE_WFA_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucOui[3]; -+ UINT_8 ucOuiType; -+ UINT_8 aucOuiSubTypeVersion[2]; -+ /*!< Please be noted. WPA defines a 16 bit field version -+ instead of one subtype field and one version field */ -+} __KAL_ATTRIB_PACKED__ IE_WFA_T, *P_IE_WFA_T; -+ -+/* HS20 3.1 - HS 2.0 Indication Information Element */ -+typedef struct _IE_HS20_INDICATION_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucType; /* Type */ -+ UINT_8 ucHotspotConfig; /* Hotspot Configuration */ -+} __KAL_ATTRIB_PACKED__ IE_HS20_INDICATION_T, *P_IE_HS20_INDICATION_T; -+ -+/* WAPI Information element format */ -+typedef struct _WAPI_INFO_ELEM_T { -+ UCHAR ucElemId; -+ UCHAR ucLength; -+ UINT_16 u2Version; -+ UINT_16 u2AuthKeyMgtSuiteCount; -+ UCHAR aucAuthKeyMgtSuite1[4]; -+} __KAL_ATTRIB_PACKED__ WAPI_INFO_ELEM_T, *P_WAPI_INFO_ELEM_T; -+ -+#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) -+#pragma pack() -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* Convert the ECWmin(max) to CWmin(max) */ -+#define ECW_TO_CW(_ECW) ((1 << (_ECW)) - 1) -+ -+/* Convert the RCPI to dBm */ -+#define RCPI_TO_dBm(_rcpi) \ -+ ((PARAM_RSSI)(((_rcpi) > RCPI_HIGH_BOUND ? RCPI_HIGH_BOUND : (_rcpi)) >> 1) - NDBM_LOW_BOUND_FOR_RCPI) -+ -+/* Convert the dBm to RCPI */ -+#define dBm_TO_RCPI(_dbm) \ -+ (RCPI)(((((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1) > RCPI_HIGH_BOUND) ? RCPI_HIGH_BOUND : \ -+ ((((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1) < RCPI_LOW_BOUND ? RCPI_LOW_BOUND : \ -+ (((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1))) -+ -+/* Convert an unsigned char pointer to an information element pointer */ -+#define IE_ID(fp) (((P_IE_HDR_T) fp)->ucId) -+#define IE_LEN(fp) (((P_IE_HDR_T) fp)->ucLength) -+#define IE_SIZE(fp) (ELEM_HDR_LEN + IE_LEN(fp)) -+ -+#define SSID_IE(fp) ((P_IE_SSID_T) fp) -+ -+#define SUP_RATES_IE(fp) ((P_IE_SUPPORTED_RATE_T) fp) -+ -+#define DS_PARAM_IE(fp) ((P_IE_DS_PARAM_SET_T) fp) -+ -+#define TIM_IE(fp) ((P_IE_TIM_T) fp) -+ -+#define IBSS_PARAM_IE(fp) ((P_IE_IBSS_PARAM_SET_T) fp) -+ -+#define ERP_INFO_IE(fp) ((P_IE_ERP_T) fp) -+ -+#define EXT_SUP_RATES_IE(fp) ((P_IE_EXT_SUPPORTED_RATE_T) fp) -+ -+#define WFA_IE(fp) ((P_IE_WFA_T) fp) -+ -+#if CFG_SUPPORT_802_11D -+#define COUNTRY_IE(fp) ((P_IE_COUNTRY_T) fp) -+#endif -+ -+#define EXT_CAP_IE(fp) ((P_EXT_CAP_T) fp) -+ -+#define HT_CAP_IE(fp) ((P_IE_HT_CAP_T) fp) -+ -+#define HT_OP_IE(fp) ((P_IE_HT_OP_T) fp) -+ -+#define OBSS_SCAN_PARAM_IE(fp) ((P_IE_OBSS_SCAN_PARAM_T) fp) -+ -+#define BSS_20_40_COEXIST_IE(fp) ((P_IE_20_40_COEXIST_T) fp) -+ -+#define SUP_OPERATING_CLASS_IE(fp) ((P_IE_SUP_OPERATING_CLASS_T) fp) -+ -+#define QUIET_IE(fp) ((P_IE_QUIET_T) fp) -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+#define SUPPORTED_CHANNELS_IE(fp) ((P_IE_SUPPORTED_CHANNELS_T)fp) -+#endif -+ -+#define TIMEOUT_INTERVAL_IE(fp) ((IE_TIMEOUT_INTERVAL_T *)fp) -+ -+/* The macro to check if the MAC address is B/MCAST Address */ -+#define IS_BMCAST_MAC_ADDR(_pucDestAddr) \ -+ ((BOOLEAN) (((PUINT_8)(_pucDestAddr))[0] & BIT(0))) -+ -+/* The macro to check if the MAC address is UCAST Address */ -+#define IS_UCAST_MAC_ADDR(_pucDestAddr) \ -+ ((BOOLEAN) !(((PUINT_8)(_pucDestAddr))[0] & BIT(0))) -+ -+/* The macro to copy the MAC address */ -+#define COPY_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ -+ kalMemCopy(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN) -+ -+/* The macro to check if two MAC addresses are equal */ -+#define EQUAL_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ -+ (!kalMemCmp(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN)) -+ -+/* The macro to check if two MAC addresses are not equal */ -+#define UNEQUAL_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ -+ (kalMemCmp(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN)) -+ -+/* The macro to check whether two SSIDs are equal */ -+#define EQUAL_SSID(pucSsid1, ucSsidLen1, pucSsid2, ucSsidLen2) \ -+ ((ucSsidLen1 <= ELEM_MAX_LEN_SSID) && \ -+ (ucSsidLen2 <= ELEM_MAX_LEN_SSID) && \ -+ ((ucSsidLen1) == (ucSsidLen2)) && \ -+ !kalMemCmp(pucSsid1, pucSsid2, ucSsidLen1)) -+ -+/* The macro to check whether two SSIDs are equal */ -+#define UNEQUAL_SSID(pucSsid1, ucSsidLen1, pucSsid2, ucSsidLen2) \ -+ ((ucSsidLen1 > ELEM_MAX_LEN_SSID) || \ -+ (ucSsidLen2 > ELEM_MAX_LEN_SSID) || \ -+ ((ucSsidLen1) != (ucSsidLen2)) || \ -+ kalMemCmp(pucSsid1, pucSsid2, ucSsidLen1)) -+ -+/* The macro to copy the SSID, the length of pucDestSsid should have at least 32 bytes */ -+#define COPY_SSID(pucDestSsid, ucDestSsidLen, pucSrcSsid, ucSrcSsidLen) \ -+ do { \ -+ ucDestSsidLen = ucSrcSsidLen; \ -+ if (ucSrcSsidLen) { \ -+ ASSERT(ucSrcSsidLen <= ELEM_MAX_LEN_SSID); \ -+ kalMemCopy(pucDestSsid, \ -+ pucSrcSsid, \ -+ ((ucSrcSsidLen > ELEM_MAX_LEN_SSID) ? ELEM_MAX_LEN_SSID : ucSrcSsidLen)); \ -+ } \ -+ } while (FALSE) -+ -+/* The macro to copy the IE */ -+#define COPY_IE(pucDestIE, pucSrcIE) \ -+ do { \ -+ kalMemCopy((PUINT_8)pucDestIE, \ -+ (PUINT_8)pucSrcIE,\ -+ IE_SIZE(pucSrcIE)); \ -+ } while (FALSE) -+ -+#define IE_FOR_EACH(_pucIEsBuf, _u2IEsBufLen, _u2Offset) \ -+ for ((_u2Offset) = 0;\ -+ ((((_u2Offset) + 2) <= (_u2IEsBufLen)) && (((_u2Offset) + IE_SIZE(_pucIEsBuf)) <= (_u2IEsBufLen))); \ -+ (_u2Offset) += IE_SIZE(_pucIEsBuf), (_pucIEsBuf) += IE_SIZE(_pucIEsBuf)) -+ -+#define SET_EXT_CAP(_aucField, _ucFieldLength, _ucBit) \ -+ do { \ -+ if ((_ucBit) < ((_ucFieldLength) * 8)) { \ -+ PUINT_8 aucExtCap = (PUINT_8)(_aucField); \ -+ ((aucExtCap)[(_ucBit) / 8]) |= BIT((_ucBit) % 8); \ -+ } \ -+ } while (FALSE) -+ -+#define TEST_EXT_CAP(_aucField, _ucFieldLength, _ucBit) \ -+ ((((_ucFieldLength) * 8) > (_ucBit)) && (((_aucField)[(_ucBit) / 8]) & BIT((_ucBit) % 8))) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _MAC_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h -new file mode 100644 -index 0000000000000..583923aed0100 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h -@@ -0,0 +1,272 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/include/nic/mtreg.h#2 -+*/ -+ -+/*! \file "mtreg.h" -+ \brief The common register definition of mt5931 -+ -+ N/A -+*/ -+ -+/* -+** Log: mtreg.h -+ * -+ * 01 28 2013 samp.lin -+ * [WCXRP00000851] [MT6582 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6582-specific definitions. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 07 13 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add initial version for MT6628 driver support. -+ * -+*/ -+ -+#ifndef _MTREG_H -+#define _MTREG_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/* 1 MT6628 MCR Definition */ -+ -+/* 2 Host Interface */ -+ -+/* 4 CHIP ID Register */ -+#define MCR_WCIR 0x0000 -+ -+/* 4 HIF Low Power Control Register */ -+#define MCR_WHLPCR 0x0004 -+ -+/* 4 Control Status Register */ -+#define MCR_WSDIOCSR 0x0008 -+#define MCR_WSPICSR 0x0008 -+ -+/* 4 HIF Control Register */ -+#define MCR_WHCR 0x000C -+ -+/* 4 HIF Interrupt Status Register */ -+#define MCR_WHISR 0x0010 -+ -+/* 4 HIF Interrupt Enable Register */ -+#define MCR_WHIER 0x0014 -+ -+/* 4 Abnormal Status Register */ -+#define MCR_WASR 0x0018 -+ -+/* 4 WLAN Software Interrupt Control Register */ -+#define MCR_WSICR 0x001C -+ -+/* 4 WLAN TX Status Register */ -+#define MCR_WTSR0 0x0020 -+ -+/* 4 WLAN TX Status Register */ -+#define MCR_WTSR1 0x0024 -+ -+/* 4 WLAN TX Data Register 0 */ -+#define MCR_WTDR0 0x0028 -+ -+/* 4 WLAN TX Data Register 1 */ -+#define MCR_WTDR1 0x002C -+ -+/* 4 WLAN RX Data Register 0 */ -+#define MCR_WRDR0 0x0030 -+ -+/* 4 WLAN RX Data Register 1 */ -+#define MCR_WRDR1 0x0034 -+ -+/* 4 Host to Device Send Mailbox 0 Register */ -+#define MCR_H2DSM0R 0x0038 -+ -+/* 4 Host to Device Send Mailbox 1 Register */ -+#define MCR_H2DSM1R 0x003c -+ -+/* 4 Device to Host Receive Mailbox 0 Register */ -+#define MCR_D2HRM0R 0x0040 -+ -+/* 4 Device to Host Receive Mailbox 1 Register */ -+#define MCR_D2HRM1R 0x0044 -+ -+/* 4 Device to Host Receive Mailbox 2 Register */ -+#define MCR_D2HRM2R 0x0048 -+ -+/* 4 WLAN RX Packet Length Register */ -+#define MCR_WRPLR 0x0050 -+ -+/* 4 HSIF Transaction Count Register */ -+#define MCR_HSTCR 0x0058 -+ -+/* #if CFG_SDIO_INTR_ENHANCE */ -+typedef struct _ENHANCE_MODE_DATA_STRUCT_T { -+ UINT_32 u4WHISR; -+ union { -+ struct { -+ UINT_8 ucTQ0Cnt; -+ UINT_8 ucTQ1Cnt; -+ UINT_8 ucTQ2Cnt; -+ UINT_8 ucTQ3Cnt; -+ UINT_8 ucTQ4Cnt; -+ UINT_8 ucTQ5Cnt; -+ UINT_16 u2Rsrv; -+ } u; -+ UINT_32 au4WTSR[2]; -+ } rTxInfo; -+ union { -+ struct { -+ UINT_16 u2NumValidRx0Len; -+ UINT_16 u2NumValidRx1Len; -+ UINT_16 au2Rx0Len[16]; -+ UINT_16 au2Rx1Len[16]; -+ } u; -+ UINT_32 au4RxStatusRaw[17]; -+ } rRxInfo; -+ UINT_32 u4RcvMailbox0; -+ UINT_32 u4RcvMailbox1; -+} ENHANCE_MODE_DATA_STRUCT_T, *P_ENHANCE_MODE_DATA_STRUCT_T; -+/* #endif */ /* ENHANCE_MODE_DATA_STRUCT_T */ -+ -+/* 2 Definition in each register */ -+/* 3 WCIR 0x0000 */ -+#define WCIR_WLAN_READY BIT(21) -+#define WCIR_POR_INDICATOR BIT(20) -+#define WCIR_REVISION_ID BITS(16, 19) -+#define WCIR_CHIP_ID BITS(0, 15) -+ -+#define MTK_CHIP_REV_72 0x00006572 -+#define MTK_CHIP_REV_82 0x00006582 -+#define MTK_CHIP_REV_92 0x00006592 -+#define MTK_CHIP_MP_REVERSION_ID 0x0 -+ -+/* 3 WHLPCR 0x0004 */ -+#define WHLPCR_FW_OWN_REQ_CLR BIT(9) -+#define WHLPCR_FW_OWN_REQ_SET BIT(8) -+#define WHLPCR_IS_DRIVER_OWN BIT(8) -+#define WHLPCR_INT_EN_CLR BIT(1) -+#define WHLPCR_INT_EN_SET BIT(0) -+ -+/* 3 WSDIOCSR 0x0008 */ -+#define WSDIOCSR_SDIO_RE_INIT_EN BIT(0) -+ -+/* 3 WSPICSR 0x0008 */ -+#define WCSR_SPI_MODE_SEL BITS(3, 4) -+#define WCSR_SPI_ENDIAN_BIG BIT(2) -+#define WCSR_SPI_INT_OUT_MODE BIT(1) -+#define WCSR_SPI_DATA_OUT_MODE BIT(0) -+ -+/* 3 WHCR 0x000C */ -+#define WHCR_RX_ENHANCE_MODE_EN BIT(16) -+#define WHCR_MAX_HIF_RX_LEN_NUM BITS(4, 7) -+#define WHCR_W_MAILBOX_RD_CLR_EN BIT(2) -+#define WHCR_W_INT_CLR_CTRL BIT(1) -+#define WHCR_MCU_DBG_EN BIT(0) -+#define WHCR_OFFSET_MAX_HIF_RX_LEN_NUM 4 -+ -+/* 3 WHISR 0x0010 */ -+#define WHISR_D2H_SW_INT BITS(8, 31) -+#define WHISR_D2H_SW_ASSERT_INFO_INT BIT(31) -+#define WHISR_FW_OWN_BACK_INT BIT(4) -+#define WHISR_ABNORMAL_INT BIT(3) -+#define WHISR_RX1_DONE_INT BIT(2) -+#define WHISR_RX0_DONE_INT BIT(1) -+#define WHISR_TX_DONE_INT BIT(0) -+ -+/* 3 WHIER 0x0014 */ -+#define WHIER_D2H_SW_INT BITS(8, 31) -+#define WHIER_FW_OWN_BACK_INT_EN BIT(4) -+#define WHIER_ABNORMAL_INT_EN BIT(3) -+#define WHIER_RX1_DONE_INT_EN BIT(2) -+#define WHIER_RX0_DONE_INT_EN BIT(1) -+#define WHIER_TX_DONE_INT_EN BIT(0) -+#define WHIER_DEFAULT (WHIER_RX0_DONE_INT_EN | \ -+ WHIER_RX1_DONE_INT_EN | \ -+ WHIER_TX_DONE_INT_EN | \ -+ WHIER_ABNORMAL_INT_EN | \ -+ WHIER_D2H_SW_INT \ -+ ) -+ -+/* 3 WASR 0x0018 */ -+#define WASR_FW_OWN_INVALID_ACCESS BIT(4) -+#define WASR_RX1_UNDER_FLOW BIT(3) -+#define WASR_RX0_UNDER_FLOW BIT(2) -+#define WASR_TX1_OVER_FLOW BIT(1) -+#define WASR_TX0_OVER_FLOW BIT(0) -+ -+/* 3 WSICR 0x001C */ -+#define WSICR_H2D_SW_INT_SET BITS(16, 31) -+ -+/* 3 WRPLR 0x0050 */ -+#define WRPLR_RX1_PACKET_LENGTH BITS(16, 31) -+#define WRPLR_RX0_PACKET_LENGTH BITS(0, 15) -+ -+/* 3 HSTCR 0x0058 */ -+#define HSTCR_AFF_BURST_LEN BITS(24, 25) -+#define HSTCR_AFF_BURST_LEN_OFFSET 24 -+#define HSTCR_TRANS_TARGET BITS(20, 22) -+#define HSTCR_TRANS_TARGET_OFFSET 20 -+#define HSTCR_HSIF_TRANS_CNT BITS(2, 19) -+#define HSTCR_HSIF_TRANS_CNT_OFFSET 2 -+ -+/* HSTCR_TRANS_TARGET */ -+typedef enum _eTransTarget { -+ TRANS_TARGET_TXD0 = 0, -+ TRANS_TARGET_TXD1, -+ TRANS_TARGET_RXD0, -+ TRANS_TARGET_RXD1, -+ TRANS_TARGET_WHISR, -+ NUM_TRANS_TARGET -+} E_TRANS_TARGET_T; -+ -+typedef enum _E_AFF_BURST_LEN { -+ BURST_1_DW = 0, -+ BURST_4_DW, -+ BURST_8_DW, -+ BURST_RSV, -+ NUM_AFF_BURST_LEN -+} E_AFF_BURST_LEN; -+ -+#endif /* _MTREG_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h -new file mode 100644 -index 0000000000000..c059b707aee84 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h -@@ -0,0 +1,498 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic.h#1 -+*/ -+ -+/*! \file "nic.h" -+ \brief The declaration of nic functions -+ -+ Detail description. -+*/ -+ -+/* -+** Log: nic.h -+ * -+ * 11 01 2011 chinglan.wang -+ * NULL -+ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP. -+ * If disconnect the AP and flush all the data frame in the TX queue, WPS -+ * cannot do the 4-way handshake to connect to the AP.. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 05 11 2011 cp.wu -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. -+ * -+ * 04 11 2011 yuche.tsai -+ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue. -+ * Fix kernel panic issue when MMPDU of P2P is pending in driver. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right -+ * after connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 01 2011 cm.chang -+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode -+ * . -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] -+ * Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 26 2010 eddie.chen -+ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB -+ * Add auto rate parameter in registry. -+ * -+ * 10 12 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * add HT (802.11n) fixed rate support. -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced -+ * by ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test -+ * with AIS associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * HIFSYS Clock Source Workaround -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * Centralize mgmt/system service procedures into independent calls. -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 06 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Update arguments for nicUpdateBeaconIETemplate() -+ * -+ * 07 06 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * STA-REC is maintained by CNM only. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) ignore RSN checking when RSN is not turned on. -+ * 2) set STA-REC deactivation callback as NULL -+ * 3) add variable initialization API based on PHY configuration -+ * -+ * 06 30 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync. with CMD/EVENT document ver0.07. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 25 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Create beacon update path, with expose bssUpdateBeaconContent() -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implement TX_DONE callback path. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) surpress compiler warning -+ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add channel frequency <-> number conversion -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+ * 03 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always process TX interrupt first then RX interrupt. -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add checksum offloading support. -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-10-13 21:58:58 GMT mtk01084 -+** update for new HW architecture design -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-24 21:12:55 GMT mtk01104 -+** Add function prototype nicRestoreSpiDefMode() -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-19 18:32:54 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:32 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _NIC_H -+#define _NIC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+struct _REG_ENTRY_T { -+ UINT_32 u4Offset; -+ UINT_32 u4Value; -+}; -+ -+struct _TABLE_ENTRY_T { -+ P_REG_ENTRY_T pu4TablePtr; -+ UINT_16 u2Size; -+}; -+ -+/*! INT status to event map */ -+typedef struct _INT_EVENT_MAP_T { -+ UINT_32 u4Int; -+ UINT_32 u4Event; -+} INT_EVENT_MAP_T, *P_INT_EVENT_MAP_T; -+ -+enum ENUM_INT_EVENT_T { -+ INT_EVENT_ABNORMAL, -+ INT_EVENT_SW_INT, -+ INT_EVENT_TX, -+ INT_EVENT_RX, -+ INT_EVENT_NUM -+}; -+ -+typedef enum _ENUM_IE_UPD_METHOD_T { -+ IE_UPD_METHOD_UPDATE_RANDOM, -+ IE_UPD_METHOD_UPDATE_ALL, -+ IE_UPD_METHOD_DELETE_ALL, -+} ENUM_IE_UPD_METHOD_T, *P_ENUM_IE_UPD_METHOD_T; -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern BOOLEAN fgIsResetting; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in nic.c */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicAllocateAdapterMemory(IN P_ADAPTER_T prAdapter); -+ -+VOID nicReleaseAdapterMemory(IN P_ADAPTER_T prAdapter); -+ -+VOID nicDisableInterrupt(IN P_ADAPTER_T prAdapter); -+ -+VOID nicEnableInterrupt(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicProcessIST(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicProcessIST_impl(IN P_ADAPTER_T prAdapter, IN UINT_32 u4IntStatus); -+ -+WLAN_STATUS nicInitializeAdapter(IN P_ADAPTER_T prAdapter); -+ -+VOID nicMCRInit(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN nicVerifyChipID(IN P_ADAPTER_T prAdapter); -+ -+#if CFG_SDIO_INTR_ENHANCE -+VOID nicSDIOInit(IN P_ADAPTER_T prAdapter); -+ -+VOID nicSDIOReadIntStatus(IN P_ADAPTER_T prAdapter, OUT PUINT_32 pu4IntStatus); -+#endif -+ -+BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter); -+ -+VOID nicpmSetFWOwn(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableGlobalInt); -+ -+BOOLEAN nicpmSetAcpiPowerD0(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN nicpmSetAcpiPowerD3(IN P_ADAPTER_T prAdapter); -+ -+#if defined(_HIF_SPI) -+void nicRestoreSpiDefMode(IN P_ADAPTER_T prAdapter); -+#endif -+ -+VOID nicProcessSoftwareInterrupt(IN P_ADAPTER_T prAdapter); -+ -+VOID nicProcessAbnormalInterrupt(IN P_ADAPTER_T prAdapter); -+ -+VOID nicPutMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, IN UINT_32 u4Data); -+ -+VOID nicGetMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, OUT PUINT_32 pu4Data); -+ -+VOID nicSetSwIntr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4SwIntrBitmap); -+ -+P_CMD_INFO_T nicGetPendingCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum); -+ -+P_MSDU_INFO_T nicGetPendingTxMsduInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum); -+ -+P_MSDU_INFO_T nicGetPendingStaMMPDU(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx); -+ -+VOID nicFreePendingTxMsduInfoByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType); -+ -+UINT_8 nicIncreaseCmdSeqNum(IN P_ADAPTER_T prAdapter); -+ -+UINT_8 nicIncreaseTxSeqNum(IN P_ADAPTER_T prAdapter); -+ -+/* Media State Change */ -+WLAN_STATUS -+nicMediaStateChange(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus); -+ -+/* Utility function for channel number conversion */ -+UINT_32 nicChannelNum2Freq(IN UINT_32 u4ChannelNum); -+ -+UINT_32 nicFreq2ChannelNum(IN UINT_32 u4FreqInKHz); -+ -+/* firmware command wrapper */ -+ /* NETWORK (WIFISYS) */ -+WLAN_STATUS nicActivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+WLAN_STATUS nicDeactivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+ /* BSS-INFO */ -+WLAN_STATUS nicUpdateBss(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+ /* BSS-INFO Indication (PM) */ -+WLAN_STATUS nicPmIndicateBssCreated(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+WLAN_STATUS nicPmIndicateBssConnected(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+WLAN_STATUS nicPmIndicateBssAbort(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+ /* Beacon Template Update */ -+WLAN_STATUS -+nicUpdateBeaconIETemplate(IN P_ADAPTER_T prAdapter, -+ IN ENUM_IE_UPD_METHOD_T eIeUpdMethod, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN UINT_16 u2Capability, IN PUINT_8 aucIe, IN UINT_16 u2IELen); -+ -+WLAN_STATUS nicQmUpdateWmmParms(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+WLAN_STATUS nicSetAutoTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_AUTO_POWER_PARAM_T prAutoPwrParam); -+ -+/*----------------------------------------------------------------------------*/ -+/* Calibration Control */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicUpdateTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam); -+ -+WLAN_STATUS nicUpdate5GOffset(IN P_ADAPTER_T prAdapter, IN P_CMD_5G_PWR_OFFSET_T pr5GPwrOffset); -+ -+WLAN_STATUS nicUpdateDPD(IN P_ADAPTER_T prAdapter, IN P_CMD_PWR_PARAM_T prDpdCalResult); -+ -+/*----------------------------------------------------------------------------*/ -+/* PHY configuration */ -+/*----------------------------------------------------------------------------*/ -+VOID nicSetAvailablePhyTypeSet(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* MGMT and System Service Control */ -+/*----------------------------------------------------------------------------*/ -+VOID nicInitSystemService(IN P_ADAPTER_T prAdapter); -+ -+VOID nicResetSystemService(IN P_ADAPTER_T prAdapter); -+ -+VOID nicUninitSystemService(IN P_ADAPTER_T prAdapter); -+ -+VOID nicInitMGMT(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo); -+ -+VOID nicUninitMGMT(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS -+nicConfigPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, PARAM_POWER_MODE ePwrMode, BOOLEAN fgEnCmdEvent); -+ -+WLAN_STATUS nicEnterCtiaMode(IN P_ADAPTER_T prAdapter, BOOLEAN fgEnterCtia, BOOLEAN fgEnCmdEvent); -+/*----------------------------------------------------------------------------*/ -+/* Scan Result Processing */ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicAddScanResult(IN P_ADAPTER_T prAdapter, -+ IN PARAM_MAC_ADDRESS rMacAddr, -+ IN P_PARAM_SSID_T prSsid, -+ IN UINT_32 u4Privacy, -+ IN PARAM_RSSI rRssi, -+ IN ENUM_PARAM_NETWORK_TYPE_T eNetworkType, -+ IN P_PARAM_802_11_CONFIG_T prConfiguration, -+ IN ENUM_PARAM_OP_MODE_T eOpMode, -+ IN PARAM_RATES_EX rSupportedRates, IN UINT_16 u2IELength, IN PUINT_8 pucIEBuf); -+ -+VOID nicFreeScanResultIE(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Idx); -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+/*----------------------------------------------------------------------------*/ -+/* Workaround Control */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicEnableClockGating(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicDisableClockGating(IN P_ADAPTER_T prAdapter); -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/* Fixed Rate Hacking */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicUpdateRateParams(IN P_ADAPTER_T prAdapter, -+ IN ENUM_REGISTRY_FIXED_RATE_T eRateSetting, -+ IN PUINT_8 pucDesiredPhyTypeSet, -+ IN PUINT_16 pu2DesiredNonHTRateSet, -+ IN PUINT_16 pu2BSSBasicRateSet, -+ IN PUINT_8 pucMcsSet, IN PUINT_8 pucSupMcs32, IN PUINT_16 u2HtCapInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* Write registers */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicWriteMcr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Address, IN UINT_32 u4Value); -+ -+/*----------------------------------------------------------------------------*/ -+/* Update auto rate */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicRlmArUpdateParms(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4ArSysParam0, -+ IN UINT_32 u4ArSysParam1, IN UINT_32 u4ArSysParam2, IN UINT_32 u4ArSysParam3); -+ -+/*----------------------------------------------------------------------------*/ -+/* Enable/Disable Roaming */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRoamingUpdateParams(IN P_ADAPTER_T prAdapter, IN UINT_32 u4EnableRoaming); -+ -+VOID nicPrintFirmwareAssertInfo(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Link Quality Updating */ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicUpdateLinkQuality(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN P_EVENT_LINK_QUALITY prEventLinkQuality); -+ -+VOID -+nicUpdateRSSI(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality); -+ -+VOID nicUpdateLinkSpeed(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN UINT_16 u2LinkSpeed); -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+WLAN_STATUS nicUpdateRddTestMode(IN P_ADAPTER_T prAdapter, IN P_CMD_RDD_CH_T prRddChParam); -+#endif -+ -+#endif /* _NIC_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h -new file mode 100644 -index 0000000000000..86e2c84b07ffa ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h -@@ -0,0 +1,420 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic_rx.h#1 -+*/ -+ -+/*! \file "nic_rx.h" -+ \brief The declaration of the nic rx functions -+ -+*/ -+ -+/* -+** Log: nic_rx.h -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 05 05 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * add delay after whole-chip resetting for MT5931 E1 ASIC. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 01 24 2011 cm.chang -+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode -+ * and stop ampdu timer when sta_rec is freed -+ * Process received 20/40 coexistence action frame for AP mode -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Change prototype of API of adding P2P device to scan result. -+ * Additional IE buffer is saved. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Modify data structure for P2P Scan result. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * newly added P2P API should be declared in header file. -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * saa_fsm.c is migrated. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * remove driver-land statistics. -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK -+ * * -+ * -+ * 03 11 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING -+ * -+ * 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement host-side firmware download logic -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * * 2) firmware image length is now retrieved via NdisFileOpen -+ * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * * 4) nicRxWaitResponse() revised -+ * * 5) another set of TQ counter default value is added for fw-download state -+ * * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * and result is retrieved by get ATInfo instead -+ * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:49:09 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-12-09 14:02:37 GMT MTK02468 -+** Added ucStaRecIdx in SW_RFB_T and HALF_SEQ_NO_COUNT definition (to replace HALF_SEQ_NO_CNOUT) -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-27 11:07:54 GMT mtk02752 -+** add flush for reset -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-25 18:18:09 GMT mtk02752 -+** modify nicRxAddScanResult() -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-24 22:42:22 GMT mtk02752 -+** add nicRxAddScanResult() to prepare to handle SCAN_RESULT event -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-24 19:57:06 GMT mtk02752 -+** adopt P_HIF_RX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-16 21:43:04 GMT mtk02752 -+** correct ENUM_RX_PKT_DESTINATION_T definitions -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 15:28:25 GMT mtk02752 -+** add ucQueuedPacketNum for indicating how many packet are queued by RX reordering buffer/forwarding path -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-16 15:05:01 GMT mtk02752 -+** add eTC for SW_RFB_T and structure RX_MAILBOX -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-13 21:16:57 GMT mtk02752 -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-13 16:59:30 GMT mtk02752 -+** add handler for event packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-13 13:45:50 GMT mtk02752 -+** add port param for nicRxEnhanceReadBuffer() -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-11 10:12:31 GMT mtk02752 -+** nicSDIOReadIntStatus() always read sizeof(ENHANCE_MODE_DATA_STRUCT_T) for int response, -+** thus the number should be set to 0(:=16) instead of 10 -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-29 19:53:32 GMT mtk01084 -+** modify structure naming -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-23 16:08:23 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:59:01 GMT mtk01084 -+** update for new HW architecture design -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-20 12:23:33 GMT mtk01461 -+** Add u4MaxEventBufferLen parameter to nicRxWaitResponse() -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-05-18 21:00:48 GMT mtk01426 -+** Update SDIO_MAXIMUM_RX_STATUS value -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-28 10:36:15 GMT mtk01461 -+** Remove unused define - SDIO_MAXIMUM_TX_STATUS -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:53:17 GMT mtk01461 -+** Add function for HIF_LOOPBACK_PRE_TEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:56:19 GMT mtk01426 -+** Add to support CFG_HIF_LOOPBACK and CFG_SDIO_RX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:19:56 GMT mtk01426 -+** Add nicRxWaitResponse function proto type -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:35 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _NIC_RX_H -+#define _NIC_RX_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern P_SW_RFB_T g_arGscnResultsTempBuffer[]; -+extern UINT_8 g_GscanResultsTempBufferIndex; -+extern UINT_8 g_arGscanResultsIndicateNumber[]; -+extern UINT_8 g_GetResultsBufferedCnt; -+extern UINT_8 g_GetResultsCmdCnt; -+extern void kalDevLoopbkRxHandle(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define MAX_SEQ_NO 4095 -+#define MAX_SEQ_NO_COUNT 4096 -+#define HALF_SEQ_NO_CNOUT 2048 -+ -+#define HALF_SEQ_NO_COUNT 2048 -+ -+#define MT6620_FIXED_WIN_SIZE 64 -+#define CFG_RX_MAX_BA_ENTRY 4 -+#define CFG_RX_MAX_BA_TID_NUM 8 -+ -+#define RX_STATUS_FLAG_MORE_PACKET BIT(30) -+#define RX_STATUS_CHKSUM_MASK BITS(0, 10) -+ -+#define RX_RFB_LEN_FIELD_LEN 4 -+#define RX_HEADER_OFFSET 2 -+ -+#define RX_RETURN_INDICATED_RFB_TIMEOUT_SEC 3 -+ -+#if defined(_HIF_SDIO) && defined(WINDOWS_DDK) -+/*! On XP, maximum Tx+Rx Statue <= 64-4(HISR)*/ -+#define SDIO_MAXIMUM_RX_LEN_NUM 0 /*!< 0~15 (0: un-limited) */ -+#else -+#define SDIO_MAXIMUM_RX_LEN_NUM 0 /*!< 0~15 (0: un-limited) */ -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_RX_STATISTIC_COUNTER_T { -+ RX_MPDU_TOTAL_COUNT = 0, -+ RX_SIZE_ERR_DROP_COUNT, -+ -+ RX_DATA_INDICATION_COUNT, -+ RX_DATA_RETURNED_COUNT, -+ RX_DATA_RETAINED_COUNT, -+ -+ RX_DROP_TOTAL_COUNT, -+ RX_TYPE_ERR_DROP_COUNT, -+ RX_CLASS_ERR_DROP_COUNT, -+ RX_DST_NULL_DROP_COUNT, -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 -+ RX_CSUM_TCP_FAILED_COUNT, -+ RX_CSUM_UDP_FAILED_COUNT, -+ RX_CSUM_IP_FAILED_COUNT, -+ RX_CSUM_TCP_SUCCESS_COUNT, -+ RX_CSUM_UDP_SUCCESS_COUNT, -+ RX_CSUM_IP_SUCCESS_COUNT, -+ RX_CSUM_UNKNOWN_L4_PKT_COUNT, -+ RX_CSUM_UNKNOWN_L3_PKT_COUNT, -+ RX_IP_V6_PKT_CCOUNT, -+#endif -+ RX_STATISTIC_COUNTER_NUM -+} ENUM_RX_STATISTIC_COUNTER_T; -+ -+typedef enum _ENUM_RX_PKT_DESTINATION_T { -+ RX_PKT_DESTINATION_HOST, /* to OS */ -+ RX_PKT_DESTINATION_FORWARD, /* to TX queue for forward, AP mode */ -+ RX_PKT_DESTINATION_HOST_WITH_FORWARD, /* to both TX and OS, AP mode broadcast packet */ -+ RX_PKT_DESTINATION_NULL, /* packet to be freed */ -+ RX_PKT_DESTINATION_NUM -+} ENUM_RX_PKT_DESTINATION_T; -+ -+struct _SW_RFB_T { -+ QUE_ENTRY_T rQueEntry; -+ PVOID pvPacket; /*!< ptr to rx Packet Descriptor */ -+ PUINT_8 pucRecvBuff; /*!< ptr to receive data buffer */ -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_32 u4HifRxHdrFlag; -+ PVOID pvHeader; -+ UINT_16 u2PacketLen; -+ UINT_16 u2HeaderLen; -+ UINT_16 u2SSN; -+ UINT_8 ucTid; -+ UINT_8 ucWlanIdx; -+ UINT_8 ucPacketType; -+ UINT_8 ucStaRecIdx; -+ -+ ENUM_CSUM_RESULT_T aeCSUM[CSUM_TYPE_NUM]; -+ ENUM_RX_PKT_DESTINATION_T eDst; -+ ENUM_TRAFFIC_CLASS_INDEX_T eTC; /* only valid when eDst == FORWARD */ -+ -+ UINT_64 rRxTime; -+}; -+ -+/*! RX configuration type structure */ -+typedef struct _RX_CTRL_T { -+ UINT_32 u4RxCachedSize; -+ PUINT_8 pucRxCached; -+ QUE_T rFreeSwRfbList; -+ QUE_T rReceivedRfbList; -+ QUE_T rIndicatedRfbList; -+ -+#if CFG_SDIO_RX_AGG -+ PUINT_8 pucRxCoalescingBufPtr; -+#endif -+ -+ PVOID apvIndPacket[CFG_RX_MAX_PKT_NUM]; -+ PVOID apvRetainedPacket[CFG_RX_MAX_PKT_NUM]; -+ -+ UINT_8 ucNumIndPacket; -+ UINT_8 ucNumRetainedPacket; -+ UINT_64 au8Statistics[RX_STATISTIC_COUNTER_NUM]; /*!< RX Counters */ -+ -+#if CFG_HIF_STATISTICS -+ UINT_32 u4TotalRxAccessNum; -+ UINT_32 u4TotalRxPacketNum; -+#endif -+ -+#if CFG_HIF_RX_STARVATION_WARNING -+ UINT_32 u4QueuedCnt; -+ UINT_32 u4DequeuedCnt; -+#endif -+ -+#if CFG_RX_PKTS_DUMP -+ UINT_32 u4RxPktsDumpTypeMask; -+#endif -+ -+} RX_CTRL_T, *P_RX_CTRL_T; -+ -+typedef struct _RX_MAILBOX_T { -+ UINT_32 u4RxMailbox[2]; /* for Device-to-Host Mailbox */ -+} RX_MAILBOX_T, *P_RX_MAILBOX_T; -+ -+typedef WLAN_STATUS(*PROCESS_RX_MGT_FUNCTION) (P_ADAPTER_T, P_SW_RFB_T); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define RX_INC_CNT(prRxCtrl, eCounter) \ -+ {((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter]++; } -+ -+#define RX_ADD_CNT(prRxCtrl, eCounter, u8Amount) \ -+ {((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter] += (UINT_64)u8Amount; } -+ -+#define RX_GET_CNT(prRxCtrl, eCounter) \ -+ (((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter]) -+ -+#define RX_RESET_ALL_CNTS(prRxCtrl) \ -+ {kalMemZero(&prRxCtrl->au8Statistics[0], sizeof(prRxCtrl->au8Statistics)); } -+ -+#define RX_STATUS_TEST_MORE_FLAG(flag) \ -+ ((BOOLEAN)((flag & RX_STATUS_FLAG_MORE_PACKET) ? TRUE : FALSE)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID nicRxInitialize(IN P_ADAPTER_T prAdapter); -+ -+VOID nicRxUninitialize(IN P_ADAPTER_T prAdapter); -+ -+VOID nicRxProcessRFBs(IN P_ADAPTER_T prAdapter); -+ -+#if !CFG_SDIO_INTR_ENHANCE -+VOID nicRxReceiveRFBs(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicRxReadBuffer(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+#else -+VOID nicRxSDIOReceiveRFBs(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS -+nicRxEnhanceReadBuffer(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DataPort, IN UINT_16 u2RxLength, IN OUT P_SW_RFB_T prSwRfb); -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+#if CFG_SDIO_RX_AGG -+VOID nicRxSDIOAggReceiveRFBs(IN P_ADAPTER_T prAdapter); -+#endif -+ -+WLAN_STATUS nicRxSetupRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prRfb); -+ -+VOID nicRxReturnRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prRfb); -+ -+VOID nicProcessRxInterrupt(IN P_ADAPTER_T prAdapter); -+ -+VOID nicRxProcessPktWithoutReorder(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID nicRxProcessForwardPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID nicRxProcessGOBroadcastPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID nicRxFillRFB(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+VOID nicRxProcessDataPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+VOID nicRxProcessMgmtPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+VOID nicRxFillChksumStatus(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb, IN UINT_32 u4TcpUdpIpCksStatus); -+ -+VOID nicRxUpdateCSUMStatistics(IN P_ADAPTER_T prAdapter, IN const ENUM_CSUM_RESULT_T aeCSUM[]); -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+VOID nicRxQueryStatus(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count); -+ -+VOID nicRxClearStatistics(IN P_ADAPTER_T prAdapter); -+ -+VOID nicRxQueryStatistics(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count); -+ -+WLAN_STATUS -+nicRxWaitResponse(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucPortIdx, OUT PUINT_8 pucRspBuffer, IN UINT_32 u4MaxRespBufferLen, OUT PUINT_32 pu4Length); -+ -+VOID nicRxEnablePromiscuousMode(IN P_ADAPTER_T prAdapter); -+ -+VOID nicRxDisablePromiscuousMode(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicRxFlush(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicRxProcessActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+#endif /* _NIC_RX_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h -new file mode 100644 -index 0000000000000..e516468fcb16a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h -@@ -0,0 +1,642 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic_tx.h#1 -+*/ -+ -+/*! \file nic_tx.h -+ \brief Functions that provide TX operation in NIC's point of view. -+ -+ This file provides TX functions which are responsible for both Hardware and -+ Software Resource Management and keep their Synchronization. -+ -+*/ -+ -+/* -+** Log: nic_tx.h -+ * -+ * 11 18 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add log counter for tx -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add TX_DONE status detail information. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing -+ * frame dropping cases for TC4 path -+ * 1. add nicTxGetResource() API for QM to make decisions. -+ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 02 16 2011 cp.wu -+ * [WCXRP00000449] [MT6620 Wi-Fi][Driver] Refine CMD queue handling by adding an extra API for checking -+ * available count and modify behavior -+ * 1. add new API: nicTxGetFreeCmdCount() -+ * 2. when there is insufficient command descriptor, nicTxEnqueueMsdu() will drop command packets directly -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 12 15 2010 yuche.tsai -+ * NULL -+ * Update SLT Descriptor number configure in driver. -+ * -+ * 11 16 2010 yarco.yang -+ * [WCXRP00000177] [MT5931 F/W] Performance tuning for 1st connection -+ * Update TX buffer count -+ * -+ * 11 03 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * 1) use 8 buffers for MT5931 which is equipped with less memory -+ * 2) modify MT5931 debug level to TRACE when download is successful -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion -+ * 2. shorten polling count for shorter response time -+ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * API added: nicTxPendingPackets(), for simplifying porting layer -+ * -+ * 07 26 2010 cp.wu -+ * -+ * change TC4 initial value from 2 to 4. -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under -+ * concurrent network operation -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 06 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Add MGMT Packet type for HIF_TX_HEADER -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * integrate . -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * refine TX-DONE callback. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * TX descriptors are now allocated once for reducing allocation overhead -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * specify correct value for management frames. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add flag on MSDU_INFO_T for indicating BIP frame and forceBasicRate -+ * 2) add packet type for indicating management frames -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add necessary changes to driver data paths. -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add TX_PACKET_MGMT to indicate the frame is coming from management modules -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * remove driver-land statistics. -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK -+ * * * -+ * -+ * 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 03 02 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Redistributed the initial TC resources for normal operation -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add mutex to avoid multiple access to qmTxQueue simultaneously. -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add new API: wlanProcessQueuedPackets() -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * * * 2) firmware image length is now retrieved via NdisFileOpen -+ * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * * * 4) nicRxWaitResponse() revised -+ * * * 5) another set of TQ counter default value is added for fw-download state -+ * * * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * * 4. correct some HAL implementation -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the Burst_End Indication mechanism -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * and result is retrieved by get ATInfo instead -+ * * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:53:28 GMT mtk02752 -+** remove unused API -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-27 11:08:00 GMT mtk02752 -+** add flush for reset -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-24 19:56:49 GMT mtk02752 -+** remove redundant eTC -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-23 22:01:08 GMT mtk02468 -+** Added MSDU_INFO fields for composing HIF TX header -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-17 22:40:51 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-17 17:35:05 GMT mtk02752 -+** + nicTxMsduInfoList() for sending MsduInfoList -+** + NIC_TX_BUFF_COUNT_TC[0~5] -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-17 11:07:00 GMT mtk02752 -+** add nicTxAdjustTcq() API -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 22:28:30 GMT mtk02752 -+** move aucFreeBufferCount/aucMaxNumOfBuffer into another structure -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-16 21:44:50 GMT mtk02752 -+** + nicTxReturnMsduInfo() -+** + nicTxFillMsduInfo() -+** + rFreeMsduInfoList field in TX_CTRL -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-16 18:00:43 GMT mtk02752 -+** use P_PACKET_INFO_T for prPacket to avoid inventing another new structure for packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-16 15:28:49 GMT mtk02752 -+** add ucQueuedPacketNum for indicating how many packets are queued by per STA/AC queue -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-16 10:52:01 GMT mtk02752 -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-14 23:39:24 GMT mtk02752 -+** interface structure redefine -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-13 21:17:03 GMT mtk02752 -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-29 19:53:10 GMT mtk01084 -+** remove strange code by Frog -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:59:04 GMT mtk01084 -+** update for new HW architecture design -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-10-02 13:53:03 GMT mtk01725 -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-28 10:36:50 GMT mtk01461 -+** Add declaration of nicTxReleaseResource() -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-17 19:58:39 GMT mtk01461 -+** Move CMD_INFO_T related define and function to cmd_buf.h -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:53:53 GMT mtk01461 -+** Add function for SDIO_TX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 00:33:27 GMT mtk01461 -+** Define constants for TX PATH and add nicTxPollingResource -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:09:32 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:38 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _NIC_TX_H -+#define _NIC_TX_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define NIC_TX_RESOURCE_POLLING_TIMEOUT 256 -+#define NIC_TX_RESOURCE_POLLING_DELAY_MSEC 50 -+ -+/* Maximum buffer count for individual HIF TCQ */ -+ -+#if defined(MT6620) -+#if CFG_SLT_SUPPORT -+ /* 20101215 mtk01725 Redistributed the initial TC resources for SLT operation */ -+#define NIC_TX_BUFF_COUNT_TC0 0 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC1 16 /* First connection: 32 */ -+#define NIC_TX_BUFF_COUNT_TC2 0 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC3 0 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ -+#define NIC_TX_BUFF_COUNT_TC5 0 /* First connection: 0 */ -+#else -+ /* 20100302 mtk02468 Redistributed the initial TC resources for normal operation */ -+#define NIC_TX_BUFF_COUNT_TC0 6 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC1 8 /* First connection: 32 */ -+#define NIC_TX_BUFF_COUNT_TC2 8 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC3 8 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ -+#define NIC_TX_BUFF_COUNT_TC5 2 /* First connection: 0 */ -+#endif -+#elif defined(MT6628) -+#if (CFG_SRAM_SIZE_OPTION == 0) -+#define NIC_TX_BUFF_COUNT_TC0 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC1 20 /* First connection: 32 */ -+#define NIC_TX_BUFF_COUNT_TC2 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC3 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ -+#define NIC_TX_BUFF_COUNT_TC5 1 /* First connection: 0 */ -+#elif (CFG_SRAM_SIZE_OPTION == 1) -+#define NIC_TX_BUFF_COUNT_TC0 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC1 36 /* First connection: 32 */ -+#define NIC_TX_BUFF_COUNT_TC2 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC3 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ -+#define NIC_TX_BUFF_COUNT_TC5 1 /* First connection: 0 */ -+#elif (CFG_SRAM_SIZE_OPTION == 2) -+#define NIC_TX_BUFF_COUNT_TC0 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC1 48 /* First connection: 32 */ -+#define NIC_TX_BUFF_COUNT_TC2 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC3 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ -+#define NIC_TX_BUFF_COUNT_TC5 1 /* First connection: 0 */ -+#else -+#error "> Set TX_BUFF_COUNT_TC error!" -+#endif -+#endif -+ -+#define NIC_TX_BUFF_SUM (NIC_TX_BUFF_COUNT_TC0 + \ -+ NIC_TX_BUFF_COUNT_TC1 + \ -+ NIC_TX_BUFF_COUNT_TC2 + \ -+ NIC_TX_BUFF_COUNT_TC3 + \ -+ NIC_TX_BUFF_COUNT_TC4 + \ -+ NIC_TX_BUFF_COUNT_TC5) -+#if CFG_ENABLE_FW_DOWNLOAD -+ -+#define NIC_TX_INIT_BUFF_COUNT_TC0 8 -+#define NIC_TX_INIT_BUFF_COUNT_TC1 0 -+#define NIC_TX_INIT_BUFF_COUNT_TC2 0 -+#define NIC_TX_INIT_BUFF_COUNT_TC3 0 -+#define NIC_TX_INIT_BUFF_COUNT_TC4 0 -+#define NIC_TX_INIT_BUFF_COUNT_TC5 0 -+ -+#define NIC_TX_INIT_BUFF_SUM (NIC_TX_INIT_BUFF_COUNT_TC0 + \ -+ NIC_TX_INIT_BUFF_COUNT_TC1 + \ -+ NIC_TX_INIT_BUFF_COUNT_TC2 + \ -+ NIC_TX_INIT_BUFF_COUNT_TC3 + \ -+ NIC_TX_INIT_BUFF_COUNT_TC4 + \ -+ NIC_TX_INIT_BUFF_COUNT_TC5) -+ -+#endif -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+#define NIC_TX_TIME_THRESHOLD 100 /* in unit of ms */ -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* 3 Session for TX QUEUES */ -+/* The definition in this ENUM is used to categorize packet's Traffic Class according -+ * to the their TID(User Priority). -+ * In order to achieve QoS goal, a particular TC should not block the process of -+ * another packet with different TC. -+ * In current design we will have 5 categories(TCs) of SW resource. -+ */ -+typedef enum _ENUM_TRAFFIC_CLASS_INDEX_T { -+ TC0_INDEX = 0, /* HIF TX0: AC0 packets */ -+ TC1_INDEX, /* HIF TX0: AC1 packets & non-QoS packets */ -+ TC2_INDEX, /* HIF TX0: AC2 packets */ -+ TC3_INDEX, /* HIF TX0: AC3 packets */ -+ TC4_INDEX, /* HIF TX1: Command packets or 802.1x packets */ -+ TC5_INDEX, /* HIF TX0: BMCAST packets */ -+ TC_NUM /* Maximum number of Traffic Classes. */ -+} ENUM_TRAFFIC_CLASS_INDEX_T; -+ -+typedef enum _ENUM_TX_STATISTIC_COUNTER_T { -+ TX_MPDU_TOTAL_COUNT = 0, -+ TX_INACTIVE_BSS_DROP, -+ TX_INACTIVE_STA_DROP, -+ TX_FORWARD_OVERFLOW_DROP, -+ TX_AP_BORADCAST_DROP, -+ TX_STATISTIC_COUNTER_NUM -+} ENUM_TX_STATISTIC_COUNTER_T; -+ -+typedef struct _TX_TCQ_STATUS_T { -+ UINT_8 aucFreeBufferCount[TC_NUM]; -+ UINT_8 aucMaxNumOfBuffer[TC_NUM]; -+} TX_TCQ_STATUS_T, *P_TX_TCQ_STATUS_T; -+ -+typedef struct _TX_TCQ_ADJUST_T { -+ INT_8 acVariation[TC_NUM]; -+} TX_TCQ_ADJUST_T, *P_TX_TCQ_ADJUST_T; -+ -+typedef struct _TX_CTRL_T { -+ UINT_32 u4TxCachedSize; -+ PUINT_8 pucTxCached; -+ -+/* Elements below is classified according to TC (Traffic Class) value. */ -+ -+ TX_TCQ_STATUS_T rTc; -+ -+ PUINT_8 pucTxCoalescingBufPtr; -+ -+ QUE_T rFreeMsduInfoList; -+ -+ /* Management Frame Tracking */ -+ /* number of management frames to be sent */ -+ INT_32 i4TxMgmtPendingNum; -+ -+ /* to tracking management frames need TX done callback */ -+ QUE_T rTxMgmtTxingQueue; -+ -+#if CFG_HIF_STATISTICS -+ UINT_32 u4TotalTxAccessNum; -+ UINT_32 u4TotalTxPacketNum; -+#endif -+ UINT_32 au4Statistics[TX_STATISTIC_COUNTER_NUM]; -+ -+ /* Number to track forwarding frames */ -+ INT_32 i4PendingFwdFrameCount; -+ -+} TX_CTRL_T, *P_TX_CTRL_T; -+ -+typedef enum _ENUM_TX_PACKET_SRC_T { -+ TX_PACKET_OS, -+ TX_PACKET_OS_OID, -+ TX_PACKET_FORWARDING, -+ TX_PACKET_MGMT, -+ TX_PACKET_NUM -+} ENUM_TX_PACKET_SRC_T; -+ -+typedef enum _ENUM_HIF_TX_PACKET_TYPE_T { -+ HIF_TX_PACKET_TYPE_DATA = 0, -+ HIF_TX_PACKET_TYPE_COMMAND, -+ HIF_TX_PACKET_TYPE_HIF_LB, -+ HIF_TX_PACKET_TYPE_MGMT -+} ENUM_HIF_TX_PACKET_TYPE_T, *P_ENUM_HIF_TX_PACKET_TYPE_T; -+ -+typedef enum _ENUM_TX_RESULT_CODE_T { -+ TX_RESULT_SUCCESS = 0, -+ TX_RESULT_LIFE_TIMEOUT, -+ TX_RESULT_RTS_ERROR, -+ TX_RESULT_MPDU_ERROR, -+ TX_RESULT_AGING_TIMEOUT, -+ TX_RESULT_FLUSHED, -+ TX_RESULT_DROPPED_IN_DRIVER = 32, -+ TX_RESULT_NUM -+} ENUM_TX_RESULT_CODE_T, *P_ENUM_TX_RESULT_CODE_T; -+ -+struct _WLAN_CFG_ENTRY_T { -+ UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX]; -+ UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX]; -+ WLAN_CFG_SET_CB pfSetCb; -+ PVOID pPrivate; -+ UINT_32 u4Flags; -+}; -+ -+struct _WLAN_CFG_T { -+ UINT_32 u4WlanCfgEntryNumMax; -+ UINT_32 u4WlanCfgKeyLenMax; -+ UINT_32 u4WlanCfgValueLenMax; -+ WLAN_CFG_ENTRY_T arWlanCfgBuf[WLAN_CFG_ENTRY_NUM_MAX]; -+}; -+ -+/* TX Call Back Function */ -+typedef WLAN_STATUS(*PFN_TX_DONE_HANDLER) (IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+typedef struct _PKT_PROFILE_T { -+ BOOLEAN fgIsValid; -+#if CFG_PRINT_RTP_PROFILE -+ BOOLEAN fgIsPrinted; -+ UINT_16 u2IpSn; -+ UINT_16 u2RtpSn; -+ UINT_8 ucTcxFreeCount; -+#endif -+ OS_SYSTIME rHardXmitArrivalTimestamp; -+ OS_SYSTIME rEnqueueTimestamp; -+ OS_SYSTIME rDequeueTimestamp; -+ OS_SYSTIME rHifTxDoneTimestamp; -+} PKT_PROFILE_T, *P_PKT_PROFILE_T; -+#endif -+ -+/* TX transactions could be divided into 4 kinds: -+ * -+ * 1) 802.1X / Bluetooth-over-Wi-Fi Security Frames -+ * [CMD_INFO_T] - [prPacket] - in skb or NDIS_PACKET form -+ * -+ * 2) MMPDU -+ * [CMD_INFO_T] - [prPacket] - [MSDU_INFO_T] - [prPacket] - direct buffer for frame body -+ * -+ * 3) Command Packets -+ * [CMD_INFO_T] - [pucInfoBuffer] - direct buffer for content of command packet -+ * -+ * 4) Normal data frame -+ * [MSDU_INFO_T] - [prPacket] - in skb or NDIS_PACKET form -+ */ -+ -+/* PS_FORWARDING_TYPE_NON_PS means that the receiving STA is in Active Mode -+* from the perspective of host driver (maybe not synchronized with FW --> SN is needed) -+*/ -+ -+struct _MSDU_INFO_T { -+ QUE_ENTRY_T rQueEntry; -+ P_NATIVE_PACKET prPacket; -+ -+ ENUM_TX_PACKET_SRC_T eSrc; /* specify OS/FORWARD packet */ -+ UINT_8 ucUserPriority; -+ -+ /* For composing HIF TX header */ -+ UINT_8 ucTC; /* Traffic Class: 0~4 (HIF TX0), 5 (HIF TX1) */ -+ UINT_8 ucPacketType; /* 0: Data, 1: Command, 2: HIF Loopback 3: Management Frame */ -+ UINT_8 ucStaRecIndex; -+ UINT_8 ucNetworkType; /* See ENUM_NETWORK_TYPE_T */ -+ UINT_8 ucFormatID; /* 0: MAUI, Linux, Windows NDIS 5.1 */ -+ BOOLEAN fgIs802_1x; /* TRUE: 802.1x frame */ -+ BOOLEAN fgIs802_11; /* TRUE: 802.11 header is present */ -+ UINT_16 u2PalLLH; /* PAL Logical Link Header (for BOW network) */ -+ UINT_16 u2AclSN; /* ACL Sequence Number (for BOW network) */ -+ UINT_8 ucPsForwardingType; /* See ENUM_PS_FORWARDING_TYPE_T */ -+ UINT_8 ucPsSessionID; /* PS Session ID specified by the FW for the STA */ -+ BOOLEAN fgIsBurstEnd; /* TRUE means this is the last packet of the burst for (STA, TID) */ -+ BOOLEAN fgIsBIP; /* Management Frame Protection */ -+ BOOLEAN fgIsBasicRate; /* Force Basic Rate Transmission */ -+ -+ /* flattened from PACKET_INFO_T */ -+ UINT_8 ucMacHeaderLength; -+ UINT_8 ucLlcLength; /* w/o EtherType */ -+ UINT_16 u2FrameLength; -+ UINT_8 aucEthDestAddr[MAC_ADDR_LEN]; /* Ethernet Destination Address */ -+ -+ /* for TX done tracking */ -+ UINT_8 ucTxSeqNum; -+ PFN_TX_DONE_HANDLER pfTxDoneHandler; -+ BOOLEAN fgNeedTxDoneStatus; -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ PKT_PROFILE_T rPktProfile; -+#endif -+ COMMAND_TYPE eCmdType; -+ UINT_8 ucCID; -+ UINT_32 u4InqueTime; -+}; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define TX_INC_CNT(prTxCtrl, eCounter) \ -+ {((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter]++; } -+ -+#define TX_ADD_CNT(prTxCtrl, eCounter, u8Amount) \ -+ {((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter] += (UINT_32)u8Amount; } -+ -+#define TX_GET_CNT(prTxCtrl, eCounter) \ -+ (((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter]) -+ -+#define TX_RESET_ALL_CNTS(prTxCtrl) \ -+ {kalMemZero(&prTxCtrl->au4Statistics[0], sizeof(prTxCtrl->au4Statistics)); } -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+#define PRINT_PKT_PROFILE(_pkt_profile, _note) \ -+{ \ -+ if (!(_pkt_profile)->fgIsPrinted) { \ -+ DBGLOG(TX, TRACE, "X[%u] E[%u] D[%u] HD[%u] B[%d] RTP[%d] %s\n", \ -+ (UINT_32)((_pkt_profile)->rHardXmitArrivalTimestamp), \ -+ (UINT_32)((_pkt_profile)->rEnqueueTimestamp), \ -+ (UINT_32)((_pkt_profile)->rDequeueTimestamp), \ -+ (UINT_32)((_pkt_profile)->rHifTxDoneTimestamp), \ -+ (UINT_8)((_pkt_profile)->ucTcxFreeCount), \ -+ (UINT_16)((_pkt_profile)->u2RtpSn), \ -+ (_note)); \ -+ (_pkt_profile)->fgIsPrinted = TRUE; \ -+ } \ -+} -+ -+#define CHK_PROFILES_DELTA(_pkt1, _pkt2, _delta) \ -+ (CHECK_FOR_TIMEOUT((_pkt1)->rHardXmitArrivalTimestamp, (_pkt2)->rHardXmitArrivalTimestamp, (_delta)) || \ -+ CHECK_FOR_TIMEOUT((_pkt1)->rEnqueueTimestamp, (_pkt2)->rEnqueueTimestamp, (_delta)) || \ -+ CHECK_FOR_TIMEOUT((_pkt1)->rDequeueTimestamp, (_pkt2)->rDequeueTimestamp, (_delta)) || \ -+ CHECK_FOR_TIMEOUT((_pkt1)->rHifTxDoneTimestamp, (_pkt2)->rHifTxDoneTimestamp, (_delta))) -+ -+#define CHK_PROFILE_DELTA(_pkt, _delta) \ -+ (CHECK_FOR_TIMEOUT((_pkt)->rEnqueueTimestamp, (_pkt)->rHardXmitArrivalTimestamp, (_delta)) || \ -+ CHECK_FOR_TIMEOUT((_pkt)->rDequeueTimestamp, (_pkt)->rEnqueueTimestamp, (_delta)) || \ -+ CHECK_FOR_TIMEOUT((_pkt)->rHifTxDoneTimestamp, (_pkt)->rDequeueTimestamp, (_delta))) -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID nicTxInitialize(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicTxAcquireResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC, IN BOOLEAN pfgIsSecOrMgmt); -+ -+WLAN_STATUS nicTxPollingResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC); -+ -+BOOLEAN nicTxReleaseResource(IN P_ADAPTER_T prAdapter, IN UINT_8 *aucTxRlsCnt); -+ -+WLAN_STATUS nicTxResetResource(IN P_ADAPTER_T prAdapter); -+ -+UINT_8 nicTxGetResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC); -+ -+WLAN_STATUS nicTxMsduInfoList(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); -+ -+WLAN_STATUS nicTxMsduQueue(IN P_ADAPTER_T prAdapter, UINT_8 ucPortIdx, P_QUE_T prQue); -+ -+WLAN_STATUS nicTxCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC); -+ -+VOID nicTxRelease(IN P_ADAPTER_T prAdapter); -+ -+VOID nicProcessTxInterrupt(IN P_ADAPTER_T prAdapter); -+ -+VOID nicTxFreeMsduInfoPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); -+ -+VOID nicTxReturnMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); -+ -+BOOLEAN nicTxFillMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prNdisPacket); -+ -+WLAN_STATUS nicTxAdjustTcq(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicTxFlush(IN P_ADAPTER_T prAdapter); -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+WLAN_STATUS nicTxInitCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC); -+ -+WLAN_STATUS nicTxInitResetResource(IN P_ADAPTER_T prAdapter); -+#endif -+ -+WLAN_STATUS nicTxEnqueueMsdu(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 nicTxGetFreeCmdCount(IN P_ADAPTER_T prAdapter); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _NIC_TX_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h -new file mode 100644 -index 0000000000000..d518aaf10eb56 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h -@@ -0,0 +1,192 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p.h#3 -+*/ -+ -+/* -+** Log: p2p.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct] add framework for driver hooks -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * p2p interface revised to be sync. with HAL -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 18 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add parameter to control: -+ * 1) auto group owner -+ * 2) P2P-PS parameter (CTWindow, NoA descriptors) -+ * -+ * 05 18 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * correct WPS Device Password ID definition. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement get scan result. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic handling framework for wireless extension ioctls. -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * p2p ioctls revised. -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement basic wi-fi direct framework -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic framework for implementating P2P driver hook. -+ * -+ * -+*/ -+ -+#ifndef _P2P_H -+#define _P2P_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* refer to 'Config Methods' in WPS */ -+#define WPS_CONFIG_USBA 0x0001 -+#define WPS_CONFIG_ETHERNET 0x0002 -+#define WPS_CONFIG_LABEL 0x0004 -+#define WPS_CONFIG_DISPLAY 0x0008 -+#define WPS_CONFIG_EXT_NFC 0x0010 -+#define WPS_CONFIG_INT_NFC 0x0020 -+#define WPS_CONFIG_NFC 0x0040 -+#define WPS_CONFIG_PBC 0x0080 -+#define WPS_CONFIG_KEYPAD 0x0100 -+ -+/* refer to 'Device Password ID' in WPS */ -+#define WPS_DEV_PASSWORD_ID_PIN 0x0000 -+#define WPS_DEV_PASSWORD_ID_USER 0x0001 -+#define WPS_DEV_PASSWORD_ID_MACHINE 0x0002 -+#define WPS_DEV_PASSWORD_ID_REKEY 0x0003 -+#define WPS_DEV_PASSWORD_ID_PUSHBUTTON 0x0004 -+#define WPS_DEV_PASSWORD_ID_REGISTRAR 0x0005 -+ -+#define P2P_DEVICE_TYPE_NUM 2 -+#define P2P_DEVICE_NAME_LENGTH 32 -+#define P2P_NETWORK_NUM 8 -+#define P2P_MEMBER_NUM 8 -+ -+#define P2P_WILDCARD_SSID "DIRECT-" -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+struct _P2P_INFO_T { -+ UINT_32 u4DeviceNum; -+ EVENT_P2P_DEV_DISCOVER_RESULT_T arP2pDiscoverResult[CFG_MAX_NUM_BSS_LIST]; -+ PUINT_8 pucCurrIePtr; -+ UINT_8 aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]; /* A common pool for IE of all scan results. */ -+}; -+ -+typedef enum { -+ ENUM_P2P_PEER_GROUP, -+ ENUM_P2P_PEER_DEVICE, -+ ENUM_P2P_PEER_NUM -+} ENUM_P2P_PEER_TYPE, *P_ENUM_P2P_PEER_TYPE; -+ -+typedef struct _P2P_DEVICE_INFO { -+ UINT_8 aucDevAddr[PARAM_MAC_ADDR_LEN]; -+ UINT_8 aucIfAddr[PARAM_MAC_ADDR_LEN]; -+ UINT_8 ucDevCapabilityBitmap; -+ INT_32 i4ConfigMethod; -+ UINT_8 aucPrimaryDeviceType[8]; -+ UINT_8 aucSecondaryDeviceType[8]; -+ UINT_8 aucDeviceName[P2P_DEVICE_NAME_LENGTH]; -+} P2P_DEVICE_INFO, *P_P2P_DEVICE_INFO; -+ -+typedef struct _P2P_GROUP_INFO { -+ PARAM_SSID_T rGroupID; -+ P2P_DEVICE_INFO rGroupOwnerInfo; -+ UINT_8 ucMemberNum; -+ P2P_DEVICE_INFO arMemberInfo[P2P_MEMBER_NUM]; -+} P2P_GROUP_INFO, *P_P2P_GROUP_INFO; -+ -+typedef struct _P2P_NETWORK_INFO { -+ ENUM_P2P_PEER_TYPE eNodeType; -+ -+ union { -+ P2P_GROUP_INFO rGroupInfo; -+ P2P_DEVICE_INFO rDeviceInfo; -+ } node; -+ -+} P2P_NETWORK_INFO, *P_P2P_NETWORK_INFO; -+ -+typedef struct _P2P_NETWORK_LIST { -+ UINT_8 ucNetworkNum; -+ P2P_NETWORK_INFO rP2PNetworkInfo[P2P_NETWORK_NUM]; -+} P2P_NETWORK_LIST, *P_P2P_NETWORK_LIST; -+ -+typedef struct _P2P_DISCONNECT_INFO { -+ UINT_8 ucRole; -+ UINT_8 ucRsv[3]; -+} P2P_DISCONNECT_INFO, *P_P2P_DISCONNECT_INFO; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#endif /*_P2P_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h -new file mode 100644 -index 0000000000000..7f7a92584c7ce ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h -@@ -0,0 +1,83 @@ -+/* -+** Id: -+*/ -+ -+/*! \file "p2p_cmd_buf.h" -+ \brief In this file we define the structure for Command Packet. -+ -+ In this file we define the structure for Command Packet and the control unit -+ of MGMT Memory Pool. -+*/ -+ -+/* -+** Log: p2p_cmd_buf.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface -+ * for supporting Wi-Fi Direct Service Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+*/ -+ -+#ifndef _P2P_CMD_BUF_H -+#define _P2P_CMD_BUF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/*--------------------------------------------------------------*/ -+/* Firmware Command Packer */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendSetQueryP2PCmd(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucCID, -+ BOOLEAN fgSetQuery, -+ BOOLEAN fgNeedResp, -+ BOOLEAN fgIsOid, -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ UINT_32 u4SetQueryInfoLen, -+ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen); -+ -+#endif /* _P2P_CMD_BUF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h -new file mode 100644 -index 0000000000000..76115dabe1a1d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h -@@ -0,0 +1,207 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_mac.h#2 -+*/ -+ -+/*! \file "p2p_mac.h" -+ \brief Brief description. -+ -+ Detail description. -+*/ -+ -+#ifndef _P2P_MAC_H -+#define _P2P_MAC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define ACTION_PUBLIC_WIFI_DIRECT 9 -+#define ACTION_GAS_INITIAL_REQUEST 10 -+#define ACTION_GAS_INITIAL_RESPONSE 11 -+#define ACTION_GAS_COMEBACK_REQUEST 12 -+#define ACTION_GAS_COMEBACK_RESPONSE 13 -+ -+/* P2P 4.2.8.1 - P2P Public Action Frame Type. */ -+#define P2P_PUBLIC_ACTION_GO_NEGO_REQ 0 -+#define P2P_PUBLIC_ACTION_GO_NEGO_RSP 1 -+#define P2P_PUBLIC_ACTION_GO_NEGO_CFM 2 -+#define P2P_PUBLIC_ACTION_INVITATION_REQ 3 -+#define P2P_PUBLIC_ACTION_INVITATION_RSP 4 -+#define P2P_PUBLIC_ACTION_DEV_DISCOVER_REQ 5 -+#define P2P_PUBLIC_ACTION_DEV_DISCOVER_RSP 6 -+#define P2P_PUBLIC_ACTION_PROV_DISCOVERY_REQ 7 -+#define P2P_PUBLIC_ACTION_PROV_DISCOVERY_RSP 8 -+ -+/* P2P 4.2.9.1 - P2P Action Frame Type */ -+#define P2P_ACTION_NOTICE_OF_ABSENCE 0 -+#define P2P_ACTION_P2P_PRESENCE_REQ 1 -+#define P2P_ACTION_P2P_PRESENCE_RSP 2 -+#define P2P_ACTION_GO_DISCOVER_REQ 3 -+ -+#define P2P_PUBLIC_ACTION_FRAME_LEN (WLAN_MAC_MGMT_HEADER_LEN+8) -+#define P2P_ACTION_FRAME_LEN (WLAN_MAC_MGMT_HEADER_LEN+7) -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/* P2P 4.2.8.2 P2P Public Action Frame Format */ -+typedef struct _P2P_PUBLIC_ACTION_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Public Action Frame Body */ -+ UINT_8 ucCategory; /* Category, 0x04 */ -+ UINT_8 ucAction; /* Action Value, 0x09 */ -+ UINT_8 aucOui[3]; /* 0x50, 0x6F, 0x9A */ -+ UINT_8 ucOuiType; /* 0x09 */ -+ UINT_8 ucOuiSubtype; /* GO Nego Req/Rsp/Cfm, P2P Invittion Req/Rsp, Device Discoverability Req/Rsp */ -+ UINT_8 ucDialogToken; /* Dialog Token. */ -+ UINT_8 aucInfoElem[1]; /* P2P IE, WSC IE. */ -+} __KAL_ATTRIB_PACKED__ P2P_PUBLIC_ACTION_FRAME_T, *P_P2P_PUBLIC_ACTION_FRAME_T; -+ -+/* P2P 4.2.9.1 - General Action Frame Format. */ -+typedef struct _P2P_ACTION_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Action Frame Body */ -+ UINT_8 ucCategory; /* 0x7F */ -+ UINT_8 aucOui[3]; /* 0x50, 0x6F, 0x9A */ -+ UINT_8 ucOuiType; /* 0x09 */ -+ UINT_8 ucOuiSubtype; /* */ -+ UINT_8 ucDialogToken; -+ UINT_8 aucInfoElem[1]; -+} __KAL_ATTRIB_PACKED__ P2P_ACTION_FRAME_T, *P_P2P_ACTION_FRAME_T; -+ -+/* P2P C.1 GAS Public Action Initial Request Frame Format */ -+typedef struct _GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Public Action Frame Body */ -+ UINT_8 ucCategory; /* Category, 0x04 */ -+ UINT_8 ucAction; /* Action Value, 0x09 */ -+ UINT_8 ucDialogToken; /* Dialog Token. */ -+ UINT_8 aucInfoElem[1]; /* Advertisement IE. */ -+} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T, *P_GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T; -+ -+/* P2P C.2 GAS Public Action Initial Response Frame Format */ -+typedef struct _GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Public Action Frame Body */ -+ UINT_8 ucCategory; /* Category, 0x04 */ -+ UINT_8 ucAction; /* Action Value, 0x09 */ -+ UINT_8 ucDialogToken; /* Dialog Token. */ -+ UINT_16 u2StatusCode; /* Initial Response. */ -+ UINT_16 u2ComebackDelay; /* Initial Response. *//* In unit of TU. */ -+ UINT_8 aucInfoElem[1]; /* Advertisement IE. */ -+} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T, *P_GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T; -+ -+/* P2P C.3-1 GAS Public Action Comeback Request Frame Format */ -+typedef struct _GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Public Action Frame Body */ -+ UINT_8 ucCategory; /* Category, 0x04 */ -+ UINT_8 ucAction; /* Action Value, 0x09 */ -+ UINT_8 ucDialogToken; /* Dialog Token. */ -+} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T, *P_GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T; -+ -+/* P2P C.3-2 GAS Public Action Comeback Response Frame Format */ -+typedef struct _GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Public Action Frame Body */ -+ UINT_8 ucCategory; /* Category, 0x04 */ -+ UINT_8 ucAction; /* Action Value, 0x09 */ -+ UINT_8 ucDialogToken; /* Dialog Token. */ -+ UINT_16 u2StatusCode; /* Comeback Response. */ -+ UINT_8 ucFragmentID; /*Comeback Response. */ -+ UINT_16 u2ComebackDelay; /* Comeback Response. */ -+ UINT_8 aucInfoElem[1]; /* Advertisement IE. */ -+} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T, *P_GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T; -+ -+typedef struct _P2P_SD_VENDER_SPECIFIC_CONTENT_T { -+ /* Service Discovery Vendor-specific Content. */ -+ UINT_8 ucOuiSubtype; /* 0x09 */ -+ UINT_16 u2ServiceUpdateIndicator; -+ UINT_8 aucServiceTLV[1]; -+} __KAL_ATTRIB_PACKED__ P2P_SD_VENDER_SPECIFIC_CONTENT_T, *P_P2P_SD_VENDER_SPECIFIC_CONTENT_T; -+ -+typedef struct _P2P_SERVICE_REQUEST_TLV_T { -+ UINT_16 u2Length; -+ UINT_8 ucServiceProtocolType; -+ UINT_8 ucServiceTransID; -+ UINT_8 aucQueryData[1]; -+} __KAL_ATTRIB_PACKED__ P2P_SERVICE_REQUEST_TLV_T, *P_P2P_SERVICE_REQUEST_TLV_T; -+ -+typedef struct _P2P_SERVICE_RESPONSE_TLV_T { -+ UINT_16 u2Length; -+ UINT_8 ucServiceProtocolType; -+ UINT_8 ucServiceTransID; -+ UINT_8 ucStatusCode; -+ UINT_8 aucResponseData[1]; -+} __KAL_ATTRIB_PACKED__ P2P_SERVICE_RESPONSE_TLV_T, *P_P2P_SERVICE_RESPONSE_TLV_T; -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h -new file mode 100644 -index 0000000000000..0a87bd457a926 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h -@@ -0,0 +1,62 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_nic.h#1 -+*/ -+ -+/*! \file "p2p_nic.h" -+ \brief The declaration of nic functions -+ -+ Detail description. -+*/ -+ -+#ifndef _P2P_NIC_H -+#define _P2P_NIC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID -+nicP2pMediaStateChange(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus); -+ -+VOID -+nicRxAddP2pDevice(IN P_ADAPTER_T prAdapter, -+ IN P_EVENT_P2P_DEV_DISCOVER_RESULT_T prP2pResult, IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELength); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h -new file mode 100644 -index 0000000000000..cea77414ce357 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h -@@ -0,0 +1,70 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_nic_cmd_event.h#1 -+*/ -+ -+/*! \file p2p_nic_cmd_event.h -+ \brief -+*/ -+ -+#ifndef _P2P_NIC_CMD_EVENT_H -+#define _P2P_NIC_CMD_EVENT_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+typedef struct _EVENT_P2P_DEV_DISCOVER_RESULT_T { -+/* UINT_8 aucCommunicateAddr[MAC_ADDR_LEN]; // Deprecated. */ -+ UINT_8 aucDeviceAddr[MAC_ADDR_LEN]; /* Device Address. */ -+ UINT_8 aucInterfaceAddr[MAC_ADDR_LEN]; /* Device Address. */ -+ UINT_8 ucDeviceCapabilityBitmap; -+ UINT_8 ucGroupCapabilityBitmap; -+ UINT_16 u2ConfigMethod; /* Configure Method. */ -+ P2P_DEVICE_TYPE_T rPriDevType; -+ UINT_8 ucSecDevTypeNum; -+ P2P_DEVICE_TYPE_T arSecDevType[2]; -+ UINT_16 u2NameLength; -+ UINT_8 aucName[32]; -+ PUINT_8 pucIeBuf; -+ UINT_16 u2IELength; -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+ /* TODO: Service Information or PasswordID valid? */ -+} EVENT_P2P_DEV_DISCOVER_RESULT_T, *P_EVENT_P2P_DEV_DISCOVER_RESULT_T; -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h -new file mode 100644 -index 0000000000000..dbfb90d94ee4c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h -@@ -0,0 +1,971 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/que_mgt.h#1 -+*/ -+ -+/*! \file "que_mgt.h" -+ \brief TX/RX queues management header file -+ -+ The main tasks of queue management include TC-based HIF TX flow control, -+ adaptive TC quota adjustment, HIF TX grant scheduling, Power-Save -+ forwarding control, RX packet reordering, and RX BA agreement management. -+*/ -+ -+/* -+** Log: que_mgt.h -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 07 26 2011 eddie.chen -+ * [WCXRP00000874] [MT5931][DRV] API for query the RX reorder queued packets counter -+ * API for query the RX reorder queued packets counter. -+ * -+ * 06 14 2011 eddie.chen -+ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931 -+ * Change the parameter for WMM pass. -+ * -+ * 05 31 2011 eddie.chen -+ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931 -+ * Fix the QM quota in MT5931. -+ * -+ * 05 09 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Check free number before copying broadcast packet. -+ * -+ * 04 14 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Check the SW RFB free. Fix the compile warning.. -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 03 28 2011 eddie.chen -+ * [WCXRP00000602] [MT6620 Wi-Fi][DRV] Fix wmm parameters in beacon for BOW -+ * Fix wmm parameters in beacon for BOW. -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 02 17 2011 eddie.chen -+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel -+ * 1) Change GetFrameAction decision when BSS is absent. -+ * 2) Check channel and resource in processing ProbeRequest -+ * -+ * 01 12 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * 1) Check Bss if support QoS before adding WMMIE -+ * 2) Check if support prAdapter->rWifiVar QoS and uapsd in flow control -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 23 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * 1. update WMM IE parsing, with ASSOC REQ handling -+ * 2. extend U-APSD parameter passing from driver to FW -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T -+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 08 04 2010 yarco.yang -+ * NULL -+ * Add TX_AMPDU and ADDBA_REJECT command -+ * -+ * 07 22 2010 george.huang -+ * -+ * Update fgIsQoS information in BSS INFO by CMD -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 13 2010 yarco.yang -+ * -+ * [WPD00003849] -+ * [MT6620 and MT5931] SW Migration, add qmGetFrameAction() API for CMD Queue Processing -+ * -+ * 07 09 2010 yarco.yang -+ * -+ * [MT6620 and MT5931] SW Migration: Add ADDBA support -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 29 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * replace g_rQM with Adpater->rQM -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 30 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled adaptive TC resource control -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 19 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * By default enabling dynamic STA_REC activation and decactivation -+ * -+ * 03 17 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Changed STA_REC index determination rules (DA=BMCAST always --> STA_REC_INDEX_BMCAST) -+ * -+ * 03 11 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Fixed buffer leak when processing BAR frames -+ * -+ * 02 25 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled multi-STA TX path with fairness -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled dynamically activating and deactivating STA_RECs -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Added code for dynamic activating and deactivating STA_RECs. -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the Burst_End Indication mechanism -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-12-09 14:04:53 GMT MTK02468 -+** Added RX buffer reordering function prototypes -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-12-02 22:08:44 GMT MTK02468 -+** Added macro QM_INIT_STA_REC for initialize a STA_REC -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-11-23 21:58:43 GMT mtk02468 -+** Initial version -+** -+*/ -+ -+#ifndef _QUE_MGT_H -+#define _QUE_MGT_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* Queue Manager Features */ -+/* 1: Indicate the last TX packet to the FW for each burst */ -+#define QM_BURST_END_INFO_ENABLED 1 -+/* 1: To fairly share TX resource among active STAs */ -+#define QM_FORWARDING_FAIRNESS 1 -+/* 1: To adaptively adjust resource for each TC */ -+#define QM_ADAPTIVE_TC_RESOURCE_CTRL 1 -+/* 1: To print TC resource adjustment results */ -+#define QM_PRINT_TC_RESOURCE_CTRL 0 -+/* 1: If pkt with SSN is missing, auto advance the RX reordering window */ -+#define QM_RX_WIN_SSN_AUTO_ADVANCING 1 -+/* 1: Indicate the packets falling behind to OS before the frame with SSN is received */ -+#define QM_RX_INIT_FALL_BEHIND_PASS 1 -+/* 1: Count times of TC resource empty happened */ -+#define QM_TC_RESOURCE_EMPTY_COUNTER 1 -+/* Parameters */ -+ -+/* -+ In TDLS or AP mode, peer maybe enter "sleep mode". -+ -+ If QM_INIT_TIME_TO_UPDATE_QUE_LEN = 60 when peer is in sleep mode, -+ we need to wait 60 * u4TimeToAdjustTcResource = 180 packets -+ u4TimeToAdjustTcResource = 3, -+ then we will adjust TC resouce for VI or VO. -+ -+ But in TDLS test case, the throughput is very low, only 0.8Mbps in 5.7, -+ we will to wait about 12 seconds to collect 180 packets. -+ but the test time is only 20 seconds. -+*/ -+#define QM_INIT_TIME_TO_UPDATE_QUE_LEN 60 /* p: Update queue lengths when p TX packets are enqueued */ -+#define QM_INIT_TIME_TO_UPDATE_QUE_LEN_MIN 5 -+ -+#define QM_INIT_TIME_TO_ADJUST_TC_RSC 3 /* s: Adjust the TC resource every s updates of queue lengths */ -+#define QM_QUE_LEN_MOVING_AVE_FACTOR 3 /* Factor for Que Len averaging */ -+ -+#define QM_MIN_RESERVED_TC0_RESOURCE 1 -+#define QM_MIN_RESERVED_TC1_RESOURCE 1 -+#define QM_MIN_RESERVED_TC2_RESOURCE 1 -+#define QM_MIN_RESERVED_TC3_RESOURCE 1 -+#define QM_MIN_RESERVED_TC4_RESOURCE 2 /* Resource for TC4 is not adjustable */ -+#define QM_MIN_RESERVED_TC5_RESOURCE 1 -+ -+#if defined(MT6620) -+ -+#define QM_GUARANTEED_TC0_RESOURCE 4 -+#define QM_GUARANTEED_TC1_RESOURCE 4 -+#define QM_GUARANTEED_TC2_RESOURCE 9 -+#define QM_GUARANTEED_TC3_RESOURCE 11 -+#define QM_GUARANTEED_TC4_RESOURCE 2 /* Resource for TC4 is not adjustable */ -+#define QM_GUARANTEED_TC5_RESOURCE 4 -+ -+#elif defined(MT6628) -+ -+#define QM_GUARANTEED_TC0_RESOURCE 4 -+#define QM_GUARANTEED_TC1_RESOURCE 4 -+#define QM_GUARANTEED_TC2_RESOURCE 6 -+#define QM_GUARANTEED_TC3_RESOURCE 6 -+#define QM_GUARANTEED_TC4_RESOURCE 2 /* Resource for TC4 is not adjustable */ -+#define QM_GUARANTEED_TC5_RESOURCE 4 -+ -+#else -+#error -+#endif -+ -+#define QM_EXTRA_RESERVED_RESOURCE_WHEN_BUSY 0 -+ -+#define QM_TOTAL_TC_RESOURCE (\ -+ NIC_TX_BUFF_COUNT_TC0 + NIC_TX_BUFF_COUNT_TC1 +\ -+ NIC_TX_BUFF_COUNT_TC2 + NIC_TX_BUFF_COUNT_TC3 +\ -+ NIC_TX_BUFF_COUNT_TC5) -+#define QM_AVERAGE_TC_RESOURCE 6 -+ -+/* Note: QM_INITIAL_RESIDUAL_TC_RESOURCE shall not be less than 0 */ -+/* for 6628: QM_TOTAL_TC_RESOURCE = 28, RESIDUAL = 4 4 6 6 2 4 = 26 */ -+#define QM_INITIAL_RESIDUAL_TC_RESOURCE (QM_TOTAL_TC_RESOURCE - \ -+ (QM_GUARANTEED_TC0_RESOURCE +\ -+ QM_GUARANTEED_TC1_RESOURCE +\ -+ QM_GUARANTEED_TC2_RESOURCE +\ -+ QM_GUARANTEED_TC3_RESOURCE +\ -+ QM_GUARANTEED_TC5_RESOURCE \ -+ )) -+ -+/* Hard-coded network type for Phase 3: NETWORK_TYPE_AIS/P2P/BOW */ -+#define QM_OPERATING_NETWORK_TYPE NETWORK_TYPE_AIS -+ -+#define QM_TEST_MODE 0 -+#define QM_TEST_TRIGGER_TX_COUNT 50 -+#define QM_TEST_STA_REC_DETERMINATION 0 -+#define QM_TEST_STA_REC_DEACTIVATION 0 -+#define QM_TEST_FAIR_FORWARDING 0 -+ -+#define QM_DEBUG_COUNTER 0 -+ -+/* Per-STA Queues: [0] AC0, [1] AC1, [2] AC2, [3] AC3, [4] 802.1x */ -+/* Per-Type Queues: [0] BMCAST */ -+#define NUM_OF_PER_STA_TX_QUEUES 5 -+#define NUM_OF_PER_TYPE_TX_QUEUES 1 -+ -+/* These two constants are also used for FW to verify the STA_REC index */ -+#define STA_REC_INDEX_BMCAST 0xFF -+#define STA_REC_INDEX_NOT_FOUND 0xFE -+ -+/* TX Queue Index */ -+#define TX_QUEUE_INDEX_BMCAST 0 -+#define TX_QUEUE_INDEX_NO_STA_REC 0 -+#define TX_QUEUE_INDEX_AC0 0 -+#define TX_QUEUE_INDEX_AC1 1 -+#define TX_QUEUE_INDEX_AC2 2 -+#define TX_QUEUE_INDEX_AC3 3 -+#define TX_QUEUE_INDEX_802_1X 4 -+#define TX_QUEUE_INDEX_NON_QOS 1 -+ -+/* 1 WMM-related */ -+/* WMM FLAGS */ -+#define WMM_FLAG_SUPPORT_WMM BIT(0) -+#define WMM_FLAG_SUPPORT_WMMSA BIT(1) -+#define WMM_FLAG_AC_PARAM_PRESENT BIT(2) -+#define WMM_FLAG_SUPPORT_UAPSD BIT(3) -+ -+/* WMM Admission Control Mandatory FLAGS */ -+#define ACM_FLAG_ADM_NOT_REQUIRED 0 -+#define ACM_FLAG_ADM_GRANTED BIT(0) -+#define ACM_FLAG_ADM_REQUIRED BIT(1) -+ -+/* WMM Power Saving FLAGS */ -+#define AC_FLAG_TRIGGER_ENABLED BIT(1) -+#define AC_FLAG_DELIVERY_ENABLED BIT(2) -+ -+/* WMM-2.2.1 WMM Information Element */ -+#define ELEM_MAX_LEN_WMM_INFO 7 -+ -+/* WMM-2.2.2 WMM Parameter Element */ -+#define ELEM_MAX_LEN_WMM_PARAM 24 -+ -+/* WMM-2.2.1 WMM QoS Info field */ -+#define WMM_QOS_INFO_PARAM_SET_CNT BITS(0, 3) /* Sent by AP */ -+#define WMM_QOS_INFO_UAPSD BIT(7) -+ -+#define WMM_QOS_INFO_VO_UAPSD BIT(0) /* Sent by non-AP STA */ -+#define WMM_QOS_INFO_VI_UAPSD BIT(1) -+#define WMM_QOS_INFO_BK_UAPSD BIT(2) -+#define WMM_QOS_INFO_BE_UAPSD BIT(3) -+#define WMM_QOS_INFO_MAX_SP_LEN_MASK BITS(5, 6) -+#define WMM_QOS_INFO_MAX_SP_ALL 0 -+#define WMM_QOS_INFO_MAX_SP_2 BIT(5) -+#define WMM_QOS_INFO_MAX_SP_4 BIT(6) -+#define WMM_QOS_INFO_MAX_SP_6 BITS(5, 6) -+ -+/* -- definitions for Max SP length field */ -+#define WMM_MAX_SP_LENGTH_ALL 0 -+#define WMM_MAX_SP_LENGTH_2 2 -+#define WMM_MAX_SP_LENGTH_4 4 -+#define WMM_MAX_SP_LENGTH_6 6 -+ -+/* WMM-2.2.2 WMM ACI/AIFSN field */ -+/* -- subfields in the ACI/AIFSN field */ -+#define WMM_ACIAIFSN_AIFSN BITS(0, 3) -+#define WMM_ACIAIFSN_ACM BIT(4) -+#define WMM_ACIAIFSN_ACI BITS(5, 6) -+#define WMM_ACIAIFSN_ACI_OFFSET 5 -+ -+/* -- definitions for ACI field */ -+#define WMM_ACI_AC_BE 0 -+#define WMM_ACI_AC_BK BIT(5) -+#define WMM_ACI_AC_VI BIT(6) -+#define WMM_ACI_AC_VO BITS(5, 6) -+ -+#define WMM_ACI(_AC) (_AC << WMM_ACIAIFSN_ACI_OFFSET) -+ -+/* -- definitions for ECWmin/ECWmax field */ -+#define WMM_ECW_WMIN_MASK BITS(0, 3) -+#define WMM_ECW_WMAX_MASK BITS(4, 7) -+#define WMM_ECW_WMAX_OFFSET 4 -+ -+#define TXM_DEFAULT_FLUSH_QUEUE_GUARD_TIME 0 /* Unit: 64 us */ -+ -+#define QM_RX_BA_ENTRY_MISS_TIMEOUT_MS (1000) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+enum { -+ QM_DBG_CNT_00 = 0, -+ QM_DBG_CNT_01, -+ QM_DBG_CNT_02, -+ QM_DBG_CNT_03, -+ QM_DBG_CNT_04, -+ QM_DBG_CNT_05, -+ QM_DBG_CNT_06, -+ QM_DBG_CNT_07, -+ QM_DBG_CNT_08, -+ QM_DBG_CNT_09, -+ QM_DBG_CNT_10, -+ QM_DBG_CNT_11, -+ QM_DBG_CNT_12, -+ QM_DBG_CNT_13, -+ QM_DBG_CNT_14, -+ QM_DBG_CNT_15, -+ QM_DBG_CNT_16, -+ QM_DBG_CNT_17, -+ QM_DBG_CNT_18, -+ QM_DBG_CNT_19, -+ QM_DBG_CNT_20, -+ QM_DBG_CNT_21, -+ QM_DBG_CNT_22, -+ QM_DBG_CNT_23, -+ QM_DBG_CNT_24, -+ QM_DBG_CNT_25, -+ QM_DBG_CNT_26, -+ QM_DBG_CNT_27, -+ QM_DBG_CNT_28, -+ QM_DBG_CNT_29, -+ QM_DBG_CNT_30, -+ QM_DBG_CNT_31, -+ QM_DBG_CNT_NUM -+}; -+ -+/* Used for MAC TX */ -+typedef enum _ENUM_MAC_TX_QUEUE_INDEX_T { -+ MAC_TX_QUEUE_AC0_INDEX = 0, -+ MAC_TX_QUEUE_AC1_INDEX, -+ MAC_TX_QUEUE_AC2_INDEX, -+ MAC_TX_QUEUE_AC3_INDEX, -+ MAC_TX_QUEUE_AC4_INDEX, -+ MAC_TX_QUEUE_AC5_INDEX, -+ MAC_TX_QUEUE_AC6_INDEX, -+ MAC_TX_QUEUE_BCN_INDEX, -+ MAC_TX_QUEUE_BMC_INDEX, -+ MAC_TX_QUEUE_NUM -+} ENUM_MAC_TX_QUEUE_INDEX_T; -+ -+typedef struct _RX_BA_ENTRY_T { -+ BOOLEAN fgIsValid; -+ QUE_T rReOrderQue; -+ UINT_16 u2WinStart; -+ UINT_16 u2WinEnd; -+ UINT_16 u2WinSize; -+ -+ /* For identifying the RX BA agreement */ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucTid; -+ -+ BOOLEAN fgIsWaitingForPktWithSsn; -+ -+ /* UINT_8 ucTxBufferSize; */ -+ /* BOOL fgIsAcConstrain; */ -+ /* BOOL fgIsBaEnabled; */ -+} RX_BA_ENTRY_T, *P_RX_BA_ENTRY_T; -+ -+/* The mailbox message (could be used for Host-To-Device or Device-To-Host Mailbox) */ -+typedef struct _MAILBOX_MSG_T { -+ UINT_32 u4Msg[2]; /* [0]: D2HRM0R or H2DRM0R, [1]: D2HRM1R or H2DRM1R */ -+} MAILBOX_MSG_T, *P_MAILBOX_MSG_T; -+ -+/* Used for adaptively adjusting TC resources */ -+typedef struct _TC_RESOURCE_CTRL_T { -+ /* TC0, TC1, TC2, TC3, TC5 */ -+ UINT_32 au4AverageQueLen[TC_NUM - 1]; -+} TC_RESOURCE_CTRL_T, *P_TC_RESOURCE_CTRL_T; -+ -+typedef struct _QUE_MGT_T { /* Queue Management Control Info */ -+ -+ /* Per-Type Queues: [0] BMCAST or UNKNOWN-STA packets */ -+ QUE_T arTxQueue[NUM_OF_PER_TYPE_TX_QUEUES]; -+ -+#if 0 -+ /* For TX Scheduling */ -+ UINT_8 arRemainingTxOppt[NUM_OF_PER_STA_TX_QUEUES]; -+ UINT_8 arCurrentTxStaIndex[NUM_OF_PER_STA_TX_QUEUES]; -+ -+#endif -+ -+ /* Reordering Queue Parameters */ -+ RX_BA_ENTRY_T arRxBaTable[CFG_NUM_OF_RX_BA_AGREEMENTS]; -+ -+ /* Current number of activated RX BA agreements <= CFG_NUM_OF_RX_BA_AGREEMENTS */ -+ UINT_8 ucRxBaCount; -+ -+#if QM_TEST_MODE -+ UINT_32 u4PktCount; -+ P_ADAPTER_T prAdapter; -+ -+#if QM_TEST_FAIR_FORWARDING -+ UINT_32 u4CurrentStaRecIndexToEnqueue; -+#endif -+ -+#endif -+ -+#if QM_FORWARDING_FAIRNESS -+ /* The current TX count for a STA with respect to a TC index */ -+ UINT_32 au4ForwardCount[NUM_OF_PER_STA_TX_QUEUES]; -+ -+ /* The current serving STA with respect to a TC index */ -+ UINT_32 au4HeadStaRecIndex[NUM_OF_PER_STA_TX_QUEUES]; -+#endif -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ UINT_32 au4AverageQueLen[TC_NUM]; -+ UINT_32 au4CurrentTcResource[TC_NUM]; -+ UINT_32 au4MinReservedTcResource[TC_NUM]; /* The minimum amount of resource no matter busy or idle */ -+ UINT_32 au4GuaranteedTcResource[TC_NUM]; /* The minimum amount of resource when extremely busy */ -+ -+ UINT_32 u4TimeToAdjustTcResource; -+ UINT_32 u4TimeToUpdateQueLen; -+ UINT_32 u4TxNumOfVi, u4TxNumOfVo; /* number of VI/VO packets */ -+ -+ /* Set to TRUE if the last TC adjustment has not been completely applied (i.e., waiting more TX-Done events -+ to align the TC quotas to the TC resource assignment) */ -+ BOOLEAN fgTcResourcePostAnnealing; -+ -+#endif -+ -+#if QM_DEBUG_COUNTER -+ UINT_32 au4QmDebugCounters[QM_DBG_CNT_NUM]; -+#endif -+#if QM_TC_RESOURCE_EMPTY_COUNTER -+ UINT_32 au4QmTcResourceEmptyCounter[NET_TYPE_NUM][TC_NUM]; -+ UINT_32 au4QmTcResourceBackCounter[TC_NUM]; -+ UINT_32 au4DequeueNoTcResourceCounter[TC_NUM]; -+ -+ UINT_32 au4ResourceUsedCounter[TC_NUM]; -+ -+ UINT_32 au4ResourceWantedCounter[TC_NUM]; -+ -+ UINT_32 u4EnqeueuCounter; -+ UINT_32 u4DequeueCounter; -+#endif -+} QUE_MGT_T, *P_QUE_MGT_T; -+ -+typedef struct _EVENT_RX_ADDBA_T { -+ /* Event header */ -+ UINT_16 u2Length; -+ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ /* Fields not present in the received ADDBA_REQ */ -+ UINT_8 ucStaRecIdx; -+ -+ /* Fields that are present in the received ADDBA_REQ */ -+ UINT_8 ucDialogToken; /* Dialog Token chosen by the sender */ -+ UINT_16 u2BAParameterSet; /* BA policy, TID, buffer size */ -+ UINT_16 u2BATimeoutValue; -+ UINT_16 u2BAStartSeqCtrl; /* SSN */ -+ -+} EVENT_RX_ADDBA_T, *P_EVENT_RX_ADDBA_T; -+ -+typedef struct _EVENT_RX_DELBA_T { -+ /* Event header */ -+ UINT_16 u2Length; -+ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ /* Fields not present in the received ADDBA_REQ */ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucTid; -+} EVENT_RX_DELBA_T, *P_EVENT_RX_DELBA_T; -+ -+typedef struct _EVENT_BSS_ABSENCE_PRESENCE_T { -+ /* Event header */ -+ UINT_16 u2Length; -+ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ /* Event Body */ -+ UINT_8 ucNetTypeIdx; -+ BOOLEAN fgIsAbsent; -+ UINT_8 ucBssFreeQuota; -+ UINT_8 aucReserved[1]; -+} EVENT_BSS_ABSENCE_PRESENCE_T, *P_EVENT_BSS_ABSENCE_PRESENCE_T; -+ -+typedef struct _EVENT_STA_CHANGE_PS_MODE_T { -+ /* Event header */ -+ UINT_16 u2Length; -+ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ /* Event Body */ -+ UINT_8 ucStaRecIdx; -+ BOOLEAN fgIsInPs; -+ UINT_8 ucUpdateMode; -+ UINT_8 ucFreeQuota; -+} EVENT_STA_CHANGE_PS_MODE_T, *P_EVENT_STA_CHANGE_PS_MODE_T; -+ -+/* The free quota is used by PS only now */ -+/* The event may be used by per STA flow conttrol in general */ -+typedef struct _EVENT_STA_UPDATE_FREE_QUOTA_T { -+ /* Event header */ -+ UINT_16 u2Length; -+ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ /* Event Body */ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucUpdateMode; -+ UINT_8 ucFreeQuota; -+ UINT_8 aucReserved[1]; -+} EVENT_STA_UPDATE_FREE_QUOTA_T, *P_EVENT_STA_UPDATE_FREE_QUOTA_T; -+ -+/* WMM-2.2.1 WMM Information Element */ -+typedef struct _IE_WMM_INFO_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 ucOuiSubtype; /* OUI Subtype */ -+ UINT_8 ucVersion; /* Version */ -+ UINT_8 ucQosInfo; /* QoS Info field */ -+ UINT_8 ucDummy[3]; /* Dummy for pack */ -+} IE_WMM_INFO_T, *P_IE_WMM_INFO_T; -+ -+/* WMM-2.2.2 WMM Parameter Element */ -+typedef struct _IE_WMM_PARAM_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ -+ /* IE Body */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 ucOuiSubtype; /* OUI Subtype */ -+ UINT_8 ucVersion; /* Version */ -+ -+ /* WMM IE Body */ -+ UINT_8 ucQosInfo; /* QoS Info field */ -+ UINT_8 ucReserved; -+ -+ /* AC Parameters */ -+ UINT_8 ucAciAifsn_BE; -+ UINT_8 ucEcw_BE; -+ UINT_8 aucTxopLimit_BE[2]; -+ -+ UINT_8 ucAciAifsn_BG; -+ UINT_8 ucEcw_BG; -+ UINT_8 aucTxopLimit_BG[2]; -+ -+ UINT_8 ucAciAifsn_VI; -+ UINT_8 ucEcw_VI; -+ UINT_8 aucTxopLimit_VI[2]; -+ -+ UINT_8 ucAciAifsn_VO; -+ UINT_8 ucEcw_VO; -+ UINT_8 aucTxopLimit_VO[2]; -+ -+} IE_WMM_PARAM_T, *P_IE_WMM_PARAM_T; -+ -+typedef struct _IE_WMM_TSPEC_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 ucOuiSubtype; /* OUI Subtype */ -+ UINT_8 ucVersion; /* Version */ -+ /* WMM TSPEC body */ -+ UINT_8 aucTsInfo[3]; /* TS Info */ -+ UINT_8 aucTspecBodyPart[1]; /* Note: Utilize PARAM_QOS_TSPEC to fill (memory copy) */ -+} IE_WMM_TSPEC_T, *P_IE_WMM_TSPEC_T; -+ -+typedef struct _IE_WMM_HDR_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 ucOuiSubtype; /* OUI Subtype */ -+ UINT_8 ucVersion; /* Version */ -+ UINT_8 aucBody[1]; /* IE body */ -+} IE_WMM_HDR_T, *P_IE_WMM_HDR_T; -+ -+typedef struct _AC_QUE_PARMS_T { -+ UINT_16 u2CWmin; /*!< CWmin */ -+ UINT_16 u2CWmax; /*!< CWmax */ -+ UINT_16 u2TxopLimit; /*!< TXOP limit */ -+ UINT_16 u2Aifsn; /*!< AIFSN */ -+ UINT_8 ucGuradTime; /*!< GuardTime for STOP/FLUSH. */ -+ BOOLEAN fgIsACMSet; -+} AC_QUE_PARMS_T, *P_AC_QUE_PARMS_T; -+ -+/* WMM ACI (AC index) */ -+typedef enum _ENUM_WMM_ACI_T { -+ WMM_AC_BE_INDEX = 0, -+ WMM_AC_BK_INDEX, -+ WMM_AC_VI_INDEX, -+ WMM_AC_VO_INDEX, -+ WMM_AC_INDEX_NUM -+} ENUM_WMM_ACI_T, *P_ENUM_WMM_ACI_T; -+ -+/* Used for CMD Queue Operation */ -+typedef enum _ENUM_FRAME_ACTION_T { -+ FRAME_ACTION_DROP_PKT = 0, -+ FRAME_ACTION_QUEUE_PKT, -+ FRAME_ACTION_TX_PKT, -+ FRAME_ACTION_NUM -+} ENUM_FRAME_ACTION_T; -+ -+typedef enum _ENUM_FRAME_TYPE_IN_CMD_Q_T { -+ FRAME_TYPE_802_1X = 0, -+ FRAME_TYPE_MMPDU, -+ FRAME_TYPE_NUM -+} ENUM_FRAME_TYPE_IN_CMD_Q_T; -+ -+typedef enum _ENUM_FREE_QUOTA_MODET_T { -+ FREE_QUOTA_UPDATE_MODE_INIT = 0, -+ FREE_QUOTA_UPDATE_MODE_OVERWRITE, -+ FREE_QUOTA_UPDATE_MODE_INCREASE, -+ FREE_QUOTA_UPDATE_MODE_DECREASE -+} ENUM_FREE_QUOTA_MODET_T, *P_ENUM_FREE_QUOTA_MODET_T; -+ -+typedef struct _CMD_UPDATE_WMM_PARMS_T { -+ AC_QUE_PARMS_T arACQueParms[AC_NUM]; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 fgIsQBSS; -+ UINT_8 aucReserved[2]; -+} CMD_UPDATE_WMM_PARMS_T, *P_CMD_UPDATE_WMM_PARMS_T; -+ -+typedef struct _CMD_TX_AMPDU_T { -+ BOOLEAN fgEnable; -+ UINT_8 aucReserved[3]; -+} CMD_TX_AMPDU_T, *P_CMD_TX_AMPDU_T; -+ -+typedef struct _CMD_ADDBA_REJECT { -+ BOOLEAN fgEnable; -+ UINT_8 aucReserved[3]; -+} CMD_ADDBA_REJECT_T, *P_CMD_ADDBA_REJECT_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define QM_TX_SET_NEXT_MSDU_INFO(_prMsduInfoPreceding, _prMsduInfoNext) \ -+ ((((_prMsduInfoPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prMsduInfoNext)) -+ -+#define QM_TX_SET_NEXT_SW_RFB(_prSwRfbPreceding, _prSwRfbNext) \ -+ ((((_prSwRfbPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prSwRfbNext)) -+ -+#define QM_TX_GET_NEXT_MSDU_INFO(_prMsduInfo) \ -+ ((P_MSDU_INFO_T)(((_prMsduInfo)->rQueEntry).prNext)) -+ -+#define QM_RX_SET_NEXT_SW_RFB(_prSwRfbPreceding, _prSwRfbNext) \ -+ ((((_prSwRfbPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prSwRfbNext)) -+ -+#define QM_RX_GET_NEXT_SW_RFB(_prSwRfb) \ -+ ((P_SW_RFB_T)(((_prSwRfb)->rQueEntry).prNext)) -+ -+#if 0 -+#define QM_GET_STA_REC_PTR_FROM_INDEX(_prAdapter, _ucIndex) \ -+ ((((_ucIndex) != STA_REC_INDEX_BMCAST) && ((_ucIndex) != STA_REC_INDEX_NOT_FOUND)) ?\ -+ &(_prAdapter->arStaRec[_ucIndex]) : NULL) -+#endif -+ -+#define QM_GET_STA_REC_PTR_FROM_INDEX(_prAdapter, _ucIndex) \ -+ cnmGetStaRecByIndex(_prAdapter, _ucIndex) -+ -+#define QM_TX_SET_MSDU_INFO_FOR_DATA_PACKET(\ -+ _prMsduInfo,\ -+ _ucTC,\ -+ _ucPacketType,\ -+ _ucFormatID,\ -+ _fgIs802_1x,\ -+ _fgIs802_11,\ -+ _u2PalLLH,\ -+ _u2AclSN,\ -+ _ucPsForwardingType,\ -+ _ucPsSessionID\ -+ ) \ -+{\ -+ ASSERT(_prMsduInfo);\ -+ (_prMsduInfo)->ucTC = (_ucTC);\ -+ (_prMsduInfo)->ucPacketType = (_ucPacketType);\ -+ (_prMsduInfo)->ucFormatID = (_ucFormatID);\ -+ (_prMsduInfo)->fgIs802_1x = (_fgIs802_1x);\ -+ (_prMsduInfo)->fgIs802_11 = (_fgIs802_11);\ -+ (_prMsduInfo)->u2PalLLH = (_u2PalLLH);\ -+ (_prMsduInfo)->u2AclSN = (_u2AclSN);\ -+ (_prMsduInfo)->ucPsForwardingType = (_ucPsForwardingType);\ -+ (_prMsduInfo)->ucPsSessionID = (_ucPsSessionID);\ -+ (_prMsduInfo)->fgIsBurstEnd = (FALSE);\ -+} -+ -+#define QM_INIT_STA_REC(\ -+ _prStaRec,\ -+ _fgIsValid,\ -+ _fgIsQoS,\ -+ _pucMacAddr\ -+ )\ -+{\ -+ ASSERT(_prStaRec);\ -+ (_prStaRec)->fgIsValid = (_fgIsValid);\ -+ (_prStaRec)->fgIsQoS = (_fgIsQoS);\ -+ (_prStaRec)->fgIsInPS = FALSE; \ -+ (_prStaRec)->ucPsSessionID = 0xFF;\ -+ COPY_MAC_ADDR((_prStaRec)->aucMacAddr, (_pucMacAddr));\ -+} -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+#define QM_GET_TX_QUEUE_LEN(_prAdapter, _u4QueIdx) \ -+ ((_prAdapter->rQM.au4AverageQueLen[(_u4QueIdx)] >> QM_QUE_LEN_MOVING_AVE_FACTOR)) -+#endif -+ -+#define WMM_IE_OUI_TYPE(fp) (((P_IE_WMM_HDR_T)(fp))->ucOuiType) -+#define WMM_IE_OUI_SUBTYPE(fp) (((P_IE_WMM_HDR_T)(fp))->ucOuiSubtype) -+#define WMM_IE_OUI(fp) (((P_IE_WMM_HDR_T)(fp))->aucOui) -+ -+#if QM_DEBUG_COUNTER -+#define QM_DBG_CNT_INC(_prQM, _index) { (_prQM)->au4QmDebugCounters[(_index)]++; } -+#else -+#define QM_DBG_CNT_INC(_prQM, _index) {} -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Queue Management and STA_REC Initialization */ -+/*----------------------------------------------------------------------------*/ -+ -+VOID qmInit(IN P_ADAPTER_T prAdapter); -+ -+#if QM_TEST_MODE -+VOID qmTestCases(IN P_ADAPTER_T prAdapter); -+#endif -+ -+VOID qmActivateStaRec(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+VOID qmDeactivateStaRec(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx); -+ -+/*----------------------------------------------------------------------------*/ -+/* TX-Related Queue Management */ -+/*----------------------------------------------------------------------------*/ -+ -+P_MSDU_INFO_T qmFlushTxQueues(IN P_ADAPTER_T prAdapter); -+ -+P_MSDU_INFO_T qmFlushStaTxQueues(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx); -+ -+P_MSDU_INFO_T qmEnqueueTxPackets(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); -+ -+P_MSDU_INFO_T qmDequeueTxPackets(IN P_ADAPTER_T prAdapter, IN P_TX_TCQ_STATUS_T prTcqStatus); -+ -+VOID qmAdjustTcQuotas(IN P_ADAPTER_T prAdapter, OUT P_TX_TCQ_ADJUST_T prTcqAdjust, IN P_TX_TCQ_STATUS_T prTcqStatus); -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+VOID qmReassignTcResource(IN P_ADAPTER_T prAdapter); -+ -+VOID qmUpdateAverageTxQueLen(IN P_ADAPTER_T prAdapter); -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/* RX-Related Queue Management */ -+/*----------------------------------------------------------------------------*/ -+ -+VOID qmInitRxQueues(IN P_ADAPTER_T prAdapter); -+ -+P_SW_RFB_T qmFlushRxQueues(IN P_ADAPTER_T prAdapter); -+ -+P_SW_RFB_T qmHandleRxPackets(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead); -+ -+VOID qmProcessPktWithReordering(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue); -+ -+VOID qmProcessBarFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue); -+ -+VOID -+qmInsertFallWithinReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue); -+ -+VOID qmInsertFallAheadReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue); -+ -+BOOLEAN -+qmPopOutDueToFallWithin(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue, OUT BOOLEAN *fgIsTimeout); -+ -+VOID qmPopOutDueToFallAhead(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue); -+ -+VOID qmHandleMailboxRxMessage(IN MAILBOX_MSG_T prMailboxRxMsg); -+ -+BOOLEAN qmCompareSnIsLessThan(IN UINT_32 u4SnLess, IN UINT_32 u4SnGreater); -+ -+VOID qmHandleEventRxAddBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); -+ -+VOID qmHandleEventRxDelBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); -+ -+P_RX_BA_ENTRY_T qmLookupRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid); -+ -+BOOLEAN -+qmAddRxBaEntry(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN UINT_16 u2WinStart, IN UINT_16 u2WinSize); -+ -+VOID qmDelRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN BOOLEAN fgFlushToHost); -+ -+VOID mqmProcessAssocRsp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength); -+ -+VOID -+mqmParseEdcaParameters(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength, IN BOOLEAN fgForceOverride); -+ -+VOID mqmFillAcQueParam(IN P_IE_WMM_PARAM_T prIeWmmParam, IN UINT_32 u4AcOffset, OUT P_AC_QUE_PARMS_T prAcQueParams); -+ -+VOID mqmProcessScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prScanResult, OUT P_STA_RECORD_T prStaRec); -+ -+/* Utility function: for deciding STA-REC index */ -+UINT_8 qmGetStaRecIdx(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucEthDestAddr, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType); -+ -+UINT_32 -+mqmGenerateWmmInfoIEByParam(BOOLEAN fgSupportUAPSD, -+ UINT_8 ucBmpDeliveryAC, UINT_8 ucBmpTriggerAC, UINT_8 ucUapsdSp, UINT_8 *pOutBuf); -+ -+VOID mqmGenerateWmmInfoIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 mqmGenerateWmmParamIEByParam(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, UINT_8 *pOutBuf, ENUM_OP_MODE_T ucOpMode); -+ -+VOID mqmGenerateWmmParamIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+ENUM_FRAME_ACTION_T -+qmGetFrameAction(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, -+ IN UINT_8 ucStaRecIdx, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_FRAME_TYPE_IN_CMD_Q_T eFrameType); -+ -+VOID qmHandleEventBssAbsencePresence(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); -+ -+VOID qmHandleEventStaChangePsMode(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); -+ -+VOID mqmProcessAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength); -+ -+VOID qmHandleEventStaUpdateFreeQuota(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); -+ -+VOID -+qmUpdateFreeQuota(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUpdateMode, IN UINT_8 ucFreeQuota, IN UINT_8 ucNumOfTxDone); -+ -+VOID qmFreeAllByNetType(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+UINT_32 qmGetRxReorderQueuedBufferCount(IN P_ADAPTER_T prAdapter); -+ -+#if ARP_MONITER_ENABLE -+VOID qmDetectArpNoResponse(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+VOID qmResetArpDetect(VOID); -+VOID qmHandleRxArpPackets(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _QUE_MGT_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h -new file mode 100644 -index 0000000000000..2804b0387f5f0 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h -@@ -0,0 +1,1010 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/wlan_def.h#1 -+*/ -+ -+/*! \file "wlan_def.h" -+ \brief This file includes the basic definition of WLAN -+ -+*/ -+ -+/* -+** Log: wlan_def.h -+** -+** 09 02 2013 cp.wu -+** add path to handle reassociation request -+ * -+ * 12 05 2011 cp.wu -+ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path -+ * add CONNECT_BY_BSSID policy -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 06 22 2011 wh.su -+ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h and let the sw -+ * structure not align at byte -+ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte, -+ * Notice needed update P2P.ko. -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 03 17 2011 yuche.tsai -+ * NULL -+ * Resize the Secondary Device Type array when WiFi Direct is enabled. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Add new station type MACRO. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 10 11 2010 kevin.huang -+ * [WCXRP00000068] [MT6620 Wi-Fi][Driver][FW] Fix STA RECORD sync issue and remove unused code -+ * Update ENUM_STA_ROLE_INDEX_T by using a fixed base value -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by -+ * ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 14 2010 chinghwa.yu -+ * NULL -+ * Update OP_MODE_BOW and include bow_fsm.h. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Change P2P Descriptor List to a pointer and allocate it dynamically to avoid structure corrupt by BssDescriptor free. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Add a pointer in BSS Descriptor for P2P Descriptor. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add an Interface in BSS Descriptor. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Modify data structure for P2P Scan result. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add an operation mode for P2P device. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * P2P/RSN/WAPI IEs need to be declared with compact structure. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add for P2P Scan Result Parsing & Saving. -+ * -+ * 07 20 2010 wh.su -+ * -+ * adding the wapi code. -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, other request will be directly -+ * dropped by returning BUSY -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * modify Beacon/ProbeResp to complete parsing, -+ * because host software has looser memory usage restriction -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P present boolean flag in BSS & Pre-BSS descriptor. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add definitions for module migration. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * move bss related data types to wlan_def.h to avoid recursive dependency. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge cnm_scan.h and hem_mbox.h -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:40 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _WLAN_DEF_H -+#define _WLAN_DEF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* disconnect reason */ -+#define DISCONNECT_REASON_CODE_RESERVED 0 -+#define DISCONNECT_REASON_CODE_RADIO_LOST 1 -+#define DISCONNECT_REASON_CODE_DEAUTHENTICATED 2 -+#define DISCONNECT_REASON_CODE_DISASSOCIATED 3 -+#define DISCONNECT_REASON_CODE_NEW_CONNECTION 4 -+#define DISCONNECT_REASON_CODE_REASSOCIATION 5 -+#define DISCONNECT_REASON_CODE_ROAMING 6 -+ -+/* The rate definitions */ -+#define TX_MODE_CCK 0x00 -+#define TX_MODE_OFDM 0x40 -+#define TX_MODE_HT_MM 0x80 -+#define TX_MODE_HT_GF 0xC0 -+ -+#define RATE_CCK_SHORT_PREAMBLE 0x10 -+#define RATE_OFDM 0x20 -+ -+#define PHY_RATE_1M 0x0 -+#define PHY_RATE_2M 0x1 -+#define PHY_RATE_5_5M 0x2 -+#define PHY_RATE_11M 0x3 -+#define PHY_RATE_6M 0xB -+#define PHY_RATE_9M 0xF -+#define PHY_RATE_12M 0xA -+#define PHY_RATE_18M 0xE -+#define PHY_RATE_24M 0x9 -+#define PHY_RATE_36M 0xD -+#define PHY_RATE_48M 0x8 -+#define PHY_RATE_54M 0xC -+#define PHY_RATE_MCS0 0x0 -+#define PHY_RATE_MCS1 0x1 -+#define PHY_RATE_MCS2 0x2 -+#define PHY_RATE_MCS3 0x3 -+#define PHY_RATE_MCS4 0x4 -+#define PHY_RATE_MCS5 0x5 -+#define PHY_RATE_MCS6 0x6 -+#define PHY_RATE_MCS7 0x7 -+#define PHY_RATE_MCS32 0x20 -+ -+#define RATE_CCK_1M_LONG (TX_MODE_CCK | PHY_RATE_1M) -+#define RATE_CCK_2M_LONG (TX_MODE_CCK | PHY_RATE_2M) -+#define RATE_CCK_5_5M_LONG (TX_MODE_CCK | PHY_RATE_5_5M) -+#define RATE_CCK_11M_LONG (TX_MODE_CCK | PHY_RATE_11M) -+#define RATE_CCK_2M_SHORT (TX_MODE_CCK | PHY_RATE_2M | RATE_CCK_SHORT_PREAMBLE) -+#define RATE_CCK_5_5M_SHORT (TX_MODE_CCK | PHY_RATE_5_5M | RATE_CCK_SHORT_PREAMBLE) -+#define RATE_CCK_11M_SHORT (TX_MODE_CCK | PHY_RATE_11M | RATE_CCK_SHORT_PREAMBLE) -+#define RATE_OFDM_6M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_6M) -+#define RATE_OFDM_9M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_9M) -+#define RATE_OFDM_12M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_12M) -+#define RATE_OFDM_18M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_18M) -+#define RATE_OFDM_24M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_24M) -+#define RATE_OFDM_36M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_36M) -+#define RATE_OFDM_48M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_48M) -+#define RATE_OFDM_54M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_54M) -+ -+#define RATE_MM_MCS_0 (TX_MODE_HT_MM | PHY_RATE_MCS0) -+#define RATE_MM_MCS_1 (TX_MODE_HT_MM | PHY_RATE_MCS1) -+#define RATE_MM_MCS_2 (TX_MODE_HT_MM | PHY_RATE_MCS2) -+#define RATE_MM_MCS_3 (TX_MODE_HT_MM | PHY_RATE_MCS3) -+#define RATE_MM_MCS_4 (TX_MODE_HT_MM | PHY_RATE_MCS4) -+#define RATE_MM_MCS_5 (TX_MODE_HT_MM | PHY_RATE_MCS5) -+#define RATE_MM_MCS_6 (TX_MODE_HT_MM | PHY_RATE_MCS6) -+#define RATE_MM_MCS_7 (TX_MODE_HT_MM | PHY_RATE_MCS7) -+#define RATE_MM_MCS_32 (TX_MODE_HT_MM | PHY_RATE_MCS32) -+ -+#define RATE_GF_MCS_0 (TX_MODE_HT_GF | PHY_RATE_MCS0) -+#define RATE_GF_MCS_1 (TX_MODE_HT_GF | PHY_RATE_MCS1) -+#define RATE_GF_MCS_2 (TX_MODE_HT_GF | PHY_RATE_MCS2) -+#define RATE_GF_MCS_3 (TX_MODE_HT_GF | PHY_RATE_MCS3) -+#define RATE_GF_MCS_4 (TX_MODE_HT_GF | PHY_RATE_MCS4) -+#define RATE_GF_MCS_5 (TX_MODE_HT_GF | PHY_RATE_MCS5) -+#define RATE_GF_MCS_6 (TX_MODE_HT_GF | PHY_RATE_MCS6) -+#define RATE_GF_MCS_7 (TX_MODE_HT_GF | PHY_RATE_MCS7) -+#define RATE_GF_MCS_32 (TX_MODE_HT_GF | PHY_RATE_MCS32) -+ -+#define RATE_TX_MODE_MASK BITS(6, 7) -+#define RATE_TX_MODE_OFFSET 6 -+#define RATE_CODE_GET_TX_MODE(_ucRateCode) ((_ucRateCode & RATE_TX_MODE_MASK) >> RATE_TX_MODE_OFFSET) -+#define RATE_PHY_RATE_MASK BITS(0, 5) -+#define RATE_PHY_RATE_OFFSET 0 -+#define RATE_CODE_GET_PHY_RATE(_ucRateCode) ((_ucRateCode & RATE_PHY_RATE_MASK) >> RATE_PHY_RATE_OFFSET) -+#define RATE_PHY_RATE_SHORT_PREAMBLE BIT(4) -+#define RATE_CODE_IS_SHORT_PREAMBLE(_ucRateCode) ((_ucRateCode & RATE_PHY_RATE_SHORT_PREAMBLE)?TRUE:FALSE) -+ -+#define CHNL_LIST_SZ_2G 14 -+#define CHNL_LIST_SZ_5G 14 -+ -+/*! CNM(STA_RECORD_T) related definition */ -+#define CFG_STA_REC_NUM 20 -+ -+/* PHY TYPE bit definitions */ -+#define PHY_TYPE_BIT_HR_DSSS BIT(PHY_TYPE_HR_DSSS_INDEX) /* HR/DSSS PHY (clause 18) */ -+#define PHY_TYPE_BIT_ERP BIT(PHY_TYPE_ERP_INDEX) /* ERP PHY (clause 19) */ -+#define PHY_TYPE_BIT_OFDM BIT(PHY_TYPE_OFDM_INDEX) /* OFDM 5 GHz PHY (clause 17) */ -+#define PHY_TYPE_BIT_HT BIT(PHY_TYPE_HT_INDEX) /* HT PHY (clause 20) */ -+ -+/* PHY TYPE set definitions */ -+#define PHY_TYPE_SET_802_11ABGN (PHY_TYPE_BIT_OFDM | \ -+ PHY_TYPE_BIT_HR_DSSS | \ -+ PHY_TYPE_BIT_ERP | \ -+ PHY_TYPE_BIT_HT) -+ -+#define PHY_TYPE_SET_802_11BGN (PHY_TYPE_BIT_HR_DSSS | \ -+ PHY_TYPE_BIT_ERP | \ -+ PHY_TYPE_BIT_HT) -+ -+#define PHY_TYPE_SET_802_11GN (PHY_TYPE_BIT_ERP | \ -+ PHY_TYPE_BIT_HT) -+ -+#define PHY_TYPE_SET_802_11AN (PHY_TYPE_BIT_OFDM | \ -+ PHY_TYPE_BIT_HT) -+ -+#define PHY_TYPE_SET_802_11ABG (PHY_TYPE_BIT_OFDM | \ -+ PHY_TYPE_BIT_HR_DSSS | \ -+ PHY_TYPE_BIT_ERP) -+ -+#define PHY_TYPE_SET_802_11BG (PHY_TYPE_BIT_HR_DSSS | \ -+ PHY_TYPE_BIT_ERP) -+ -+#define PHY_TYPE_SET_802_11A (PHY_TYPE_BIT_OFDM) -+ -+#define PHY_TYPE_SET_802_11G (PHY_TYPE_BIT_ERP) -+ -+#define PHY_TYPE_SET_802_11B (PHY_TYPE_BIT_HR_DSSS) -+ -+#define PHY_TYPE_SET_802_11N (PHY_TYPE_BIT_HT) -+ -+/* Rate set bit definitions */ -+#define RATE_SET_BIT_1M BIT(RATE_1M_INDEX) /* Bit 0: 1M */ -+#define RATE_SET_BIT_2M BIT(RATE_2M_INDEX) /* Bit 1: 2M */ -+#define RATE_SET_BIT_5_5M BIT(RATE_5_5M_INDEX) /* Bit 2: 5.5M */ -+#define RATE_SET_BIT_11M BIT(RATE_11M_INDEX) /* Bit 3: 11M */ -+#define RATE_SET_BIT_22M BIT(RATE_22M_INDEX) /* Bit 4: 22M */ -+#define RATE_SET_BIT_33M BIT(RATE_33M_INDEX) /* Bit 5: 33M */ -+#define RATE_SET_BIT_6M BIT(RATE_6M_INDEX) /* Bit 6: 6M */ -+#define RATE_SET_BIT_9M BIT(RATE_9M_INDEX) /* Bit 7: 9M */ -+#define RATE_SET_BIT_12M BIT(RATE_12M_INDEX) /* Bit 8: 12M */ -+#define RATE_SET_BIT_18M BIT(RATE_18M_INDEX) /* Bit 9: 18M */ -+#define RATE_SET_BIT_24M BIT(RATE_24M_INDEX) /* Bit 10: 24M */ -+#define RATE_SET_BIT_36M BIT(RATE_36M_INDEX) /* Bit 11: 36M */ -+#define RATE_SET_BIT_48M BIT(RATE_48M_INDEX) /* Bit 12: 48M */ -+#define RATE_SET_BIT_54M BIT(RATE_54M_INDEX) /* Bit 13: 54M */ -+#define RATE_SET_BIT_HT_PHY BIT(RATE_HT_PHY_INDEX) /* Bit 14: BSS Selector */ -+ -+/* Rate set definitions */ -+#define RATE_SET_HR_DSSS (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M) -+ -+#define RATE_SET_ERP (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M | \ -+ RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_9M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_18M | \ -+ RATE_SET_BIT_24M | \ -+ RATE_SET_BIT_36M | \ -+ RATE_SET_BIT_48M | \ -+ RATE_SET_BIT_54M) -+ -+#define RATE_SET_ERP_P2P (RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_9M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_18M | \ -+ RATE_SET_BIT_24M | \ -+ RATE_SET_BIT_36M | \ -+ RATE_SET_BIT_48M | \ -+ RATE_SET_BIT_54M) -+ -+#define RATE_SET_OFDM (RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_9M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_18M | \ -+ RATE_SET_BIT_24M | \ -+ RATE_SET_BIT_36M | \ -+ RATE_SET_BIT_48M | \ -+ RATE_SET_BIT_54M) -+ -+#define RATE_SET_HT (RATE_SET_ERP) -+/* #define RATE_SET_HT (RATE_SET_ERP | RATE_SET_BIT_HT_PHY) *//* NOTE(Kevin): TBD */ -+ -+#define RATE_SET_ALL_ABG RATE_SET_ERP -+ -+#define BASIC_RATE_SET_HR_DSSS (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M) -+ -+#define BASIC_RATE_SET_HR_DSSS_ERP (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M) -+ -+#define BASIC_RATE_SET_ERP (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M | \ -+ RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_24M) -+ -+#define BASIC_RATE_SET_OFDM (RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_24M) -+ -+#define BASIC_RATE_SET_ERP_P2P (RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_24M) -+ -+#define INITIAL_RATE_SET_RCPI_100 RATE_SET_ALL_ABG -+ -+#define INITIAL_RATE_SET_RCPI_80 (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M | \ -+ RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_9M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_24M) -+ -+#define INITIAL_RATE_SET_RCPI_60 (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M | \ -+ RATE_SET_BIT_6M) -+ -+#define INITIAL_RATE_SET(_rcpi) (INITIAL_RATE_SET_ ## _rcpi) -+ -+#define RCPI_100 100 /* -60 dBm */ -+#define RCPI_80 80 /* -70 dBm */ -+#define RCPI_60 60 /* -80 dBm */ -+ -+/* The number of RCPI records used to calculate their average value */ -+#define MAX_NUM_RCPI_RECORDS 10 -+ -+/* The number of RCPI records used to calculate their average value */ -+#define NO_RCPI_RECORDS -128 -+#define MAX_RCPI_DBM 0 -+#define MIN_RCPI_DBM -100 -+ -+#define MAC_TX_RESERVED_FIELD 0 /* NOTE(Kevin): Should defined in tx.h */ -+ -+#define MAX_ASSOC_ID (CFG_STA_REC_NUM) /* Available AID: 1 ~ 20(STA_REC_NUM) */ -+ -+#define MAX_DEAUTH_INFO_COUNT 4 /* NOTE(Kevin): Used in auth.c */ -+#define MIN_DEAUTH_INTERVAL_MSEC 500 /* The minimum interval if continuously send Deauth Frame */ -+ -+/* Authentication Type */ -+#define AUTH_TYPE_OPEN_SYSTEM BIT(AUTH_ALGORITHM_NUM_OPEN_SYSTEM) -+#define AUTH_TYPE_SHARED_KEY BIT(AUTH_ALGORITHM_NUM_SHARED_KEY) -+#define AUTH_TYPE_FAST_BSS_TRANSITION BIT(AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION) -+ -+/* Authentication Retry Limit */ -+#define TX_AUTH_ASSOCI_RETRY_LIMIT 2 -+#define TX_AUTH_ASSOCI_RETRY_LIMIT_FOR_ROAMING 1 -+ -+/* WMM-2.2.1 WMM Information Element */ -+#define ELEM_MAX_LEN_WMM_INFO 7 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef UINT_16 PHY_TYPE, *P_PHY_TYPE; -+typedef UINT_8 RCPI, *P_RCPI; -+typedef UINT_8 ALC_VAL, *P_ALC_VAL; -+ -+typedef enum _ENUM_HW_BSSID_T { -+ BSSID_0 = 0, -+ BSSID_1, -+ BSSID_NUM -+} ENUM_HW_BSSID_T; -+ -+typedef enum _ENUM_HW_MAC_ADDR_T { -+ MAC_ADDR_0 = 0, -+ MAC_ADDR_1, -+ MAC_ADDR_NUM -+} ENUM_HW_MAC_ADDR_T; -+ -+typedef enum _ENUM_HW_OP_MODE_T { -+ HW_OP_MODE_STA = 0, -+ HW_OP_MODE_AP, -+ HW_OP_MODE_ADHOC, -+ HW_OP_MODE_NUM -+} ENUM_HW_OP_MODE_T; -+ -+typedef enum _ENUM_TSF_T { -+ ENUM_LOCAL_TSF_0, -+ ENUM_LOCAL_TSF_1, -+ ENUM_LOCAL_TSF_NUM -+} ENUM_LOCAL_TSF_T, *P_ENUM_LOCAL_TSF_T; -+ -+typedef enum _HAL_TS_HW_UPDATE_MODE { -+ HAL_TSF_HW_UPDATE_BY_TICK_AND_RECEIVED_FRAME, -+ HAL_TSF_HW_UPDATE_BY_TICK_ONLY, -+ HAL_TSF_HW_UPDATE_BY_RECEIVED_FRAME_ONLY, -+ HAL_TSF_HW_UPDATE_BY_TICK_AND_RECEIVED_FRAME_AD_HOC -+} HAL_TSF_HW_UPDATE_MODE; -+ -+typedef enum _ENUM_AC_T { -+ AC0 = 0, -+ AC1, -+ AC2, -+ AC3, -+ AC_NUM -+} ENUM_AC_T, *P_ENUM_AC_T; -+ -+/* The Type of Network been activated */ -+typedef enum _ENUM_NETWORK_TYPE_INDEX_T { -+ NETWORK_TYPE_AIS_INDEX = 0, -+ NETWORK_TYPE_P2P_INDEX, -+ NETWORK_TYPE_BOW_INDEX, -+ NETWORK_TYPE_INDEX_NUM -+} ENUM_NETWORK_TYPE_INDEX_T; -+ -+/* The Type of STA Type. */ -+typedef enum _ENUM_STA_TYPE_INDEX_T { -+ STA_TYPE_LEGACY_INDEX = 0, -+ STA_TYPE_P2P_INDEX, -+ STA_TYPE_BOW_INDEX, -+ STA_TYPE_INDEX_NUM -+} ENUM_STA_TYPE_INDEX_T; -+ -+#define STA_ROLE_BASE_INDEX 4 -+ -+typedef enum _ENUM_STA_ROLE_INDEX_T { -+ STA_ROLE_ADHOC_INDEX = STA_ROLE_BASE_INDEX, /* 4 */ -+ STA_ROLE_CLIENT_INDEX, -+ STA_ROLE_AP_INDEX, -+ STA_ROLE_TDLS_INDEX, -+ STA_ROLE_DLS_INDEX /* Note: need to extend P_CMD_UPDATE_STA_RECORD_T */ -+} ENUM_STA_ROLE_INDEX_T; -+ -+/* The Power State of a specific Network */ -+typedef enum _ENUM_PWR_STATE_T { -+ PWR_STATE_IDLE = 0, -+ PWR_STATE_ACTIVE, -+ PWR_STATE_PS, -+ PWR_STATE_NUM -+} ENUM_PWR_STATE_T; -+ -+typedef enum _ENUM_PHY_TYPE_INDEX_T { -+ /* PHY_TYPE_DSSS_INDEX, *//* DSSS PHY (clause 15) -- Not used anymore */ -+ PHY_TYPE_HR_DSSS_INDEX = 0, /* HR/DSSS PHY (clause 18) */ -+ PHY_TYPE_ERP_INDEX, /* ERP PHY (clause 19) */ -+ PHY_TYPE_ERP_P2P_INDEX, /* ERP PHY (clause 19) w/o HR/DSSS */ -+ PHY_TYPE_OFDM_INDEX, /* OFDM 5 GHz PHY (clause 17) */ -+ PHY_TYPE_HT_INDEX, /* HT PHY (clause 20) */ -+ PHY_TYPE_INDEX_NUM /* 5 */ -+} ENUM_PHY_TYPE_INDEX_T, *P_ENUM_PHY_TYPE_INDEX_T; -+ -+typedef enum _ENUM_ACPI_STATE_T { -+ ACPI_STATE_D0 = 0, -+ ACPI_STATE_D1, -+ ACPI_STATE_D2, -+ ACPI_STATE_D3 -+} ENUM_ACPI_STATE_T; -+ -+/* The operation mode of a specific Network */ -+typedef enum _ENUM_OP_MODE_T { -+ OP_MODE_INFRASTRUCTURE = 0, /* Infrastructure/GC */ -+ OP_MODE_IBSS, /* AdHoc */ -+ OP_MODE_ACCESS_POINT, /* For GO */ -+ OP_MODE_P2P_DEVICE, /* P2P Device */ -+ OP_MODE_BOW, -+ OP_MODE_NUM -+} ENUM_OP_MODE_T, *P_ENUM_OP_MODE_T; -+ -+typedef enum _ENUM_CHNL_EXT_T { -+ CHNL_EXT_SCN = 0, -+ CHNL_EXT_SCA = 1, -+ CHNL_EXT_RES = 2, -+ CHNL_EXT_SCB = 3 -+} ENUM_CHNL_EXT_T, *P_ENUM_CHNL_EXT_T; -+ -+/* This starting freq of the band is unit of kHz */ -+typedef enum _ENUM_BAND_T { -+ BAND_NULL, -+ BAND_2G4, -+ BAND_5G, -+ BAND_NUM -+} ENUM_BAND_T, *P_ENUM_BAND_T; -+ -+/* Provide supported channel list to other components in array format */ -+typedef struct _RF_CHANNEL_INFO_T { -+ ENUM_BAND_T eBand; -+ UINT_8 ucChannelNum; -+} RF_CHANNEL_INFO_T, *P_RF_CHANNEL_INFO_T; -+ -+typedef enum _ENUM_RATE_INDEX_T { -+ RATE_1M_INDEX = 0, /* 1M */ -+ RATE_2M_INDEX, /* 2M */ -+ RATE_5_5M_INDEX, /* 5.5M */ -+ RATE_11M_INDEX, /* 11M */ -+ RATE_22M_INDEX, /* 22M */ -+ RATE_33M_INDEX, /* 33M */ -+ RATE_6M_INDEX, /* 6M */ -+ RATE_9M_INDEX, /* 9M */ -+ RATE_12M_INDEX, /* 12M */ -+ RATE_18M_INDEX, /* 18M */ -+ RATE_24M_INDEX, /* 24M */ -+ RATE_36M_INDEX, /* 36M */ -+ RATE_48M_INDEX, /* 48M */ -+ RATE_54M_INDEX, /* 54M */ -+ RATE_HT_PHY_INDEX, /* BSS Selector - HT PHY */ -+ RATE_NUM /* 15 */ -+} ENUM_RATE_INDEX_T, *P_ENUM_RATE_INDEX_T; -+ -+typedef enum _ENUM_HT_RATE_INDEX_T { -+ HT_RATE_MCS0_INDEX = 0, -+ HT_RATE_MCS1_INDEX, -+ HT_RATE_MCS2_INDEX, -+ HT_RATE_MCS3_INDEX, -+ HT_RATE_MCS4_INDEX, -+ HT_RATE_MCS5_INDEX, -+ HT_RATE_MCS6_INDEX, -+ HT_RATE_MCS7_INDEX, -+ HT_RATE_MCS32_INDEX, -+ HT_RATE_NUM /* 9 */ -+} ENUM_HT_RATE_INDEX_T, *P_ENUM_HT_RATE_INDEX_T; -+ -+typedef enum _ENUM_PREMABLE_OPTION_T { -+ PREAMBLE_DEFAULT_LONG_NONE = 0, /* LONG for PHY_TYPE_HR_DSSS, NONE for PHY_TYPE_OFDM */ -+ PREAMBLE_OPTION_SHORT, /* SHORT mandatory for PHY_TYPE_ERP, SHORT option for PHY_TYPE_HR_DSSS */ -+ PREAMBLE_HT_MIXED_MODE, -+ PREAMBLE_HT_GREEN_FIELD, -+ PREAMBLE_OPTION_NUM -+} ENUM_PREMABLE_OPTION_T, *P_ENUM_PREMABLE_OPTION_T; -+ -+typedef enum _ENUM_CHANNEL_WIDTH_T { -+ CW_20_40MHZ = 0, -+ CW_80MHZ = 1, -+ CW_160MHZ = 2, -+ CW_80P80MHZ = 3 -+} ENUM_CHANNEL_WIDTH_T, *P_ENUM_CHANNEL_WIDTH_P; -+ -+typedef enum _ENUM_MODULATION_SYSTEM_T { -+ MODULATION_SYSTEM_CCK = 0, -+ MODULATION_SYSTEM_OFDM, -+ MODULATION_SYSTEM_HT20, -+ MODULATION_SYSTEM_HT40, -+ MODULATION_SYSTEM_NUM -+} ENUM_MODULATION_SYSTEM_T, *P_ENUM_MODULATION_SYSTEM_T; -+ -+typedef enum _ENUM_MODULATION_TYPE_T { -+ MODULATION_TYPE_CCK_BPSK = 0, -+ MODULATION_TYPE_QPSK, -+ MODULATION_TYPE_16QAM, -+ MODULATION_TYPE_64QAM, -+ MODULATION_TYPE_NUM -+} ENUM_MODULATION_TYPE_T, *P_ENUM_MODULATION_TYPE_T; -+ -+typedef enum _ENUM_PS_FORWARDING_TYPE_T { -+ PS_FORWARDING_TYPE_NON_PS = 0, -+ PS_FORWARDING_TYPE_DELIVERY_ENABLED, -+ PS_FORWARDING_TYPE_NON_DELIVERY_ENABLED, -+ PS_FORWARDING_MORE_DATA_ENABLED, -+ PS_FORWARDING_TYPE_NUM -+} ENUM_PS_FORWARDING_TYPE_T, *P_ENUM_PS_FORWARDING_TYPE_T; -+ -+typedef struct _DEAUTH_INFO_T { -+ UINT_8 aucRxAddr[MAC_ADDR_LEN]; -+ OS_SYSTIME rLastSendTime; -+} DEAUTH_INFO_T, *P_DEAUTH_INFO_T; -+ -+/*----------------------------------------------------------------------------*/ -+/* Information Element (IE) handlers */ -+/*----------------------------------------------------------------------------*/ -+typedef VOID(*PFN_APPEND_IE_FUNC) (P_ADAPTER_T, P_MSDU_INFO_T); -+typedef VOID(*PFN_HANDLE_IE_FUNC) (P_ADAPTER_T, P_SW_RFB_T, P_IE_HDR_T); -+typedef VOID(*PFN_VERIFY_IE_FUNC) (P_ADAPTER_T, P_SW_RFB_T, P_IE_HDR_T, PUINT_16); -+typedef UINT_32(*PFN_CALCULATE_VAR_IE_LEN_FUNC) (P_ADAPTER_T, ENUM_NETWORK_TYPE_INDEX_T, P_STA_RECORD_T); -+ -+typedef struct _APPEND_IE_ENTRY_T { -+ UINT_16 u2EstimatedIELen; -+ PFN_APPEND_IE_FUNC pfnAppendIE; -+} APPEND_IE_ENTRY_T, *P_APPEND_IE_ENTRY_T; -+ -+typedef struct _APPEND_VAR_IE_ENTRY_T { -+ UINT_16 u2EstimatedFixedIELen; /* For Fixed Length */ -+ PFN_CALCULATE_VAR_IE_LEN_FUNC pfnCalculateVariableIELen; -+ PFN_APPEND_IE_FUNC pfnAppendIE; -+} APPEND_VAR_IE_ENTRY_T, *P_APPEND_VAR_IE_ENTRY_T; -+ -+typedef struct _HANDLE_IE_ENTRY_T { -+ UINT_8 ucElemID; -+ PFN_HANDLE_IE_FUNC pfnHandleIE; -+} HANDLE_IE_ENTRY_T, *P_HANDLE_IE_ENTRY_T; -+ -+typedef struct _VERIFY_IE_ENTRY_T { -+ UINT_8 ucElemID; -+ PFN_VERIFY_IE_FUNC pfnVarifyIE; -+} VERIFY_IE_ENTRY_T, *P_VERIFY_IE_ENTRY_T; -+ -+/*----------------------------------------------------------------------------*/ -+/* Parameters of User Configuration */ -+/*----------------------------------------------------------------------------*/ -+typedef enum _ENUM_PARAM_CONNECTION_POLICY_T { -+ CONNECT_BY_SSID_BEST_RSSI = 0, -+ CONNECT_BY_SSID_GOOD_RSSI_MIN_CH_LOAD, -+ CONNECT_BY_SSID_ANY, /* NOTE(Kevin): Needed by WHQL */ -+ CONNECT_BY_BSSID, -+ CONNECT_BY_CUSTOMIZED_RULE /* NOTE(Kevin): TBD */ -+} ENUM_PARAM_CONNECTION_POLICY_T, *P_ENUM_PARAM_CONNECTION_POLICY_T; -+ -+typedef enum _ENUM_PARAM_PREAMBLE_TYPE_T { -+ PREAMBLE_TYPE_LONG = 0, -+ PREAMBLE_TYPE_SHORT, -+ PREAMBLE_TYPE_AUTO /*!< Try preamble short first, if fail tray preamble long. */ -+} ENUM_PARAM_PREAMBLE_TYPE_T, *P_ENUM_PARAM_PREAMBLE_TYPE_T; -+ -+/* This is enum defined for user to select a phy config listed in combo box */ -+typedef enum _ENUM_PARAM_PHY_CONFIG_T { -+ /*!< Can associated with 802.11abg AP but without n capability, Scan dual band. */ -+ PHY_CONFIG_802_11ABG = 0, -+ PHY_CONFIG_802_11BG, /*!< Can associated with 802_11bg AP, Scan single band and not report 5G BSSs. */ -+ PHY_CONFIG_802_11G, /*!< Can associated with 802_11g only AP, Scan single band and not report 5G BSSs. */ -+ PHY_CONFIG_802_11A, /*!< Can associated with 802_11a only AP, Scan single band and not report 2.4G BSSs. */ -+ PHY_CONFIG_802_11B, /*!< Can associated with 802_11b only AP, Scan single band and not report 5G BSSs. */ -+ PHY_CONFIG_802_11ABGN, /*!< Can associated with 802.11abgn AP, Scan dual band. */ -+ PHY_CONFIG_802_11BGN, /*!< Can associated with 802_11bgn AP, Scan single band and not report 5G BSSs. */ -+ PHY_CONFIG_802_11AN, /*!< Can associated with 802_11an AP, Scan single band and not report 2.4G BSSs. */ -+ PHY_CONFIG_802_11GN, /*!< Can associated with 802_11gn AP, Scan single band and not report 5G BSSs. */ -+ PHY_CONFIG_NUM /* 9 */ -+} ENUM_PARAM_PHY_CONFIG_T, *P_ENUM_PARAM_PHY_CONFIG_T; -+ -+/* This is enum defined for user to select an AP Mode */ -+typedef enum _ENUM_PARAM_AP_MODE_T { -+ AP_MODE_11B = 0, /*!< Create 11b BSS if we support 802.11abg/802.11bg. */ -+ AP_MODE_MIXED_11BG, /*!< Create 11bg mixed BSS if we support 802.11abg/802.11bg/802.11g. */ -+ AP_MODE_11G, /*!< Create 11g only BSS if we support 802.11abg/802.11bg/802.11g. */ -+ AP_MODE_11G_P2P, /*!< Create 11g only BSS for P2P if we support 802.11abg/802.11bg/802.11g. */ -+ AP_MODE_11A, /*!< Create 11a only BSS if we support 802.11abg. */ -+ AP_MODE_NUM /* 4 */ -+} ENUM_PARAM_AP_MODE_T, *P_ENUM_PARAM_AP_MODE_T; -+ -+/* Masks for determining the Network Type or the Station Role, given the ENUM_STA_TYPE_T */ -+#define NETWORK_TYPE_AIS_MASK BIT(NETWORK_TYPE_AIS_INDEX) -+#define NETWORK_TYPE_P2P_MASK BIT(NETWORK_TYPE_P2P_INDEX) -+#define NETWORK_TYPE_BOW_MASK BIT(NETWORK_TYPE_BOW_INDEX) -+#define STA_TYPE_LEGACY_MASK BIT(STA_TYPE_LEGACY_INDEX) -+#define STA_TYPE_P2P_MASK BIT(STA_TYPE_P2P_INDEX) -+#define STA_TYPE_BOW_MASK BIT(STA_TYPE_BOW_INDEX) -+#define STA_TYPE_ADHOC_MASK BIT(STA_ROLE_ADHOC_INDEX) -+#define STA_TYPE_CLIENT_MASK BIT(STA_ROLE_CLIENT_INDEX) -+#define STA_TYPE_AP_MASK BIT(STA_ROLE_AP_INDEX) -+#define STA_TYPE_DLS_MASK BIT(STA_ROLE_DLS_INDEX) -+#define STA_TYPE_TDLS_MASK BIT(STA_ROLE_TDLS_INDEX) -+ -+/* Macros for obtaining the Network Type or the Station Role, given the ENUM_STA_TYPE_T */ -+#define IS_STA_IN_AIS(_prStaRec) ((_prStaRec)->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) -+#define IS_STA_IN_P2P(_prStaRec) ((_prStaRec)->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+#define IS_STA_IN_BOW(_prStaRec) ((_prStaRec)->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) -+#define IS_STA_LEGACY_TYPE(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_LEGACY_MASK) -+#define IS_STA_P2P_TYPE(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_P2P_MASK) -+#define IS_STA_BOW_TYPE(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_BOW_MASK) -+#define IS_ADHOC_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_ADHOC_MASK) -+#define IS_CLIENT_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_CLIENT_MASK) -+#define IS_AP_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_AP_MASK) -+#define IS_DLS_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_DLS_MASK) -+#define IS_TDLS_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_TDLS_MASK) -+ -+/* The ENUM_STA_TYPE_T accounts for ENUM_NETWORK_TYPE_T and ENUM_STA_ROLE_INDEX_T. -+ * * It is a merged version of Network Type and STA Role. -+ * */ -+typedef enum _ENUM_STA_TYPE_T { -+ STA_TYPE_LEGACY_AP = (STA_TYPE_LEGACY_MASK | STA_TYPE_AP_MASK), -+ STA_TYPE_LEGACY_CLIENT = (STA_TYPE_LEGACY_MASK | STA_TYPE_CLIENT_MASK), -+ STA_TYPE_ADHOC_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_ADHOC_MASK), -+#if CFG_ENABLE_WIFI_DIRECT -+ STA_TYPE_P2P_GO = (STA_TYPE_P2P_MASK | STA_TYPE_AP_MASK), -+ STA_TYPE_P2P_GC = (STA_TYPE_P2P_MASK | STA_TYPE_CLIENT_MASK), -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ STA_TYPE_BOW_AP = (STA_TYPE_BOW_MASK | STA_TYPE_AP_MASK), -+ STA_TYPE_BOW_CLIENT = (STA_TYPE_BOW_MASK | STA_TYPE_CLIENT_MASK), -+#endif -+ STA_TYPE_DLS_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_DLS_MASK), -+ STA_TYPE_TDLS_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_TDLS_MASK) -+} ENUM_STA_TYPE_T, *P_ENUM_STA_TYPE_T; -+ -+/* The type of BSS we discovered */ -+typedef enum _ENUM_BSS_TYPE_T { -+ BSS_TYPE_INFRASTRUCTURE = 1, -+ BSS_TYPE_IBSS, -+ BSS_TYPE_P2P_DEVICE, -+ BSS_TYPE_BOW_DEVICE, -+ BSS_TYPE_NUM -+} ENUM_BSS_TYPE_T, *P_ENUM_BSS_TYPE_T; -+ -+/*----------------------------------------------------------------------------*/ -+/* RSN structures */ -+/*----------------------------------------------------------------------------*/ -+/* #if defined(WINDOWS_DDK) || defined(WINDOWS_CE) */ -+/* #pragma pack(1) */ -+/* #endif */ -+ -+#define MAX_NUM_SUPPORTED_CIPHER_SUITES 8 /* max number of supported cipher suites */ -+#if CFG_SUPPORT_802_11W -+#define MAX_NUM_SUPPORTED_AKM_SUITES 8 /* max number of supported AKM suites */ -+#else -+#define MAX_NUM_SUPPORTED_AKM_SUITES 6 /* max number of supported AKM suites */ -+#endif -+ -+/* Structure of RSN Information */ -+typedef struct _RSN_INFO_T { -+ UINT_8 ucElemId; -+ UINT_16 u2Version; -+ UINT_32 u4GroupKeyCipherSuite; -+ UINT_32 u4PairwiseKeyCipherSuiteCount; -+ UINT_32 au4PairwiseKeyCipherSuite[MAX_NUM_SUPPORTED_CIPHER_SUITES]; -+ UINT_32 u4AuthKeyMgtSuiteCount; -+ UINT_32 au4AuthKeyMgtSuite[MAX_NUM_SUPPORTED_AKM_SUITES]; -+ UINT_16 u2RsnCap; -+ BOOLEAN fgRsnCapPresent; -+} /*__KAL_ATTRIB_PACKED__*/ RSN_INFO_T, *P_RSN_INFO_T; -+ -+#define MAX_NUM_SUPPORTED_WAPI_AKM_SUITES 1 /* max number of supported AKM suites */ -+#define MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES 1 /* max number of supported cipher suites */ -+ -+/* Structure of WAPI Information */ -+typedef struct _WAPI_INFO_T { -+ UINT_8 ucElemId; -+ UCHAR ucLength; -+ UINT_16 u2Version; -+ UINT_32 u4AuthKeyMgtSuiteCount; -+ UINT_32 au4AuthKeyMgtSuite[MAX_NUM_SUPPORTED_WAPI_AKM_SUITES]; -+ UINT_32 u4PairwiseKeyCipherSuiteCount; -+ UINT_32 au4PairwiseKeyCipherSuite[MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES]; -+ UINT_32 u4GroupKeyCipherSuite; -+ UINT_16 u2WapiCap; -+ UINT_16 u2Bkid; -+ UINT_8 aucBkid[1][16]; -+} /* __KAL_ATTRIB_PACKED__ */ WAPI_INFO_T, *P_WAPI_INFO_T; -+ -+/* #if defined(WINDOWS_DDK) || defined(WINDOWS_CE) */ -+/* #pragma pack() */ -+/* #endif */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ -+typedef struct _P2P_DEVICE_TYPE_T { -+ UINT_16 u2CategoryID; -+ UINT_16 u2SubCategoryID; -+} P2P_DEVICE_TYPE_T, *P_P2P_DEVICE_TYPE_T; -+ -+typedef struct _P2P_DEVICE_DESC_T { -+ LINK_ENTRY_T rLinkEntry; -+ BOOLEAN fgDevInfoValid; -+ UINT_8 aucDeviceAddr[MAC_ADDR_LEN]; /* Device Address. */ -+ UINT_8 aucInterfaceAddr[MAC_ADDR_LEN]; /* Interface Address. */ -+ UINT_8 ucDeviceCapabilityBitmap; -+ UINT_8 ucGroupCapabilityBitmap; -+ UINT_16 u2ConfigMethod; /* Configure Method support. */ -+ P2P_DEVICE_TYPE_T rPriDevType; -+ UINT_8 ucSecDevTypeNum; -+ P2P_DEVICE_TYPE_T arSecDevType[8]; /* Reference to P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT */ -+ UINT_16 u2NameLength; -+ UINT_8 aucName[32]; /* Reference to WPS_ATTRI_MAX_LEN_DEVICE_NAME */ -+ /* TODO: Service Information or PasswordID valid? */ -+} P2P_DEVICE_DESC_T, *P_P2P_DEVICE_DESC_T; -+ -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static const UINT_8 aucRateIndex2RateCode[PREAMBLE_OPTION_NUM][RATE_NUM] = { -+ { /* Long Preamble */ -+ RATE_CCK_1M_LONG, /* RATE_1M_INDEX = 0 */ -+ RATE_CCK_2M_LONG, /* RATE_2M_INDEX */ -+ RATE_CCK_5_5M_LONG, /* RATE_5_5M_INDEX */ -+ RATE_CCK_11M_LONG, /* RATE_11M_INDEX */ -+ RATE_CCK_1M_LONG, /* RATE_22M_INDEX - Not supported */ -+ RATE_CCK_1M_LONG, /* RATE_33M_INDEX - Not supported */ -+ RATE_OFDM_6M, /* RATE_6M_INDEX */ -+ RATE_OFDM_9M, /* RATE_9M_INDEX */ -+ RATE_OFDM_12M, /* RATE_12M_INDEX */ -+ RATE_OFDM_18M, /* RATE_18M_INDEX */ -+ RATE_OFDM_24M, /* RATE_24M_INDEX */ -+ RATE_OFDM_36M, /* RATE_36M_INDEX */ -+ RATE_OFDM_48M, /* RATE_48M_INDEX */ -+ RATE_OFDM_54M, /* RATE_54M_INDEX */ -+ }, -+ { /* Short Preamble */ -+ RATE_CCK_1M_LONG, /* RATE_1M_INDEX = 0 */ -+ RATE_CCK_2M_SHORT, /* RATE_2M_INDEX */ -+ RATE_CCK_5_5M_SHORT, /* RATE_5_5M_INDEX */ -+ RATE_CCK_11M_SHORT, /* RATE_11M_INDEX */ -+ RATE_CCK_1M_LONG, /* RATE_22M_INDEX - Not supported */ -+ RATE_CCK_1M_LONG, /* RATE_33M_INDEX - Not supported */ -+ RATE_OFDM_6M, /* RATE_6M_INDEX */ -+ RATE_OFDM_9M, /* RATE_9M_INDEX */ -+ RATE_OFDM_12M, /* RATE_12M_INDEX */ -+ RATE_OFDM_18M, /* RATE_18M_INDEX */ -+ RATE_OFDM_24M, /* RATE_24M_INDEX */ -+ RATE_OFDM_36M, /* RATE_36M_INDEX */ -+ RATE_OFDM_48M, /* RATE_48M_INDEX */ -+ RATE_OFDM_54M, /* RATE_54M_INDEX */ -+ }, -+ { /* Mixed Mode(Option) */ -+ RATE_MM_MCS_0, /* RATE_MCS0_INDEX, */ -+ RATE_MM_MCS_1, /* RATE_MCS1_INDEX, */ -+ RATE_MM_MCS_2, /* RATE_MCS2_INDEX, */ -+ RATE_MM_MCS_3, /* RATE_MCS3_INDEX, */ -+ RATE_MM_MCS_4, /* RATE_MCS4_INDEX, */ -+ RATE_MM_MCS_5, /* RATE_MCS5_INDEX, */ -+ RATE_MM_MCS_6, /* RATE_MCS6_INDEX, */ -+ RATE_MM_MCS_7, /* RATE_MCS7_INDEX, */ -+ RATE_MM_MCS_32 /* RATE_MCS32_INDEX, */ -+ }, -+ { /* Green Field(Option) */ -+ RATE_GF_MCS_0, /* RATE_MCS0_INDEX, */ -+ RATE_GF_MCS_1, /* RATE_MCS1_INDEX, */ -+ RATE_GF_MCS_2, /* RATE_MCS2_INDEX, */ -+ RATE_GF_MCS_3, /* RATE_MCS3_INDEX, */ -+ RATE_GF_MCS_4, /* RATE_MCS4_INDEX, */ -+ RATE_GF_MCS_5, /* RATE_MCS5_INDEX, */ -+ RATE_GF_MCS_6, /* RATE_MCS6_INDEX, */ -+ RATE_GF_MCS_7, /* RATE_MCS7_INDEX, */ -+ RATE_GF_MCS_32 /* RATE_MCS32_INDEX, */ -+ } -+}; -+ -+static const UINT_8 aucRateTableSize[PREAMBLE_OPTION_NUM] = { -+ RATE_HT_PHY_INDEX, -+ RATE_HT_PHY_INDEX, -+ HT_RATE_NUM, -+ HT_RATE_NUM -+}; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* Macros to get and set the wireless LAN frame fields those are 16/32 bits in -+ length. */ -+#define WLAN_GET_FIELD_16(_memAddr_p, _value_p) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ *(PUINT_16)(_value_p) = ((UINT_16) __cp[0]) | ((UINT_16) __cp[1] << 8); \ -+ } -+ -+#define WLAN_GET_FIELD_BE16(_memAddr_p, _value_p) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ *(PUINT_16)(_value_p) = ((UINT_16) __cp[0] << 8) | ((UINT_16) __cp[1]); \ -+ } -+ -+#define WLAN_GET_FIELD_32(_memAddr_p, _value_p) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ *(PUINT_32)(_value_p) = ((UINT_32) __cp[0]) | ((UINT_32) __cp[1] << 8) | \ -+ ((UINT_32) __cp[2] << 16) | ((UINT_32) __cp[3] << 24); \ -+ } -+ -+#define WLAN_GET_FIELD_64(_memAddr_p, _value_p) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ *(PUINT_64)(_value_p) = \ -+ ((UINT_64) __cp[0]) | ((UINT_64) __cp[1] << 8) | \ -+ ((UINT_64) __cp[2] << 16) | ((UINT_64) __cp[3] << 24) | \ -+ ((UINT_64) __cp[4] << 32) | ((UINT_64) __cp[5] << 40) | \ -+ ((UINT_64) __cp[6] << 48) | ((UINT_64) __cp[7] << 56); \ -+ } -+ -+#define WLAN_SET_FIELD_16(_memAddr_p, _value) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ __cp[0] = (UINT_8) (_value); \ -+ __cp[1] = (UINT_8) ((_value) >> 8); \ -+ } -+ -+#define WLAN_SET_FIELD_BE16(_memAddr_p, _value) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ __cp[0] = (UINT_8) ((_value) >> 8); \ -+ __cp[1] = (UINT_8) (_value); \ -+ } -+ -+#define WLAN_SET_FIELD_32(_memAddr_p, _value) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ __cp[0] = (UINT_8) (_value); \ -+ __cp[1] = (UINT_8) ((_value) >> 8); \ -+ __cp[2] = (UINT_8) ((_value) >> 16); \ -+ __cp[3] = (UINT_8) ((_value) >> 24); \ -+ } -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WLAN_DEF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h -new file mode 100644 -index 0000000000000..aba2e040c1949 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h -@@ -0,0 +1,2290 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic_cmd_event.h#1 -+*/ -+ -+/*! \file "nic_cmd_event.h" -+ \brief This file contains the declairation file of the WLAN OID processing routines -+ of Windows driver for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: nic_cmd_event.h -+ * -+ * 03 29 2012 eason.tsai -+ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define -+ * add conditional define. -+ * -+ * 03 04 2012 eason.tsai -+ * NULL -+ * modify the cal fail report code. -+ * -+ * 01 06 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * redefine the CMD_ID_SET_TXPWR_CTRL value. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 11 30 2011 cm.chang -+ * [WCXRP00001128] [MT5931 Wi-Fi][FW] Update BB/RF setting based on RF doc v0.7 for LGE spec -+ * 1. Add a new CMD for driver to set device mode -+ * 2. Update calibration parameters -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Update RSSI for P2P. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add TX_DONE status detail information. -+ * -+ * 11 08 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * check if CFG_SUPPORT_SWCR is defined to aoid compiler error. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 10 26 2011 cp.wu -+ * [WCXRP00001065] [MT6620 Wi-Fi][MT5931][FW][DRV] Adding parameter for controlling -+ * minimum channel dwell time for scanning -+ * add interface for control minimum channel dwell time for scanning. -+ * -+ * 09 20 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * New CMD definition about RLM parameters -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 08 25 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add DFS switch. -+ * -+ * 08 24 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Update RDD test mode cases. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 08 09 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * add CCK-DSSS TX-PWR control field in NVRAM and CMD definition for MT5931-MP -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 22 2011 jeffrey.chang -+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time -+ * add osc stable time command structure -+ * -+ * 07 22 2011 jeffrey.chang -+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time -+ * modify driver to set OSC stable time after f/w download -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for more than -+ * one SSID in a single scanning request -+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID -+ * support as well as uProbeDelay in NDIS 6.x driver model -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * check with firmware for valid MAC address. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 06 09 2011 tsaiyuan.hsu -+ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size -+ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. -+ * -+ * 05 27 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 31 2011 chinglan.wang -+ * [WCXRP00000613] [MT6620 Wi-Fi] [FW] [Driver] BssInfo can get the security mode which is WPA/WPA2/WAPI or not. -+ * . -+ * -+ * 03 18 2011 cm.chang -+ * [WCXRP00000576] [MT6620 Wi-Fi][Driver][FW] Remove P2P compile option in scan req/cancel command -+ * As CR title -+ * -+ * 03 17 2011 yarco.yang -+ * [WCXRP00000569] [MT6620 Wi-Fi][F/W][Driver] Set multicast address support current network usage -+ * . -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add Security check related code. -+ * -+ * 03 02 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * Support UAPSD/OppPS/NoA parameter setting -+ * -+ * 02 16 2011 cm.chang -+ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism -+ * . -+ * -+ * 02 10 2011 cp.wu -+ * [WCXRP00000434] [MT6620 Wi-Fi][Driver] Obsolete unused event packet handlers -+ * EVENT_ID_CONNECTION_STATUS has been obsoleted and no need to handle. -+ * -+ * 02 08 2011 eddie.chen -+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode -+ * Add event STA agint timeout -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Update cmd format of BSS INFO, always sync OwnMac to FW no matter P2P is enabled or not.. -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 01 15 2011 puff.wen -+ * NULL -+ * Add Stress test -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * Sync HT operation element information from host to FW -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * report EEPROM used flag via NIC_CAPABILITY -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools -+ * -+ * 12 23 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * 1. update WMM IE parsing, with ASSOC REQ handling -+ * 2. extend U-APSD parameter passing from driver to FW -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 29 2010 cm.chang -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for -+ * initial TX rate selection of auto-rate algorithm -+ * Sync RCPI of STA_REC to FW as reference of initial TX rate -+ * -+ * 11 08 2010 cm.chang -+ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID -+ * Remove CNM channel reover message ID -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 25 2010 cp.wu -+ * [WCXRP00000133] [MT6620 Wi-Fi] [FW][Driver] Change TX power offset band definition -+ * follow-up for CMD_5G_PWR_OFFSET_T definition change -+ * -+ * 10 20 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * use OID_CUSTOM_TEST_MODE as indication for driver reset -+ * by dropping pending TX packets -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 09 15 2010 cm.chang -+ * NULL -+ * Add new CMD for TX power, 5G power offset and power parameters -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Add a pointer in P2P SCAN RESULT structure. This pointer -+ * is pointed to a IE buffer for this P2p device. -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * add new CMD ID definition -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add a field in BSS INFO cmd to change interface address for P2P. (switching between Device Addr & Interface Addr) -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Add interface address indication when indicate connection status. -+ * It is requested by supplicant to do 4 way handshake. -+ * -+ * 08 07 2010 wh.su -+ * NULL -+ * adding the privacy related code for P2P network -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Change data structure for P2P Device scan result, all channel time for scan command. -+ * -+ * 08 04 2010 george.huang -+ * NULL -+ * handle change PS mode OID/ CMD -+ * -+ * 08 04 2010 yarco.yang -+ * NULL -+ * Add TX_AMPDU and ADDBA_REJECT command -+ * -+ * 08 03 2010 george.huang -+ * NULL -+ * handle event for updating NOA parameters indicated from FW -+ * -+ * 08 02 2010 george.huang -+ * NULL -+ * add WMM-PS test related OID/ CMD handlers -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * sync. CMD_BSS_INFO structure change to CMD-EVENT v0.15. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add P2P Device Found Event. -+ * Channel extension option in scan abort command. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * add AIS-FSM handling for beacon timeout event. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add for P2P Scan Result Parsing & Saving. -+ * -+ * 07 20 2010 george.huang -+ * -+ * DWORD align for the CMD data structure -+ * -+ * 07 20 2010 cp.wu -+ * -+ * pass band information for scan in an efficient way by mapping ENUM_BAND_T into UINT_8.. -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * pass band with channel number information as scan parameter -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 09 2010 cp.wu -+ * -+ * reorder members of CMD_SET_BSS_INFO. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * update prStaRecOfAP with BSS-INFO. -+ * -+ * 07 07 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support state of STA record change from 1 to 1 -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support sync command of STA_REC -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 30 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync. with CMD/EVENT document ver0.07. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * correct variable naming for 8-bit variable used in CMD_BEACON_TEMPLATE_UPDATE. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 28 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Create beacon update path, with expose bssUpdateBeaconContent() -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add BSS/STA_REC commands for integration. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Add TX Done Event handle entry -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct OID_802_11_DISASSOCIATE handling. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * sync statistics data structure definition with firmware implementation -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * statistics information OIDs are now handled by querying from firmware domain -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * indicate media stream mode after set is done -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add a temporary flag for integration with CMD/EVENT v0.9. -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. -+ * * the frequency is used for adhoc connection only -+ * * 2) update with SD1 v0.9 CMD/EVENT documentation -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00003824][MT6620 Wi-Fi][New Feature] Add support of large scan list -+ * Implement feature needed by CR: WPD00003824: refining association command by pasting scanning result -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+ * 03 15 2010 kevin.huang -+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test -+ * Add event for activate STA_RECORD_T -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement custom OID: EEPROM read/write access -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_3_MULTICAST_LIST oid handling -+ * -+ * 02 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move EVENT_ID_ASSOC_INFO from nic_rx.c to gl_kal_ndis_51.c -+ * 'cause it involves OS dependent data structure handling -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * send CMD_ID_INFRASTRUCTURE when handling OID_802_11_INFRASTRUCTURE_MODE set. -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * * * 4. correct some HAL implementation -+ * -+ * 01 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement following 802.11 OIDs: -+ * * * OID_802_11_RSSI, -+ * * * OID_802_11_RSSI_TRIGGER, -+ * * * OID_802_11_STATISTICS, -+ * * * OID_802_11_DISASSOCIATE, -+ * * * OID_802_11_POWER_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_MEDIA_STREAM_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * * and result is retrieved by get ATInfo instead -+ * * * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-12-11 18:35:07 GMT mtk02752 -+** add CMD added in CMD/EVEN document v0.8 -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-12-10 16:39:37 GMT mtk02752 -+** eliminate unused definitions -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-12-10 09:55:11 GMT mtk02752 -+** command ID/event ID revised -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-12-09 13:57:37 GMT MTK02468 -+** Added event ids (EVENT_ID_RX_ADDBA and EVENT_ID_RX_DELBA) -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-08 17:35:39 GMT mtk02752 -+** + add event ID for EVENT_ID_TEST_STATUS (rf test) -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-12-07 23:01:09 GMT mtk02752 -+** add data structure for RF_TEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-12-03 16:22:56 GMT mtk01461 -+** Modify the element - i4RSSI in EVENT of SCAN RESULT -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-30 10:54:44 GMT mtk02752 -+** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T, while 1st DW of WIFI_EVENT_T is shared with HIF_RX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-26 10:16:58 GMT mtk02752 -+** resync EVENT_CONNECTION_STATUS -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-25 21:34:01 GMT mtk02752 -+** sync. EVENT_SCAN_RESULT_T with firmware -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-11-25 21:03:48 GMT mtk02752 -+** refine MGMT_FRAME -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-11-25 18:17:47 GMT mtk02752 -+** refine GL_WLAN_INFO_T for buffering scan result and presume max. ie length = 600 bytes -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-24 22:41:20 GMT mtk02752 -+** add EVENT_SCAN_RESULT_T definition -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-11-23 20:29:16 GMT mtk02752 -+** fix typo -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-11-23 14:46:01 GMT mtk02752 -+** add new command/event structure upon CM@SD1's documentation -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-13 15:13:40 GMT mtk02752 -+** add command definition for CMD_BUILD_CONNECTION and EVENT_CONNECTION_STATUS -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-05-20 12:22:22 GMT mtk01461 -+** Add SeqNum field to Event Header -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-29 15:42:11 GMT mtk01461 -+** Update structure of HIF_EVENT_HEADER_T and EVENT_HDR_SIZE -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 12:10:36 GMT mtk01461 -+** Add Common Set CMD Callback for MCR Write and other Set OID -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-21 01:40:17 GMT mtk01461 -+** Command Done Handler -+*/ -+#ifndef _NIC_CMD_EVENT_H -+#define _NIC_CMD_EVENT_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define CMD_STATUS_SUCCESS 0 -+#define CMD_STATUS_REJECTED 1 -+#define CMD_STATUS_UNKNOWN 2 -+ -+#define EVENT_HDR_SIZE OFFSET_OF(WIFI_EVENT_T, aucBuffer[0]) -+ -+#define MAX_IE_LENGTH (600) -+#define MAX_WSC_IE_LENGTH (400) -+ -+/* Action field in structure CMD_CH_PRIVILEGE_T */ -+#define CMD_CH_ACTION_REQ 0 -+#define CMD_CH_ACTION_ABORT 1 -+ -+/* Status field in structure EVENT_CH_PRIVILEGE_T */ -+#define EVENT_CH_STATUS_GRANT 0 -+ -+#define SCN_PSCAN_SWC_RSSI_WIN_MAX 75 -+#define SCN_PSCAN_SWC_MAX_NUM 8 -+#define SCN_PSCAN_HOTLIST_REPORT_MAX_NUM 8 -+ -+typedef enum _ENUM_CMD_ID_T { -+ CMD_ID_TEST_MODE = 1, /* 0x01 (Set) */ -+ CMD_ID_RESET_REQUEST, /* 0x02 (Set) */ -+ CMD_ID_BUILD_CONNECTION, /* 0x03 (Set) */ -+ CMD_ID_SCAN_REQ_V2, /* 0x04 (Set) */ -+ CMD_ID_NIC_POWER_CTRL, /* 0x05 (Set) */ -+ CMD_ID_POWER_SAVE_MODE, /* 0x06 (Set) */ -+ CMD_ID_LINK_ATTRIB, /* 0x07 (Set) */ -+ CMD_ID_ADD_REMOVE_KEY, /* 0x08 (Set) */ -+ CMD_ID_DEFAULT_KEY_ID, /* 0x09 (Set) */ -+ CMD_ID_INFRASTRUCTURE, /* 0x0a (Set) */ -+ CMD_ID_SET_RX_FILTER, /* 0x0b (Set) */ -+ CMD_ID_DOWNLOAD_BUF, /* 0x0c (Set) */ -+ CMD_ID_WIFI_START, /* 0x0d (Set) */ -+ CMD_ID_CMD_BT_OVER_WIFI, /* 0x0e (Set) */ -+ CMD_ID_SET_MEDIA_CHANGE_DELAY_TIME, /* 0x0f (Set) */ -+ CMD_ID_SEND_ADDBA_RSP, /* 0x10 (Set) */ -+ CMD_ID_WAPI_MODE, /* 0x11 (Set) (obsolete) */ -+ CMD_ID_WAPI_ASSOC_INFO, /* 0x12 (Set) (obsolete) */ -+ CMD_ID_SET_DOMAIN_INFO, /* 0x13 (Set) */ -+ CMD_ID_SET_IP_ADDRESS, /* 0x14 (Set) */ -+ CMD_ID_BSS_ACTIVATE_CTRL, /* 0x15 (Set) */ -+ CMD_ID_SET_BSS_INFO, /* 0x16 (Set) */ -+ CMD_ID_UPDATE_STA_RECORD, /* 0x17 (Set) */ -+ CMD_ID_REMOVE_STA_RECORD, /* 0x18 (Set) */ -+ CMD_ID_INDICATE_PM_BSS_CREATED, /* 0x19 (Set) */ -+ CMD_ID_INDICATE_PM_BSS_CONNECTED, /* 0x1a (Set) */ -+ CMD_ID_INDICATE_PM_BSS_ABORT, /* 0x1b (Set) */ -+ CMD_ID_UPDATE_BEACON_CONTENT, /* 0x1c (Set) */ -+ CMD_ID_SET_BSS_RLM_PARAM, /* 0x1d (Set) */ -+ CMD_ID_SCAN_REQ, /* 0x1e (Set) */ -+ CMD_ID_SCAN_CANCEL, /* 0x1f (Set) */ -+ CMD_ID_CH_PRIVILEGE, /* 0x20 (Set) */ -+ CMD_ID_UPDATE_WMM_PARMS, /* 0x21 (Set) */ -+ CMD_ID_SET_WMM_PS_TEST_PARMS, /* 0x22 (Set) */ -+ CMD_ID_TX_AMPDU, /* 0x23 (Set) */ -+ CMD_ID_ADDBA_REJECT, /* 0x24 (Set) */ -+ CMD_ID_SET_PS_PROFILE_ADV, /* 0x25 (Set) */ -+ CMD_ID_SET_RAW_PATTERN, /* 0x26 (Set) */ -+ CMD_ID_CONFIG_PATTERN_FUNC, /* 0x27 (Set) */ -+ CMD_ID_SET_TX_PWR, /* 0x28 (Set) */ -+ CMD_ID_SET_5G_PWR_OFFSET, /* 0x29 (Set) */ -+ CMD_ID_SET_PWR_PARAM, /* 0x2A (Set) */ -+ CMD_ID_P2P_ABORT, /* 0x2B (Set) */ -+#if CFG_STRESS_TEST_SUPPORT -+ CMD_ID_RANDOM_RX_RESET_EN = 0x2C, /* 0x2C (Set ) */ -+ CMD_ID_RANDOM_RX_RESET_DE = 0x2D, /* 0x2D (Set ) */ -+ CMD_ID_SAPP_EN = 0x2E, /* 0x2E (Set ) */ -+ CMD_ID_SAPP_DE = 0x2F, /* 0x2F (Set ) */ -+#endif -+ CMD_ID_ROAMING_TRANSIT = 0x30, /* 0x30 (Set) */ -+ CMD_ID_SET_PHY_PARAM, /* 0x31 (Set) */ -+ CMD_ID_SET_NOA_PARAM, /* 0x32 (Set) */ -+ CMD_ID_SET_OPPPS_PARAM, /* 0x33 (Set) */ -+ CMD_ID_SET_UAPSD_PARAM, /* 0x34 (Set) */ -+ CMD_ID_SET_SIGMA_STA_SLEEP, /* 0x35 (Set) */ -+ CMD_ID_SET_EDGE_TXPWR_LIMIT, /* 0x36 (Set) */ -+ CMD_ID_SET_DEVICE_MODE, /* 0x37 (Set) */ -+ CMD_ID_SET_TXPWR_CTRL, /* 0x38 (Set) */ -+ CMD_ID_SET_AUTOPWR_CTRL, /* 0x39 (Set) */ -+ CMD_ID_SET_WFD_CTRL, /* 0x3A (Set) */ -+ CMD_ID_SET_5G_EDGE_TXPWR_LIMIT, /* 0x3B (Set) */ -+ CMD_ID_SET_RSSI_COMPENSATE, /* 0x3C (Set) */ -+ CMD_ID_SET_BAND_SUPPORT = 0x3D, /* 0x3D (Set) */ -+ CMD_ID_SET_NLO_REQ, /* 0x3E (Set) */ -+ CMD_ID_SET_NLO_CANCEL, /* 0x3F (Set) */ -+ CMD_ID_SET_BATCH_REQ, /* 0x40 (Set) */ -+ CMD_ID_SET_WOWLAN, /* 0x41 (Set) */ /*CFG_SUPPORT_WOWLAN */ -+ CMD_ID_GET_PSCAN_CAPABILITY = 0x42, /* 0x42 (Set) */ -+ CMD_ID_SET_PSCN_ENABLE = 0x43, /* 0x43 (Set) */ -+ CMD_ID_SET_PSCAN_PARAM = 0x44, /* 0x44 (Set) */ -+ CMD_ID_SET_PSCN_ADD_HOTLIST_BSSID = 0x45, /* 0x45 (Set) */ -+ CMD_ID_SET_PSCN_ADD_SW_BSSID = 0x46, /* 0x46 (Set) */ -+ CMD_ID_SET_PSCN_MAC_ADDR = 0x47, /* 0x47 (Set) */ -+ CMD_ID_GET_GSCN_SCN_RESULT = 0x48, /* 0x48 (Get) */ -+ CMD_ID_SET_COUNTRY_POWER_LIMIT = 0x4A, /* 0x4A (Set) */ -+ CMD_ID_SET_SYSTEM_SUSPEND = 0x60, /* 0x60 (Set) */ -+ CMD_ID_GET_NIC_CAPABILITY = 0x80, /* 0x80 (Query) */ -+ CMD_ID_GET_LINK_QUALITY, /* 0x81 (Query) */ -+ CMD_ID_GET_STATISTICS, /* 0x82 (Query) */ -+ CMD_ID_GET_CONNECTION_STATUS, /* 0x83 (Query) */ -+ CMD_ID_GET_ASSOC_INFO, /* 0x84 (Query) (obsolete) */ -+ CMD_ID_GET_STA_STATISTICS = 0x85, /* 0x85 (Query) */ -+ CMD_ID_GET_DEBUG_CODE = 0x86, /* 0x86 (Query) */ -+ CMD_ID_GET_LTE_CHN = 0x87, /* 0x87 (Query) */ -+ CMD_ID_GET_CHN_LOADING = 0x88, /* 0x88 (Query) */ -+ CMD_ID_GET_STATISTICS_PL = 0x89, /* 0x87 (Query) */ -+ CMD_ID_BASIC_CONFIG = 0xc1, /* 0xc1 (Set / Query) */ -+ CMD_ID_ACCESS_REG, /* 0xc2 (Set / Query) */ -+ CMD_ID_MAC_MCAST_ADDR, /* 0xc3 (Set / Query) */ -+ CMD_ID_802_11_PMKID, /* 0xc4 (Set / Query) */ -+ CMD_ID_ACCESS_EEPROM, /* 0xc5 (Set / Query) */ -+ CMD_ID_SW_DBG_CTRL, /* 0xc6 (Set / Query) */ -+#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ -+ CMD_ID_SEC_CHECK, /* 0xc7 (Set / Query) */ -+#endif -+ CMD_ID_DUMP_MEM, /* 0xc8 (Query) */ -+ -+ CMD_ID_CHIP_CONFIG = 0xCA, /* 0xca (Set / Query) */ -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ CMD_ID_SET_RDD_CH = 0xE1, -+#endif -+ -+ CMD_ID_SET_BWCS = 0xF1, -+ CMD_ID_SET_ROAMING_INFO = 0xF3, -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+ CMD_ID_GET_BUILD_DATE_CODE = 0xF8, -+#endif -+ CMD_ID_GET_BSS_INFO = 0xF9, -+#if 1 /* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */ -+ CMD_ID_SET_HOTSPOT_OPTIMIZATION = 0xFA, /* 0xFA (Set) */ -+#endif -+ -+ CMD_ID_TDLS_CORE = 0xFC, -+ CMD_ID_STATS = 0xFD, -+ CMD_ID_TX_AR_ERR_CONFIG = 0xFF -+} ENUM_CMD_ID_T, *P_ENUM_CMD_ID_T; -+ -+typedef enum _ENUM_EVENT_ID_T { -+ EVENT_ID_CMD_RESULT = 1, /* 0x01 (Query) */ -+ EVENT_ID_NIC_CAPABILITY, /* 0x02 (Query) */ -+ EVENT_ID_CONNECTION_STATUS, /* 0x03 (Query / Unsolicited) (obsolete) */ -+ EVENT_ID_SCAN_RESULT, /* 0x04 (Query / Unsolicited) (obselete) */ -+ EVENT_ID_LINK_QUALITY, /* 0x05 (Query / Unsolicited) */ -+ EVENT_ID_STATISTICS, /* 0x06 (Query) */ -+ EVENT_ID_MIC_ERR_INFO, /* 0x07 (Unsolicited) */ -+ EVENT_ID_ASSOC_INFO, /* 0x08 (Query - CMD_ID_GET_ASSOC_INFO) */ -+ EVENT_ID_BASIC_CONFIG, /* 0x09 (Query - CMD_ID_BASIC_CONFIG) */ -+ EVENT_ID_ACCESS_REG, /* 0x0a (Query - CMD_ID_ACCESS_REG) */ -+ EVENT_ID_MAC_MCAST_ADDR, /* 0x0b (Query - CMD_ID_MAC_MCAST_ADDR) */ -+ EVENT_ID_802_11_PMKID, /* 0x0c (Query - CMD_ID_802_11_PMKID) */ -+ EVENT_ID_ACCESS_EEPROM, /* 0x0d (Query - CMD_ID_ACCESS_EEPROM) */ -+ EVENT_ID_SLEEPY_NOTIFY, /* 0x0e (Query) */ -+ EVENT_ID_BT_OVER_WIFI, /* 0x0f (Unsolicited) */ -+ EVENT_ID_TEST_STATUS, /* 0x10 (Query - CMD_ID_TEST_MODE) */ -+ EVENT_ID_RX_ADDBA, /* 0x11 (Unsolicited) (obsolete) */ -+ EVENT_ID_RX_DELBA, /* 0x12 (Unsolicited) (obsolete) */ -+ EVENT_ID_ACTIVATE_STA_REC_T, /* 0x13 (Unsolicited) */ -+ EVENT_ID_DEACTIVATE_STA_REC_T, /* 0x14 (Unsolicited) */ -+ EVENT_ID_SCAN_DONE, /* 0x15 (Unsoiicited) */ -+ EVENT_ID_RX_FLUSH, /* 0x16 (Unsolicited) */ -+ EVENT_ID_TX_DONE, /* 0x17 (Unsolicited) */ -+ EVENT_ID_CH_PRIVILEGE, /* 0x18 (Unsolicited) */ -+ EVENT_ID_BSS_ABSENCE_PRESENCE = 0x19, /* 0x19 (Unsolicited) */ -+ EVENT_ID_STA_CHANGE_PS_MODE, /* 0x1A (Unsolicited) */ -+ EVENT_ID_BSS_BEACON_TIMEOUT, /* 0x1B (Unsolicited) */ -+ EVENT_ID_UPDATE_NOA_PARAMS, /* 0x1C (Unsolicited) */ -+ EVENT_ID_AP_OBSS_STATUS, /* 0x1D (Unsolicited) */ -+ EVENT_ID_STA_UPDATE_FREE_QUOTA, /* 0x1E (Unsolicited) */ -+ EVENT_ID_SW_DBG_CTRL, /* 0x1F (Query - CMD_ID_SW_DBG_CTRL) */ -+ EVENT_ID_ROAMING_STATUS, /* 0x20 (Unsolicited) */ -+ EVENT_ID_STA_AGING_TIMEOUT, /* 0x21 (Unsolicited) */ -+#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ -+ EVENT_ID_SEC_CHECK_RSP, /* 0x22 (Unsolicited) */ -+#endif -+ EVENT_ID_SEND_DEAUTH, /* 0x23 (Unsolicited) */ -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ EVENT_ID_UPDATE_RDD_STATUS, /* 0x24 (Unsolicited) */ -+#endif -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+ EVENT_ID_UPDATE_BWCS_STATUS = 0x25, /* 0x25 (Unsolicited) */ -+ EVENT_ID_UPDATE_BCM_DEBUG, /* 0x26 (Unsolicited) */ -+#endif -+ EVENT_ID_RX_ERR, -+ EVENT_ID_DUMP_MEM, -+ EVENT_ID_STA_STATISTICS = 0x29, /* 0x29 (Query ) */ -+ EVENT_ID_STA_STATISTICS_UPDATE, /* 0x2A (Unsolicited) */ -+ EVENT_ID_NLO_DONE = 0x2b, -+ -+ EVENT_ID_GSCAN_CAPABILITY = 0x30, -+ EVENT_ID_GSCAN_SCAN_COMPLETE = 0x31, -+ EVENT_ID_GSCAN_FULL_RESULT = 0x32, -+ EVENT_ID_GSCAN_SIGNIFICANT_CHANGE = 0x33, -+ EVENT_ID_GSCAN_GEOFENCE_FOUND = 0x34, -+ EVENT_ID_GSCAN_SCAN_AVAILABLE = 0x35, -+ EVENT_ID_GSCAN_RESULT = 0x36, -+ EVENT_ID_BATCH_RESULT = 0x37, -+ -+ EVENT_ID_TDLS = 0x80, -+ EVENT_ID_STATS_ENV = 0x81, -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+ EVENT_ID_BUILD_DATE_CODE = 0xF8, -+#endif -+ EVENT_ID_GET_AIS_BSS_INFO = 0xF9, -+ EVENT_ID_DEBUG_CODE = 0xFB, -+ EVENT_ID_RFTEST_READY = 0xFC, /* 0xFC */ -+ EVENT_ID_TX_DONE_STATUS = 0xFD, -+ EVENT_ID_FW_LOG_ENV = 0xFE, /* 0xFE, FW real time debug log */ -+} ENUM_EVENT_ID_T, *P_ENUM_EVENT_ID_T; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#ifndef LINUX -+typedef UINT_8 CMD_STATUS; -+#endif -+ -+typedef struct _EVENT_TX_DONE_STATUS_T { -+ UINT_8 ucPacketSeq; -+ UINT_8 ucStatus; -+ UINT_16 u2SequenceNumber; -+ UINT_32 au4Reserved1; -+ UINT_32 au4Reserved2; -+ UINT_32 au4Reserved3; -+ UINT_32 u4PktBufInfo; -+ UINT_8 aucPktBuf[200]; -+} EVENT_TX_DONE_STATUS_T, *P_EVENT_TX_DONE_STATUS_T; -+ -+/* for Event Packet (via HIF-RX) */ -+ /* following CM's documentation v0.7 */ -+typedef struct _WIFI_CMD_T { -+ UINT_16 u2TxByteCount_UserPriority; -+ UINT_8 ucEtherTypeOffset; -+ UINT_8 ucResource_PktType_CSflags; -+ UINT_8 ucCID; -+ UINT_8 ucSetQuery; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2; -+ -+ UINT_8 aucBuffer[0]; -+} WIFI_CMD_T, *P_WIFI_CMD_T; -+ -+/* for Command Packet (via HIF-TX) */ -+ /* following CM's documentation v0.7 */ -+typedef struct _WIFI_EVENT_T { -+ UINT_16 u2PacketLen; -+ UINT_16 u2PacketType; -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ UINT_8 aucBuffer[0]; -+} WIFI_EVENT_T, *P_WIFI_EVENT_T; -+ -+/* CMD_ID_TEST_MODE */ -+typedef struct _CMD_TEST_CTRL_T { -+ UINT_8 ucAction; -+ UINT_8 aucReserved[3]; -+ union { -+ UINT_32 u4OpMode; -+ UINT_32 u4ChannelFreq; -+ PARAM_MTK_WIFI_TEST_STRUCT_T rRfATInfo; -+ } u; -+} CMD_TEST_CTRL_T, *P_CMD_TEST_CTRL_T; -+ -+/* EVENT_TEST_STATUS */ -+typedef struct _PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T { -+ UINT_32 u4PktSentStatus; -+ UINT_32 u4PktSentCount; -+ UINT_16 u2AvgAlc; -+ UINT_8 ucCckGainControl; -+ UINT_8 ucOfdmGainControl; -+} PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T, *P_PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T { -+ UINT_32 u4IntRxOk; /*!< number of packets that Rx ok from interrupt */ -+ UINT_32 u4IntCrcErr; /*!< number of packets that CRC error from interrupt */ -+ UINT_32 u4IntShort; /*!< number of packets that is short preamble from interrupt */ -+ UINT_32 u4IntLong; /*!< number of packets that is long preamble from interrupt */ -+ UINT_32 u4PauRxPktCount; /*!< number of packets that Rx ok from PAU */ -+ UINT_32 u4PauCrcErrCount; /*!< number of packets that CRC error from PAU */ -+ UINT_32 u4PauRxFifoFullCount; /*!< number of packets that is short preamble from PAU */ -+ UINT_32 u4PauCCACount; /*!< CCA rising edge count */ -+} PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T, *P_PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T; -+ -+typedef union _EVENT_TEST_STATUS { -+ PARAM_MTK_WIFI_TEST_STRUCT_T rATInfo; -+/* PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T rTxStatus; */ -+/* PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T rRxStatus; */ -+} EVENT_TEST_STATUS, *P_EVENT_TEST_STATUS; -+ -+/* CMD_BUILD_CONNECTION */ -+typedef struct _CMD_BUILD_CONNECTION { -+ UINT_8 ucInfraMode; -+ UINT_8 ucAuthMode; -+ UINT_8 ucEncryptStatus; -+ UINT_8 ucSsidLen; -+ UINT_8 aucSsid[PARAM_MAX_LEN_SSID]; -+ UINT_8 aucBssid[PARAM_MAC_ADDR_LEN]; -+ -+ /* Ad-hoc mode */ -+ UINT_16 u2BeaconPeriod; -+ UINT_16 u2ATIMWindow; -+ UINT_8 ucJoinOnly; -+ UINT_8 ucReserved; -+ UINT_32 u4FreqInKHz; -+ -+ /* for faster connection */ -+ UINT_8 aucScanResult[0]; -+} CMD_BUILD_CONNECTION, *P_CMD_BUILD_CONNECTION; -+ -+/* CMD_ADD_REMOVE_KEY */ -+typedef struct _CMD_802_11_KEY { -+ UINT_8 ucAddRemove; -+ UINT_8 ucTxKey; -+ UINT_8 ucKeyType; -+ UINT_8 ucIsAuthenticator; -+ UINT_8 aucPeerAddr[6]; -+ UINT_8 ucNetType; -+ UINT_8 ucAlgorithmId; -+ UINT_8 ucKeyId; -+ UINT_8 ucKeyLen; -+ UINT_8 aucReverved[2]; -+ UINT_8 aucKeyMaterial[32]; -+ UINT_8 aucKeyRsc[16]; -+} CMD_802_11_KEY, *P_CMD_802_11_KEY; -+ -+/* WPA2 PMKID cache structure */ -+typedef struct _PMKID_ENTRY_T { -+ PARAM_BSSID_INFO_T rBssidInfo; -+ BOOLEAN fgPmkidExist; -+} PMKID_ENTRY_T, *P_PMKID_ENTRY_T; -+ -+typedef struct _CMD_802_11_PMKID { -+ ULONG u4BSSIDInfoCount; -+ P_PMKID_ENTRY_T arPMKIDInfo[1]; -+} CMD_802_11_PMKID, *P_CMD_802_11_PMKID; -+ -+/* CMD_BASIC_CONFIG */ -+typedef struct _CMD_CSUM_OFFLOAD { -+ UINT_16 u2RxChecksum; /* bit0: IP, bit1: UDP, bit2: TCP */ -+ UINT_16 u2TxChecksum; /* bit0: IP, bit1: UDP, bit2: TCP */ -+} CMD_CSUM_OFFLOAD, *P_CMD_CSUM_OFFLOAD; -+ -+typedef struct _CMD_BASIC_CONFIG { -+ PARAM_MAC_ADDRESS rMyMacAddr; -+ UINT_8 ucNative80211; -+ UINT_8 aucReserved[1]; -+ -+ CMD_CSUM_OFFLOAD rCsumOffload; -+} CMD_BASIC_CONFIG, *P_CMD_BASIC_CONFIG, EVENT_BASIC_CONFIG, *P_EVENT_BASIC_CONFIG; -+ -+/* CMD_MAC_MCAST_ADDR */ -+typedef struct _CMD_MAC_MCAST_ADDR { -+ UINT_32 u4NumOfGroupAddr; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 aucReserved[3]; -+ PARAM_MAC_ADDRESS arAddress[MAX_NUM_GROUP_ADDR]; -+} CMD_MAC_MCAST_ADDR, *P_CMD_MAC_MCAST_ADDR, EVENT_MAC_MCAST_ADDR, *P_EVENT_MAC_MCAST_ADDR; -+ -+/* CMD_ACCESS_EEPROM */ -+typedef struct _CMD_ACCESS_EEPROM { -+ UINT_16 u2Offset; -+ UINT_16 u2Data; -+} CMD_ACCESS_EEPROM, *P_CMD_ACCESS_EEPROM, EVENT_ACCESS_EEPROM, *P_EVENT_ACCESS_EEPROM; -+ -+typedef struct _CMD_CUSTOM_NOA_PARAM_STRUCT_T { -+ UINT_32 u4NoaDurationMs; -+ UINT_32 u4NoaIntervalMs; -+ UINT_32 u4NoaCount; -+} CMD_CUSTOM_NOA_PARAM_STRUCT_T, *P_CMD_CUSTOM_NOA_PARAM_STRUCT_T; -+ -+typedef struct _CMD_CUSTOM_OPPPS_PARAM_STRUCT_T { -+ UINT_32 u4CTwindowMs; -+} CMD_CUSTOM_OPPPS_PARAM_STRUCT_T, *P_CMD_CUSTOM_OPPPS_PARAM_STRUCT_T; -+ -+typedef struct _CMD_CUSTOM_UAPSD_PARAM_STRUCT_T { -+ UINT_8 fgEnAPSD; -+ UINT_8 fgEnAPSD_AcBe; -+ UINT_8 fgEnAPSD_AcBk; -+ UINT_8 fgEnAPSD_AcVo; -+ UINT_8 fgEnAPSD_AcVi; -+ UINT_8 ucMaxSpLen; -+ UINT_8 aucResv[2]; -+} CMD_CUSTOM_UAPSD_PARAM_STRUCT_T, *P_CMD_CUSTOM_UAPSD_PARAM_STRUCT_T; -+ -+/* EVENT_CONNECTION_STATUS */ -+typedef struct _EVENT_CONNECTION_STATUS { -+ UINT_8 ucMediaStatus; -+ UINT_8 ucReasonOfDisconnect; -+ -+ UINT_8 ucInfraMode; -+ UINT_8 ucSsidLen; -+ UINT_8 aucSsid[PARAM_MAX_LEN_SSID]; -+ UINT_8 aucBssid[PARAM_MAC_ADDR_LEN]; -+ UINT_8 ucAuthenMode; -+ UINT_8 ucEncryptStatus; -+ UINT_16 u2BeaconPeriod; -+ UINT_16 u2AID; -+ UINT_16 u2ATIMWindow; -+ UINT_8 ucNetworkType; -+ UINT_8 aucReserved[1]; -+ UINT_32 u4FreqInKHz; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ UINT_8 aucInterfaceAddr[PARAM_MAC_ADDR_LEN]; -+#endif -+ -+} EVENT_CONNECTION_STATUS, *P_EVENT_CONNECTION_STATUS; -+ -+/* EVENT_NIC_CAPABILITY */ -+typedef struct _EVENT_NIC_CAPABILITY { -+ UINT_16 u2ProductID; -+ UINT_16 u2FwVersion; -+ UINT_16 u2DriverVersion; -+ UINT_8 ucHw5GBandDisabled; -+ UINT_8 ucEepromUsed; -+ UINT_8 ucEfuseValid; -+ UINT_8 ucMacAddrValid; -+#if CFG_REPORT_RFBB_VERSION -+ UINT_8 ucRfVersion; -+ UINT_8 ucPhyVersion; -+#endif -+#if CFG_ENABLE_CAL_LOG -+ UINT_8 ucRfCalFail; -+ UINT_8 ucBbCalFail; -+#endif -+ -+#define FEATURE_SET_OFFSET_TDLS 0 -+#define FEATURE_SET_OFFSET_5G_SUPPORT 1 -+ UINT_8 ucFeatureSet; /* bit0: TDLS */ -+ -+ UINT_8 aucReserved[1]; -+#if CFG_EMBED_FIRMWARE_BUILD_DATE_CODE -+ UINT_8 aucDateCode[16]; -+#endif -+} EVENT_NIC_CAPABILITY, *P_EVENT_NIC_CAPABILITY; -+ -+/* modified version of WLAN_BEACON_FRAME_BODY_T for simplier buffering */ -+typedef struct _WLAN_BEACON_FRAME_BODY_T_LOCAL { -+ /* Beacon frame body */ -+ UINT_32 au4Timestamp[2]; /* Timestamp */ -+ UINT_16 u2BeaconInterval; /* Beacon Interval */ -+ UINT_16 u2CapInfo; /* Capability */ -+ UINT_8 aucInfoElem[MAX_IE_LENGTH]; /* Various IEs, start from SSID */ -+ UINT_16 u2IELength; /* This field is *NOT* carried by F/W but caculated by nic_rx */ -+} WLAN_BEACON_FRAME_BODY_T_LOCAL, *P_WLAN_BEACON_FRAME_BODY_T_LOCAL; -+ -+/* EVENT_SCAN_RESULT */ -+typedef struct _EVENT_SCAN_RESULT_T { -+ INT_32 i4RSSI; -+ UINT_32 u4LinkQuality; -+ UINT_32 u4DSConfig; /* Center frequency */ -+ UINT_32 u4DomainInfo; /* Require CM opinion */ -+ UINT_32 u4Reserved; -+ UINT_8 ucNetworkType; -+ UINT_8 ucOpMode; -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX]; -+ WLAN_BEACON_FRAME_BODY_T_LOCAL rBeaconFrameBody; -+} EVENT_SCAN_RESULT_T, *P_EVENT_SCAN_RESULT_T; -+ -+/* event of tkip mic error */ -+typedef struct _EVENT_MIC_ERR_INFO { -+ UINT_32 u4Flags; -+} EVENT_MIC_ERR_INFO, *P_EVENT_MIC_ERR_INFO; -+ -+typedef struct _EVENT_PMKID_CANDIDATE_LIST_T { -+ UINT_32 u4Version; /*!< Version */ -+ UINT_32 u4NumCandidates; /*!< How many candidates follow */ -+ PARAM_PMKID_CANDIDATE_T arCandidateList[1]; -+} EVENT_PMKID_CANDIDATE_LIST_T, *P_EVENT_PMKID_CANDIDATE_LIST_T; -+ -+typedef struct _EVENT_CMD_RESULT { -+ UINT_8 ucCmdID; -+ UINT_8 ucStatus; -+ UINT_8 aucReserved[2]; -+} EVENT_CMD_RESULT, *P_EVENT_CMD_RESULT; -+ -+/* CMD_ID_ACCESS_REG & EVENT_ID_ACCESS_REG */ -+typedef struct _CMD_ACCESS_REG { -+ UINT_32 u4Address; -+ UINT_32 u4Data; -+} CMD_ACCESS_REG, *P_CMD_ACCESS_REG; -+ -+/* CMD_ID_ACCESS_REG & EVENT_ID_ACCESS_REG */ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ -+typedef struct _CMD_ACCESS_CHN_LOAD { -+ UINT_32 u4Address; -+ UINT_32 u4Data; -+ UINT_16 u2Channel; -+ UINT_8 aucReserved[2]; -+} CMD_ACCESS_CHN_LOAD, *P_ACCESS_CHN_LOAD; -+ -+#endif -+/* CMD_DUMP_MEMORY */ -+typedef struct _CMD_DUMP_MEM { -+ UINT_32 u4Address; -+ UINT_32 u4Length; -+ UINT_32 u4RemainLength; -+ UINT_8 ucFragNum; -+} CMD_DUMP_MEM, *P_CMD_DUMP_MEM; -+ -+typedef struct _EVENT_DUMP_MEM_T { -+ UINT_32 u4Address; -+ UINT_32 u4Length; -+ UINT_32 u4RemainLength; -+ UINT_8 ucFragNum; -+ UINT_8 aucBuffer[1]; -+} EVENT_DUMP_MEM_T, *P_EVENT_DUMP_MEM_T; -+ -+typedef struct _CMD_SW_DBG_CTRL_T { -+ UINT_32 u4Id; -+ UINT_32 u4Data; -+ /* Debug Support */ -+ UINT_32 u4DebugCnt[64]; -+} CMD_SW_DBG_CTRL_T, *P_CMD_SW_DBG_CTRL_T; -+ -+/* CMD_ID_LINK_ATTRIB */ -+typedef struct _CMD_LINK_ATTRIB { -+ INT_8 cRssiTrigger; -+ UINT_8 ucDesiredRateLen; -+ UINT_16 u2DesiredRate[32]; -+ UINT_8 ucMediaStreamMode; -+ UINT_8 aucReserved[1]; -+} CMD_LINK_ATTRIB, *P_CMD_LINK_ATTRIB; -+ -+/* CMD_ID_NIC_POWER_CTRL */ -+typedef struct _CMD_NIC_POWER_CTRL { -+ UINT_8 ucPowerMode; -+ UINT_8 aucReserved[3]; -+} CMD_NIC_POWER_CTRL, *P_CMD_NIC_POWER_CTRL; -+ -+/* CMD_ID_POWER_SAVE_MODE */ -+typedef struct _CMD_PS_PROFILE_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucPsProfile; -+ UINT_8 aucReserved[2]; -+} CMD_PS_PROFILE_T, *P_CMD_PS_PROFILE_T; -+ -+/* EVENT_LINK_QUALITY */ -+typedef struct _EVENT_LINK_QUALITY { -+ INT_8 cRssi; -+ INT_8 cLinkQuality; -+ UINT_16 u2LinkSpeed; -+ UINT_8 ucMediumBusyPercentage; -+} EVENT_LINK_QUALITY, *P_EVENT_LINK_QUALITY; -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+/* EVENT_LINK_QUALITY */ -+typedef struct _EVENT_LINK_QUALITY_EX { -+ INT_8 cRssi; -+ INT_8 cLinkQuality; -+ UINT_16 u2LinkSpeed; -+ UINT_8 ucMediumBusyPercentage; -+ UINT_8 ucIsLQ0Rdy; -+ INT_8 cRssiP2P; /* For P2P Network. */ -+ INT_8 cLinkQualityP2P; -+ UINT_16 u2LinkSpeedP2P; -+ UINT_8 ucMediumBusyPercentageP2P; -+ UINT_8 ucIsLQ1Rdy; -+} EVENT_LINK_QUALITY_EX, *P_EVENT_LINK_QUALITY_EX; -+#endif -+ -+/* EVENT_ID_STATISTICS */ -+typedef struct _EVENT_STATISTICS { -+ LARGE_INTEGER rTransmittedFragmentCount; -+ LARGE_INTEGER rMulticastTransmittedFrameCount; -+ LARGE_INTEGER rFailedCount; -+ LARGE_INTEGER rRetryCount; -+ LARGE_INTEGER rMultipleRetryCount; -+ LARGE_INTEGER rRTSSuccessCount; -+ LARGE_INTEGER rRTSFailureCount; -+ LARGE_INTEGER rACKFailureCount; -+ LARGE_INTEGER rFrameDuplicateCount; -+ LARGE_INTEGER rReceivedFragmentCount; -+ LARGE_INTEGER rMulticastReceivedFrameCount; -+ LARGE_INTEGER rFCSErrorCount; -+} EVENT_STATISTICS, *P_EVENT_STATISTICS; -+ -+/* EVENT_ID_FW_SLEEPY_NOTIFY */ -+typedef struct _EVENT_SLEEPY_NOTIFY { -+ UINT_8 ucSleepyState; -+ UINT_8 aucReserved[3]; -+} EVENT_SLEEPY_NOTIFY, *P_EVENT_SLEEPY_NOTIFY; -+ -+typedef struct _EVENT_ACTIVATE_STA_REC_T { -+ UINT_8 aucMacAddr[6]; -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucNetworkTypeIndex; -+ BOOLEAN fgIsQoS; -+ BOOLEAN fgIsAP; -+ UINT_8 aucReserved[2]; -+} EVENT_ACTIVATE_STA_REC_T, *P_EVENT_ACTIVATE_STA_REC_T; -+ -+typedef struct _EVENT_DEACTIVATE_STA_REC_T { -+ UINT_8 ucStaRecIdx; -+ UINT_8 aucReserved[3]; -+} EVENT_DEACTIVATE_STA_REC_T, *P_EVENT_DEACTIVATE_STA_REC_T; -+ -+/* CMD_BT_OVER_WIFI */ -+typedef struct _CMD_BT_OVER_WIFI { -+ UINT_8 ucAction; /* 0: query, 1: setup, 2: destroy */ -+ UINT_8 ucChannelNum; -+ PARAM_MAC_ADDRESS rPeerAddr; -+ UINT_16 u2BeaconInterval; -+ UINT_8 ucTimeoutDiscovery; -+ UINT_8 ucTimeoutInactivity; -+ UINT_8 ucRole; -+ UINT_8 PAL_Capabilities; -+ UINT_8 cMaxTxPower; -+ UINT_8 ucChannelBand; -+ UINT_8 ucReserved[1]; -+} CMD_BT_OVER_WIFI, *P_CMD_BT_OVER_WIFI; -+ -+/* EVENT_BT_OVER_WIFI */ -+typedef struct _EVENT_BT_OVER_WIFI { -+ UINT_8 ucLinkStatus; -+ UINT_8 ucSelectedChannel; -+ INT_8 cRSSI; -+ UINT_8 ucReserved[1]; -+} EVENT_BT_OVER_WIFI, *P_EVENT_BT_OVER_WIFI; -+ -+/* Same with DOMAIN_SUBBAND_INFO */ -+typedef struct _CMD_SUBBAND_INFO { -+ UINT_8 ucRegClass; -+ UINT_8 ucBand; -+ UINT_8 ucChannelSpan; -+ UINT_8 ucFirstChannelNum; -+ UINT_8 ucNumChannels; -+ UINT_8 aucReserved[3]; -+} CMD_SUBBAND_INFO, *P_CMD_SUBBAND_INFO; -+ -+/* CMD_SET_DOMAIN_INFO */ -+typedef struct _CMD_SET_DOMAIN_INFO_T { -+ UINT_16 u2CountryCode; -+ UINT_16 u2IsSetPassiveScan; /* 0: set channel domain; 1: set passive scan channel domain */ -+ CMD_SUBBAND_INFO rSubBand[6]; -+ -+ UINT_8 uc2G4Bandwidth; /* CONFIG_BW_20_40M or CONFIG_BW_20M */ -+ UINT_8 uc5GBandwidth; /* CONFIG_BW_20_40M or CONFIG_BW_20M */ -+ UINT_8 aucReserved[2]; -+} CMD_SET_DOMAIN_INFO_T, *P_CMD_SET_DOMAIN_INFO_T; -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+/* CMD_SET_PWR_LIMIT_TABLE */ -+typedef struct _CMD_CHANNEL_POWER_LIMIT { -+ UINT_8 ucCentralCh; -+ INT_8 cPwrLimitCCK; -+ INT_8 cPwrLimit20; -+ INT_8 cPwrLimit40; -+ INT_8 cPwrLimit80; -+ INT_8 cPwrLimit160; -+ UINT_8 ucFlag; -+ UINT_8 aucReserved[1]; -+} CMD_CHANNEL_POWER_LIMIT, *P_CMD_CHANNEL_POWER_LIMIT; -+ -+typedef struct _CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T { -+ UINT_16 u2CountryCode; -+ UINT_8 ucCountryFlag; -+ UINT_8 ucNum; -+ UINT_8 aucReserved[4]; -+ CMD_CHANNEL_POWER_LIMIT rChannelPowerLimit[1]; -+} CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T, *P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T; -+ -+#endif -+ -+/* CMD_SET_IP_ADDRESS */ -+typedef struct _IPV4_NETWORK_ADDRESS { -+ UINT_8 aucIpAddr[4]; -+} IPV4_NETWORK_ADDRESS, *P_IPV4_NETWORK_ADDRESS; -+ -+typedef struct _CMD_SET_NETWORK_ADDRESS_LIST { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucAddressCount; -+ UINT_8 ucReserved[2]; -+ IPV4_NETWORK_ADDRESS arNetAddress[1]; -+} CMD_SET_NETWORK_ADDRESS_LIST, *P_CMD_SET_NETWORK_ADDRESS_LIST; -+ -+typedef struct _PATTERN_DESCRIPTION { -+ UINT_8 fgCheckBcA1; -+ UINT_8 fgCheckMcA1; -+ UINT_8 ePatternHeader; -+ UINT_8 fgAndOp; -+ UINT_8 fgNotOp; -+ UINT_8 ucPatternMask; -+ UINT_16 ucPatternOffset; -+ UINT_8 aucPattern[8]; -+} PATTERN_DESCRIPTION, *P_PATTERN_DESCRIPTION; -+ -+typedef struct _CMD_RAW_PATTERN_CONFIGURATION_T { -+ PATTERN_DESCRIPTION arPatternDesc[4]; -+} CMD_RAW_PATTERN_CONFIGURATION_T, *P_CMD_RAW_PATTERN_CONFIGURATION_T; -+ -+typedef struct _CMD_PATTERN_FUNC_CONFIG { -+ BOOLEAN fgBcA1En; -+ BOOLEAN fgMcA1En; -+ BOOLEAN fgBcA1MatchDrop; -+ BOOLEAN fgMcA1MatchDrop; -+} CMD_PATTERN_FUNC_CONFIG, *P_CMD_PATTERN_FUNC_CONFIG; -+ -+typedef struct _EVENT_TX_DONE_T { -+ UINT_8 ucPacketSeq; -+ UINT_8 ucStatus; -+ UINT_16 u2SequenceNumber; -+ UINT_32 au4Reserved1; -+ UINT_32 au4Reserved2; -+ UINT_32 au4Reserved3; -+} EVENT_TX_DONE_T, *P_EVENT_TX_DONE_T; -+ -+typedef struct _CMD_BSS_ACTIVATE_CTRL { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucActive; -+ UINT_8 aucReserved[2]; -+} CMD_BSS_ACTIVATE_CTRL, *P_CMD_BSS_ACTIVATE_CTRL; -+ -+typedef struct _CMD_SET_BSS_RLM_PARAM_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucRfBand; -+ UINT_8 ucPrimaryChannel; -+ UINT_8 ucRfSco; -+ UINT_8 ucErpProtectMode; -+ UINT_8 ucHtProtectMode; -+ UINT_8 ucGfOperationMode; -+ UINT_8 ucTxRifsMode; -+ UINT_16 u2HtOpInfo3; -+ UINT_16 u2HtOpInfo2; -+ UINT_8 ucHtOpInfo1; -+ UINT_8 ucUseShortPreamble; -+ UINT_8 ucUseShortSlotTime; -+ UINT_8 ucCheckId; /* Fixed value: 0x72 */ -+} CMD_SET_BSS_RLM_PARAM_T, *P_CMD_SET_BSS_RLM_PARAM_T; -+ -+typedef struct _CMD_SET_BSS_INFO { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucConnectionState; -+ UINT_8 ucCurrentOPMode; -+ UINT_8 ucSSIDLen; -+ UINT_8 aucSSID[32]; -+ UINT_8 aucBSSID[6]; -+ UINT_8 ucIsQBSS; -+ UINT_8 ucReserved1; -+ UINT_16 u2OperationalRateSet; -+ UINT_16 u2BSSBasicRateSet; -+ UINT_8 ucStaRecIdxOfAP; -+ UINT_8 ucReserved2; -+ UINT_8 ucReserved3; -+ UINT_8 ucNonHTBasicPhyType; /* For Slot Time and CWmin */ -+ UINT_8 ucAuthMode; -+ UINT_8 ucEncStatus; -+ UINT_8 ucPhyTypeSet; -+ UINT_8 aucOwnMac[6]; -+ UINT_8 fgWapiMode; -+ UINT_8 fgIsApMode; -+ UINT_8 fgHiddenSsidMode; -+ CMD_SET_BSS_RLM_PARAM_T rBssRlmParam; -+} CMD_SET_BSS_INFO, *P_CMD_SET_BSS_INFO; -+ -+typedef struct _CMD_UPDATE_STA_RECORD_T { -+ UINT_8 ucIndex; -+ UINT_8 ucStaType; -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+ UINT_16 u2AssocId; -+ UINT_16 u2ListenInterval; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucDesiredPhyTypeSet; -+ UINT_16 u2DesiredNonHTRateSet; -+ UINT_16 u2BSSBasicRateSet; -+ UINT_8 ucIsQoS; -+ UINT_8 ucIsUapsdSupported; -+ UINT_8 ucStaState; -+ UINT_8 ucMcsSet; -+ UINT_8 ucSupMcs32; -+ UINT_8 ucAmpduParam; -+ UINT_16 u2HtCapInfo; -+ UINT_16 u2HtExtendedCap; -+ UINT_32 u4TxBeamformingCap; -+ UINT_8 ucAselCap; -+ UINT_8 ucRCPI; -+ UINT_8 ucNeedResp; -+ UINT_8 ucUapsdAc; /* b0~3: Trigger enabled, b4~7: Delivery enabled */ -+ UINT_8 ucUapsdSp; /* 0: all, 1: max 2, 2: max 4, 3: max 6 */ -+ UINT_8 aucReserved[3]; -+ /* TBD */ -+} CMD_UPDATE_STA_RECORD_T, *P_CMD_UPDATE_STA_RECORD_T; -+ -+typedef struct _CMD_REMOVE_STA_RECORD_T { -+ UINT_8 ucIndex; -+ UINT_8 ucReserved; -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+} CMD_REMOVE_STA_RECORD_T, *P_CMD_REMOVE_STA_RECORD_T; -+ -+typedef struct _CMD_INDICATE_PM_BSS_CREATED_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucDtimPeriod; -+ UINT_16 u2BeaconInterval; -+ UINT_16 u2AtimWindow; -+ UINT_8 aucReserved[2]; -+} CMD_INDICATE_PM_BSS_CREATED, *P_CMD_INDICATE_PM_BSS_CREATED; -+ -+typedef struct _CMD_INDICATE_PM_BSS_CONNECTED_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucDtimPeriod; -+ UINT_16 u2AssocId; -+ UINT_16 u2BeaconInterval; -+ UINT_16 u2AtimWindow; -+ UINT_8 fgIsUapsdConnection; -+ UINT_8 ucBmpDeliveryAC; -+ UINT_8 ucBmpTriggerAC; -+ UINT_8 aucReserved[1]; -+} CMD_INDICATE_PM_BSS_CONNECTED, *P_CMD_INDICATE_PM_BSS_CONNECTED; -+ -+typedef struct _CMD_INDICATE_PM_BSS_ABORT { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 aucReserved[3]; -+} CMD_INDICATE_PM_BSS_ABORT, *P_CMD_INDICATE_PM_BSS_ABORT; -+ -+typedef struct _CMD_BEACON_TEMPLATE_UPDATE { -+ UINT_8 ucUpdateMethod; /* 0: update randomly, -+ * 1: update all, -+ * 2: delete all (1 and 2 will update directly without search) -+ */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 aucReserved[2]; -+ UINT_16 u2Capability; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} CMD_BEACON_TEMPLATE_UPDATE, *P_CMD_BEACON_TEMPLATE_UPDATE; -+ -+typedef struct _CMD_SET_WMM_PS_TEST_STRUCT_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 bmfgApsdEnAc; /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ -+ UINT_8 ucIsEnterPsAtOnce; /* enter PS immediately without 5 second guard after connected */ -+ UINT_8 ucIsDisableUcTrigger; /* not to trigger UC on beacon TIM is matched (under U-APSD) */ -+} CMD_SET_WMM_PS_TEST_STRUCT_T, *P_CMD_SET_WMM_PS_TEST_STRUCT_T; -+ -+/* Definition for CHANNEL_INFO.ucBand: -+ * 0: Reserved -+ * 1: BAND_2G4 -+ * 2: BAND_5G -+ * Others: Reserved -+ */ -+typedef struct _CHANNEL_INFO_T { -+ UINT_8 ucBand; -+ UINT_8 ucChannelNum; -+} CHANNEL_INFO_T, *P_CHANNEL_INFO_T; -+ -+typedef struct _CMD_SCAN_REQ_EXT_CH_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetworkType; -+ UINT_8 ucScanType; -+ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ -+ UINT_8 ucSSIDLength; -+ UINT_8 aucReserved[1]; -+ UINT_16 u2ChannelMinDwellTime; -+ UINT_8 aucSSID[32]; -+ UINT_16 u2ChannelDwellTime; /* For P2P */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ CHANNEL_INFO_T arChannelList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} CMD_SCAN_REQ_EXT_CH, *P_CMD_SCAN_REQ_EXT_CH; -+ -+typedef struct _CMD_SCAN_REQ_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetworkType; -+ UINT_8 ucScanType; -+ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ -+ UINT_8 ucSSIDLength; -+ UINT_8 aucReserved[1]; -+ UINT_16 u2ChannelMinDwellTime; -+ UINT_8 aucSSID[32]; -+ UINT_16 u2ChannelDwellTime; /* For P2P */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ CHANNEL_INFO_T arChannelList[32]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} CMD_SCAN_REQ, *P_CMD_SCAN_REQ; -+ -+typedef struct _CMD_SCAN_REQ_V2_EXT_CH_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetworkType; -+ UINT_8 ucScanType; -+ UINT_8 ucSSIDType; -+ PARAM_SSID_T arSSID[4]; -+ UINT_16 u2ProbeDelayTime; -+ UINT_16 u2ChannelDwellTime; /* For P2P */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ CHANNEL_INFO_T arChannelList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} CMD_SCAN_REQ_V2_EXT_CH, *P_CMD_SCAN_REQ_V2_EXT_CH; -+ -+typedef struct _CMD_SCAN_REQ_V2_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetworkType; -+ UINT_8 ucScanType; -+ UINT_8 ucSSIDType; -+ PARAM_SSID_T arSSID[4]; -+ UINT_16 u2ProbeDelayTime; -+ UINT_16 u2ChannelDwellTime; /* For P2P */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ CHANNEL_INFO_T arChannelList[32]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} CMD_SCAN_REQ_V2, *P_CMD_SCAN_REQ_V2; -+ -+typedef struct _CMD_SCAN_CANCEL_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucIsExtChannel; /* For P2P channel extension. */ -+ UINT_8 aucReserved[2]; -+} CMD_SCAN_CANCEL, *P_CMD_SCAN_CANCEL; -+ -+typedef struct _EVENT_SCAN_DONE_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucSparseChannelValid; -+ CHANNEL_INFO_T rSparseChannel; -+} EVENT_SCAN_DONE, *P_EVENT_SCAN_DONE; -+ -+#if CFG_SUPPORT_GET_CH_ENV -+typedef struct _CH_ENV_T { -+ UINT_8 ucChNum; -+ UINT_8 ucApNum; -+} CH_ENV_T, *P_CH_ENV_T; -+#endif -+ -+#if 0 /* CFG_SUPPORT_BATCH_SCAN */ -+typedef struct _CMD_BATCH_REQ_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucCmd; /* Start/ Stop */ -+ UINT_8 ucMScan; /* an integer number of scans per batch */ -+ UINT_8 ucBestn; /* an integer number of the max AP to remember per scan */ -+ UINT_8 ucRtt; /* an integer number of highest-strength AP for which we'd -+ like approximate distance reported */ -+ UINT_8 ucChannel; /* channels */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ UINT_8 aucReserved[3]; -+ UINT_32 u4Scanfreq; /* an integer number of seconds between scans */ -+ CHANNEL_INFO_T arChannelList[32]; /* channels */ -+} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T; -+ -+typedef struct _EVENT_BATCH_RESULT_ENTRY_T { -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+ UINT_8 ucSSIDLen; -+ INT_8 cRssi; -+ UINT_32 ucFreq; -+ UINT_32 u4Age; -+ UINT_32 u4Dist; -+ UINT_32 u4Distsd; -+} EVENT_BATCH_RESULT_ENTRY_T, *P_EVENT_BATCH_RESULT_ENTRY_T; -+ -+typedef struct _EVENT_BATCH_RESULT_T { -+ UINT_8 ucScanCount; -+ UINT_8 aucReserved[3]; -+ EVENT_BATCH_RESULT_ENTRY_T arBatchResult[12]; /* Must be the same with SCN_BATCH_STORE_MAX_NUM */ -+} EVENT_BATCH_RESULT_T, *P_EVENT_BATCH_RESULT_T; -+#endif -+ -+typedef struct _CMD_CH_PRIVILEGE_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+ UINT_8 ucAction; -+ UINT_8 ucPrimaryChannel; -+ UINT_8 ucRfSco; -+ UINT_8 ucRfBand; -+ UINT_8 ucReqType; -+ UINT_8 ucReserved; -+ UINT_32 u4MaxInterval; /* In unit of ms */ -+ UINT_8 aucBSSID[6]; -+ UINT_8 aucReserved[2]; -+} CMD_CH_PRIVILEGE_T, *P_CMD_CH_PRIVILEGE_T; -+ -+typedef struct _CMD_TX_PWR_T { -+ INT_8 cTxPwr2G4Cck; /* signed, in unit of 0.5dBm */ -+#if defined(MT6620) -+ INT_8 acReserved[3]; -+#elif defined(MT6628) -+ INT_8 cTxPwr2G4Dsss; /* signed, in unit of 0.5dBm */ -+ INT_8 acReserved[2]; -+#else -+#error "No valid definition!" -+#endif -+ -+ INT_8 cTxPwr2G4OFDM_BPSK; -+ INT_8 cTxPwr2G4OFDM_QPSK; -+ INT_8 cTxPwr2G4OFDM_16QAM; -+ INT_8 cTxPwr2G4OFDM_Reserved; -+ INT_8 cTxPwr2G4OFDM_48Mbps; -+ INT_8 cTxPwr2G4OFDM_54Mbps; -+ -+ INT_8 cTxPwr2G4HT20_BPSK; -+ INT_8 cTxPwr2G4HT20_QPSK; -+ INT_8 cTxPwr2G4HT20_16QAM; -+ INT_8 cTxPwr2G4HT20_MCS5; -+ INT_8 cTxPwr2G4HT20_MCS6; -+ INT_8 cTxPwr2G4HT20_MCS7; -+ -+ INT_8 cTxPwr2G4HT40_BPSK; -+ INT_8 cTxPwr2G4HT40_QPSK; -+ INT_8 cTxPwr2G4HT40_16QAM; -+ INT_8 cTxPwr2G4HT40_MCS5; -+ INT_8 cTxPwr2G4HT40_MCS6; -+ INT_8 cTxPwr2G4HT40_MCS7; -+ -+ INT_8 cTxPwr5GOFDM_BPSK; -+ INT_8 cTxPwr5GOFDM_QPSK; -+ INT_8 cTxPwr5GOFDM_16QAM; -+ INT_8 cTxPwr5GOFDM_Reserved; -+ INT_8 cTxPwr5GOFDM_48Mbps; -+ INT_8 cTxPwr5GOFDM_54Mbps; -+ -+ INT_8 cTxPwr5GHT20_BPSK; -+ INT_8 cTxPwr5GHT20_QPSK; -+ INT_8 cTxPwr5GHT20_16QAM; -+ INT_8 cTxPwr5GHT20_MCS5; -+ INT_8 cTxPwr5GHT20_MCS6; -+ INT_8 cTxPwr5GHT20_MCS7; -+ -+ INT_8 cTxPwr5GHT40_BPSK; -+ INT_8 cTxPwr5GHT40_QPSK; -+ INT_8 cTxPwr5GHT40_16QAM; -+ INT_8 cTxPwr5GHT40_MCS5; -+ INT_8 cTxPwr5GHT40_MCS6; -+ INT_8 cTxPwr5GHT40_MCS7; -+} CMD_TX_PWR_T, *P_CMD_TX_PWR_T; -+ -+typedef struct _CMD_5G_PWR_OFFSET_T { -+ INT_8 cOffsetBand0; /* 4.915-4.980G */ -+ INT_8 cOffsetBand1; /* 5.000-5.080G */ -+ INT_8 cOffsetBand2; /* 5.160-5.180G */ -+ INT_8 cOffsetBand3; /* 5.200-5.280G */ -+ INT_8 cOffsetBand4; /* 5.300-5.340G */ -+ INT_8 cOffsetBand5; /* 5.500-5.580G */ -+ INT_8 cOffsetBand6; /* 5.600-5.680G */ -+ INT_8 cOffsetBand7; /* 5.700-5.825G */ -+} CMD_5G_PWR_OFFSET_T, *P_CMD_5G_PWR_OFFSET_T; -+ -+typedef struct _CMD_PWR_PARAM_T { -+ UINT_32 au4Data[28]; -+ UINT_32 u4RefValue1; -+ UINT_32 u4RefValue2; -+} CMD_PWR_PARAM_T, *P_CMD_PWR_PARAM_T; -+ -+typedef struct _CMD_PHY_PARAM_T { -+ UINT_8 aucData[144]; /* eFuse content */ -+} CMD_PHY_PARAM_T, *P_CMD_PHY_PARAM_T; -+ -+typedef struct _CMD_AUTO_POWER_PARAM_T { -+ UINT_8 ucType; /* 0: Disable 1: Enalbe 0x10: Change parameters */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 aucReserved[2]; -+ UINT_8 aucLevelRcpiTh[3]; -+ UINT_8 aucReserved2[1]; -+ INT_8 aicLevelPowerOffset[3]; /* signed, in unit of 0.5dBm */ -+ UINT_8 aucReserved3[1]; -+ UINT_8 aucReserved4[8]; -+} CMD_AUTO_POWER_PARAM_T, *P_CMD_AUTO_POWER_PARAM_T; -+ -+typedef struct _EVENT_CH_PRIVILEGE_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+ UINT_8 ucStatus; -+ UINT_8 ucPrimaryChannel; -+ UINT_8 ucRfSco; -+ UINT_8 ucRfBand; -+ UINT_8 ucReqType; -+ UINT_8 ucReserved; -+ UINT_32 u4GrantInterval; /* In unit of ms */ -+} EVENT_CH_PRIVILEGE_T, *P_EVENT_CH_PRIVILEGE_T; -+ -+typedef enum _ENUM_BEACON_TIMEOUT_TYPE_T { -+ BEACON_TIMEOUT_LOST_BEACON = 0, -+ BEACON_TIMEOUT_AGE, -+ BEACON_TIMEOUT_CONNECT, -+ BEACON_TIMEOUT_BEACON_INTERVAL, -+ BEACON_TIMEOUT_ABORT, -+ BEACON_TIMEOUT_TX_ERROR, -+ BEACON_TIMEOUT_TYPE_NUM -+} ENUM_BEACON_TIMEOUT_TYPE_T, *P_ENUM_BEACON_TIMEOUT_TYPE_T; -+ -+typedef struct _EVENT_BSS_BEACON_TIMEOUT_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucReason; /* ENUM_BEACON_TIMEOUT_TYPE_T */ -+ UINT_8 aucReserved[2]; -+} EVENT_BSS_BEACON_TIMEOUT_T, *P_EVENT_BSS_BEACON_TIMEOUT_T; -+ -+typedef struct _EVENT_STA_AGING_TIMEOUT_T { -+ UINT_8 ucStaRecIdx; -+ UINT_8 aucReserved[3]; -+} EVENT_STA_AGING_TIMEOUT_T, *P_EVENT_STA_AGING_TIMEOUT_T; -+ -+typedef struct _EVENT_NOA_TIMING_T { -+ UINT_8 fgIsInUse; /* Indicate if this entry is in use or not */ -+ UINT_8 ucCount; /* Count */ -+ UINT_8 aucReserved[2]; -+ -+ UINT_32 u4Duration; /* Duration */ -+ UINT_32 u4Interval; /* Interval */ -+ UINT_32 u4StartTime; /* Start Time */ -+} EVENT_NOA_TIMING_T, *P_EVENT_NOA_TIMING_T; -+ -+typedef struct _EVENT_UPDATE_NOA_PARAMS_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 aucReserved[2]; -+ UINT_8 fgEnableOppPS; -+ UINT_16 u2CTWindow; -+ -+ UINT_8 ucNoAIndex; -+ UINT_8 ucNoATimingCount; /* Number of NoA Timing */ -+ EVENT_NOA_TIMING_T arEventNoaTiming[8 /*P2P_MAXIMUM_NOA_COUNT */]; -+} EVENT_UPDATE_NOA_PARAMS_T, *P_EVENT_UPDATE_NOA_PARAMS_T; -+ -+typedef struct _EVENT_AP_OBSS_STATUS_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucObssErpProtectMode; -+ UINT_8 ucObssHtProtectMode; -+ UINT_8 ucObssGfOperationMode; -+ UINT_8 ucObssRifsOperationMode; -+ UINT_8 ucObssBeaconForcedTo20M; -+ UINT_8 aucReserved[2]; -+} EVENT_AP_OBSS_STATUS_T, *P_EVENT_AP_OBSS_STATUS_T; -+ -+typedef struct _CMD_EDGE_TXPWR_LIMIT_T { -+ INT_8 cBandEdgeMaxPwrCCK; -+ INT_8 cBandEdgeMaxPwrOFDM20; -+ INT_8 cBandEdgeMaxPwrOFDM40; -+ INT_8 cReserved; -+} CMD_EDGE_TXPWR_LIMIT_T, *P_CMD_EDGE_TXPWR_LIMIT_T; -+ -+typedef struct _CMD_RSSI_COMPENSATE_T { -+ UINT_8 uc2GRssiCompensation; -+ UINT_8 uc5GRssiCompensation; -+ UINT_8 ucRssiCompensationValidbit; -+ UINT_8 cReserved; -+} CMD_RSSI_COMPENSATE_T, *P_CMD_RSSI_COMPENSATE_T; -+ -+typedef struct _CMD_BAND_SUPPORT_T { -+ UINT_8 uc5GBandSupport; -+ UINT_8 cReserved[3]; -+} CMD_BAND_SUPPORT_T, *P_CMD_BAND_SUPPORT_T; -+ -+typedef struct _CMD_TX_PWR_CE_T { -+ INT_8 cTxPwrCckLmt; /* signed, in unit of 0.5dBm */ -+ INT_8 cTxPwrOfdmLmt; /* signed, in unit of 0.5dBm */ -+ INT_8 cTxPwrHt20Lmt; -+ INT_8 cTxPwrHt40Lmt; -+} CMD_TX_PWR_CE_T, *P_CMD_TX_PWR_CE_T; -+ -+typedef struct _CMD_SET_DEVICE_MODE_T { -+ UINT_16 u2ChipID; -+ UINT_16 u2Mode; -+} CMD_SET_DEVICE_MODE_T, *P_CMD_SET_DEVICE_MODE_T; -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+typedef struct _CMD_RDD_CH_T { -+ UINT_8 ucRddTestMode; -+ UINT_8 ucRddShutCh; -+ UINT_8 ucRddStartCh; -+ UINT_8 ucRddStopCh; -+ UINT_8 ucRddDfs; -+ UINT_8 ucReserved; -+ UINT_8 ucReserved1; -+ UINT_8 ucReserved2; -+} CMD_RDD_CH_T, *P_CMD_RDD_CH_T; -+ -+typedef struct _EVENT_RDD_STATUS_T { -+ UINT_8 ucRddStatus; -+ UINT_8 aucReserved[3]; -+} EVENT_RDD_STATUS_T, *P_EVENT_RDD_STATUS_T; -+#endif -+ -+typedef struct _EVENT_AIS_BSS_INFO_T { -+ ENUM_PARAM_MEDIA_STATE_T eConnectionState; /* Connected Flag used in AIS_NORMAL_TR */ -+ ENUM_OP_MODE_T eCurrentOPMode; /* Current Operation Mode - Infra/IBSS */ -+ BOOLEAN fgIsNetActive; /* TRUE if this network has been actived */ -+ UINT_8 ucReserved[3]; -+} EVENT_AIS_BSS_INFO_T, *P_EVENT_AIS_BSS_INFO_T; -+ -+typedef struct _CMD_SET_TXPWR_CTRL_T { -+ INT_8 c2GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ -+ INT_8 c2GHotspotPwrOffset; -+ INT_8 c2GP2pPwrOffset; -+ INT_8 c2GBowPwrOffset; -+ INT_8 c5GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ -+ INT_8 c5GHotspotPwrOffset; -+ INT_8 c5GP2pPwrOffset; -+ INT_8 c5GBowPwrOffset; -+ UINT_8 ucConcurrencePolicy; /* TX power policy when concurrence -+ in the same channel -+ 0: Highest power has priority -+ 1: Lowest power has priority */ -+ INT_8 acReserved1[3]; /* Must be zero */ -+ -+ /* Power limit by channel for all data rates */ -+ INT_8 acTxPwrLimit2G[14]; /* Channel 1~14, Unit: 0.5dBm */ -+ INT_8 acTxPwrLimit5G[4]; /* UNII 1~4 */ -+ INT_8 acReserved2[2]; /* Must be zero */ -+} CMD_SET_TXPWR_CTRL_T, *P_CMD_SET_TXPWR_CTRL_T; -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+typedef struct _CMD_GET_BUILD_DATE_CODE { -+ UINT_8 aucReserved[4]; -+} CMD_GET_BUILD_DATE_CODE, *P_CMD_GET_BUILD_DATE_CODE; -+ -+typedef struct _EVENT_BUILD_DATE_CODE { -+ UINT_8 aucDateCode[16]; -+} EVENT_BUILD_DATE_CODE, *P_EVENT_BUILD_DATE_CODE; -+#endif -+ -+typedef struct _CMD_GET_STA_STATISTICS_T { -+ UINT_8 ucIndex; -+ UINT_8 ucFlags; -+ UINT_8 ucReadClear; -+ UINT_8 aucReserved0[1]; -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+ UINT_8 aucReserved1[2]; -+ UINT_8 aucReserved2[16]; -+} CMD_GET_STA_STATISTICS_T, *P_CMD_GET_STA_STATISTICS_T; -+ -+/* CFG_SUPPORT_WFD */ -+typedef struct _EVENT_STA_STATISTICS_T { -+ /* Event header */ -+ /* UINT_16 u2Length; */ -+ /* UINT_16 u2Reserved1; *//* Must be filled with 0x0001 (EVENT Packet) */ -+ /* UINT_8 ucEID; */ -+ /* UINT_8 ucSeqNum; */ -+ /* UINT_8 aucReserved2[2]; */ -+ -+ /* Event Body */ -+ UINT_8 ucVersion; -+ UINT_8 aucReserved1[3]; -+ UINT_32 u4Flags; /* Bit0: valid */ -+ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucNetworkTypeIndex; -+ UINT_8 ucWTEntry; -+ UINT_8 aucReserved4[1]; -+ -+ UINT_8 ucMacAddr[MAC_ADDR_LEN]; -+ UINT_8 ucPer; /* base: 128 */ -+ UINT_8 ucRcpi; -+ -+ UINT_32 u4PhyMode; /* SGI BW */ -+ UINT_16 u2LinkSpeed; /* unit is 0.5 Mbits */ -+ UINT_8 ucLinkQuality; -+ UINT_8 ucLinkReserved; -+ -+ UINT_32 u4TxCount; -+ UINT_32 u4TxFailCount; -+ UINT_32 u4TxLifeTimeoutCount; -+ UINT_32 u4TxDoneAirTime; -+ -+ UINT_8 aucReserved[64]; -+} EVENT_STA_STATISTICS_T, *P_EVENT_STA_STATISTICS_T; -+ -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+typedef struct _CMD_HOTSPOT_OPTIMIZATION_CONFIG { -+ UINT_32 fgHotspotOptimizationEn; -+ UINT_32 u4Level; -+} CMD_HOTSPOT_OPTIMIZATION_CONFIG, *P_HOTSPOT_OPTIMIZATION_CONFIG; -+#endif -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ -+/* 4 Auto Channel Selection */ -+ -+typedef struct _CMD_GET_CHN_LOAD_T { -+ UINT_8 ucIndex; -+ UINT_8 ucFlags; -+ UINT_8 ucReadClear; -+ UINT_8 aucReserved0[1]; -+ -+ UINT_8 ucChannel; -+ UINT_16 u2ChannelLoad; -+ UINT_8 aucReserved1[1]; -+ UINT_8 aucReserved2[16]; -+} CMD_GET_CHN_LOAD_T, *P_CMD_GET_CHN_LOAD_T; -+/* 4 Auto Channel Selection */ -+ -+typedef struct _EVENT_CHN_LOAD_T { -+ /* Event Body */ -+ UINT_8 ucVersion; -+ UINT_8 aucReserved1[3]; -+ UINT_32 u4Flags; /* Bit0: valid */ -+ -+ UINT_8 ucChannel; -+ UINT_16 u2ChannelLoad; -+ UINT_8 aucReserved4[1]; -+ -+ UINT_8 aucReserved[64]; -+ -+} EVENT_CHN_LOAD_T, *P_EVENT_CHN_LOAD_T; -+typedef struct _CMD_GET_LTE_SAFE_CHN_T { -+ UINT_8 ucIndex; -+ UINT_8 ucFlags; -+ UINT_8 aucReserved0[2]; -+ -+ UINT_8 aucReserved2[16]; -+} CMD_GET_LTE_SAFE_CHN_T, *P_CMD_GET_LTE_SAFE_CHN_T; -+ -+typedef struct _EVENT_LTE_MODE_T { -+ /* Event Body */ -+ UINT_8 ucVersion; -+ UINT_8 aucReserved1[3]; -+ UINT_32 u4Flags; /* Bit0: valid */ -+ -+ LTE_SAFE_CH_INFO_T rLteSafeChn; -+ UINT_8 aucReserved4[3]; -+ -+ UINT_8 aucReserved[4]; -+ -+} EVENT_LTE_MODE_T, *P_EVENT_LTE_MODE_T; -+#endif -+typedef struct _CMD_ROAMING_INFO_T { -+ UINT_32 fgIsFastRoamingApplied; -+ UINT_32 Reserved[9]; -+} CMD_ROAMING_INFO_T; -+ -+typedef struct _CMD_WFD_DEBUG_MODE_INFO_T { -+ UINT_8 ucDebugMode; -+ UINT_16 u2PeriodInteval; -+ UINT_8 Reserved; -+} CMD_WFD_DEBUG_MODE_INFO_T, *P_CMD_WFD_DEBUG_MODE_INFO_T; -+ -+typedef struct _EVENT_FW_LOG_T { -+ UINT_8 fileName[64]; -+ UINT_32 lineNo; -+ UINT_32 WifiUpTime; -+ UINT_8 log[896]; /* total size is aucBuffer in WIFI_EVENT_T */ -+} EVENT_FW_LOG_T, *P_EVENT_FW_LOG_T; -+ -+typedef enum _ENUM_NLO_CIPHER_ALGORITHM { -+ NLO_CIPHER_ALGO_NONE = 0x00, -+ NLO_CIPHER_ALGO_WEP40 = 0x01, -+ NLO_CIPHER_ALGO_TKIP = 0x02, -+ NLO_CIPHER_ALGO_CCMP = 0x04, -+ NLO_CIPHER_ALGO_WEP104 = 0x05, -+ NLO_CIPHER_ALGO_WPA_USE_GROUP = 0x100, -+ NLO_CIPHER_ALGO_RSN_USE_GROUP = 0x100, -+ NLO_CIPHER_ALGO_WEP = 0x101, -+} ENUM_NLO_CIPHER_ALGORITHM, *P_ENUM_NLO_CIPHER_ALGORITHM; -+ -+typedef enum _ENUM_NLO_AUTH_ALGORITHM { -+ NLO_AUTH_ALGO_80211_OPEN = 1, -+ NLO_AUTH_ALGO_80211_SHARED_KEY = 2, -+ NLO_AUTH_ALGO_WPA = 3, -+ NLO_AUTH_ALGO_WPA_PSK = 4, -+ NLO_AUTH_ALGO_WPA_NONE = 5, -+ NLO_AUTH_ALGO_RSNA = 6, -+ NLO_AUTH_ALGO_RSNA_PSK = 7, -+} ENUM_NLO_AUTH_ALGORITHM, *P_ENUM_NLO_AUTH_ALGORITHM; -+ -+typedef struct _NLO_NETWORK { -+ UINT_8 ucNumChannelHint[4]; -+ UINT_8 ucSSIDLength; -+ UINT_8 ucCipherAlgo; -+ UINT_16 u2AuthAlgo; -+ UINT_8 aucSSID[32]; -+} NLO_NETWORK, *P_NLO_NETWORK; -+ -+typedef struct _CMD_NLO_REQ { -+ UINT_8 ucSeqNum; -+ UINT_8 ucBssIndex; -+ UINT_8 ucNetworkType; -+ UINT_8 fgStopAfterIndication; -+ UINT_8 ucFastScanIteration; -+ UINT_16 u2FastScanPeriod; -+ UINT_16 u2SlowScanPeriod; -+ UINT_8 ucEntryNum; -+ UINT_8 ucReserved; -+ UINT_16 u2IELen; -+ NLO_NETWORK arNetworkList[16]; -+ UINT_8 aucIE[0]; -+ UINT_8 ucScanType; -+} CMD_NLO_REQ, *P_CMD_NLO_REQ; -+ -+typedef struct _CMD_NLO_CANCEL_T { -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved[3]; -+} CMD_NLO_CANCEL, *P_CMD_NLO_CANCEL; -+ -+typedef struct _EVENT_NLO_DONE_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucStatus; -+ UINT_8 aucReserved[2]; -+} EVENT_NLO_DONE_T, *P_EVENT_NLO_DONE_T; -+ -+typedef struct _EVENT_GSCAN_CAPABILITY_T { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved1[3]; -+ UINT_32 u4MaxScanCacheSize; -+ UINT_32 u4MaxScanBuckets; -+ UINT_32 u4MaxApCachePerScan; -+ UINT_32 u4MaxRssiSampleSize; -+ UINT_32 u4MaxScanReportingThreshold; -+ UINT_32 u4MaxHotlistAps; -+ UINT_32 u4MaxSignificantWifiChangeAps; -+ UINT_32 au4Reserved[4]; -+} EVENT_GSCAN_CAPABILITY_T, *P_EVENT_GSCAN_CAPABILITY_T; -+ -+typedef struct _EVENT_GSCAN_SCAN_AVAILABLE_T { -+ UINT_16 u2Num; -+ UINT_8 aucReserved[2]; -+} EVENT_GSCAN_SCAN_AVAILABLE_T, *P_EVENT_GSCAN_SCAN_AVAILABLE_T; -+ -+typedef struct _EVENT_GSCAN_SCAN_COMPLETE_T { -+ UINT_8 ucScanState; -+ UINT_8 aucReserved[3]; -+} EVENT_GSCAN_SCAN_COMPLETE_T, *P_EVENT_GSCAN_SCAN_COMPLETE_T; -+ -+typedef struct WIFI_GSCAN_RESULT { -+ UINT_64 u8Ts; /* Time of discovery */ -+ UINT_8 arSsid[ELEM_MAX_LEN_SSID + 1]; /* null terminated */ -+ UINT_8 arMacAddr[6]; /* BSSID */ -+ UINT_32 u4Channel; /* channel frequency in MHz */ -+ INT_32 i4Rssi; /* in db */ -+ UINT_64 u8Rtt; /* in nanoseconds */ -+ UINT_64 u8RttSd; /* standard deviation in rtt */ -+ UINT_16 u2BeaconPeriod; /* units are Kusec */ -+ UINT_16 u2Capability; /* Capability information */ -+ UINT_32 u4IeLength; /* byte length of Information Elements */ -+ UINT_8 ucIeData[1]; /* IE data to follow */ -+} WIFI_GSCAN_RESULT_T, *P_WIFI_GSCAN_RESULT_T; -+ -+typedef struct _EVENT_GSCAN_RESULT_T { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved[3]; -+ UINT_16 u2ScanId; -+ UINT_16 u2ScanFlags; -+ UINT_16 u2NumOfResults; -+ WIFI_GSCAN_RESULT_T rResult[1]; -+} EVENT_GSCAN_RESULT_T, *P_EVENT_GSCAN_RESULT_T; -+ -+typedef struct _EVENT_GSCAN_FULL_RESULT_T { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved[3]; -+ WIFI_GSCAN_RESULT_T rResult; -+} EVENT_GSCAN_FULL_RESULT_T, *P_EVENT_GSCAN_FULL_RESULT_T; -+ -+typedef struct GSCAN_SWC_NET { -+ UINT_16 u2Flags; -+ UINT_16 u2Channel; -+ UINT_8 arBssid[6]; -+ INT_8 aicRssi[SCN_PSCAN_SWC_RSSI_WIN_MAX]; -+} GSCAN_SWC_NET_T, P_GSCAN_SWC_NET_T; -+ -+typedef struct _EVENT_GSCAN_SIGNIFICANT_CHANGE_T { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved[3]; -+ GSCAN_SWC_NET_T arNet[SCN_PSCAN_SWC_MAX_NUM]; -+} EVENT_GSCAN_SIGNIFICANT_CHANGE_T, *P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T; -+ -+typedef struct _EVENT_GSCAN_GEOFENCE_FOUND_T { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved[3]; -+ WIFI_GSCAN_RESULT_T rResult[SCN_PSCAN_HOTLIST_REPORT_MAX_NUM]; -+} EVENT_GSCAN_GEOFENCE_FOUND_T, *P_EVENT_GSCAN_GEOFENCE_FOUND_T; -+ -+#if CFG_SUPPORT_BATCH_SCAN -+ -+#if 0 /* !CFG_SUPPORT_GSCN */ -+typedef struct _CMD_BATCH_REQ_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucCmd; /* Start/ Stop */ -+ UINT_8 ucMScan; /* an integer number of scans per batch */ -+ UINT_8 ucBestn; /* an integer number of the max AP to remember per scan */ -+ UINT_8 ucRtt; /* an integer number of highest-strength AP for which -+ we'd like approximate distance reported */ -+ UINT_8 ucChannel; /* channels */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ UINT_8 aucReserved[3]; -+ UINT_32 u4Scanfreq; /* an integer number of seconds between scans */ -+ CHANNEL_INFO_T arChannelList[32]; /* channels */ -+} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T; -+ -+#endif -+ -+typedef struct _EVENT_BATCH_RESULT_ENTRY_T { -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+ UINT_8 ucSSIDLen; -+ INT_8 cRssi; -+ UINT_32 ucFreq; -+ UINT_32 u4Age; -+ UINT_32 u4Dist; -+ UINT_32 u4Distsd; -+} EVENT_BATCH_RESULT_ENTRY_T, *P_EVENT_BATCH_RESULT_ENTRY_T; -+ -+typedef struct _EVENT_BATCH_RESULT_T { -+ UINT_8 ucScanCount; -+ UINT_8 aucReserved[3]; -+ EVENT_BATCH_RESULT_ENTRY_T arBatchResult[12]; /* Must be the same with SCN_BATCH_STORE_MAX_NUM */ -+} EVENT_BATCH_RESULT_T, *P_EVENT_BATCH_RESULT_T; -+#endif -+ -+typedef struct _CMD_RLM_INFO_T { -+ UINT_32 u4Version; -+ UINT_32 fgIsErrRatioEnhanceApplied; -+ UINT_8 ucErrRatio2LimitMinRate; -+ /* -+ 0:1M, 1:2M, 2:5.5M, 3:11M, 6:6M, 7:9M, 8:12M, 9:18M, 10:24M, 11:36M, 12:48M, 13:54M -+ */ -+ UINT_8 ucMinLegacyRateIdx; -+ INT_8 cMinRssiThreshold; -+ BOOLEAN fgIsRtsApplied; -+ UINT_8 ucRecoverTime; -+ -+ UINT_32 u4Reserved[0]; -+} CMD_RLM_INFO_T; -+ -+typedef struct _WIFI_SYSTEM_SUSPEND_CMD_T { -+ BOOLEAN fgIsSystemSuspend; -+ UINT_8 reserved[3]; -+} WIFI_SYSTEM_SUSPEND_CMD_T, *P_WIFI_SYSTEM_SUSPEND_CMD_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID nicCmdEventQueryMcrRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryMemDump(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRfTestATInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventSetDisassociate(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventSetIpAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryLinkSpeed(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventEnterRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventLeaveRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryMcastAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryEepromRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventSetMediaStreamMode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+/* Statistics responder */ -+VOID nicCmdEventQueryXmitOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRecvOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryXmitError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRecvError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRecvNoBuffer(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRecvCrcError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRecvErrorAlignment(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+/* for timeout check */ -+VOID nicOidCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+VOID nicCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+VOID nicOidCmdEnterRFTestTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+VOID nicCmdEventBuildDateCode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+#endif -+ -+VOID nicCmdEventQueryStaStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+/* 4 Auto Channel Selection */ -+VOID nicCmdEventQueryChannelLoad(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryLTESafeChn(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+#endif -+ -+#if CFG_SUPPORT_BATCH_SCAN -+VOID nicCmdEventBatchScanResult(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+#endif -+ -+VOID nicCmdEventGetBSSInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _NIC_CMD_EVENT_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h -new file mode 100644 -index 0000000000000..994c589190dee ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h -@@ -0,0 +1,177 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic_init_cmd_event.h#1 -+*/ -+ -+/*! \file "nic_init_cmd_event.h" -+ \brief This file contains the declairation file of the WLAN initialization routines -+ for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: nic_init_cmd_event.h -+ * -+ * 09 26 2011 cp.wu -+ * [WCXRP00001011] [MT6628 Wi-Fi] Firmware Download Agent: make CRC validation as an optional feature -+ * add definition for disabling CRC32 validation (for MT6628 only) -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add two option for ACK and ENCRYPTION for firmware download -+ * -+ * 03 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add command/event definitions for initial states -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement host-side firmware download logic -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+*/ -+#ifndef _NIC_INIT_CMD_EVENT_H -+#define _NIC_INIT_CMD_EVENT_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "gl_typedef.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define INIT_CMD_STATUS_SUCCESS 0 -+#define INIT_CMD_STATUS_REJECTED_INVALID_PARAMS 1 -+#define INIT_CMD_STATUS_REJECTED_CRC_ERROR 2 -+#define INIT_CMD_STATUS_REJECTED_DECRYPT_FAIL 3 -+#define INIT_CMD_STATUS_UNKNOWN 4 -+ -+#define EVENT_HDR_SIZE OFFSET_OF(WIFI_EVENT_T, aucBuffer[0]) -+ -+typedef enum _ENUM_INIT_CMD_ID { -+ INIT_CMD_ID_DOWNLOAD_BUF = 1, -+ INIT_CMD_ID_WIFI_START, -+ INIT_CMD_ID_ACCESS_REG, -+ INIT_CMD_ID_QUERY_PENDING_ERROR -+} ENUM_INIT_CMD_ID, *P_ENUM_INIT_CMD_ID; -+ -+typedef enum _ENUM_INIT_EVENT_ID { -+ INIT_EVENT_ID_CMD_RESULT = 1, -+ INIT_EVENT_ID_ACCESS_REG, -+ INIT_EVENT_ID_PENDING_ERROR -+} ENUM_INIT_EVENT_ID, *P_ENUM_INIT_EVENT_ID; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef UINT_8 CMD_STATUS; -+ -+/* commands */ -+typedef struct _INIT_WIFI_CMD_T { -+ UINT_8 ucCID; -+ UINT_8 ucSeqNum; -+ UINT_16 u2Reserved; -+ UINT_8 aucBuffer[0]; -+} INIT_WIFI_CMD_T, *P_INIT_WIFI_CMD_T; -+ -+typedef struct _INIT_HIF_TX_HEADER_T { -+ UINT_16 u2TxByteCount; -+ UINT_8 ucEtherTypeOffset; -+ UINT_8 ucCSflags; -+ INIT_WIFI_CMD_T rInitWifiCmd; -+} INIT_HIF_TX_HEADER_T, *P_INIT_HIF_TX_HEADER_T; -+ -+#define DOWNLOAD_BUF_ENCRYPTION_MODE BIT(0) -+#define DOWNLOAD_BUF_NO_CRC_CHECKING BIT(30) -+#define DOWNLOAD_BUF_ACK_OPTION BIT(31) -+typedef struct _INIT_CMD_DOWNLOAD_BUF { -+ UINT_32 u4Address; -+ UINT_32 u4Length; -+ UINT_32 u4CRC32; -+ UINT_32 u4DataMode; -+ UINT_8 aucBuffer[0]; -+} INIT_CMD_DOWNLOAD_BUF, *P_INIT_CMD_DOWNLOAD_BUF; -+ -+typedef struct _INIT_CMD_WIFI_START { -+ UINT_32 u4Override; -+ UINT_32 u4Address; -+} INIT_CMD_WIFI_START, *P_INIT_CMD_WIFI_START; -+ -+typedef struct _INIT_CMD_ACCESS_REG { -+ UINT_8 ucSetQuery; -+ UINT_8 aucReserved[3]; -+ UINT_32 u4Address; -+ UINT_32 u4Data; -+} INIT_CMD_ACCESS_REG, *P_INIT_CMD_ACCESS_REG; -+ -+/* Events */ -+typedef struct _INIT_WIFI_EVENT_T { -+ UINT_16 u2RxByteCount; -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucBuffer[0]; -+} INIT_WIFI_EVENT_T, *P_INIT_WIFI_EVENT_T; -+ -+typedef struct _INIT_HIF_RX_HEADER_T { -+ INIT_WIFI_EVENT_T rInitWifiEvent; -+} INIT_HIF_RX_HEADER_T, *P_INIT_HIF_RX_HEADER_T; -+ -+typedef struct _INIT_EVENT_CMD_RESULT { -+ UINT_8 ucStatus; /* 0: success */ -+ /* 1: rejected by invalid param */ -+ /* 2: rejected by incorrect CRC */ -+ /* 3: rejected by decryption failure */ -+ /* 4: unknown CMD */ -+ UINT_8 aucReserved[3]; -+} INIT_EVENT_CMD_RESULT, *P_INIT_EVENT_CMD_RESULT, INIT_EVENT_PENDING_ERROR, *P_INIT_EVENT_PENDING_ERROR; -+ -+typedef struct _INIT_EVENT_ACCESS_REG { -+ UINT_32 u4Address; -+ UINT_32 u4Data; -+} INIT_EVENT_ACCESS_REG, *P_INIT_EVENT_ACCESS_REG; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _NIC_INIT_CMD_EVENT_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h -new file mode 100644 -index 0000000000000..85af819f4e624 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h -@@ -0,0 +1,201 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/p2p_precomp.h#1 -+*/ -+ -+/*! \file p2p_precomp.h -+ \brief Collection of most compiler flags for p2p driver are described here. -+ -+ In this file we collect all compiler flags and detail the p2p driver behavior if -+ enable/disable such switch or adjust numeric parameters. -+*/ -+ -+#ifndef _P2P_PRECOMP_H -+#define _P2P_PRECOMP_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_os.h" /* Include "config.h" */ -+ -+#include "gl_p2p_os.h" -+ -+#include "debug.h" -+ -+#include "link.h" -+#include "queue.h" -+ -+/*------------------------------------------------------------------------------ -+ * .\include\mgmt -+ *------------------------------------------------------------------------------ -+ */ -+#include "wlan_typedef.h" -+ -+#include "mac.h" -+ -+/* Dependency: mac.h (MAC_ADDR_LEN) */ -+#include "wlan_def.h" -+ -+#include "roaming_fsm.h" -+ -+/*------------------------------------------------------------------------------ -+ * .\include\nic -+ *------------------------------------------------------------------------------ -+ */ -+/* Dependency: wlan_def.h (ENUM_NETWORK_TYPE_T) */ -+#include "cmd_buf.h" -+ -+/* Dependency: mac.h (MAC_ADDR_LEN) */ -+#include "nic_cmd_event.h" -+ -+/* Dependency: nic_cmd_event.h (P_EVENT_CONNECTION_STATUS) */ -+#include "nic.h" -+ -+#include "nic_init_cmd_event.h" -+ -+#include "hif_rx.h" -+#include "hif_tx.h" -+ -+#include "nic_tx.h" -+ -+/* Dependency: hif_rx.h (P_HIF_RX_HEADER_T) */ -+#include "nic_rx.h" -+ -+#include "que_mgt.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "p2p_typedef.h" -+#include "p2p_cmd_buf.h" -+#include "p2p_nic_cmd_event.h" -+#include "p2p_mac.h" -+#include "p2p_nic.h" -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * .\include\mgmt -+ *------------------------------------------------------------------------------ -+ */ -+ -+#include "hem_mbox.h" -+ -+#include "scan.h" -+#include "bss.h" -+ -+#include "wlan_lib.h" -+#include "wlan_oid.h" -+#include "wlan_bow.h" -+ -+#include "wlan_p2p.h" -+ -+#include "hal.h" -+ -+#if defined(MT6620) -+#include "mt6620_reg.h" -+#endif -+ -+#include "rlm.h" -+#include "rlm_domain.h" -+#include "rlm_protection.h" -+#include "rlm_obss.h" -+#include "rate.h" -+ -+#include "aa_fsm.h" -+ -+#include "cnm_timer.h" -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+#include "bow.h" -+#include "bow_fsm.h" -+#endif -+ -+#include "pwr_mgt.h" -+ -+#include "cnm.h" -+/* Dependency: aa_fsm.h (ENUM_AA_STATE_T), p2p_fsm.h (WPS_ATTRI_MAX_LEN_DEVICE_NAME) */ -+#include "cnm_mem.h" -+#include "cnm_scan.h" -+ -+#include "p2p_rlm_obss.h" -+#include "p2p_bss.h" -+#include "p2p.h" -+/* Dependency: cnm_timer.h (TIMER_T) */ -+#include "p2p_fsm.h" -+#include "p2p_scan.h" -+#include "p2p_state.h" -+#include "p2p_func.h" -+#include "p2p_rlm.h" -+#include "p2p_assoc.h" -+#include "p2p_ie.h" -+ -+#include "privacy.h" -+ -+#include "mib.h" -+ -+#include "auth.h" -+#include "assoc.h" -+ -+#include "ais_fsm.h" -+ -+#include "adapter.h" -+ -+#include "que_mgt.h" -+#include "rftest.h" -+ -+#if CFG_RSN_MIGRATION -+#include "rsn.h" -+#include "sec_fsm.h" -+#endif -+ -+#if CFG_SUPPORT_WAPI -+#include "wapi.h" -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * NVRAM structure -+ *------------------------------------------------------------------------------ -+ */ -+#include "CFG_Wifi_File.h" -+ -+#include "gl_p2p_kal.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /*_P2P_PRECOMP_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h -new file mode 100644 -index 0000000000000..a02d391d36430 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h -@@ -0,0 +1,165 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/p2p_typedef.h#1 -+*/ -+ -+/*! \file p2p_typedef.h -+ \brief Declaration of data type and return values of internal protocol stack. -+ -+ In this file we declare the data type and return values which will be exported -+ to all MGMT Protocol Stack. -+*/ -+ -+#ifndef _P2P_TYPEDEF_H -+#define _P2P_TYPEDEF_H -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/* -+* type definition of pointer to p2p structure -+*/ -+/* typedef struct _GL_P2P_INFO_T GL_P2P_INFO_T, *P_GL_P2P_INFO_T; */ -+typedef struct _P2P_INFO_T P2P_INFO_T, *P_P2P_INFO_T; -+ -+typedef struct _P2P_FSM_INFO_T P2P_FSM_INFO_T, *P_P2P_FSM_INFO_T; -+ -+typedef struct _P2P_CONNECTION_SETTINGS_T P2P_CONNECTION_SETTINGS_T, *P_P2P_CONNECTION_SETTINGS_T; -+ -+/* Type definition for function pointer to p2p function*/ -+typedef BOOLEAN(*P2P_LAUNCH) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef BOOLEAN(*P2P_REMOVE) (P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsWlanLaunched); -+ -+typedef BOOLEAN(*KAL_P2P_GET_CIPHER) (IN P_GLUE_INFO_T prGlueInfo); -+ -+typedef BOOLEAN(*KAL_P2P_GET_TKIP_CIPHER) (IN P_GLUE_INFO_T prGlueInfo); -+ -+typedef BOOLEAN(*KAL_P2P_GET_CCMP_CIPHER) (IN P_GLUE_INFO_T prGlueInfo); -+ -+typedef BOOLEAN(*KAL_P2P_GET_WSC_MODE) (IN P_GLUE_INFO_T prGlueInfo); -+ -+typedef struct net_device *(*KAL_P2P_GET_DEV_HDLR) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef VOID(*KAL_P2P_SET_MULTICAST_WORK_ITEM) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef VOID(*P2P_NET_REGISTER) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef VOID(*P2P_NET_UNREGISTER) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef VOID(*KAL_P2P_UPDATE_ASSOC_INFO) (IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBody, -+ IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest); -+ -+typedef BOOLEAN(*P2P_VALIDATE_AUTH) (IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode); -+ -+typedef BOOLEAN(*P2P_VALIDATE_ASSOC_REQ) (IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu4ControlFlags); -+ -+typedef VOID(*P2P_RUN_EVENT_AAA_TX_FAIL) (IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+typedef BOOLEAN(*P2P_PARSE_CHECK_FOR_P2P_INFO_ELEM) (IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType); -+ -+typedef WLAN_STATUS(*P2P_RUN_EVENT_AAA_COMPLETE) (IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+typedef VOID(*P2P_PROCESS_EVENT_UPDATE_NOA_PARAM) (IN P_ADAPTER_T prAdapter, -+ UINT_8 ucNetTypeIndex, -+ P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam); -+ -+typedef VOID(*SCAN_P2P_PROCESS_BEACON_AND_PROBE_RESP) (IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, -+ IN P_WLAN_STATUS prStatus, -+ IN P_BSS_DESC_T prBssDesc, -+ IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame); -+ -+typedef VOID(*P2P_RX_PUBLIC_ACTION_FRAME) (P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+typedef VOID(*RLM_RSP_GENERATE_OBSS_SCAN_IE) (P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+typedef VOID(*RLM_UPDATE_BW_BY_CH_LIST_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+typedef VOID(*RLM_PROCESS_PUBLIC_ACTION) (P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+ -+typedef VOID(*RLM_PROCESS_HT_ACTION) (P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+ -+typedef VOID(*RLM_UPDATE_PARAMS_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon); -+ -+typedef VOID(*RLM_HANDLE_OBSS_STATUS_EVENT_PKT) (P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus); -+ -+typedef BOOLEAN(*P2P_FUNC_VALIDATE_PROBE_REQ) (IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); -+ -+typedef VOID(*RLM_BSS_INIT_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+typedef UINT_32(*P2P_GET_PROB_RSP_IE_TABLE_SIZE) (VOID); -+ -+typedef PUINT_8(*P2P_BUILD_REASSOC_REQ_FRAME_COMMON_IES) (IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer); -+ -+typedef VOID(*P2P_FUNC_DISCONNECT) (IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode); -+ -+typedef VOID(*P2P_FSM_RUN_EVENT_RX_DEAUTH) (IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); -+ -+typedef VOID(*P2P_FSM_RUN_EVENT_RX_DISASSOC) (IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); -+ -+typedef BOOLEAN(*P2P_FUN_IS_AP_MODE) (IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+typedef VOID(*P2P_FSM_RUN_EVENT_BEACON_TIMEOUT) (IN P_ADAPTER_T prAdapter); -+ -+typedef VOID(*P2P_FUNC_STORE_ASSOC_RSP_IE_BUFFER) (IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+typedef VOID(*P2P_GENERATE_P2P_IE) (IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+typedef UINT_32(*P2P_CALCULATE_P2P_IE_LEN) (IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /*CFG_ENABLE_WIFI_DIRECT */ -+ -+#endif /* _P2P_TYPEDEF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h -new file mode 100644 -index 0000000000000..1b7e7ede66e1a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h -@@ -0,0 +1,388 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/precomp.h#2 -+*/ -+ -+/*! \file precomp.h -+ \brief Collection of most compiler flags are described here. -+ -+ In this file we collect all compiler flags and detail the driver behavior if -+ enable/disable such switch or adjust numeric parameters. -+*/ -+ -+/* -+** Log: precomp.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver -+ * create branch for Wi-Fi driver v1.1 -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 09 14 2010 chinghwa.yu -+ * NULL -+ * Fix BOW_FSM_INFO_T dependence. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 20 2010 wh.su -+ * -+ * adding the wapi code. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Modify CNM message handler for new flow -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge cnm_scan.h and hem_mbox.h -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * build up basic data structure and definitions to support BT-over-WiFi -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-08 11:30:58 GMT mtk02752 -+** add rftest.h for implementing RF test mode in driver land -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-23 22:02:00 GMT mtk02468 -+** Added que_mgt.h -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-10-13 21:58:36 GMT mtk01084 -+** update for new macro define -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-21 09:40:11 GMT mtk01461 -+** Add nic_cmd_event.h -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-17 20:00:26 GMT mtk01461 -+** Add cmd_buf.h -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:44 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:25 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:38 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _PRECOMP_H -+#define _PRECOMP_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_os.h" /* Include "config.h" */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "gl_p2p_os.h" -+#endif -+ -+#include "debug.h" -+ -+#include "link.h" -+#include "queue.h" -+ -+/*------------------------------------------------------------------------------ -+ * .\include\mgmt -+ *------------------------------------------------------------------------------ -+ */ -+#include "wlan_typedef.h" -+ -+#include "mac.h" -+ -+/* Dependency: mac.h (MAC_ADDR_LEN) */ -+#include "wlan_def.h" -+ -+#if CFG_SUPPORT_SWCR -+#include "swcr.h" -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * .\include\nic -+ *------------------------------------------------------------------------------ -+ */ -+/* Dependency: wlan_def.h (ENUM_NETWORK_TYPE_T) */ -+#include "cmd_buf.h" -+ -+/* Dependency: mac.h (MAC_ADDR_LEN) */ -+#include "nic_cmd_event.h" -+ -+/* Dependency: nic_cmd_event.h (P_EVENT_CONNECTION_STATUS) */ -+#include "nic.h" -+ -+#include "nic_init_cmd_event.h" -+ -+#include "hif_rx.h" -+#include "hif_tx.h" -+ -+#include "nic_tx.h" -+ -+/* Dependency: hif_rx.h (P_HIF_RX_HEADER_T) */ -+#include "nic_rx.h" -+ -+#include "que_mgt.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "p2p_typedef.h" -+#include "p2p_cmd_buf.h" -+#include "p2p_nic_cmd_event.h" -+#include "p2p_mac.h" -+#include "p2p_nic.h" -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * .\include\mgmt -+ *------------------------------------------------------------------------------ -+ */ -+ -+#include "hem_mbox.h" -+ -+#include "scan.h" -+#include "bss.h" -+ -+#include "wlan_lib.h" -+#include "wlan_oid.h" -+#include "wlan_bow.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "wlan_p2p.h" -+#endif -+ -+#include "hal.h" -+ -+#if defined(MT6620) -+#include "mt6620_reg.h" -+#elif defined(MT6628) -+/* #include "mt6628_reg.h" */ -+#include "mtreg.h" -+#endif -+ -+#include "rlm.h" -+#include "rlm_domain.h" -+#include "rlm_protection.h" -+#include "rlm_obss.h" -+#include "rate.h" -+#if CFG_SUPPORT_802_11V -+#include "wnm.h" -+#endif -+ -+#include "aa_fsm.h" -+ -+#include "cnm_timer.h" -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+#include "bow.h" -+#include "bow_fsm.h" -+#endif -+ -+#include "pwr_mgt.h" -+ -+#if (CFG_SUPPORT_STATISTICS == 1) -+#include "stats.h" -+#endif /* CFG_SUPPORT_STATISTICS */ -+ -+#include "cnm.h" -+/* Dependency: aa_fsm.h (ENUM_AA_STATE_T), p2p_fsm.h (WPS_ATTRI_MAX_LEN_DEVICE_NAME) */ -+#include "cnm_mem.h" -+#include "cnm_scan.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "p2p_rlm_obss.h" -+#include "p2p_bss.h" -+#include "p2p.h" -+#include "p2p_fsm.h" -+#include "p2p_scan.h" -+#include "p2p_state.h" -+#include "p2p_func.h" -+#include "p2p_rlm.h" -+#include "p2p_assoc.h" -+#include "p2p_ie.h" -+#endif -+ -+#include "privacy.h" -+ -+#include "mib.h" -+ -+#include "auth.h" -+#include "assoc.h" -+ -+#if CFG_SUPPORT_ROAMING -+#include "roaming_fsm.h" -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+#include "ais_fsm.h" -+ -+#include "adapter.h" -+ -+#include "que_mgt.h" -+#include "rftest.h" -+ -+#if CFG_RSN_MIGRATION -+#include "rsn.h" -+#include "sec_fsm.h" -+#endif -+ -+#if CFG_SUPPORT_WAPI -+#include "wapi.h" -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * NVRAM structure -+ *------------------------------------------------------------------------------ -+ */ -+#include "CFG_Wifi_File.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "gl_p2p_kal.h" -+#endif -+ -+typedef int (*set_p2p_mode) (struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode); -+typedef void (*set_dbg_level) (unsigned char modules[DBG_MODULE_NUM]); -+ -+extern void wlanRegisterNotifier(void); -+extern void wlanUnregisterNotifier(void); -+extern void register_set_p2p_mode_handler(set_p2p_mode handler); -+extern void register_set_dbg_level_handler(set_dbg_level handler); -+ -+#if CFG_TC1_FEATURE -+#define NIC_INF_NAME_IN_AP_MODE "legacy%d" -+extern volatile int wlan_if_changed; -+#endif -+extern BOOLEAN fgIsResetting; -+ -+extern UINT_8 g_aucBufIpAddr[32]; -+extern UINT_8 aucDebugModule[]; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _PRECOMP_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h -new file mode 100644 -index 0000000000000..40f52dcc9d681 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h -@@ -0,0 +1,141 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/pwr_mgt.h#1 -+*/ -+ -+/*! \file "pwr_mgt.h" -+ \brief In this file we define the STATE and EVENT for Power Management FSM. -+ -+ The SCAN FSM is responsible for performing SCAN behavior when the Arbiter enter -+ ARB_STATE_SCAN. The STATE and EVENT for SCAN FSM are defined here with detail -+ description. -+*/ -+ -+/* -+** Log: pwr_mgt.h -+ * -+ * 07 09 2010 george.huang -+ * -+ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * don't need SPIN_LOCK_PWR_CTRL anymore, it will raise IRQL -+ * and cause SdBusSubmitRequest running at DISPATCH_LEVEL as well. -+ -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * firmware download load address & start address are now configured from config.h -+ * * * due to the different configurations on FPGA and ASIC -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-12-10 16:39:10 GMT mtk02752 -+** disable PM macros temporally -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-10-29 19:48:37 GMT mtk01084 -+** temp remove power management macro -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-08 16:51:11 GMT mtk01084 -+** update for power management control macro -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-03 14:59:58 GMT mtk01426 -+** Add #if CFG_HIF_LOOPBACK_PRETEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-23 16:53:10 GMT mtk01084 -+** modify ACQUIRE_POWER_CONTROL_FROM_PM() and RECLAIM_POWER_CONTROL_TO_PM() macro -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-19 18:32:47 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-03-19 15:05:20 GMT mtk01084 -+** Initial version -+** -+*/ -+ -+#ifndef _PWR_MGT_H -+#define _PWR_MGT_H -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define PM_UAPSD_AC0 (BIT(0)) -+#define PM_UAPSD_AC1 (BIT(1)) -+#define PM_UAPSD_AC2 (BIT(2)) -+#define PM_UAPSD_AC3 (BIT(3)) -+ -+#define PM_UAPSD_ALL (PM_UAPSD_AC0 | PM_UAPSD_AC1 | PM_UAPSD_AC2 | PM_UAPSD_AC3) -+#define PM_UAPSD_NONE 0 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _PM_PROFILE_SETUP_INFO_T { -+ /* Profile setup */ -+ UINT_8 ucBmpDeliveryAC; /* 0: AC_BE, 1: AC_BK, 2: AC_VI, 3: AC_VO */ -+ UINT_8 ucBmpTriggerAC; /* 0: AC_BE, 1: AC_BK, 2: AC_VI, 3: AC_VO */ -+ -+ UINT_8 ucUapsdSp; /* Number of triggered packets in UAPSD */ -+ -+} PM_PROFILE_SETUP_INFO_T, *P_PM_PROFILE_SETUP_INFO_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#if !CFG_ENABLE_FULL_PM -+#define ACQUIRE_POWER_CONTROL_FROM_PM(_prAdapter) -+#define RECLAIM_POWER_CONTROL_TO_PM(_prAdapter, _fgEnableGINT_in_IST) -+#else -+#define ACQUIRE_POWER_CONTROL_FROM_PM(_prAdapter) \ -+ { \ -+ if (_prAdapter->fgIsFwOwn) { \ -+ nicpmSetDriverOwn(_prAdapter); \ -+ } \ -+ /* Increase Block to Enter Low Power Semaphore count */ \ -+ GLUE_INC_REF_CNT(_prAdapter->u4PwrCtrlBlockCnt); \ -+ } -+ -+#define RECLAIM_POWER_CONTROL_TO_PM(_prAdapter, _fgEnableGINT_in_IST) \ -+ { \ -+ ASSERT(_prAdapter->u4PwrCtrlBlockCnt != 0); \ -+ /* Decrease Block to Enter Low Power Semaphore count */ \ -+ GLUE_DEC_REF_CNT(_prAdapter->u4PwrCtrlBlockCnt); \ -+ if (_prAdapter->fgWiFiInSleepyState && (_prAdapter->u4PwrCtrlBlockCnt == 0)) { \ -+ nicpmSetFWOwn(_prAdapter, _fgEnableGINT_in_IST); \ -+ } \ -+ } -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _PWR_MGT_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h -new file mode 100644 -index 0000000000000..a9e74b58a8c97 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h -@@ -0,0 +1,195 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/queue.h#1 -+*/ -+ -+/*! \file queue.h -+ \brief Definition for singly queue operations. -+ -+ In this file we define the singly queue data structure and its -+ queue operation MACROs. -+*/ -+ -+/* -+** Log: queue.h -+ * -+ * 07 16 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * bugfix for SCN migration -+ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue -+ * 2) before AIS issues scan request, network(BSS) needs to be activated first -+ * 3) only invoke COPY_SSID when using specified SSID for scan -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * . -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:46 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _QUEUE_H -+#define _QUEUE_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_typedef.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Singly Queue Structures - Entry Part */ -+typedef struct _QUE_ENTRY_T { -+ struct _QUE_ENTRY_T *prNext; -+ struct _QUE_ENTRY_T *prPrev; /* For Rx buffer reordering used only */ -+} QUE_ENTRY_T, *P_QUE_ENTRY_T; -+ -+/* Singly Queue Structures - Queue Part */ -+typedef struct _QUE_T { -+ P_QUE_ENTRY_T prHead; -+ P_QUE_ENTRY_T prTail; -+ UINT_32 u4NumElem; -+} QUE_T, *P_QUE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/* -+ * To resolve compiler warning of address check -Waddress -+ * Redefine a ASSERT dedicate for queue operation -+ */ -+#if DBG -+#define QUE_ASSERT ASSERT -+#else -+#define QUE_ASSERT(_exp) -+#endif -+ -+#define QUEUE_INITIALIZE(prQueue) \ -+ { \ -+ (prQueue)->prHead = (P_QUE_ENTRY_T)NULL; \ -+ (prQueue)->prTail = (P_QUE_ENTRY_T)NULL; \ -+ (prQueue)->u4NumElem = 0; \ -+ } -+ -+#define QUEUE_IS_EMPTY(prQueue) (((P_QUE_T)(prQueue))->prHead == (P_QUE_ENTRY_T)NULL) -+ -+#define QUEUE_IS_NOT_EMPTY(prQueue) ((prQueue)->u4NumElem > 0) -+ -+#define QUEUE_GET_HEAD(prQueue) ((prQueue)->prHead) -+ -+#define QUEUE_GET_TAIL(prQueue) ((prQueue)->prTail) -+ -+#define QUEUE_GET_NEXT_ENTRY(prQueueEntry) ((prQueueEntry)->prNext) -+ -+#define QUEUE_INSERT_HEAD(prQueue, prQueueEntry) \ -+ { \ -+ QUE_ASSERT(prQueue); \ -+ QUE_ASSERT(prQueueEntry); \ -+ (prQueueEntry)->prNext = (prQueue)->prHead; \ -+ (prQueue)->prHead = (prQueueEntry); \ -+ if ((prQueue)->prTail == (P_QUE_ENTRY_T)NULL) { \ -+ (prQueue)->prTail = (prQueueEntry); \ -+ } \ -+ ((prQueue)->u4NumElem)++; \ -+ } -+ -+#define QUEUE_INSERT_TAIL(prQueue, prQueueEntry) \ -+ { \ -+ QUE_ASSERT(prQueue); \ -+ QUE_ASSERT(prQueueEntry); \ -+ (prQueueEntry)->prNext = (P_QUE_ENTRY_T)NULL; \ -+ if ((prQueue)->prTail) { \ -+ ((prQueue)->prTail)->prNext = (prQueueEntry); \ -+ } else { \ -+ (prQueue)->prHead = (prQueueEntry); \ -+ } \ -+ (prQueue)->prTail = (prQueueEntry); \ -+ ((prQueue)->u4NumElem)++; \ -+ } -+ -+/* NOTE: We assume the queue entry located at the beginning of "prQueueEntry Type", -+ * so that we can cast the queue entry to other data type without doubts. -+ * And this macro also decrease the total entry count at the same time. -+ */ -+#define QUEUE_REMOVE_HEAD(prQueue, prQueueEntry, _P_TYPE) \ -+ { \ -+ QUE_ASSERT(prQueue); \ -+ prQueueEntry = (_P_TYPE)((prQueue)->prHead); \ -+ if (prQueueEntry) { \ -+ (prQueue)->prHead = ((P_QUE_ENTRY_T)(prQueueEntry))->prNext; \ -+ if ((prQueue)->prHead == (P_QUE_ENTRY_T)NULL) { \ -+ (prQueue)->prTail = (P_QUE_ENTRY_T)NULL; \ -+ } \ -+ ((P_QUE_ENTRY_T)(prQueueEntry))->prNext = (P_QUE_ENTRY_T)NULL; \ -+ ((prQueue)->u4NumElem)--; \ -+ } \ -+ } -+ -+#define QUEUE_MOVE_ALL(prDestQueue, prSrcQueue) \ -+ { \ -+ QUE_ASSERT(prDestQueue); \ -+ QUE_ASSERT(prSrcQueue); \ -+ *(P_QUE_T)prDestQueue = *(P_QUE_T)prSrcQueue; \ -+ QUEUE_INITIALIZE(prSrcQueue); \ -+ } -+ -+#define QUEUE_CONCATENATE_QUEUES(prDestQueue, prSrcQueue) \ -+ { \ -+ QUE_ASSERT(prDestQueue); \ -+ QUE_ASSERT(prSrcQueue); \ -+ if (prSrcQueue->u4NumElem > 0) { \ -+ if ((prDestQueue)->prTail) { \ -+ ((prDestQueue)->prTail)->prNext = (prSrcQueue)->prHead; \ -+ } else { \ -+ (prDestQueue)->prHead = (prSrcQueue)->prHead; \ -+ } \ -+ (prDestQueue)->prTail = (prSrcQueue)->prTail; \ -+ ((prDestQueue)->u4NumElem) += ((prSrcQueue)->u4NumElem); \ -+ QUEUE_INITIALIZE(prSrcQueue); \ -+ } \ -+ } -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _QUEUE_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h -new file mode 100644 -index 0000000000000..4489e56013025 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h -@@ -0,0 +1,294 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/rftest.h#1 -+*/ -+ -+/*! \file "rftest.h" -+ \brief definitions for RF Productino test -+ -+*/ -+ -+/* -+** Log: rftest.h -+ * -+ * 12 20 2011 cp.wu -+ * [WCXRP00001144] [MT6620 Wi-Fi][Driver][Firmware] Add RF_FUNC_ID for exposing device and related version information -+ * add driver implementations for RF_AT_FUNCID_FW_INFO & RF_AT_FUNCID_DRV_INFO -+ * to expose version information -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add an extra parameter to rftestQueryATInfo 'cause it's necessary to pass u4FuncData for query request. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * * * and result is retrieved by get ATInfo instead -+ * * * * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-12-08 17:35:11 GMT mtk02752 -+** * comment out RF test which is not supported on MT6620 -+** + API decalre for rftest -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-12-08 11:29:07 GMT mtk02752 -+** definitions for RF test mode -+** -+*/ -+#ifndef _RFTEST_H -+#define _RFTEST_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Table Version */ -+#define RF_AUTO_TEST_FUNCTION_TABLE_VERSION 0x01000001 -+ -+/* Power */ -+#define RF_AT_PARAM_POWER_MASK BITS(0, 7) -+#define RF_AT_PARAM_POWER_MAX RF_AT_PARAM_POWER_MASK -+ -+/* Rate */ -+#define RF_AT_PARAM_RATE_MCS_MASK BIT(31) -+#define RF_AT_PARAM_RATE_MASK BITS(0, 7) -+#define RF_AT_PARAM_RATE_CCK_MAX 3 -+#define RF_AT_PARAM_RATE_1M 0 -+#define RF_AT_PARAM_RATE_2M 1 -+#define RF_AT_PARAM_RATE_5_5M 2 -+#define RF_AT_PARAM_RATE_11M 3 -+#define RF_AT_PARAM_RATE_6M 4 -+#define RF_AT_PARAM_RATE_9M 5 -+#define RF_AT_PARAM_RATE_12M 6 -+#define RF_AT_PARAM_RATE_18M 7 -+#define RF_AT_PARAM_RATE_24M 8 -+#define RF_AT_PARAM_RATE_36M 9 -+#define RF_AT_PARAM_RATE_48M 10 -+#define RF_AT_PARAM_RATE_54M 11 -+ -+/* Antenna */ -+#define RF_AT_PARAM_ANTENNA_ID_MASK BITS(0, 7) -+#define RF_AT_PARAM_ANTENNA_ID_MAX 1 -+ -+/* Packet Length */ -+#define RF_AT_PARAM_TX_80211HDR_BYTE_MAX (32) -+#define RF_AT_PARAM_TX_80211PAYLOAD_BYTE_MAX (2048) -+ -+#define RF_AT_PARAM_TX_PKTLEN_BYTE_DEFAULT 1024 -+#define RF_AT_PARAM_TX_PKTLEN_BYTE_MAX \ -+ ((UINT_16)(RF_AT_PARAM_TX_80211HDR_BYTE_MAX + RF_AT_PARAM_TX_80211PAYLOAD_BYTE_MAX)) -+ -+/* Packet Count */ -+#define RF_AT_PARAM_TX_PKTCNT_DEFAULT 1000 -+#define RF_AT_PARAM_TX_PKTCNT_UNLIMITED 0 -+ -+/* Packet Interval */ -+#define RF_AT_PARAM_TX_PKT_INTERVAL_US_DEFAULT 50 -+ -+/* ALC */ -+#define RF_AT_PARAM_ALC_DISABLE 0 -+#define RF_AT_PARAM_ALC_ENABLE 1 -+ -+/* TXOP */ -+#define RF_AT_PARAM_TXOP_DEFAULT 0 -+#define RF_AT_PARAM_TXOPQUE_QMASK BITS(16, 31) -+#define RF_AT_PARAM_TXOPQUE_TMASK BITS(0, 15) -+#define RF_AT_PARAM_TXOPQUE_AC0 (0<<16) -+#define RF_AT_PARAM_TXOPQUE_AC1 (1<<16) -+#define RF_AT_PARAM_TXOPQUE_AC2 (2<<16) -+#define RF_AT_PARAM_TXOPQUE_AC3 (3<<16) -+#define RF_AT_PARAM_TXOPQUE_AC4 (4<<16) -+#define RF_AT_PARAM_TXOPQUE_QOFFSET 16 -+ -+/* Retry Limit */ -+#define RF_AT_PARAM_TX_RETRY_DEFAULT 0 -+#define RF_AT_PARAM_TX_RETRY_MAX 6 -+ -+/* QoS Queue */ -+#define RF_AT_PARAM_QOSQUE_AC0 0 -+#define RF_AT_PARAM_QOSQUE_AC1 1 -+#define RF_AT_PARAM_QOSQUE_AC2 2 -+#define RF_AT_PARAM_QOSQUE_AC3 3 -+#define RF_AT_PARAM_QOSQUE_AC4 4 -+#define RF_AT_PARAM_QOSQUE_DEFAULT RF_AT_PARAM_QOSQUE_AC0 -+ -+/* Bandwidth */ -+#define RF_AT_PARAM_BANDWIDTH_20MHZ 0 -+#define RF_AT_PARAM_BANDWIDTH_40MHZ 1 -+#define RF_AT_PARAM_BANDWIDTH_U20_IN_40MHZ 2 -+#define RF_AT_PARAM_BANDWIDTH_D20_IN_40MHZ 3 -+#define RF_AT_PARAM_BANDWIDTH_DEFAULT RF_AT_PARAM_BANDWIDTH_20MHZ -+ -+/* GI (Guard Interval) */ -+#define RF_AT_PARAM_GI_800NS 0 -+#define RF_AT_PARAM_GI_400NS 1 -+#define RF_AT_PARAM_GI_DEFAULT RF_AT_PARAM_GI_800NS -+ -+/* STBC */ -+#define RF_AT_PARAM_STBC_DISABLE 0 -+#define RF_AT_PARAM_STBC_ENABLE 1 -+ -+/* RIFS */ -+#define RF_AT_PARAM_RIFS_DISABLE 0 -+#define RF_AT_PARAM_RIFS_ENABLE 1 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Function ID List */ -+typedef enum _ENUM_RF_AT_FUNCID_T { -+ RF_AT_FUNCID_VERSION = 0, -+ RF_AT_FUNCID_COMMAND, -+ RF_AT_FUNCID_POWER, -+ RF_AT_FUNCID_RATE, -+ RF_AT_FUNCID_PREAMBLE, -+ RF_AT_FUNCID_ANTENNA, -+ RF_AT_FUNCID_PKTLEN, -+ RF_AT_FUNCID_PKTCNT, -+ RF_AT_FUNCID_PKTINTERVAL, -+ RF_AT_FUNCID_TEMP_COMPEN, -+ RF_AT_FUNCID_TXOPLIMIT, -+ RF_AT_FUNCID_ACKPOLICY, -+ RF_AT_FUNCID_PKTCONTENT, -+ RF_AT_FUNCID_RETRYLIMIT, -+ RF_AT_FUNCID_QUEUE, -+ RF_AT_FUNCID_BANDWIDTH, -+ RF_AT_FUNCID_GI, -+ RF_AT_FUNCID_STBC, -+ RF_AT_FUNCID_CHNL_FREQ, -+ RF_AT_FUNCID_RIFS, -+ RF_AT_FUNCID_TRSW_TYPE, -+ RF_AT_FUNCID_RF_SX_SHUTDOWN, -+ RF_AT_FUNCID_PLL_SHUTDOWN, -+ RF_AT_FUNCID_SLOW_CLK_MODE, -+ RF_AT_FUNCID_ADC_CLK_MODE, -+ RF_AT_FUNCID_MEASURE_MODE, -+ RF_AT_FUNCID_VOLT_COMPEN, -+ RF_AT_FUNCID_DPD_TX_GAIN, -+ RF_AT_FUNCID_DPD_MODE, -+ RF_AT_FUNCID_TSSI_MODE, -+ RF_AT_FUNCID_TX_GAIN_CODE, -+ RF_AT_FUNCID_TX_PWR_MODE, -+ -+ /* Query command */ -+ RF_AT_FUNCID_TXED_COUNT = 32, -+ RF_AT_FUNCID_TXOK_COUNT, -+ RF_AT_FUNCID_RXOK_COUNT, -+ RF_AT_FUNCID_RXERROR_COUNT, -+ RF_AT_FUNCID_RESULT_INFO, -+ RF_AT_FUNCID_TRX_IQ_RESULT, -+ RF_AT_FUNCID_TSSI_RESULT, -+ RF_AT_FUNCID_DPD_RESULT, -+ RF_AT_FUNCID_RXV_DUMP, -+ RF_AT_FUNCID_RX_PHY_STATIS, -+ RF_AT_FUNCID_MEASURE_RESULT, -+ RF_AT_FUNCID_TEMP_SENSOR, -+ RF_AT_FUNCID_VOLT_SENSOR, -+ RF_AT_FUNCID_READ_EFUSE, -+ RF_AT_FUNCID_RX_RSSI, -+ RF_AT_FUNCID_FW_INFO, -+ RF_AT_FUNCID_DRV_INFO, -+ -+ /* Set command */ -+ RF_AT_FUNCID_SET_DPD_RESULT = 64, -+ RF_AT_FUNCID_SET_CW_MODE, -+ RF_AT_FUNCID_SET_JAPAN_CH14_FILTER, -+ RF_AT_FUNCID_WRITE_EFUSE, -+ RF_AT_FUNCID_SET_MAC_ADDRESS -+} ENUM_RF_AT_FUNCID_T; -+ -+/* Command */ -+typedef enum _ENUM_RF_AT_COMMAND_T { -+ RF_AT_COMMAND_STOPTEST = 0, -+ RF_AT_COMMAND_STARTTX, -+ RF_AT_COMMAND_STARTRX, -+ RF_AT_COMMAND_RESET, -+ RF_AT_COMMAND_OUTPUT_POWER, /* Payload */ -+ RF_AT_COMMAND_LO_LEAKAGE, /* Local freq is renamed to Local leakage */ -+ RF_AT_COMMAND_CARRIER_SUPPR, /* OFDM (LTF/STF), CCK (PI,PI/2) */ -+ RF_AT_COMMAND_TRX_IQ_CAL, -+ RF_AT_COMMAND_TSSI_CAL, -+ RF_AT_COMMAND_DPD_CAL, -+ RF_AT_COMMAND_CW, -+ RF_AT_COMMAND_NUM -+} ENUM_RF_AT_COMMAND_T; -+ -+/* Preamble */ -+typedef enum _ENUM_RF_AT_PREAMBLE_T { -+ RF_AT_PREAMBLE_NORMAL = 0, -+ RF_AT_PREAMBLE_CCK_SHORT, -+ RF_AT_PREAMBLE_11N_MM, -+ RF_AT_PREAMBLE_11N_GF, -+ RF_AT_PREAMBLE_NUM -+} ENUM_RF_AT_PREAMBLE_T; -+ -+/* Ack Policy */ -+typedef enum _ENUM_RF_AT_ACK_POLICY_T { -+ RF_AT_ACK_POLICY_NORMAL = 0, -+ RF_AT_ACK_POLICY_NOACK, -+ RF_AT_ACK_POLICY_NOEXPLICTACK, -+ RF_AT_ACK_POLICY_BLOCKACK, -+ RF_AT_ACK_POLICY_NUM -+} ENUM_RF_AT_ACK_POLICY_T; -+ -+typedef enum _ENUM_RF_AUTOTEST_STATE_T { -+ RF_AUTOTEST_STATE_STANDBY = 0, -+ RF_AUTOTEST_STATE_TX, -+ RF_AUTOTEST_STATE_RX, -+ RF_AUTOTEST_STATE_RESET, -+ RF_AUTOTEST_STATE_OUTPUT_POWER, -+ RF_AUTOTEST_STATE_LOCA_FREQUENCY, -+ RF_AUTOTEST_STATE_CARRIER_SUPRRESION, -+ RF_AUTOTEST_STATE_NUM -+} ENUM_RF_AUTOTEST_STATE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+WLAN_STATUS rftestSetATInfo(IN P_ADAPTER_T prAdapter, UINT_32 u4FuncIndex, UINT_32 u4FuncData); -+ -+WLAN_STATUS -+rftestQueryATInfo(IN P_ADAPTER_T prAdapter, -+ UINT_32 u4FuncIndex, UINT_32 u4FuncData, OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen); -+ -+WLAN_STATUS rftestSetFrequency(IN P_ADAPTER_T prAdapter, IN UINT_32 u4FreqInKHz, IN PUINT_32 pu4SetInfoLen); -+ -+#endif /* _RFTEST_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h -new file mode 100644 -index 0000000000000..8ee184591fc2f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h -@@ -0,0 +1,427 @@ -+/* -+** Id: include/tdls_extr.h#1 -+*/ -+ -+/*! \file "tdls_extr.h" -+ \brief This file contains the external used in other modules -+ for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: tdls_extr.h -+ * -+ * 11 18 2013 vend_samp.lin -+ * NULL -+ * Initial version. -+ * -+ ** -+ */ -+ -+#ifndef _TDLS_EXTR_H -+#define _TDLS_EXTR_H -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#define TDLS_TX_QUOTA_EMPTY_TIMEOUT 10 -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* protocol */ -+#define TDLS_FRM_PROT_TYPE 0x890d -+ -+/* TDLS uses Ethertype 89-0d frames. The UP shall be AC_VI, unless otherwise specified. */ -+#define USER_PRIORITY_TDLS 5 -+ -+/* Status code */ -+#define TDLS_STATUS WLAN_STATUS -+ -+#define TDLS_STATUS_SUCCESS WLAN_STATUS_SUCCESS -+#define TDLS_STATUS_FAILURE WLAN_STATUS_FAILURE -+#define TDLS_STATUS_INVALID_LENGTH WLAN_STATUS_INVALID_LENGTH -+#define TDLS_STATUS_RESOURCES WLAN_STATUS_RESOURCES -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#define TDLS_U32 UINT32 -+#define TDLS_U16 UINT16 -+#define TDLS_U8 UINT8 -+ -+typedef enum _TDLS_REASON_CODE { -+ TDLS_REASON_CODE_UNREACHABLE = 25, -+ TDLS_REASON_CODE_UNSPECIFIED = 26, -+ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_UNKNOWN = 0x80, /* 128 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WIFI_OFF = 0x81, /* 129 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_ROAMING = 0x82, /* 130 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT = 0x83, /* 131 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT = 0x84, /* 132 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY = 0x85, /* 133 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_FAIL = 0x86, /* 134 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_MAX_FAIL = 0x87, /* 135 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WRONG_NETWORK_IDX = 0x88, /* 136 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_NON_STATE3 = 0x89, /* 137 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_TX_QUOTA_EMPTY = 0x8a, /* 138 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_LOST_TEAR_DOWN = 0x8b /* 139 */ -+} TDLS_REASON_CODE; -+ -+/* TDLS FSM */ -+typedef struct _TDLS_CMD_PEER_ADD_T { -+ -+ TDLS_U8 aucPeerMac[6]; -+ -+#if 0 -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ UINT_16 u2CapInfo; -+ -+ UINT_16 u2OperationalRateSet; -+ UINT_16 u2BSSBasicRateSet; -+ BOOLEAN fgIsUnknownBssBasicRate; -+ -+ UINT_8 ucPhyTypeSet; -+#endif -+} TDLS_CMD_PEER_ADD_T; -+ -+typedef struct _TDLS_CMD_LINK_T { -+ -+ TDLS_U8 aucPeerMac[6]; -+ BOOLEAN fgIsEnabled; -+} TDLS_CMD_LINK_T; -+ -+typedef struct _TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T { -+ TDLS_U8 arRxMask[10]; -+ TDLS_U16 u2RxHighest; -+ TDLS_U8 ucTxParams; -+ TDLS_U8 Reserved[3]; -+} TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T; -+ -+typedef struct _TDLS_CMD_PEER_UPDATE_HT_CAP_T { -+ TDLS_U16 u2CapInfo; -+ TDLS_U8 ucAmpduParamsInfo; -+ -+ /* 16 bytes MCS information */ -+ TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T rMCS; -+ -+ TDLS_U16 u2ExtHtCapInfo; -+ TDLS_U32 u4TxBfCapInfo; -+ TDLS_U8 ucAntennaSelInfo; -+} TDLS_CMD_PEER_UPDATE_HT_CAP_T; -+ -+typedef struct _TDLS_CMD_PEER_UPDATE_T { -+ -+ TDLS_U8 aucPeerMac[6]; -+ -+#define TDLS_CMD_PEER_UPDATE_SUP_CHAN_MAX 50 -+ TDLS_U8 aucSupChan[TDLS_CMD_PEER_UPDATE_SUP_CHAN_MAX]; -+ -+ TDLS_U16 u2StatusCode; -+ -+#define TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX 50 -+ TDLS_U8 aucSupRate[TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX]; -+ TDLS_U16 u2SupRateLen; -+ -+ TDLS_U8 UapsdBitmap; -+ TDLS_U8 UapsdMaxSp; /* MAX_SP */ -+ -+ TDLS_U16 u2Capability; -+#define TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN 5 -+ TDLS_U8 aucExtCap[TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN]; -+ TDLS_U16 u2ExtCapLen; -+ -+ TDLS_CMD_PEER_UPDATE_HT_CAP_T rHtCap; -+ BOOLEAN fgIsSupHt; -+ -+} TDLS_CMD_PEER_UPDATE_T; -+ -+/* Command to TDLS core module */ -+typedef enum _TDLS_CMD_CORE_ID { -+ TDLS_CORE_CMD_TEST_NULL_RCV = 0x00, -+ TDLS_CORE_CMD_TEST_PTI_RSP = 0x01, -+ TDLS_CORE_CMD_MIB_UPDATE = 0x02, -+ TDLS_CORE_CMD_TEST_TX_FAIL_SKIP = 0x03, -+ TDLS_CORE_CMD_UAPSD_CONF = 0x04, -+ TDLS_CORE_CMD_TEST_DATA_RCV = 0x05, -+ TDLS_CORE_CMD_TEST_PTI_REQ = 0x06, -+ TDLS_CORE_CMD_TEST_CHSW_REQ = 0x07, -+ TDLS_CORE_CMD_CHSW_CONF = 0x08, -+ TDLS_CORE_CMD_TEST_KEEP_ALIVE_SKIP = 0x09, -+ TDLS_CORE_CMD_TEST_CHSW_TIMEOUT_SKIP = 0x0a, -+ TDLS_CORE_CMD_TEST_CHSW_RSP = 0x0b, -+ TDLS_CORE_CMD_TEST_SCAN_SKIP = 0x0c, -+ TDLS_CORE_CMD_SETUP_CONF = 0x0d, -+ TDLS_CORE_CMD_TEST_TEAR_DOWN = 0x0e, -+ TDLS_CORE_CMD_KEY_INFO = 0x0f, -+ TDLS_CORE_CMD_TEST_PTI_TX_FAIL = 0x10 -+} TDLS_CMD_CORE_ID; -+ -+typedef struct _TDLS_CMD_CORE_TEST_NULL_RCV_T { -+ -+ TDLS_U32 u4PM; -+} TDLS_CMD_CORE_TEST_NULL_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T { -+ -+ TDLS_U32 u4DialogToken; -+} TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T { -+ -+ TDLS_U32 u4DialogToken; -+ TDLS_U32 u4PM; -+} TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T { -+ -+ TDLS_U32 u4ReasonCode; -+} TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T { -+ -+ TDLS_U32 u4Chan; -+ TDLS_U32 u4RegClass; -+ TDLS_U32 u4SecChanOff; -+ TDLS_U32 u4SwitchTime; -+ TDLS_U32 u4SwitchTimeout; -+} TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T { -+ -+ TDLS_U32 u4Chan; -+ TDLS_U32 u4SwitchTime; -+ TDLS_U32 u4SwitchTimeout; -+ TDLS_U32 u4StatusCode; -+} TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_DATA_RCV_T { -+ -+ TDLS_U32 u4PM; -+ TDLS_U32 u4UP; -+ TDLS_U32 u4EOSP; -+ TDLS_U32 u4IsNull; -+} TDLS_CMD_CORE_TEST_DATA_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_MIB_PARAM_UPDATE_T { -+ -+ BOOLEAN Tdlsdot11TunneledDirectLinkSetupImplemented; -+ BOOLEAN Tdlsdot11TDLSPeerUAPSDBufferSTAActivated; -+ BOOLEAN Tdlsdot11TDLSPeerPSMActivated; -+ TDLS_U16 Tdlsdot11TDLSPeerUAPSDIndicationWindow; -+ BOOLEAN Tdlsdot11TDLSChannelSwitchingActivated; -+ TDLS_U8 Tdlsdot11TDLSPeerSTAMissingAckRetryLimit; -+ TDLS_U8 Tdlsdot11TDLSResponseTimeout; -+ TDLS_U16 Tdlsdot11TDLSProbeDelay; -+ TDLS_U8 Tdlsdot11TDLSDiscoveryRequestWindow; -+ TDLS_U8 Tdlsdot11TDLSACDeterminationInterval; -+} TDLS_CMD_CORE_MIB_PARAM_UPDATE_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T { -+ -+ BOOLEAN fgIsEnable; -+} TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T; -+ -+typedef struct _TDLS_CMD_CORE_UAPSD_CONFIG_T { -+ -+ BOOLEAN fgIsSpTimeoutSkip; -+ BOOLEAN fgIsPtiTimeoutSkip; -+} TDLS_CMD_CORE_UAPSD_CONFIG_T; -+ -+typedef struct _TDLS_CMD_CORE_SETUP_CONFIG_T { -+ -+ BOOLEAN fgIs2040Supported; -+} TDLS_CMD_CORE_SETUP_CONFIG_T; -+ -+typedef struct _TDLS_CMD_CORE_CHSW_CONFIG_T { -+ -+ TDLS_U8 ucNetTypeIndex; -+ BOOLEAN fgIsChSwEnabled; -+ BOOLEAN fgIsChSwStarted; -+ TDLS_U8 ucRegClass; -+ TDLS_U8 ucTargetChan; -+ TDLS_U8 ucSecChanOff; -+ BOOLEAN fgIsChSwRegular; -+} TDLS_CMD_CORE_CHSW_CONFIG_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T { -+ -+ BOOLEAN fgIsEnable; -+} TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T { -+ -+ BOOLEAN fgIsEnable; -+} TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_PROHIBIT_T { -+ -+ BOOLEAN fgIsEnable; -+ BOOLEAN fgIsSet; -+} TDLS_CMD_CORE_TEST_PROHIBIT_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_SCAN_SKIP_T { -+ -+ BOOLEAN fgIsEnable; -+} TDLS_CMD_CORE_TEST_SCAN_SKIP_T; -+ -+typedef struct _TDLS_CMD_CORE_INFO_DISPLAY_T { -+ -+ BOOLEAN fgIsToClearAllHistory; -+} TDLS_CMD_CORE_INFO_DISPLAY_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T { -+ -+ BOOLEAN fgIsEnable; -+} TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T; -+ -+typedef struct _TDLS_CMD_CORE_T { -+ -+ TDLS_U32 u4Command; /* TDLS_CMD_CORE_ID */ -+ -+ TDLS_U8 aucPeerMac[6]; -+ TDLS_U8 ucNetTypeIndex; -+ -+#define TDLS_CMD_CORE_RESERVED_SIZE 50 -+ union { -+ TDLS_CMD_CORE_TEST_NULL_RCV_T rCmdNullRcv; -+ TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T rCmdPtiReqRcv; -+ TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T rCmdPtiRspRcv; -+ TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T rCmdTearDownRcv; -+ TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T rCmdChStReqRcv; -+ TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T rCmdChStRspRcv; -+ TDLS_CMD_CORE_TEST_DATA_RCV_T rCmdDatRcv; -+ TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T rCmdTxFailSkip; -+ TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T rCmdKeepAliveSkip; -+ TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T rCmdChSwTimeoutSkip; -+ TDLS_CMD_CORE_TEST_PROHIBIT_T rCmdProhibit; -+ TDLS_CMD_CORE_TEST_SCAN_SKIP_T rCmdScanSkip; -+ TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T rCmdPtiTxFail; -+ -+ TDLS_CMD_CORE_MIB_PARAM_UPDATE_T rCmdMibUpdate; -+ TDLS_CMD_CORE_UAPSD_CONFIG_T rCmdUapsdConf; -+ TDLS_CMD_CORE_CHSW_CONFIG_T rCmdChSwConf; -+ TDLS_CMD_CORE_SETUP_CONFIG_T rCmdSetupConf; -+ TDLS_CMD_CORE_INFO_DISPLAY_T rCmdInfoDisplay; -+ TDLS_U8 Reserved[TDLS_CMD_CORE_RESERVED_SIZE]; -+ } Content; -+} TDLS_CMD_CORE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* -+ assign station record idx for the packet only when STA_STATE_3 -+ Or we will try to send data frame when the TDLS peer's state is STA_STATE_1 -+ EX: -+ 1. mtk_cfg80211_add_station: First create the STA_RECORD_T; -+ 2. TdlsexCfg80211TdlsMgmt: Send a TDLS request frame. -+ 3. mtk_cfg80211_add_station: Change state to STA_STATE_1. -+ 4. TdlsexCfg80211TdlsMgmt: Send a TDLS request frame. -+*/ -+#define TDLSEX_STA_REC_IDX_GET(__prAdapter__, __MsduInfo__) \ -+{ \ -+ STA_RECORD_T *__StaRec__; \ -+ __MsduInfo__->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; \ -+ __StaRec__ = cnmGetStaRecByAddress(__prAdapter__, \ -+ (UINT_8) NETWORK_TYPE_AIS_INDEX, \ -+ __MsduInfo__->aucEthDestAddr); \ -+ if ((__StaRec__ != NULL) && \ -+ ((__StaRec__)->ucStaState == STA_STATE_3) && \ -+ (IS_TDLS_STA(__StaRec__))) { \ -+ __MsduInfo__->ucStaRecIndex = __StaRec__->ucIndex; \ -+ } \ -+} -+ -+/* fill wiphy flag */ -+#define TDLSEX_WIPHY_FLAGS_INIT(__fgFlag__)\ -+{ \ -+ __fgFlag__ |= (WIPHY_FLAG_SUPPORTS_TDLS | WIPHY_FLAG_TDLS_EXTERNAL_SETUP);\ -+} -+ -+/* assign user priority of a TDLS action frame */ -+/* -+ According to 802.11z: Setup req/resp are sent in AC_BK, otherwise we should default -+ to AC_VI. -+*/ -+#define TDLSEX_UP_ASSIGN(__UserPriority__) \ -+{ \ -+ __UserPriority__ = USER_PRIORITY_TDLS; \ -+} -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+int -+TdlsexCfg80211TdlsMgmt(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, u8 action_code, u8 dialog_token, -+ u16 status_code, u32 peer_capability, -+ bool initiator, const u8 *buf, size_t len); -+ -+int TdlsexCfg80211TdlsOper(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, enum nl80211_tdls_operation oper); -+ -+VOID TdlsexCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+VOID TdlsexBssExtCapParse(STA_RECORD_T *prStaRec, UINT_8 *pucIE); -+ -+VOID TdlsexEventHandle(P_GLUE_INFO_T prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); -+ -+TDLS_STATUS TdlsexKeyHandle(ADAPTER_T *prAdapter, PARAM_KEY_T *prNewKey); -+ -+VOID TdlsexInit(ADAPTER_T *prAdapter); -+ -+BOOLEAN TdlsexIsAnyPeerInPowerSave(ADAPTER_T *prAdapter); -+ -+TDLS_STATUS TdlsexLinkCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+VOID -+TdlsexLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, -+ BOOLEAN fgIsTearDown, UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode); -+ -+TDLS_STATUS TdlsexMgmtCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+TDLS_STATUS TdlsexPeerAdd(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen); -+ -+TDLS_STATUS TdlsexPeerUpdate(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen); -+ -+BOOLEAN TdlsexRxFrameDrop(GLUE_INFO_T *prGlueInfo, UINT_8 *pPkt); -+ -+VOID TdlsexRxFrameHandle(GLUE_INFO_T *prGlueInfo, UINT8 *pPkt, UINT16 u2PktLen); -+ -+TDLS_STATUS TdlsexStaRecIdxGet(ADAPTER_T *prAdapter, MSDU_INFO_T *prMsduInfo); -+ -+VOID TdlsexTxQuotaCheck(GLUE_INFO_T *prGlueInfo, STA_RECORD_T *prStaRec, UINT8 FreeQuota); -+ -+VOID TdlsexUninit(ADAPTER_T *prAdapter); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* CFG_SUPPORT_TDLS */ -+ -+#endif /* _TDLS_EXTR_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h -new file mode 100644 -index 0000000000000..7ab62dae8813e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h -@@ -0,0 +1,244 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/typedef.h#1 -+*/ -+ -+/*! \file typedef.h -+ \brief Declaration of data type and return values of internal protocol stack. -+ -+ In this file we declare the data type and return values which will be exported -+ to the GLUE Layer. -+*/ -+ -+/* -+** Log: typedef.h -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 12 30 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * host driver not to set FW-own when there is still pending interrupts -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * integrate . -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add necessary changes to driver data paths. -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add definitions for module migration. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move timer callback to glue layer. -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add cfg80211 interface, which is to replace WE, for further extension -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 02 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add Ethernet destination address information in packet info for TX -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add new API: wlanProcessQueuedPackets() -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 21:41:37 GMT mtk01461 -+** Update PACKET_INFO_INIT for TX Path -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:30:17 GMT mtk01461 -+** Add parameter in PACKET_INFO_T for HIF Loopback -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:25:22 GMT mtk01461 -+** Fix LINT warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:28 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:54 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _TYPEDEF_H -+#define _TYPEDEF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* ieee80211.h of linux has duplicated definitions */ -+#if defined(WLAN_STATUS_SUCCESS) -+#undef WLAN_STATUS_SUCCESS -+#endif -+ -+#define WLAN_STATUS_SUCCESS ((WLAN_STATUS) 0x00000000L) -+#define WLAN_STATUS_PENDING ((WLAN_STATUS) 0x00000103L) -+#define WLAN_STATUS_NOT_ACCEPTED ((WLAN_STATUS) 0x00010003L) -+ -+#define WLAN_STATUS_MEDIA_CONNECT ((WLAN_STATUS) 0x4001000BL) -+#define WLAN_STATUS_MEDIA_DISCONNECT ((WLAN_STATUS) 0x4001000CL) -+#define WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY ((WLAN_STATUS) 0x4001000DL) -+ -+#define WLAN_STATUS_MEDIA_SPECIFIC_INDICATION ((WLAN_STATUS) 0x40010012L) -+ -+#define WLAN_STATUS_SCAN_COMPLETE ((WLAN_STATUS) 0x60010001L) -+#define WLAN_STATUS_MSDU_OK ((WLAN_STATUS) 0x60010002L) -+ -+/* TODO(Kevin): double check if 0x60010001 & 0x60010002 is proprietary */ -+#define WLAN_STATUS_ROAM_OUT_FIND_BEST ((WLAN_STATUS) 0x60010101L) -+#define WLAN_STATUS_ROAM_DISCOVERY ((WLAN_STATUS) 0x60010102L) -+ -+#define WLAN_STATUS_FAILURE ((WLAN_STATUS) 0xC0000001L) -+#define WLAN_STATUS_RESOURCES ((WLAN_STATUS) 0xC000009AL) -+#define WLAN_STATUS_NOT_SUPPORTED ((WLAN_STATUS) 0xC00000BBL) -+ -+#define WLAN_STATUS_MULTICAST_FULL ((WLAN_STATUS) 0xC0010009L) -+#define WLAN_STATUS_INVALID_PACKET ((WLAN_STATUS) 0xC001000FL) -+#define WLAN_STATUS_ADAPTER_NOT_READY ((WLAN_STATUS) 0xC0010011L) -+#define WLAN_STATUS_NOT_INDICATING ((WLAN_STATUS) 0xC0010013L) -+#define WLAN_STATUS_INVALID_LENGTH ((WLAN_STATUS) 0xC0010014L) -+#define WLAN_STATUS_INVALID_DATA ((WLAN_STATUS) 0xC0010015L) -+#define WLAN_STATUS_BUFFER_TOO_SHORT ((WLAN_STATUS) 0xC0010016L) -+ -+#define WLAN_STATUS_BWCS_UPDATE ((WLAN_STATUS) 0xC0010017L) -+ -+#define WLAN_STATUS_CONNECT_INDICATION ((WLAN_STATUS) 0xC0010018L) -+ -+/* NIC status flags */ -+#define ADAPTER_FLAG_HW_ERR 0x00400000 -+ -+/* Type Length */ -+#define TL_IPV4 0x0008 -+#define TL_IPV6 0xDD86 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Type definition for GLUE_INFO structure */ -+typedef struct _GLUE_INFO_T GLUE_INFO_T, *P_GLUE_INFO_T; -+ -+/* Type definition for WLAN STATUS */ -+typedef UINT_32 WLAN_STATUS, *P_WLAN_STATUS; -+ -+/* Type definition for ADAPTER structure */ -+typedef struct _ADAPTER_T ADAPTER_T, *P_ADAPTER_T; -+ -+/* Type definition for MESSAGE HEADER structure */ -+typedef struct _MSG_HDR_T MSG_HDR_T, *P_MSG_HDR_T; -+ -+/* Type definition for WLAN configuration */ -+typedef struct _WLAN_CFG_T WLAN_CFG_T, *P_WLAN_CFG_T; -+ -+/* Type definition for WLAN configuration entry */ -+typedef struct _WLAN_CFG_ENTRY_T WLAN_CFG_ENTRY_T, *P_WLAN_CFG_ENTRY_T; -+ -+/* Type definition for WLAN configuration callback */ -+typedef WLAN_STATUS(*WLAN_CFG_SET_CB) (P_ADAPTER_T prAdapter, -+ PUINT_8 pucKey, PUINT_8 pucValue, PVOID pPrivate, UINT_32 u4Flags); -+ -+/* Type definition for Pointer to OS Native Packet */ -+typedef void *P_NATIVE_PACKET; -+ -+/* Type definition for STA_RECORD_T structure to handle the connectivity and packet reception -+ * for a particular STA. -+ */ -+typedef struct _STA_RECORD_T STA_RECORD_T, *P_STA_RECORD_T, **PP_STA_RECORD_T; -+ -+/* CMD_INFO_T is used by Glue Layer to send a cluster of Command(OID) information to -+ * the TX Path to reduce the parameters of a function call. -+ */ -+typedef struct _CMD_INFO_T CMD_INFO_T, *P_CMD_INFO_T; -+ -+/* Following typedef should be removed later, because Glue Layer should not -+ * be aware of following data type. -+ */ -+typedef struct _SW_RFB_T SW_RFB_T, *P_SW_RFB_T, **PP_SW_RFB_T; -+ -+typedef struct _MSDU_INFO_T MSDU_INFO_T, *P_MSDU_INFO_T; -+ -+typedef struct _REG_ENTRY_T REG_ENTRY_T, *P_REG_ENTRY_T; -+ -+/* IST handler definition */ -+typedef VOID(*IST_EVENT_FUNCTION) (P_ADAPTER_T); -+ -+/* Type definition for function pointer of timer handler */ -+typedef VOID(*PFN_TIMER_CALLBACK) (IN P_GLUE_INFO_T); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _TYPEDEF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h -new file mode 100644 -index 0000000000000..e8937166dc4f3 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h -@@ -0,0 +1,352 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_bow.h#1 -+*/ -+ -+/*! \file "wlan_bow.h" -+ \brief This file contains the declairations of 802.11 PAL -+ command processing routines for -+ MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_bow.h -+ * -+ * 05 25 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add BoW Cancel Scan Request and Turn On deactive network function. -+ * -+ * 05 23 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add some BoW error handling. -+ * -+ * 05 21 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Protect BoW connection establishment. -+ * -+ * 05 17 2011 terry.wu -+ * [WCXRP00000730] [MT6620 Wi-Fi][BoW] Send deauth while disconnecting -+ * Send deauth while disconnecting BoW link. -+ * -+ * 05 06 2011 terry.wu -+ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue -+ * Fix BoW Multiple Physical Link connect/disconnect issue. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support multiple physical link. -+ * -+ * 03 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW table. -+ * -+ * 02 16 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add bowNotifyAllLinkDisconnected interface and change channel grant procedure for bow starting.. -+ * -+ * 02 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update bowString and channel grant. -+ * -+ * 01 11 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update BOW Activity Report structure and bug fix. -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 14 2010 chinghwa.yu -+ * NULL -+ * Add bowRunEventAAAComplete. -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update BOW for the 1st time. -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 15 2010 cp.wu -+ * -+ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * 1) all BT physical handles shares the same RSSI/Link Quality. -+ * 2) simplify BT command composing -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+** -+*/ -+ -+#ifndef _WLAN_BOW_H -+#define _WLAN_BOW_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "nic/bow.h" -+#include "nic/cmd_buf.h" -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ -+#if CFG_BOW_TEST -+extern UINT_32 g_arBowRevPalPacketTime[32]; -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define BOWCMD_STATUS_SUCCESS 0 -+#define BOWCMD_STATUS_FAILURE 1 -+#define BOWCMD_STATUS_UNACCEPTED 2 -+#define BOWCMD_STATUS_INVALID 3 -+#define BOWCMD_STATUS_TIMEOUT 4 -+ -+#define BOW_WILDCARD_SSID "AMP" -+#define BOW_WILDCARD_SSID_LEN 3 -+#define BOW_SSID_LEN 21 -+ -+ /* 0: query, 1: setup, 2: destroy */ -+#define BOW_QUERY_CMD 0 -+#define BOW_SETUP_CMD 1 -+#define BOW_DESTROY_CMD 2 -+ -+#define BOW_INITIATOR 0 -+#define BOW_RESPONDER 1 -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+typedef struct _BOW_TABLE_T { -+ UINT_8 ucAcquireID; -+ BOOLEAN fgIsValid; -+ ENUM_BOW_DEVICE_STATE eState; -+ UINT_8 aucPeerAddress[6]; -+ /* UINT_8 ucRole; */ -+ /* UINT_8 ucChannelNum; */ -+ UINT_16 u2Reserved; -+} BOW_TABLE_T, *P_BOW_TABLE_T; -+ -+typedef WLAN_STATUS(*PFN_BOW_CMD_HANDLE) (P_ADAPTER_T, P_AMPC_COMMAND); -+ -+typedef struct _BOW_CMD_T { -+ UINT_8 uCmdID; -+ PFN_BOW_CMD_HANDLE pfCmdHandle; -+} BOW_CMD_T, *P_BOW_CMD_T; -+ -+typedef struct _BOW_EVENT_ACTIVITY_REPORT_T { -+ UINT_8 ucReason; -+ UINT_8 aucReserved; -+ UINT_8 aucPeerAddress[6]; -+} BOW_EVENT_ACTIVITY_REPORT_T, *P_BOW_EVENT_ACTIVITY_REPORT_T; -+ -+/* -+ucReason: 0: success -+ 1: general failure -+ 2: too much time (> 2/3 second totally) requested for scheduling. -+ Others: reserved. -+*/ -+ -+typedef struct _BOW_EVENT_SYNC_TSF_T { -+ UINT_64 u4TsfTime; -+ UINT_32 u4TsfSysTime; -+ UINT_32 u4ScoTime; -+ UINT_32 u4ScoSysTime; -+} BOW_EVENT_SYNC_TSF_T, *P_BOW_EVENT_SYNC_TSF_T; -+ -+typedef struct _BOW_ACTIVITY_REPORT_BODY_T { -+ UINT_32 u4StartTime; -+ UINT_32 u4Duration; -+ UINT_32 u4Periodicity; -+} BOW_ACTIVITY_REPORT_BODY_T, *P_BOW_ACTIVITY_REPORT_BODY_T; -+ -+typedef struct _BOW_ACTIVITY_REPORT_T { -+ UINT_8 aucPeerAddress[6]; -+ UINT_8 ucScheduleKnown; -+ UINT_8 ucNumReports; -+ BOW_ACTIVITY_REPORT_BODY_T arBowActivityReportBody[MAX_ACTIVITY_REPORT]; -+} BOW_ACTIVITY_REPORT_T, *P_BOW_ACTIVITY_REPORT_T; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*--------------------------------------------------------------*/ -+/* Firmware Command Packer */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendSetQueryBowCmd(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucCID, -+ BOOLEAN fgSetQuery, -+ BOOLEAN fgNeedResp, -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ UINT_32 u4SetQueryInfoLen, PUINT_8 pucInfoBuffer, IN UINT_8 ucSeqNumber); -+ -+/*--------------------------------------------------------------*/ -+/* Command Dispatcher */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS wlanbowHandleCommand(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+/*--------------------------------------------------------------*/ -+/* Routines to handle command */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS bowCmdGetMacStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdSetupConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdDestroyConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdSetPTK(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdReadRSSI(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdShortRangeMode(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdGetChannelList(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+VOID wlanbowCmdEventSetStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd, IN UINT_8 ucEventBuf); -+ -+/*--------------------------------------------------------------*/ -+/* Callbacks for event indication */ -+/*--------------------------------------------------------------*/ -+VOID wlanbowCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdEventLinkConnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdEventLinkDisconnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdEventSetSetupConnection(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdEventReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdEventReadRssi(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdTimeoutHandler(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+VOID bowStopping(IN P_ADAPTER_T prAdapter); -+ -+VOID bowStarting(IN P_ADAPTER_T prAdapter); -+ -+VOID bowAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 pucSsidLen); -+ -+BOOLEAN bowValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); -+ -+VOID bowSendBeacon(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID bowResponderScan(IN P_ADAPTER_T prAdapter); -+ -+VOID bowResponderScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID bowResponderCancelScan(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtention); -+ -+VOID bowResponderJoin(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); -+ -+VOID bowFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID -+bowIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, -+ ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication); -+ -+VOID bowRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS bowRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS bowRunEventRxDeAuth(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); -+ -+VOID bowDisconnectLink(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+BOOLEAN bowValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); -+ -+BOOLEAN -+bowValidateAuth(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode); -+ -+VOID bowRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID bowRequestCh(IN P_ADAPTER_T prAdapter); -+ -+VOID bowReleaseCh(IN P_ADAPTER_T prAdapter); -+ -+VOID bowChGrantedTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam); -+ -+BOOLEAN bowNotifyAllLinkDisconnected(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN bowCheckBowTableIfVaild(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]); -+ -+BOOLEAN bowGetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, OUT P_BOW_TABLE_T prBowTable); -+ -+BOOLEAN -+bowGetBowTableEntryByPeerAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], OUT PUINT_8 pucBowTableIdx); -+ -+BOOLEAN bowGetBowTableFreeEntry(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucBowTableIdx); -+ -+ENUM_BOW_DEVICE_STATE bowGetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]); -+ -+BOOLEAN bowSetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], IN ENUM_BOW_DEVICE_STATE eState); -+ -+BOOLEAN bowSetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, IN P_BOW_TABLE_T prBowTable); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -+#endif /* _WLAN_BOW_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h -new file mode 100644 -index 0000000000000..87259397a93d1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h -@@ -0,0 +1,1001 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_lib.h#1 -+*/ -+ -+/*! \file "wlan_lib.h" -+ \brief The declaration of the functions of the wlanAdpater objects -+ -+ Detail description. -+*/ -+ -+/* -+** Log: wlan_lib.h -+ * -+ * 06 08 2012 eason.tsai -+ * NULL -+ * Nvram context covert from 6620 to 6628 for old 6620 meta tool -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for -+ * preferred band configuration with corresponding network configuration -+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for -+ * setting preferred band configuration corresponding to network type. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * eliminate win32 native data types. -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware download path in divided scatters. -+ * -+ * 10 03 2011 cp.wu -+ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware downloading aggregated path. -+ * -+ * 09 20 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * change window registry of driver for roaming. -+ * -+ * 09 08 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 08 25 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add DFS switch. -+ * -+ * 08 24 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Update RDD test mode cases. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms. -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, -+ * TX deauth to a disconnecting device issue. -+ * Fix GO send deauth frame issue. -+ * -+ * 07 22 2011 jeffrey.chang -+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time -+ * modify driver to set OSC stable time after f/w download -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 05 27 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. -+ * -+ * 05 11 2011 cp.wu -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. -+ * -+ * 04 18 2011 cp.wu -+ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) -+ * 1) add API for glue layer to query ACPI state -+ * 2) Windows glue should not access to hardware after switched into D3 state -+ * -+ * 03 10 2011 cp.wu -+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 -+ * deprecate configuration used by MT6620 E2 -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 27 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Support current measure mode, assigned by registry (XP only). -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result -+ * in OID handling layer when the corresponding BSS is disconnected due to beacon timeout -+ * remove from scanning result when the BSS is disconnected due to beacon timeout. -+ * -+ * 10 27 2010 george.huang -+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to -+ * disable Beacon Timeout function for SQA test by using E1 EVB -+ * Support registry option for disable beacon lost detection. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 26 2010 eddie.chen -+ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB -+ * Add auto rate parameter in registry. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * divide a single function into 2 part to surpress a weird compiler warning from gcc-4.4.0 -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature -+ * Modify online scan as a run-time adjustable option (for Windows, in registry) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item -+ * use firmware reported mac address right after wlanAdapterStart() as permanent address -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add AT GO test configure mode under WinXP. -+ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * . -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid -+ * descriptor underflow under concurrent network operation -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change MAC address updating logic. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * simplify timer usage. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add extra 64 adjustable parameters for CoEX scenario. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) for some OID, never do timeout expiration -+ * * 2) add 2 kal API for later integration -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change to use WIFI_TCM_ALWAYS_ON as firmware image -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always send CMD_NIC_POWER_CTRL packet when nic is being halted -+ * -+ * 03 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add two option for ACK and ENCRYPTION for firmware download -+ * -+ * 02 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * separate wlanProcesQueuePacket() into 2 APIs upon request -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add new API: wlanProcessQueuedPackets() -+ * -+ * 02 11 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. add logic for firmware download -+ * * * 2. firmware image filename and start/load address are now retrieved from registry -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * * * * 2) firmware image length is now retrieved via NdisFileOpen -+ * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * * * * 4) nicRxWaitResponse() revised -+ * * * * 5) another set of TQ counter default value is added for fw-download state -+ * * * * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * * * * 4. correct some HAL implementation -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:39:55 GMT mtk02752 -+** eliminate unused API -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:58:41 GMT mtk01084 -+** update for new macro define -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-19 10:43:06 GMT mtk01461 -+** Add wlanReleasePendingOid() -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-13 16:38:44 GMT mtk01084 -+** add WIFI start function -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-08 16:51:14 GMT mtk01084 -+** Update for the image download part -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:57:38 GMT mtk01461 -+** Add wlanSendLeftClusteredFrames() for SDIO_TX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 00:31:02 GMT mtk01461 -+** Add declaration of FW Image download reference code -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:31 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:12:04 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _WLAN_LIB_H -+#define _WLAN_LIB_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "CFG_Wifi_File.h" -+#include "rlm_domain.h" -+#include "wlan_typedef.h" -+ -+ -+extern BOOLEAN fgIsResetting; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define MAX_NUM_GROUP_ADDR 32 /* max number of group addresses */ -+ -+#define TX_CS_TCP_UDP_GEN BIT(1) -+#define TX_CS_IP_GEN BIT(0) -+ -+#define CSUM_OFFLOAD_EN_TX_TCP BIT(0) -+#define CSUM_OFFLOAD_EN_TX_UDP BIT(1) -+#define CSUM_OFFLOAD_EN_TX_IP BIT(2) -+#define CSUM_OFFLOAD_EN_RX_TCP BIT(3) -+#define CSUM_OFFLOAD_EN_RX_UDP BIT(4) -+#define CSUM_OFFLOAD_EN_RX_IPv4 BIT(5) -+#define CSUM_OFFLOAD_EN_RX_IPv6 BIT(6) -+#define CSUM_OFFLOAD_EN_TX_MASK BITS(0, 2) -+#define CSUM_OFFLOAD_EN_ALL BITS(0, 6) -+ -+/* TCP, UDP, IP Checksum */ -+#define RX_CS_TYPE_UDP BIT(7) -+#define RX_CS_TYPE_TCP BIT(6) -+#define RX_CS_TYPE_IPv6 BIT(5) -+#define RX_CS_TYPE_IPv4 BIT(4) -+ -+#define RX_CS_STATUS_UDP BIT(3) -+#define RX_CS_STATUS_TCP BIT(2) -+#define RX_CS_STATUS_IP BIT(0) -+ -+#define CSUM_NOT_SUPPORTED 0x0 -+ -+#define TXPWR_USE_PDSLOPE 0 -+ -+/* NVRAM error code definitions */ -+#define NVRAM_ERROR_VERSION_MISMATCH BIT(1) -+#define NVRAM_ERROR_INVALID_TXPWR BIT(2) -+#define NVRAM_ERROR_INVALID_DPD BIT(3) -+#define NVRAM_ERROR_INVALID_MAC_ADDR BIT(4) -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+#define NVRAM_POWER_LIMIT_TABLE_INVALID BIT(5) -+#endif -+ -+#define NUM_TC_RESOURCE_TO_STATISTICS 4 -+ -+#define WLAN_CFG_ARGV_MAX 8 -+#define WLAN_CFG_ENTRY_NUM_MAX 128 -+#define WLAN_CFG_KEY_LEN_MAX 32 /* include \x00 EOL */ -+#define WLAN_CFG_VALUE_LEN_MAX 32 /* include \x00 EOL */ -+#define WLAN_CFG_FLAG_SKIP_CB BIT(0) -+#define WLAN_CFG_FILE_BUF_SIZE 2048 -+ -+#define WLAN_CFG_SET_CHIP_LEN_MAX 10 -+#define WLAN_CFG_SET_DEBUG_LEVEL_LEN_MAX 10 -+#define WLAN_CFG_SET_SW_CTRL_LEN_MAX 10 -+ -+#define WLAN_OID_TIMEOUT_THRESHOLD 2000 /* OID timeout (in ms) */ -+#define WLAN_OID_TIMEOUT_THRESHOLD_IN_RESETTING 300 /* OID timeout during chip-resetting (in ms) */ -+ -+#define WLAN_OID_NO_ACK_THRESHOLD 3 -+ -+#define WLAN_TX_THREAD_TASK_PRIORITY 0 /* If not setting the priority, 0 is the default */ -+#define WLAN_TX_THREAD_TASK_NICE (-10) /* If not setting the nice, -10 is the default */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef WLAN_STATUS(*PFN_OID_HANDLER_FUNC) (IN P_ADAPTER_T prAdapter, -+ IN PVOID pvBuf, IN UINT_32 u4BufLen, OUT PUINT_32 pu4OutInfoLen); -+ -+typedef enum _ENUM_CSUM_TYPE_T { -+ CSUM_TYPE_IPV4, -+ CSUM_TYPE_IPV6, -+ CSUM_TYPE_TCP, -+ CSUM_TYPE_UDP, -+ CSUM_TYPE_NUM -+} ENUM_CSUM_TYPE_T, *P_ENUM_CSUM_TYPE_T; -+ -+typedef enum _ENUM_CSUM_RESULT_T { -+ CSUM_RES_NONE, -+ CSUM_RES_SUCCESS, -+ CSUM_RES_FAILED, -+ CSUM_RES_NUM -+} ENUM_CSUM_RESULT_T, *P_ENUM_CSUM_RESULT_T; -+ -+typedef enum _ENUM_PHY_MODE_T { -+ ENUM_PHY_2G4_CCK, -+ ENUM_PHY_2G4_OFDM_BPSK, -+ ENUM_PHY_2G4_OFDM_QPSK, -+ ENUM_PHY_2G4_OFDM_16QAM, -+ ENUM_PHY_2G4_OFDM_48M, -+ ENUM_PHY_2G4_OFDM_54M, -+ ENUM_PHY_2G4_HT20_BPSK, -+ ENUM_PHY_2G4_HT20_QPSK, -+ ENUM_PHY_2G4_HT20_16QAM, -+ ENUM_PHY_2G4_HT20_MCS5, -+ ENUM_PHY_2G4_HT20_MCS6, -+ ENUM_PHY_2G4_HT20_MCS7, -+ ENUM_PHY_2G4_HT40_BPSK, -+ ENUM_PHY_2G4_HT40_QPSK, -+ ENUM_PHY_2G4_HT40_16QAM, -+ ENUM_PHY_2G4_HT40_MCS5, -+ ENUM_PHY_2G4_HT40_MCS6, -+ ENUM_PHY_2G4_HT40_MCS7, -+ ENUM_PHY_5G_OFDM_BPSK, -+ ENUM_PHY_5G_OFDM_QPSK, -+ ENUM_PHY_5G_OFDM_16QAM, -+ ENUM_PHY_5G_OFDM_48M, -+ ENUM_PHY_5G_OFDM_54M, -+ ENUM_PHY_5G_HT20_BPSK, -+ ENUM_PHY_5G_HT20_QPSK, -+ ENUM_PHY_5G_HT20_16QAM, -+ ENUM_PHY_5G_HT20_MCS5, -+ ENUM_PHY_5G_HT20_MCS6, -+ ENUM_PHY_5G_HT20_MCS7, -+ ENUM_PHY_5G_HT40_BPSK, -+ ENUM_PHY_5G_HT40_QPSK, -+ ENUM_PHY_5G_HT40_16QAM, -+ ENUM_PHY_5G_HT40_MCS5, -+ ENUM_PHY_5G_HT40_MCS6, -+ ENUM_PHY_5G_HT40_MCS7, -+ ENUM_PHY_MODE_NUM -+} ENUM_PHY_MODE_T, *P_ENUM_PHY_MODE_T; -+ -+typedef enum _ENUM_POWER_SAVE_POLL_MODE_T { -+ ENUM_POWER_SAVE_POLL_DISABLE, -+ ENUM_POWER_SAVE_POLL_LEGACY_NULL, -+ ENUM_POWER_SAVE_POLL_QOS_NULL, -+ ENUM_POWER_SAVE_POLL_NUM -+} ENUM_POWER_SAVE_POLL_MODE_T, *P_ENUM_POWER_SAVE_POLL_MODE_T; -+ -+typedef enum _ENUM_AC_TYPE_T { -+ ENUM_AC_TYPE_AC0, -+ ENUM_AC_TYPE_AC1, -+ ENUM_AC_TYPE_AC2, -+ ENUM_AC_TYPE_AC3, -+ ENUM_AC_TYPE_AC4, -+ ENUM_AC_TYPE_AC5, -+ ENUM_AC_TYPE_AC6, -+ ENUM_AC_TYPE_BMC, -+ ENUM_AC_TYPE_NUM -+} ENUM_AC_TYPE_T, *P_ENUM_AC_TYPE_T; -+ -+typedef enum _ENUM_ADV_AC_TYPE_T { -+ ENUM_ADV_AC_TYPE_RX_NSW, -+ ENUM_ADV_AC_TYPE_RX_PTA, -+ ENUM_ADV_AC_TYPE_RX_SP, -+ ENUM_ADV_AC_TYPE_TX_PTA, -+ ENUM_ADV_AC_TYPE_TX_RSP, -+ ENUM_ADV_AC_TYPE_NUM -+} ENUM_ADV_AC_TYPE_T, *P_ENUM_ADV_AC_TYPE_T; -+ -+typedef enum _ENUM_REG_CH_MAP_T { -+ REG_CH_MAP_COUNTRY_CODE, -+ REG_CH_MAP_TBL_IDX, -+ REG_CH_MAP_CUSTOMIZED, -+ REG_CH_MAP_NUM -+} ENUM_REG_CH_MAP_T, *P_ENUM_REG_CH_MAP_T; -+ -+#define CHIP_CONFIG_RESP_SIZE 320 -+enum { -+ CHIP_CONFIG_TYPE_WO_RESPONSE = 0x00, -+ CHIP_CONFIG_TYPE_MEM8 = 0x01, -+ CHIP_CONFIG_TYPE_MEM32 = 0x02, -+ CHIP_CONFIG_TYPE_ASCII = 0x03, -+ CHIP_CONFIG_TYPE_BINARY = 0x04, -+ CHIP_CONFIG_TYPE_DRV_PASSTHROUGH = 0x05, -+ CHIP_CONFIG_TYPE_END -+}; -+ -+typedef struct _SET_TXPWR_CTRL_T { -+ INT_8 c2GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ -+ INT_8 c2GHotspotPwrOffset; -+ INT_8 c2GP2pPwrOffset; -+ INT_8 c2GBowPwrOffset; -+ INT_8 c5GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ -+ INT_8 c5GHotspotPwrOffset; -+ INT_8 c5GP2pPwrOffset; -+ INT_8 c5GBowPwrOffset; -+ UINT_8 ucConcurrencePolicy; /* TX power policy when concurrence -+ in the same channel -+ 0: Highest power has priority -+ 1: Lowest power has priority */ -+ INT_8 acReserved1[3]; /* Must be zero */ -+ -+ /* Power limit by channel for all data rates */ -+ INT_8 acTxPwrLimit2G[14]; /* Channel 1~14, Unit: 0.5dBm */ -+ INT_8 acTxPwrLimit5G[4]; /* UNII 1~4 */ -+ INT_8 acReserved2[2]; /* Must be zero */ -+} SET_TXPWR_CTRL_T, *P_SET_TXPWR_CTRL_T; -+ -+/* For storing driver initialization value from glue layer */ -+typedef struct _REG_INFO_T { -+ UINT_32 u4SdBlockSize; /* SDIO block size */ -+ UINT_32 u4SdBusWidth; /* SDIO bus width. 1 or 4 */ -+ UINT_32 u4SdClockRate; /* SDIO clock rate. (in unit of HZ) */ -+ UINT_32 u4StartAddress; /* Starting address of Wi-Fi Firmware */ -+ UINT_32 u4LoadAddress; /* Load address of Wi-Fi Firmware */ -+ UINT_16 aucFwImgFilename[65]; /* Firmware filename */ -+ UINT_16 aucFwImgFilenameE6[65]; /* Firmware filename for E6 */ -+ UINT_32 u4StartFreq; /* Start Frequency for Ad-Hoc network : in unit of KHz */ -+ UINT_32 u4AdhocMode; /* Default mode for Ad-Hoc network : ENUM_PARAM_AD_HOC_MODE_T */ -+ UINT_32 u4RddStartFreq; -+ UINT_32 u4RddStopFreq; -+ UINT_32 u4RddTestMode; -+ UINT_32 u4RddShutFreq; -+ UINT_32 u4RddDfs; -+ INT_32 i4HighRssiThreshold; -+ INT_32 i4MediumRssiThreshold; -+ INT_32 i4LowRssiThreshold; -+ INT_32 au4TxPriorityTag[ENUM_AC_TYPE_NUM]; -+ INT_32 au4RxPriorityTag[ENUM_AC_TYPE_NUM]; -+ INT_32 au4AdvPriorityTag[ENUM_ADV_AC_TYPE_NUM]; -+ UINT_32 u4FastPSPoll; -+ UINT_32 u4PTA; /* 0: disable, 1: enable */ -+ UINT_32 u4TXLimit; /* 0: disable, 1: enable */ -+ UINT_32 u4SilenceWindow; /* range: 100 - 625, unit: us */ -+ UINT_32 u4TXLimitThreshold; /* range: 250 - 1250, unit: us */ -+ UINT_32 u4PowerMode; -+ UINT_32 fgEnArpFilter; -+ UINT_32 u4PsCurrentMeasureEn; -+ UINT_32 u4UapsdAcBmp; -+ UINT_32 u4MaxSpLen; -+ UINT_32 fgDisOnlineScan; /* 0: enable online scan, non-zero: disable online scan */ -+ UINT_32 fgDisBcnLostDetection; /* 0: enable online scan, non-zero: disable online scan */ -+ UINT_32 u4FixedRate; /* 0: automatic, non-zero: fixed rate */ -+ UINT_32 u4ArSysParam0; -+ UINT_32 u4ArSysParam1; -+ UINT_32 u4ArSysParam2; -+ UINT_32 u4ArSysParam3; -+ UINT_32 fgDisRoaming; /* 0:enable roaming 1:disable */ -+ -+ /* NVRAM - MP Data -START- */ -+ UINT_8 aucMacAddr[6]; -+ UINT_16 au2CountryCode[4]; /* Country code (in ISO 3166-1 expression, ex: "US", "TW") */ -+ TX_PWR_PARAM_T rTxPwr; -+ UINT_8 aucEFUSE[144]; -+ UINT_8 ucTxPwrValid; -+ UINT_8 ucSupport5GBand; -+ UINT_8 fg2G4BandEdgePwrUsed; -+ INT_8 cBandEdgeMaxPwrCCK; -+ INT_8 cBandEdgeMaxPwrOFDM20; -+ INT_8 cBandEdgeMaxPwrOFDM40; -+ ENUM_REG_CH_MAP_T eRegChannelListMap; -+ UINT_8 ucRegChannelListIndex; -+ DOMAIN_INFO_ENTRY rDomainInfo; -+ /* NVRAM - MP Data -END- */ -+ -+ /* NVRAM - Functional Data -START- */ -+ UINT_8 uc2G4BwFixed20M; -+ UINT_8 uc5GBwFixed20M; -+ UINT_8 ucEnable5GBand; -+ UINT_8 uc2GRssiCompensation; -+ UINT_8 uc5GRssiCompensation; -+ UINT_8 fgRssiCompensationValidbit; -+ UINT_8 ucRxAntennanumber; -+ /* NVRAM - Functional Data -END- */ -+ -+} REG_INFO_T, *P_REG_INFO_T; -+ -+/* for divided firmware loading */ -+typedef struct _FWDL_SECTION_INFO_T { -+ UINT_32 u4Offset; -+ UINT_32 u4Reserved; -+ UINT_32 u4Length; -+ UINT_32 u4DestAddr; -+} FWDL_SECTION_INFO_T, *P_FWDL_SECTION_INFO_T; -+ -+typedef struct _FIRMWARE_DIVIDED_DOWNLOAD_T { -+ UINT_32 u4Signature; -+ UINT_32 u4CRC; /* CRC calculated without first 8 bytes included */ -+ UINT_32 u4NumOfEntries; -+ UINT_32 u4Reserved; -+ FWDL_SECTION_INFO_T arSection[]; -+} FIRMWARE_DIVIDED_DOWNLOAD_T, *P_FIRMWARE_DIVIDED_DOWNLOAD_T; -+ -+typedef struct _PARAM_MCR_RW_STRUCT_T { -+ UINT_32 u4McrOffset; -+ UINT_32 u4McrData; -+} PARAM_MCR_RW_STRUCT_T, *P_PARAM_MCR_RW_STRUCT_T; -+ -+typedef struct _PARAM_GET_STA_STATISTICS { -+ UINT_8 ucInvalid; -+ UINT_8 ucVersion; -+ /* Per-STA statistic */ -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+ UINT_32 u4LinkScore; -+ UINT_32 u4Flag; -+ -+ /* From FW */ -+ UINT_8 ucPer; /* base: 128 */ -+ UINT_8 ucRcpi; -+ UINT_32 u4PhyMode; -+ UINT_16 u2LinkSpeed; /* unit is 0.5 Mbits */ -+ -+ UINT_32 u4TxFailCount; -+ UINT_32 u4TxLifeTimeoutCount; -+ UINT_32 u4TxAverageAirTime; -+ -+ /* From driver */ -+ UINT_32 u4TxTotalCount; -+ UINT_32 u4TxExceedThresholdCount; -+ UINT_32 u4TxAverageProcessTime; -+ -+ UINT_32 u4TxMaxTime; -+ UINT_32 u4TxMaxHifTime; -+ UINT_32 u4TxAverageHifTime; -+ -+ /* -+ * How many packages Enqueue/Deqeue during statistics interval -+ */ -+ UINT_32 u4EnqueueCounter; -+ UINT_32 u4DequeueCounter; -+ -+ UINT_32 u4EnqueueStaCounter; -+ UINT_32 u4DequeueStaCounter; -+ -+ UINT_32 IsrCnt; -+ UINT_32 IsrPassCnt; -+ UINT_32 TaskIsrCnt; -+ -+ UINT_32 IsrAbnormalCnt; -+ UINT_32 IsrSoftWareCnt; -+ UINT_32 IsrRxCnt; -+ UINT_32 IsrTxCnt; -+ -+ UINT_32 au4TcResourceEmptyCount[NUM_TC_RESOURCE_TO_STATISTICS]; -+ UINT_32 au4DequeueNoTcResource[NUM_TC_RESOURCE_TO_STATISTICS]; -+ UINT_32 au4TcResourceBackCount[NUM_TC_RESOURCE_TO_STATISTICS]; -+ -+ UINT_32 au4TcResourceUsedCount[NUM_TC_RESOURCE_TO_STATISTICS]; -+ UINT_32 au4TcResourceWantedCount[NUM_TC_RESOURCE_TO_STATISTICS]; -+ -+ UINT_32 au4TcQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; -+ /* Global queue management statistic */ -+ UINT_32 au4TcAverageQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; -+ UINT_32 au4TcCurrentQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; -+ -+ /* Reserved fields */ -+ UINT_8 au4Reserved[32]; -+} PARAM_GET_STA_STA_STATISTICS, *P_PARAM_GET_STA_STATISTICS; -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+typedef enum _ENUM_TESTMODE_AVAILABLE_CHAN_ATTR { -+ NL80211_TESTMODE_AVAILABLE_CHAN_INVALID = 0, -+ NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, -+ -+ NL80211_TESTMODE_AVAILABLE_CHAN_NUM, -+} ENUM_TESTMODE_AVAILABLE_CHAN_ATTR; -+ -+typedef struct _LTE_SAFE_CH_INFO_T { -+ UINT_32 au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_NUM - 1]; -+} LTE_SAFE_CH_INFO_T, *P_CMD_LTE_SAFE_CH_INFO_T; -+ -+ /* Record Each CH Load */ -+typedef struct _PARAM_CHN_LOAD_INFO { -+ /* Per-CHN Load */ -+ UINT_32 u4Flag; -+ -+ UINT_8 ucChannel; -+ UINT_16 u2ChannelLoad; -+ UINT_8 au4Reserved[1]; -+ -+ UINT_16 u2APNum; -+ UINT_16 u2APNumTmpCountingBuf; -+ -+ /* Reserved fields */ -+ UINT_8 au4Reserved1[8]; -+} PARAM_CHN_LOAD_INFO, *P_PARAM_CHN_LOAD_INFO; -+ -+typedef struct _PARAM_GET_CHN_LOAD { -+ LTE_SAFE_CH_INFO_T rLteSafeChnList; -+ PARAM_CHN_LOAD_INFO rEachChnLoad[MAX_AUTO_CHAL_NUM]; -+ BOOLEAN fgDataReadyBit; -+ UINT_8 au4Reserved1[3]; -+} PARAM_GET_CHN_LOAD, *P_PARAM_GET_CHN_LOAD; -+ -+typedef struct _PARAM_PREFER_CHN_INFO { -+ -+ UINT_8 ucChannel; -+ UINT_16 u2APNum; -+ UINT_8 au4Reserved1[1]; -+} PARAM_PREFER_CHN_INFO, *P_PARAM_PREFER_CHN_INFO; -+ -+typedef struct _PARAM_GET_LTE_MODE { -+ /* Event Body */ -+ UINT_8 ucVersion; -+ UINT_8 aucReserved1[3]; -+ UINT_32 u4Flags; /* Bit0: valid */ -+ -+ LTE_SAFE_CH_INFO_T LTE_MODE; -+ UINT_8 aucReserved4[3]; -+ -+ UINT_8 aucReserved[4]; -+ -+} PARAM_GET_LTE_MODE, *P_PARAM_GET_LTE_MODE; -+ -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define BUILD_SIGN(ch0, ch1, ch2, ch3) \ -+ ((UINT_32)(UINT_8)(ch0) | ((UINT_32)(UINT_8)(ch1) << 8) | \ -+ ((UINT_32)(UINT_8)(ch2) << 16) | ((UINT_32)(UINT_8)(ch3) << 24)) -+ -+#define MTK_WIFI_SIGNATURE BUILD_SIGN('M', 'T', 'K', 'W') -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+P_ADAPTER_T wlanAdapterCreate(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID wlanAdapterDestroy(IN P_ADAPTER_T prAdapter); -+ -+VOID wlanCardEjected(IN P_ADAPTER_T prAdapter); -+ -+VOID wlanIST(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN wlanISR(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgGlobalIntrCtrl); -+ -+WLAN_STATUS wlanProcessCommandQueue(IN P_ADAPTER_T prAdapter, IN P_QUE_T prCmdQue); -+ -+WLAN_STATUS wlanSendCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+VOID wlanReleaseCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+VOID wlanReleasePendingOid(IN P_ADAPTER_T prAdapter, IN ULONG ulData); -+ -+VOID wlanReleasePendingCMDbyNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType); -+ -+VOID wlanReturnPacket(IN P_ADAPTER_T prAdapter, IN PVOID pvPacket); -+ -+VOID wlanReturnIndicatedPacketsTimeOut(IN P_ADAPTER_T prAdapter, IN ULONG ulData); -+ -+WLAN_STATUS -+wlanQueryInformation(IN P_ADAPTER_T prAdapter, -+ IN PFN_OID_HANDLER_FUNC pfOidQryHandler, -+ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4QryInfoLen); -+ -+WLAN_STATUS -+wlanSetInformation(IN P_ADAPTER_T prAdapter, -+ IN PFN_OID_HANDLER_FUNC pfOidSetHandler, -+ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanAdapterStart(IN P_ADAPTER_T prAdapter, -+ IN P_REG_INFO_T prRegInfo, IN PVOID pvFwImageMapFile, IN UINT_32 u4FwImageFileLength); -+ -+WLAN_STATUS wlanAdapterStop(IN P_ADAPTER_T prAdapter); -+ -+#if CFG_SUPPORT_WAPI -+BOOLEAN wlanQueryWapiMode(IN P_ADAPTER_T prAdapter); -+#endif -+ -+VOID wlanReturnRxPacket(IN PVOID pvAdapter, IN PVOID pvPacket); -+ -+VOID wlanRxSetBroadcast(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableBroadcast); -+ -+BOOLEAN wlanIsHandlerNeedHwAccess(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo); -+ -+VOID wlanSetPromiscuousMode(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnablePromiscuousMode); -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+WLAN_STATUS -+wlanImageSectionDownloadAggregated(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf); -+#endif -+ -+WLAN_STATUS -+wlanImageSectionDownload(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf); -+ -+#if !CFG_ENABLE_FW_DOWNLOAD_ACK -+WLAN_STATUS wlanImageQueryStatus(IN P_ADAPTER_T prAdapter); -+#else -+WLAN_STATUS wlanImageSectionDownloadStatus(IN P_ADAPTER_T prAdapter, IN UINT_8 ucCmdSeqNum); -+#endif -+ -+WLAN_STATUS wlanConfigWifiFunc(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable, IN UINT_32 u4StartAddress); -+ -+UINT_32 wlanCRC32(PUINT_8 buf, UINT_32 len); -+ -+#endif -+ -+WLAN_STATUS wlanSendNicPowerCtrlCmd(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPowerMode); -+ -+BOOLEAN wlanIsHandlerAllowedInRFTest(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo); -+ -+WLAN_STATUS wlanProcessQueuedSwRfb(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead); -+ -+WLAN_STATUS wlanProcessQueuedMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); -+ -+BOOLEAN wlanoidTimeoutCheck(IN P_ADAPTER_T prAdapter, IN PFN_OID_HANDLER_FUNC pfnOidHandler); -+ -+VOID wlanoidClearTimeoutCheck(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS wlanUpdateNetworkAddress(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN wlanQueryTestMode(IN P_ADAPTER_T prAdapter); -+ -+/* Security Frame Handling */ -+BOOLEAN wlanProcessSecurityFrame(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prPacket); -+ -+VOID wlanSecurityFrameTxDone(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanSecurityFrameTxTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* OID/IOCTL Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID wlanClearScanningResult(IN P_ADAPTER_T prAdapter); -+ -+VOID wlanClearBssInScanningResult(IN P_ADAPTER_T prAdapter, IN PUINT_8 arBSSID); -+ -+#if CFG_TEST_WIFI_DIRECT_GO -+VOID wlanEnableP2pFunction(IN P_ADAPTER_T prAdapter); -+ -+VOID wlanEnableATGO(IN P_ADAPTER_T prAdapter); -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/* Address Retrieve by Polling */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryPermanentAddress(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* NIC Capability Retrieve by Polling */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryNicCapability(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* NIC Capability Retrieve by Polling */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryDebugCode(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Compiler Flags Retrieve by Polling */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryCompileFlags(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* PD MCR Retrieve by Polling */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryPdMcr(IN P_ADAPTER_T prAdapter, IN P_PARAM_MCR_RW_STRUCT_T prMcrRdInfo); -+/*----------------------------------------------------------------------------*/ -+/* Loading Manufacture Data */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanLoadManufactureData(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* Media Stream Mode */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanResetMediaStreamMode(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Timer Timeout Check (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanTimerTimeoutCheck(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Mailbox Message Check (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanProcessMboxMessage(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* TX Pending Packets Handling (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanEnqueueTxPacket(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prNativePacket); -+ -+WLAN_STATUS wlanFlushTxPendingPackets(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS wlanTxPendingPackets(IN P_ADAPTER_T prAdapter, IN OUT PBOOLEAN pfgHwAccess); -+ -+/*----------------------------------------------------------------------------*/ -+/* Low Power Acquire/Release (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanAcquirePowerControl(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS wlanReleasePowerControl(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Pending Packets Number Reporting (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+UINT_32 wlanGetTxPendingFrameCount(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* ACPI state inquiry (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+ENUM_ACPI_STATE_T wlanGetAcpiState(IN P_ADAPTER_T prAdapter); -+ -+VOID wlanSetAcpiState(IN P_ADAPTER_T prAdapter, IN ENUM_ACPI_STATE_T ePowerState); -+ -+VOID wlanDefTxPowerCfg(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* get ECO version from Revision ID register (for Win32) */ -+/*----------------------------------------------------------------------------*/ -+UINT_8 wlanGetEcoVersion(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* set preferred band configuration corresponding to network type */ -+/*----------------------------------------------------------------------------*/ -+VOID -+wlanSetPreferBandByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+/*----------------------------------------------------------------------------*/ -+/* get currently operating channel information */ -+/*----------------------------------------------------------------------------*/ -+UINT_8 wlanGetChannelNumberByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+/*----------------------------------------------------------------------------*/ -+/* get BSS Descriptor information */ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T wlanGetTargetBssDescByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+/*----------------------------------------------------------------------------*/ -+/* check for system configuration to generate message on scan list */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanCheckSystemConfiguration(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* query sta statistics information from driver and firmware */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryStaStatistics(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS wlanCfgParseArgument(CHAR *cmdLine, INT_32 *argc, CHAR *argv[]); -+ -+P_WLAN_CFG_ENTRY_T wlanCfgGetEntry(IN P_ADAPTER_T prAdapter, const PCHAR pucKey); -+ -+WLAN_STATUS -+wlanCfgGet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, PCHAR pucValueDef, UINT_32 u4Flags); -+ -+UINT_32 wlanCfgGetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4ValueDef); -+ -+INT_32 wlanCfgGetInt32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, INT_32 i4ValueDef); -+ -+WLAN_STATUS wlanCfgSetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4Value); -+ -+WLAN_STATUS wlanCfgSet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, UINT_32 u4Flags); -+ -+WLAN_STATUS -+wlanCfgSetCb(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, WLAN_CFG_SET_CB pfSetCb, void *pPrivate, UINT_32 u4Flags); -+ -+#if CFG_SUPPORT_CFG_FILE -+WLAN_STATUS wlanCfgInit(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen, UINT_32 u4Flags); -+ -+VOID wlanCfgApply(IN P_ADAPTER_T prAdapter); -+#endif /* CFG_SUPPORT_CFG_FILE */ -+ -+extern VOID mtk_wcn_wmt_set_wifi_ver(UINT_32 Value); -+ -+#endif /* _WLAN_LIB_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h -new file mode 100644 -index 0000000000000..45919df996e95 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h -@@ -0,0 +1,1715 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_oid.h#2 -+*/ -+ -+/*! \file "wlan_oid.h" -+ \brief This file contains the declairation file of the WLAN OID processing routines -+ of Windows driver for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_oid.h -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 02 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * Support UAPSD/OppPS/NoA parameter setting -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Finish SLT TX/RX & Rate Changing Support. -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * revert changelist #15371, efuse read/write access will be done by RF test approach -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add OID definitions for EFUSE read/write access. -+ * -+ * 08 04 2010 yarco.yang -+ * NULL -+ * Add TX_AMPDU and ADDBA_REJECT command -+ * -+ * 08 02 2010 george.huang -+ * NULL -+ * add WMM-PS test related OID/ CMD handlers -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move timer callback to glue layer. -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 18 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement Wakeup-on-LAN except firmware integration part -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * MT6620 is not supporting NDIS_PACKET_TYPE_PROMISCUOUS. -+ * -+ -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add NULL OID implementation for WOL-related OIDs. -+ * -+ * 04 22 2010 cp.wu -+ * [WPD00003830]add OID_802_11_PRIVACY_FILTER support -+ * enable RX filter OID -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * indicate media stream mode after set is done -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement custom OID: EEPROM read/write access -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) implement timeout mechanism when OID is pending for longer than 1 second -+ * * * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+ * -+ * 01 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement following 802.11 OIDs: -+ * * * * OID_802_11_RSSI, -+ * * * * OID_802_11_RSSI_TRIGGER, -+ * * * * OID_802_11_STATISTICS, -+ * * * * OID_802_11_DISASSOCIATE, -+ * * * * OID_802_11_POWER_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_MEDIA_STREAM_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-12-08 11:38:11 GMT mtk02752 -+** add declares for RF test related APIs -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-24 22:41:53 GMT mtk02752 -+** remove u4SysTime, MSDN 10-second will be implemented in FW side -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-23 20:30:13 GMT mtk02752 -+** add u4SysTime field in PARAM_BSSID_EX_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-12 19:48:35 GMT mtk02752 -+** allow upper layer to set a packet filter with PROMISCUOUS mode -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:12:12 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _WLAN_OID_H -+#define _WLAN_OID_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#if DBG -+extern UINT_8 aucDebugModule[DBG_MODULE_NUM]; -+extern UINT_32 u4DebugModule; -+UINT_32 u4DebugModuleTemp; -+#endif /* DBG */ -+extern int sprintf(char *buf, const char *fmt, ...); -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define PARAM_MAX_LEN_SSID 32 -+ -+#define PARAM_MAC_ADDR_LEN 6 -+ -+#define ETHERNET_HEADER_SZ 14 -+#define ETHERNET_MIN_PKT_SZ 60 -+#define ETHERNET_MAX_PKT_SZ 1514 -+ -+#define PARAM_MAX_LEN_RATES 8 -+#define PARAM_MAX_LEN_RATES_EX 16 -+ -+#define PARAM_AUTH_REQUEST_REAUTH 0x01 -+#define PARAM_AUTH_REQUEST_KEYUPDATE 0x02 -+#define PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 -+#define PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E -+ -+#define PARAM_EEPROM_READ_METHOD_READ 1 -+#define PARAM_EEPROM_READ_METHOD_GETSIZE 0 -+ -+#define PARAM_WHQL_RSSI_MAX_DBM (-10) -+#define PARAM_WHQL_RSSI_MIN_DBM (-200) -+ -+#define PARAM_DEVICE_WAKE_UP_ENABLE 0x00000001 -+#define PARAM_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 -+#define PARAM_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 -+ -+#define PARAM_WAKE_UP_MAGIC_PACKET 0x00000001 -+#define PARAM_WAKE_UP_PATTERN_MATCH 0x00000002 -+#define PARAM_WAKE_UP_LINK_CHANGE 0x00000004 -+ -+/* Packet filter bit definitioin (UINT_32 bit-wise definition) */ -+#define PARAM_PACKET_FILTER_DIRECTED 0x00000001 -+#define PARAM_PACKET_FILTER_MULTICAST 0x00000002 -+#define PARAM_PACKET_FILTER_ALL_MULTICAST 0x00000004 -+#define PARAM_PACKET_FILTER_BROADCAST 0x00000008 -+#define PARAM_PACKET_FILTER_PROMISCUOUS 0x00000020 -+#define PARAM_PACKET_FILTER_ALL_LOCAL 0x00000080 -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#define PARAM_PACKET_FILTER_P2P_MASK 0xC0000000 -+#define PARAM_PACKET_FILTER_PROBE_REQ 0x80000000 -+#define PARAM_PACKET_FILTER_ACTION_FRAME 0x40000000 -+#endif -+ -+#if CFG_SLT_SUPPORT -+#define PARAM_PACKET_FILTER_SUPPORTED (PARAM_PACKET_FILTER_DIRECTED | \ -+ PARAM_PACKET_FILTER_MULTICAST | \ -+ PARAM_PACKET_FILTER_BROADCAST | \ -+ PARAM_PACKET_FILTER_ALL_MULTICAST) -+#else -+#define PARAM_PACKET_FILTER_SUPPORTED (PARAM_PACKET_FILTER_DIRECTED | \ -+ PARAM_PACKET_FILTER_MULTICAST | \ -+ PARAM_PACKET_FILTER_BROADCAST) -+#endif -+ -+#define PARAM_MEM_DUMP_MAX_SIZE 2048 -+ -+#define BT_PROFILE_PARAM_LEN 8 -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Parameters of User Configuration which match to NDIS5.1 */ -+/*----------------------------------------------------------------------------*/ -+/* NDIS_802_11_AUTHENTICATION_MODE */ -+typedef enum _ENUM_PARAM_AUTH_MODE_T { -+ AUTH_MODE_OPEN, /*!< Open system */ -+ AUTH_MODE_SHARED, /*!< Shared key */ -+ AUTH_MODE_AUTO_SWITCH, /*!< Either open system or shared key */ -+ AUTH_MODE_WPA, -+ AUTH_MODE_WPA_PSK, -+ AUTH_MODE_WPA_NONE, /*!< For Ad hoc */ -+ AUTH_MODE_WPA2, -+ AUTH_MODE_WPA2_PSK, -+ AUTH_MODE_NUM /*!< Upper bound, not real case */ -+} ENUM_PARAM_AUTH_MODE_T, *P_ENUM_PARAM_AUTH_MODE_T; -+ -+/* NDIS_802_11_ENCRYPTION_STATUS *//* Encryption types */ -+typedef enum _ENUM_WEP_STATUS_T { -+ ENUM_WEP_ENABLED, -+ ENUM_ENCRYPTION1_ENABLED = ENUM_WEP_ENABLED, -+ ENUM_WEP_DISABLED, -+ ENUM_ENCRYPTION_DISABLED = ENUM_WEP_DISABLED, -+ ENUM_WEP_KEY_ABSENT, -+ ENUM_ENCRYPTION1_KEY_ABSENT = ENUM_WEP_KEY_ABSENT, -+ ENUM_WEP_NOT_SUPPORTED, -+ ENUM_ENCRYPTION_NOT_SUPPORTED = ENUM_WEP_NOT_SUPPORTED, -+ ENUM_ENCRYPTION2_ENABLED, -+ ENUM_ENCRYPTION2_KEY_ABSENT, -+ ENUM_ENCRYPTION3_ENABLED, -+ ENUM_ENCRYPTION3_KEY_ABSENT -+} ENUM_PARAM_ENCRYPTION_STATUS_T, *P_ENUM_PARAM_ENCRYPTION_STATUS_T; -+ -+typedef UINT_8 PARAM_MAC_ADDRESS[PARAM_MAC_ADDR_LEN]; -+ -+typedef UINT_32 PARAM_KEY_INDEX; -+typedef UINT_64 PARAM_KEY_RSC; -+typedef INT_32 PARAM_RSSI; -+ -+typedef UINT_32 PARAM_FRAGMENTATION_THRESHOLD; -+typedef UINT_32 PARAM_RTS_THRESHOLD; -+ -+typedef UINT_8 PARAM_RATES[PARAM_MAX_LEN_RATES]; -+typedef UINT_8 PARAM_RATES_EX[PARAM_MAX_LEN_RATES_EX]; -+ -+typedef enum _ENUM_PARAM_PHY_TYPE_T { -+ PHY_TYPE_802_11ABG = 0, /*!< Can associated with 802.11abg AP, -+ Scan dual band. */ -+ PHY_TYPE_802_11BG, /*!< Can associated with 802_11bg AP, -+ Scan single band and not report 802_11a BSSs. */ -+ PHY_TYPE_802_11G, /*!< Can associated with 802_11g only AP, -+ Scan single band and not report 802_11ab BSSs. */ -+ PHY_TYPE_802_11A, /*!< Can associated with 802_11a only AP, -+ Scan single band and not report 802_11bg BSSs. */ -+ PHY_TYPE_802_11B, /*!< Can associated with 802_11b only AP, -+ Scan single band and not report 802_11ag BSSs. */ -+ PHY_TYPE_NUM /* 5 */ -+} ENUM_PARAM_PHY_TYPE_T, *P_ENUM_PARAM_PHY_TYPE_T; -+ -+typedef enum _ENUM_PARAM_OP_MODE_T { -+ NET_TYPE_IBSS = 0, /*!< Try to merge/establish an AdHoc, do periodic SCAN for merging. */ -+ NET_TYPE_INFRA, /*!< Try to join an Infrastructure, do periodic SCAN for joining. */ -+ NET_TYPE_AUTO_SWITCH, /*!< Try to join an Infrastructure, if fail then try to merge or -+ establish an AdHoc, do periodic SCAN for joining or merging. */ -+ NET_TYPE_DEDICATED_IBSS, /*!< Try to merge an AdHoc first, -+ if fail then establish AdHoc permanently, no more SCAN. */ -+ NET_TYPE_NUM /* 4 */ -+} ENUM_PARAM_OP_MODE_T, *P_ENUM_PARAM_OP_MODE_T; -+ -+typedef struct _PARAM_SSID_T { -+ UINT_32 u4SsidLen; /*!< SSID length in bytes. Zero length is broadcast(any) SSID */ -+ UINT_8 aucSsid[PARAM_MAX_LEN_SSID]; -+ UINT_32 u4CenterFreq; -+} PARAM_SSID_T, *P_PARAM_SSID_T; -+ -+typedef struct _PARAM_CONNECT_T { -+ UINT_32 u4SsidLen; /*!< SSID length in bytes. Zero length is broadcast(any) SSID */ -+ UINT_8 *pucSsid; -+ UINT_8 *pucBssid; -+ UINT_32 u4CenterFreq; -+} PARAM_CONNECT_T, *P_PARAM_CONNECT_T; -+ -+/* This is enum defined for user to select an AdHoc Mode */ -+typedef enum _ENUM_PARAM_AD_HOC_MODE_T { -+ AD_HOC_MODE_11B = 0, /*!< Create 11b IBSS if we support 802.11abg/802.11bg. */ -+ AD_HOC_MODE_MIXED_11BG, /*!< Create 11bg mixed IBSS if we support 802.11abg/802.11bg/802.11g. */ -+ AD_HOC_MODE_11G, /*!< Create 11g only IBSS if we support 802.11abg/802.11bg/802.11g. */ -+ AD_HOC_MODE_11A, /*!< Create 11a only IBSS if we support 802.11abg. */ -+ AD_HOC_MODE_NUM /* 4 */ -+} ENUM_PARAM_AD_HOC_MODE_T, *P_ENUM_PARAM_AD_HOC_MODE_T; -+ -+typedef enum _ENUM_PARAM_MEDIA_STATE_T { -+ PARAM_MEDIA_STATE_CONNECTED, -+ PARAM_MEDIA_STATE_DISCONNECTED, -+ PARAM_MEDIA_STATE_TO_BE_INDICATED /* for following MSDN re-association behavior */ -+} ENUM_PARAM_MEDIA_STATE_T, *P_ENUM_PARAM_MEDIA_STATE_T; -+ -+typedef enum _ENUM_PARAM_NETWORK_TYPE_T { -+ PARAM_NETWORK_TYPE_FH, -+ PARAM_NETWORK_TYPE_DS, -+ PARAM_NETWORK_TYPE_OFDM5, -+ PARAM_NETWORK_TYPE_OFDM24, -+ PARAM_NETWORK_TYPE_AUTOMODE, -+ PARAM_NETWORK_TYPE_NUM /*!< Upper bound, not real case */ -+} ENUM_PARAM_NETWORK_TYPE_T, *P_ENUM_PARAM_NETWORK_TYPE_T; -+ -+typedef struct _PARAM_NETWORK_TYPE_LIST { -+ UINT_32 NumberOfItems; /*!< At least 1 */ -+ ENUM_PARAM_NETWORK_TYPE_T eNetworkType[1]; -+} PARAM_NETWORK_TYPE_LIST, *PPARAM_NETWORK_TYPE_LIST; -+ -+typedef enum _ENUM_PARAM_PRIVACY_FILTER_T { -+ PRIVACY_FILTER_ACCEPT_ALL, -+ PRIVACY_FILTER_8021xWEP, -+ PRIVACY_FILTER_NUM -+} ENUM_PARAM_PRIVACY_FILTER_T, *P_ENUM_PARAM_PRIVACY_FILTER_T; -+ -+typedef enum _ENUM_RELOAD_DEFAULTS { -+ ENUM_RELOAD_WEP_KEYS -+} PARAM_RELOAD_DEFAULTS, *P_PARAM_RELOAD_DEFAULTS; -+ -+typedef struct _PARAM_PM_PACKET_PATTERN { -+ UINT_32 Priority; /* Importance of the given pattern. */ -+ UINT_32 Reserved; /* Context information for transports. */ -+ UINT_32 MaskSize; /* Size in bytes of the pattern mask. */ -+ UINT_32 PatternOffset; /* Offset from beginning of this */ -+ /* structure to the pattern bytes. */ -+ UINT_32 PatternSize; /* Size in bytes of the pattern. */ -+ UINT_32 PatternFlags; /* Flags (TBD). */ -+} PARAM_PM_PACKET_PATTERN, *P_PARAM_PM_PACKET_PATTERN; -+ -+/*--------------------------------------------------------------*/ -+/*! \brief Struct definition to indicate specific event. */ -+/*--------------------------------------------------------------*/ -+typedef enum _ENUM_STATUS_TYPE_T { -+ ENUM_STATUS_TYPE_AUTHENTICATION, -+ ENUM_STATUS_TYPE_MEDIA_STREAM_MODE, -+ ENUM_STATUS_TYPE_CANDIDATE_LIST, -+ ENUM_STATUS_TYPE_NUM /*!< Upper bound, not real case */ -+} ENUM_STATUS_TYPE_T, *P_ENUM_STATUS_TYPE_T; -+ -+typedef struct _PARAM_802_11_CONFIG_FH_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4HopPattern; /*!< Defined as 802.11 */ -+ UINT_32 u4HopSet; /*!< to one if non-802.11 */ -+ UINT_32 u4DwellTime; /*!< In unit of Kusec */ -+} PARAM_802_11_CONFIG_FH_T, *P_PARAM_802_11_CONFIG_FH_T; -+ -+typedef struct _PARAM_802_11_CONFIG_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4BeaconPeriod; /*!< In unit of Kusec */ -+ UINT_32 u4ATIMWindow; /*!< In unit of Kusec */ -+ UINT_32 u4DSConfig; /*!< Channel frequency in unit of kHz */ -+ PARAM_802_11_CONFIG_FH_T rFHConfig; -+} PARAM_802_11_CONFIG_T, *P_PARAM_802_11_CONFIG_T; -+ -+typedef struct _PARAM_STATUS_INDICATION_T { -+ ENUM_STATUS_TYPE_T eStatusType; -+} PARAM_STATUS_INDICATION_T, *P_PARAM_STATUS_INDICATION_T; -+ -+typedef struct _PARAM_AUTH_REQUEST_T { -+ UINT_32 u4Length; /*!< Length of this struct */ -+ PARAM_MAC_ADDRESS arBssid; -+ UINT_32 u4Flags; /*!< Definitions are as follows */ -+} PARAM_AUTH_REQUEST_T, *P_PARAM_AUTH_REQUEST_T; -+ -+typedef struct _PARAM_AUTH_EVENT_T { -+ PARAM_STATUS_INDICATION_T rStatus; -+ PARAM_AUTH_REQUEST_T arRequest[1]; -+} PARAM_AUTH_EVENT_T, *P_PARAM_AUTH_EVENT_T; -+ -+/*! \brief Capabilities, privacy, rssi and IEs of each BSSID */ -+typedef struct _PARAM_BSSID_EX_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ PARAM_MAC_ADDRESS arMacAddress; /*!< BSSID */ -+ UINT_8 Reserved[2]; -+ PARAM_SSID_T rSsid; /*!< SSID */ -+ UINT_32 u4Privacy; /*!< Need WEP encryption */ -+ PARAM_RSSI rRssi; /*!< in dBm */ -+ ENUM_PARAM_NETWORK_TYPE_T eNetworkTypeInUse; -+ PARAM_802_11_CONFIG_T rConfiguration; -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ PARAM_RATES_EX rSupportedRates; -+ UINT_32 u4IELength; -+ UINT_8 aucIEs[1]; -+} PARAM_BSSID_EX_T, *P_PARAM_BSSID_EX_T; -+ -+typedef struct _PARAM_BSSID_LIST_EX { -+ UINT_32 u4NumberOfItems; /*!< at least 1 */ -+ PARAM_BSSID_EX_T arBssid[1]; -+} PARAM_BSSID_LIST_EX_T, *P_PARAM_BSSID_LIST_EX_T; -+ -+typedef struct _PARAM_WEP_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4KeyIndex; /*!< 0: pairwise key, others group keys */ -+ UINT_32 u4KeyLength; /*!< Key length in bytes */ -+ UINT_8 aucKeyMaterial[32]; /*!< Key content by above setting */ -+} PARAM_WEP_T, *P_PARAM_WEP_T; -+ -+/*! \brief Key mapping of BSSID */ -+typedef struct _PARAM_KEY_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4KeyIndex; /*!< KeyID */ -+ UINT_32 u4KeyLength; /*!< Key length in bytes */ -+ PARAM_MAC_ADDRESS arBSSID; /*!< MAC address */ -+ PARAM_KEY_RSC rKeyRSC; -+ UINT_8 aucKeyMaterial[32]; /*!< Key content by above setting */ -+} PARAM_KEY_T, *P_PARAM_KEY_T; -+ -+typedef struct _PARAM_REMOVE_KEY_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4KeyIndex; /*!< KeyID */ -+ PARAM_MAC_ADDRESS arBSSID; /*!< MAC address */ -+} PARAM_REMOVE_KEY_T, *P_PARAM_REMOVE_KEY_T; -+ -+#if CFG_SUPPORT_WAPI -+typedef enum _ENUM_KEY_TYPE { -+ ENUM_WPI_PAIRWISE_KEY = 0, -+ ENUM_WPI_GROUP_KEY -+} ENUM_KEY_TYPE; -+ -+typedef enum _ENUM_WPI_PROTECT_TYPE { -+ ENUM_WPI_NONE, -+ ENUM_WPI_RX, -+ ENUM_WPI_TX, -+ ENUM_WPI_RX_TX -+} ENUM_WPI_PROTECT_TYPE; -+ -+typedef struct _PARAM_WPI_KEY_T { -+ ENUM_KEY_TYPE eKeyType; -+ ENUM_WPI_PROTECT_TYPE eDirection; -+ UINT_8 ucKeyID; -+ UINT_8 aucRsv[3]; -+ UINT_8 aucAddrIndex[12]; -+ UINT_32 u4LenWPIEK; -+ UINT_8 aucWPIEK[256]; -+ UINT_32 u4LenWPICK; -+ UINT_8 aucWPICK[256]; -+ UINT_8 aucPN[16]; -+} PARAM_WPI_KEY_T, *P_PARAM_WPI_KEY_T; -+#endif -+ -+typedef enum _PARAM_POWER_MODE { -+ Param_PowerModeCAM, -+ Param_PowerModeMAX_PSP, -+ Param_PowerModeFast_PSP, -+#if CFG_SUPPORT_DBG_POWERMODE -+ Param_PowerModeKeepActiveOn, /* privilege mode, always active */ -+ Param_PowerModeKeepActiveOff, /* to leave privilege mode */ -+#endif -+ Param_PowerModeMax /* Upper bound, not real case */ -+} PARAM_POWER_MODE, *PPARAM_POWER_MODE; -+ -+typedef enum _PARAM_DEVICE_POWER_STATE { -+ ParamDeviceStateUnspecified = 0, -+ ParamDeviceStateD0, -+ ParamDeviceStateD1, -+ ParamDeviceStateD2, -+ ParamDeviceStateD3, -+ ParamDeviceStateMaximum -+} PARAM_DEVICE_POWER_STATE, *PPARAM_DEVICE_POWER_STATE; -+ -+#if CFG_SUPPORT_802_11D -+ -+/*! \brief The enumeration definitions for OID_IPN_MULTI_DOMAIN_CAPABILITY */ -+typedef enum _PARAM_MULTI_DOMAIN_CAPABILITY { -+ ParamMultiDomainCapDisabled, -+ ParamMultiDomainCapEnabled -+} PARAM_MULTI_DOMAIN_CAPABILITY, *P_PARAM_MULTI_DOMAIN_CAPABILITY; -+#endif -+ -+typedef struct _COUNTRY_STRING_ENTRY { -+ UINT_8 aucCountryCode[2]; -+ UINT_8 aucEnvironmentCode[2]; -+} COUNTRY_STRING_ENTRY, *P_COUNTRY_STRING_ENTRY; -+ -+/* Power management related definition and enumerations */ -+#define UAPSD_NONE 0 -+#define UAPSD_AC0 (BIT(0) | BIT(4)) -+#define UAPSD_AC1 (BIT(1) | BIT(5)) -+#define UAPSD_AC2 (BIT(2) | BIT(6)) -+#define UAPSD_AC3 (BIT(3) | BIT(7)) -+#define UAPSD_ALL (UAPSD_AC0 | UAPSD_AC1 | UAPSD_AC2 | UAPSD_AC3) -+ -+typedef enum _ENUM_POWER_SAVE_PROFILE_T { -+ ENUM_PSP_CONTINUOUS_ACTIVE = 0, -+ ENUM_PSP_CONTINUOUS_POWER_SAVE, -+ ENUM_PSP_FAST_SWITCH, -+ ENUM_PSP_NUM -+} ENUM_POWER_SAVE_PROFILE_T, *PENUM_POWER_SAVE_PROFILE_T; -+ -+/*--------------------------------------------------------------*/ -+/*! \brief Set/Query testing type. */ -+/*--------------------------------------------------------------*/ -+typedef struct _PARAM_802_11_TEST_T { -+ UINT_32 u4Length; -+ UINT_32 u4Type; -+ union { -+ PARAM_AUTH_EVENT_T AuthenticationEvent; -+ PARAM_RSSI RssiTrigger; -+ } u; -+} PARAM_802_11_TEST_T, *P_PARAM_802_11_TEST_T; -+ -+/*--------------------------------------------------------------*/ -+/*! \brief Set/Query authentication and encryption capability. */ -+/*--------------------------------------------------------------*/ -+typedef struct _PARAM_AUTH_ENCRYPTION_T { -+ ENUM_PARAM_AUTH_MODE_T eAuthModeSupported; -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncryptStatusSupported; -+} PARAM_AUTH_ENCRYPTION_T, *P_PARAM_AUTH_ENCRYPTION_T; -+ -+typedef struct _PARAM_CAPABILITY_T { -+ UINT_32 u4Length; -+ UINT_32 u4Version; -+ UINT_32 u4NoOfPMKIDs; -+ UINT_32 u4NoOfAuthEncryptPairsSupported; -+ PARAM_AUTH_ENCRYPTION_T arAuthenticationEncryptionSupported[1]; -+} PARAM_CAPABILITY_T, *P_PARAM_CAPABILITY_T; -+ -+typedef UINT_8 PARAM_PMKID_VALUE[16]; -+ -+typedef struct _PARAM_BSSID_INFO_T { -+ PARAM_MAC_ADDRESS arBSSID; -+ PARAM_PMKID_VALUE arPMKID; -+} PARAM_BSSID_INFO_T, *P_PARAM_BSSID_INFO_T; -+ -+typedef struct _PARAM_PMKID_T { -+ UINT_32 u4Length; -+ UINT_32 u4BSSIDInfoCount; -+ PARAM_BSSID_INFO_T arBSSIDInfo[1]; -+} PARAM_PMKID_T, *P_PARAM_PMKID_T; -+ -+/*! \brief PMKID candidate lists. */ -+typedef struct _PARAM_PMKID_CANDIDATE_T { -+ PARAM_MAC_ADDRESS arBSSID; -+ UINT_32 u4Flags; -+} PARAM_PMKID_CANDIDATE_T, *P_PARAM_PMKID_CANDIDATE_T; -+ -+/* #ifdef LINUX */ -+typedef struct _PARAM_PMKID_CANDIDATE_LIST_T { -+ UINT_32 u4Version; /*!< Version */ -+ UINT_32 u4NumCandidates; /*!< How many candidates follow */ -+ PARAM_PMKID_CANDIDATE_T arCandidateList[1]; -+} PARAM_PMKID_CANDIDATE_LIST_T, *P_PARAM_PMKID_CANDIDATE_LIST_T; -+/* #endif */ -+ -+typedef struct _PARAM_CUSTOM_MCR_RW_STRUCT_T { -+ UINT_32 u4McrOffset; -+ UINT_32 u4McrData; -+} PARAM_CUSTOM_MCR_RW_STRUCT_T, *P_PARAM_CUSTOM_MCR_RW_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_MEM_DUMP_STRUCT_T { -+ UINT_32 u4Address; -+ UINT_32 u4Length; -+ UINT_32 u4RemainLength; -+ UINT_8 ucFragNum; -+} PARAM_CUSTOM_MEM_DUMP_STRUCT_T, *P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_SW_CTRL_STRUCT_T { -+ UINT_32 u4Id; -+ UINT_32 u4Data; -+} PARAM_CUSTOM_SW_CTRL_STRUCT_T, *P_PARAM_CUSTOM_SW_CTRL_STRUCT_T; -+ -+typedef struct _CMD_CHIP_CONFIG_T { -+ UINT_16 u2Id; -+ UINT_8 ucType; -+ UINT_8 ucRespType; -+ UINT_16 u2MsgSize; -+ UINT_8 aucReserved0[2]; -+ UINT_8 aucCmd[CHIP_CONFIG_RESP_SIZE]; -+} CMD_CHIP_CONFIG_T, *P_CMD_CHIP_CONFIG_T; -+ -+typedef struct _PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T { -+ UINT_16 u2Id; -+ UINT_8 ucType; -+ UINT_8 ucRespType; -+ UINT_16 u2MsgSize; -+ UINT_8 aucReserved0[2]; -+ UINT_8 aucCmd[CHIP_CONFIG_RESP_SIZE]; -+} PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T, *P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_KEY_CFG_STRUCT_T { -+ UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX]; -+ UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX]; -+} PARAM_CUSTOM_KEY_CFG_STRUCT_T, *P_PARAM_CUSTOM_KEY_CFG_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_EEPROM_RW_STRUCT_T { -+ UINT_8 ucEepromMethod; /* For read only read: 1, query size: 0 */ -+ UINT_8 ucEepromIndex; -+ UINT_8 reserved; -+ UINT_16 u2EepromData; -+} PARAM_CUSTOM_EEPROM_RW_STRUCT_T, *P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T, -+PARAM_CUSTOM_NVRAM_RW_STRUCT_T, *P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T { -+ UINT_8 bmfgApsdEnAc; /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ -+ UINT_8 ucIsEnterPsAtOnce; /* enter PS immediately without 5 second guard after connected */ -+ UINT_8 ucIsDisableUcTrigger; /* not to trigger UC on beacon TIM is matched (under U-APSD) */ -+ UINT_8 reserved; -+} PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T, *P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_NOA_PARAM_STRUCT_T { -+ UINT_32 u4NoaDurationMs; -+ UINT_32 u4NoaIntervalMs; -+ UINT_32 u4NoaCount; -+} PARAM_CUSTOM_NOA_PARAM_STRUCT_T, *P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T { -+ UINT_32 u4CTwindowMs; -+} PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T, *P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T { -+ UINT_8 fgEnAPSD; -+ UINT_8 fgEnAPSD_AcBe; -+ UINT_8 fgEnAPSD_AcBk; -+ UINT_8 fgEnAPSD_AcVo; -+ UINT_8 fgEnAPSD_AcVi; -+ UINT_8 ucMaxSpLen; -+ UINT_8 aucResv[2]; -+} PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T, *P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_P2P_SET_STRUCT_T { -+ UINT_32 u4Enable; -+ UINT_32 u4Mode; -+} PARAM_CUSTOM_P2P_SET_STRUCT_T, *P_PARAM_CUSTOM_P2P_SET_STRUCT_T; -+ -+typedef enum _ENUM_CFG_SRC_TYPE_T { -+ CFG_SRC_TYPE_EEPROM, -+ CFG_SRC_TYPE_NVRAM, -+ CFG_SRC_TYPE_UNKNOWN, -+ CFG_SRC_TYPE_NUM -+} ENUM_CFG_SRC_TYPE_T, *P_ENUM_CFG_SRC_TYPE_T; -+ -+typedef enum _ENUM_EEPROM_TYPE_T { -+ EEPROM_TYPE_NO, -+ EEPROM_TYPE_PRESENT, -+ EEPROM_TYPE_NUM -+} ENUM_EEPROM_TYPE_T, *P_ENUM_EEPROM_TYPE_T; -+ -+typedef struct _PARAM_QOS_TSINFO { -+ UINT_8 ucTrafficType; /* Traffic Type: 1 for isochronous 0 for asynchronous */ -+ UINT_8 ucTid; /* TSID: must be between 8 ~ 15 */ -+ UINT_8 ucDirection; /* direction */ -+ UINT_8 ucAccessPolicy; /* access policy */ -+ UINT_8 ucAggregation; /* aggregation */ -+ UINT_8 ucApsd; /* APSD */ -+ UINT_8 ucuserPriority; /* user priority */ -+ UINT_8 ucTsInfoAckPolicy; /* TSINFO ACK policy */ -+ UINT_8 ucSchedule; /* Schedule */ -+} PARAM_QOS_TSINFO, *P_PARAM_QOS_TSINFO; -+ -+typedef struct _PARAM_QOS_TSPEC { -+ PARAM_QOS_TSINFO rTsInfo; /* TS info field */ -+ UINT_16 u2NominalMSDUSize; /* nominal MSDU size */ -+ UINT_16 u2MaxMSDUsize; /* maximum MSDU size */ -+ UINT_32 u4MinSvcIntv; /* minimum service interval */ -+ UINT_32 u4MaxSvcIntv; /* maximum service interval */ -+ UINT_32 u4InactIntv; /* inactivity interval */ -+ UINT_32 u4SpsIntv; /* suspension interval */ -+ UINT_32 u4SvcStartTime; /* service start time */ -+ UINT_32 u4MinDataRate; /* minimum Data rate */ -+ UINT_32 u4MeanDataRate; /* mean data rate */ -+ UINT_32 u4PeakDataRate; /* peak data rate */ -+ UINT_32 u4MaxBurstSize; /* maximum burst size */ -+ UINT_32 u4DelayBound; /* delay bound */ -+ UINT_32 u4MinPHYRate; /* minimum PHY rate */ -+ UINT_16 u2Sba; /* surplus bandwidth allowance */ -+ UINT_16 u2MediumTime; /* medium time */ -+} PARAM_QOS_TSPEC, *P_PARAM_QOS_TSPEC; -+ -+typedef struct _PARAM_QOS_ADDTS_REQ_INFO { -+ PARAM_QOS_TSPEC rTspec; -+} PARAM_QOS_ADDTS_REQ_INFO, *P_PARAM_QOS_ADDTS_REQ_INFO; -+ -+typedef struct _PARAM_VOIP_CONFIG { -+ UINT_32 u4VoipTrafficInterval; /* 0: disable VOIP configuration */ -+} PARAM_VOIP_CONFIG, *P_PARAM_VOIP_CONFIG; -+ -+/*802.11 Statistics Struct*/ -+typedef struct _PARAM_802_11_STATISTICS_STRUCT_T { -+ UINT_32 u4Length; /* Length of structure */ -+ LARGE_INTEGER rTransmittedFragmentCount; -+ LARGE_INTEGER rMulticastTransmittedFrameCount; -+ LARGE_INTEGER rFailedCount; -+ LARGE_INTEGER rRetryCount; -+ LARGE_INTEGER rMultipleRetryCount; -+ LARGE_INTEGER rRTSSuccessCount; -+ LARGE_INTEGER rRTSFailureCount; -+ LARGE_INTEGER rACKFailureCount; -+ LARGE_INTEGER rFrameDuplicateCount; -+ LARGE_INTEGER rReceivedFragmentCount; -+ LARGE_INTEGER rMulticastReceivedFrameCount; -+ LARGE_INTEGER rFCSErrorCount; -+ LARGE_INTEGER rTKIPLocalMICFailures; -+ LARGE_INTEGER rTKIPICVErrors; -+ LARGE_INTEGER rTKIPCounterMeasuresInvoked; -+ LARGE_INTEGER rTKIPReplays; -+ LARGE_INTEGER rCCMPFormatErrors; -+ LARGE_INTEGER rCCMPReplays; -+ LARGE_INTEGER rCCMPDecryptErrors; -+ LARGE_INTEGER rFourWayHandshakeFailures; -+ LARGE_INTEGER rWEPUndecryptableCount; -+ LARGE_INTEGER rWEPICVErrorCount; -+ LARGE_INTEGER rDecryptSuccessCount; -+ LARGE_INTEGER rDecryptFailureCount; -+} PARAM_802_11_STATISTICS_STRUCT_T, *P_PARAM_802_11_STATISTICS_STRUCT_T; -+ -+/* Linux Network Device Statistics Struct */ -+typedef struct _PARAM_LINUX_NETDEV_STATISTICS_T { -+ UINT_32 u4RxPackets; -+ UINT_32 u4TxPackets; -+ UINT_32 u4RxBytes; -+ UINT_32 u4TxBytes; -+ UINT_32 u4RxErrors; -+ UINT_32 u4TxErrors; -+ UINT_32 u4Multicast; -+} PARAM_LINUX_NETDEV_STATISTICS_T, *P_PARAM_LINUX_NETDEV_STATISTICS_T; -+ -+typedef struct _PARAM_MTK_WIFI_TEST_STRUCT_T { -+ UINT_32 u4FuncIndex; -+ UINT_32 u4FuncData; -+} PARAM_MTK_WIFI_TEST_STRUCT_T, *P_PARAM_MTK_WIFI_TEST_STRUCT_T; -+ -+/* 802.11 Media stream constraints */ -+typedef enum _ENUM_MEDIA_STREAM_MODE { -+ ENUM_MEDIA_STREAM_OFF, -+ ENUM_MEDIA_STREAM_ON -+} ENUM_MEDIA_STREAM_MODE, *P_ENUM_MEDIA_STREAM_MODE; -+ -+/* for NDIS 5.1 Media Streaming Change */ -+typedef struct _PARAM_MEDIA_STREAMING_INDICATION { -+ PARAM_STATUS_INDICATION_T rStatus; -+ ENUM_MEDIA_STREAM_MODE eMediaStreamMode; -+} PARAM_MEDIA_STREAMING_INDICATION, *P_PARAM_MEDIA_STREAMING_INDICATION; -+ -+#define PARAM_PROTOCOL_ID_DEFAULT 0x00 -+#define PARAM_PROTOCOL_ID_TCP_IP 0x02 -+#define PARAM_PROTOCOL_ID_IPX 0x06 -+#define PARAM_PROTOCOL_ID_NBF 0x07 -+#define PARAM_PROTOCOL_ID_MAX 0x0F -+#define PARAM_PROTOCOL_ID_MASK 0x0F -+ -+/* for NDIS OID_GEN_NETWORK_LAYER_ADDRESSES */ -+typedef struct _PARAM_NETWORK_ADDRESS_IP { -+ UINT_16 sin_port; -+ UINT_32 in_addr; -+ UINT_8 sin_zero[8]; -+} PARAM_NETWORK_ADDRESS_IP, *P_PARAM_NETWORK_ADDRESS_IP; -+ -+typedef struct _PARAM_NETWORK_ADDRESS { -+ UINT_16 u2AddressLength; /* length in bytes of Address[] in this */ -+ UINT_16 u2AddressType; /* type of this address (PARAM_PROTOCOL_ID_XXX above) */ -+ UINT_8 aucAddress[1]; /* actually AddressLength bytes long */ -+} PARAM_NETWORK_ADDRESS, *P_PARAM_NETWORK_ADDRESS; -+ -+/* The following is used with OID_GEN_NETWORK_LAYER_ADDRESSES to set network layer addresses on an interface */ -+ -+typedef struct _PARAM_NETWORK_ADDRESS_LIST { -+ UINT_32 u4AddressCount; /* number of addresses following */ -+ UINT_16 u2AddressType; /* type of this address (NDIS_PROTOCOL_ID_XXX above) */ -+ PARAM_NETWORK_ADDRESS arAddress[1]; /* actually AddressCount elements long */ -+} PARAM_NETWORK_ADDRESS_LIST, *P_PARAM_NETWORK_ADDRESS_LIST; -+ -+#if CFG_SLT_SUPPORT -+ -+#define FIXED_BW_LG20 0x0000 -+#define FIXED_BW_UL20 0x2000 -+#define FIXED_BW_DL40 0x3000 -+ -+#define FIXED_EXT_CHNL_U20 0x4000 /* For AGG register. */ -+#define FIXED_EXT_CHNL_L20 0xC000 /* For AGG regsiter. */ -+ -+typedef enum _ENUM_MTK_LP_TEST_MODE_T { -+ ENUM_MTK_LP_TEST_NORMAL, -+ ENUM_MTK_LP_TEST_GOLDEN_SAMPLE, -+ ENUM_MTK_LP_TEST_DUT, -+ ENUM_MTK_LP_TEST_MODE_NUM -+} ENUM_MTK_LP_TEST_MODE_T, *P_ENUM_MTK_LP_TEST_MODE_T; -+ -+typedef enum _ENUM_MTK_SLT_FUNC_IDX_T { -+ ENUM_MTK_SLT_FUNC_DO_NOTHING, -+ ENUM_MTK_SLT_FUNC_INITIAL, -+ ENUM_MTK_SLT_FUNC_RATE_SET, -+ ENUM_MTK_SLT_FUNC_LP_SET, -+ ENUM_MTK_SLT_FUNC_NUM -+} ENUM_MTK_SLT_FUNC_IDX_T, *P_ENUM_MTK_SLT_FUNC_IDX_T; -+ -+typedef struct _PARAM_MTK_SLT_LP_TEST_STRUCT_T { -+ ENUM_MTK_LP_TEST_MODE_T rLpTestMode; -+ UINT_32 u4BcnRcvNum; -+} PARAM_MTK_SLT_LP_TEST_STRUCT_T, *P_PARAM_MTK_SLT_LP_TEST_STRUCT_T; -+ -+typedef struct _PARAM_MTK_SLT_TR_TEST_STRUCT_T { -+ ENUM_PARAM_NETWORK_TYPE_T rNetworkType; /* Network Type OFDM5G or OFDM2.4G */ -+ UINT_32 u4FixedRate; /* Fixed Rate including BW */ -+} PARAM_MTK_SLT_TR_TEST_STRUCT_T, *P_PARAM_MTK_SLT_TR_TEST_STRUCT_T; -+ -+typedef struct _PARAM_MTK_SLT_INITIAL_STRUCT_T { -+ UINT_8 aucTargetMacAddr[PARAM_MAC_ADDR_LEN]; -+ UINT_16 u2SiteID; -+} PARAM_MTK_SLT_INITIAL_STRUCT_T, *P_PARAM_MTK_SLT_INITIAL_STRUCT_T; -+ -+typedef struct _PARAM_MTK_SLT_TEST_STRUCT_T { -+ ENUM_MTK_SLT_FUNC_IDX_T rSltFuncIdx; -+ UINT_32 u4Length; /* Length of structure, -+ including myself */ -+ UINT_32 u4FuncInfoLen; /* Include following content -+ field and myself */ -+ union { -+ PARAM_MTK_SLT_INITIAL_STRUCT_T rMtkInitTest; -+ PARAM_MTK_SLT_LP_TEST_STRUCT_T rMtkLpTest; -+ PARAM_MTK_SLT_TR_TEST_STRUCT_T rMtkTRTest; -+ } unFuncInfoContent; -+ -+} PARAM_MTK_SLT_TEST_STRUCT_T, *P_PARAM_MTK_SLT_TEST_STRUCT_T; -+ -+#endif -+ -+/*--------------------------------------------------------------*/ -+/*! \brief For Fixed Rate Configuration (Registry) */ -+/*--------------------------------------------------------------*/ -+typedef enum _ENUM_REGISTRY_FIXED_RATE_T { -+ FIXED_RATE_NONE, -+ FIXED_RATE_1M, -+ FIXED_RATE_2M, -+ FIXED_RATE_5_5M, -+ FIXED_RATE_11M, -+ FIXED_RATE_6M, -+ FIXED_RATE_9M, -+ FIXED_RATE_12M, -+ FIXED_RATE_18M, -+ FIXED_RATE_24M, -+ FIXED_RATE_36M, -+ FIXED_RATE_48M, -+ FIXED_RATE_54M, -+ FIXED_RATE_MCS0_20M_800NS, -+ FIXED_RATE_MCS1_20M_800NS, -+ FIXED_RATE_MCS2_20M_800NS, -+ FIXED_RATE_MCS3_20M_800NS, -+ FIXED_RATE_MCS4_20M_800NS, -+ FIXED_RATE_MCS5_20M_800NS, -+ FIXED_RATE_MCS6_20M_800NS, -+ FIXED_RATE_MCS7_20M_800NS, -+ FIXED_RATE_MCS0_20M_400NS, -+ FIXED_RATE_MCS1_20M_400NS, -+ FIXED_RATE_MCS2_20M_400NS, -+ FIXED_RATE_MCS3_20M_400NS, -+ FIXED_RATE_MCS4_20M_400NS, -+ FIXED_RATE_MCS5_20M_400NS, -+ FIXED_RATE_MCS6_20M_400NS, -+ FIXED_RATE_MCS7_20M_400NS, -+ FIXED_RATE_MCS0_40M_800NS, -+ FIXED_RATE_MCS1_40M_800NS, -+ FIXED_RATE_MCS2_40M_800NS, -+ FIXED_RATE_MCS3_40M_800NS, -+ FIXED_RATE_MCS4_40M_800NS, -+ FIXED_RATE_MCS5_40M_800NS, -+ FIXED_RATE_MCS6_40M_800NS, -+ FIXED_RATE_MCS7_40M_800NS, -+ FIXED_RATE_MCS32_800NS, -+ FIXED_RATE_MCS0_40M_400NS, -+ FIXED_RATE_MCS1_40M_400NS, -+ FIXED_RATE_MCS2_40M_400NS, -+ FIXED_RATE_MCS3_40M_400NS, -+ FIXED_RATE_MCS4_40M_400NS, -+ FIXED_RATE_MCS5_40M_400NS, -+ FIXED_RATE_MCS6_40M_400NS, -+ FIXED_RATE_MCS7_40M_400NS, -+ FIXED_RATE_MCS32_400NS, -+ FIXED_RATE_NUM -+} ENUM_REGISTRY_FIXED_RATE_T, *P_ENUM_REGISTRY_FIXED_RATE_T; -+ -+typedef enum _ENUM_BT_CMD_T { -+ BT_CMD_PROFILE = 0, -+ BT_CMD_UPDATE, -+ BT_CMD_NUM -+} ENUM_BT_CMD_T; -+ -+typedef enum _ENUM_BT_PROFILE_T { -+ BT_PROFILE_CUSTOM = 0, -+ BT_PROFILE_SCO, -+ BT_PROFILE_ACL, -+ BT_PROFILE_MIXED, -+ BT_PROFILE_NO_CONNECTION, -+ BT_PROFILE_NUM -+} ENUM_BT_PROFILE_T; -+ -+typedef struct _PTA_PROFILE_T { -+ ENUM_BT_PROFILE_T eBtProfile; -+ union { -+ UINT_8 aucBTPParams[BT_PROFILE_PARAM_LEN]; -+ /* 0: sco reserved slot time, -+ 1: sco idle slot time, -+ 2: acl throughput, -+ 3: bt tx power, -+ 4: bt rssi -+ 5: VoIP interval -+ 6: BIT(0) Use this field, BIT(1) 0 apply single/ 1 dual PTA setting. -+ */ -+ UINT_32 au4Btcr[4]; -+ } u; -+} PTA_PROFILE_T, *P_PTA_PROFILE_T; -+ -+typedef struct _PTA_IPC_T { -+ UINT_8 ucCmd; -+ UINT_8 ucLen; -+ union { -+ PTA_PROFILE_T rProfile; -+ UINT_8 aucBTPParams[BT_PROFILE_PARAM_LEN]; -+ } u; -+} PARAM_PTA_IPC_T, *P_PARAM_PTA_IPC_T, PTA_IPC_T, *P_PTA_IPC_T; -+ -+/*--------------------------------------------------------------*/ -+/*! \brief CFG80211 Scan Request Container */ -+/*--------------------------------------------------------------*/ -+ -+typedef struct _PARAM_SCAN_REQUEST_EXT_T { -+ PARAM_SSID_T rSsid; -+ UINT_32 u4IELength; -+ PUINT_8 pucIE; -+} PARAM_SCAN_REQUEST_EXT_T, *P_PARAM_SCAN_REQUEST_EXT_T; -+ -+/*--------------------------------------------------------------*/ -+/*! \brief CFG80211 Scheduled Scan Request Container */ -+/*--------------------------------------------------------------*/ -+typedef struct _PARAM_SCHED_SCAN_REQUEST_T { -+ UINT_32 u4SsidNum; -+ PARAM_SSID_T arSsid[CFG_SCAN_SSID_MATCH_MAX_NUM]; -+ UINT_32 u4IELength; -+ PUINT_8 pucIE; -+ UINT_16 u2ScanInterval; /* in milliseconds */ -+} PARAM_SCHED_SCAN_REQUEST, *P_PARAM_SCHED_SCAN_REQUEST; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+typedef struct _PARAM_HS20_SET_BSSID_POOL { -+ BOOLEAN fgIsEnable; -+ UINT_8 ucNumBssidPool; -+ PARAM_MAC_ADDRESS arBSSID[8]; -+} PARAM_HS20_SET_BSSID_POOL, *P_PARAM_HS20_SET_BSSID_POOL; -+ -+#endif -+ -+typedef struct _PARAM_CUSTOM_WFD_DEBUG_STRUCT_T { -+ UINT_8 ucWFDDebugMode; /* 0: Disable -+ 1:Enable but only show inqueue skb ether SN -+ 2.show skb ether SN and the statistics of skb inqueue time */ -+ UINT_16 u2SNPeriod; /* The Ether SN Period */ -+ -+ UINT_8 reserved; -+} PARAM_CUSTOM_WFD_DEBUG_STRUCT_T, *P_PARAM_CUSTOM_WFD_DEBUG_STRUCT_T; -+ -+typedef struct _CMD_GET_PSCAN_CAPABILITY { -+/* TBD */ -+} CMD_GET_GSCAN_CAPABILITY, *P_CMD_GET_GSCAN_CAPABILITY; -+ -+typedef struct _CMD_SET_PSCAN_ENABLE { -+ UINT_8 ucPscanAct; -+ UINT_8 aucReserved[3]; -+} CMD_SET_PSCAN_ENABLE, *P_CMD_SET_PSCAN_ENABLE; -+ -+typedef enum _ENUM_PSCAN_ACT_T { -+ ENABLE, -+ DISABLE, -+ SUSPEND, -+ CLEAR -+} ENUM_PSCAN_ACT_T, *P_ENUM_PSCAN_ACT_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*--------------------------------------------------------------*/ -+/* Routines to set parameters or query information. */ -+/*--------------------------------------------------------------*/ -+/***** Routines in wlan_oid.c *****/ -+WLAN_STATUS -+wlanoidQueryNetworkTypesSupported(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryNetworkTypeInUse(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetNetworkTypeInUse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBssid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetBssidListScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetBssidListScanExt(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBssidList(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetBssid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetSsid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetConnect(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQuerySsid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryInfrastructureMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetInfrastructureMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryAuthMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAuthMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+#if 0 -+WLAN_STATUS -+wlanoidQueryPrivacyFilter(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetPrivacyFilter(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+WLAN_STATUS -+wlanoidSetEncryptionStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryEncryptionStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAddWep(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRemoveWep(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+_wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, IN BOOLEAN fgIsOid, IN UINT_8 ucAlgorithmId, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRemoveKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetReloadDefaults(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetTest(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryCapability(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryFrequency(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetFrequency(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryAtimWindow(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAtimWindow(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetChannel(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRssi(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRssiTrigger(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRssiTrigger(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRtsThreshold(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRtsThreshold(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQuery802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSet802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID prSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryPmkid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetPmkid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQuerySupportedRates(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryDesiredRates(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetDesiredRates(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryCurrentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryLinkSpeed(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryMcrRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryMemDump(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetMcrWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetSwCtrlWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryEepromRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetEepromWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRfTestRxStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRfTestTxStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryOidInterfaceVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryVendorId(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryMulticastList(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetMulticastList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRcvError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRcvNoBuffer(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRcvCrcError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryStatistics(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+WLAN_STATUS -+wlanoidQueryStatisticsPL(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+#ifdef LINUX -+ -+WLAN_STATUS -+wlanoidQueryStatisticsForLinux(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+#endif -+ -+WLAN_STATUS -+wlanoidQueryMediaStreamMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetMediaStreamMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRcvOk(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryXmitOk(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryXmitError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetCurrentPacketFilter(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryCurrentPacketFilter(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetDisassociate(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryFragThreshold(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetFragThreshold(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryAdHocMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAdHocMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBeaconInterval(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetBeaconInterval(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetCurrentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+WLAN_STATUS -+wlanoidSetCSUMOffload(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+WLAN_STATUS -+wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryMaxFrameSize(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryMaxTotalSize(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetCurrentLookahead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+/* RF Test related APIs */ -+WLAN_STATUS -+wlanoidRftestSetTestMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidRftestSetAbortTestMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidRftestQueryAutoTest(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidRftestSetAutoTest(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+#if CFG_SUPPORT_WAPI -+WLAN_STATUS -+wlanoidSetWapiMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetWapiAssocInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetWapiKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+WLAN_STATUS -+wlanoidSetWSCAssocInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+#if CFG_ENABLE_WAKEUP_ON_LAN -+WLAN_STATUS -+wlanoidSetAddWakeupPattern(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRemoveWakeupPattern(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryEnableWakeup(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 u4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetEnableWakeup(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+WLAN_STATUS -+wlanoidSetWiFiWmmPsTest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetTxAmpdu(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBSSInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAddbaReject(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryNvramRead(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetNvramWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryCfgSrcType(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryEepromType(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetCountryCode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS wlanSendMemDumpCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen); -+ -+#if CFG_SLT_SUPPORT -+ -+WLAN_STATUS -+wlanoidQuerySLTStatus(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidUpdateSLTMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+#endif -+ -+#if 0 -+WLAN_STATUS -+wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBT(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBT(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetTxPower(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+WLAN_STATUS -+wlanoidQueryBuildDateCode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+#endif -+ -+/* -+WLAN_STATUS -+wlanoidQueryBtSingleAntenna ( -+ IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, -+ IN UINT_32 u4QueryBufferLen, -+ OUT PUINT_32 pu4QueryInfoLen -+ ); -+ -+WLAN_STATUS -+wlanoidSetBtSingleAntenna ( -+ IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, -+ OUT PUINT_32 pu4SetInfoLen -+ ); -+ -+WLAN_STATUS -+wlanoidSetPta ( -+ IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, -+ OUT PUINT_32 pu4SetInfoLen -+ ); -+ -+WLAN_STATUS -+wlanoidQueryPta ( -+ IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, -+ IN UINT_32 u4QueryBufferLen, -+ OUT PUINT_32 pu4QueryInfoLen -+ ); -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+WLAN_STATUS -+wlanoidSetP2pMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+#if CFG_SUPPORT_BATCH_SCAN -+WLAN_STATUS -+wlanoidSetBatchScanReq(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBatchScanResult(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+WLAN_STATUS -+wlanoidSetHS20Info(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetInterworkingInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRoamingConsortiumIEInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetHS20BssidPool(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+WLAN_STATUS -+wlanoidSetRoamingInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetWfdDebugMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetStartSchedScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetStopSchedScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetGSCNAction(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetGSCNAParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetGSCNAConfig(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidGetGSCNResult(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetTxRateInfo( -+ IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, -+ OUT PUINT_32 pu4SetInfoLen -+ ); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+WLAN_STATUS -+wlanoidSetChipConfig(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+WLAN_STATUS -+wlanoidNotifyFwSuspend(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, -+ OUT PUINT_32 pu4SetInfoLen); -+ -+#endif /* _WLAN_OID_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h -new file mode 100644 -index 0000000000000..0b558d64034d4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h -@@ -0,0 +1,307 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/wlan_p2p.h#3 -+*/ -+ -+/*! \file "wlan_p2p.h" -+ \brief This file contains the declairations of Wi-Fi Direct command -+ processing routines for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_p2p.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Add RSSI support for P2P network. -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version -+ * query & set support for service discovery version check. -+ * Add support for driver version query & p2p supplicant verseion set. -+ * For new service discovery mechanism sync. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * Support Channel Query. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 04 27 2011 george.huang -+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter -+ * Support P2P ARP filter setting on early suspend/ late resume -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add Security check related code. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface -+ * for supporting Wi-Fi Direct Service Discovery -+ * ioctl implementations for P2P Service Discovery -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface -+ * for supporting Wi-Fi Direct Service Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add subroutines for P2P to set multicast list. -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * support wlanoidSetP2pPowerSaveProfile() in P2P -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * Support wlanoidSetNetworkAddress() for P2P -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * MT6620 is not supporting NDIS_PACKET_TYPE_PROMISCUOUS. -+ * -+ -+ * -+** -+*/ -+ -+#ifndef _WLAN_P2P_H -+#define _WLAN_P2P_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/* Service Discovery */ -+typedef struct _PARAM_P2P_SEND_SD_RESPONSE { -+ PARAM_MAC_ADDRESS rReceiverAddr; -+ UINT_8 fgNeedTxDoneIndication; -+ UINT_8 ucChannelNum; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_SEND_SD_RESPONSE, *P_PARAM_P2P_SEND_SD_RESPONSE; -+ -+typedef struct _PARAM_P2P_GET_SD_REQUEST { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_GET_SD_REQUEST, *P_PARAM_P2P_GET_SD_REQUEST; -+ -+typedef struct _PARAM_P2P_GET_SD_REQUEST_EX { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 ucChannelNum; /* Channel Number Where SD Request is received. */ -+ UINT_8 ucSeqNum; /* Get SD Request by sequence number. */ -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_GET_SD_REQUEST_EX, *P_PARAM_P2P_GET_SD_REQUEST_EX; -+ -+typedef struct _PARAM_P2P_SEND_SD_REQUEST { -+ PARAM_MAC_ADDRESS rReceiverAddr; -+ UINT_8 fgNeedTxDoneIndication; -+ UINT_8 ucVersionNum; /* Indicate the Service Discovery Supplicant Version. */ -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_SEND_SD_REQUEST, *P_PARAM_P2P_SEND_SD_REQUEST; -+ -+/* Service Discovery 1.0. */ -+typedef struct _PARAM_P2P_GET_SD_RESPONSE { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_GET_SD_RESPONSE, *P_PARAM_P2P_GET_SD_RESPONSE; -+ -+/* Service Discovery 2.0. */ -+typedef struct _PARAM_P2P_GET_SD_RESPONSE_EX { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 ucSeqNum; /* Get SD Response by sequence number. */ -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_GET_SD_RESPONSE_EX, *P_PARAM_P2P_GET_SD_RESPONSE_EX; -+ -+typedef struct _PARAM_P2P_TERMINATE_SD_PHASE { -+ PARAM_MAC_ADDRESS rPeerAddr; -+} PARAM_P2P_TERMINATE_SD_PHASE, *P_PARAM_P2P_TERMINATE_SD_PHASE; -+ -+/*! \brief Key mapping of BSSID */ -+typedef struct _P2P_PARAM_KEY_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4KeyIndex; /*!< KeyID */ -+ UINT_32 u4KeyLength; /*!< Key length in bytes */ -+ PARAM_MAC_ADDRESS arBSSID; /*!< MAC address */ -+ PARAM_KEY_RSC rKeyRSC; -+ UINT_8 aucKeyMaterial[32]; /*!< Key content by above setting */ -+} P2P_PARAM_KEY_T, *P_P2P_PARAM_KEY_T; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/*--------------------------------------------------------------*/ -+/* Routines to handle command */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAddP2PKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRemoveP2PKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2PMulticastList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+/*--------------------------------------------------------------*/ -+/* Service Discovery Subroutines */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendP2PSDRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSendP2PSDResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidGetP2PSDRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidGetP2PSDResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 puQueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2PTerminateSDPhase(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+WLAN_STATUS -+wlanoidSetSecCheckRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidGetSecCheckResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+#endif -+ -+WLAN_STATUS -+wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2pSetNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryP2pOpChannel(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryP2pVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2pSupplicantVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2pWPSmode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+WLAN_STATUS -+wlanoidQueryP2pRssi(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+#endif -+ -+/*--------------------------------------------------------------*/ -+/* Callbacks for event indication */ -+/*--------------------------------------------------------------*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -+#endif /* _WLAN_P2P_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c -new file mode 100644 -index 0000000000000..f2324f13280e3 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c -@@ -0,0 +1,1303 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/aaa_fsm.c#2 -+*/ -+ -+/*! \file "aaa_fsm.c" -+ \brief This file defines the FSM for AAA MODULE. -+ -+ This file defines the FSM for AAA MODULE. -+*/ -+ -+/* -+** Log: aaa_fsm.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 02 22 2012 yuche.tsai -+ * NULL -+ * Solve sigma test 5.1.3 issue, assoc response should have P2P IE. -+ * -+ * 12 02 2011 yuche.tsai -+ * NULL -+ * Resolve inorder issue under AP mode. -+ * -+ * data frame may TX before assoc response frame. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 06 17 2011 terry.wu -+ * NULL -+ * Add BoW 11N support. -+ * -+ * 06 02 2011 eddie.chen -+ * [WCXRP00000759] [MT6620 Wi-Fi][DRV] Update RCPI in AAA -+ * Update RCPI when receiving Assoc request. -+ * -+ * 04 21 2011 terry.wu -+ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame -+ * Add network type parameter to authSendAuthFrame. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 04 09 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Change Link connection event procedure and change skb length check to 1512 bytes. -+ * -+ * 03 09 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * Skip to call p2pRunEventAAAComplete to avoid indicate STA connect twice. -+ * -+ * 03 04 2011 terry.wu -+ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection -+ * Remove unused variable. -+ * -+ * 02 16 2011 yuche.tsai -+ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue -+ * Add more check after RX assoc frame under Hot-Spot mode. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue -+ * Fix Client Limit Issue. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 15 2011 puff.wen -+ * NULL -+ * [On behalf of Frog] Add CFG_ENABLE_WIFI_DIRECT to p2pRunEventAAAComplete -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Modify AAA flow according to CM's comment. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Fix Compile warning, type cast from UINT_32 to UINT_16. -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * In P2P AT GO test mode under WinXP, we would not indicate connected event to host. -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 kevin.huang -+ * NULL -+ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete() -+ * -+ * 08 17 2010 yuche.tsai -+ * NULL -+ * Fix bug while enabling P2P GO. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * refine TX-DONE callback. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * modify due to P2P functino call prototype change. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * First draft for migration P2P FSM from FW to Driver. -+ * -+ * 04 02 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Modify CFG flags -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * add support of Driver STA_RECORD_T activation -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send Event to AIS/BOW/P2P -+* -+* @param[in] rJoinStatus To indicate JOIN success or failure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] prSwRfb Pointer to the SW_RFB_T -+ -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS aaaFsmSendEventJoinComplete(WLAN_STATUS rJoinStatus, P_STA_RECORD_T prStaRec, P_SW_RFB_T prSwRfb) -+{ -+ P_MSG_SAA_JOIN_COMP_T prJoinCompMsg; -+ -+ ASSERT(prStaRec); -+ -+ prJoinCompMsg = cnmMemAlloc(RAM_TYPE_TCM, sizeof(MSG_SAA_JOIN_COMP_T)); -+ if (!prJoinCompMsg) -+ return WLAN_STATUS_RESOURCES; -+ -+ if (IS_STA_IN_AIS(prStaRec)) -+ prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE; -+ else if (IS_STA_IN_P2P(prStaRec)) -+ prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE; -+ else if (IS_STA_IN_BOW(prStaRec)) -+ prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE; -+ else -+ ASSERT(0); -+ -+ prJoinCompMsg->rJoinStatus = rJoinStatus; -+ prJoinCompMsg->prStaRec = prStaRec; -+ prJoinCompMsg->prSwRfb = prSwRfb; -+ -+ mboxSendMsg(MBOX_ID_0, (P_MSG_HDR_T) prJoinCompMsg, MSG_SEND_METHOD_BUF); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of saaFsmSendEventJoinComplete() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Start Event to AAA FSM. -+* -+* @param[in] prMsgHdr Message of Join Request for a particular STA. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aaaFsmRunEventStart(IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SAA_JOIN_REQ_T prJoinReqMsg; -+ P_STA_RECORD_T prStaRec; -+ P_AIS_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prMsgHdr); -+ -+ prJoinReqMsg = (P_MSG_SAA_JOIN_REQ_T) prMsgHdr; -+ prStaRec = prJoinReqMsg->prStaRec; -+ -+ ASSERT(prStaRec); -+ -+ DBGLOG(SAA, LOUD, "EVENT-START: Trigger SAA FSM\n"); -+ -+ cnmMemFree(prMsgHdr); -+ -+ /* 4 <1> Validation of SAA Start Event */ -+ if (!IS_AP_STA(prStaRec->eStaType)) { -+ -+ DBGLOG(SAA, ERROR, "EVENT-START: STA Type - %d was not supported.\n", prStaRec->eStaType); -+ -+ /* Ignore the return value because don't care the prSwRfb */ -+ saaFsmSendEventJoinComplete(WLAN_STATUS_FAILURE, prStaRec, NULL); -+ -+ return; -+ } -+ /* 4 <2> The previous JOIN process is not completed ? */ -+ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { -+ DBGLOG(SAA, ERROR, "EVENT-START: Reentry of SAA Module.\n"); -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+ } -+ /* 4 <3> Reset Status Code and Time */ -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ -+ /* Update the record join time. */ -+ GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime); -+ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ if (prStaRec->prChallengeText) { -+ cnmMemFree(prStaRec->prChallengeText); -+ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; -+ } -+ -+ cnmTimerStopTimer(&prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ prStaRec->ucStaState = STA_STATE_1; -+ -+ /* Trigger SAA MODULE */ -+ saaFsmSteps(prStaRec, SAA_STATE_SEND_AUTH1, (P_SW_RFB_T) NULL); -+ -+} /* end of saaFsmRunEventStart() */ -+#endif -+ -+#if CFG_SUPPORT_AAA -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx Auth Request Frame and then -+* trigger AAA FSM. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aaaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ UINT_16 u2StatusCode; -+ BOOLEAN fgReplyAuth = FALSE; -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ -+ ASSERT(prAdapter); -+ -+ do { -+ -+ /* 4 <1> Check P2P network conditions */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) { -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ if (prBssInfo->fgIsNetActive) { -+ -+ /* 4 <1.1> Validate Auth Frame by Auth Algorithm/Transation Seq */ -+ if (WLAN_STATUS_SUCCESS == -+ authProcessRxAuth1Frame(prAdapter, -+ prSwRfb, -+ prBssInfo->aucBSSID, -+ AUTH_ALGORITHM_NUM_OPEN_SYSTEM, -+ AUTH_TRANSACTION_SEQ_1, &u2StatusCode)) { -+ -+ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { -+ /* 4 <1.2> Validate Auth Frame for Network Specific Conditions */ -+ fgReplyAuth = p2pFuncValidateAuth(prAdapter, -+ prSwRfb, &prStaRec, &u2StatusCode); -+ } else { -+ fgReplyAuth = TRUE; -+ } -+ eNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ break; -+ } -+ } -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ /* 4 <2> Check BOW network conditions */ -+#if CFG_ENABLE_BT_OVER_WIFI -+ { -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ if ((prBssInfo->fgIsNetActive) && (OP_MODE_BOW == prBssInfo->eCurrentOPMode)) { -+ -+ /* 4 <2.1> Validate Auth Frame by Auth Algorithm/Transation Seq */ -+ /* Check if for this BSSID */ -+ if (WLAN_STATUS_SUCCESS == -+ authProcessRxAuth1Frame(prAdapter, -+ prSwRfb, -+ prBssInfo->aucBSSID, -+ AUTH_ALGORITHM_NUM_OPEN_SYSTEM, -+ AUTH_TRANSACTION_SEQ_1, &u2StatusCode)) { -+ -+ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { -+ -+ /* 4 <2.2> Validate Auth Frame for Network Specific Conditions */ -+ fgReplyAuth = -+ bowValidateAuth(prAdapter, prSwRfb, &prStaRec, &u2StatusCode); -+ -+ } else { -+ -+ fgReplyAuth = TRUE; -+ } -+ eNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ /* TODO(Kevin): Allocate a STA_RECORD_T for new client */ -+ break; -+ } -+ } -+ } -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+ return; -+ } while (FALSE); -+ -+ if (prStaRec) { -+ /* update RCPI */ -+ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; -+ } -+ /* 4 <3> Update STA_RECORD_T and reply Auth_2(Response to Auth_1) Frame */ -+ if (fgReplyAuth) { -+ -+ if (prStaRec) { -+ -+ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { -+ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { -+ DBGLOG(AAA, WARN, "Previous AuthAssocState (%d) != IDLE.\n", -+ prStaRec->eAuthAssocState); -+ } -+ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; -+ } else { -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+ -+ /* NOTE(Kevin): Change to STATE_1 */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ } -+ -+ /* Update the record join time. */ -+ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); -+ -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = u2StatusCode; -+ -+ prStaRec->ucAuthAlgNum = AUTH_ALGORITHM_NUM_OPEN_SYSTEM; -+ } else { -+ /* NOTE(Kevin): We should have STA_RECORD_T if the status code was successful */ -+ ASSERT(!(u2StatusCode == STATUS_CODE_SUCCESSFUL)); -+ } -+ -+ /* NOTE: Ignore the return status for AAA */ -+ /* 4 <4> Reply Auth */ -+ authSendAuthFrame(prAdapter, prStaRec, eNetTypeIndex, prSwRfb, AUTH_TRANSACTION_SEQ_2, u2StatusCode); -+ -+ } -+ -+} /* end of aaaFsmRunEventRxAuth() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx (Re)Association Request Frame and then -+* trigger AAA FSM. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always return success -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS aaaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ UINT_16 u2StatusCode = STATUS_CODE_RESERVED; -+ BOOLEAN fgReplyAssocResp = FALSE; -+ -+ ASSERT(prAdapter); -+ -+ do { -+ -+ /* 4 <1> Check if we have the STA_RECORD_T for incoming Assoc Req */ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ /* We should have the corresponding Sta Record. */ -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) { -+ ASSERT(0); /* Only for debug phase */ -+ break; -+ } -+ -+ if (!IS_CLIENT_STA(prStaRec)) -+ break; -+ -+ if (prStaRec->ucStaState == STA_STATE_3) { -+ /* Do Reassocation */ -+ } else if ((prStaRec->ucStaState == STA_STATE_2) && -+ (prStaRec->eAuthAssocState == AAA_STATE_SEND_AUTH2)) { -+ /* Normal case */ -+ } else { -+ DBGLOG(AAA, INFO, "Previous AuthAssocState (%d) != SEND_AUTH2, ucStaState:%d.\n", -+ prStaRec->eAuthAssocState, -+ prStaRec->ucStaState); -+ /* TODO: Why assoc req event is faster than tx done of auth */ -+ if (prStaRec->eAuthAssocState != AAA_STATE_SEND_AUTH2) -+ break; -+ } -+ -+ /* update RCPI */ -+ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; -+ -+ /* 4 <2> Check P2P network conditions */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ if (prBssInfo->fgIsNetActive) { -+ -+ /* 4 <2.1> Validate Assoc Req Frame and get Status Code */ -+ /* Check if for this BSSID */ -+ if (WLAN_STATUS_SUCCESS == -+ assocProcessRxAssocReqFrame(prAdapter, prSwRfb, &u2StatusCode)) { -+ -+ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { -+ /* 4 <2.2> Validate Assoc Req Frame for Network Specific Conditions */ -+ fgReplyAssocResp = p2pFuncValidateAssocReq(prAdapter, -+ prSwRfb, -+ (PUINT_16)&u2StatusCode); -+ } else { -+ fgReplyAssocResp = TRUE; -+ } -+ -+ break; -+ } -+ } -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ /* 4 <3> Check BOW network conditions */ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (IS_STA_IN_BOW(prStaRec)) { -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ if ((prBssInfo->fgIsNetActive) && (OP_MODE_BOW == prBssInfo->eCurrentOPMode)) { -+ -+ /* 4 <3.1> Validate Auth Frame by Auth Algorithm/Transation Seq */ -+ /* Check if for this BSSID */ -+ if (WLAN_STATUS_SUCCESS == -+ assocProcessRxAssocReqFrame(prAdapter, prSwRfb, &u2StatusCode)) { -+ -+ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { -+ -+ /* 4 <3.2> Validate Auth Frame for Network Specific Conditions */ -+ fgReplyAssocResp = -+ bowValidateAssocReq(prAdapter, prSwRfb, &u2StatusCode); -+ -+ } else { -+ -+ fgReplyAssocResp = TRUE; -+ } -+ -+ /* TODO(Kevin): Allocate a STA_RECORD_T for new client */ -+ break; -+ } -+ } -+ } -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+ return WLAN_STATUS_SUCCESS; /* To release the SW_RFB_T */ -+ } while (FALSE); -+ -+ /* 4 <4> Update STA_RECORD_T and reply Assoc Resp Frame */ -+ if (fgReplyAssocResp) { -+ UINT_16 u2IELength; -+ PUINT_8 pucIE; -+ -+ if ((((P_WLAN_ASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->u2FrameCtrl & MASK_FRAME_TYPE) == -+ MAC_FRAME_REASSOC_REQ) { -+ -+ u2IELength = prSwRfb->u2PacketLen - -+ (UINT_16) OFFSET_OF(WLAN_REASSOC_REQ_FRAME_T, aucInfoElem[0]); -+ -+ pucIE = ((P_WLAN_REASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem; -+ } else { -+ u2IELength = prSwRfb->u2PacketLen - (UINT_16) OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem[0]); -+ -+ pucIE = ((P_WLAN_ASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem; -+ } -+ -+ rlmProcessAssocReq(prAdapter, prSwRfb, pucIE, u2IELength); -+ -+ /* 4 <4.1> Assign Association ID */ -+ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { -+ if (p2pRunEventAAAComplete(prAdapter, prStaRec) == WLAN_STATUS_SUCCESS) { -+ prStaRec->u2AssocId = bssAssignAssocID(prStaRec); -+ /* prStaRec->eAuthAssocState = AA_STATE_IDLE; */ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_ASSOC2;/* NOTE(Kevin): for TX done */ -+ -+ /* NOTE(Kevin): Method A: Change to STATE_3 before handle TX Done */ -+ /* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */ -+ } else { -+ /* Client List FULL. */ -+ u2StatusCode = STATUS_CODE_REQ_DECLINED; -+ -+ prStaRec->u2AssocId = 0; /* Invalid Association ID */ -+ -+ /* If (Re)association fail, the peer can try Association w/o Auth immediately */ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; -+ -+ /* NOTE(Kevin): Better to change state here, not at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ } -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if ((IS_STA_IN_BOW(prStaRec))) { -+ /* if (bowRunEventAAAComplete(prAdapter, prStaRec) == WLAN_STATUS_SUCCESS) { */ -+ prStaRec->u2AssocId = bssAssignAssocID(prStaRec); -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_ASSOC2; /* NOTE(Kevin): for TX done */ -+ -+ /* NOTE(Kevin): Method A: Change to STATE_3 before handle TX Done */ -+ /* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */ -+ } -+#if 0 -+ else { -+ /* Client List FULL. */ -+ u2StatusCode = STATUS_CODE_REQ_DECLINED; -+ -+ prStaRec->u2AssocId = 0; /* Invalid Association ID */ -+ -+ /* If (Re)association fail, the peer can try Association w/o Auth immediately */ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; -+ -+ /* NOTE(Kevin): Better to change state here, not at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ } -+ } -+#endif -+#endif -+ } else { -+ prStaRec->u2AssocId = 0; /* Invalid Association ID */ -+ -+ /* If (Re)association fail, the peer can try Association w/o Auth immediately */ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; -+ -+ /* NOTE(Kevin): Better to change state here, not at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ } -+ -+ /* Update the record join time. */ -+ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); -+ -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = u2StatusCode; -+ -+ /* NOTE: Ignore the return status for AAA */ -+ /* 4 <4.2> Reply Assoc Resp */ -+ assocSendReAssocRespFrame(prAdapter, prStaRec); -+ -+} -+ -+return WLAN_STATUS_SUCCESS; -+ -+} /* end of aaaFsmRunEventRxAssoc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle TxDone(Auth2/AssocReq) Event of AAA FSM. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prMsduInfo Pointer to the MSDU_INFO_T. -+* @param[in] rTxDoneStatus Return TX status of the Auth1/Auth3/AssocReq frame. -+* -+* @retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+aaaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ DBGLOG(AAA, LOUD, "EVENT-TX DONE: Current Time = %lu\n", (unsigned long)kalGetTimeTick()); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) { -+ DBGLOG(AAA, INFO, "EVENT-TX DONE: Invalid StaRec"); -+ return WLAN_STATUS_SUCCESS; /* For the case of replying ERROR STATUS CODE */ -+ } -+ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ DBGLOG(AAA, INFO, "TX DONE status: %d, AuthAssocState: %d, SeqNo: %d\n", -+ rTxDoneStatus, prStaRec->eAuthAssocState, -+ prMsduInfo->ucTxSeqNum); -+ -+ switch (prStaRec->eAuthAssocState) { -+ case AAA_STATE_SEND_AUTH2: -+ { -+ /* Strictly check the outgoing frame is matched with current AA STATE */ -+ if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_2) != WLAN_STATUS_SUCCESS) -+ break; -+ -+ if (STATUS_CODE_SUCCESSFUL == prStaRec->u2StatusCode) { -+ if (TX_RESULT_SUCCESS == rTxDoneStatus) { -+ -+ /* NOTE(Kevin): Change to STATE_2 at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ } else { -+ -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+ -+ /* NOTE(Kevin): Change to STATE_1 */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) -+ p2pRunEventAAATxFail(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (IS_STA_IN_BOW(prStaRec)) -+ bowRunEventAAATxFail(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ } -+ -+ } -+ /* NOTE(Kevin): Ignore the TX Done Event of Auth Frame with Error Status Code */ -+ -+ } -+ break; -+ -+ case AAA_STATE_SEND_ASSOC2: -+ { -+ /* Strictly check the outgoing frame is matched with current SAA STATE */ -+ if (assocCheckTxReAssocRespFrame(prAdapter, prMsduInfo) != WLAN_STATUS_SUCCESS) -+ break; -+ -+ if (STATUS_CODE_SUCCESSFUL == prStaRec->u2StatusCode) { -+ if (TX_RESULT_SUCCESS == rTxDoneStatus) { -+ -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+ -+ /* NOTE(Kevin): Change to STATE_3 at TX Done */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) -+ p2pRunEventAAASuccess(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ -+ if (IS_STA_IN_BOW(prStaRec)) -+ bowRunEventAAAComplete(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+ } else { -+ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; -+ -+ /* NOTE(Kevin): Change to STATE_2 */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) -+ p2pRunEventAAATxFail(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (IS_STA_IN_BOW(prStaRec)) -+ bowRunEventAAATxFail(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+ } -+ } -+ /* NOTE(Kevin): Ignore the TX Done Event of Auth Frame with Error Status Code */ -+ } -+ break; -+ -+ default: -+ break; /* Ignore other cases */ -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of aaaFsmRunEventTxDone() */ -+#endif /* CFG_SUPPORT_AAA */ -+ -+#if 0 /* TODO(Kevin): for abort event, just reset the STA_RECORD_T. */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will send ABORT Event to JOIN FSM. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventAbort(IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("joinFsmRunEventAbort"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ -+ DBGLOG(JOIN, EVENT, "JOIN EVENT: ABORT\n"); -+ -+ /* NOTE(Kevin): when reach here, the ARB_STATE should be in ARB_STATE_JOIN. */ -+ ASSERT(prJoinInfo->prBssDesc); -+ -+ /* 4 <1> Update Flags and Elements of JOIN Module. */ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prJoinInfo->ucTxAuthAssocRetryCount = 0; -+ -+ /* Cancel all JOIN relative Timer */ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); -+ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); -+ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rJoinTimer); -+ -+ /* 4 <2> Update the associated STA_RECORD_T during JOIN. */ -+ /* Get a Station Record if possible, TA == BSSID for AP */ -+ prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID); -+ if (prStaRec) -+ prStaRec->ucStaState = STA_STATE_1; /* Update Station Record - Class 1 Flag */ -+#if DBG -+ else -+ ASSERT(0); /* Shouldn't happened, because we already add this STA_RECORD_T at JOIN_STATE_INIT */ -+#endif /* DBG */ -+ -+ /* 4 <3> Pull back to IDLE. */ -+ joinFsmSteps(prAdapter, JOIN_STATE_IDLE); -+ -+ /* 4 <4> If we are in Roaming, recover the settings of previous BSS. */ -+ /* NOTE: JOIN FAIL - -+ * Restore original setting from current BSS_INFO_T. -+ */ -+ if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) -+ joinAdoptParametersFromCurrentBss(prAdapter); -+ -+} /* end of joinFsmRunEventAbort() */ -+#endif -+ -+/* TODO(Kevin): following code will be modified and move to AIS FSM */ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will send Join Timeout Event to JOIN FSM. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \retval WLAN_STATUS_FAILURE Fail because of Join Timeout -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS joinFsmRunEventJoinTimeOut(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("joinFsmRunEventJoinTimeOut"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ -+ DBGLOG(JOIN, EVENT, "JOIN EVENT: JOIN TIMEOUT\n"); -+ -+ /* Get a Station Record if possible, TA == BSSID for AP */ -+ prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID); -+ -+ /* We have renew this Sta Record when in JOIN_STATE_INIT */ -+ ASSERT(prStaRec); -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT; -+ -+ /* Increase Failure Count */ -+ prStaRec->ucJoinFailureCount++; -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prJoinInfo->ucTxAuthAssocRetryCount = 0; -+ -+ /* Cancel other JOIN relative Timer */ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); -+ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); -+ -+ /* Restore original setting from current BSS_INFO_T */ -+ if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) -+ joinAdoptParametersFromCurrentBss(prAdapter); -+ -+ /* Pull back to IDLE */ -+ joinFsmSteps(prAdapter, JOIN_STATE_IDLE); -+ -+ return WLAN_STATUS_FAILURE; -+ -+} /* end of joinFsmRunEventJoinTimeOut() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will adopt the parameters from Peer BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinAdoptParametersFromPeerBss(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_BSS_DESC_T prBssDesc; -+ -+ DEBUGFUNC("joinAdoptParametersFromPeerBss"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ prBssDesc = prJoinInfo->prBssDesc; -+ -+ /* 4 <1> Adopt Peer BSS' PHY TYPE */ -+ prAdapter->eCurrentPhyType = prBssDesc->ePhyType; -+ -+ DBGLOG(JOIN, INFO, "Target BSS[%s]'s PhyType = %s\n", -+ prBssDesc->aucSSID, (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? "ERP" : "HR_DSSS"); -+ -+ /* 4 <2> Adopt Peer BSS' Frequency(Band/Channel) */ -+ DBGLOG(JOIN, INFO, "Target BSS's Channel = %d, Band = %d\n", prBssDesc->ucChannelNum, prBssDesc->eBand); -+ -+ nicSwitchChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum, 10); -+ -+ prJoinInfo->fgIsParameterAdopted = TRUE; -+ -+} /* end of joinAdoptParametersFromPeerBss() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will adopt the parameters from current associated BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinAdoptParametersFromCurrentBss(IN P_ADAPTER_T prAdapter) -+{ -+ /* P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo; */ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ prBssInfo = &prAdapter->rBssInfo; -+ -+ /* 4 <1> Adopt current BSS' PHY TYPE */ -+ prAdapter->eCurrentPhyType = prBssInfo->ePhyType; -+ -+ /* 4 <2> Adopt current BSS' Frequency(Band/Channel) */ -+ DBGLOG(JOIN, INFO, "Current BSS's Channel = %d, Band = %d\n", prBssInfo->ucChnl, prBssInfo->eBand); -+ -+ nicSwitchChannel(prAdapter, prBssInfo->eBand, prBssInfo->ucChnl, 10); -+ -+} /* end of joinAdoptParametersFromCurrentBss() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will update all the SW variables and HW MCR registers after -+* the association with target BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinComplete(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_BSS_DESC_T prBssDesc; -+ P_PEER_BSS_INFO_T prPeerBssInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_STA_RECORD_T prStaRec; -+ P_TX_CTRL_T prTxCtrl; -+#if CFG_SUPPORT_802_11D -+ P_IE_COUNTRY_T prIECountry; -+#endif -+ -+ DEBUGFUNC("joinComplete"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ prBssDesc = prJoinInfo->prBssDesc; -+ prPeerBssInfo = &prAdapter->rPeerBssInfo; -+ prBssInfo = &prAdapter->rBssInfo; -+ prConnSettings = &prAdapter->rConnSettings; -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+/* 4 <1> Update Connecting & Connected Flag of BSS_DESC_T. */ -+ /* Remove previous AP's Connection Flags if have */ -+ scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, prBssInfo->aucBSSID); -+ -+ prBssDesc->fgIsConnected = TRUE; /* Mask as Connected */ -+ -+ if (prBssDesc->fgIsHiddenSSID) { -+ /* NOTE(Kevin): This is for the case of Passive Scan and the target BSS didn't -+ * broadcast SSID on its Beacon Frame. -+ */ -+ COPY_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prAdapter->rConnSettings.aucSSID, prAdapter->rConnSettings.ucSSIDLen); -+ -+ if (prBssDesc->ucSSIDLen) -+ prBssDesc->fgIsHiddenSSID = FALSE; -+#if DBG -+ else -+ ASSERT(0); -+#endif /* DBG */ -+ -+ DBGLOG(JOIN, INFO, "Hidden SSID! - Update SSID : %s\n", prBssDesc->aucSSID); -+ } -+/* 4 <2> Update BSS_INFO_T from BSS_DESC_T */ -+ /* 4 <2.A> PHY Type */ -+ prBssInfo->ePhyType = prBssDesc->ePhyType; -+ -+ /* 4 <2.B> BSS Type */ -+ prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE; -+ -+ /* 4 <2.C> BSSID */ -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID); -+ -+ DBGLOG(JOIN, INFO, "JOIN to BSSID: [%pM]\n", prBssDesc->aucBSSID); -+ -+ /* 4 <2.D> SSID */ -+ COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ -+ /* 4 <2.E> Channel / Band information. */ -+ prBssInfo->eBand = prBssDesc->eBand; -+ prBssInfo->ucChnl = prBssDesc->ucChannelNum; -+ -+ /* 4 <2.F> RSN/WPA information. */ -+ secFsmRunEventStart(prAdapter); -+ prBssInfo->u4RsnSelectedPairwiseCipher = prBssDesc->u4RsnSelectedPairwiseCipher; -+ prBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher; -+ prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; -+ -+ if (secRsnKeyHandshakeEnabled()) -+ prBssInfo->fgIsWPAorWPA2Enabled = TRUE; -+ else -+ prBssInfo->fgIsWPAorWPA2Enabled = FALSE; -+ -+ /* 4 <2.G> Beacon interval. */ -+ prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; -+ -+ /* 4 <2.H> DTIM period. */ -+ prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod; -+ -+ /* 4 <2.I> ERP Information */ -+ if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) && /* Our BSS's PHY_TYPE is ERP now. */ -+ (prBssDesc->fgIsERPPresent)) { -+ -+ prBssInfo->fgIsERPPresent = TRUE; -+ prBssInfo->ucERP = prBssDesc->ucERP; /* Save the ERP for later check */ -+ } else { /* Some AP, may send ProbeResp without ERP IE. Thus prBssDesc->fgIsERPPresent is FALSE. */ -+ prBssInfo->fgIsERPPresent = FALSE; -+ prBssInfo->ucERP = 0; -+ } -+ -+#if CFG_SUPPORT_802_11D -+ /* 4 <2.J> Country inforamtion of the associated AP */ -+ if (prConnSettings->fgMultiDomainCapabilityEnabled) { -+ DOMAIN_INFO_ENTRY rDomainInfo; -+ -+ if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) { -+ if (prBssDesc->prIECountry) { -+ prIECountry = prBssDesc->prIECountry; -+ -+ domainParseCountryInfoElem(prIECountry, &prBssInfo->rDomainInfo); -+ -+ /* use the domain get from the BSS info */ -+ prBssInfo->fgIsCountryInfoPresent = TRUE; -+ nicSetupOpChnlList(prAdapter, prBssInfo->rDomainInfo.u2CountryCode, FALSE); -+ } else { -+ /* use the domain get from the scan result */ -+ prBssInfo->fgIsCountryInfoPresent = TRUE; -+ nicSetupOpChnlList(prAdapter, rDomainInfo.u2CountryCode, FALSE); -+ } -+ } -+ } -+#endif -+ -+ /* 4 <2.K> Signal Power of the associated AP */ -+ prBssInfo->rRcpi = prBssDesc->rRcpi; -+ prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi); -+ GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime); -+ -+ /* 4 <2.L> Capability Field of the associated AP */ -+ prBssInfo->u2CapInfo = prBssDesc->u2CapInfo; -+ -+ DBGLOG(JOIN, INFO, "prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n", -+ prBssInfo->fgIsERPPresent, prBssInfo->ucERP, prBssInfo->rRcpi, prBssInfo->rRssi); -+ -+/* 4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC */ -+ /* 4 <3.A> Association ID */ -+ prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId; -+ -+ /* 4 <3.B> WMM Information */ -+ if (prAdapter->fgIsEnableWMM && (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) { -+ -+ prBssInfo->fgIsWmmAssoc = TRUE; -+ prTxCtrl->rTxQForVoipAccess = TXQ_AC3; -+ -+ qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE); -+ -+ if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) { -+ kalMemCopy(&prBssInfo->rWmmInfo, &prPeerBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); -+ } else { -+ kalMemCopy(&prBssInfo->rWmmInfo, -+ &prPeerBssInfo->rWmmInfo, -+ sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams)); -+ } -+ } else { -+ prBssInfo->fgIsWmmAssoc = FALSE; -+ prTxCtrl->rTxQForVoipAccess = TXQ_AC1; -+ -+ kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); -+ } -+ -+ /* 4 <3.C> Operational Rate Set & BSS Basic Rate Set */ -+ prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet; -+ prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet; -+ -+ /* 4 <3.D> Short Preamble */ -+ if (prBssInfo->fgIsERPPresent) { -+ -+ /* NOTE(Kevin 2007/12/24): Truth Table. -+ * Short Preamble Bit in -+ * Final Driver Setting(Short) -+ * TRUE FALSE FALSE FALSE(shouldn't have such case, -+ * use the AssocResp) -+ * TRUE FALSE TRUE FALSE -+ * FALSE FALSE FALSE FALSE(shouldn't have such case, -+ * use the AssocResp) -+ * FALSE FALSE TRUE FALSE -+ * TRUE TRUE FALSE TRUE(follow ERP) -+ * TRUE TRUE TRUE FALSE(follow ERP) -+ * FALSE TRUE FALSE FALSE(shouldn't have such case, -+ * and we should set to FALSE) -+ * FALSE TRUE TRUE FALSE(we should set to FALSE) -+ */ -+ if ((prPeerBssInfo->fgIsShortPreambleAllowed) && -+ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ -+ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) && -+ (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { -+ -+ prBssInfo->fgIsShortPreambleAllowed = TRUE; -+ -+ if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) -+ prBssInfo->fgUseShortPreamble = FALSE; -+ else -+ prBssInfo->fgUseShortPreamble = TRUE; -+ } else { -+ prBssInfo->fgIsShortPreambleAllowed = FALSE; -+ prBssInfo->fgUseShortPreamble = FALSE; -+ } -+ } else { -+ /* NOTE(Kevin 2007/12/24): Truth Table. -+ * Short Preamble Bit in -+ * Final Driver Setting(Short) -+ * TRUE FALSE FALSE -+ * FALSE FALSE FALSE -+ * TRUE TRUE TRUE -+ * FALSE TRUE(status success) TRUE -+ * --> Honor the result of prPeerBssInfo. -+ */ -+ -+ prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble = -+ prPeerBssInfo->fgIsShortPreambleAllowed; -+ } -+ -+ DBGLOG(JOIN, INFO, "prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n", -+ prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble); -+ -+ /* 4 <3.E> Short Slot Time */ -+ prBssInfo->fgUseShortSlotTime = prPeerBssInfo->fgUseShortSlotTime; /* AP support Short Slot Time */ -+ -+ DBGLOG(JOIN, INFO, "prBssInfo->fgUseShortSlotTime = %d\n", prBssInfo->fgUseShortSlotTime); -+ -+ nicSetSlotTime(prAdapter, -+ prBssInfo->ePhyType, -+ ((prConnSettings->fgIsShortSlotTimeOptionEnable && -+ prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE)); -+ -+ /* 4 <3.F> Update Tx Rate for Control Frame */ -+ bssUpdateTxRateForControlFrame(prAdapter); -+ -+ /* 4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition). */ -+ /* if (prAdapter->fgIsEnableRoaming) */ /* NOTE(Kevin): Always prepare info for roaming */ -+ { -+ -+ if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM) -+ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM; -+ else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) -+ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY; -+ -+ prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes; -+ -+ /* Set the stable time of the associated BSS. We won't do roaming decision -+ * during the stable time. -+ */ -+ SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime, -+ SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC)); -+ } -+ -+ /* 4 <3.H> Update Parameter for TX Fragmentation Threshold */ -+#if CFG_TX_FRAGMENT -+ txFragInfoUpdate(prAdapter); -+#endif /* CFG_TX_FRAGMENT */ -+ -+/* 4 <4> Update STA_RECORD_T */ -+ /* Get a Station Record if possible */ -+ prStaRec = staRecGetStaRecordByAddr(prAdapter, prBssDesc->aucBSSID); -+ -+ if (prStaRec) { -+ UINT_16 u2OperationalRateSet, u2DesiredRateSet; -+ -+ /* 4 <4.A> Desired Rate Set */ -+ u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet & -+ prBssInfo->u2OperationalRateSet); -+ -+ u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet); -+ if (u2DesiredRateSet) { -+ prStaRec->u2DesiredRateSet = u2DesiredRateSet; -+ } else { -+ /* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */ -+ prStaRec->u2DesiredRateSet = u2OperationalRateSet; -+ } -+ -+ /* Try to set the best initial rate for this entry */ -+ if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet, -+ prStaRec->rRcpi, &prStaRec->ucCurrRate1Index)) { -+ -+ if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet, &prStaRec->ucCurrRate1Index)) -+ ASSERT(0); -+ } -+ -+ DBGLOG(JOIN, INFO, "prStaRec->ucCurrRate1Index = %d\n", prStaRec->ucCurrRate1Index); -+ -+ /* 4 <4.B> Preamble Mode */ -+ prStaRec->fgIsShortPreambleOptionEnable = prBssInfo->fgUseShortPreamble; -+ -+ /* 4 <4.C> QoS Flag */ -+ prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc; -+ } -+#if DBG -+ else -+ ASSERT(0); -+#endif /* DBG */ -+ -+/* 4 <5> Update NIC */ -+ /* 4 <5.A> Update BSSID & Operation Mode */ -+ nicSetupBSS(prAdapter, prBssInfo); -+ -+ /* 4 <5.B> Update WLAN Table. */ -+ if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) -+ ASSERT(FALSE); -+ /* 4 <5.C> Update Desired Rate Set for BT. */ -+#if CFG_TX_FRAGMENT -+ if (prConnSettings->fgIsEnableTxAutoFragmentForBT) -+ txRateSetInitForBT(prAdapter, prStaRec); -+#endif /* CFG_TX_FRAGMENT */ -+ -+ /* 4 <5.D> TX AC Parameter and TX/RX Queue Control */ -+ if (prBssInfo->fgIsWmmAssoc) { -+ -+#if CFG_TX_AGGREGATE_HW_FIFO -+ nicTxAggregateTXQ(prAdapter, FALSE); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo); -+ } else { -+ -+#if CFG_TX_AGGREGATE_HW_FIFO -+ nicTxAggregateTXQ(prAdapter, TRUE); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter); -+ -+ nicTxNonQoSUpdateTXQParameters(prAdapter, prBssInfo->ePhyType); -+ } -+ -+#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN -+ { -+ prTxCtrl->fgBlockTxDuringJoin = FALSE; -+ -+#if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */ -+ nicTxFlushStopQueues(prAdapter, (UINT_8) TXQ_DATA_MASK, (UINT_8) NULL); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ nicTxRetransmitOfSendWaitQue(prAdapter); -+ -+ if (prTxCtrl->fgIsPacketInOsSendQueue) -+ nicTxRetransmitOfOsSendQue(prAdapter); -+#if CFG_SDIO_TX_ENHANCE -+ halTxLeftClusteredMpdu(prAdapter); -+#endif /* CFG_SDIO_TX_ENHANCE */ -+ -+ } -+#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */ -+ -+/* 4 <6> Setup CONNECTION flag. */ -+ prAdapter->eConnectionState = MEDIA_STATE_CONNECTED; -+ prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED; -+ -+ if (prJoinInfo->fgIsReAssoc) -+ prAdapter->fgBypassPortCtrlForRoaming = TRUE; -+ else -+ prAdapter->fgBypassPortCtrlForRoaming = FALSE; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, (PVOID) NULL, 0); -+ -+} /* end of joinComplete() */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c -new file mode 100644 -index 0000000000000..7b5a49a5ba631 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c -@@ -0,0 +1,5039 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/ais_fsm.c#1 -+*/ -+ -+/*! \file "aa_fsm.c" -+ \brief This file defines the FSM for SAA and AAA MODULE. -+ -+ This file defines the FSM for SAA and AAA MODULE. -+*/ -+ -+/* -+** Log: ais_fsm.c -+** -+** 09 06 2013 cp.wu -+** always paste SSID information to SAA-FSM -+** -+** 09 06 2013 cp.wu -+** add error handling when reassociation request failed to locate bss descriptor -+** -+** 09 05 2013 cp.wu -+** isolate logic regarding roaming & reassociation -+** -+** 09 04 2013 cp.wu -+** fix typo -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+ * -+ * 04 20 2012 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * correct macro -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with -+ * corresponding network configuration -+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred band configuration -+ * corresponding to network type. -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 22 2011 cp.wu -+ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous -+ * to asynchronous approach to avoid incomplete state termination -+ * 1. change RDD related compile option brace position. -+ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state -+ * without join timeout timer ticking -+ * 3. otherwise, insert AIS_REQUEST into pending request queue -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 04 2011 cp.wu -+ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT for REASSOCIATED -+ * cases as an explicit trigger for Android framework -+ * correct reference to BSSID field in Association-Response frame. -+ * -+ * 11 04 2011 cp.wu -+ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT for REASSOCIATED -+ * cases as an explicit trigger for Android framework -+ * 1. for DEAUTH/DISASSOC cases, indicate for DISCONNECTION immediately. -+ * 2. (Android only) when reassociation-and-non-roaming cases happened, indicate an extra DISCONNECT -+ * indication to Android Wi-Fi framework -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 10 26 2011 tsaiyuan.hsu -+ * [WCXRP00001064] [MT6620 Wi-Fi][DRV]] add code with roaming awareness when disconnecting AIS network -+ * be aware roaming when disconnecting AIS network. -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * STA_REC shall be NULL for Beacon's MSDU -+ * -+ * 10 13 2011 cp.wu -+ * [MT6620 Wi-Fi][Driver] Reduce join failure count limit to 2 for faster re-join for other BSS -+ * 1. short join failure count limit to 2 -+ * 2. treat join timeout as kind of join failure as well -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 30 2011 cm.chang -+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band -+ * . -+ * -+ * 09 20 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * change window registry of driver for roaming. -+ * -+ * 09 20 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * Handle client mode about preamble type and slot time -+ * -+ * 09 08 2011 tsaiyuan.hsu -+ * [WCXRP00000972] [MT6620 Wi-Fi][DRV]] check if roaming occurs after join failure to avoid state incosistence. -+ * check if roaming occurs after join failure to avoid deactivation of network. -+ * -+ * 08 24 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Update RDD test mode cases. -+ * -+ * 08 16 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * EnableRoaming in registry is deprecated. -+ * -+ * 08 16 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * use registry to enable or disable roaming. -+ * -+ * 07 07 2011 cp.wu -+ * [WCXRP00000840] [MT6620 Wi-Fi][Driver][AIS] Stop timer for joining when channel is released -+ * due to join failure count exceeding limit -+ * stop timer when joining operation is failed due to try count exceeds limitation -+ * -+ * 06 28 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work -+ * around some tricky AP which use space character as hidden SSID -+ * do not handle SCAN request immediately after connected to increase the probability of receiving 1st beacon frame. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 06 16 2011 cp.wu -+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout -+ * ensure DEAUTH is always sent before establish a new connection -+ * -+ * 06 16 2011 cp.wu -+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout -+ * typo fix: a right brace is missed. -+ * -+ * 06 16 2011 cp.wu -+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout -+ * When RECONNECT request is identified as disconnected, it is necessary to check for pending scan request. -+ * -+ * 06 16 2011 cp.wu -+ * [WCXRP00000757] [MT6620 Wi-Fi][Driver][SCN] take use of RLM API to filter out BSS in disallowed channels -+ * mark fgIsTransition as TRUE for state rolling. -+ * -+ * 06 16 2011 cp.wu -+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout -+ * always check for pending scan after switched into NORMAL_TR state. -+ * -+ * 06 14 2011 cp.wu -+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout -+ * always treat connection request at higher priority over scanning request -+ * -+ * 06 09 2011 tsaiyuan.hsu -+ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size -+ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. -+ * -+ * 06 02 2011 cp.wu -+ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction -+ * eliminate unused parameters for SAA-FSM -+ * -+ * 05 18 2011 cp.wu -+ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state -+ * when DEAUTH frame is dropped due to bss disconnection -+ * change SCAN handling behavior when followed by a CONNECT/DISCONNECT requests by pending instead of dropping. -+ * -+ * 05 17 2011 cp.wu -+ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state -+ * when DEAUTH frame is dropped due to bss disconnection -+ * when TX DONE status is TX_RESULT_DROPPED_IN_DRIVER, no need to switch back to IDLE state. -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 13 2011 george.huang -+ * [WCXRP00000628] [MT6620 Wi-Fi][FW][Driver] Modify U-APSD setting to default OFF -+ * remove assert -+ * -+ * 03 18 2011 cp.wu -+ * [WCXRP00000575] [MT6620 Wi-Fi][Driver][AIS] reduce memory usage when generating mailbox message for scan request -+ * when there is no IE needed for probe request, then request a smaller memory for mailbox message -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 16 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * remove obsolete definition and unused variables. -+ * -+ * 03 11 2011 cp.wu -+ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently -+ * When fixed channel operation is necessary, AIS-FSM would scan and only connect for BSS on the specific channel -+ * -+ * 03 09 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * avoid clearing fgIsScanReqIssued so as to add scan results. -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 04 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * reset retry conter of attemp to connect to ap after completion of join. -+ * -+ * 03 04 2011 cp.wu -+ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection -+ * surpress compile warning occurred when compiled by GNU compiler collection. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right -+ * after connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 26 2011 tsaiyuan.hsu -+ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support -+ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. -+ * -+ * 02 23 2011 cp.wu -+ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with a queue-based approach to -+ * improve response time for scanning request -+ * when handling reconnect request, set fgTryScan as TRUE -+ * -+ * 02 22 2011 cp.wu -+ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with a queue-based approach -+ * to improve response time for scanning request -+ * handle SCAN and RECONNECT with a FIFO approach. -+ * -+ * 02 09 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * Check if prRegInfo is null or not before initializing roaming parameters. -+ * -+ * 02 01 2011 cp.wu -+ * [WCXRP00000416] [MT6620 Wi-Fi][Driver] treat "unable to find BSS" as connection trial -+ * to prevent infinite reconnection trials -+ * treat "unable to find BSS" as connection trial to prevent infinite reconnection trials. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix Compile Error when DBG is disabled. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 14 2011 cp.wu -+ * [WCXRP00000359] [MT6620 Wi-Fi][Driver] add an extra state to ensure DEAUTH frame is always sent -+ * Add an extra state to guarantee DEAUTH frame is sent then connect to new BSS. -+ * This change is due to WAPI AP needs DEAUTH frame as a necessary step in handshaking protocol. -+ * -+ * 01 11 2011 cp.wu -+ * [WCXRP00000307] [MT6620 Wi-Fi][SQA]WHQL test .2c_wlan_adhoc case fail. -+ * [IBSS] when merged in, the bss state should be updated to firmware to pass WHQL adhoc failed item -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result in OID handling layer -+ * when the corresponding BSS is disconnected due to beacon timeout -+ * remove from scanning result when the BSS is disconnected due to beacon timeout. -+ * -+ * 01 03 2011 cp.wu -+ * [WCXRP00000337] [MT6620 Wi-FI][Driver] AIS-FSM not to invoke cnmStaRecResetStatus -+ * directly 'cause it frees all belonging STA-RECs -+ * do not invoke cnmStaRecResetStatus() directly, nicUpdateBss will do the things after bss is disconnected -+ * -+ * 12 30 2010 cp.wu -+ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged -+ * do not need to manipulate prStaRec after indicating BSS disconnection to firmware, -+ * 'cause all STA-RECs belongs to BSS has been freed already -+ * -+ * 12 27 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * add DEBUGFUNC() macro invoking for more detailed debugging information -+ * -+ * 12 23 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * 1. update WMM IE parsing, with ASSOC REQ handling -+ * 2. extend U-APSD parameter passing from driver to FW -+ * -+ * 12 17 2010 cp.wu -+ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged -+ * before BSS disconnection is indicated to firmware, all correlated peer should be cleared and freed -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 11 25 2010 yuche.tsai -+ * NULL -+ * Update SLT Function for QoS Support and not be affected by fixed rate function. -+ * -+ * 11 25 2010 cp.wu -+ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM -+ * add scanning with specified SSID facility to AIS-FSM -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with -+ * Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate -+ * from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] -+ * Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000097] [MT6620 Wi-Fi] [Driver] Fixed the P2P not setting the fgIsChannelExt value make scan not abort -+ * initial the fgIsChannelExt value. -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000087] [MT6620 Wi-Fi][Driver] Cannot connect to 5GHz AP, driver will cause FW assert. -+ * correct erroneous logic: specifying eBand with incompatible eSco -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T -+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000049] [MT6620 Wi-Fi][Driver] Adhoc cannot be created successfully. -+ * keep IBSS-ALONE state retrying until further instruction is received -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD -+ * when entering RF test with AIS associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 09 2010 yuche.tsai -+ * NULL -+ * Fix NULL IE Beacon issue. Sync Beacon Content to FW before enable beacon. -+ * Both in IBSS Create & IBSS Merge -+ * -+ * 09 09 2010 cp.wu -+ * NULL -+ * frequency is in unit of KHz thus no need to divide 1000 once more. -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * 1) initialize for correct parameter even for disassociation. -+ * 2) AIS-FSM should have a limit on trials to build connection -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Finish SLT TX/RX & Rate Changing Support. -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * add option for enabling AIS 5GHz scan -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * [AIS-FSM] IBSS no longer needs to acquire channel for beaconing, -+ * RLM/CNM will handle the channel switching when BSS information is updated -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * check-in missed files. -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 09 2010 cp.wu -+ * NULL -+ * reset fgIsScanReqIssued when abort request is received right after join completion. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 02 2010 cp.wu -+ * NULL -+ * comment out deprecated members in BSS_INFO, which are only used by firmware rather than driver. -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * allocate on MGMT packet for IBSS beaconing. -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * [AIS-FSM] fix: when join failed, release channel privilege as well -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * reuse join-abort sub-procedure to reduce code size. -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 26 2010 cp.wu -+ * -+ * AIS-FSM: when scan request is coming in the 1st 5 seconds of channel privilege period, -+ * just pend it til 5-sec. period finishes -+ * -+ * 07 26 2010 cp.wu -+ * -+ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet -+ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found -+ * -+ * 07 26 2010 cp.wu -+ * -+ * re-commit code logic being overwriten. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) re-enable AIS-FSM beacon timeout handling. -+ * 2) scan done API revised -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) enable Ad-Hoc -+ * 2) disable beacon timeout handling temporally due to unexpected beacon timeout event. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * indicate scan done for linux wireless extension -+ * -+ * 07 23 2010 cp.wu -+ * -+ * add AIS-FSM handling for beacon timeout event. -+ * -+ * 07 22 2010 cp.wu -+ * -+ * 1) refine AIS-FSM indent. -+ * 2) when entering RF Test mode, flush 802.1X frames as well -+ * 3) when entering D3 state, flush 802.1X frames as well -+ * -+ * 07 21 2010 cp.wu -+ * -+ * separate AIS-FSM states into different cases of channel request. -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 20 2010 cp.wu -+ * -+ * 1) [AIS] when new scan is issued, clear currently available scanning result except the connected one -+ * 2) refine disconnection behaviour when issued during BG-SCAN process -+ * -+ * 07 20 2010 cp.wu -+ * -+ * 1) bugfix: do not stop timer for join after switched into normal_tr state, -+ * for providing chance for DHCP handshasking -+ * 2) modify rsnPerformPolicySelection() invoking -+ * -+ * 07 19 2010 cp.wu -+ * -+ * 1) init AIS_BSS_INFO as channel number = 1 with band = 2.4GHz -+ * 2) correct typo -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * when IBSS is being merged-in, send command packet to PM for connected indication -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 16 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * bugfix for SCN migration -+ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue -+ * 2) before AIS issues scan request, network(BSS) needs to be activated first -+ * 3) only invoke COPY_SSID when using specified SSID for scan -+ * -+ * 07 15 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * for AIS scanning, driver specifies no extra IE for probe request -+ * -+ * 07 15 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * driver no longer generates probe request frames -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * Remove CFG_MQM_MIGRATION -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Refine AIS-FSM by divided into more states -+ * -+ * 07 13 2010 cm.chang -+ * -+ * Rename MSG_CH_RELEASE_T to MSG_CH_ABORT_T -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, -+ * other request will be directly dropped by returning BUSY -+ * -+ * 07 09 2010 george.huang -+ * -+ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT -+ * -+ * 07 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * for first connection, if connecting failed do not enter into scan state. -+ * -+ * 07 06 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * once STA-REC is allocated and updated, invoke cnmStaRecChangeState() to sync. with firmware. -+ * -+ * 07 06 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Update arguments for nicUpdateBeaconIETemplate() -+ * -+ * 07 06 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * STA-REC is maintained by CNM only. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * remove unused definitions. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 30 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync. with CMD/EVENT document ver0.07. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * modify Beacon/ProbeResp to complete parsing, -+ * because host software has looser memory usage restriction -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * integrate . -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * comment out RLM APIs by CFG_RLM_MIGRATION. -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan_fsm into building. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * RSN/PRIVACY compilation flag awareness correction -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan.c. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * restore utility function invoking via hem_mbox to direct calls -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add bss.c. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change to enqueue TX frame infinitely. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 01 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add conditionial compiling flag to choose default available bandwidth -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. -+ * -+ * 05 21 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Fix compile error if CFG_CMD_EVENT_VER_009 == 0 for prEventConnStatus->ucNetworkType. -+ * -+ * 05 21 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set -+ * -+ * 05 17 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Call pmAbort() and add ucNetworkType field in EVENT_CONNECTION_STATUS -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Fix compile warning - define of MQM_WMM_PARSING was removed -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 28 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed the use of compiling flag MQM_WMM_PARSING -+ * -+ * 04 27 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * -+ * Fix typo -+ * -+ * 04 27 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Send Deauth for Class 3 Error and Leave Network Support -+ * -+ * 04 15 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the protected bit at cap info for ad-hoc. -+ * -+ * 04 13 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add new HW CH macro support -+ * -+ * 04 07 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Add TX Power Control RCPI function. -+ * -+ * 03 29 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * move the wlan table alloc / free to change state function. -+ * -+ * 03 25 2010 wh.su -+ * [BORA00000676][MT6620] Support the frequency setting and query at build connection / connection event -+ * modify the build connection and status event structure bu CMD_EVENT doc 0.09 draft, default is disable. -+ * -+ * 03 24 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * fixed some WHQL testing error. -+ * -+ * 03 24 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * Add Set / Unset POWER STATE in AIS Network -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 03 03 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add PHY_CONFIG to change Phy Type -+ * -+ * 03 03 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Use bcmWiFiNotify to replace wifi_send_msg to pass information to BCM module. -+ * -+ * 03 03 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Remove wmt_task definition and add PTA function. -+ * -+ * 03 02 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Init TXM and MQM testing procedures in aisFsmRunEventJoinComplete() -+ * -+ * 03 01 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Modified aisUpdateBssInfo() to call TXM's functions for setting WTBL TX parameters -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * clear the pmkid cache while indicate media disconnect. -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * . -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Enabled MQM parsing WMM IEs for non-AP mode -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Remove CFG_TEST_VIRTUAL_CMD and add support of Driver STA_RECORD_T activation -+ * -+ * 02 25 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * use the Rx0 dor event indicate. -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Support dynamic channel selection -+ * -+ * 02 23 2010 wh.su -+ * [BORA00000621][MT6620 Wi-Fi] Add the RSSI indicate to avoid XP stalled for query rssi value -+ * Adding the RSSI event support, -+ * using the HAL function to get the rcpi value and tranlsate to RSSI and indicate to driver -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Revise data structure to share the same BSS_INFO_T for avoiding coding error -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 27 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Set max AMDPU size supported by the peer to 64 KB, -+ * removed mqmInit() and mqmTxSendAddBaReq() function calls in aisUpdateBssInfo() -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+ * -+ * 01 20 2010 kevin.huang -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Add PHASE_2_INTEGRATION_WORK_AROUND and CFG_SUPPORT_BCM flags -+ * -+ * 01 15 2010 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Configured the AMPDU factor to 3 for the APu1rwduu`wvpghlqg|q`mpdkb+ilp -+ * -+ * 01 14 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Add WiFi BCM module for the 1st time. -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * Refine JOIN Complete and separate the function of Media State indication -+ * -+ * 01 04 2010 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * For working out the first connection Chariot-verified version -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 10 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the sample code to update the wlan table rate, -+ * -+ * Dec 10 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Different function prototype of wifi_send_msg() -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Call rlm related function to process HT info when join complete -+ * -+ * Dec 9 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * default the acquired wlan table entry code off -+ * -+ * Dec 9 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the code to acquired the wlan table entry, and a sample code to update the BA bit at table -+ * -+ * Dec 7 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix the problem of prSwRfb overwrited by event packet in aisFsmRunEventJoinComplete() -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the code to integrate the security related code -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove redundant declaration -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add code for JOIN init and JOIN complete -+ * -+ * Nov 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Rename u4RSSI to i4RSSI -+ * -+ * Nov 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise ENUM_MEDIA_STATE to ENUM_PARAM_MEDIA_STATE -+ * -+ * Nov 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add fgIsScanReqIssued to CONNECTION_SETTINGS_T -+ * -+ * Nov 26 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise Virtual CMD handler due to structure changed -+ * -+ * Nov 25 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add Virtual CMD & RESP for testing CMD PATH -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add aisFsmInitializeConnectionSettings() -+ * -+ * Nov 20 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add CFG_TEST_MGMT_FSM flag for aisFsmTest() -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define AIS_ROAMING_CONNECTION_TRIAL_LIMIT 2 -+#define AIS_ROAMING_SCAN_CHANNEL_DWELL_TIME 80 -+ -+#define CTIA_MAGIC_SSID "ctia_test_only_*#*#3646633#*#*" -+#define CTIA_MAGIC_SSID_LEN 30 -+ -+#define AIS_JOIN_TIMEOUT 7 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugAisState[AIS_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("AIS_STATE_IDLE"), -+ (PUINT_8) DISP_STRING("AIS_STATE_SEARCH"), -+ (PUINT_8) DISP_STRING("AIS_STATE_SCAN"), -+ (PUINT_8) DISP_STRING("AIS_STATE_ONLINE_SCAN"), -+ (PUINT_8) DISP_STRING("AIS_STATE_LOOKING_FOR"), -+ (PUINT_8) DISP_STRING("AIS_STATE_WAIT_FOR_NEXT_SCAN"), -+ (PUINT_8) DISP_STRING("AIS_STATE_REQ_CHANNEL_JOIN"), -+ (PUINT_8) DISP_STRING("AIS_STATE_JOIN"), -+ (PUINT_8) DISP_STRING("AIS_STATE_IBSS_ALONE"), -+ (PUINT_8) DISP_STRING("AIS_STATE_IBSS_MERGE"), -+ (PUINT_8) DISP_STRING("AIS_STATE_NORMAL_TR"), -+ (PUINT_8) DISP_STRING("AIS_STATE_DISCONNECTING"), -+ (PUINT_8) DISP_STRING("AIS_STATE_REQ_REMAIN_ON_CHANNEL"), -+ (PUINT_8) DISP_STRING("AIS_STATE_REMAIN_ON_CHANNEL") -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief the function is used to initialize the value of the connection settings for -+* AIS network -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisInitializeConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ UINT_8 aucAnyBSSID[] = BC_BSSID; -+ UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; -+ int i = 0; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* Setup default values for operation */ -+ COPY_MAC_ADDR(prConnSettings->aucMacAddress, aucZeroMacAddr); -+ -+ if (prRegInfo) -+ prConnSettings->ucDelayTimeOfDisconnectEvent = -+ (!prAdapter->fgIsHw5GBandDisabled && prRegInfo->ucSupport5GBand) ? -+ AIS_DELAY_TIME_OF_DISC_SEC_DUALBAND : AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4; -+ else -+ prConnSettings->ucDelayTimeOfDisconnectEvent = AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4; -+ -+ COPY_MAC_ADDR(prConnSettings->aucBSSID, aucAnyBSSID); -+ prConnSettings->fgIsConnByBssidIssued = FALSE; -+ -+ prConnSettings->fgIsConnReqIssued = FALSE; -+ prConnSettings->fgIsDisconnectedByNonRequest = FALSE; -+ -+ prConnSettings->ucSSIDLen = 0; -+ -+ prConnSettings->eOPMode = NET_TYPE_INFRA; -+ -+ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; -+ -+ if (prRegInfo) { -+ prConnSettings->ucAdHocChannelNum = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4StartFreq); -+ prConnSettings->eAdHocBand = prRegInfo->u4StartFreq < 5000000 ? BAND_2G4 : BAND_5G; -+ prConnSettings->eAdHocMode = (ENUM_PARAM_AD_HOC_MODE_T) (prRegInfo->u4AdhocMode); -+ } -+ -+ prConnSettings->eAuthMode = AUTH_MODE_OPEN; -+ -+ prConnSettings->eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ -+ prConnSettings->fgIsScanReqIssued = FALSE; -+ -+ /* MIB attributes */ -+ prConnSettings->u2BeaconPeriod = DOT11_BEACON_PERIOD_DEFAULT; -+ -+ prConnSettings->u2RTSThreshold = DOT11_RTS_THRESHOLD_DEFAULT; -+ -+ prConnSettings->u2DesiredNonHTRateSet = RATE_SET_ALL_ABG; -+ -+ /* prConnSettings->u4FreqInKHz; */ /* Center frequency */ -+ -+ /* Set U-APSD AC */ -+ prConnSettings->bmfgApsdEnAc = PM_UAPSD_NONE; -+ -+ secInit(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* Features */ -+ prConnSettings->fgIsEnableRoaming = FALSE; -+#if CFG_SUPPORT_ROAMING -+ if (prRegInfo) -+ prConnSettings->fgIsEnableRoaming = ((prRegInfo->fgDisRoaming > 0) ? (FALSE) : (TRUE)); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ prConnSettings->fgIsAdHocQoSEnable = FALSE; -+ -+ prConnSettings->eDesiredPhyConfig = PHY_CONFIG_802_11ABGN; -+ -+ /* Set default bandwidth modes */ -+ prConnSettings->uc2G4BandwidthMode = CONFIG_BW_20M; -+ prConnSettings->uc5GBandwidthMode = CONFIG_BW_20_40M; -+ -+ prConnSettings->rRsnInfo.ucElemId = 0x30; -+ prConnSettings->rRsnInfo.u2Version = 0x0001; -+ prConnSettings->rRsnInfo.u4GroupKeyCipherSuite = 0; -+ prConnSettings->rRsnInfo.u4PairwiseKeyCipherSuiteCount = 0; -+ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) -+ prConnSettings->rRsnInfo.au4PairwiseKeyCipherSuite[i] = 0; -+ prConnSettings->rRsnInfo.u4AuthKeyMgtSuiteCount = 0; -+ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) -+ prConnSettings->rRsnInfo.au4AuthKeyMgtSuite[i] = 0; -+ prConnSettings->rRsnInfo.u2RsnCap = 0; -+ prConnSettings->rRsnInfo.fgRsnCapPresent = FALSE; -+ -+} /* end of aisFsmInitializeConnectionSettings() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief the function is used to initialize the value in AIS_FSM_INFO_T for -+* AIS FSM operation -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 ucScanTimeoutTimes = 0; -+VOID aisFsmInit(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; -+ -+ DEBUGFUNC("aisFsmInit()"); -+ DBGLOG(SW1, TRACE, "->aisFsmInit()\n"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); -+ -+ /* 4 <1> Initiate FSM */ -+ prAisFsmInfo->ePreviousState = AIS_STATE_IDLE; -+ prAisFsmInfo->eCurrentState = AIS_STATE_IDLE; -+ -+ prAisFsmInfo->ucAvailableAuthTypes = 0; -+ -+ prAisFsmInfo->prTargetBssDesc = (P_BSS_DESC_T) NULL; -+ -+ prAisFsmInfo->ucSeqNumOfReqMsg = 0; -+ prAisFsmInfo->ucSeqNumOfChReq = 0; -+ prAisFsmInfo->ucSeqNumOfScanReq = 0; -+ -+ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; -+#if CFG_SUPPORT_ROAMING -+ prAisFsmInfo->fgIsRoamingScanPending = FALSE; -+#endif /* CFG_SUPPORT_ROAMING */ -+ prAisFsmInfo->fgIsChannelRequested = FALSE; -+ prAisFsmInfo->fgIsChannelGranted = FALSE; -+ -+ /* 4 <1.1> Initiate FSM - Timer INIT */ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rBGScanTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventBGSleepTimeOut, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rIbssAloneTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventIbssAloneTimeOut, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rIndicationOfDisconnectTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisPostponedEventOfDisconnTimeout, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rJoinTimeoutTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventJoinTimeout, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rScanDoneTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventScanDoneTimeOut, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rChannelTimeoutTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventChannelTimeout, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rDeauthDoneTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventDeauthTimeout, (ULONG) NULL); -+ -+ /* 4 <1.2> Initiate PWR STATE */ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <2> Initiate BSS_INFO_T - common part */ -+ BSS_INFO_INIT(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ COPY_MAC_ADDR(prAisBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucMacAddress); -+ -+ /* 4 <3> Initiate BSS_INFO_T - private part */ -+ /* TODO */ -+ prAisBssInfo->eBand = BAND_2G4; -+ prAisBssInfo->ucPrimaryChannel = 1; -+ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ -+ /* 4 <4> Allocate MSDU_INFO_T for Beacon */ -+ prAisBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH); -+ -+ if (prAisBssInfo->prBeacon) { -+ prAisBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; -+ prAisBssInfo->prBeacon->ucStaRecIndex = 0xFF; /* NULL STA_REC */ -+ } else { -+ ASSERT(0); -+ } -+ -+#if 0 -+ prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; -+ prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; -+ prAisBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; -+#else -+ if (prAdapter->u4UapsdAcBmp == 0) { -+ prAdapter->u4UapsdAcBmp = CFG_INIT_UAPSD_AC_BMP; -+ /* ASSERT(prAdapter->u4UapsdAcBmp); */ -+ } -+ prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = (UINT_8) prAdapter->u4UapsdAcBmp; -+ prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = (UINT_8) prAdapter->u4UapsdAcBmp; -+ prAisBssInfo->rPmProfSetupInfo.ucUapsdSp = (UINT_8) prAdapter->u4MaxSpLen; -+#endif -+ -+ /* request list initialization */ -+ LINK_INITIALIZE(&prAisFsmInfo->rPendingReqList); -+ -+ /* DBGPRINTF("[2] ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x, ucUapsdSp:0x%x", */ -+ /* prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC, */ -+ /* prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC, */ -+ /* prAisBssInfo->rPmProfSetupInfo.ucUapsdSp); */ -+ -+ /*reset ucScanTimeoutTimes value*/ -+ ucScanTimeoutTimes = 0; -+ -+} /* end of aisFsmInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief the function is used to uninitialize the value in AIS_FSM_INFO_T for -+* AIS FSM operation -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmUninit(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; -+ -+ DEBUGFUNC("aisFsmUninit()"); -+ DBGLOG(SW1, INFO, "->aisFsmUninit()\n"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); -+ -+ /* 4 <1> Stop all timers */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rBGScanTimer); -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer); -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIndicationOfDisconnectTimer); -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); /* Add by Enlai */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); -+ -+ /* 4 <2> flush pending request */ -+ aisFsmFlushRequest(prAdapter); -+ -+ /* 4 <3> Reset driver-domain BSS-INFO */ -+ if (prAisBssInfo->prBeacon) { -+ cnmMgtPktFree(prAdapter, prAisBssInfo->prBeacon); -+ prAisBssInfo->prBeacon = NULL; -+ } -+#if CFG_SUPPORT_802_11W -+ rsnStopSaQuery(prAdapter); -+#endif -+ -+} /* end of aisFsmUninit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialization of JOIN STATE -+* -+* @param[in] prBssDesc The pointer of BSS_DESC_T which is the BSS we will try to join with. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateInit_JOIN(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_STA_RECORD_T prStaRec; -+ P_MSG_JOIN_REQ_T prJoinReqMsg; -+ -+ DEBUGFUNC("aisFsmStateInit_JOIN()"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ ASSERT(prBssDesc); -+ -+ /* 4 <1> We are going to connect to this BSS. */ -+ prBssDesc->fgIsConnecting = TRUE; -+ -+ /* 4 <2> Setup corresponding STA_RECORD_T */ -+ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_LEGACY_AP, NETWORK_TYPE_AIS_INDEX, prBssDesc); -+ if (prStaRec == NULL) { -+ DBGLOG(AIS, WARN, "Create station record fail\n"); -+ return; -+ } -+ -+ prAisFsmInfo->prTargetStaRec = prStaRec; -+ -+ /* 4 <2.1> sync. to firmware domain */ -+ if (prStaRec->ucStaState == STA_STATE_1) -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ /* 4 <3> Update ucAvailableAuthTypes which we can choice during SAA */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ -+ prStaRec->fgIsReAssoc = FALSE; -+ -+ switch (prConnSettings->eAuthMode) { -+ case AUTH_MODE_OPEN: /* Note: Omit break here. */ -+ case AUTH_MODE_WPA: -+ case AUTH_MODE_WPA_PSK: -+ case AUTH_MODE_WPA2: -+ case AUTH_MODE_WPA2_PSK: -+ prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ break; -+ -+ case AUTH_MODE_SHARED: -+ prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_SHARED_KEY; -+ break; -+ -+ case AUTH_MODE_AUTO_SWITCH: -+ DBGLOG(AIS, LOUD, "JOIN INIT: eAuthMode == AUTH_MODE_AUTO_SWITCH\n"); -+ prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) (AUTH_TYPE_OPEN_SYSTEM | AUTH_TYPE_SHARED_KEY); -+ break; -+ -+ default: -+ ASSERT(!(prConnSettings->eAuthMode == AUTH_MODE_WPA_NONE)); -+ DBGLOG(AIS, ERROR, "JOIN INIT: Auth Algorithm : %d was not supported by JOIN\n", -+ prConnSettings->eAuthMode); -+ /* TODO(Kevin): error handling ? */ -+ return; -+ } -+ -+ /* TODO(tyhsu): Assume that Roaming Auth Type is equal to ConnSettings eAuthMode */ -+ prAisSpecificBssInfo->ucRoamingAuthTypes = prAisFsmInfo->ucAvailableAuthTypes; -+ -+ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; -+ -+ } else { -+ ASSERT(prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE); -+ ASSERT(!prBssDesc->fgIsConnected); -+ -+ DBGLOG(AIS, LOUD, "JOIN INIT: AUTH TYPE = %d for Roaming\n", -+ prAisSpecificBssInfo->ucRoamingAuthTypes); -+ -+ prStaRec->fgIsReAssoc = TRUE; /* We do roaming while the medium is connected */ -+ -+ /* TODO(Kevin): We may call a sub function to acquire the Roaming Auth Type */ -+ prAisFsmInfo->ucAvailableAuthTypes = prAisSpecificBssInfo->ucRoamingAuthTypes; -+ -+ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT_FOR_ROAMING; -+ } -+ -+ /* 4 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes */ -+ if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) { -+ -+ DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); -+ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; -+ } else if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { -+ -+ DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == SHARED_KEY.\n"); -+ -+ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; -+ } else if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION) { -+ -+ DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == FAST_BSS_TRANSITION.\n"); -+ -+ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION; -+ } else { -+ ASSERT(0); -+ } -+ -+ /* 4 <5> Overwrite Connection Setting for eConnectionPolicy == ANY (Used by Assoc Req) */ -+ if (prBssDesc->ucSSIDLen) -+ COPY_SSID(prConnSettings->aucSSID, prConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ /* 4 <6> Send a Msg to trigger SAA to start JOIN process. */ -+ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); -+ if (!prJoinReqMsg) { -+ -+ ASSERT(0); /* Can't trigger SAA FSM */ -+ return; -+ } -+ -+ prJoinReqMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_START; -+ prJoinReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfReqMsg; -+ prJoinReqMsg->prStaRec = prStaRec; -+ -+ if (1) { -+ int j; -+ P_FRAG_INFO_T prFragInfo; -+ -+ for (j = 0; j < MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS; j++) { -+ prFragInfo = &prStaRec->rFragInfo[j]; -+ -+ if (prFragInfo->pr1stFrag) { -+ /* nicRxReturnRFB(prAdapter, prFragInfo->pr1stFrag); */ -+ prFragInfo->pr1stFrag = (P_SW_RFB_T) NULL; -+ } -+ } -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); -+ -+} /* end of aisFsmInit_JOIN() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Retry JOIN for AUTH_MODE_AUTO_SWITCH -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @retval TRUE We will retry JOIN -+* @retval FALSE We will not retry JOIN -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN aisFsmStateInit_RetryJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_JOIN_REQ_T prJoinReqMsg; -+ -+ DEBUGFUNC("aisFsmStateInit_RetryJOIN()"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* Retry other AuthType if possible */ -+ if (!prAisFsmInfo->ucAvailableAuthTypes) -+ return FALSE; -+ -+ if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { -+ -+ DBGLOG(AIS, INFO, "RETRY JOIN INIT: Retry Authentication with AuthType == SHARED_KEY.\n"); -+ -+ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; -+ } else { -+ DBGLOG(AIS, ERROR, "RETRY JOIN INIT: Retry Authentication with Unexpected AuthType.\n"); -+ ASSERT(0); -+ } -+ -+ prAisFsmInfo->ucAvailableAuthTypes = 0; /* No more available Auth Types */ -+ -+ /* Trigger SAA to start JOIN process. */ -+ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); -+ if (!prJoinReqMsg) { -+ -+ ASSERT(0); /* Can't trigger SAA FSM */ -+ return FALSE; -+ } -+ -+ prJoinReqMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_START; -+ prJoinReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfReqMsg; -+ prJoinReqMsg->prStaRec = prStaRec; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); -+ -+ return TRUE; -+ -+} /* end of aisFsmRetryJOIN() */ -+ -+#if CFG_SUPPORT_ADHOC -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief State Initialization of AIS_STATE_IBSS_ALONE -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateInit_IBSS_ALONE(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prAisBssInfo; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* 4 <1> Check if IBSS was created before ? */ -+ if (prAisBssInfo->fgIsBeaconActivated) { -+ -+ /* 4 <2> Start IBSS Alone Timer for periodic SCAN and then SEARCH */ -+#if !CFG_SLT_SUPPORT -+ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer, SEC_TO_MSEC(AIS_IBSS_ALONE_TIMEOUT_SEC)); -+#endif -+ } -+ -+ aisFsmCreateIBSS(prAdapter); -+ -+} /* end of aisFsmStateInit_IBSS_ALONE() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief State Initialization of AIS_STATE_IBSS_MERGE -+* -+* @param[in] prBssDesc The pointer of BSS_DESC_T which is the IBSS we will try to merge with. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateInit_IBSS_MERGE(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prAisBssInfo; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ ASSERT(prBssDesc); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* 4 <1> We will merge with to this BSS immediately. */ -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ -+ /* 4 <2> Setup corresponding STA_RECORD_T */ -+ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_ADHOC_PEER, NETWORK_TYPE_AIS_INDEX, prBssDesc); -+ if (prStaRec == NULL) { -+ DBGLOG(AIS, WARN, "Create station record fail\n"); -+ return; -+ } -+ -+ prStaRec->fgIsMerging = TRUE; -+ -+ prAisFsmInfo->prTargetStaRec = prStaRec; -+ -+ /* 4 <2.1> sync. to firmware domain */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ /* 4 <3> IBSS-Merge */ -+ aisFsmMergeIBSS(prAdapter, prStaRec); -+ -+} /* end of aisFsmStateInit_IBSS_MERGE() */ -+ -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of JOIN Abort -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateAbort_JOIN(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_JOIN_ABORT_T prJoinAbortMsg; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* 1. Abort JOIN process */ -+ prJoinAbortMsg = (P_MSG_JOIN_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_ABORT_T)); -+ if (!prJoinAbortMsg) { -+ -+ ASSERT(0); /* Can't abort SAA FSM */ -+ return; -+ } -+ -+ prJoinAbortMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_ABORT; -+ prJoinAbortMsg->ucSeqNum = prAisFsmInfo->ucSeqNumOfReqMsg; -+ prJoinAbortMsg->prStaRec = prAisFsmInfo->prTargetStaRec; -+ -+ scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisFsmInfo->prTargetStaRec->aucMacAddr); -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ /* 2. Return channel privilege */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 3.1 stop join timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); -+ -+ /* 3.2 reset local variable */ -+ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; -+ -+} /* end of aisFsmAbortJOIN() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of SCAN Abort -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateAbort_SCAN(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_SCN_SCAN_CANCEL prScanCancelMsg; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* Abort JOIN process. */ -+ prScanCancelMsg = (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL)); -+ if (!prScanCancelMsg) { -+ -+ ASSERT(0); /* Can't abort SCN FSM */ -+ return; -+ } -+ -+ prScanCancelMsg->rMsgHdr.eMsgId = MID_AIS_SCN_SCAN_CANCEL; -+ prScanCancelMsg->ucSeqNum = prAisFsmInfo->ucSeqNumOfScanReq; -+ prScanCancelMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX; -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ prScanCancelMsg->fgIsChannelExt = FALSE; -+#endif -+ -+ /* unbuffered message to guarantee scan is cancelled in sequence */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_UNBUF); -+ -+} /* end of aisFsmAbortSCAN() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of NORMAL_TR Abort -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateAbort_NORMAL_TR(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ DBGLOG(AIS, TRACE, "aisFsmStateAbort_NORMAL_TR\n"); -+ -+ /* TODO(Kevin): Do abort other MGMT func */ -+ -+ /* 1. Release channel to CNM */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 2.1 stop join timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); -+ -+ /* 2.2 reset local variable */ -+ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; -+ -+} /* end of aisFsmAbortNORMAL_TR() */ -+ -+#if CFG_SUPPORT_ADHOC -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of NORMAL_TR Abort -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateAbort_IBSS(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_DESC_T prBssDesc; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* reset BSS-DESC */ -+ if (prAisFsmInfo->prTargetStaRec) { -+ prBssDesc = scanSearchBssDescByTA(prAdapter, prAisFsmInfo->prTargetStaRec->aucMacAddr); -+ -+ if (prBssDesc) { -+ prBssDesc->fgIsConnected = FALSE; -+ prBssDesc->fgIsConnecting = FALSE; -+ } -+ } -+ /* release channel privilege */ -+ aisFsmReleaseCh(prAdapter); -+ -+} -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The Core FSM engine of AIS(Ad-hoc, Infra STA) -+* -+* @param[in] eNextState Enum value of next AIS STATE -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmSteps(IN P_ADAPTER_T prAdapter, ENUM_AIS_STATE_T eNextState) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_DESC_T prBssDesc; -+ P_MSG_CH_REQ_T prMsgChReq; -+ P_MSG_SCN_SCAN_REQ prScanReqMsg; -+ P_AIS_REQ_HDR_T prAisReq; -+ ENUM_BAND_T eBand; -+ UINT_8 ucChannel; -+ UINT_16 u2ScanIELen; -+ ENUM_AIS_STATE_T eOriPreState; -+ -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ DEBUGFUNC("aisFsmSteps()"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ eOriPreState = prAisFsmInfo->ePreviousState; -+ -+ do { -+ -+ /* Do entering Next State */ -+ prAisFsmInfo->ePreviousState = prAisFsmInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(AIS, STATE, "TRANSITION: [%s] -> [%s]\n", -+ apucDebugAisState[prAisFsmInfo->eCurrentState], apucDebugAisState[eNextState]); -+#else -+ DBGLOG(AIS, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", -+ DBG_AIS_IDX, prAisFsmInfo->eCurrentState, eNextState); -+#endif -+ /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */ -+ prAisFsmInfo->eCurrentState = eNextState; -+ -+ fgIsTransition = (BOOLEAN) FALSE; -+ -+ /* Do tasks of the State that we just entered */ -+ switch (prAisFsmInfo->eCurrentState) { -+ /* NOTE(Kevin): we don't have to rearrange the sequence of following -+ * switch case. Instead I would like to use a common lookup table of array -+ * of function pointer to speed up state search. -+ */ -+ case AIS_STATE_IDLE: -+ -+ prAisReq = aisFsmGetNextRequest(prAdapter); -+ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ -+ if (prAisReq == NULL || prAisReq->eReqType == AIS_REQUEST_RECONNECT) { -+ if (prConnSettings->fgIsConnReqIssued == TRUE && -+ prConnSettings->fgIsDisconnectedByNonRequest == FALSE) { -+ -+ prAisFsmInfo->fgTryScan = TRUE; -+ -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* sync with firmware */ -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* reset trial count */ -+ prAisFsmInfo->ucConnTrialCount = 0; -+ -+ eNextState = AIS_STATE_SEARCH; -+ fgIsTransition = TRUE; -+ } else { -+ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* sync with firmware */ -+ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* check for other pending request */ -+ if (prAisReq && -+ (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE)) { -+ -+ wlanClearScanningResult(prAdapter); -+ eNextState = AIS_STATE_SCAN; -+ -+ fgIsTransition = TRUE; -+ } -+ } -+ -+ if (prAisReq) { -+ /* free the message */ -+ cnmMemFree(prAdapter, prAisReq); -+ } -+ } else if (prAisReq->eReqType == AIS_REQUEST_SCAN) { -+#if CFG_SUPPORT_ROAMING -+ prAisFsmInfo->fgIsRoamingScanPending = FALSE; -+#endif /* CFG_SUPPORT_ROAMING */ -+ wlanClearScanningResult(prAdapter); -+ -+ eNextState = AIS_STATE_SCAN; -+ fgIsTransition = TRUE; -+ -+ /* free the message */ -+ cnmMemFree(prAdapter, prAisReq); -+ } else if (prAisReq->eReqType == AIS_REQUEST_ROAMING_CONNECT -+ || prAisReq->eReqType == AIS_REQUEST_ROAMING_SEARCH) { -+ /* ignore */ -+ /* free the message */ -+ cnmMemFree(prAdapter, prAisReq); -+ } else if (prAisReq->eReqType == AIS_REQUEST_REMAIN_ON_CHANNEL) { -+ eNextState = AIS_STATE_REQ_REMAIN_ON_CHANNEL; -+ fgIsTransition = TRUE; -+ -+ /* free the message */ -+ cnmMemFree(prAdapter, prAisReq); -+ } -+ -+ prAisFsmInfo->u4SleepInterval = AIS_BG_SCAN_INTERVAL_MIN_SEC; -+ -+ break; -+ -+ case AIS_STATE_SEARCH: -+ /* 4 <1> Search for a matched candidate and save it to prTargetBssDesc. */ -+#if CFG_SLT_SUPPORT -+ prBssDesc = prAdapter->rWifiVar.rSltInfo.prPseudoBssDesc; -+#else -+ prBssDesc = scanSearchBssDescByPolicy(prAdapter, NETWORK_TYPE_AIS_INDEX); -+#endif -+ /* every time BSS join failure count is integral multiples of SCN_BSS_JOIN_FAIL_THRESOLD, -+ we need to scan again to find if a new BSS is here in the ESS, -+ this can also avoid too frequency to retry the rejected AP */ -+ if (prAisFsmInfo->ePreviousState == AIS_STATE_LOOKING_FOR || -+ ((eOriPreState == AIS_STATE_ONLINE_SCAN || -+ eOriPreState == AIS_STATE_SCAN) && prAisFsmInfo->ePreviousState != eOriPreState)) { -+ /* if previous state is scan/online scan/looking for, don't try to scan again */ -+ } else if (prBssDesc && prBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD && -+ ((prBssDesc->ucJoinFailureCount - SCN_BSS_JOIN_FAIL_THRESOLD) % -+ SCN_BSS_JOIN_FAIL_THRESOLD) == 0) -+ prBssDesc = NULL; -+ -+ /* we are under Roaming Condition. */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ if (prAisFsmInfo->ucConnTrialCount > AIS_ROAMING_CONNECTION_TRIAL_LIMIT) { -+#if CFG_SUPPORT_ROAMING -+ roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_CONNLIMIT); -+#endif /* CFG_SUPPORT_ROAMING */ -+ /* reset retry count */ -+ prAisFsmInfo->ucConnTrialCount = 0; -+ -+ /* abort connection trial */ -+ prConnSettings->fgIsConnReqIssued = FALSE; -+ -+ eNextState = AIS_STATE_NORMAL_TR; -+ fgIsTransition = TRUE; -+ -+ break; -+ } -+ } -+ /* 4 <2> We are not under Roaming Condition. */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ -+ /* 4 <2.a> If we have the matched one */ -+ if (prBssDesc) { -+ -+ /* 4 Stored the Selected BSS security cipher. -+ For later asoc req compose IE */ -+ prAisBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher; -+ prAisBssInfo->u4RsnSelectedPairwiseCipher = -+ prBssDesc->u4RsnSelectedPairwiseCipher; -+ prAisBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; -+ -+ /* 4 Do STATE transition and update current Operation Mode. */ -+ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { -+ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; -+ -+ /* Record the target BSS_DESC_T for next STATE. */ -+ prAisFsmInfo->prTargetBssDesc = prBssDesc; -+ -+ /* Transit to channel acquire */ -+ eNextState = AIS_STATE_REQ_CHANNEL_JOIN; -+ fgIsTransition = TRUE; -+ -+ /* increase connection trial count */ -+ prAisFsmInfo->ucConnTrialCount++; -+ } -+#if CFG_SUPPORT_ADHOC -+ else if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { -+ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; -+ -+ /* Record the target BSS_DESC_T for next STATE. */ -+ prAisFsmInfo->prTargetBssDesc = prBssDesc; -+ -+ eNextState = AIS_STATE_IBSS_MERGE; -+ fgIsTransition = TRUE; -+ } -+#endif /* CFG_SUPPORT_ADHOC */ -+ else { -+ ASSERT(0); -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+ fgIsTransition = TRUE; -+ } -+ } -+ /* 4 <2.b> If we don't have the matched one */ -+ else { -+ -+ /* increase connection trial count for infrastructure connection */ -+ if (prConnSettings->eOPMode == NET_TYPE_INFRA) -+ prAisFsmInfo->ucConnTrialCount++; -+ /* 4 Try to SCAN */ -+ if (prAisFsmInfo->fgTryScan) { -+ eNextState = AIS_STATE_LOOKING_FOR; -+ -+ fgIsTransition = TRUE; -+ break; -+ } -+ /* 4 We've do SCAN already, now wait in some STATE. */ -+ if (prConnSettings->eOPMode == NET_TYPE_INFRA) { -+ -+ /* issue reconnect request, -+ * and retreat to idle state for scheduling */ -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); -+ -+ eNextState = AIS_STATE_IDLE; -+ fgIsTransition = TRUE; -+ } -+#if CFG_SUPPORT_ADHOC -+ else if ((prConnSettings->eOPMode == NET_TYPE_IBSS) -+ || (prConnSettings->eOPMode == NET_TYPE_AUTO_SWITCH) -+ || (prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS)) { -+ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; -+ prAisFsmInfo->prTargetBssDesc = NULL; -+ -+ eNextState = AIS_STATE_IBSS_ALONE; -+ fgIsTransition = TRUE; -+ } -+#endif /* CFG_SUPPORT_ADHOC */ -+ else { -+ ASSERT(0); -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+ fgIsTransition = TRUE; -+ } -+ } -+ } -+ /* 4 <3> We are under Roaming Condition. */ -+ else { /* prAdapter->eConnectionState == MEDIA_STATE_CONNECTED. */ -+ -+ /* 4 <3.a> This BSS_DESC_T is our AP. */ -+ /* NOTE(Kevin 2008/05/16): Following cases will go back to NORMAL_TR. -+ * CASE I: During Roaming, APP(WZC/NDISTEST) change the connection -+ * settings. That make we can NOT match the original AP, so the -+ * prBssDesc is NULL. -+ * CASE II: The same reason as CASE I. Because APP change the -+ * eOPMode to other network type in connection setting -+ * (e.g. NET_TYPE_IBSS), so the BssDesc become the IBSS node. -+ * (For CASE I/II, before WZC/NDISTEST set the OID_SSID, it will change -+ * other parameters in connection setting first. So if we do roaming -+ * at the same time, it will hit these cases.) -+ * -+ * CASE III: Normal case, we can't find other candidate to roam -+ * out, so only the current AP will be matched. -+ * -+ * CASE IV: Timestamp of the current AP might be reset -+ */ -+ if (prAisBssInfo->ucReasonOfDisconnect != DISCONNECT_REASON_CODE_REASSOCIATION && -+ ((!prBssDesc) || /* CASE I */ -+ (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE) || /* CASE II */ -+ (prBssDesc->fgIsConnected) || /* CASE III */ -+ (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID))) /* CASE IV */) { -+#if DBG -+ if ((prBssDesc) && (prBssDesc->fgIsConnected)) -+ ASSERT(EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID)); -+#endif /* DBG */ -+ /* We already associated with it, go back to NORMAL_TR */ -+ /* TODO(Kevin): Roaming Fail */ -+#if CFG_SUPPORT_ROAMING -+ roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_NOCANDIDATE); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ /* Retreat to NORMAL_TR state */ -+ eNextState = AIS_STATE_NORMAL_TR; -+ fgIsTransition = TRUE; -+ break; -+ } -+ -+ /* 4 <3.b> Try to roam out for JOIN this BSS_DESC_T. */ -+ if (prBssDesc == NULL) { -+ /* increase connection trial count for infrastructure connection */ -+ if (prConnSettings->eOPMode == NET_TYPE_INFRA) -+ prAisFsmInfo->ucConnTrialCount++; -+ /* 4 Try to SCAN */ -+ if (prAisFsmInfo->fgTryScan) { -+ eNextState = AIS_STATE_LOOKING_FOR; -+ -+ fgIsTransition = TRUE; -+ break; -+ } -+ -+ /* 4 We've do SCAN already, now wait in some STATE. */ -+ if (prConnSettings->eOPMode == NET_TYPE_INFRA) { -+ -+ /* issue reconnect request, and retreat to idle state -+ * for scheduling */ -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); -+ -+ eNextState = AIS_STATE_IDLE; -+ fgIsTransition = TRUE; -+ } -+#if CFG_SUPPORT_ADHOC -+ else if ((prConnSettings->eOPMode == NET_TYPE_IBSS) -+ || (prConnSettings->eOPMode == NET_TYPE_AUTO_SWITCH) -+ || (prConnSettings->eOPMode == -+ NET_TYPE_DEDICATED_IBSS)) { -+ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; -+ prAisFsmInfo->prTargetBssDesc = NULL; -+ -+ eNextState = AIS_STATE_IBSS_ALONE; -+ fgIsTransition = TRUE; -+ } -+#endif /* CFG_SUPPORT_ADHOC */ -+ else { -+ ASSERT(0); -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+ fgIsTransition = TRUE; -+ } -+ } else { -+#if DBG -+ if (prAisBssInfo->ucReasonOfDisconnect != -+ DISCONNECT_REASON_CODE_REASSOCIATION) { -+ ASSERT(UNEQUAL_MAC_ADDR -+ (prBssDesc->aucBSSID, prAisBssInfo->aucBSSID)); -+ } -+#endif /* DBG */ -+ -+ /* 4 Record the target BSS_DESC_T for next STATE. */ -+ prAisFsmInfo->prTargetBssDesc = prBssDesc; -+ -+ /* tyhsu: increase connection trial count */ -+ prAisFsmInfo->ucConnTrialCount++; -+ -+ /* Transit to channel acquire */ -+ eNextState = AIS_STATE_REQ_CHANNEL_JOIN; -+ fgIsTransition = TRUE; -+ } -+ } -+ -+ break; -+ -+ case AIS_STATE_WAIT_FOR_NEXT_SCAN: -+ -+ DBGLOG(AIS, LOUD, "SCAN: Idle Begin - Current Time = %u\n", kalGetTimeTick()); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prAisFsmInfo->rBGScanTimer, SEC_TO_MSEC(prAisFsmInfo->u4SleepInterval)); -+ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ if (prAisFsmInfo->u4SleepInterval < AIS_BG_SCAN_INTERVAL_MAX_SEC) -+ prAisFsmInfo->u4SleepInterval <<= 1; -+ break; -+ -+ case AIS_STATE_SCAN: -+ case AIS_STATE_ONLINE_SCAN: -+ case AIS_STATE_LOOKING_FOR: -+ -+ if (!IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX)) { -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* sync with firmware */ -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ } -+ -+ /* IE length decision */ -+ if (prAisFsmInfo->u4ScanIELength > 0) { -+ u2ScanIELen = (UINT_16) prAisFsmInfo->u4ScanIELength; -+ } else { -+#if CFG_SUPPORT_WPS2 -+ u2ScanIELen = prAdapter->prGlueInfo->u2WSCIELen; -+#else -+ u2ScanIELen = 0; -+#endif -+ } -+ -+ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, -+ OFFSET_OF(MSG_SCN_SCAN_REQ, -+ aucIE) + u2ScanIELen); -+ if (!prScanReqMsg) { -+ ASSERT(0); /* Can't trigger SCAN FSM */ -+ return; -+ } -+ -+ prScanReqMsg->rMsgHdr.eMsgId = MID_AIS_SCN_SCAN_REQ; -+ prScanReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfScanReq; -+ prScanReqMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX; -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ prScanReqMsg->eScanType = SCAN_TYPE_PASSIVE_SCAN; -+#else -+ prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+#endif -+ -+#if CFG_SUPPORT_ROAMING_ENC -+ if (prAdapter->fgIsRoamingEncEnabled == TRUE) { -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR && -+ prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ prScanReqMsg->u2ChannelDwellTime = AIS_ROAMING_SCAN_CHANNEL_DWELL_TIME; -+ } -+ } -+#endif /* CFG_SUPPORT_ROAMING_ENC */ -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_SCAN -+ || prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN) { -+ if (prAisFsmInfo->ucScanSSIDLen == 0) { -+ /* Scan for all available SSID */ -+ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD; -+ } else { -+ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ COPY_SSID(prScanReqMsg->aucSSID, -+ prScanReqMsg->ucSSIDLength, -+ prAisFsmInfo->aucScanSSID, prAisFsmInfo->ucScanSSIDLen); -+ } -+ } else { -+ /* Scan for determined SSID */ -+ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ COPY_SSID(prScanReqMsg->aucSSID, -+ prScanReqMsg->ucSSIDLength, -+ prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ } -+ -+ /* check if tethering is running and need to fix on specific channel */ -+ if (cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE) { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; -+ prScanReqMsg->ucChannelListNum = 1; -+ prScanReqMsg->arChnlInfoList[0].eBand = eBand; -+ prScanReqMsg->arChnlInfoList[0].ucChannelNum = ucChannel; -+ } else { -+#if 0 -+ aisFsmSetChannelInfo(prAdapter, prScanReqMsg, prAisFsmInfo->eCurrentState); -+#endif -+ if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_NULL) { -+ if (prAdapter->fgEnable5GBand == TRUE) -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; -+ else -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; -+ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_2G4) { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; -+ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_5G) { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; -+ } else { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; -+ ASSERT(0); -+ } -+ -+ } -+ -+ if (prAisFsmInfo->u4ScanIELength > 0) { -+ kalMemCopy(prScanReqMsg->aucIE, prAisFsmInfo->aucScanIEBuf, -+ prAisFsmInfo->u4ScanIELength); -+ } else { -+#if CFG_SUPPORT_WPS2 -+ if (prAdapter->prGlueInfo->u2WSCIELen > 0) { -+ kalMemCopy(prScanReqMsg->aucIE, &prAdapter->prGlueInfo->aucWSCIE, -+ prAdapter->prGlueInfo->u2WSCIELen); -+ } -+ } -+#endif -+ -+ prScanReqMsg->u2IELen = u2ScanIELen; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); -+ DBGLOG(AIS, TRACE, "SendSR%d\n", prScanReqMsg->ucSeqNum); -+ prAisFsmInfo->fgTryScan = FALSE; /* Will enable background sleep for infrastructure */ -+ -+ prAdapter->ucScanTime++; -+ break; -+ -+ case AIS_STATE_REQ_CHANNEL_JOIN: -+ /* send message to CNM for acquiring channel */ -+ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); -+ if (!prMsgChReq) { -+ ASSERT(0); /* Can't indicate CNM for channel acquiring */ -+ return; -+ } -+ -+ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; -+ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ prMsgChReq->ucTokenID = ++prAisFsmInfo->ucSeqNumOfChReq; -+ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; -+ prMsgChReq->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL; -+ -+ if (prAisFsmInfo->prTargetBssDesc != NULL) { -+ prMsgChReq->ucPrimaryChannel = prAisFsmInfo->prTargetBssDesc->ucChannelNum; -+ prMsgChReq->eRfSco = prAisFsmInfo->prTargetBssDesc->eSco; -+ prMsgChReq->eRfBand = prAisFsmInfo->prTargetBssDesc->eBand; -+ COPY_MAC_ADDR(prMsgChReq->aucBSSID, prAisFsmInfo->prTargetBssDesc->aucBSSID); -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); -+ -+ prAisFsmInfo->fgIsChannelRequested = TRUE; -+ break; -+ -+ case AIS_STATE_JOIN: -+ aisFsmStateInit_JOIN(prAdapter, prAisFsmInfo->prTargetBssDesc); -+ break; -+ -+#if CFG_SUPPORT_ADHOC -+ case AIS_STATE_IBSS_ALONE: -+ aisFsmStateInit_IBSS_ALONE(prAdapter); -+ break; -+ -+ case AIS_STATE_IBSS_MERGE: -+ aisFsmStateInit_IBSS_MERGE(prAdapter, prAisFsmInfo->prTargetBssDesc); -+ break; -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ case AIS_STATE_NORMAL_TR: -+ if (prAisFsmInfo->fgIsInfraChannelFinished == FALSE) { -+ /* Don't do anything when rJoinTimeoutTimer is still ticking */ -+ } else { -+ /* 1. Process for pending scan */ -+ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE) { -+ wlanClearScanningResult(prAdapter); -+ eNextState = AIS_STATE_ONLINE_SCAN; -+ fgIsTransition = TRUE; -+ } -+ /* 2. Process for pending roaming scan */ -+ else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE) == TRUE) { -+ eNextState = AIS_STATE_LOOKING_FOR; -+ fgIsTransition = TRUE; -+ } -+ /* 3. Process for pending roaming scan */ -+ else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE) == TRUE) { -+ eNextState = AIS_STATE_SEARCH; -+ fgIsTransition = TRUE; -+ } else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL, TRUE) == -+ TRUE) { -+ eNextState = AIS_STATE_REQ_REMAIN_ON_CHANNEL; -+ fgIsTransition = TRUE; -+ } -+ } -+ -+ break; -+ -+ case AIS_STATE_DISCONNECTING: -+ /* send for deauth frame for disconnection */ -+ authSendDeauthFrame(prAdapter, -+ prAisBssInfo->prStaRecOfAP, -+ (P_SW_RFB_T) NULL, REASON_CODE_DEAUTH_LEAVING_BSS, aisDeauthXmitComplete); -+ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rDeauthDoneTimer, 100); -+ break; -+ -+ case AIS_STATE_REQ_REMAIN_ON_CHANNEL: -+ /* send message to CNM for acquiring channel */ -+ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); -+ if (!prMsgChReq) { -+ ASSERT(0); /* Can't indicate CNM for channel acquiring */ -+ return; -+ } -+ -+ /* zero-ize */ -+ kalMemZero(prMsgChReq, sizeof(MSG_CH_REQ_T)); -+ -+ /* filling */ -+ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; -+ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ prMsgChReq->ucTokenID = ++prAisFsmInfo->ucSeqNumOfChReq; -+ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; -+ prMsgChReq->u4MaxInterval = prAisFsmInfo->rChReqInfo.u4DurationMs; -+ prMsgChReq->ucPrimaryChannel = prAisFsmInfo->rChReqInfo.ucChannelNum; -+ prMsgChReq->eRfSco = prAisFsmInfo->rChReqInfo.eSco; -+ prMsgChReq->eRfBand = prAisFsmInfo->rChReqInfo.eBand; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); -+ -+ prAisFsmInfo->fgIsChannelRequested = TRUE; -+ -+ break; -+ -+ case AIS_STATE_REMAIN_ON_CHANNEL: -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ /* sync with firmware */ -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ break; -+ -+ default: -+ ASSERT(0); /* Make sure we have handle all STATEs */ -+ break; -+ -+ } -+ } while (fgIsTransition); -+ -+ return; -+ -+} /* end of aisFsmSteps() */ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmSetChannelInfo(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ ScanReqMsg, IN ENUM_AIS_STATE_T CurrentState) -+{ -+ /*get scan channel infro from prAdapter->prGlueInfo->prScanRequest*/ -+ struct cfg80211_scan_request *scan_req_t = NULL; -+ struct ieee80211_channel *channel_tmp = NULL; -+ int i = 0; -+ int j = 0; -+ UINT_8 channel_num = 0; -+ UINT_8 channel_counts = 0; -+ -+ if ((prAdapter == NULL) || (ScanReqMsg == NULL)) -+ return; -+ if ((CurrentState == AIS_STATE_SCAN) || (CurrentState == AIS_STATE_ONLINE_SCAN)) { -+ if (prAdapter->prGlueInfo->prScanRequest != NULL) { -+ scan_req_t = prAdapter->prGlueInfo->prScanRequest; -+ if ((scan_req_t != NULL) && (scan_req_t->n_channels != 0) && -+ (scan_req_t->channels != NULL)) { -+ channel_counts = scan_req_t->n_channels; -+ DBGLOG(AIS, TRACE, "channel_counts=%d\n", channel_counts); -+ -+ while (j < channel_counts) { -+ channel_tmp = scan_req_t->channels[j]; -+ if (channel_tmp == NULL) -+ break; -+ -+ DBGLOG(AIS, TRACE, "set channel band=%d\n", channel_tmp->band); -+ if (channel_tmp->band >= IEEE80211_BAND_60GHZ) { -+ j++; -+ continue; -+ } -+ if (i >= MAXIMUM_OPERATION_CHANNEL_LIST) -+ break; -+ if (channel_tmp->band == IEEE80211_BAND_2GHZ) -+ ScanReqMsg->arChnlInfoList[i].eBand = BAND_2G4; -+ else if (channel_tmp->band == IEEE80211_BAND_5GHZ) -+ ScanReqMsg->arChnlInfoList[i].eBand = BAND_5G; -+ -+ DBGLOG(AIS, TRACE, "set channel channel_rer =%d\n", -+ channel_tmp->center_freq); -+ -+ channel_num = (UINT_8)nicFreq2ChannelNum( -+ channel_tmp->center_freq * 1000); -+ -+ DBGLOG(AIS, TRACE, "set channel channel_num=%d\n", -+ channel_num); -+ ScanReqMsg->arChnlInfoList[i].ucChannelNum = channel_num; -+ -+ j++; -+ i++; -+ } -+ } -+ } -+ } -+ -+ DBGLOG(AIS, INFO, "set channel i=%d\n", i); -+ if (i > 0) { -+ ScanReqMsg->ucChannelListNum = i; -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; -+ -+ return; -+ } -+ -+ if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_NULL) { -+ if (prAdapter->fgEnable5GBand == TRUE) -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; -+ else -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; -+ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_2G4) { -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; -+ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_5G) { -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; -+ } else { -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; -+ ASSERT(0); -+ } -+ -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID aisFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SCN_SCAN_DONE prScanDoneMsg; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ UINT_8 ucSeqNumOfCompMsg; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ DEBUGFUNC("aisFsmRunEventScanDone()"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ ucScanTimeoutTimes = 0; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; -+ ASSERT(prScanDoneMsg->ucNetTypeIndex == (UINT_8) NETWORK_TYPE_AIS_INDEX); -+ -+ ucSeqNumOfCompMsg = prScanDoneMsg->ucSeqNum; -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ if (ucSeqNumOfCompMsg != prAisFsmInfo->ucSeqNumOfScanReq) { -+ DBGLOG(AIS, WARN, "SEQ NO of AIS SCN DONE MSG is not matched %d %d.\n", -+ ucSeqNumOfCompMsg, prAisFsmInfo->ucSeqNumOfScanReq); -+ } else { -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_SCAN: -+ prConnSettings->fgIsScanReqIssued = FALSE; -+ -+ /* reset scan IE buffer */ -+ prAisFsmInfo->u4ScanIELength = 0; -+ -+ kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS); -+ eNextState = AIS_STATE_IDLE; -+#if CFG_SUPPORT_AGPS_ASSIST -+ scanReportScanResultToAgps(prAdapter); -+#endif -+ break; -+ -+ case AIS_STATE_ONLINE_SCAN: -+ prConnSettings->fgIsScanReqIssued = FALSE; -+ -+ /* reset scan IE buffer */ -+ prAisFsmInfo->u4ScanIELength = 0; -+ -+ kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS); -+#if CFG_SUPPORT_ROAMING -+ eNextState = aisFsmRoamingScanResultsUpdate(prAdapter); -+#else -+ eNextState = AIS_STATE_NORMAL_TR; -+#endif /* CFG_SUPPORT_ROAMING */ -+#if CFG_SUPPORT_AGPS_ASSIST -+ scanReportScanResultToAgps(prAdapter); -+#endif -+ break; -+ -+ case AIS_STATE_LOOKING_FOR: -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ scanReportBss2Cfg80211(prAdapter, BSS_TYPE_INFRASTRUCTURE, NULL); -+#if CFG_SUPPORT_ROAMING -+ eNextState = aisFsmRoamingScanResultsUpdate(prAdapter); -+#else -+ eNextState = AIS_STATE_SEARCH; -+#endif /* CFG_SUPPORT_ROAMING */ -+ break; -+ -+ default: -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ break; -+ -+ } -+ } -+ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisFsmRunEventScanDone() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ UINT_8 ucReasonOfDisconnect; -+ BOOLEAN fgDelayIndication; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ DEBUGFUNC("aisFsmRunEventAbort()"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* 4 <1> Extract information of Abort Message and then free memory. */ -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) prMsgHdr; -+ ucReasonOfDisconnect = prAisAbortMsg->ucReasonOfDisconnect; -+ fgDelayIndication = prAisAbortMsg->fgDelayIndication; -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+#if DBG -+ DBGLOG(AIS, STATE, "EVENT-ABORT: Current State %s %d\n", -+ apucDebugAisState[prAisFsmInfo->eCurrentState], ucReasonOfDisconnect); -+#else -+ DBGLOG(AIS, STATE, "[%d] EVENT-ABORT: Current State [%d %d]\n", -+ DBG_AIS_IDX, prAisFsmInfo->eCurrentState, ucReasonOfDisconnect); -+#endif -+ -+ GET_CURRENT_SYSTIME(&(prAisFsmInfo->rJoinReqTime)); -+ -+ /* 4 <2> clear previous pending connection request and insert new one */ -+ if (ucReasonOfDisconnect == DISCONNECT_REASON_CODE_DEAUTHENTICATED -+ || ucReasonOfDisconnect == DISCONNECT_REASON_CODE_DISASSOCIATED) { -+ prConnSettings->fgIsDisconnectedByNonRequest = TRUE; -+ } else { -+ prConnSettings->fgIsDisconnectedByNonRequest = FALSE; -+ } -+ /* to support user space triggered roaming */ -+ if (ucReasonOfDisconnect == DISCONNECT_REASON_CODE_ROAMING && -+ prAisFsmInfo->eCurrentState != AIS_STATE_DISCONNECTING) { -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR && -+ prAisFsmInfo->fgIsInfraChannelFinished == TRUE) { -+ aisFsmSteps(prAdapter, AIS_STATE_SEARCH); -+ } else { -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE); -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE); -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_ROAMING_CONNECT); -+ } -+ return; -+ } -+ -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE); -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); -+ -+ if (prAisFsmInfo->eCurrentState != AIS_STATE_DISCONNECTING) { -+ /* 4 <3> invoke abort handler */ -+ aisFsmStateAbort(prAdapter, ucReasonOfDisconnect, fgDelayIndication); -+ } -+ -+} /* end of aisFsmRunEventAbort() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function handles AIS-FSM abort event/command -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* ucReasonOfDisconnect Reason for disonnection -+* fgDelayIndication Option to delay disconnection indication -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateAbort(IN P_ADAPTER_T prAdapter, UINT_8 ucReasonOfDisconnect, BOOLEAN fgDelayIndication) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ BOOLEAN fgIsCheckConnected; -+ -+ ASSERT(prAdapter); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ fgIsCheckConnected = FALSE; -+ -+ /* 4 <1> Save information of Abort Message and then free memory. */ -+ prAisBssInfo->ucReasonOfDisconnect = ucReasonOfDisconnect; -+ -+ /* 4 <2> Abort current job. */ -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_IDLE: -+ case AIS_STATE_SEARCH: -+ break; -+ -+ case AIS_STATE_WAIT_FOR_NEXT_SCAN: -+ /* Do cancel timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rBGScanTimer); -+ -+ /* in case roaming is triggered */ -+ fgIsCheckConnected = TRUE; -+ break; -+ -+ case AIS_STATE_SCAN: -+ /* Do abort SCAN */ -+ aisFsmStateAbort_SCAN(prAdapter); -+ -+ /* queue for later handling */ -+ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, FALSE) == FALSE) -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); -+ -+ break; -+ -+ case AIS_STATE_LOOKING_FOR: -+ /* Do abort SCAN */ -+ aisFsmStateAbort_SCAN(prAdapter); -+ -+ /* in case roaming is triggered */ -+ fgIsCheckConnected = TRUE; -+ break; -+ -+ case AIS_STATE_REQ_CHANNEL_JOIN: -+ /* Release channel to CNM */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* in case roaming is triggered */ -+ fgIsCheckConnected = TRUE; -+ break; -+ -+ case AIS_STATE_JOIN: -+ /* Do abort JOIN */ -+ aisFsmStateAbort_JOIN(prAdapter); -+ -+ /* in case roaming is triggered */ -+ fgIsCheckConnected = TRUE; -+ break; -+ -+#if CFG_SUPPORT_ADHOC -+ case AIS_STATE_IBSS_ALONE: -+ case AIS_STATE_IBSS_MERGE: -+ aisFsmStateAbort_IBSS(prAdapter); -+ break; -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ case AIS_STATE_ONLINE_SCAN: -+ /* Do abort SCAN */ -+ aisFsmStateAbort_SCAN(prAdapter); -+ -+ /* queue for later handling */ -+ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, FALSE) == FALSE) -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); -+ -+ fgIsCheckConnected = TRUE; -+ break; -+ -+ case AIS_STATE_NORMAL_TR: -+ fgIsCheckConnected = TRUE; -+ break; -+ -+ case AIS_STATE_DISCONNECTING: -+ /* Do abort NORMAL_TR */ -+ aisFsmStateAbort_NORMAL_TR(prAdapter); -+ -+ break; -+ -+ case AIS_STATE_REQ_REMAIN_ON_CHANNEL: -+ /* release channel */ -+ aisFsmReleaseCh(prAdapter); -+ break; -+ -+ case AIS_STATE_REMAIN_ON_CHANNEL: -+ /* 1. release channel */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 2. stop channel timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); -+ -+ break; -+ -+ default: -+ break; -+ } -+ -+ if (fgIsCheckConnected && (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState)) { -+ -+ /* switch into DISCONNECTING state for sending DEAUTH if necessary */ -+ if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && -+ prAisBssInfo->ucReasonOfDisconnect == DISCONNECT_REASON_CODE_NEW_CONNECTION && -+ prAisBssInfo->prStaRecOfAP && prAisBssInfo->prStaRecOfAP->fgIsInUse) { -+ aisFsmSteps(prAdapter, AIS_STATE_DISCONNECTING); -+ -+ return; -+ } -+ /* Do abort NORMAL_TR */ -+ aisFsmStateAbort_NORMAL_TR(prAdapter); -+ -+ } -+ -+ aisFsmDisconnect(prAdapter, fgDelayIndication); -+ -+ -+} /* end of aisFsmStateAbort() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Join Complete Event from SAA FSM for AIS FSM -+* -+* @param[in] prMsgHdr Message of Join Complete of SAA FSM. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_JOIN_COMP_T prJoinCompMsg; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ P_STA_RECORD_T prStaRec; -+ P_SW_RFB_T prAssocRspSwRfb; -+ P_BSS_INFO_T prAisBssInfo; -+ UINT_8 aucP2pSsid[] = CTIA_MAGIC_SSID; -+ OS_SYSTIME rCurrentTime; -+ -+ DEBUGFUNC("aisFsmRunEventJoinComplete()"); -+ -+ ASSERT(prMsgHdr); -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr; -+ prStaRec = prJoinCompMsg->prStaRec; -+ prAssocRspSwRfb = prJoinCompMsg->prSwRfb; -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ DBGLOG(AIS, TRACE, "AISOK\n"); -+ -+ /* Check State and SEQ NUM */ -+ do { -+ if (prAisFsmInfo->eCurrentState != AIS_STATE_JOIN) -+ break; -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* Check SEQ NUM */ -+ if (prJoinCompMsg->ucSeqNum == prAisFsmInfo->ucSeqNumOfReqMsg) { -+ -+ /* 4 <1> JOIN was successful */ -+ if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { -+ -+ /* 1. Reset retry count */ -+ prAisFsmInfo->ucConnTrialCount = 0; -+ -+ /* Completion of roaming */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ -+#if CFG_SUPPORT_ROAMING -+ /* 2. Deactivate previous BSS */ -+ aisFsmRoamingDisconnectPrevAP(prAdapter, prStaRec); -+ -+ /* 3. Update bss based on roaming staRec */ -+ aisUpdateBssInfoForRoamingAP(prAdapter, prStaRec, prAssocRspSwRfb); -+#endif /* CFG_SUPPORT_ROAMING */ -+ } else { -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */ -+ if ((prAisBssInfo->prStaRecOfAP) && -+ (prAisBssInfo->prStaRecOfAP != prStaRec) && -+ (prAisBssInfo->prStaRecOfAP->fgIsInUse)) { -+ -+ cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, -+ STA_STATE_1); -+ } -+ /* 4 <1.3> Update BSS_INFO_T */ -+ aisUpdateBssInfoForJOIN(prAdapter, prStaRec, prAssocRspSwRfb); -+ -+ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+ /* 4 <1.5> Update RSSI if necessary */ -+ nicUpdateRSSI(prAdapter, NETWORK_TYPE_AIS_INDEX, -+ (INT_8) (RCPI_TO_dBm(prStaRec->ucRCPI)), 0); -+ -+ /* 4 <1.6> Indicate Connected Event to Host immediately. */ -+ /* Require BSSID, Association ID, Beacon Interval.. */ -+ /* from AIS_BSS_INFO_T */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, -+ FALSE); -+ -+ /* add for ctia mode */ -+ if (EQUAL_SSID -+ (aucP2pSsid, CTIA_MAGIC_SSID_LEN, prAisBssInfo->aucSSID, -+ prAisBssInfo->ucSSIDLen)) { -+ nicEnterCtiaMode(prAdapter, TRUE, FALSE); -+ } -+ } -+ -+#if CFG_SUPPORT_ROAMING -+ /* if bssid is given, it means we no need fw roaming */ -+ if (prAdapter->rWifiVar.rConnSettings.eConnectionPolicy != CONNECT_BY_BSSID) -+ roamingFsmRunEventStart(prAdapter); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ /* 4 <1.7> Set the Next State of AIS FSM */ -+ eNextState = AIS_STATE_NORMAL_TR; -+ } -+ /* 4 <2> JOIN was not successful */ -+ else { -+ /* 4 <2.1> Redo JOIN process with other Auth Type if possible */ -+ if (aisFsmStateInit_RetryJOIN(prAdapter, prStaRec) == FALSE) { -+ P_BSS_DESC_T prBssDesc; -+ -+ /* 1. Increase Failure Count */ -+ prStaRec->ucJoinFailureCount++; -+ -+ /* 2. release channel */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 3.1 stop join timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); -+ -+ /* 3.2 reset local variable */ -+ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; -+ -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prStaRec->aucMacAddr); -+ -+ if (prBssDesc == NULL) { -+ /* it maybe NULL when wlanRemove */ -+ /* -+ (1) UI does wifi off during SAA does auth/assoc procedure. -+ (2) We will do LINK_INITIALIZE(&prScanInfo->rBSSDescList); -+ in nicUninitMGMT(). -+ (3) We will handle prMsduInfo->pfTxDoneHandler -+ in nicTxRelease(). -+ (4) prMsduInfo->pfTxDoneHandler will point to -+ saaFsmRunEventTxDone(). -+ (5) Then jump to saaFsmSteps() -> saaFsmSendEventJoinComplete() -+ (6) Finally mboxSendMsg() -> aisFsmRunEventJoinComplete(). -+ (7) In aisFsmRunEventJoinComplete(), we will check -+ "prBssDesc = scanSearchBssDescByBssid(prAdapter, -+ prStaRec->aucMacAddr);" -+ (8) And prBssDesc will be NULL and hangs in -+ "ASSERT(prBssDesc->fgIsConnecting);" when DBG=0. -+ ASSERT(prBssDesc); -+ ASSERT(prBssDesc->fgIsConnecting); -+ */ -+ break; -+ } -+ /* ASSERT(prBssDesc); */ -+ /* ASSERT(prBssDesc->fgIsConnecting); */ -+ prBssDesc->ucJoinFailureCount++; -+ if (prBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) { -+ GET_CURRENT_SYSTIME(&prBssDesc->rJoinFailTime); -+ DBGLOG(AIS, INFO, -+ "Bss %pM join fail %d times,temp disable it at time:%u\n", -+ prBssDesc->aucBSSID, -+ SCN_BSS_JOIN_FAIL_THRESOLD, prBssDesc->rJoinFailTime); -+ } -+ -+ if (prBssDesc) -+ prBssDesc->fgIsConnecting = FALSE; -+ -+ /* 3.3 Free STA-REC */ -+ if (prStaRec != prAisBssInfo->prStaRecOfAP) -+ cnmStaRecFree(prAdapter, prStaRec, FALSE); -+ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+#if CFG_SUPPORT_ROAMING -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+#endif /* CFG_SUPPORT_ROAMING */ -+ } else if (CHECK_FOR_TIMEOUT(rCurrentTime, prAisFsmInfo->rJoinReqTime, -+ SEC_TO_SYSTIME(AIS_JOIN_TIMEOUT))) { -+ /* abort connection trial */ -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_CONNECT_INDICATION, NULL, 0); -+ -+ eNextState = AIS_STATE_IDLE; -+ } else { -+ /* 4.b send reconnect request */ -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); -+ -+ eNextState = AIS_STATE_IDLE; -+ } -+ } -+ } -+ } -+#if DBG -+ else -+ DBGLOG(AIS, WARN, "SEQ NO of AIS JOIN COMP MSG is not matched.\n"); -+#endif /* DBG */ -+ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ } while (FALSE); -+ -+ if (prAssocRspSwRfb) -+ nicRxReturnRFB(prAdapter, prAssocRspSwRfb); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* end of aisFsmRunEventJoinComplete() */ -+ -+#if CFG_SUPPORT_ADHOC -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Grant Msg of IBSS Create which was sent by -+* CNM to indicate that channel was changed for creating IBSS. -+* -+* @param[in] prAdapter Pointer of ADAPTER_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmCreateIBSS(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ ASSERT(prAdapter); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ do { -+ /* Check State */ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_IBSS_ALONE) -+ aisUpdateBssInfoForCreateIBSS(prAdapter); -+ } while (FALSE); -+ -+} /* end of aisFsmCreateIBSS() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Grant Msg of IBSS Merge which was sent by -+* CNM to indicate that channel was changed for merging IBSS. -+* -+* @param[in] prAdapter Pointer of ADAPTER_T -+* @param[in] prStaRec Pointer of STA_RECORD_T for merge -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ P_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ do { -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_IBSS_MERGE: -+ { -+ P_BSS_DESC_T prBssDesc; -+ -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* 4 <1.2> Deactivate previous Peers' STA_RECORD_T in Driver if have. */ -+ bssClearClientList(prAdapter, prAisBssInfo); -+ -+ /* 4 <1.3> Unmark connection flag of previous BSS_DESC_T. */ -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ if (prBssDesc != NULL) { -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = FALSE; -+ } -+ /* 4 <1.4> Update BSS_INFO_T */ -+ aisUpdateBssInfoForMergeIBSS(prAdapter, prStaRec); -+ -+ /* 4 <1.5> Add Peers' STA_RECORD_T to Client List */ -+ bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec); -+ -+ /* 4 <1.6> Activate current Peer's STA_RECORD_T in Driver. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ prStaRec->fgIsMerging = FALSE; -+ -+ /* 4 <1.7> Enable other features */ -+ -+ /* 4 <1.8> Indicate Connected Event to Host immediately. */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE); -+ -+ /* 4 <1.9> Set the Next State of AIS FSM */ -+ eNextState = AIS_STATE_NORMAL_TR; -+ -+ /* 4 <1.10> Release channel privilege */ -+ aisFsmReleaseCh(prAdapter); -+ -+#if CFG_SLT_SUPPORT -+ prAdapter->rWifiVar.rSltInfo.prPseudoStaRec = prStaRec; -+#endif -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+ } while (FALSE); -+ -+} /* end of aisFsmMergeIBSS() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Notification of existing IBSS was found -+* from SCN. -+* -+* @param[in] prMsgHdr Message of Notification of an IBSS was present. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventFoundIBSSPeer(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_AIS_IBSS_PEER_FOUND_T prAisIbssPeerFoundMsg; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ P_STA_RECORD_T prStaRec; -+ P_BSS_INFO_T prAisBssInfo; -+ P_BSS_DESC_T prBssDesc; -+ BOOLEAN fgIsMergeIn; -+ -+ ASSERT(prMsgHdr); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ prAisIbssPeerFoundMsg = (P_MSG_AIS_IBSS_PEER_FOUND_T) prMsgHdr; -+ -+ ASSERT(prAisIbssPeerFoundMsg->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX); -+ -+ prStaRec = prAisIbssPeerFoundMsg->prStaRec; -+ ASSERT(prStaRec); -+ -+ fgIsMergeIn = prAisIbssPeerFoundMsg->fgIsMergeIn; -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_IBSS_ALONE: -+ { -+ /* 4 <1> An IBSS Peer 'merged in'. */ -+ if (fgIsMergeIn) { -+ -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* 4 <1.2> Add Peers' STA_RECORD_T to Client List */ -+ bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec); -+ -+#if CFG_SLT_SUPPORT -+ /* 4 <1.3> Mark connection flag of BSS_DESC_T. */ -+ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); -+ if (prBssDesc != NULL) { -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ } else { -+ ASSERT(0); /* Should be able to find a BSS_DESC_T here. */ -+ } -+ -+ /* 4 <1.4> Activate current Peer's STA_RECORD_T in Driver. */ -+ prStaRec->fgIsQoS = TRUE; /* TODO(Kevin): TBD */ -+#else -+ /* 4 <1.3> Mark connection flag of BSS_DESC_T. */ -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ if (prBssDesc != NULL) { -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ } else { -+ ASSERT(0); /* Should be able to find a BSS_DESC_T here. */ -+ } -+ -+ /* 4 <1.4> Activate current Peer's STA_RECORD_T in Driver. */ -+ prStaRec->fgIsQoS = FALSE; /* TODO(Kevin): TBD */ -+ -+#endif -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ prStaRec->fgIsMerging = FALSE; -+ -+ /* 4 <1.6> sync. to firmware */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <1.7> Indicate Connected Event to Host immediately. */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE); -+ -+ /* 4 <1.8> indicate PM for connected */ -+ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <1.9> Set the Next State of AIS FSM */ -+ eNextState = AIS_STATE_NORMAL_TR; -+ -+ /* 4 <1.10> Release channel privilege */ -+ aisFsmReleaseCh(prAdapter); -+ } -+ /* 4 <2> We need 'merge out' to this IBSS */ -+ else { -+ -+ /* 4 <2.1> Get corresponding BSS_DESC_T */ -+ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); -+ -+ prAisFsmInfo->prTargetBssDesc = prBssDesc; -+ -+ /* 4 <2.2> Set the Next State of AIS FSM */ -+ eNextState = AIS_STATE_IBSS_MERGE; -+ } -+ } -+ break; -+ -+ case AIS_STATE_NORMAL_TR: -+ { -+ -+ /* 4 <3> An IBSS Peer 'merged in'. */ -+ if (fgIsMergeIn) { -+ -+ /* 4 <3.1> Add Peers' STA_RECORD_T to Client List */ -+ bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec); -+ -+#if CFG_SLT_SUPPORT -+ /* 4 <3.2> Activate current Peer's STA_RECORD_T in Driver. */ -+ prStaRec->fgIsQoS = TRUE; /* TODO(Kevin): TBD */ -+#else -+ /* 4 <3.2> Activate current Peer's STA_RECORD_T in Driver. */ -+ prStaRec->fgIsQoS = FALSE; /* TODO(Kevin): TBD */ -+#endif -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ prStaRec->fgIsMerging = FALSE; -+ -+ } -+ /* 4 <4> We need 'merge out' to this IBSS */ -+ else { -+ -+ /* 4 <4.1> Get corresponding BSS_DESC_T */ -+ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); -+ -+ prAisFsmInfo->prTargetBssDesc = prBssDesc; -+ -+ /* 4 <4.2> Set the Next State of AIS FSM */ -+ eNextState = AIS_STATE_IBSS_MERGE; -+ -+ } -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisFsmRunEventFoundIBSSPeer() */ -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Media State to HOST -+* -+* @param[in] eConnectionState Current Media State -+* @param[in] fgDelayIndication Set TRUE for postponing the Disconnect Indication. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+aisIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, -+ ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication) -+{ -+ EVENT_CONNECTION_STATUS rEventConnStatus; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ DEBUGFUNC("aisIndicationOfMediaStateToHost()"); -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* NOTE(Kevin): Move following line to aisChangeMediaState() macro per CM's request. */ -+ /* prAisBssInfo->eConnectionState = eConnectionState; */ -+ -+ /* For indicating the Disconnect Event only if current media state is -+ * disconnected and we didn't do indication yet. -+ */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ if (prAisBssInfo->eConnectionStateIndicated == eConnectionState) -+ return; -+ } -+ -+ if (!fgDelayIndication) { -+ /* 4 <0> Cancel Delay Timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIndicationOfDisconnectTimer); -+ -+ /* 4 <1> Fill EVENT_CONNECTION_STATUS */ -+ rEventConnStatus.ucMediaStatus = (UINT_8) eConnectionState; -+ -+ if (eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ rEventConnStatus.ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; -+ -+ if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { -+ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_INFRA; -+ rEventConnStatus.u2AID = prAisBssInfo->u2AssocId; -+ rEventConnStatus.u2ATIMWindow = 0; -+ } else if (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_IBSS; -+ rEventConnStatus.u2AID = 0; -+ rEventConnStatus.u2ATIMWindow = prAisBssInfo->u2ATIMWindow; -+ } else { -+ ASSERT(0); -+ } -+ -+ COPY_SSID(rEventConnStatus.aucSsid, -+ rEventConnStatus.ucSsidLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ COPY_MAC_ADDR(rEventConnStatus.aucBssid, prAisBssInfo->aucBSSID); -+ -+ rEventConnStatus.u2BeaconPeriod = prAisBssInfo->u2BeaconInterval; -+ rEventConnStatus.u4FreqInKHz = nicChannelNum2Freq(prAisBssInfo->ucPrimaryChannel); -+ -+ switch (prAisBssInfo->ucNonHTBasicPhyType) { -+ case PHY_TYPE_HR_DSSS_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; -+ break; -+ -+ case PHY_TYPE_ERP_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM24; -+ break; -+ -+ case PHY_TYPE_OFDM_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM5; -+ break; -+ -+ default: -+ ASSERT(0); -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; -+ break; -+ } -+ } else { -+ /* Deactivate previous Peers' STA_RECORD_T in Driver if have. */ -+ bssClearClientList(prAdapter, prAisBssInfo); -+ -+#if CFG_PRIVACY_MIGRATION -+ /* Clear the pmkid cache while media disconnect */ -+ secClearPmkid(prAdapter); -+#endif -+ -+ rEventConnStatus.ucReasonOfDisconnect = prAisBssInfo->ucReasonOfDisconnect; -+ } -+ -+ /* 4 <2> Indication */ -+ nicMediaStateChange(prAdapter, NETWORK_TYPE_AIS_INDEX, &rEventConnStatus); -+ prAisBssInfo->eConnectionStateIndicated = eConnectionState; -+ } else { -+ /* NOTE: Only delay the Indication of Disconnect Event */ -+ ASSERT(eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ DBGLOG(AIS, INFO, "Postpone the indication of Disconnect for %d seconds\n", -+ prConnSettings->ucDelayTimeOfDisconnectEvent); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prAisFsmInfo->rIndicationOfDisconnectTimer, -+ SEC_TO_MSEC(prConnSettings->ucDelayTimeOfDisconnectEvent)); -+ } -+ -+} /* end of aisIndicationOfMediaStateToHost() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Media Disconnect" to HOST -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisPostponedEventOfDisconnTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* 4 <1> Deactivate previous AP's STA_RECORD_T in Driver if have. */ -+ if (prAisBssInfo->prStaRecOfAP) { -+ /* cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); */ -+ -+ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ } -+ /* 4 <2> Remove pending connection request */ -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE); -+ prConnSettings->fgIsDisconnectedByNonRequest = TRUE; -+ prAisBssInfo->u2DeauthReason = REASON_CODE_BEACON_TIMEOUT; -+ /* 4 <3> Indicate Disconnected Event to Host immediately. */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, FALSE); -+ -+} /* end of aisPostponedEventOfDisconnTimeout() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will update the contain of BSS_INFO_T for AIS network once -+* the association was completed. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] prAssocRspSwRfb Pointer to SW RFB of ASSOC RESP FRAME. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, P_SW_RFB_T prAssocRspSwRfb) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; -+ P_BSS_DESC_T prBssDesc; -+ UINT_16 u2IELength; -+ PUINT_8 pucIE; -+ -+ DEBUGFUNC("aisUpdateBssInfoForJOIN()"); -+ -+ ASSERT(prStaRec); -+ ASSERT(prAssocRspSwRfb); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader; -+ -+ DBGLOG(AIS, TRACE, "Update AIS_BSS_INFO_T and apply settings to MAC\n"); -+ -+ /* 3 <1> Update BSS_INFO_T from AIS_FSM_INFO_T or User Settings */ -+ /* 4 <1.1> Setup Operation Mode */ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; -+ -+ /* 4 <1.2> Setup SSID */ -+ COPY_SSID(prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ /* 4 <1.3> Setup Channel, Band */ -+ prAisBssInfo->ucPrimaryChannel = prAisFsmInfo->prTargetBssDesc->ucChannelNum; -+ prAisBssInfo->eBand = prAisFsmInfo->prTargetBssDesc->eBand; -+ -+ /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ -+ /* 4 <2.1> Save current AP's STA_RECORD_T and current AID */ -+ prAisBssInfo->prStaRecOfAP = prStaRec; -+ prAisBssInfo->u2AssocId = prStaRec->u2AssocId; -+ -+ /* 4 <2.2> Setup Capability */ -+ prAisBssInfo->u2CapInfo = prStaRec->u2CapInfo; /* Use AP's Cap Info as BSS Cap Info */ -+ -+ if (prAisBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) -+ prAisBssInfo->fgIsShortPreambleAllowed = TRUE; -+ else -+ prAisBssInfo->fgIsShortPreambleAllowed = FALSE; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ /* init the TDLS flags */ -+ prAisBssInfo->fgTdlsIsProhibited = prStaRec->fgTdlsIsProhibited; -+ prAisBssInfo->fgTdlsIsChSwProhibited = prStaRec->fgTdlsIsChSwProhibited; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ /* 4 <2.3> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ -+ prAisBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; -+ -+ prAisBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; -+ -+ prAisBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; -+ prAisBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; -+ -+ /* 3 <3> Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ -+ /* 4 <3.1> Setup BSSID */ -+ COPY_MAC_ADDR(prAisBssInfo->aucBSSID, prAssocRspFrame->aucBSSID); -+ -+ u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) - -+ (OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN)); -+ pucIE = prAssocRspFrame->aucInfoElem; -+ -+ /* 4 <3.2> Parse WMM and setup QBSS flag */ -+ /* Parse WMM related IEs and configure HW CRs accordingly */ -+ mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+ -+ prAisBssInfo->fgIsQBSS = prStaRec->fgIsQoS; -+ -+ /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAssocRspFrame->aucBSSID); -+ if (prBssDesc) { -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ prBssDesc->ucJoinFailureCount = 0; -+ -+ /* 4 <4.1> Setup MIB for current BSS */ -+ prAisBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; -+ } else { -+ /* should never happen */ -+ ASSERT(0); -+ } -+ -+ /* NOTE: Defer ucDTIMPeriod updating to when beacon is received after connection */ -+ prAisBssInfo->ucDTIMPeriod = 0; -+ prAisBssInfo->u2ATIMWindow = 0; -+ -+ prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_INFRA; -+ -+ /* 4 <4.2> Update HT information and set channel */ -+ /* Record HT related parameters in rStaRec and rBssInfo -+ * Note: it shall be called before nicUpdateBss() -+ */ -+ rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+ -+ /* 4 <4.3> Sync with firmware for BSS-INFO */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <4.4> *DEFER OPERATION* nicPmIndicateBssConnected() will be invoked */ -+ /* inside scanProcessBeaconAndProbeResp() after 1st beacon is received */ -+ -+} /* end of aisUpdateBssInfoForJOIN() */ -+ -+#if CFG_SUPPORT_ADHOC -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will create an Ad-Hoc network and start sending Beacon Frames. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisUpdateBssInfoForCreateIBSS(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ if (prAisBssInfo->fgIsBeaconActivated) -+ return; -+ /* 3 <1> Update BSS_INFO_T per Network Basis */ -+ /* 4 <1.1> Setup Operation Mode */ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; -+ -+ /* 4 <1.2> Setup SSID */ -+ COPY_SSID(prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ -+ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ prAisBssInfo->u2AssocId = 0; -+ -+ /* 4 <1.4> Setup Channel, Band and Phy Attributes */ -+ prAisBssInfo->ucPrimaryChannel = prConnSettings->ucAdHocChannelNum; -+ prAisBssInfo->eBand = prConnSettings->eAdHocBand; -+ -+ if (prAisBssInfo->eBand == BAND_2G4) { -+ /* Depend on eBand */ -+ prAisBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN; -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prAisBssInfo->ucConfigAdHocAPMode = AD_HOC_MODE_MIXED_11BG; -+ } else { -+ /* Depend on eBand */ -+ prAisBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AN; -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prAisBssInfo->ucConfigAdHocAPMode = AD_HOC_MODE_11A; -+ } -+ -+ /* 4 <1.5> Setup MIB for current BSS */ -+ prAisBssInfo->u2BeaconInterval = prConnSettings->u2BeaconPeriod; -+ prAisBssInfo->ucDTIMPeriod = 0; -+ prAisBssInfo->u2ATIMWindow = prConnSettings->u2AtimWindow; -+ -+ prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_ADHOC; -+ -+#if CFG_PRIVACY_MIGRATION -+ if (prConnSettings->eEncStatus == ENUM_ENCRYPTION1_ENABLED || -+ prConnSettings->eEncStatus == ENUM_ENCRYPTION2_ENABLED || -+ prConnSettings->eEncStatus == ENUM_ENCRYPTION3_ENABLED) { -+ prAisBssInfo->fgIsProtection = TRUE; -+ } else { -+ prAisBssInfo->fgIsProtection = FALSE; -+ } -+#else -+ prAisBssInfo->fgIsProtection = FALSE; -+#endif -+ -+ /* 3 <2> Update BSS_INFO_T common part */ -+ ibssInitForAdHoc(prAdapter, prAisBssInfo); -+ -+ /* 3 <3> Set MAC HW */ -+ /* 4 <3.1> Setup channel and bandwidth */ -+ rlmBssInitForAPandIbss(prAdapter, prAisBssInfo); -+ -+ /* 4 <3.2> use command packets to inform firmware */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <3.3> enable beaconing */ -+ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <3.4> Update AdHoc PM parameter */ -+ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 3 <4> Set ACTIVE flag. */ -+ prAisBssInfo->fgIsBeaconActivated = TRUE; -+ prAisBssInfo->fgHoldSameBssidForIBSS = TRUE; -+ -+ /* 3 <5> Start IBSS Alone Timer */ -+ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer, SEC_TO_MSEC(AIS_IBSS_ALONE_TIMEOUT_SEC)); -+ -+ return; -+ -+} /* end of aisCreateIBSS() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will update the contain of BSS_INFO_T for AIS network once -+* the existing IBSS was found. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisUpdateBssInfoForMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_DESC_T prBssDesc; -+ /* UINT_16 u2IELength; */ -+ /* PUINT_8 pucIE; */ -+ -+ ASSERT(prStaRec); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer); -+ -+ if (!prAisBssInfo->fgIsBeaconActivated) { -+ -+ /* 3 <1> Update BSS_INFO_T per Network Basis */ -+ /* 4 <1.1> Setup Operation Mode */ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; -+ -+ /* 4 <1.2> Setup SSID */ -+ COPY_SSID(prAisBssInfo->aucSSID, -+ prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ -+ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ prAisBssInfo->u2AssocId = 0; -+ } -+ /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ -+ /* 4 <2.1> Setup Capability */ -+ prAisBssInfo->u2CapInfo = prStaRec->u2CapInfo; /* Use Peer's Cap Info as IBSS Cap Info */ -+ -+ if (prAisBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) { -+ prAisBssInfo->fgIsShortPreambleAllowed = TRUE; -+ prAisBssInfo->fgUseShortPreamble = TRUE; -+ } else { -+ prAisBssInfo->fgIsShortPreambleAllowed = FALSE; -+ prAisBssInfo->fgUseShortPreamble = FALSE; -+ } -+ -+ /* 7.3.1.4 For IBSS, the Short Slot Time subfield shall be set to 0. */ -+ prAisBssInfo->fgUseShortSlotTime = FALSE; /* Set to FALSE for AdHoc */ -+ prAisBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME; -+ -+ if (prAisBssInfo->u2CapInfo & CAP_INFO_PRIVACY) -+ prAisBssInfo->fgIsProtection = TRUE; -+ else -+ prAisBssInfo->fgIsProtection = FALSE; -+ -+ /* 4 <2.2> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ -+ prAisBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; -+ -+ prAisBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; -+ -+ prAisBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; -+ prAisBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; -+ -+ rateGetDataRatesFromRateSet(prAisBssInfo->u2OperationalRateSet, -+ prAisBssInfo->u2BSSBasicRateSet, -+ prAisBssInfo->aucAllSupportedRates, &prAisBssInfo->ucAllSupportedRatesLen); -+ -+ /* 3 <3> X Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ -+ -+ /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ -+ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); -+ if (prBssDesc) { -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ -+ /* 4 <4.1> Setup BSSID */ -+ COPY_MAC_ADDR(prAisBssInfo->aucBSSID, prBssDesc->aucBSSID); -+ -+ /* 4 <4.2> Setup Channel, Band */ -+ prAisBssInfo->ucPrimaryChannel = prBssDesc->ucChannelNum; -+ prAisBssInfo->eBand = prBssDesc->eBand; -+ -+ /* 4 <4.3> Setup MIB for current BSS */ -+ prAisBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; -+ prAisBssInfo->ucDTIMPeriod = 0; -+ prAisBssInfo->u2ATIMWindow = 0; /* TBD(Kevin) */ -+ -+ prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_ADHOC; -+ } else { -+ /* should never happen */ -+ ASSERT(0); -+ } -+ -+ /* 3 <5> Set MAC HW */ -+ /* 4 <5.1> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ -+ { -+ UINT_8 ucLowestBasicRateIndex; -+ -+ if (!rateGetLowestRateIndexFromRateSet(prAisBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex)) { -+ -+ if (prAisBssInfo->ucPhyTypeSet & PHY_TYPE_BIT_OFDM) -+ ucLowestBasicRateIndex = RATE_6M_INDEX; -+ else -+ ucLowestBasicRateIndex = RATE_1M_INDEX; -+ } -+ -+ prAisBssInfo->ucHwDefaultFixedRateCode = -+ aucRateIndex2RateCode[prAisBssInfo->fgUseShortPreamble][ucLowestBasicRateIndex]; -+ } -+ -+ /* 4 <5.2> Setup channel and bandwidth */ -+ rlmBssInitForAPandIbss(prAdapter, prAisBssInfo); -+ -+ /* 4 <5.3> use command packets to inform firmware */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <5.4> enable beaconing */ -+ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <5.5> Update AdHoc PM parameter */ -+ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 3 <6> Set ACTIVE flag. */ -+ prAisBssInfo->fgIsBeaconActivated = TRUE; -+ prAisBssInfo->fgHoldSameBssidForIBSS = TRUE; -+ -+} /* end of aisUpdateBssInfoForMergeIBSS() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Probe Request Frame and then return -+* result to BSS to indicate if need to send the corresponding Probe Response -+* Frame if the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu4ControlFlags Control flags for replying the Probe Response -+* -+* @retval TRUE Reply the Probe Response -+* @retval FALSE Don't reply the Probe Response -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN aisValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags) -+{ -+ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; -+ P_BSS_INFO_T prBssInfo; -+ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; -+ PUINT_8 pucIE; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ BOOLEAN fgReplyProbeResp = FALSE; -+ -+ ASSERT(prSwRfb); -+ ASSERT(pu4ControlFlags); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* 4 <1> Parse Probe Req IE and Get IE ptr (SSID, Supported Rate IE, ...) */ -+ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; -+ -+ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; -+ pucIE = (PUINT_8) prSwRfb->pvHeader + prSwRfb->u2HeaderLen; -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ if (ELEM_ID_SSID == IE_ID(pucIE)) { -+ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ /* 4 <2> Check network conditions */ -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ -+ if ((prIeSsid) && ((prIeSsid->ucLength == BC_SSID_LEN) || /* WILDCARD SSID */ -+ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, /* CURRENT SSID */ -+ prIeSsid->aucSSID, prIeSsid->ucLength))) { -+ fgReplyProbeResp = TRUE; -+ } -+ } -+ -+ return fgReplyProbeResp; -+ -+} /* end of aisValidateProbeReq() */ -+ -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will modify and update necessary information to firmware -+* for disconnection handling -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* -+* @retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmDisconnect(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgDelayIndication) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+#if CFG_SUPPORT_ADHOC -+ if (prAisBssInfo->fgIsBeaconActivated) { -+ nicUpdateBeaconIETemplate(prAdapter, IE_UPD_METHOD_DELETE_ALL, NETWORK_TYPE_AIS_INDEX, 0, NULL, 0); -+ -+ prAisBssInfo->fgIsBeaconActivated = FALSE; -+ } -+#endif -+ -+ rlmBssAborted(prAdapter, prAisBssInfo); -+ -+ /* 4 <3> Unset the fgIsConnected flag of BSS_DESC_T and send Deauth if needed. */ -+ if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) { -+ /* add for ctia mode */ -+ { -+ UINT_8 aucP2pSsid[] = CTIA_MAGIC_SSID; -+ -+ if (EQUAL_SSID(aucP2pSsid, CTIA_MAGIC_SSID_LEN, prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen)) -+ nicEnterCtiaMode(prAdapter, FALSE, FALSE); -+ } -+ -+ if (prAisBssInfo->ucReasonOfDisconnect == DISCONNECT_REASON_CODE_RADIO_LOST) { -+ scanRemoveBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ -+ /* remove from scanning results as well */ -+ wlanClearBssInScanningResult(prAdapter, prAisBssInfo->aucBSSID); -+ -+ /* trials for re-association */ -+ if (fgDelayIndication) { -+ DBGLOG(AIS, INFO, "try to do re-association due to radio lost!\n"); -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE); -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); -+ } -+ } else { -+ scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ } -+ -+ if (fgDelayIndication) { -+ if (OP_MODE_IBSS != prAisBssInfo->eCurrentOPMode) -+ prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; -+ } else { -+ prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; -+ } -+ } else { -+ prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; -+ } -+ -+ /* 4 <4> Change Media State immediately. */ -+ if (prAisBssInfo->ucReasonOfDisconnect != DISCONNECT_REASON_CODE_REASSOCIATION) { -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ /* 4 <4.1> sync. with firmware */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ } -+ -+ if (!fgDelayIndication) { -+ /* 4 <5> Deactivate previous AP's STA_RECORD_T or all Clients in Driver if have. */ -+ if (prAisBssInfo->prStaRecOfAP) { -+ /* cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); */ -+ -+ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ } -+ } -+#if CFG_SUPPORT_ROAMING -+ roamingFsmRunEventAbort(prAdapter); -+ -+ /* clear pending roaming connection request */ -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE); -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ /* 4 <6> Indicate Disconnected Event to Host */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, fgDelayIndication); -+ -+ /* 4 <7> Trigger AIS FSM */ -+ aisFsmSteps(prAdapter, AIS_STATE_IDLE); -+ -+} /* end of aisFsmDisconnect() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of Scan done Time-Out to AIS FSM. -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 IsrCnt = 0, IsrPassCnt = 0, TaskIsrCnt = 0; -+VOID aisFsmRunEventScanDoneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+#define SCAN_DONE_TIMEOUT_TIMES_LIMIT 20 -+ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ GL_HIF_INFO_T *HifInfo; -+ UINT_32 u4FwCnt; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ DEBUGFUNC("aisFsmRunEventScanDoneTimeOut()"); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ HifInfo = &prAdapter->prGlueInfo->rHifInfo; -+ -+ DBGLOG(AIS, WARN, "aisFsmRunEventScanDoneTimeOut Current[%d], ucScanTimeoutTimes=%d\n", -+ prAisFsmInfo->eCurrentState, ucScanTimeoutTimes); -+ DBGLOG(AIS, WARN, "Isr/task %u %u %u (0x%x)\n", prGlueInfo->IsrCnt, prGlueInfo->IsrPassCnt, -+ prGlueInfo->TaskIsrCnt, prAdapter->fgIsIntEnable); -+ -+ /* dump firmware program counter */ -+ DBGLOG(AIS, WARN, "CONNSYS FW CPUINFO:\n"); -+ for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++) -+ DBGLOG(AIS, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR)); -+ -+ ucScanTimeoutTimes++; -+ if (ucScanTimeoutTimes > SCAN_DONE_TIMEOUT_TIMES_LIMIT) { -+ kalSendAeeWarning("[Scan done timeout more than 20 times!]", __func__); -+ glDoChipReset(); -+ } -+#if 0 /* ALPS02018734: remove trigger assert */ -+ if (prAdapter->fgTestMode == FALSE) { -+ /* Titus - xxx */ -+ /* assert if and only if in normal mode */ -+ mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 40); -+ } -+#endif -+ /* report all scanned frames to upper layer to avoid scanned frame is timeout */ -+ /* must be put before kalScanDone */ -+/* scanReportBss2Cfg80211(prAdapter,BSS_TYPE_INFRASTRUCTURE,NULL); */ -+ -+ prConnSettings->fgIsScanReqIssued = FALSE; -+ kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS); -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_SCAN: -+ prAisFsmInfo->u4ScanIELength = 0; -+ eNextState = AIS_STATE_IDLE; -+ break; -+ case AIS_STATE_ONLINE_SCAN: -+ /* reset scan IE buffer */ -+ prAisFsmInfo->u4ScanIELength = 0; -+#if CFG_SUPPORT_ROAMING -+ eNextState = aisFsmRoamingScanResultsUpdate(prAdapter); -+#else -+ eNextState = AIS_STATE_NORMAL_TR; -+#endif /* CFG_SUPPORT_ROAMING */ -+ break; -+ default: -+ break; -+ } -+ -+ /* try to stop scan in CONNSYS */ -+ aisFsmStateAbort_SCAN(prAdapter); -+ -+ /* wlanQueryDebugCode(prAdapter); */ /* display current SCAN FSM in FW, debug use */ -+ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisFsmBGSleepTimeout() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Background Scan Time-Out" to AIS FSM. -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventBGSleepTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ -+ DEBUGFUNC("aisFsmRunEventBGSleepTimeOut()"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_WAIT_FOR_NEXT_SCAN: -+ DBGLOG(AIS, LOUD, "EVENT - SCAN TIMER: Idle End - Current Time = %u\n", kalGetTimeTick()); -+ -+ eNextState = AIS_STATE_LOOKING_FOR; -+ -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ break; -+ -+ default: -+ break; -+ } -+ -+ /* Call aisFsmSteps() when we are going to change AIS STATE */ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisFsmBGSleepTimeout() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "IBSS ALONE Time-Out" to AIS FSM. -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventIbssAloneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ -+ DEBUGFUNC("aisFsmRunEventIbssAloneTimeOut()"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_IBSS_ALONE: -+ -+ /* There is no one participate in our AdHoc during this TIMEOUT Interval -+ * so go back to search for a valid IBSS again. -+ */ -+ -+ DBGLOG(AIS, LOUD, "EVENT-IBSS ALONE TIMER: Start pairing\n"); -+ -+ prAisFsmInfo->fgTryScan = TRUE; -+ -+ /* abort timer */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* Pull back to SEARCH to find candidate again */ -+ eNextState = AIS_STATE_SEARCH; -+ -+ break; -+ -+ default: -+ break; -+ } -+ -+ /* Call aisFsmSteps() when we are going to change AIS STATE */ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisIbssAloneTimeOut() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Join Time-Out" to AIS FSM. -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventJoinTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ OS_SYSTIME rCurrentTime; -+ -+ DEBUGFUNC("aisFsmRunEventJoinTimeout()"); -+ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_JOIN: -+ DBGLOG(AIS, LOUD, "EVENT- JOIN TIMEOUT\n"); -+ -+ /* 1. Do abort JOIN */ -+ aisFsmStateAbort_JOIN(prAdapter); -+ -+ /* 2. Increase Join Failure Count */ -+ prAisFsmInfo->prTargetBssDesc->ucJoinFailureCount++; -+/* For JB nl802.11 */ -+ if (prAisFsmInfo->prTargetBssDesc->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) { -+ /* 3.1 Retreat to AIS_STATE_SEARCH state for next try */ -+ eNextState = AIS_STATE_SEARCH; -+ } else if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* 3.2 Retreat to AIS_STATE_WAIT_FOR_NEXT_SCAN state for next try */ -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+ } else if (!CHECK_FOR_TIMEOUT(rCurrentTime, prAisFsmInfo->rJoinReqTime, -+ SEC_TO_SYSTIME(AIS_JOIN_TIMEOUT))) { -+ /* 3.3 Retreat to AIS_STATE_WAIT_FOR_NEXT_SCAN state for next try */ -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+ } else { -+ /* 3.4 Retreat to AIS_STATE_JOIN_FAILURE to terminate join operation */ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_CONNECT_INDICATION, NULL, 0); -+ eNextState = AIS_STATE_IDLE; -+ } -+ break; -+ -+ case AIS_STATE_NORMAL_TR: -+ /* 1. release channel */ -+ aisFsmReleaseCh(prAdapter); -+ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; -+ -+ /* 2. process if there is pending scan */ -+ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE) { -+ wlanClearScanningResult(prAdapter); -+ eNextState = AIS_STATE_ONLINE_SCAN; -+ } -+ -+ break; -+ -+ default: -+ /* release channel */ -+ aisFsmReleaseCh(prAdapter); -+ break; -+ -+ } -+ -+ /* Call aisFsmSteps() when we are going to change AIS STATE */ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisFsmRunEventJoinTimeout() */ -+ -+VOID aisFsmRunEventDeauthTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ aisDeauthXmitComplete(prAdapter, NULL, TX_RESULT_LIFE_TIMEOUT); -+} -+ -+#if defined(CFG_TEST_MGMT_FSM) && (CFG_TEST_MGMT_FSM != 0) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisTest(VOID) -+{ -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ UINT_8 aucSSID[] = "pci-11n"; -+ UINT_8 ucSSIDLen = 7; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* Set Connection Request Issued Flag */ -+ prConnSettings->fgIsConnReqIssued = TRUE; -+ prConnSettings->ucSSIDLen = ucSSIDLen; -+ kalMemCopy(prConnSettings->aucSSID, aucSSID, ucSSIDLen); -+ -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) { -+ -+ ASSERT(0); /* Can't trigger SCAN FSM */ -+ return; -+ } -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_HEM_AIS_FSM_ABORT; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ wifi_send_msg(INDX_WIFI, MSG_ID_WIFI_IST, 0); -+ -+} -+#endif /* CFG_TEST_MGMT_FSM */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to handle OID_802_11_BSSID_LIST_SCAN -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[in] prSsid Pointer of SSID_T if specified -+* \param[in] pucIe Pointer to buffer of extra information elements to be attached -+* \param[in] u4IeLength Length of information elements -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmScanRequest(IN P_ADAPTER_T prAdapter, IN P_PARAM_SSID_T prSsid, IN PUINT_8 pucIe, IN UINT_32 u4IeLength) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ DEBUGFUNC("aisFsmScanRequest()"); -+ -+ ASSERT(prAdapter); -+ ASSERT(u4IeLength <= MAX_IE_LENGTH); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ if (!prConnSettings->fgIsScanReqIssued) { -+ prConnSettings->fgIsScanReqIssued = TRUE; -+ -+ if (prSsid == NULL) { -+ prAisFsmInfo->ucScanSSIDLen = 0; -+ } else { -+ COPY_SSID(prAisFsmInfo->aucScanSSID, -+ prAisFsmInfo->ucScanSSIDLen, prSsid->aucSsid, (UINT_8) prSsid->u4SsidLen); -+ } -+ -+ if (u4IeLength > 0 && u4IeLength <= MAX_IE_LENGTH) { -+ prAisFsmInfo->u4ScanIELength = u4IeLength; -+ kalMemCopy(prAisFsmInfo->aucScanIEBuf, pucIe, u4IeLength); -+ } else { -+ prAisFsmInfo->u4ScanIELength = 0; -+ } -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR) { -+ if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE -+ && prAisFsmInfo->fgIsInfraChannelFinished == FALSE) { -+ /* 802.1x might not finished yet, pend it for later handling .. */ -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); -+ } else { -+ if (prAisFsmInfo->fgIsChannelGranted == TRUE) { -+ DBGLOG(AIS, WARN, -+ "Scan Request with channel granted for join operation: %d, %d", -+ prAisFsmInfo->fgIsChannelGranted, prAisFsmInfo->fgIsChannelRequested); -+ } -+ -+ /* start online scan */ -+ wlanClearScanningResult(prAdapter); -+ aisFsmSteps(prAdapter, AIS_STATE_ONLINE_SCAN); -+ } -+ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_IDLE) { -+ wlanClearScanningResult(prAdapter); -+ aisFsmSteps(prAdapter, AIS_STATE_SCAN); -+ } else { -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); -+ } -+ } else { -+ DBGLOG(AIS, WARN, "Scan Request dropped. (state: %d)\n", prAisFsmInfo->eCurrentState); -+ } -+ -+} /* end of aisFsmScanRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is invoked when CNM granted channel privilege -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_CH_GRANT_T prMsgChGrant; -+ UINT_8 ucTokenID; -+ UINT_32 u4GrantInterval; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr; -+ -+ ucTokenID = prMsgChGrant->ucTokenID; -+ u4GrantInterval = prMsgChGrant->u4GrantInterval; -+ -+ /* 1. free message */ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_CHANNEL_JOIN && prAisFsmInfo->ucSeqNumOfChReq == ucTokenID) { -+ /* 2. channel privilege has been approved */ -+ prAisFsmInfo->u4ChGrantedInterval = u4GrantInterval; -+ -+ /* 3. state transition to join/ibss-alone/ibss-merge */ -+ /* 3.1 set timeout timer in cases join could not be completed */ -+ cnmTimerStartTimer(prAdapter, -+ &prAisFsmInfo->rJoinTimeoutTimer, -+ prAisFsmInfo->u4ChGrantedInterval - AIS_JOIN_CH_GRANT_THRESHOLD); -+ /* 3.2 set local variable to indicate join timer is ticking */ -+ prAisFsmInfo->fgIsInfraChannelFinished = FALSE; -+ -+ /* 3.3 switch to join state */ -+ aisFsmSteps(prAdapter, AIS_STATE_JOIN); -+ -+ prAisFsmInfo->fgIsChannelGranted = TRUE; -+ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_REMAIN_ON_CHANNEL && -+ prAisFsmInfo->ucSeqNumOfChReq == ucTokenID) { -+ /* 2. channel privilege has been approved */ -+ prAisFsmInfo->u4ChGrantedInterval = u4GrantInterval; -+ -+ /* 3.1 set timeout timer in cases upper layer cancel_remain_on_channel never comes */ -+ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer, prAisFsmInfo->u4ChGrantedInterval); -+ -+ /* 3.2 switch to remain_on_channel state */ -+ aisFsmSteps(prAdapter, AIS_STATE_REMAIN_ON_CHANNEL); -+ -+ /* 3.3. indicate upper layer for channel ready */ -+ kalReadyOnChannel(prAdapter->prGlueInfo, -+ prAisFsmInfo->rChReqInfo.u8Cookie, -+ prAisFsmInfo->rChReqInfo.eBand, -+ prAisFsmInfo->rChReqInfo.eSco, -+ prAisFsmInfo->rChReqInfo.ucChannelNum, prAisFsmInfo->rChReqInfo.u4DurationMs); -+ -+ prAisFsmInfo->fgIsChannelGranted = TRUE; -+ } else { /* mismatched grant */ -+ /* 2. return channel privilege to CNM immediately */ -+ aisFsmReleaseCh(prAdapter); -+ } -+ -+} /* end of aisFsmRunEventChGrant() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform CNM that channel privilege -+* has been released -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmReleaseCh(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_CH_ABORT_T prMsgChAbort; -+ -+ ASSERT(prAdapter); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ if (prAisFsmInfo->fgIsChannelGranted == TRUE || prAisFsmInfo->fgIsChannelRequested == TRUE) { -+ -+ prAisFsmInfo->fgIsChannelRequested = FALSE; -+ prAisFsmInfo->fgIsChannelGranted = FALSE; -+ -+ /* 1. return channel privilege to CNM immediately */ -+ prMsgChAbort = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T)); -+ if (!prMsgChAbort) { -+ ASSERT(0); /* Can't release Channel to CNM */ -+ return; -+ } -+ -+ prMsgChAbort->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; -+ prMsgChAbort->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ prMsgChAbort->ucTokenID = prAisFsmInfo->ucSeqNumOfChReq; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChAbort, MSG_SEND_METHOD_BUF); -+ } -+ -+} /* end of aisFsmReleaseCh() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform AIS that corresponding beacon has not -+* been received for a while and probing is not successful -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisBssBeaconTimeout(IN P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ BOOLEAN fgDoAbortIndication = FALSE; -+ -+ ASSERT(prAdapter); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* 4 <1> Diagnose Connection for Beacon Timeout Event */ -+ if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) { -+ if (OP_MODE_INFRASTRUCTURE == prAisBssInfo->eCurrentOPMode) { -+ P_STA_RECORD_T prStaRec = prAisBssInfo->prStaRecOfAP; -+ -+ if (prStaRec) -+ fgDoAbortIndication = TRUE; -+ } else if (OP_MODE_IBSS == prAisBssInfo->eCurrentOPMode) { -+ fgDoAbortIndication = TRUE; -+ } -+ } -+ /* 4 <2> invoke abort handler */ -+ if (fgDoAbortIndication) { -+#if 0 -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prConnSettings->fgIsDisconnectedByNonRequest = TRUE; -+#endif -+ -+ DBGLOG(AIS, INFO, "Beacon Timeout, Remove BSS [%pM]\n", prAisBssInfo->aucBSSID); -+ scanRemoveBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ -+ /* -+ Note: Cannot change TRUE to FALSE; or you will suffer the problem in -+ ALPS01270257/ ALPS01804173 -+ */ -+ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_RADIO_LOST, TRUE); -+ } -+ -+} /* end of aisBssBeaconTimeout() */ -+ -+VOID aisBssSecurityChanged(P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ prAdapter->rWifiVar.rConnSettings.fgIsDisconnectedByNonRequest = TRUE; -+ prAisBssInfo->u2DeauthReason = REASON_CODE_BSS_SECURITY_CHANGE; -+ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_DEAUTHENTICATED, FALSE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform AIS that DEAUTH frame has been -+* sent and thus state machine could go ahead -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[in] prMsduInfo Pointer of MSDU_INFO_T for DEAUTH frame -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+aisDeauthXmitComplete(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ ASSERT(prAdapter); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ if (rTxDoneStatus == TX_RESULT_SUCCESS) -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rDeauthDoneTimer); -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_DISCONNECTING) { -+ if (rTxDoneStatus != TX_RESULT_DROPPED_IN_DRIVER) -+ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_NEW_CONNECTION, FALSE); -+ } else { -+ DBGLOG(AIS, WARN, "DEAUTH frame transmitted without further handling"); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of aisDeauthXmitComplete() */ -+ -+#if CFG_SUPPORT_ROAMING -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Looking for a candidate due to weak signal" to AIS FSM. -+* -+* @param[in] u4ReqScan Requesting Scan or not -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventRoamingDiscovery(IN P_ADAPTER_T prAdapter, UINT_32 u4ReqScan) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ ENUM_AIS_REQUEST_TYPE_T eAisRequest; -+ -+ DBGLOG(AIS, LOUD, "aisFsmRunEventRoamingDiscovery()\n"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* search candidates by best rssi */ -+ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; -+ -+#if CFG_SUPPORT_WFD -+#if CFG_ENABLE_WIFI_DIRECT -+ { -+ /* Check WFD is running */ -+ P_BSS_INFO_T prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ if (prAdapter->fgIsP2PRegistered && -+ IS_BSS_ACTIVE(prP2pBssInfo) && -+ (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT || -+ prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE)) { -+ DBGLOG(ROAMING, INFO, "Handle roaming when P2P is GC or GO.\n"); -+ if (prAdapter->rWifiVar.prP2pFsmInfo) { -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ if ((prWfdCfgSettings->ucWfdEnable == 1) && -+ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) { -+ DBGLOG(ROAMING, INFO, "WFD is running. Stop roaming.\n"); -+ roamingFsmRunEventRoam(prAdapter); -+ roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_NOCANDIDATE); -+ return; -+ } -+ } else { -+ ASSERT(0); -+ } -+ } /* fgIsP2PRegistered */ -+ } -+#endif -+#endif -+ -+ /* results are still new */ -+ if (!u4ReqScan) { -+ roamingFsmRunEventRoam(prAdapter); -+ eAisRequest = AIS_REQUEST_ROAMING_CONNECT; -+ } else { -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN -+ || prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR) { -+ eAisRequest = AIS_REQUEST_ROAMING_CONNECT; -+ } else { -+ eAisRequest = AIS_REQUEST_ROAMING_SEARCH; -+ } -+ } -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR && prAisFsmInfo->fgIsInfraChannelFinished == TRUE) { -+ if (eAisRequest == AIS_REQUEST_ROAMING_SEARCH) -+ aisFsmSteps(prAdapter, AIS_STATE_LOOKING_FOR); -+ else -+ aisFsmSteps(prAdapter, AIS_STATE_SEARCH); -+ } else { -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE); -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE); -+ -+ aisFsmInsertRequest(prAdapter, eAisRequest); -+ } -+ -+} /* end of aisFsmRunEventRoamingDiscovery() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Update the time of ScanDone for roaming and transit to Roam state. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_AIS_STATE_T aisFsmRoamingScanResultsUpdate(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ -+ DBGLOG(AIS, LOUD, "->aisFsmRoamingScanResultsUpdate()\n"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ roamingFsmScanResultsUpdate(prAdapter); -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ if (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_DISCOVERY) { -+ roamingFsmRunEventRoam(prAdapter); -+ eNextState = AIS_STATE_SEARCH; -+ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR) { -+ eNextState = AIS_STATE_SEARCH; -+ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN) { -+ eNextState = AIS_STATE_NORMAL_TR; -+ } -+ -+ return eNextState; -+} /* end of aisFsmRoamingScanResultsUpdate() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will modify and update necessary information to firmware -+* for disconnection of last AP before switching to roaming bss. -+* -+* @param IN prAdapter Pointer to the Adapter structure. -+* prTargetStaRec Target of StaRec of roaming -+* -+* @retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRoamingDisconnectPrevAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prTargetStaRec) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ -+ DBGLOG(AIS, LOUD, "aisFsmRoamingDisconnectPrevAP()"); -+ -+ ASSERT(prAdapter); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* Not invoke rlmBssAborted() here to avoid prAisBssInfo->fg40mBwAllowed -+ * to be reset. RLM related parameters will be reset again when handling -+ * association response in rlmProcessAssocRsp(). 20110413 -+ */ -+ /* rlmBssAborted(prAdapter, prAisBssInfo); */ -+ -+ /* 4 <3> Unset the fgIsConnected flag of BSS_DESC_T and send Deauth if needed. */ -+ if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) -+ scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ /* 4 <4> Change Media State immediately. */ -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ /* 4 <4.1> sync. with firmware */ -+ prTargetStaRec->ucNetTypeIndex = 0xff; /* Virtial NetType */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ prTargetStaRec->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; /* Virtial NetType */ -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ TdlsexLinkHistoryRecord(prAdapter->prGlueInfo, TRUE, prAisBssInfo->aucBSSID, -+ TRUE, TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_ROAMING); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+} /* end of aisFsmRoamingDisconnectPrevAP() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will update the contain of BSS_INFO_T for AIS network once -+* the roaming was completed. -+* -+* @param IN prAdapter Pointer to the Adapter structure. -+* prStaRec StaRec of roaming AP -+* prAssocRspSwRfb -+* -+* @retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisUpdateBssInfoForRoamingAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ -+ DBGLOG(AIS, LOUD, "aisUpdateBssInfoForRoamingAP()"); -+ -+ ASSERT(prAdapter); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */ -+ if ((prAisBssInfo->prStaRecOfAP) && -+ (prAisBssInfo->prStaRecOfAP != prStaRec) && (prAisBssInfo->prStaRecOfAP->fgIsInUse)) { -+ cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); -+ } -+ /* 4 <1.3> Update BSS_INFO_T */ -+ aisUpdateBssInfoForJOIN(prAdapter, prStaRec, prAssocRspSwRfb); -+ -+ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+ /* 4 <1.6> Indicate Connected Event to Host immediately. */ -+ /* Require BSSID, Association ID, Beacon Interval.. from AIS_BSS_INFO_T */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE); -+ -+} /* end of aisFsmRoamingUpdateBss() */ -+ -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Check if there is any pending request and remove it (optional) -+* -+* @param prAdapter -+* eReqType -+* bRemove -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN aisFsmIsRequestPending(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType, IN BOOLEAN bRemove) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_AIS_REQ_HDR_T prPendingReqHdr, prPendingReqHdrNext; -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* traverse through pending request list */ -+ LINK_FOR_EACH_ENTRY_SAFE(prPendingReqHdr, -+ prPendingReqHdrNext, &(prAisFsmInfo->rPendingReqList), rLinkEntry, AIS_REQ_HDR_T) { -+ /* check for specified type */ -+ if (prPendingReqHdr->eReqType == eReqType) { -+ /* check if need to remove */ -+ if (bRemove == TRUE) { -+ LINK_REMOVE_KNOWN_ENTRY(&(prAisFsmInfo->rPendingReqList), -+ &(prPendingReqHdr->rLinkEntry)); -+ -+ cnmMemFree(prAdapter, prPendingReqHdr); -+ } -+ -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Get next pending request -+* -+* @param prAdapter -+* -+* @return P_AIS_REQ_HDR_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_AIS_REQ_HDR_T aisFsmGetNextRequest(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_AIS_REQ_HDR_T prPendingReqHdr; -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ LINK_REMOVE_HEAD(&(prAisFsmInfo->rPendingReqList), prPendingReqHdr, P_AIS_REQ_HDR_T); -+ -+ return prPendingReqHdr; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Insert a new request -+* -+* @param prAdapter -+* eReqType -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN aisFsmInsertRequest(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType) -+{ -+ P_AIS_REQ_HDR_T prAisReq; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ prAisReq = (P_AIS_REQ_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(AIS_REQ_HDR_T)); -+ -+ if (!prAisReq) { -+ ASSERT(0); /* Can't generate new message */ -+ return FALSE; -+ } -+ -+ prAisReq->eReqType = eReqType; -+ -+ /* attach request into pending request list */ -+ LINK_INSERT_TAIL(&prAisFsmInfo->rPendingReqList, &prAisReq->rLinkEntry); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Flush all pending requests -+* -+* @param prAdapter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmFlushRequest(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_REQ_HDR_T prAisReq; -+ -+ ASSERT(prAdapter); -+ -+ while ((prAisReq = aisFsmGetNextRequest(prAdapter)) != NULL) -+ cnmMemFree(prAdapter, prAisReq); -+ -+} -+ -+VOID aisFsmRunEventRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_REMAIN_ON_CHANNEL_T prRemainOnChannel; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ DEBUGFUNC("aisFsmRunEventRemainOnChannel()"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ prRemainOnChannel = (P_MSG_REMAIN_ON_CHANNEL_T) prMsgHdr; -+ -+ /* record parameters */ -+ prAisFsmInfo->rChReqInfo.eBand = prRemainOnChannel->eBand; -+ prAisFsmInfo->rChReqInfo.eSco = prRemainOnChannel->eSco; -+ prAisFsmInfo->rChReqInfo.ucChannelNum = prRemainOnChannel->ucChannelNum; -+ prAisFsmInfo->rChReqInfo.u4DurationMs = prRemainOnChannel->u4DurationMs; -+ prAisFsmInfo->rChReqInfo.u8Cookie = prRemainOnChannel->u8Cookie; -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_IDLE || prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR) { -+ /* transit to next state */ -+ aisFsmSteps(prAdapter, AIS_STATE_REQ_REMAIN_ON_CHANNEL); -+ } else { -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL); -+ } -+ -+ /* free messages */ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -+ -+VOID aisFsmRunEventCancelRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_MSG_CANCEL_REMAIN_ON_CHANNEL_T prCancelRemainOnChannel; -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ prCancelRemainOnChannel = (P_MSG_CANCEL_REMAIN_ON_CHANNEL_T) prMsgHdr; -+ -+ /* 1. Check the cookie first */ -+ if (prCancelRemainOnChannel->u8Cookie == prAisFsmInfo->rChReqInfo.u8Cookie) { -+ -+ /* 2. release channel privilege/request */ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_REMAIN_ON_CHANNEL) { -+ /* 2.1 elease channel */ -+ aisFsmReleaseCh(prAdapter); -+ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_REMAIN_ON_CHANNEL) { -+ /* 2.1 release channel */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 2.2 stop channel timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); -+ } -+ -+ /* 3. clear pending request of remain_on_channel */ -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL, TRUE); -+ -+ /* 4. decide which state to retreat */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) -+ aisFsmSteps(prAdapter, AIS_STATE_NORMAL_TR); -+ else -+ aisFsmSteps(prAdapter, AIS_STATE_IDLE); -+ } -+ -+ /* 5. free message */ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -+ -+VOID aisFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_MGMT_TX_REQUEST_T prMgmtTxMsg = (P_MSG_MGMT_TX_REQUEST_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ /* prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); */ -+ -+ if (prAisFsmInfo == NULL) -+ break; -+ prMgmtTxMsg = (P_MSG_MGMT_TX_REQUEST_T) prMsgHdr; -+ -+ aisFuncTxMgmtFrame(prAdapter, -+ &prAisFsmInfo->rMgmtTxInfo, prMgmtTxMsg->prMgmtMsduInfo, prMgmtTxMsg->u8Cookie); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* aisFsmRunEventMgmtFrameTx */ -+ -+VOID aisFsmRunEventChannelTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ -+ DEBUGFUNC("aisFsmRunEventRemainOnChannel()"); -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_REMAIN_ON_CHANNEL) { -+ /* 1. release channel */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 2. stop channel timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); -+ -+ /* 3. expiration indication to upper layer */ -+ kalRemainOnChannelExpired(prAdapter->prGlueInfo, -+ prAisFsmInfo->rChReqInfo.u8Cookie, -+ prAisFsmInfo->rChReqInfo.eBand, -+ prAisFsmInfo->rChReqInfo.eSco, prAisFsmInfo->rChReqInfo.ucChannelNum); -+ -+ /* 4. decide which state to retreat */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) -+ aisFsmSteps(prAdapter, AIS_STATE_NORMAL_TR); -+ else -+ aisFsmSteps(prAdapter, AIS_STATE_IDLE); -+ } else { -+ DBGLOG(AIS, WARN, "Unexpected remain_on_channel timeout event\n"); -+#if DBG -+ DBGLOG(AIS, STATE, "CURRENT State: [%s]\n", apucDebugAisState[prAisFsmInfo->eCurrentState]); -+#else -+ DBGLOG(AIS, STATE, "[%d] CURRENT State: [%d]\n", DBG_AIS_IDX, prAisFsmInfo->eCurrentState); -+#endif -+ } -+ -+} -+ -+WLAN_STATUS -+aisFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo = (P_AIS_MGMT_TX_REQ_INFO_T) NULL; -+ BOOLEAN fgIsSuccess = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prMgmtTxReqInfo = &(prAisFsmInfo->rMgmtTxInfo); -+ -+ if (rTxDoneStatus != TX_RESULT_SUCCESS) { -+ DBGLOG(AIS, ERROR, "Mgmt Frame TX Fail, Status:%d.\n", rTxDoneStatus); -+ } else { -+ fgIsSuccess = TRUE; -+ /* printk("Mgmt Frame TX Done.\n"); */ -+ } -+ -+ if (prMgmtTxReqInfo->prMgmtTxMsdu == prMsduInfo) { -+ kalIndicateMgmtTxStatus(prAdapter->prGlueInfo, -+ prMgmtTxReqInfo->u8Cookie, -+ fgIsSuccess, prMsduInfo->prPacket, (UINT_32) prMsduInfo->u2FrameLength); -+ -+ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; -+ } -+ -+ } while (FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* aisFsmRunEventMgmtFrameTxDone */ -+ -+WLAN_STATUS -+aisFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, -+ IN P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T) NULL; -+ P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxReqInfo != NULL)); -+ -+ if (prMgmtTxReqInfo->fgIsMgmtTxRequested) { -+ -+ /* 1. prMgmtTxReqInfo->prMgmtTxMsdu != NULL */ -+ /* Packet on driver, not done yet, drop it. */ -+ prTxMsduInfo = prMgmtTxReqInfo->prMgmtTxMsdu; -+ if (prTxMsduInfo != NULL) { -+ -+ kalIndicateMgmtTxStatus(prAdapter->prGlueInfo, -+ prMgmtTxReqInfo->u8Cookie, -+ FALSE, -+ prTxMsduInfo->prPacket, (UINT_32) prTxMsduInfo->u2FrameLength); -+ -+ /* Leave it to TX Done handler. */ -+ /* cnmMgtPktFree(prAdapter, prTxMsduInfo); */ -+ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; -+ } -+ /* 2. prMgmtTxReqInfo->prMgmtTxMsdu == NULL */ -+ /* Packet transmitted, wait tx done. (cookie issue) */ -+ } -+ -+ ASSERT(prMgmtTxReqInfo->prMgmtTxMsdu == NULL); -+ -+ prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); -+ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prWlanHdr->aucAddr1); -+ prMgmtTxMsdu->ucNetworkType = (UINT_8) NETWORK_TYPE_AIS_INDEX; -+ -+ prMgmtTxReqInfo->u8Cookie = u8Cookie; -+ prMgmtTxReqInfo->prMgmtTxMsdu = prMgmtTxMsdu; -+ prMgmtTxReqInfo->fgIsMgmtTxRequested = TRUE; -+ -+ prMgmtTxMsdu->eSrc = TX_PACKET_MGMT; -+ prMgmtTxMsdu->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMgmtTxMsdu->ucStaRecIndex = (prStaRec != NULL) ? (prStaRec->ucIndex) : (0xFF); -+ if (prStaRec != NULL) { -+ /* Do nothing */ -+ /* printk("Mgmt with station record: %pM .\n", prStaRec->aucMacAddr); */ -+ } -+ -+ prMgmtTxMsdu->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; /* TODO: undcertain. */ -+ prMgmtTxMsdu->fgIs802_1x = FALSE; -+ prMgmtTxMsdu->fgIs802_11 = TRUE; -+ prMgmtTxMsdu->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMgmtTxMsdu->pfTxDoneHandler = aisFsmRunEventMgmtFrameTxDone; -+ prMgmtTxMsdu->fgIsBasicRate = TRUE; -+ DBGLOG(AIS, TRACE, "Mgmt seq NO. %d .\n", prMgmtTxMsdu->ucTxSeqNum); -+ -+ nicTxEnqueueMsdu(prAdapter, prMgmtTxMsdu); -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* aisFuncTxMgmtFrame */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Action Frame and indicate to uppoer layer -+* if the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu4ControlFlags Control flags for replying the Probe Response -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL; -+ -+ DEBUGFUNC("aisFuncValidateRxActionFrame"); -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ if (1 /* prAisFsmInfo->u4AisPacketFilter & PARAM_PACKET_FILTER_ACTION_FRAME */) { -+ /* Leave the action frame to wpa_supplicant. */ -+ kalIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb); -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* aisFuncValidateRxActionFrame */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c -new file mode 100644 -index 0000000000000..f02d7c3bb5b27 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c -@@ -0,0 +1,1932 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/assoc.c#3 -+*/ -+ -+/*! \file "assoc.c" -+ \brief This file includes the association-related functions. -+ -+ This file includes the association-related functions. -+*/ -+ -+/*\ -+** Log: assoc.c -+** -+** 07 27 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Fix wifi direct connection issue. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 06 08 2012 cp.wu -+ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development -+ * add a pair of brace for compilation success. -+ * -+ * 06 04 2012 cp.wu -+ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development -+ * discussed with WH, privacy bit in associate response is not necessary to be checked, -+ * and identified as association failure when mismatching with beacon/probe response -+ * -+ * 03 14 2012 wh.su -+ * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting -+ * Add code from 2.2 -+ * -+ * 03 09 2012 terry.wu -+ * NULL -+ * Fix build error. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 16 2012 yuche.tsai -+ * NULL -+ * Update Driver for wifi driect gc join IE update issue. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * Fix PhyTypeSet in STA_REC in AP mode -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 19 2011 yuche.tsai -+ * NULL -+ * Fix KE when enable hot-spot & any one client connect to this hot-spot. -+ * -+ * 09 14 2011 yuche.tsai -+ * NULL -+ * Add P2P IE in assoc response. -+ * -+ * 07 15 2011 terry.wu -+ * [WCXRP00000855] [MT6620 Wi-Fi] [Driver] Workaround for Kingnet 710 AP wrong AID assignment -+ * Update workaround for Kingnet AP. -+ * -+ * 07 15 2011 terry.wu -+ * [WCXRP00000855] [MT6620 Wi-Fi] [Driver] Workaround for Kingnet 710 AP wrong AID assignment -+ * Workaround for Kingnet 710 AP wrong AID assignment. -+ * -+ * 05 02 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning[WCXRP00000672] [MT6620 Wi-Fi][FW] -+ * Fix the PS event allocation -+ * Check STA when rx assoc. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Make assoc req to append P2P IE if wifi direct is enabled. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 16 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * enable the protected while at P2P start GO, and skip some security check . -+ * -+ * 03 14 2011 wh.su -+ * [WCXRP00000545] [MT6620 Wi-Fi] [Driver] Fixed the p2p not enable, received a assoc rsp -+ * cause the rx assoc execute a null function -+ * Modify file for avoid assert at BOW receive a assoc response frame but no p2p function. -+ * -+ * 03 08 2011 terry.wu -+ * [WCXRP00000524] [MT6620 Wi-Fi][Driver] Fix p2p assoc request containing wrong IE format -+ * Fix p2p assoc request containing wrong IE format. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add code to let the beacon and probe response for Auto GO WSC . -+ * -+ * 02 15 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Fix RX disassoc issue under Hot-spot mode. -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode -+ * adding the code for check STA privacy bit at AP mode, . -+ * -+ * 02 08 2011 eddie.chen -+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode -+ * Add event STA agint timeout -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Update Phy Type Set. When legacy client is connected, it can use 11b rate, -+ * but if the P2P device is connected, 11b rate is not allowed. -+ * -+ * 01 11 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Update Desired Non-HT Rate Set. -+ * -+ * 12 30 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Recover the code that was coverwritted.. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * use definition macro to replace hard-coded constant -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Change conditional compiling options for BOW -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add SSID IE in assoc req frame which is sent by P2P GC. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 07 20 2010 wh.su -+ * -+ * adding the wapi code. -+ * -+ * 07 09 2010 yarco.yang -+ * -+ * [MT6620 and MT5931] SW Migration: Add ADDBA support -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * comment out RSN IE generation by CFG_RSN_MIGRATION compilation flag. -+ * -+ * 06 28 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * send MMPDU in basic rate. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan_fsm into building. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * specify correct value for management frames. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * revised. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Update assocProcessRxAssocReqFrame() to avoid redundant SSID IE {0,0} for IOT. -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Fix compile warning - macro > 10 line, initial value of an array -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support -+ * * * * * * * * and will send Null frame to diagnose connection -+ * -+ * 04 16 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * adding the wpa-none for ibss beacon. -+ * -+ * 03 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Remove compiling warning -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Not carry HT cap when being associated with b/g only AP -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 28 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * fixed the compiling warning.u1rwduu`wvpghlqg|rm+vp -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update Assoc ID for PS -+ * -+ * 01 04 2010 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * For working out the first connection Chariot-verified version -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Use new constant definition ELEM_MAX_LEN_EXT_CAP -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Modify assoc req IE talbe for HT cap IE -+ * -+ * Dec 7 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * update the assocComposeReAssocReqFrameHeader() and fix the u2EstimatedFrameLen in assocSendReAssocReqFrame() -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * remove some space line -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the sending disassoc frame function -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the txassocReq IE table, adding for WPA/RSN -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix eNetType not init in send AssocReq function -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Integrate the send Assoc with TXM -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the code to indicate the assoc request and assoc response (now disable) -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove unused variables -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+APPEND_VAR_IE_ENTRY_T txAssocReqIETable[] = { -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmReqGenerateHtCapIE} -+ , /* 45 */ -+#if CFG_SUPPORT_WPS2 -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WSC), NULL, rsnGenerateWSCIE} -+ , /* 221 */ -+#endif -+#if CFG_RSN_MIGRATION -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE} -+ , /* 48 */ -+#endif -+#if CFG_SUPPORT_WAPI -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WAPI), NULL, wapiGenerateWAPIIE} -+ , /* 68 */ -+#endif -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_INTERWORKING), NULL, hs20GenerateInterworkingIE} -+ , /* 107 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ROAMING_CONSORTIUM), NULL, hs20GenerateRoamingConsortiumIE} -+ , /* 111 */ -+#endif -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmReqGenerateExtCapIE} -+ , /* 127 */ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HS20_INDICATION), NULL, hs20GenerateHS20IE} -+ , /* 221 */ -+#endif -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_INFO), NULL, mqmGenerateWmmInfoIE} -+ , /* 221 */ -+#if CFG_RSN_MIGRATION -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWPAIE} -+ , /* 221 */ -+#endif -+}; -+ -+#if CFG_SUPPORT_AAA -+VERIFY_IE_ENTRY_T rxAssocReqIETable[] = { -+ {ELEM_ID_RESERVED, NULL} /* 255 */ -+}; -+ -+APPEND_VAR_IE_ENTRY_T txAssocRespIETable[] = { -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE} -+ , /* 42 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE} -+ , /* 45 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE} -+ , /* 61 */ -+#if CFG_ENABLE_WIFI_DIRECT -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE} -+ , /* 74 */ -+ {(0), p2pFuncCalculateP2p_IELenForAssocRsp, p2pFuncGenerateP2p_IEForAssocRsp} -+ , /* 221 */ -+#if CFG_SUPPORT_WFD -+ {(0), wfdFuncCalculateWfdIELenForAssocRsp, wfdFuncGenerateWfdIEForAssocRsp} -+ , /* 221 */ -+#endif -+#endif -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE} -+ , /* 127 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE} -+ , /* 221 */ -+ -+ {(0), p2pFuncCalculateWSC_IELenForAssocRsp, p2pFuncGenerateWSC_IEForAssocRsp} /* 221 */ -+ -+}; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to compose the Capability Info Field. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @retval Capability Info Field -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_16 -+assocBuildCapabilityInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ UINT_32 u4NonHTPhyType; -+ UINT_16 u2CapInfo; -+ -+ /* Set up our requested capabilities. */ -+ u2CapInfo = CAP_INFO_ESS; -+ u2CapInfo |= CAP_CF_STA_NOT_POLLABLE; -+ -+ if (prStaRec == NULL) -+ u2CapInfo |= CAP_INFO_PRIVACY; -+ else { -+ if (prStaRec->u2CapInfo & CAP_INFO_PRIVACY) -+ u2CapInfo |= CAP_INFO_PRIVACY; -+ } -+ -+ /* 7.3.1.4 */ -+ if (prStaRec == NULL) { -+ if ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) ||/* ShortPreambleOptionEnable is TRUE */ -+ (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO)) -+ u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; -+ if (prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable) -+ u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; -+ } else if (prStaRec->fgHasBasicPhyType) { -+ u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; -+ -+ if ((rNonHTPhyAttributes[u4NonHTPhyType].fgIsShortPreambleOptionImplemented) && -+ /* Short Preamble Option Enable is TRUE */ -+ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || -+ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO) && -+ (prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { -+ -+ /* Case I: Implemented == TRUE and Short Preamble Option Enable == TRUE. -+ * Case II: Implemented == TRUE and Short Preamble == AUTO (depends on -+ * BSS_DESC_T's capability) -+ */ -+ u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; -+ } -+#if CFG_SUPPORT_SPEC_MGMT /*Add by Enlai */ -+ /* Support 802.11h */ -+ if (prStaRec->u2CapInfo & CAP_INFO_SPEC_MGT) { -+ /* -+ 1. The Power Capability element shall be present if -+ dot11SpectrumManagementRequired is true. -+ -+ 2. A STA shall set dot11SpectrumManagementRequired to TRUE before -+ associating with a BSS or IBSS in which the Spectrum Management -+ bit is set to 1 in the Capability Information field in Beacon frames -+ and Probe Response frames received from the BSS or IBSS. -+ */ -+ if (prAdapter->fgEnable5GBand == TRUE) -+ u2CapInfo |= CAP_INFO_SPEC_MGT; -+ } -+#endif -+ -+ if (rNonHTPhyAttributes[u4NonHTPhyType].fgIsShortSlotTimeOptionImplemented && -+ prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable) { -+ u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; -+ } -+ } -+ -+ if (prStaRec) { -+ DBGLOG(SAA, LOUD, "ASSOC REQ: Compose Capability = 0x%04x for Target BSS [%pM].\n", -+ u2CapInfo, prStaRec->aucMacAddr); -+ } -+ -+ return u2CapInfo; -+ -+} /* end of assocBuildCapabilityInfo() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to compose Common Information Elements for Association -+* Request Frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID assocBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_STA_RECORD_T prStaRec; -+ PUINT_8 pucBuffer; -+ UINT_16 u2SupportedRateSet; -+ UINT_8 aucAllSupportedRates[RATE_NUM] = { 0 }; -+ UINT_8 ucAllSupportedRatesLen; -+ UINT_8 ucSupRatesLen; -+ UINT_8 ucExtSupRatesLen; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ ASSERT(prMsduInfo); -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return; -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (ULONG) prMsduInfo->u2FrameLength); -+ ASSERT(pucBuffer); -+ -+ if (IS_STA_IN_AIS(prStaRec)) { -+ -+ /* Fill the SSID element. */ -+ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; -+ -+ /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of -+ * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame. -+ */ -+ -+ COPY_SSID(SSID_IE(pucBuffer)->aucSSID, -+ SSID_IE(pucBuffer)->ucLength, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) -+ pucBuffer = p2pBuildReAssocReqFrameCommonIEs(prAdapter, prMsduInfo, pucBuffer); -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (IS_STA_IN_BOW(prStaRec)) { -+ -+ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; -+ -+ /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of -+ * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame. -+ */ -+ -+ COPY_SSID(SSID_IE(pucBuffer)->aucSSID, -+ SSID_IE(pucBuffer)->ucLength, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+#endif -+ else { -+ /* Do nothing */ -+ /* TODO(Kevin): For other network */ -+ } -+ -+ /* NOTE(Kevin 2008/12/19): 16.3.6.3 MLME-ASSOCIATE.indication - -+ * SupportedRates - The set of data rates that are supported by the STA -+ * that is requesting association. -+ * Original(Portable Driver): Only send the Rates that we'll support. -+ * New: Send the Phy Rates if the result of following & operation == NULL. -+ */ -+ /* rateGetDataRatesFromRateSet((prBssDesc->u2OperationalRateSet & */ -+ /* rPhyAttributes[prBssDesc->ePhyType].u2SupportedRateSet), */ -+ -+ if (prStaRec->fgHasBasicPhyType) { -+ UINT_32 u4NonHTPhyType; -+ -+ u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; -+ -+ u2SupportedRateSet = (prStaRec->u2OperationalRateSet & -+ rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet); -+ -+ ASSERT(u2SupportedRateSet); -+ -+ if (!u2SupportedRateSet) -+ u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet; -+ -+ /* TODO(Kevin): For P2P, we shouldn't send support rate set which contains 11b rate */ -+ -+ rateGetDataRatesFromRateSet(u2SupportedRateSet, 0, aucAllSupportedRates, &ucAllSupportedRatesLen); -+ -+ ucSupRatesLen = ((ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ? -+ ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen); -+ -+ ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen; -+ -+ /* Fill the Supported Rates element. */ -+ if (ucSupRatesLen) { -+ SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; -+ SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; -+ kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, aucAllSupportedRates, ucSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ -+ /* Fill the Extended Supported Rates element. */ -+ if (ucExtSupRatesLen) { -+ -+ EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; -+ EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; -+ -+ kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, -+ &aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ -+ /* 7.3.2.19 Supported Channels element */ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+ if (prAdapter->fgEnable5GBand == TRUE) { -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucId = ELEM_ID_SUP_CHS; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucLength = 8; -+ -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[0] = 36; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[1] = 4; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[2] = 52; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[3] = 4; -+/* Not China --- Start */ -+ /* SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[4] = 100; */ -+ /* SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[5] = 11; */ -+/* Not China --- End */ -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[4] = 149; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[5] = 4; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[6] = 165; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[7] = 1; -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+#endif -+ } -+ -+} /* end of assocBuildReAssocReqFrameCommonIEs() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the (Re)Association Request frame header and -+* its fixed fields -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] aucMACAddress Given Our MAC Address. -+* @param[in out] pu2PayloadLen Return the length of the composed fixed fields -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+assocComposeReAssocReqFrameHeaderAndFF(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN PUINT_8 pucBuffer, IN UINT_8 aucMACAddress[], IN OUT PUINT_16 pu2PayloadLen) -+{ -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame; -+ BOOLEAN fgIsReAssoc; -+ -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2CapInfo; -+ UINT_16 u2ListenInterval; -+ -+ ASSERT(prStaRec); -+ ASSERT(pucBuffer); -+ ASSERT(aucMACAddress); -+ ASSERT(pu2PayloadLen); -+ -+ prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) pucBuffer; -+ fgIsReAssoc = prStaRec->fgIsReAssoc; -+ -+ /* 4 <1> Compose the frame header of the (Re)Association Request frame. */ -+ /* Fill the Frame Control field. */ -+ if (fgIsReAssoc) -+ u2FrameCtrl = MAC_FRAME_REASSOC_REQ; -+ else -+ u2FrameCtrl = MAC_FRAME_ASSOC_REQ; -+ WLAN_SET_FIELD_16(&prAssocFrame->u2FrameCtrl, u2FrameCtrl); -+ -+ /* Fill the DA field with Target BSSID. */ -+ COPY_MAC_ADDR(prAssocFrame->aucDestAddr, prStaRec->aucMacAddr); -+ -+ /* Fill the SA field with our MAC Address. */ -+ COPY_MAC_ADDR(prAssocFrame->aucSrcAddr, aucMACAddress); -+ -+ /* Fill the BSSID field with Target BSSID. */ -+ COPY_MAC_ADDR(prAssocFrame->aucBSSID, prStaRec->aucMacAddr); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prAssocFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's common fixed field part of the (Re)Association Request frame. */ -+ u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec); -+ -+ /* Fill the Capability Information field. */ -+ WLAN_SET_FIELD_16(&prAssocFrame->u2CapInfo, u2CapInfo); -+ -+ /* Calculate the listen interval for the maximum power mode. Currently, we -+ set it to the value 2 times DTIM period. */ -+ if (prStaRec->ucDTIMPeriod) { -+ u2ListenInterval = prStaRec->ucDTIMPeriod * DEFAULT_LISTEN_INTERVAL_BY_DTIM_PERIOD; -+ } else { -+ DBGLOG(SAA, TRACE, "Use default listen interval\n"); -+ u2ListenInterval = DEFAULT_LISTEN_INTERVAL; -+ } -+ prStaRec->u2ListenInterval = u2ListenInterval; -+ -+ /* Fill the Listen Interval field. */ -+ WLAN_SET_FIELD_16(&prAssocFrame->u2ListenInterval, u2ListenInterval); -+ -+ /* 4 <3> Compose the Current AP Address field for ReAssociation Request frame. */ -+ /* Fill the Current AP Address field. */ -+ if (prStaRec->fgIsReAssoc) { -+ if (IS_STA_IN_AIS(prStaRec)) { -+ -+ P_AIS_BSS_INFO_T prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ P_WLAN_REASSOC_REQ_FRAME_T prReAssocFrame = (P_WLAN_REASSOC_REQ_FRAME_T) prAssocFrame; -+ -+ COPY_MAC_ADDR(prReAssocFrame->aucCurrentAPAddr, prAisBssInfo->aucBSSID); -+ } else { -+ ASSERT(0); /* We don't support ReAssociation for other network */ -+ } -+ -+ *pu2PayloadLen = (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN + CURR_AP_ADDR_FIELD_LEN); -+ } else { -+ *pu2PayloadLen = (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN); -+ } -+ -+} /* end of assocComposeReAssocReqFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the (Re)Association Request frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocSendReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ UINT_16 u2PayloadLen; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2EstimatedExtraIELen; -+ BOOLEAN fgIsReAssoc; -+ UINT_32 i; -+ -+ ASSERT(prStaRec); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ -+ fgIsReAssoc = prStaRec->fgIsReAssoc; -+ -+ /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Length */ -+ if (fgIsReAssoc) { -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ CAP_INFO_FIELD_LEN + -+ LISTEN_INTERVAL_FIELD_LEN + -+ CURR_AP_ADDR_FIELD_LEN + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)); -+ } else { -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ CAP_INFO_FIELD_LEN + -+ LISTEN_INTERVAL_FIELD_LEN + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)); -+ } -+ -+ /* + Extra IE Length */ -+ u2EstimatedExtraIELen = 0; -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 && CFG_ENABLE_WIFI_DIRECT -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ if ((prAdapter->fgIsP2PRegistered)) { -+ u2EstimatedExtraIELen = p2pCalculate_IEForAssocReq(prAdapter, -+ prStaRec->ucNetTypeIndex, prStaRec); -+ } else { -+ DBGLOG(P2P, TRACE, "Function Linker Lost.\n"); -+ ASSERT(FALSE); -+ } -+ } else { -+ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocReqIETable[i].u2EstimatedFixedIELen != 0) { -+ u2EstimatedExtraIELen += txAssocReqIETable[i].u2EstimatedFixedIELen; -+ } else { -+ u2EstimatedExtraIELen += -+ (UINT_16) txAssocReqIETable[i].pfnCalculateVariableIELen(prAdapter, -+ prStaRec->ucNetTypeIndex, -+ prStaRec); -+ } -+ } -+ } -+#else -+ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocReqIETable[i].u2EstimatedFixedIELen != 0) { -+ u2EstimatedExtraIELen += txAssocReqIETable[i].u2EstimatedFixedIELen; -+ } else { -+ u2EstimatedExtraIELen += (UINT_16) txAssocReqIETable[i].pfnCalculateVariableIELen(prAdapter, -+ prStaRec->ucNetTypeIndex, -+ prStaRec); -+ } -+ } -+#endif -+ -+ u2EstimatedFrameLen += u2EstimatedExtraIELen; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending (Re)Assoc Request.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose (Re)Association Request frame header and fixed fields in MSDU_INfO_T. */ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ /* Compose Header and Fixed Field */ -+ assocComposeReAssocReqFrameHeaderAndFF(prAdapter, -+ prStaRec, -+ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prBssInfo->aucOwnMacAddr, &u2PayloadLen); -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = saaFsmRunEventTxDone; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Compose the frame body's IEs of the (Re)Association Request frame. */ -+ assocBuildReAssocReqFrameCommonIEs(prAdapter, prMsduInfo); -+ -+ /* 4 <5> Compose IEs in MSDU_INFO_T */ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 && CFG_ENABLE_WIFI_DIRECT -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ if ((prAdapter->fgIsP2PRegistered)) { -+ p2pGenerate_IEForAssocReq(prAdapter, prMsduInfo); -+ } else { -+ DBGLOG(P2P, TRACE, "Function Linker Lost.\n"); -+ ASSERT(FALSE); -+ } -+ } else { -+ /* Append IE */ -+ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocReqIETable[i].pfnAppendIE) -+ txAssocReqIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ } -+#else -+ /* Append IE */ -+ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocReqIETable[i].pfnAppendIE) -+ txAssocReqIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+#endif -+ -+ /* 4 <6> Update the (Re)association request information */ -+ if (IS_STA_IN_AIS(prStaRec)) { -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame; -+ -+ prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+#if CFG_RSN_MIGRATION -+ kalUpdateReAssocReqInfo(prAdapter->prGlueInfo, -+ (PUINT_8) &prAssocFrame->u2CapInfo, -+ prMsduInfo->u2FrameLength - offsetof(WLAN_ASSOC_REQ_FRAME_T, u2CapInfo), -+ fgIsReAssoc); -+#endif -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame; -+ -+ prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ kalP2PUpdateAssocInfo(prAdapter->prGlueInfo, -+ (PUINT_8) &prAssocFrame->u2CapInfo, -+ prMsduInfo->u2FrameLength - offsetof(WLAN_ASSOC_REQ_FRAME_T, u2CapInfo), -+ fgIsReAssoc); -+ } -+#endif -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* 4 <6> Enqueue the frame to send this (Re)Association request frame. */ -+ DBGLOG(SAA, INFO, "Sending (Re)Assoc Request, network: %d seqNo: %d\n", -+ prMsduInfo->ucNetworkType, prMsduInfo->ucTxSeqNum); -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of assocSendReAssocReqFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will strictly check the TX (Re)Association Request frame for -+* SAA event handling. -+* -+* @param[in] prMsduInfo Pointer of MSDU_INFO_T -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocCheckTxReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2TxFrameCtrl; -+ -+ ASSERT(prMsduInfo); -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) (prMsduInfo->prPacket); -+ ASSERT(prAssocReqFrame); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ /* WLAN_GET_FIELD_16(&prAssocReqFrame->u2FrameCtrl, &u2TxFrameCtrl) */ -+ u2TxFrameCtrl = prAssocReqFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ u2TxFrameCtrl &= MASK_FRAME_TYPE; -+ if (prStaRec->fgIsReAssoc) { -+ if (u2TxFrameCtrl != MAC_FRAME_REASSOC_REQ) -+ return WLAN_STATUS_FAILURE; -+ } else { -+ if (u2TxFrameCtrl != MAC_FRAME_ASSOC_REQ) -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocCheckTxReAssocReqFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will strictly check the TX (Re)Association Response frame for -+* AAA event handling. -+* -+* @param[in] prMsduInfo Pointer of MSDU_INFO_T -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocCheckTxReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2TxFrameCtrl; -+ -+ ASSERT(prMsduInfo); -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) (prMsduInfo->prPacket); -+ ASSERT(prAssocRspFrame); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ /* WLAN_GET_FIELD_16(&prAssocFrame->u2FrameCtrl, &u2TxFrameCtrl) */ -+ u2TxFrameCtrl = prAssocRspFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ u2TxFrameCtrl &= MASK_FRAME_TYPE; -+ if (prStaRec->fgIsReAssoc) { -+ if (u2TxFrameCtrl != MAC_FRAME_REASSOC_RSP) -+ return WLAN_STATUS_FAILURE; -+ } else { -+ if (u2TxFrameCtrl != MAC_FRAME_ASSOC_RSP) -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocCheckTxReAssocRespFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the incoming (Re)Association Frame and take out -+* the status code. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu2StatusCode Pointer to store the Status Code from Authentication. -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+assocCheckRxReAssocRspFrameStatus(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; -+ UINT_16 u2RxFrameCtrl; -+ UINT_16 u2RxCapInfo; -+ UINT_16 u2RxStatusCode; -+ UINT_16 u2RxAssocId; -+ -+ ASSERT(prSwRfb); -+ ASSERT(pu2StatusCode); -+ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (CAP_INFO_FIELD_LEN + -+ STATUS_CODE_FIELD_LEN + AID_FIELD_LEN)) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ DBGLOG(SAA, LOUD, "prSwRfb->u2PayloadLength = %d\n", prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ /* 4 <1> locate the (Re)Association Resp Frame. */ -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Header of (Re)Association Resp Frame. */ -+ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2FrameCtrl, &u2RxFrameCtrl); */ -+ u2RxFrameCtrl = prAssocRspFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ u2RxFrameCtrl &= MASK_FRAME_TYPE; -+ if (prStaRec->fgIsReAssoc) { -+ if (u2RxFrameCtrl != MAC_FRAME_REASSOC_RSP) -+ return WLAN_STATUS_FAILURE; -+ } else { -+ if (u2RxFrameCtrl != MAC_FRAME_ASSOC_RSP) -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* 4 <3> Parse the Fixed Fields of (Re)Association Resp Frame Body. */ -+ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2CapInfo, &u2RxCapInfo); */ -+ u2RxCapInfo = prAssocRspFrame->u2CapInfo; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2StatusCode, &u2RxStatusCode); */ -+ u2RxStatusCode = prAssocRspFrame->u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* 4 <4> Check CAP_INFO */ -+ /* NOTE(Kevin): CM suggest to add MGMT workaround for those APs didn't check -+ * the CAP Privacy Bit to overcome a corner case that the Privacy Bit -+ * of our SCAN result didn't consist with AP's Association Resp. -+ */ -+ if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { -+#if CFG_SUPPORT_WAPI -+ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) { -+ /* WAPI AP allow the customer use WZC to join mode, the privacy bit is 0 */ -+ /* even at WAI & WAPI_PSK mode, but the assoc respose set the privacy bit set 1 */ -+ DBGLOG(SEC, TRACE, "Workaround the WAPI AP allow the customer to use WZC to join\n"); -+ } else -+#endif -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && 1) { -+ /* Todo:: Fixed this */ -+ } else -+#endif -+ { -+ } -+ -+#if CFG_STRICT_CHECK_CAPINFO_PRIVACY -+ if ((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) ^ (u2RxCapInfo & CAP_INFO_PRIVACY)) -+ u2RxStatusCode = STATUS_CODE_CAP_NOT_SUPPORTED; -+#endif -+ } -+ -+ if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { -+#if CFG_RSN_MIGRATION -+ /* Update the information in the structure used to query and set -+ OID_802_11_ASSOCIATION_INFORMATION. */ -+ kalUpdateReAssocRspInfo(prAdapter->prGlueInfo, -+ (PUINT_8) &prAssocRspFrame->u2CapInfo, (UINT_32) (prSwRfb->u2PacketLen)); -+#endif -+ } -+ /* 4 <5> Update CAP_INFO and ASSOC_ID */ -+ if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { -+ prStaRec->u2CapInfo = u2RxCapInfo; -+ -+ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2AssocId, &u2RxAssocId); */ -+ u2RxAssocId = prAssocRspFrame->u2AssocId; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* 20110715 Workaround for Kingnet 710 AP (Realtek 8186) -+ * This AP raises the bit 6&7 not bit 14&15 in AID field. -+ * It cause wrong AID assignment. -+ * For AID = 2 -+ * Normal case: 0xC002(1100 0000 0000 0010) => 2 -+ * Kingnet 710: 0x00C2(0000 0000 1100 0010) => 194 -+ * workaround: mask bit 6&7 for this AP -+ */ -+ if ((u2RxAssocId & BIT(6)) && (u2RxAssocId & BIT(7)) && !(u2RxAssocId & BITS(8, 15))) { -+ prStaRec->u2AssocId = u2RxAssocId & ~BITS(6, 7); -+ } else { -+ prStaRec->u2AssocId = u2RxAssocId & ~AID_MSB; -+#if CFG_SUPPORT_802_11W -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; -+ -+ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prBssSpecInfo); -+ -+ prBssSpecInfo->ucSaQueryTimedOut = 0; -+ } -+#endif -+ } -+ } -+#if CFG_SUPPORT_802_11W -+ if (u2RxStatusCode == STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED) { -+ DBGLOG(SAA, INFO, "AP rejected due the authentication algorithm not support\n"); -+ } else if (u2RxStatusCode == STATUS_CODE_ASSOC_REJECTED_TEMPORARILY) { -+ PUINT_8 pucIE, pucTime; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ -+ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; -+ pucIE = (PUINT_8) ((ULONG) prSwRfb->pvHeader + prSwRfb->u2HeaderLen); -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ if (ELEM_ID_TIMEOUT_INTERVAL == IE_ID(pucIE) && IE_LEN(pucIE) == 5) { -+ pucTime = ((P_IE_HDR_T) pucIE)->aucInfo; -+ if (pucTime[0] == ACTION_SA_TIMEOUT_ASSOC_COMEBACK) { -+ UINT_32 tu; -+ -+ WLAN_GET_FIELD_32(pucTime + 1, &tu); -+ DBGLOG(SAA, INFO, -+ "AP rejected association temporarily;comeback duration %u TU (%u ms)\n", -+ tu, TU_TO_MSEC(tu)); -+ if (tu > TX_ASSOCIATION_RETRY_TIMEOUT_TU) { -+ DBGLOG(SAA, INFO, "Update timer based on comeback duration\n"); -+ /* ieee80211_reschedule_timer(wpa_s, ms); */ -+ } -+ } -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ } -+#endif -+ *pu2StatusCode = u2RxStatusCode; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocCheckRxReAssocRspFrameStatus() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will compose the Disassociation frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] aucMACAddress Given Our MAC Address. -+* @param[in] u2ReasonCode The reason code of disassociation -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+assocComposeDisassocFrame(IN P_STA_RECORD_T prStaRec, -+ IN PUINT_8 pucBuffer, IN UINT_8 aucMACAddress[], IN UINT_16 u2ReasonCode) -+{ -+ P_WLAN_DISASSOC_FRAME_T prDisAssocFrame; -+ UINT_16 u2FrameCtrl; -+ -+ ASSERT(pucBuffer); -+ ASSERT(pucBuffer); -+ ASSERT(aucMACAddress); -+ -+ prDisAssocFrame = (P_WLAN_DISASSOC_FRAME_T) pucBuffer; -+ -+ /* 4 <1> Compose the frame header of the DisAssociation frame. */ -+ /* Fill the Frame Control field. */ -+ u2FrameCtrl = MAC_FRAME_DISASSOC; -+ -+ WLAN_SET_FIELD_16(&prDisAssocFrame->u2FrameCtrl, u2FrameCtrl); -+ -+ /* Fill the DA field with Target BSSID. */ -+ COPY_MAC_ADDR(prDisAssocFrame->aucDestAddr, prStaRec->aucMacAddr); -+ -+ /* Fill the SA field with our MAC Address. */ -+ COPY_MAC_ADDR(prDisAssocFrame->aucSrcAddr, aucMACAddress); -+ -+ /* Fill the BSSID field with Target BSSID. */ -+ COPY_MAC_ADDR(prDisAssocFrame->aucBSSID, prStaRec->aucMacAddr); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prDisAssocFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's fixed field part of the Disassociation frame. */ -+ /* Fill the Reason Code field. */ -+ WLAN_SET_FIELD_16(&prDisAssocFrame->u2ReasonCode, u2ReasonCode); -+ -+} /* end of assocComposeDisassocFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the Disassociation frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] u2ReasonCode The reason code of disassociation -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocSendDisAssocFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2ReasonCode) -+{ -+ PUINT_8 pucMacAddress; -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2PayloadLen; -+ UINT_16 u2EstimatedFrameLen; -+ /* UINT_32 u4Status = WLAN_STATUS_SUCCESS; */ -+ -+ ASSERT(prStaRec); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Disassociation Frame */ -+ /* Init with MGMT Header Length + Length of Fixed Fields + IE Length */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending DisAssoc.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Disassociation frame header and fixed fields in MSDU_INfO_T. */ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ pucMacAddress = prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex].aucOwnMacAddr; -+ -+ /* Compose Header and Fixed Field */ -+ assocComposeDisassocFrame(prStaRec, -+ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ pucMacAddress, u2ReasonCode); -+ -+#if CFG_SUPPORT_802_11W -+ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { -+ P_WLAN_DISASSOC_FRAME_T prDisassocFrame; -+ -+ prDisassocFrame = -+ (P_WLAN_DEAUTH_FRAME_T) (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prDisassocFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; -+ DBGLOG(TX, WARN, "assocSendDisAssocFrame with protection\n"); -+ } -+#endif -+ -+ u2PayloadLen = REASON_CODE_FIELD_LEN; -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Enqueue the frame to send this (Re)Association request frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of assocSendDisAssocFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will parse and process the incoming Disassociation frame -+* if the given BSSID is matched. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] aucBSSID Given BSSID -+* @param[out] pu2ReasonCode Pointer to store the Reason Code from Deauthentication. -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+assocProcessRxDisassocFrame(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode) -+{ -+ P_WLAN_DISASSOC_FRAME_T prDisassocFrame; -+ UINT_16 u2RxReasonCode; -+ -+ ASSERT(prSwRfb); -+ ASSERT(aucBSSID); -+ ASSERT(pu2ReasonCode); -+ -+ /* 4 <1> locate the Disassociation Frame. */ -+ prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Header of Disassociation Frame. */ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < REASON_CODE_FIELD_LEN) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* Check if this Disassoc Frame is coming from Target BSSID */ -+ if (UNEQUAL_MAC_ADDR(prDisassocFrame->aucBSSID, aucBSSID)) { -+ DBGLOG(SAA, LOUD, "Ignore Disassoc Frame from other BSS [ %pM ]\n", -+ prDisassocFrame->aucSrcAddr); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* 4 <3> Parse the Fixed Fields of Deauthentication Frame Body. */ -+ WLAN_GET_FIELD_16(&prDisassocFrame->u2ReasonCode, &u2RxReasonCode); -+ *pu2ReasonCode = u2RxReasonCode; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocProcessRxDisassocFrame() */ -+ -+#if CFG_SUPPORT_AAA -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will parse and process the incoming Association Req frame -+* and return a Status Code. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu2StatusCode Pointer to store the Status Code for carried in Association Response. -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocProcessRxAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) -+{ -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame; -+ P_STA_RECORD_T prStaRec; -+ P_BSS_INFO_T prBssInfo; -+ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; -+ P_RSN_INFO_ELEM_T prIeRsn = (P_RSN_INFO_ELEM_T) NULL; -+ P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL; -+ P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL; -+ PUINT_8 pucIE, pucIEStart; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ UINT_16 u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ UINT_16 u2RxFrameCtrl; -+ UINT_16 u2BSSBasicRateSet; -+ BOOLEAN fgIsUnknownBssBasicRate; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ ASSERT(pu2StatusCode); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prStaRec == NULL) -+ return WLAN_STATUS_FAILURE; -+ /* 4 <1> locate the Association Req Frame. */ -+ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Header of Association Req Frame. */ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN)) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ /* Check if this Disassoc Frame is coming from Target BSSID */ -+ if (UNEQUAL_MAC_ADDR(prAssocReqFrame->aucBSSID, prBssInfo->aucBSSID)) -+ return WLAN_STATUS_FAILURE; /* Just Ignore this MMPDU */ -+ /* WLAN_GET_FIELD_16(&prAssocReqFrame->u2FrameCtrl, &u2RxFrameCtrl); */ -+ u2RxFrameCtrl = prAssocReqFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ u2RxFrameCtrl &= MASK_FRAME_TYPE; -+ if (MAC_FRAME_REASSOC_REQ == u2RxFrameCtrl) { -+ prStaRec->fgIsReAssoc = TRUE; -+ -+ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (UINT_16) (OFFSET_OF(WLAN_REASSOC_REQ_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN); -+ -+ pucIEStart = pucIE = ((P_WLAN_REASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem; -+ } else { -+ prStaRec->fgIsReAssoc = FALSE; -+ -+ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (UINT_16) (OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN); -+ -+ pucIEStart = pucIE = prAssocReqFrame->aucInfoElem; -+ } -+ -+ /* 4 <3> Parse the Fixed Fields of Assoc Req Frame Body. */ -+ prStaRec->u2CapInfo = prAssocReqFrame->u2CapInfo; -+ -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK -+ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+ if (((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) && !kalP2PGetCipher(prAdapter->prGlueInfo))) { -+ u2StatusCode = STATUS_CODE_CAP_NOT_SUPPORTED; -+ DBGLOG(RSN, TRACE, "STA Assoc req privacy bit check fail\n"); -+ return WLAN_STATUS_SUCCESS; -+ } -+ } -+#endif -+ -+ prStaRec->u2ListenInterval = prAssocReqFrame->u2ListenInterval; -+ prStaRec->ucPhyTypeSet = 0; -+ -+ /* Might be legacy client or p2p gc. */ -+ prStaRec->eStaType = STA_TYPE_LEGACY_CLIENT; -+ -+ /* 4 <4> Parse the IE of Assoc Req Frame Body. */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_SSID: -+ if ((!prIeSsid) && /* NOTE(Kevin): Get SSID once */ -+ (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) { -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ } -+ break; -+ -+ case ELEM_ID_SUP_RATES: -+ if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM)) -+ prIeSupportedRate = SUP_RATES_IE(pucIE); -+ break; -+ -+ case ELEM_ID_EXTENDED_SUP_RATES: -+ if (!prIeExtSupportedRate) -+ prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); -+ break; -+ case ELEM_ID_HT_CAP: -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HT; -+ kalMemCopy(&prStaRec->u2HtCapInfo, &(HT_CAP_IE(pucIE)->u2HtCapInfo), 2); -+ break; -+ case ELEM_ID_RSN: -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK -+ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+ prIeRsn = RSN_IE(pucIE); -+ rsnParserCheckForRSNCCMPPSK(prAdapter, prIeRsn, &u2StatusCode); -+ if (u2StatusCode != STATUS_CODE_SUCCESSFUL) { -+ *pu2StatusCode = u2StatusCode; -+ return WLAN_STATUS_SUCCESS; -+ } -+ } -+#endif -+ break; -+ case ELEM_ID_VENDOR: -+#if CFG_ENABLE_WIFI_DIRECT -+ { -+ if ((prAdapter->fgIsP2PRegistered)) { -+ UINT_8 ucOuiType = 0; -+ -+ p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType); -+ -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ DBGLOG(P2P, TRACE, "Target Client is a P2P group client\n"); -+ prStaRec->eStaType = STA_TYPE_P2P_GC; -+ } -+ } -+ } -+#endif -+ break; -+ default: -+ for (i = 0; i < (sizeof(rxAssocReqIETable) / sizeof(VERIFY_IE_ENTRY_T)); i++) { -+ -+ if ((IE_ID(pucIE)) == rxAssocReqIETable[i].ucElemID) { -+ rxAssocReqIETable[i].pfnVarifyIE(prAdapter, prSwRfb, (P_IE_HDR_T) pucIE, -+ &u2StatusCode); -+ -+ if (u2StatusCode != STATUS_CODE_SUCCESSFUL) { -+ *pu2StatusCode = u2StatusCode; -+ return WLAN_STATUS_SUCCESS; -+ } -+ } -+ } -+ -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ /* parsing for WMM related information (2010/12/21) */ -+ mqmProcessAssocReq(prAdapter, prSwRfb, pucIEStart, u2IELength); -+ -+ do { -+ if (prIeSsid) { -+ if (UNEQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, -+ prIeSsid->aucSSID, prIeSsid->ucLength)) { -+ -+ u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE; -+ break; -+ } -+ } else { -+ u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE; -+ break; -+ } -+ -+ prStaRec->u2OperationalRateSet = 0; -+ prStaRec->u2BSSBasicRateSet = 0; -+ -+ if (prIeSupportedRate || prIeExtSupportedRate) { -+ rateGetRateSetFromIEs(prIeSupportedRate, prIeExtSupportedRate, &prStaRec->u2OperationalRateSet, -+ &u2BSSBasicRateSet, /* Ignore any Basic Bit */ -+ &fgIsUnknownBssBasicRate); -+ -+ if ((prBssInfo->u2BSSBasicRateSet & prStaRec->u2OperationalRateSet) != -+ prBssInfo->u2BSSBasicRateSet) { -+ -+ u2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; -+ break; -+ } -+ -+ /* Accpet the Sta, update BSSBasicRateSet from Bss */ -+ -+ prStaRec->u2BSSBasicRateSet = prBssInfo->u2BSSBasicRateSet; -+ -+ prStaRec->u2DesiredNonHTRateSet = (prStaRec->u2OperationalRateSet & RATE_SET_ALL_ABG); -+ -+ if (BAND_2G4 == HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr)) { -+#if 0 /* Marked by CMC 20111024 */ -+ /* check if support 11n */ -+ if (!(u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) { -+ -+ if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_ERP; -+ -+ if ((!(u2BSSBasicRateSet & RATE_SET_OFDM)) && -+ (prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS)) { -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS; -+ -+ } -+ -+ } -+#else -+ if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_ERP; -+ if (prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS) -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS; -+#endif -+ } else { /* (BAND_5G == prBssDesc->eBande) */ -+#if 0 /* Marked by CMC 20111024 */ -+ if (!(u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; -+ ASSERT((prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS) == 0); -+#else -+ if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; -+#endif -+ } -+ -+ } else { -+ ASSERT(0); -+ u2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; -+ break; -+ } -+ -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK -+ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+ if (prIeRsn) { -+ if (!kalP2PGetCipher(prAdapter->prGlueInfo)) { -+ u2StatusCode = STATUS_CODE_CIPHER_SUITE_REJECTED; -+ break; -+ } -+ } else { -+ prStaRec->rSecInfo.fgAllowOnly1x = FALSE; -+ if (kalP2PGetCipher(prAdapter->prGlueInfo)) { -+ /* Only Allow 1x */ -+ prStaRec->rSecInfo.fgAllowOnly1x = TRUE; -+ break; -+ } -+ } -+ } -+#endif -+ -+ } while (FALSE); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+#if 1 /* ICS */ -+ { -+ PUINT_8 cp = (PUINT_8) &prAssocReqFrame->u2CapInfo; -+ P_UINT_8 prNewAssocReqIe = NULL; -+ -+ if (u2IELength) { -+ prNewAssocReqIe = kalMemAlloc(u2IELength, VIR_MEM_TYPE); -+ if (NULL == prNewAssocReqIe) { -+ DBGLOG(AIS, WARN, "allocate memory for (Re)assocReqIe fail!\n"); -+ u2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT; -+ return WLAN_STATUS_FAILURE; -+ } -+ } -+ -+ if (prStaRec->fgIsReAssoc) -+ cp += 10; -+ else -+ cp += 4; -+ if (prStaRec->pucAssocReqIe) { -+ kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen); -+ prStaRec->pucAssocReqIe = NULL; -+ } -+ prStaRec->u2AssocReqIeLen = u2IELength; -+ if (u2IELength) { -+ prStaRec->pucAssocReqIe = prNewAssocReqIe; /* kalMemAlloc(u2IELength, VIR_MEM_TYPE); */ -+ kalMemCopy(prStaRec->pucAssocReqIe, cp, u2IELength); -+ } -+ } -+#endif -+ kalP2PUpdateAssocInfo(prAdapter->prGlueInfo, (PUINT_8) &prAssocReqFrame->u2CapInfo, -+ u2IELength + (prStaRec->fgIsReAssoc ? 10 : 4), prStaRec->fgIsReAssoc); -+ } -+#endif -+ -+ *pu2StatusCode = u2StatusCode; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocProcessRxAssocReqFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to compose Common Information Elements for Association -+* Response Frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* @param[in] prBssInfo Pointer to the BSS_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+assocBuildReAssocRespFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo) -+{ -+ PUINT_8 pucBuffer; -+ P_STA_RECORD_T prStaRec; -+ UINT_8 ucSupRatesLen; -+ UINT_8 ucExtSupRatesLen; -+ -+ ASSERT(prMsduInfo); -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ ASSERT(pucBuffer); -+ -+ if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) { -+ -+ ucSupRatesLen = ELEM_MAX_LEN_SUP_RATES; -+ ucExtSupRatesLen = prBssInfo->ucAllSupportedRatesLen - ELEM_MAX_LEN_SUP_RATES; -+ } else { -+ ucSupRatesLen = prBssInfo->ucAllSupportedRatesLen; -+ ucExtSupRatesLen = 0; -+ } -+ -+ /* Fill the Supported Rates element. */ -+ if (ucSupRatesLen) { -+ SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; -+ SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; -+ kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, prBssInfo->aucAllSupportedRates, ucSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ -+ /* Fill the Extended Supported Rates element. */ -+ if (ucExtSupRatesLen) { -+ -+ EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; -+ EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; -+ -+ kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, -+ &prBssInfo->aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ } -+ -+} /* end of assocBuildReAssocRespFrameCommonIEs() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the (Re)Association Response frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] aucBssid Given BSSID. -+* @param[in] u2CapInfo Capability Field of current BSS. -+* @param[in out] pu2PayloadLen Return the length of the composed fixed fields -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+assocComposeReAssocRespFrameHeaderAndFF(IN P_STA_RECORD_T prStaRec, -+ IN PUINT_8 pucBuffer, -+ IN UINT_8 aucBSSID[], IN UINT_16 u2CapInfo, IN OUT PUINT_16 pu2PayloadLen) -+{ -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; -+ BOOLEAN fgIsReAssoc; -+ -+ UINT_16 u2FrameCtrl; -+ -+ ASSERT(prStaRec); -+ ASSERT(pucBuffer); -+ ASSERT(aucBSSID); -+ ASSERT(pu2PayloadLen); -+ -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) pucBuffer; -+ fgIsReAssoc = prStaRec->fgIsReAssoc; -+ -+ /* 4 <1> Compose the frame header of the (Re)Association Request frame. */ -+ /* Fill the Frame Control field. */ -+ if (fgIsReAssoc) -+ u2FrameCtrl = MAC_FRAME_REASSOC_RSP; -+ else -+ u2FrameCtrl = MAC_FRAME_ASSOC_RSP; -+ /* WLAN_SET_FIELD_16(&prAssocFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prAssocRspFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the DA field with Target MAC Address. */ -+ COPY_MAC_ADDR(prAssocRspFrame->aucDestAddr, prStaRec->aucMacAddr); -+ -+ /* Fill the SA field with current BSSID. */ -+ COPY_MAC_ADDR(prAssocRspFrame->aucSrcAddr, aucBSSID); -+ -+ /* Fill the BSSID field with current BSSID. */ -+ COPY_MAC_ADDR(prAssocRspFrame->aucBSSID, aucBSSID); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prAssocRspFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's common fixed field part of the (Re)Association Request frame. */ -+ /* Fill the Capability Information field. */ -+ /* WLAN_SET_FIELD_16(&prAssocFrame->u2CapInfo, u2CapInfo); */ -+ prAssocRspFrame->u2CapInfo = u2CapInfo; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* WLAN_SET_FIELD_16(&prAssocFrame->u2StatusCode, prStaRec->u2StatusCode); */ -+ prAssocRspFrame->u2StatusCode = prStaRec->u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* WLAN_SET_FIELD_16(&prAssocFrame->u2AssocId, ((prStaRec->u2AssocId & AID_MASK) | AID_MSB)); */ -+ prAssocRspFrame->u2AssocId = ((prStaRec->u2AssocId & AID_MASK) | AID_MSB); /* NOTE(Kevin): Optimized for ARM */ -+ -+ *pu2PayloadLen = (CAP_INFO_FIELD_LEN + STATUS_CODE_FIELD_LEN + AID_FIELD_LEN); -+ -+} /* end of assocComposeReAssocRespFrameHeaderAndFF() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the (Re)Association Resp frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocSendReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ UINT_16 u2PayloadLen; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2EstimatedExtraIELen; -+ BOOLEAN fgIsReAssoc; -+ UINT_32 i; -+ -+ ASSERT(prStaRec); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ -+ fgIsReAssoc = prStaRec->fgIsReAssoc; -+ -+ /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Length */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ CAP_INFO_FIELD_LEN + -+ STATUS_CODE_FIELD_LEN + -+ AID_FIELD_LEN + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)); -+ -+ /* + Extra IE Length */ -+ u2EstimatedExtraIELen = 0; -+ -+ for (i = 0; i < sizeof(txAssocRespIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocRespIETable[i].u2EstimatedFixedIELen != 0) { -+ u2EstimatedExtraIELen += txAssocRespIETable[i].u2EstimatedFixedIELen; -+ } else if (txAssocRespIETable[i].pfnCalculateVariableIELen != NULL) { -+ u2EstimatedExtraIELen += (UINT_16) txAssocRespIETable[i].pfnCalculateVariableIELen(prAdapter, -+ prStaRec->ucNetTypeIndex, -+ prStaRec); -+ } -+ -+ } -+ -+ u2EstimatedFrameLen += u2EstimatedExtraIELen; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(AAA, WARN, "No PKT_INFO_T for sending (Re)Assoc Response.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose (Re)Association Request frame header and fixed fields in MSDU_INfO_T. */ -+ ASSERT(prStaRec->ucNetTypeIndex != NETWORK_TYPE_AIS_INDEX); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ /* Compose Header and Fixed Field */ -+ assocComposeReAssocRespFrameHeaderAndFF(prStaRec, -+ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prBssInfo->aucBSSID, prBssInfo->u2CapInfo, &u2PayloadLen); -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = aaaFsmRunEventTxDone; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Compose the frame body's IEs of the (Re)Association Request frame. */ -+ assocBuildReAssocRespFrameCommonIEs(prAdapter, prMsduInfo, prBssInfo); -+ -+ /* 4 <5> Compose IEs in MSDU_INFO_T */ -+ -+ /* Append IE */ -+ for (i = 0; i < sizeof(txAssocRespIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocRespIETable[i].pfnAppendIE) -+ txAssocRespIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* 4 <6> Enqueue the frame to send this (Re)Association request frame. */ -+ DBGLOG(SAA, INFO, "Sending (Re)Assoc Response, network: %d seqNo: %d\n", -+ prMsduInfo->ucNetworkType, prMsduInfo->ucTxSeqNum); -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocSendReAssocRespFrame() */ -+#endif /* CFG_SUPPORT_AAA */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c -new file mode 100644 -index 0000000000000..43b91d72bd431 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c -@@ -0,0 +1,1211 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/auth.c#1 -+*/ -+ -+/*! \file "auth.c" -+ \brief This file includes the authentication-related functions. -+ -+ This file includes the authentication-related functions. -+*/ -+ -+/* -+** Log: auth.c -+ * -+ * 02 13 2012 cp.wu -+ * NULL -+ * show error message only instead of raise assertion when -+ * received authentication frame is carrying illegal parameters. -+ * -+ * 11 09 2011 yuche.tsai -+ * NULL -+ * Fix a network index & station record index issue when TX deauth frame. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 06 22 2011 yuche.tsai -+ * NULL -+ * Fix coding error. -+ * -+ * 06 20 2011 yuche.tsai -+ * [WCXRP00000796] [Volunteer Patch][MT6620][Driver] Add BC deauth frame TX feature. -+ * BC deauth support. -+ * -+ * 04 21 2011 terry.wu -+ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame -+ * Add network type parameter to authSendAuthFrame. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * 1. Fix Service Disocvery Logical issue. -+ * 2. Fix a NULL pointer access violation issue when sending deauthentication packet to a class error station. -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 21 2011 terry.wu -+ * [WCXRP00000381] [MT6620 Wi-Fi][Driver] Kernel panic when replying unaccept Auth in AP mode -+ * In AP mode, use STA_REC_INDEX_NOT_FOUND(0xFE) instead of StaRec index when replying an unaccept Auth frame. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * use definition macro to replace hard-coded constant -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 28 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * send MMPDU in basic rate. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * specify correct value for management frames. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Update authSendDeauthFrame() for correct the value of eNetTypeIndex in MSDU_INFO_T -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Check Net is active before sending Deauth frame. -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Send Deauth for Class 3 Error and Leave Network Support -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Fix compile warning -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add debug message for abnormal authentication frame from AP -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * Fix the Debug Label -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 7 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update the authComposeAuthFrameHeader() -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the send deauth frame function -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Integrate send Auth with TXM -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise MGMT Handler with Retain Status -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+APPEND_IE_ENTRY_T txAuthIETable[] = { -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_CHALLENGE_TEXT), authAddIEChallengeText} -+}; -+ -+HANDLE_IE_ENTRY_T rxAuthIETable[] = { -+ {ELEM_ID_CHALLENGE_TEXT, authHandleIEChallengeText} -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the Authentication frame header and fixed fields. -+* -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] aucPeerMACAddress Given Peer MAC Address. -+* @param[in] aucMACAddress Given Our MAC Address. -+* @param[in] u2AuthAlgNum Authentication Algorithm Number -+* @param[in] u2TransactionSeqNum Transaction Sequence Number -+* @param[in] u2StatusCode Status Code -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+authComposeAuthFrameHeaderAndFF(IN PUINT_8 pucBuffer, -+ IN UINT_8 aucPeerMACAddress[], -+ IN UINT_8 aucMACAddress[], -+ IN UINT_16 u2AuthAlgNum, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ UINT_16 u2FrameCtrl; -+ -+ ASSERT(pucBuffer); -+ ASSERT(aucPeerMACAddress); -+ ASSERT(aucMACAddress); -+ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) pucBuffer; -+ -+ /* 4 <1> Compose the frame header of the Authentication frame. */ -+ /* Fill the Frame Control field. */ -+ u2FrameCtrl = MAC_FRAME_AUTH; -+ -+ /* If this frame is the third frame in the shared key authentication -+ * sequence, it shall be encrypted. -+ */ -+ if ((u2AuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3)) -+ u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; /* HW will also detect this bit for applying encryption */ -+ /* WLAN_SET_FIELD_16(&prAuthFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prAuthFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the DA field with Target BSSID. */ -+ COPY_MAC_ADDR(prAuthFrame->aucDestAddr, aucPeerMACAddress); -+ -+ /* Fill the SA field with our MAC Address. */ -+ COPY_MAC_ADDR(prAuthFrame->aucSrcAddr, aucMACAddress); -+ -+ switch (u2TransactionSeqNum) { -+ case AUTH_TRANSACTION_SEQ_1: -+ case AUTH_TRANSACTION_SEQ_3: -+ -+ /* Fill the BSSID field with Target BSSID. */ -+ COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucPeerMACAddress); -+ break; -+ -+ case AUTH_TRANSACTION_SEQ_2: -+ case AUTH_TRANSACTION_SEQ_4: -+ -+ /* Fill the BSSID field with Current BSSID. */ -+ COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucMACAddress); -+ break; -+ -+ default: -+ ASSERT(0); -+ } -+ -+ /* Clear the SEQ/FRAG_NO field. */ -+ prAuthFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's fixed field part of the Authentication frame. */ -+ /* Fill the Authentication Algorithm Number field. */ -+ /* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthAlgNum, u2AuthAlgNum); */ -+ prAuthFrame->u2AuthAlgNum = u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the Authentication Transaction Sequence Number field. */ -+ /* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, u2TransactionSeqNum); */ -+ prAuthFrame->u2AuthTransSeqNo = u2TransactionSeqNum; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the Status Code field. */ -+ /* WLAN_SET_FIELD_16(&prAuthFrame->u2StatusCode, u2StatusCode); */ -+ prAuthFrame->u2StatusCode = u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ -+ -+} /* end of authComposeAuthFrameHeaderAndFF() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will append Challenge Text IE to the Authentication frame -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID authAddIEChallengeText(IN P_ADAPTER_T prAdapter, IN OUT P_MSDU_INFO_T prMsduInfo) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2TransactionSeqNum; -+ -+ ASSERT(prMsduInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (!prStaRec) -+ return; -+ -+ ASSERT(prStaRec); -+ -+ /* For Management, frame header and payload are in a continuous buffer */ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prMsduInfo->prPacket; -+ -+ WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum) -+ -+ /* Only consider SEQ_3 for Challenge Text */ -+ if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3) && -+ (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (prStaRec->prChallengeText != NULL)) { -+ -+ COPY_IE(((ULONG) (prMsduInfo->prPacket) + prMsduInfo->u2FrameLength), (prStaRec->prChallengeText)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prStaRec->prChallengeText); -+ } -+ -+ return; -+ -+} /* end of authAddIEChallengeText() */ -+ -+#if !CFG_SUPPORT_AAA -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the Authenticiation frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] u2TransactionSeqNum Transaction Sequence Number -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS authSendAuthFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2TransactionSeqNum) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ P_BSS_INFO_T prBssInfo; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2EstimatedExtraIELen; -+ UINT_16 u2PayloadLen; -+ UINT_32 i; -+ -+ DBGLOG(SAA, LOUD, "Send Auth Frame\n"); -+ -+ ASSERT(prStaRec); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ -+ /* Init with MGMT Header Length + Length of Fixed Fields */ -+ u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ AUTH_ALGORITHM_NUM_FIELD_LEN + -+ AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); -+ -+ /* + Extra IE Length */ -+ u2EstimatedExtraIELen = 0; -+ -+ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) -+ u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen; -+ -+ u2EstimatedFrameLen += u2EstimatedExtraIELen; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ /* Compose Header and some Fixed Fields */ -+ authComposeAuthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prStaRec->aucMacAddr, -+ prBssInfo->aucOwnMacAddr, -+ prStaRec->ucAuthAlgNum, u2TransactionSeqNum, STATUS_CODE_RESERVED); -+ -+ u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = saaFsmRunEventTxDone; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Compose IEs in MSDU_INFO_T */ -+ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) { -+ if (txAuthIETable[i].pfnAppendIE) -+ txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* 4 <6> Inform TXM to send this Authentication frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of authSendAuthFrame() */ -+ -+#else -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the Authenticiation frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] u2TransactionSeqNum Transaction Sequence Number -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+authSendAuthFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN P_SW_RFB_T prFalseAuthSwRfb, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode) -+{ -+ PUINT_8 pucReceiveAddr; -+ PUINT_8 pucTransmitAddr; -+ P_MSDU_INFO_T prMsduInfo; -+ P_BSS_INFO_T prBssInfo; -+ /*get from input parameter */ -+ /* ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; */ -+ PFN_TX_DONE_HANDLER pfTxDoneHandler = (PFN_TX_DONE_HANDLER) NULL; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2EstimatedExtraIELen; -+ UINT_16 u2PayloadLen; -+ UINT_16 ucAuthAlgNum; -+ UINT_32 i; -+ -+ DBGLOG(SAA, LOUD, "Send Auth Frame %d, Status Code = %d\n", u2TransactionSeqNum, u2StatusCode); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ -+ /* Init with MGMT Header Length + Length of Fixed Fields */ -+ u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ AUTH_ALGORITHM_NUM_FIELD_LEN + -+ AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); -+ -+ /* + Extra IE Length */ -+ u2EstimatedExtraIELen = 0; -+ -+ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) -+ u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen; -+ -+ u2EstimatedFrameLen += u2EstimatedExtraIELen; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */ -+ if (prStaRec) { -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ pucTransmitAddr = prBssInfo->aucOwnMacAddr; -+ -+ pucReceiveAddr = prStaRec->aucMacAddr; -+ -+ ucAuthAlgNum = prStaRec->ucAuthAlgNum; -+ -+ switch (u2TransactionSeqNum) { -+ case AUTH_TRANSACTION_SEQ_1: -+ case AUTH_TRANSACTION_SEQ_3: -+ pfTxDoneHandler = saaFsmRunEventTxDone; -+ break; -+ -+ case AUTH_TRANSACTION_SEQ_2: -+ case AUTH_TRANSACTION_SEQ_4: -+ pfTxDoneHandler = aaaFsmRunEventTxDone; -+ break; -+ } -+ -+ } else { /* For Error Status Code */ -+ P_WLAN_AUTH_FRAME_T prFalseAuthFrame; -+ -+ ASSERT(prFalseAuthSwRfb); -+ prFalseAuthFrame = (P_WLAN_AUTH_FRAME_T) prFalseAuthSwRfb->pvHeader; -+ -+ ASSERT(u2StatusCode != STATUS_CODE_SUCCESSFUL); -+ -+ pucTransmitAddr = prFalseAuthFrame->aucDestAddr; -+ -+ pucReceiveAddr = prFalseAuthFrame->aucSrcAddr; -+ -+ ucAuthAlgNum = prFalseAuthFrame->u2AuthAlgNum; -+ -+ u2TransactionSeqNum = (prFalseAuthFrame->u2AuthTransSeqNo + 1); -+ } -+ -+ /* Compose Header and some Fixed Fields */ -+ authComposeAuthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ pucReceiveAddr, -+ pucTransmitAddr, ucAuthAlgNum, u2TransactionSeqNum, u2StatusCode); -+ -+ u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ if (prStaRec) -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ else -+ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; /* false Auth frame */ -+ prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Compose IEs in MSDU_INFO_T */ -+ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) { -+ if (txAuthIETable[i].pfnAppendIE) -+ txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* 4 <6> Inform TXM to send this Authentication frame. */ -+ DBGLOG(SAA, INFO, "network: %d Send Auth Frame %d, Status Code = %d seq num %d\n", -+ eNetTypeIndex, u2TransactionSeqNum, u2StatusCode, prMsduInfo->ucTxSeqNum); -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of authSendAuthFrame() */ -+ -+#endif /* CFG_SUPPORT_AAA */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will strictly check the TX Authentication frame for SAA/AAA event -+* handling. -+* -+* @param[in] prMsduInfo Pointer of MSDU_INFO_T -+* @param[in] u2TransactionSeqNum Transaction Sequence Number -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS authCheckTxAuthFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN UINT_16 u2TransactionSeqNum) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2TxFrameCtrl; -+ UINT_16 u2TxAuthAlgNum; -+ UINT_16 u2TxTransactionSeqNum; -+ -+ ASSERT(prMsduInfo); -+ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) (prMsduInfo->prPacket); -+ ASSERT(prAuthFrame); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2FrameCtrl, &u2TxFrameCtrl) */ -+ u2TxFrameCtrl = prAuthFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ u2TxFrameCtrl &= MASK_FRAME_TYPE; -+ if (u2TxFrameCtrl != MAC_FRAME_AUTH) -+ return WLAN_STATUS_FAILURE; -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2TxAuthAlgNum) */ -+ u2TxAuthAlgNum = prAuthFrame->u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */ -+ if (u2TxAuthAlgNum != (UINT_16) (prStaRec->ucAuthAlgNum)) -+ return WLAN_STATUS_FAILURE; -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TxTransactionSeqNum) */ -+ u2TxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ -+ if (u2TxTransactionSeqNum != u2TransactionSeqNum) -+ return WLAN_STATUS_FAILURE; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authCheckTxAuthFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will check the incoming Auth Frame's Transaction Sequence -+* Number before delivering it to the corresponding SAA or AAA Module. -+* -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always not retain authentication frames -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS authCheckRxAuthFrameTransSeq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ UINT_16 u2RxTransactionSeqNum; -+ -+ ASSERT(prSwRfb); -+ -+ /* 4 <1> locate the Authentication Frame. */ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Header of Authentication Frame. */ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (AUTH_ALGORITHM_NUM_FIELD_LEN + -+ AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + -+ STATUS_CODE_FIELD_LEN)) { -+ ASSERT(0); -+ return WLAN_STATUS_SUCCESS; -+ } -+ /* 4 <3> Parse the Fixed Fields of Authentication Frame Body. */ -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum); */ -+ u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ -+ -+ switch (u2RxTransactionSeqNum) { -+ case AUTH_TRANSACTION_SEQ_2: -+ case AUTH_TRANSACTION_SEQ_4: -+ saaFsmRunEventRxAuth(prAdapter, prSwRfb); -+ break; -+ -+ case AUTH_TRANSACTION_SEQ_1: -+ case AUTH_TRANSACTION_SEQ_3: -+#if CFG_SUPPORT_AAA -+ aaaFsmRunEventRxAuth(prAdapter, prSwRfb); -+#endif /* CFG_SUPPORT_AAA */ -+ break; -+ -+ default: -+ DBGLOG(SAA, WARN, "Strange Authentication Packet: Auth Trans Seq No = %d, Error Status Code = %d\n", -+ u2RxTransactionSeqNum, prAuthFrame->u2StatusCode); -+ break; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authCheckRxAuthFrameTransSeq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the incoming Authentication Frame and take -+* the status code out. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] u2TransactionSeqNum Transaction Sequence Number -+* @param[out] pu2StatusCode Pointer to store the Status Code from Authentication. -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+authCheckRxAuthFrameStatus(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN UINT_16 u2TransactionSeqNum, OUT PUINT_16 pu2StatusCode) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ UINT_16 u2RxAuthAlgNum; -+ UINT_16 u2RxTransactionSeqNum; -+ /* UINT_16 u2RxStatusCode; // NOTE(Kevin): Optimized for ARM */ -+ -+ ASSERT(prSwRfb); -+ ASSERT(pu2StatusCode); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ /* 4 <1> locate the Authentication Frame. */ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Fixed Fields of Authentication Frame Body. */ -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2RxAuthAlgNum); */ -+ u2RxAuthAlgNum = prAuthFrame->u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */ -+ if (u2RxAuthAlgNum != (UINT_16) prStaRec->ucAuthAlgNum) { -+ DBGLOG(SAA, WARN, "Discard Auth frame with auth type = %d, current = %d\n", -+ u2RxAuthAlgNum, prStaRec->ucAuthAlgNum); -+ *pu2StatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED; -+ return WLAN_STATUS_SUCCESS; -+ } -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum); */ -+ u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ -+ if (u2RxTransactionSeqNum != u2TransactionSeqNum) { -+ DBGLOG(SAA, WARN, "Discard Auth frame with Transaction Seq No = %d\n", u2RxTransactionSeqNum); -+ *pu2StatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ; -+ return WLAN_STATUS_SUCCESS; -+ } -+ /* 4 <3> Get the Status code */ -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2StatusCode, &u2RxStatusCode); */ -+ /* *pu2StatusCode = u2RxStatusCode; */ -+ *pu2StatusCode = prAuthFrame->u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authCheckRxAuthFrameStatus() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Challenge Text IE from the Authentication frame -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] prIEHdr Pointer to start address of IE -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID authHandleIEChallengeText(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, P_IE_HDR_T prIEHdr) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2TransactionSeqNum; -+ -+ ASSERT(prSwRfb); -+ ASSERT(prIEHdr); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return; -+ -+ /* For Management, frame header and payload are in a continuous buffer */ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum) */ -+ u2TransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Only consider SEQ_2 for Challenge Text */ -+ if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_2) && -+ (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY)) { -+ -+ /* Free previous allocated TCM memory */ -+ if (prStaRec->prChallengeText) { -+ ASSERT(0); -+ cnmMemFree(prAdapter, prStaRec->prChallengeText); -+ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; -+ } -+ -+ prStaRec->prChallengeText = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, IE_SIZE(prIEHdr)); -+ if (prStaRec->prChallengeText == NULL) -+ return; -+ -+ /* Save the Challenge Text from Auth Seq 2 Frame, before sending Auth Seq 3 Frame */ -+ COPY_IE(prStaRec->prChallengeText, prIEHdr); -+ } -+ -+ return; -+ -+} /* end of authAddIEChallengeText() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will parse and process the incoming Authentication frame. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS authProcessRxAuth2_Auth4Frame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ PUINT_8 pucIEsBuffer; -+ UINT_16 u2IEsLen; -+ UINT_16 u2Offset; -+ UINT_8 ucIEID; -+ UINT_32 i; -+ -+ ASSERT(prSwRfb); -+ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ pucIEsBuffer = &prAuthFrame->aucInfoElem[0]; -+ u2IEsLen = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); -+ -+ IE_FOR_EACH(pucIEsBuffer, u2IEsLen, u2Offset) { -+ ucIEID = IE_ID(pucIEsBuffer); -+ -+ for (i = 0; i < (sizeof(rxAuthIETable) / sizeof(HANDLE_IE_ENTRY_T)); i++) { -+ -+ if (ucIEID == rxAuthIETable[i].ucElemID) -+ rxAuthIETable[i].pfnHandleIE(prAdapter, prSwRfb, (P_IE_HDR_T) pucIEsBuffer); -+ } -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authProcessRxAuth2_Auth4Frame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the Deauthentication frame -+* -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] aucPeerMACAddress Given Peer MAC Address. -+* @param[in] aucMACAddress Given Our MAC Address. -+* @param[in] u2StatusCode Status Code -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+authComposeDeauthFrameHeaderAndFF(IN PUINT_8 pucBuffer, -+ IN UINT_8 aucPeerMACAddress[], -+ IN UINT_8 aucMACAddress[], IN UINT_8 aucBssid[], IN UINT_16 u2ReasonCode) -+{ -+ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; -+ UINT_16 u2FrameCtrl; -+ -+ ASSERT(pucBuffer); -+ ASSERT(aucPeerMACAddress); -+ ASSERT(aucMACAddress); -+ ASSERT(aucBssid); -+ -+ prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) pucBuffer; -+ -+ /* 4 <1> Compose the frame header of the Deauthentication frame. */ -+ /* Fill the Frame Control field. */ -+ u2FrameCtrl = MAC_FRAME_DEAUTH; -+ -+ /* WLAN_SET_FIELD_16(&prDeauthFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prDeauthFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the DA field with Target BSSID. */ -+ COPY_MAC_ADDR(prDeauthFrame->aucDestAddr, aucPeerMACAddress); -+ -+ /* Fill the SA field with our MAC Address. */ -+ COPY_MAC_ADDR(prDeauthFrame->aucSrcAddr, aucMACAddress); -+ -+ /* Fill the BSSID field with Target BSSID. */ -+ COPY_MAC_ADDR(prDeauthFrame->aucBSSID, aucBssid); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prDeauthFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's fixed field part of the Authentication frame. */ -+ /* Fill the Status Code field. */ -+ /* WLAN_SET_FIELD_16(&prDeauthFrame->u2ReasonCode, u2ReasonCode); */ -+ prDeauthFrame->u2ReasonCode = u2ReasonCode; /* NOTE(Kevin): Optimized for ARM */ -+ -+} /* end of authComposeDeauthFrameHeaderAndFF() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the Deauthenticiation frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] prClassErrSwRfb Pointer to the SW_RFB_T which is Class Error. -+* @param[in] u2ReasonCode A reason code to indicate why to leave BSS. -+* @param[in] pfTxDoneHandler TX Done call back function -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+* @retval WLAN_STATUS_FAILURE Didn't send Deauth frame for various reasons. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+authSendDeauthFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN P_SW_RFB_T prClassErrSwRfb, IN UINT_16 u2ReasonCode, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) -+{ -+ P_WLAN_MAC_HEADER_A4_T prWlanMacHeader = NULL; -+ PUINT_8 pucReceiveAddr; -+ PUINT_8 pucTransmitAddr; -+ PUINT_8 pucBssid = NULL; -+ -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2RxFrameCtrl; -+ P_BSS_INFO_T prBssInfo; -+ -+ P_DEAUTH_INFO_T prDeauthInfo; -+ OS_SYSTIME rCurrentTime; -+ INT_32 i4NewEntryIndex, i; -+ UINT_8 ucStaRecIdx = STA_REC_INDEX_NOT_FOUND; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ UINT_8 aucBMC[] = BC_MAC_ADDR; -+#endif -+ -+ /* NOTE(Kevin): The best way to reply the Deauth is according to the incoming data -+ * frame -+ */ -+ /* 4 <1> Find the Receiver Address first. */ -+ if (prClassErrSwRfb) { -+ BOOLEAN fgIsAbleToSendDeauth = FALSE; -+ -+ prWlanMacHeader = (P_WLAN_MAC_HEADER_A4_T) prClassErrSwRfb->pvHeader; -+ -+ /* WLAN_GET_FIELD_16(&prWlanMacHeader->u2FrameCtrl, &u2RxFrameCtrl); */ -+ u2RxFrameCtrl = prWlanMacHeader->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* TODO(Kevin): Currently we won't send Deauth for IBSS node. How about DLS ? */ -+ if ((prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) == 0) -+ return WLAN_STATUS_FAILURE; -+ -+ /* Check if corresponding BSS is able to send Deauth */ -+ for (i = NETWORK_TYPE_AIS_INDEX; i < NETWORK_TYPE_INDEX_NUM; i++) { -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[i]); -+ -+ if (IS_NET_ACTIVE(prAdapter, i) && -+ (EQUAL_MAC_ADDR(prWlanMacHeader->aucAddr1, prBssInfo->aucOwnMacAddr))) { -+ { -+ fgIsAbleToSendDeauth = TRUE; -+ eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) i; -+ break; -+ } -+ } -+ } -+ -+ if (!fgIsAbleToSendDeauth) -+ return WLAN_STATUS_FAILURE; -+ -+ pucReceiveAddr = prWlanMacHeader->aucAddr2; -+ -+ } else if (prStaRec) { -+ -+ pucReceiveAddr = prStaRec->aucMacAddr; -+ } else { -+#if CFG_ENABLE_WIFI_DIRECT -+ pucReceiveAddr = aucBMC; -+#else -+ return WLAN_STATUS_FAILURE; -+#endif -+ } -+ -+ /* 4 <2> Check if already send a Deauth frame in MIN_DEAUTH_INTERVAL_MSEC */ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ -+ i4NewEntryIndex = -1; -+ for (i = 0; i < MAX_DEAUTH_INFO_COUNT; i++) { -+ prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i]); -+ -+ /* For continuously sending Deauth frame, the minimum interval is -+ * MIN_DEAUTH_INTERVAL_MSEC. -+ */ -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, -+ prDeauthInfo->rLastSendTime, MSEC_TO_SYSTIME(MIN_DEAUTH_INTERVAL_MSEC))) { -+ -+ i4NewEntryIndex = i; -+ } else if (EQUAL_MAC_ADDR(pucReceiveAddr, prDeauthInfo->aucRxAddr) && (!pfTxDoneHandler)) { -+ -+ return WLAN_STATUS_FAILURE; -+ } -+ } -+ -+ /* 4 <3> Update information. */ -+ if (i4NewEntryIndex > 0) { -+ -+ prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i4NewEntryIndex]); -+ -+ COPY_MAC_ADDR(prDeauthInfo->aucRxAddr, pucReceiveAddr); -+ prDeauthInfo->rLastSendTime = rCurrentTime; -+ } else { -+ /* NOTE(Kevin): for the case of AP mode, we may encounter this case -+ * if deauth all the associated clients. -+ */ -+ DBGLOG(SAA, WARN, "No unused DEAUTH_INFO_T !\n"); -+ } -+ -+ /* 4 <4> Allocate a PKT_INFO_T for Deauthentication Frame */ -+ /* Init with MGMT Header Length + Length of Fixed Fields + IE Length */ -+ u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN); -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Deauth Request.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <5> Find the Transmitter Address and BSSID. */ -+ if (prClassErrSwRfb) { -+ -+ /* The TA of Deauth is the A1 of RX frame */ -+ pucTransmitAddr = prWlanMacHeader->aucAddr1; -+ -+ switch (prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) { -+ -+ case MASK_FC_FROM_DS: -+ /* The BSSID of Deauth is the A2 of RX frame */ -+ pucBssid = prWlanMacHeader->aucAddr2; -+ break; -+ -+ case MASK_FC_TO_DS: -+ /* The BSSID of Deauth is the A1 of RX frame */ -+ pucBssid = prWlanMacHeader->aucAddr1; -+ break; -+ -+ case MASK_TO_DS_FROM_DS: -+ /* TODO(Kevin): Consider BOW, now we set the BSSID of Deauth -+ * to the A2 of RX frame for temporary solution. -+ */ -+ pucBssid = prWlanMacHeader->aucAddr2; -+ break; -+ -+ /* No Default */ -+ } -+ -+ } else if (prStaRec) { -+ eNetTypeIndex = prStaRec->ucNetTypeIndex; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ pucTransmitAddr = prBssInfo->aucOwnMacAddr; -+ -+ pucBssid = prBssInfo->aucBSSID; -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else { -+ if (prAdapter->fgIsP2PRegistered) { -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ ucStaRecIdx = STA_REC_INDEX_BMCAST; -+ -+ pucTransmitAddr = prBssInfo->aucOwnMacAddr; -+ -+ pucBssid = prBssInfo->aucBSSID; -+ -+ eNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ } else { -+ /* 20130122: free packet by samplin */ -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ return WLAN_STATUS_FAILURE; -+ } -+ } -+ -+#endif -+ -+ /* 4 <6> compose Deauthentication frame header and some fixed fields */ -+ authComposeDeauthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ pucReceiveAddr, pucTransmitAddr, pucBssid, u2ReasonCode); -+ -+#if CFG_SUPPORT_802_11W -+ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { -+ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; -+ -+ prDeauthFrame = -+ (P_WLAN_DEAUTH_FRAME_T) (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prDeauthFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; -+ DBGLOG(TX, WARN, "authSendDeauthFrame with protection\n"); -+ } -+#endif -+ -+ /* 4 <7> Update information of MSDU_INFO_T */ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = ((prStaRec == NULL) ? ucStaRecIdx : prStaRec->ucIndex); -+ prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ DBGLOG(SAA, INFO, "Sending Deauth, network: %d, seqNo %d\n", -+ eNetTypeIndex, prMsduInfo->ucTxSeqNum); -+ -+ /* 4 <8> Inform TXM to send this Deauthentication frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of authSendDeauthFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will parse and process the incoming Deauthentication frame -+* if the given BSSID is matched. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] aucBSSID Given BSSID -+* @param[out] pu2ReasonCode Pointer to store the Reason Code from Deauthentication. -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS authProcessRxDeauthFrame(IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode) -+{ -+ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; -+ UINT_16 u2RxReasonCode; -+ -+ ASSERT(prSwRfb); -+ ASSERT(aucBSSID); -+ ASSERT(pu2ReasonCode); -+ -+ /* 4 <1> locate the Deauthentication Frame. */ -+ prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Header of Deauthentication Frame. */ -+#if 0 /* Kevin: Seems redundant */ -+ WLAN_GET_FIELD_16(&prDeauthFrame->u2FrameCtrl, &u2RxFrameCtrl) -+ u2RxFrameCtrl &= MASK_FRAME_TYPE; -+ if (u2RxFrameCtrl != MAC_FRAME_DEAUTH) -+ return WLAN_STATUS_FAILURE; -+#endif -+ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < REASON_CODE_FIELD_LEN) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* Check if this Deauth Frame is coming from Target BSSID */ -+ if (UNEQUAL_MAC_ADDR(prDeauthFrame->aucBSSID, aucBSSID)) { -+ DBGLOG(SAA, LOUD, "Ignore Deauth Frame from other BSS [ %pM ]\n", -+ prDeauthFrame->aucSrcAddr); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* 4 <3> Parse the Fixed Fields of Deauthentication Frame Body. */ -+ WLAN_GET_FIELD_16(&prDeauthFrame->u2ReasonCode, &u2RxReasonCode); -+ *pu2ReasonCode = u2RxReasonCode; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authProcessRxDeauthFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will parse and process the incoming Authentication frame. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] aucExpectedBSSID Given Expected BSSID. -+* @param[in] u2ExpectedAuthAlgNum Given Expected Authentication Algorithm Number -+* @param[in] u2ExpectedTransSeqNum Given Expected Transaction Sequence Number. -+* @param[out] pu2ReturnStatusCode Return Status Code. -+* -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+* @retval WLAN_STATUS_FAILURE The frame we will ignore. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+authProcessRxAuth1Frame(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, -+ IN UINT_8 aucExpectedBSSID[], -+ IN UINT_16 u2ExpectedAuthAlgNum, -+ IN UINT_16 u2ExpectedTransSeqNum, OUT PUINT_16 pu2ReturnStatusCode) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ UINT_16 u2ReturnStatusCode = STATUS_CODE_SUCCESSFUL; -+ -+ ASSERT(prSwRfb); -+ ASSERT(aucExpectedBSSID); -+ ASSERT(pu2ReturnStatusCode); -+ -+ /* 4 <1> locate the Authentication Frame. */ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Check the BSSID */ -+ if (UNEQUAL_MAC_ADDR(prAuthFrame->aucBSSID, aucExpectedBSSID)) -+ return WLAN_STATUS_FAILURE; /* Just Ignore this MMPDU */ -+ /* 4 <3> Check the SA, which should not be MC/BC */ -+ if (prAuthFrame->aucSrcAddr[0] & BIT(0)) { -+ DBGLOG(P2P, WARN, "Invalid STA MAC with MC/BC bit set: %pM\n", -+ prAuthFrame->aucSrcAddr); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* 4 <4> Parse the Fixed Fields of Authentication Frame Body. */ -+ if (prAuthFrame->u2AuthAlgNum != u2ExpectedAuthAlgNum) -+ u2ReturnStatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED; -+ -+ if (prAuthFrame->u2AuthTransSeqNo != u2ExpectedTransSeqNum) -+ u2ReturnStatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ; -+ -+ *pu2ReturnStatusCode = u2ReturnStatusCode; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authProcessRxAuth1Frame() */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c -new file mode 100644 -index 0000000000000..160779583655f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c -@@ -0,0 +1,2521 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/bss.c#3 -+*/ -+ -+/*! \file "bss.c" -+ \brief This file contains the functions for creating BSS(AP)/IBSS(AdHoc). -+ -+ This file contains the functions for BSS(AP)/IBSS(AdHoc). We may create a BSS/IBSS -+ network, or merge with exist IBSS network and sending Beacon Frame or reply -+ the Probe Response Frame for received Probe Request Frame. -+*/ -+ -+/* -+** Log: bss.c -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+** -+** 08 30 2012 chinglan.wang -+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only -+** . -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 14 2012 chinglan.wang -+ * NULL -+ * Fix the losing of the HT IE in assoc request.. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 03 08 2012 yuche.tsai -+ * NULL -+ * Fix FW assert when start Hot-Spot. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 01 20 2012 chinglan.wang -+ * 03 02 2012 terry.wu -+ * NULL -+ * Fix the WPA-PSK TKIP and WPA2-PSK AES security mode bug. -+ * -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 15 2012 yuche.tsai -+ * NULL -+ * Fix wrong basic rate issue. -+ * -+ * 01 13 2012 yuche.tsai -+ * NULL -+ * WiFi Hot Spot Tethering for ICS ALPHA testing version. -+ * -+ * 11 03 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * Always set short slot time to TRUE initially in AP mode -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG -+ * -+ * 09 14 2011 yuche.tsai -+ * NULL -+ * Add P2P IE in assoc response. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 03 29 2011 eddie.chen -+ * [WCXRP00000608] [MT6620 Wi-Fi][DRV] Change wmm parameters in beacon -+ * Change wmm parameters in beacon. -+ * -+ * 03 29 2011 yuche.tsai -+ * [WCXRP00000607] [Volunteer Patch][MT6620][Driver] Coding Style Fix for klocwork scan. -+ * Fix klocwork issue. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Make assoc req to append P2P IE if wifi direct is enabled. -+ * -+ * 03 11 2011 chinglan.wang -+ * [WCXRP00000537] [MT6620 Wi-Fi][Driver] Can not connect to 802.11b/g/n mixed AP with WEP security. -+ * . -+ * -+ * 03 03 2011 george.huang -+ * [WCXRP00000508] [MT6620 Wi-Fi][Driver] aware of beacon MSDU will be free, after BSS deactivated -+ * . -+ * -+ * 03 03 2011 george.huang -+ * [WCXRP00000508] [MT6620 Wi-Fi][Driver] aware of beacon MSDU will be free, after BSS deactivated -+ * modify to handle if beacon MSDU been released when BSS deactivated -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add code to let the beacon and probe response for Auto GO WSC . -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * Add code to send beacon and probe response WSC IE at Auto GO. -+ * -+ * 02 17 2011 eddie.chen -+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel -+ * 1) Change GetFrameAction decision when BSS is absent. -+ * 2) Check channel and resource in processing ProbeRequest -+ * -+ * 02 12 2011 yuche.tsai -+ * [WCXRP00000441] [Volunteer Patch][MT6620][Driver] BoW can not create desired station type when Hot Spot is enabled. -+ * bss should create station record type according to callers input. -+ * -+ * 02 11 2011 terry.wu -+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules -+ * In p2p link function, check networktype before calling p2p function. -+ * -+ * 02 11 2011 terry.wu -+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules -+ * Modify p2p link function to avoid assert. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 25 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Fix the compile error in windows. -+ * -+ * 01 24 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Add destination decision in AP mode. -+ * -+ * 01 24 2011 terry.wu -+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules -+ * .Fix typo and missing entry -+ * -+ * 12 30 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Fix prBssInfo->aucCWminLog to prBssInfo->aucCWminLogForBcast -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Add WMM parameter for broadcast. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 11 29 2010 cp.wu -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC -+ * for initial TX rate selection of auto-rate algorithm -+ * update ucRcpi of STA_RECORD_T for AIS when -+ * 1) Beacons for IBSS merge is received -+ * 2) Associate Response for a connecting peer is received -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * use definition macro to replace hard-coded constant -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * update the frog's new p2p state machine. -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Change conditional compiling options for BOW -+ * -+ * 09 10 2010 cm.chang -+ * NULL -+ * Always update Beacon content if FW sync OBSS info -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Finish SLT TX/RX & Rate Changing Support. -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Before composing Beacon IE, assign network type index for msdu info, -+ * this information is needed by RLM module while composing some RLM related IE field. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Fix undefined pucDestAddr in bssUpdateBeaconContent() -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 11 2010 cp.wu -+ * NULL -+ * 1) do not use in-stack variable for beacon updating. (for MAUI porting) -+ * 2) extending scanning result to 64 instead of 48 -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 08 02 2010 george.huang -+ * NULL -+ * add WMM-PS test related OID/ CMD handlers -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add support to RX probe response for P2P. -+ * -+ * 07 20 2010 cp.wu -+ * -+ * 1) bugfix: do not stop timer for join after switched into normal_tr state, for providing chance for DHCP handshasking -+ * 2) modify rsnPerformPolicySelection() invoking -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * when IBSS is being merged-in, send command packet to PM for connected indication -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 06 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Update arguments for nicUpdateBeaconIETemplate() -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 28 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * send MMPDU in basic rate. -+ * -+ * 06 25 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Create beacon update path, with expose bssUpdateBeaconContent() -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix compile error while enable WIFI_DIRECT support. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable RX management frame handling. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * specify correct value for management frames. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * correct when ADHOC support is turned on. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan.c. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * fix compilation error when WIFI_DIRECT is turned on -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add bss.c. -+ * -+ * 06 04 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * [PM] Support U-APSD for STA mode -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Update bssProcessProbeRequest() to avoid redundant SSID IE {0,0} for IOT. -+ * -+ * 05 21 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set -+ * -+ * 05 18 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Ad-hoc Beacon should not carry HT OP and OBSS IEs -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Use TX MGMT Frame API for sending PS NULL frame to avoid the TX Burst Mechanism in TX FW Frame API -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Separate Beacon and ProbeResp IE array -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 28 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed the use of compiling flag MQM_WMM_PARSING -+ * -+ * 04 27 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 04 20 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Fix restart Beacon Timeout Func after connection diagnosis -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support and will send Null frame to diagnose connection -+ * -+ * 04 16 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * adding the wpa-none for ibss beacon. -+ * -+ * 04 15 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the protected bit at cap info for ad-hoc. -+ * -+ * 03 18 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Rename the CFG flags -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Update outgoing beacon's TX data rate -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add DTIM count update while TX Beacon -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Modify code due to define - BAND_24G and specific BSS_INFO_T was changed -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Revise data structure to share the same BSS_INFO_T for avoiding coding error -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) -+APPEND_VAR_IE_ENTRY_T txBcnIETable[] = { -+ {(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE}, /* 50 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE}, /* 42 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE}, /* 45 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE}, /* 61 */ -+#if CFG_ENABLE_WIFI_DIRECT -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE}, /* 74 */ -+#endif -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE}, /* 127 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE}, /* 221 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE}, /* 221 */ -+#if CFG_ENABLE_WIFI_DIRECT -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWPAIE}, /* 221 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE}, /* 48 */ -+#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ -+ {0, p2pFuncCalculateExtra_IELenForBeacon, p2pFuncGenerateExtra_IEForBeacon}, /* 221 */ -+#else -+ {0, p2pFuncCalculateP2p_IELenForBeacon, p2pFuncGenerateP2p_IEForBeacon}, /* 221 */ -+ {0, p2pFuncCalculateWSC_IELenForBeacon, p2pFuncGenerateWSC_IEForBeacon}, /* 221 */ -+ {0, p2pFuncCalculateP2P_IE_NoA, p2pFuncGenerateP2P_IE_NoA}, /* 221 */ -+#endif -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+}; -+ -+APPEND_VAR_IE_ENTRY_T txProbRspIETable[] = { -+ {(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE}, /* 50 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE}, /* 42 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE}, /* 45 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE}, /* 61 */ -+#if CFG_ENABLE_WIFI_DIRECT -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE}, /* 48 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE}, /* 74 */ -+#endif -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE}, /* 127 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE}, /* 221 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE} /* 221 */ -+}; -+ -+#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines for all Operation Modes */ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will create or reset a STA_RECORD_T by given BSS_DESC_T for -+* Infrastructure or AdHoc Mode. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eStaType Assign STA Type for this STA_RECORD_T -+* @param[in] eNetTypeIndex Assign Net Type Index for this STA_RECORD_T -+* @param[in] prBssDesc Received Beacon/ProbeResp from this STA -+* -+* @retval Pointer to STA_RECORD_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_STA_RECORD_T -+bssCreateStaRecFromBssDesc(IN P_ADAPTER_T prAdapter, -+ IN ENUM_STA_TYPE_T eStaType, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_8 ucNonHTPhyTypeSet; -+ -+ ASSERT(prBssDesc); -+ -+ /* 4 <1> Get a valid STA_RECORD_T */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex, prBssDesc->aucSrcAddr); -+ if (!prStaRec) { -+ -+ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) eNetTypeIndex); -+ -+ /* TODO(Kevin): Error handling of allocation of STA_RECORD_T for -+ * exhausted case and do removal of unused STA_RECORD_T. -+ */ -+ -+ if (!prStaRec) { -+ ASSERT(FALSE); -+ return NULL; -+ } -+ -+ ASSERT(prStaRec); -+ -+ prStaRec->ucStaState = STA_STATE_1; -+ prStaRec->ucJoinFailureCount = 0; -+ /* TODO(Kevin): If this is an old entry, we may also reset the ucJoinFailureCount to 0. -+ */ -+ -+ COPY_MAC_ADDR(prStaRec->aucMacAddr, prBssDesc->aucSrcAddr); -+ } -+ /* 4 <2> Setup STA TYPE and NETWORK */ -+ prStaRec->eStaType = eStaType; -+ -+ prStaRec->ucNetTypeIndex = eNetTypeIndex; -+ -+ /* 4 <3> Update information from BSS_DESC_T to current P_STA_RECORD_T */ -+ prStaRec->u2CapInfo = prBssDesc->u2CapInfo; -+ -+ prStaRec->u2OperationalRateSet = prBssDesc->u2OperationalRateSet; -+ prStaRec->u2BSSBasicRateSet = prBssDesc->u2BSSBasicRateSet; -+ -+ prStaRec->ucPhyTypeSet = prBssDesc->ucPhyTypeSet; -+ if (IS_STA_IN_AIS(prStaRec)) { -+ if (!((prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) || -+ (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_KEY_ABSENT) || -+ (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION_DISABLED) || -+ (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) || (prAdapter->prGlueInfo->u2WapiAssocInfoIESz))) { -+ DBGLOG(BSS, TRACE, "Ignore the HT Bit for TKIP as pairwise cipher configured!\n"); -+ prStaRec->ucPhyTypeSet &= ~PHY_TYPE_BIT_HT; -+ } -+ } else { -+ DBGLOG(BSS, TRACE, "P2P skip TKIP limitation for HT Hit!\n"); -+ } -+ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prAdapter->rWifiVar.ucAvailablePhyTypeSet; -+ -+ ucNonHTPhyTypeSet = prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11ABG; -+ -+ /* Check for Target BSS's non HT Phy Types */ -+ if (ucNonHTPhyTypeSet) { -+ -+ if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_ERP) { -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; -+ } else if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_OFDM) { -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; -+ } else { /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ -+ -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; -+ } -+ -+ prStaRec->fgHasBasicPhyType = TRUE; -+ } else { -+ /* Use mandatory for 11N only BSS */ -+ ASSERT(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N); -+ -+ { -+ /* TODO(Kevin): which value should we set for 11n ? ERP ? */ -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; -+ } -+ -+ prStaRec->fgHasBasicPhyType = FALSE; -+ } -+ -+ /* Update non HT Desired Rate Set */ -+ { -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ prStaRec->u2DesiredNonHTRateSet = -+ (prStaRec->u2OperationalRateSet & prConnSettings->u2DesiredNonHTRateSet); -+ } -+ -+ /* 4 <4> Update information from BSS_DESC_T to current P_STA_RECORD_T */ -+ if (IS_AP_STA(prStaRec)) { -+ /* do not need to parse IE for DTIM, -+ * which have been parsed before inserting into BSS_DESC_T -+ */ -+ if (prBssDesc->ucDTIMPeriod) -+ prStaRec->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; -+ else -+ prStaRec->ucDTIMPeriod = 0; /* Means that TIM was not parsed. */ -+ } -+ /* 4 <5> Update default value */ -+ prStaRec->fgDiagnoseConnection = FALSE; -+ -+ /* 4 <6> Update default value for other Modules */ -+ /* Determine fgIsWmmSupported and fgIsUapsdSupported in STA_REC */ -+ mqmProcessScanResult(prAdapter, prBssDesc, prStaRec); -+ -+ return prStaRec; -+ -+} /* end of bssCreateStaRecFromBssDesc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the Null Data frame. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] prStaRec Pointer to the STA_RECORD_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssComposeNullFrame(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec) -+{ -+ P_WLAN_MAC_HEADER_T prNullFrame; -+ P_BSS_INFO_T prBssInfo; -+ UINT_16 u2FrameCtrl; -+ -+ ASSERT(pucBuffer); -+ ASSERT(prStaRec); -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ ASSERT(prBssInfo); -+ -+ prNullFrame = (P_WLAN_MAC_HEADER_T) pucBuffer; -+ -+ /* 4 <1> Decide the Frame Control Field */ -+ u2FrameCtrl = MAC_FRAME_NULL; -+ -+ if (IS_AP_STA(prStaRec)) { -+ u2FrameCtrl |= MASK_FC_TO_DS; -+ -+ if (prStaRec->fgSetPwrMgtBit) -+ u2FrameCtrl |= MASK_FC_PWR_MGT; -+ } else if (IS_CLIENT_STA(prStaRec)) { -+ u2FrameCtrl |= MASK_FC_FROM_DS; -+ } else if (IS_DLS_STA(prStaRec)) { -+ /* TODO(Kevin) */ -+ } else { -+ /* NOTE(Kevin): We won't send Null frame for IBSS */ -+ ASSERT(0); -+ return; -+ } -+ -+ /* 4 <2> Compose the Null frame */ -+ /* Fill the Frame Control field. */ -+ /* WLAN_SET_FIELD_16(&prNullFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prNullFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the Address 1 field with Target Peer Address. */ -+ COPY_MAC_ADDR(prNullFrame->aucAddr1, prStaRec->aucMacAddr); -+ -+ /* Fill the Address 2 field with our MAC Address. */ -+ COPY_MAC_ADDR(prNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr); -+ -+ /* Fill the Address 3 field with Target BSSID. */ -+ COPY_MAC_ADDR(prNullFrame->aucAddr3, prBssInfo->aucBSSID); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prNullFrame->u2SeqCtrl = 0; -+ -+ return; -+ -+} /* end of bssComposeNullFrameHeader() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the QoS Null Data frame. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] prStaRec Pointer to the STA_RECORD_T. -+* @param[in] ucUP User Priority. -+* @param[in] fgSetEOSP Set the EOSP bit. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+bssComposeQoSNullFrame(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN BOOLEAN fgSetEOSP) -+{ -+ P_WLAN_MAC_HEADER_QOS_T prQoSNullFrame; -+ P_BSS_INFO_T prBssInfo; -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2QosControl; -+ -+ ASSERT(pucBuffer); -+ ASSERT(prStaRec); -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ ASSERT(prBssInfo); -+ -+ prQoSNullFrame = (P_WLAN_MAC_HEADER_QOS_T) pucBuffer; -+ -+ /* 4 <1> Decide the Frame Control Field */ -+ u2FrameCtrl = MAC_FRAME_QOS_NULL; -+ -+ if (IS_AP_STA(prStaRec)) { -+ u2FrameCtrl |= MASK_FC_TO_DS; -+ -+ if (prStaRec->fgSetPwrMgtBit) -+ u2FrameCtrl |= MASK_FC_PWR_MGT; -+ } else if (IS_CLIENT_STA(prStaRec)) { -+ u2FrameCtrl |= MASK_FC_FROM_DS; -+ } else if (IS_DLS_STA(prStaRec)) { -+ /* TODO(Kevin) */ -+ } else { -+ /* NOTE(Kevin): We won't send QoS Null frame for IBSS */ -+ ASSERT(0); -+ return; -+ } -+ -+ /* 4 <2> Compose the QoS Null frame */ -+ /* Fill the Frame Control field. */ -+ /* WLAN_SET_FIELD_16(&prQoSNullFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prQoSNullFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the Address 1 field with Target Peer Address. */ -+ COPY_MAC_ADDR(prQoSNullFrame->aucAddr1, prStaRec->aucMacAddr); -+ -+ /* Fill the Address 2 field with our MAC Address. */ -+ COPY_MAC_ADDR(prQoSNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr); -+ -+ /* Fill the Address 3 field with Target BSSID. */ -+ COPY_MAC_ADDR(prQoSNullFrame->aucAddr3, prBssInfo->aucBSSID); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prQoSNullFrame->u2SeqCtrl = 0; -+ -+ u2QosControl = (UINT_16) (ucUP & WMM_QC_UP_MASK); -+ -+ if (fgSetEOSP) -+ u2QosControl |= WMM_QC_EOSP; -+ /* WLAN_SET_FIELD_16(&prQoSNullFrame->u2QosCtrl, u2QosControl); */ -+ prQoSNullFrame->u2QosCtrl = u2QosControl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ return; -+ -+} /* end of bssComposeQoSNullFrameHeader() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Send the Null Frame -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] pfTxDoneHandler TX Done call back function -+* -+* @retval WLAN_STATUS_RESOURCE No available resources to send frame. -+* @retval WLAN_STATUS_SUCCESS Succe]ss. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+bssSendNullFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2EstimatedFrameLen; -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ -+ /* Init with MGMT Header Length */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_LEN; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(BSS, WARN, "No PKT_INFO_T for sending Null Frame.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Null frame in MSDU_INfO_T. */ -+ bssComposeNullFrame(prAdapter, (PUINT_8) ((ULONG) prMsduInfo->prPacket + MAC_TX_RESERVED_FIELD), prStaRec); -+#if 0 -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ TXM_SET_DATA_PACKET( -+ /* STA_REC ptr */ prStaRec, -+ /* MSDU_INFO ptr */ prMsduInfo, -+ /* MAC HDR ptr */ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD), -+ /* MAC HDR length */ WLAN_MAC_HEADER_LEN, -+ /* PAYLOAD ptr */ -+ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_LEN), -+ /* PAYLOAD length */ 0, -+ /* Network Type Index */ (UINT_8) prStaRec->ucNetTypeIndex, -+ /* TID */ 0 /* BE: AC1 */ , -+ /* Flag 802.11 */ TRUE, -+ /* Pkt arrival time */ 0 /* TODO: Obtain the system time */ , -+ /* Resource TC */ 0 /* Irrelevant */ , -+ /* Flag 802.1x */ FALSE, -+ /* TX-done callback */ pfTxDoneHandler, -+ /* PS forwarding type */ PS_FORWARDING_TYPE_NON_PS, -+ /* PS Session ID */ 0 /* Irrelevant */ , -+ /* Flag fixed rate */ TRUE, -+ /* Fixed tx rate */ g_aprBssInfo[prStaRec->ucNetTypeIndex]->ucHwDefaultFixedRateCode, -+ /* Fixed-rate retry */ BSS_DEFAULT_CONN_TEST_NULL_FRAME_RETRY_LIMIT, -+ /* PAL LLH */ 0 /* Irrelevant */ , -+ /* ACL SN */ 0 /* Irrelevant */ , -+ /* Flag No Ack */ FALSE -+ ); -+ -+ /* Terminate with a NULL pointer */ -+ NIC_HIF_TX_SET_NEXT_MSDU_INFO(prMsduInfo, NULL); -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* Indicate the packet to TXM */ -+ /* 4 <4> Inform TXM to send this Null frame. */ -+ txmSendFwDataPackets(prMsduInfo); -+#endif -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_DATA; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_LEN; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ /* 4 <4> Inform TXM to send this Null frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of bssSendNullFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Send the QoS Null Frame -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] pfTxDoneHandler TX Done call back function -+* -+* @retval WLAN_STATUS_RESOURCE No available resources to send frame. -+* @retval WLAN_STATUS_SUCCESS Success. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+bssSendQoSNullFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2EstimatedFrameLen; -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ -+ /* Init with MGMT Header Length */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(BSS, WARN, "No PKT_INFO_T for sending Null Frame.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Null frame in MSDU_INfO_T. */ -+ bssComposeQoSNullFrame(prAdapter, -+ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prStaRec, ucUP, FALSE); -+#if 0 -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ TXM_SET_DATA_PACKET( -+ /* STA_REC ptr */ prStaRec, -+ /* MSDU_INFO ptr */ prMsduInfo, -+ /* MAC HDR ptr */ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD), -+ /* MAC HDR length */ WLAN_MAC_HEADER_QOS_LEN, -+ /* PAYLOAD ptr */ -+ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN), -+ /* PAYLOAD length */ 0, -+ /* Network Type Index */ (UINT_8) prStaRec->ucNetTypeIndex, -+ /* TID */ 0 /* BE: AC1 */ , -+ /* Flag 802.11 */ TRUE, -+ /* Pkt arrival time */ 0 /* TODO: Obtain the system time */ , -+ /* Resource TC */ 0 /* Irrelevant */ , -+ /* Flag 802.1x */ FALSE, -+ /* TX-done callback */ pfTxDoneHandler, -+ /* PS forwarding type */ PS_FORWARDING_TYPE_NON_PS, -+ /* PS Session ID */ 0 /* Irrelevant */ , -+ /* Flag fixed rate */ TRUE, -+ /* Fixed tx rate */ g_aprBssInfo[prStaRec->ucNetTypeIndex]->ucHwDefaultFixedRateCode, -+ /* Fixed-rate retry */ TXM_DEFAULT_DATA_FRAME_RETRY_LIMIT, -+ /* PAL LLH */ 0 /* Irrelevant */ , -+ /* ACL SN */ 0 /* Irrelevant */ , -+ /* Flag No Ack */ FALSE -+ ); -+ -+ /* Terminate with a NULL pointer */ -+ NIC_HIF_TX_SET_NEXT_MSDU_INFO(prMsduInfo, NULL); -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* Indicate the packet to TXM */ -+ /* 4 <4> Inform TXM to send this Null frame. */ -+ txmSendFwDataPackets(prMsduInfo); -+#endif -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_QOS_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_QOS_LEN; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Inform TXM to send this Null frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of bssSendQoSNullFrame() */ -+ -+#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) -+/*----------------------------------------------------------------------------*/ -+/* Routines for both IBSS(AdHoc) and BSS(AP) */ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate Information Elements of Extended -+* Support Rate -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssGenerateExtSuppRate_IE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ PUINT_8 pucBuffer; -+ UINT_8 ucExtSupRatesLen; -+ -+ ASSERT(prMsduInfo); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]); -+ ASSERT(prBssInfo); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ ASSERT(pucBuffer); -+ -+ if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) -+ ucExtSupRatesLen = prBssInfo->ucAllSupportedRatesLen - ELEM_MAX_LEN_SUP_RATES; -+ else -+ ucExtSupRatesLen = 0; -+ -+ /* Fill the Extended Supported Rates element. */ -+ if (ucExtSupRatesLen) { -+ -+ EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; -+ EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; -+ -+ kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, -+ &prBssInfo->aucAllSupportedRates[ELEM_MAX_LEN_SUP_RATES], ucExtSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ } -+ -+} /* end of bssGenerateExtSuppRate_IE() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to compose Common Information Elements for Beacon -+* or Probe Response Frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* @param[in] prBssInfo Pointer to the BSS_INFO_T. -+* @param[in] pucDestAddr Pointer to the Destination Address, if NULL, means Beacon. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+bssBuildBeaconProbeRespFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo, IN PUINT_8 pucDestAddr) -+{ -+ PUINT_8 pucBuffer; -+ UINT_8 ucSupRatesLen; -+ -+ ASSERT(prMsduInfo); -+ ASSERT(prBssInfo); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ ASSERT(pucBuffer); -+ -+ /* Compose the frame body of the Probe Response frame. */ -+ /* 4 <1> Fill the SSID element. */ -+ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; -+ if (prBssInfo->eHiddenSsidType == ENUM_HIDDEN_SSID_LEN) { -+ if ((!pucDestAddr) && /* For Beacon only */ -+ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { -+ SSID_IE(pucBuffer)->ucLength = 0; -+ } else { /* Probe response */ -+ SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen; -+ if (prBssInfo->ucSSIDLen) -+ kalMemCopy(SSID_IE(pucBuffer)->aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); -+ } -+ } else { -+ SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen; -+ if (prBssInfo->ucSSIDLen) -+ kalMemCopy(SSID_IE(pucBuffer)->aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); -+ } -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ -+ /* 4 <2> Fill the Supported Rates element. */ -+ if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) -+ ucSupRatesLen = ELEM_MAX_LEN_SUP_RATES; -+ else -+ ucSupRatesLen = prBssInfo->ucAllSupportedRatesLen; -+ -+ if (ucSupRatesLen) { -+ SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; -+ SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; -+ kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, prBssInfo->aucAllSupportedRates, ucSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ /* 4 <3> Fill the DS Parameter Set element. */ -+ if (prBssInfo->eBand == BAND_2G4) { -+ DS_PARAM_IE(pucBuffer)->ucId = ELEM_ID_DS_PARAM_SET; -+ DS_PARAM_IE(pucBuffer)->ucLength = ELEM_MAX_LEN_DS_PARAMETER_SET; -+ DS_PARAM_IE(pucBuffer)->ucCurrChnl = prBssInfo->ucPrimaryChannel; -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ /* 4 <4> IBSS Parameter Set element, ID: 6 */ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ IBSS_PARAM_IE(pucBuffer)->ucId = ELEM_ID_IBSS_PARAM_SET; -+ IBSS_PARAM_IE(pucBuffer)->ucLength = ELEM_MAX_LEN_IBSS_PARAMETER_SET; -+ WLAN_SET_FIELD_16(&(IBSS_PARAM_IE(pucBuffer)->u2ATIMWindow), prBssInfo->u2ATIMWindow); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ /* 4 <5> TIM element, ID: 5 */ -+ if ((!pucDestAddr) && /* For Beacon only. */ -+ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /*no fgIsP2PRegistered protect */ -+ if (prBssInfo->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+#if 0 -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; -+ UINT_8 ucBitmapControl = 0; -+ UINT_32 u4N1, u4N2; -+ -+ prP2pSpecificBssInfo = &(prAdapter->rWifiVar.rP2pSpecificBssInfo); -+ -+ /* Clear existing value. */ -+ prP2pSpecificBssInfo->ucBitmapCtrl = 0; -+ kalMemZero(prP2pSpecificBssInfo->aucPartialVirtualBitmap, -+ sizeof(prP2pSpecificBssInfo->aucPartialVirtualBitmap)); -+ -+ /* IEEE 802.11 2007 - 7.3.2.6 */ -+ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; -+ TIM_IE(pucBuffer)->ucDTIMCount = prBssInfo->ucDTIMCount; -+ TIM_IE(pucBuffer)->ucDTIMPeriod = prBssInfo->ucDTIMPeriod; -+ -+ /* Setup DTIM Count for next TBTT. */ -+ if (prBssInfo->ucDTIMCount == 0) { -+ /*Do nothing*/ -+ /* 3 *** pmQueryBufferedBCAST(); */ -+ } -+ /* 3 *** pmQueryBufferedPSNode(); */ -+ /* TODO(Kevin): Call PM Module here to loop all STA_RECORD_Ts and it -+ * will call bssSetTIMBitmap to toggle the Bitmap. -+ */ -+ -+ /* Set Virtual Bitmap for UCAST */ -+ u4N1 = (prP2pSpecificBssInfo->u2SmallestAID >> 4) << 1; /* Find the largest even number. */ -+ u4N2 = prP2pSpecificBssInfo->u2LargestAID >> 3; /* Find the smallest number. */ -+ -+ ASSERT(u4N2 >= u4N1); -+ -+ kalMemCopy(TIM_IE(pucBuffer)->aucPartialVirtualMap, -+ &prP2pSpecificBssInfo->aucPartialVirtualBitmap[u4N1], ((u4N2 - u4N1) + 1)); -+ -+ /* Set Virtual Bitmap for BMCAST */ -+ /* BMC bit only indicated when DTIM count == 0. */ -+ if (prBssInfo->ucDTIMCount == 0) -+ ucBitmapControl = prP2pSpecificBssInfo->ucBitmapCtrl; -+ TIM_IE(pucBuffer)->ucBitmapControl = ucBitmapControl | (UINT_8) u4N1; -+ -+ TIM_IE(pucBuffer)->ucLength = ((u4N2 - u4N1) + 4); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+#else -+ -+ /* IEEE 802.11 2007 - 7.3.2.6 */ -+ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; -+ /* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */ -+ TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP); /*((u4N2 - u4N1) + 4) */ -+ /* will be overwrite by FW */ -+ TIM_IE(pucBuffer)->ucDTIMCount = 0; /*prBssInfo->ucDTIMCount */ -+ TIM_IE(pucBuffer)->ucDTIMPeriod = prBssInfo->ucDTIMPeriod; -+ /* will be overwrite by FW */ -+ TIM_IE(pucBuffer)->ucBitmapControl = 0; /*ucBitmapControl | (UINT_8)u4N1 */ -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ -+#endif -+ -+ } else -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ { -+ /* NOTE(Kevin): 1. AIS - Didn't Support AP Mode. -+ * 2. BOW - Didn't Support BCAST and PS. -+ */ -+ } -+ -+ } -+ -+} /* end of bssBuildBeaconProbeRespFrameCommonIEs() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the Beacon/Probe Response frame header and -+* its fixed fields. -+* -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] pucDestAddr Pointer to the Destination Address, if NULL, means Beacon. -+* @param[in] pucOwnMACAddress Given Our MAC Address. -+* @param[in] pucBSSID Given BSSID of the BSS. -+* @param[in] u2BeaconInterval Given Beacon Interval. -+* @param[in] u2CapInfo Given Capability Info. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+bssComposeBeaconProbeRespFrameHeaderAndFF(IN PUINT_8 pucBuffer, -+ IN PUINT_8 pucDestAddr, -+ IN PUINT_8 pucOwnMACAddress, -+ IN PUINT_8 pucBSSID, IN UINT_16 u2BeaconInterval, IN UINT_16 u2CapInfo) -+{ -+ P_WLAN_BEACON_FRAME_T prBcnProbRspFrame; -+ UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+ UINT_16 u2FrameCtrl; -+ -+ DEBUGFUNC("bssComposeBeaconProbeRespFrameHeaderAndFF"); -+ /* DBGLOG(INIT, LOUD, ("\n")); */ -+ -+ ASSERT(pucBuffer); -+ ASSERT(pucOwnMACAddress); -+ ASSERT(pucBSSID); -+ -+ prBcnProbRspFrame = (P_WLAN_BEACON_FRAME_T) pucBuffer; -+ -+ /* 4 <1> Compose the frame header of the Beacon /ProbeResp frame. */ -+ /* Fill the Frame Control field. */ -+ if (pucDestAddr) { -+ u2FrameCtrl = MAC_FRAME_PROBE_RSP; -+ } else { -+ u2FrameCtrl = MAC_FRAME_BEACON; -+ pucDestAddr = aucBCAddr; -+ } -+ /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prBcnProbRspFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the DA field with BCAST MAC ADDR or TA of ProbeReq. */ -+ COPY_MAC_ADDR(prBcnProbRspFrame->aucDestAddr, pucDestAddr); -+ -+ /* Fill the SA field with our MAC Address. */ -+ COPY_MAC_ADDR(prBcnProbRspFrame->aucSrcAddr, pucOwnMACAddress); -+ -+ /* Fill the BSSID field with current BSSID. */ -+ COPY_MAC_ADDR(prBcnProbRspFrame->aucBSSID, pucBSSID); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prBcnProbRspFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's common fixed field part of the Beacon /ProbeResp frame. */ -+ /* MAC will update TimeStamp field */ -+ -+ /* Fill the Beacon Interval field. */ -+ /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2BeaconInterval, u2BeaconInterval); */ -+ prBcnProbRspFrame->u2BeaconInterval = u2BeaconInterval; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the Capability Information field. */ -+ /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2CapInfo, u2CapInfo); */ -+ prBcnProbRspFrame->u2CapInfo = u2CapInfo; /* NOTE(Kevin): Optimized for ARM */ -+ -+} /* end of bssComposeBeaconProbeRespFrameHeaderAndFF() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Update the Beacon Frame Template to FW for AIS AdHoc and P2P GO. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eNetTypeIndex Specify which network reply the Probe Response. -+* -+* @retval WLAN_STATUS_SUCCESS Success. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bssUpdateBeaconContent(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ P_WLAN_BEACON_FRAME_T prBcnFrame; -+ UINT_32 i; -+ -+ DEBUGFUNC("bssUpdateBeaconContent"); -+ DBGLOG(BSS, LOUD, "\n"); -+ -+ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Beacon Frame */ -+ /* Allocate a MSDU_INFO_T */ -+ /* For Beacon */ -+ prMsduInfo = prBssInfo->prBeacon; -+ -+ /* beacon prMsduInfo will be NULLify once BSS deactivated, so skip if it is */ -+ if (prMsduInfo == NULL) -+ return WLAN_STATUS_SUCCESS; -+ /* 4 <2> Compose header */ -+ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ NULL, -+ prBssInfo->aucOwnMacAddr, -+ prBssInfo->aucBSSID, -+ prBssInfo->u2BeaconInterval, prBssInfo->u2CapInfo); -+ -+ prMsduInfo->u2FrameLength = (WLAN_MAC_MGMT_HEADER_LEN + -+ (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)); -+ -+ prMsduInfo->ucNetworkType = eNetTypeIndex; -+ -+ /* 4 <3> Compose the frame body's Common IEs of the Beacon frame. */ -+ bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, prBssInfo, NULL); -+ -+ /* 4 <4> Compose IEs in MSDU_INFO_T */ -+ -+ /* Append IE for Beacon */ -+ for (i = 0; i < sizeof(txBcnIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txBcnIETable[i].pfnAppendIE) -+ txBcnIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ -+ prBcnFrame = (P_WLAN_BEACON_FRAME_T) prMsduInfo->prPacket; -+ -+ return nicUpdateBeaconIETemplate(prAdapter, -+ IE_UPD_METHOD_UPDATE_ALL, -+ eNetTypeIndex, -+ prBssInfo->u2CapInfo, -+ (PUINT_8) prBcnFrame->aucInfoElem, -+ prMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem)); -+ -+} /* end of bssUpdateBeaconContent() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Send the Beacon Frame(for BOW) or Probe Response Frame according to the given -+* Destination Address. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eNetTypeIndex Specify which network reply the Probe Response. -+* @param[in] pucDestAddr Pointer to the Destination Address to reply -+* @param[in] u4ControlFlags Control flags for information on Probe Response. -+* -+* @retval WLAN_STATUS_RESOURCE No available resources to send frame. -+* @retval WLAN_STATUS_SUCCESS Success. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+bssSendBeaconProbeResponse(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN PUINT_8 pucDestAddr, IN UINT_32 u4ControlFlags) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2EstimatedFixedIELen; -+ UINT_16 u2EstimatedExtraIELen; -+ P_APPEND_VAR_IE_ENTRY_T prIeArray = NULL; -+ UINT_32 u4IeArraySize = 0; -+ UINT_32 i; -+ -+ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ if (!pucDestAddr) { /* For Beacon */ -+ prIeArray = &txBcnIETable[0]; -+ u4IeArraySize = sizeof(txBcnIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); -+ } else { -+ prIeArray = &txProbRspIETable[0]; -+ u4IeArraySize = sizeof(txProbRspIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); -+ } -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Beacon /Probe Response Frame */ -+ /* Allocate a MSDU_INFO_T */ -+ -+ /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Fields */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ TIMESTAMP_FIELD_LEN + -+ BEACON_INTERVAL_FIELD_LEN + -+ CAP_INFO_FIELD_LEN + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_DS_PARAMETER_SET) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_IBSS_PARAMETER_SET) + (ELEM_HDR_LEN + (3 + MAX_LEN_TIM_PARTIAL_BMP)); -+ -+ /* + Extra IE Length */ -+ u2EstimatedExtraIELen = 0; -+ -+ for (i = 0; i < u4IeArraySize; i++) { -+ u2EstimatedFixedIELen = prIeArray[i].u2EstimatedFixedIELen; -+ -+ if (u2EstimatedFixedIELen) { -+ u2EstimatedExtraIELen += u2EstimatedFixedIELen; -+ } else { -+ ASSERT(prIeArray[i].pfnCalculateVariableIELen); -+ -+ u2EstimatedExtraIELen += (UINT_16) -+ prIeArray[i].pfnCalculateVariableIELen(prAdapter, eNetTypeIndex, NULL); -+ } -+ } -+ -+ u2EstimatedFrameLen += u2EstimatedExtraIELen; -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(BSS, WARN, "No PKT_INFO_T for sending %s.\n", ((!pucDestAddr) ? "Beacon" : "Probe Response")); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Beacon/Probe Response frame header and fixed fields in MSDU_INfO_T. */ -+ /* Compose Header and Fixed Field */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (u4ControlFlags & BSS_PROBE_RESP_USE_P2P_DEV_ADDR) { -+ if (prAdapter->fgIsP2PRegistered) { -+ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) -+ ((ULONG) (prMsduInfo->prPacket) + -+ MAC_TX_RESERVED_FIELD), pucDestAddr, -+ prAdapter->rWifiVar.aucDeviceAddress, -+ prAdapter->rWifiVar.aucDeviceAddress, -+ DOT11_BEACON_PERIOD_DEFAULT, -+ (prBssInfo->u2CapInfo & -+ ~(CAP_INFO_ESS | CAP_INFO_IBSS))); -+ } -+ } else -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ { -+ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) -+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ pucDestAddr, prBssInfo->aucOwnMacAddr, prBssInfo->aucBSSID, -+ prBssInfo->u2BeaconInterval, prBssInfo->u2CapInfo); -+ } -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = 0xFF; -+ prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = (WLAN_MAC_MGMT_HEADER_LEN + -+ TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN); -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Compose the frame body's Common IEs of the Beacon/ProbeResp frame. */ -+ bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, prBssInfo, pucDestAddr); -+ -+ /* 4 <5> Compose IEs in MSDU_INFO_T */ -+ -+ /* Append IE */ -+ for (i = 0; i < u4IeArraySize; i++) { -+ if (prIeArray[i].pfnAppendIE) -+ prIeArray[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* 4 <6> Inform TXM to send this Beacon /Probe Response frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of bssSendBeaconProbeResponse() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx Probe Request Frame and then send -+* back the corresponding Probe Response Frame if the specified conditions -+* were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always return success -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; -+ P_BSS_INFO_T prBssInfo; -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ UINT_8 aucBCBSSID[] = BC_BSSID; -+ BOOLEAN fgIsBcBssid; -+ BOOLEAN fgReplyProbeResp; -+ UINT_32 u4CtrlFlagsForProbeResp = 0; -+ ENUM_BAND_T eBand; -+ UINT_8 ucHwChannelNum; -+ -+ ASSERT(prSwRfb); -+ -+ /* 4 <1> Parse Probe Req and Get BSSID */ -+ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; -+ -+ if (EQUAL_MAC_ADDR(aucBCBSSID, prMgtHdr->aucBSSID)) -+ fgIsBcBssid = TRUE; -+ else -+ fgIsBcBssid = FALSE; -+ -+ /* 4 <2> Check network conditions before reply Probe Response Frame (Consider Concurrent) */ -+ for (eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; eNetTypeIndex < NETWORK_TYPE_INDEX_NUM; eNetTypeIndex++) { -+ -+ if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex)) -+ continue; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ if ((!fgIsBcBssid) && UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prMgtHdr->aucBSSID)) -+ continue; -+ -+ eBand = HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr); -+ ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr); -+ -+ if (prBssInfo->eBand != eBand) -+ continue; -+ -+ if (prBssInfo->ucPrimaryChannel != ucHwChannelNum) -+ continue; -+ -+ fgReplyProbeResp = FALSE; -+ -+ if (NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) { -+ -+#if CFG_SUPPORT_ADHOC -+ fgReplyProbeResp = aisValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp); -+#endif -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && (NETWORK_TYPE_P2P_INDEX == eNetTypeIndex)) { -+ if (nicTxGetFreeCmdCount(prAdapter) > (CFG_TX_MAX_CMD_PKT_NUM / 2)) { -+ /* Resource margin is enough */ -+ fgReplyProbeResp = -+ p2pFuncValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp); -+ } -+ } -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (NETWORK_TYPE_BOW_INDEX == eNetTypeIndex) -+ fgReplyProbeResp = bowValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp); -+#endif -+ -+ if (fgReplyProbeResp) { -+ if (nicTxGetFreeCmdCount(prAdapter) > (CFG_TX_MAX_CMD_PKT_NUM / 2)) { -+ /* Resource margin is enough */ -+ bssSendBeaconProbeResponse(prAdapter, eNetTypeIndex, prMgtHdr->aucSrcAddr, -+ u4CtrlFlagsForProbeResp); -+ } -+ } -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of bssProcessProbeRequest() */ -+ -+#if 0 /* NOTE(Kevin): condition check should move to P2P_FSM.c */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx Probe Request Frame and then send -+* back the corresponding Probe Response Frame if the specified conditions -+* were matched. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always return success -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; -+ P_BSS_INFO_T prBssInfo; -+ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; -+ P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL; -+ P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL; -+ PUINT_8 pucIE; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ UINT_8 aucBCBSSID[] = BC_BSSID; -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ BOOLEAN fgReplyProbeResp; -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgP2PTargetDeviceFound; -+ UINT_8 aucP2PWildcardSSID[] = P2P_WILDCARD_SSID; -+#endif -+ -+ ASSERT(prSwRfb); -+ -+ /* 4 <1> Parse Probe Req and Get SSID IE ptr */ -+ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; -+ -+ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; -+ pucIE = (PUINT_8) ((UINT_32) prSwRfb->pvHeader + prSwRfb->u2HeaderLen); -+ -+ prIeSsid = (P_IE_SSID_T) NULL; -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_SSID: -+ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ break; -+ -+ case ELEM_ID_SUP_RATES: -+ /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8. -+ * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B), -+ * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" -+ */ -+ /* if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SUP_RATES) { */ -+ if (IE_LEN(pucIE) <= RATE_NUM) -+ prIeSupportedRate = SUP_RATES_IE(pucIE); -+ break; -+ -+ case ELEM_ID_EXTENDED_SUP_RATES: -+ prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); -+ break; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* TODO: P2P IE & WCS IE parsing for P2P. */ -+ case ELEM_ID_P2P: -+ -+ break; -+#endif -+ -+ /* no default */ -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ /* 4 <2> Check network conditions before reply Probe Response Frame (Consider Concurrent) */ -+ for (eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; eNetTypeIndex < NETWORK_TYPE_INDEX_NUM; eNetTypeIndex++) { -+ -+ if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex)) -+ continue; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ if (UNEQUAL_MAC_ADDR(aucBCBSSID, prMgtHdr->aucBSSID) && -+ UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prMgtHdr->aucBSSID)) { -+ /* BSSID not Wildcard BSSID. */ -+ continue; -+ } -+ -+ fgReplyProbeResp = FALSE; -+ -+ if (NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) { -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ -+ /* TODO(Kevin): Check if we are IBSS Master. */ -+ if (TRUE && prIeSsid) { -+ if ((prIeSsid->ucLength == BC_SSID_LEN) || /* WILDCARD SSID */ -+ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, -+ prIeSsid->aucSSID, prIeSsid->ucLength)) { -+ fgReplyProbeResp = TRUE; -+ } -+ } -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if (NETWORK_TYPE_P2P_INDEX == eNetTypeIndex) { -+ -+ /* TODO(Kevin): Move following lines to p2p_fsm.c */ -+ -+ if ((prIeSsid) && -+ ((prIeSsid->ucLength == BC_SSID_LEN) || -+ (EQUAL_SSID(aucP2PWildcardSSID, -+ P2P_WILDCARD_SSID_LEN, prIeSsid->aucSSID, prIeSsid->ucLength)))) { -+ /* if (p2pFsmRunEventRxProbeRequestFrame(prAdapter, prMgtHdr->aucSrcAddr, -+ pucIE, u2IELength)) { */ -+ if (p2pFsmRunEventRxProbeRequestFrame(prAdapter, prSwRfb)) { -+ /* Extand channel request time & cancel scan request. */ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ /* TODO: RX probe request may not caused by LISTEN state. */ -+ /* TODO: It can be GO. */ -+ /* Generally speaking, cancel a non-exist scan request is fine. -+ * We can check P2P FSM here for only LISTEN state. -+ */ -+ -+ P_MSG_SCN_SCAN_CANCEL prScanCancelMsg; -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ /* Abort JOIN process. */ -+ prScanCancelMsg = -+ (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_SCN_SCAN_CANCEL)); -+ if (!prScanCancelMsg) { -+ ASSERT(0); /* Can't abort SCN FSM */ -+ continue; -+ } -+ -+ prScanCancelMsg->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_CANCEL; -+ prScanCancelMsg->ucSeqNum = prP2pFsmInfo->ucSeqNumOfScnMsg; -+ prScanCancelMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_P2P_INDEX; -+ prScanCancelMsg->fgIsChannelExt = TRUE; -+ -+ mboxSendMsg(prAdapter, -+ MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_BUF); -+ } -+ } else { -+ /* 1. Probe Request without SSID. -+ * 2. Probe Request with SSID not Wildcard SSID & not P2P Wildcard SSID. -+ */ -+ continue; -+ } -+ -+#if 0 /* Frog */ -+ if (prAdapter->rWifiVar.prP2pFsmInfo->eCurrentState == P2P_STATE_LISTEN) { -+ /* P2P 2.4.1 - P2P Devices shall not respond to Probe Request frames -+ which only contain 11b rates only. */ -+ if (prIeSupportedRate || prIeExtSupportedRate) { -+ UINT_16 u2OperationalRateSet, u2BSSBasicRateSet; -+ BOOLEAN fgIsUnknownBssBasicRate; -+ -+ rateGetRateSetFromIEs(prIeSupportedRate, prIeExtSupportedRate, -+ &u2OperationalRateSet, -+ &u2BSSBasicRateSet, /* Ignore any Basic Bit */ -+ &fgIsUnknownBssBasicRate); -+ -+ if (u2OperationalRateSet & ~RATE_SET_HR_DSSS) -+ continue; -+ } -+ } -+ /* TODO: Check channel time before first check point to: */ -+ /* If Target device is selected: -+ * 1. Send XXXX request frame. -+ * else -+ * 1. Send Probe Response frame. -+ */ -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ /* TODO(Kevin): During PROVISION state, can we reply Probe Response ? */ -+ -+ /* TODO(Kevin): -+ * If we are GO, accept legacy client --> accept Wildcard SSID -+ * If we are in Listen State, accept only P2P Device --> check P2P IE and WPS IE -+ */ -+ if (TRUE /* We are GO */ && prIeSsid) { -+ UINT_8 aucSSID[] = P2P_WILDCARD_SSID; -+ -+ if ((prIeSsid->ucLength == BC_SSID_LEN) || /* WILDCARD SSID */ -+ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, -+ prIeSsid->aucSSID, prIeSsid->ucLength) || -+ EQUAL_SSID(aucSSID, P2P_WILDCARD_SSID_LEN, -+ prIeSsid->aucSSID, prIeSsid->ucLength)) { -+ fgReplyProbeResp = TRUE; -+ } -+ } -+/* else if (FALSE) { */ /* We are in Listen State */ -+/* } */ -+ -+ /* TODO(Kevin): Check P2P IE and WPS IE */ -+ } -+#endif -+ } -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (NETWORK_TYPE_BOW_INDEX == eNetTypeIndex) { -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ /* Do nothing */ -+ /* TODO(Kevin): TBD */ -+ } -+ } -+#endif -+ else -+ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ if (fgReplyProbeResp) -+ bssSendBeaconProbeResponse(prAdapter, eNetTypeIndex, prMgtHdr->aucSrcAddr); -+ -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of bssProcessProbeRequest() */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to clear the client list for AdHoc or AP Mode -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prBssInfo Given related BSS_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssClearClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo) -+{ -+ P_LINK_T prStaRecOfClientList; -+ -+ ASSERT(prBssInfo); -+ -+ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; -+ -+ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ P_STA_RECORD_T prPeerStaRec; -+ -+ LINK_FOR_EACH_ENTRY(prPeerStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { -+ cnmStaRecChangeState(prAdapter, prPeerStaRec, STA_STATE_1); -+ } -+ -+ LINK_INITIALIZE(prStaRecOfClientList); -+ } -+ -+} /* end of bssClearClientList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to Add a STA_RECORD_T to the client list for AdHoc or AP Mode -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prBssInfo Given related BSS_INFO_T. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssAddStaRecToClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec) -+{ -+ P_LINK_T prStaRecOfClientList; -+ -+ ASSERT(prBssInfo); -+ -+ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; -+ -+ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ P_STA_RECORD_T prCurrStaRec; -+ -+ LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { -+ -+ if (prCurrStaRec == prStaRec) { -+ DBGLOG(BSS, WARN, -+ "Current Client List already contains that STA_RECORD_T[%pM]\n", -+ prStaRec->aucMacAddr); -+ return; -+ } -+ } -+ } -+ -+ LINK_INSERT_TAIL(prStaRecOfClientList, &prStaRec->rLinkEntry); -+ -+} /* end of bssAddStaRecToClientList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to Remove a STA_RECORD_T from the client list for AdHoc or AP Mode -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssRemoveStaRecFromClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec) -+{ -+ P_LINK_T prStaRecOfClientList; -+ -+ ASSERT(prBssInfo); -+ -+ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; -+ -+#if 0 -+ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ P_STA_RECORD_T prCurrStaRec; -+ -+ LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { -+ -+ if (prCurrStaRec == prStaRec) { -+ -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prStaRec->rLinkEntry); -+ -+ return; -+ } -+ } -+ } -+#endif -+ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ if ((ULONG) prStaRec == (ULONG) prLinkEntry) { -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prStaRec->rLinkEntry); -+ return; -+ } -+ } -+ } -+ -+ DBGLOG(BSS, INFO, "Current Client List didn't contain that STA_RECORD_T[%pM] before removing.\n", -+ prStaRec->aucMacAddr); -+ -+} /* end of bssRemoveStaRecFromClientList() */ -+#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Get station record by Address for AP mode -+* -+* @param[in] prBssInfo Pointer to BSS_INFO_T. -+* @param[in] pucMacAddr Pointer to target mac address -+* -+* @return pointer of STA_RECORD_T if found, otherwise, return NULL -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+P_STA_RECORD_T bssGetClientByAddress(IN P_BSS_INFO_T prBssInfo, PUINT_8 pucMacAddr) -+{ -+ P_LINK_T prStaRecOfClientList; -+ -+ ASSERT(prBssInfo); -+ ASSERT(pucMacAddr); -+ -+ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; -+ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ P_STA_RECORD_T prCurrStaRec; -+ -+ LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { -+ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, pucMacAddr)) -+ return prCurrStaRec; -+ } -+ } -+ return NULL; -+} -+ -+#if CFG_SUPPORT_ADHOC -+/*----------------------------------------------------------------------------*/ -+/* Routines for IBSS(AdHoc) only */ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to process Beacons from current Ad-Hoc network peers. -+* We also process Beacons from other Ad-Hoc network during SCAN. If it has -+* the same SSID and we'll decide to merge into it if it has a larger TSF. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prBssInfo Pointer to the BSS_INFO_T. -+* @param[in] prBSSDesc Pointer to the BSS Descriptor. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+ibssProcessMatchedBeacon(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prBssInfo, IN P_BSS_DESC_T prBssDesc, IN UINT_8 ucRCPI) -+{ -+ P_STA_RECORD_T prStaRec = NULL; -+ -+ BOOLEAN fgIsCheckCapability = FALSE; -+ BOOLEAN fgIsCheckTSF = FALSE; -+ BOOLEAN fgIsGoingMerging = FALSE; -+ BOOLEAN fgIsSameBSSID; -+ -+ ASSERT(prBssInfo); -+ ASSERT(prBssDesc); -+ -+ /* 4 <1> Process IBSS Beacon only after we create or merge with other IBSS. */ -+ if (!prBssInfo->fgIsBeaconActivated) -+ return; -+ /* 4 <2> Get the STA_RECORD_T of TA. */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prBssDesc->aucSrcAddr); -+ -+ fgIsSameBSSID = UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID) ? FALSE : TRUE; -+ -+ /* 4 <3> IBSS Merge Decision Flow for Processing Beacon. */ -+ if (fgIsSameBSSID) { -+ -+ /* Same BSSID: -+ * Case I. This is a new TA and it has decide to merged with us. -+ * a) If fgIsMerging == FALSE - we will send msg to notify AIS. -+ * b) If fgIsMerging == TRUE - already notify AIS. -+ * Case II. This is an old TA and we've already merged together. -+ */ -+ if (!prStaRec) { -+ -+ /* For Case I - Check this IBSS's capability first before adding this Sta Record. */ -+ fgIsCheckCapability = TRUE; -+ -+ /* If check is passed, then we perform merging with this new IBSS */ -+ fgIsGoingMerging = TRUE; -+ -+ } else { -+ -+ ASSERT((prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) && IS_ADHOC_STA(prStaRec)); -+ -+ if (prStaRec->ucStaState != STA_STATE_3) { -+ -+ if (!prStaRec->fgIsMerging) { -+ -+ /* For Case I - Check this IBSS's capability first -+ * before adding this Sta Record. */ -+ fgIsCheckCapability = TRUE; -+ -+ /* If check is passed, then we perform merging with this new IBSS */ -+ fgIsGoingMerging = TRUE; -+ } else { -+ /* For Case II - Update rExpirationTime of Sta Record */ -+ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); -+ } -+ } else { -+ /* For Case II - Update rExpirationTime of Sta Record */ -+ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); -+ } -+ -+ } -+ } else { -+ -+ /* Unequal BSSID: -+ * Case III. This is a new TA and we need to compare the TSF and get the winner. -+ * Case IV. This is an old TA and it merge into a new IBSS before we do the same thing. -+ * We need to compare the TSF to get the winner. -+ * Case V. This is an old TA and it restart a new IBSS. We also need to -+ * compare the TSF to get the winner. -+ */ -+ -+ /* For Case III, IV & V - We'll always check this new IBSS's capability first -+ * before merging into new IBSS. -+ */ -+ fgIsCheckCapability = TRUE; -+ -+ /* If check is passed, we need to perform TSF check to decide the major BSSID */ -+ fgIsCheckTSF = TRUE; -+ -+ /* For Case IV & V - We won't update rExpirationTime of Sta Record */ -+ } -+ -+ /* 4 <7> Check this BSS_DESC_T's capability. */ -+ if (fgIsCheckCapability) { -+ BOOLEAN fgIsCapabilityMatched = FALSE; -+ -+ do { -+ if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) { -+ DBGLOG(BSS, LOUD, -+ "IBSS MERGE: Ignore Peer MAC: %pM - Unsupported Phy.\n", -+ prBssDesc->aucSrcAddr); -+ -+ break; -+ } -+ -+ if (prBssDesc->fgIsUnknownBssBasicRate) { -+ DBGLOG(BSS, LOUD, -+ "IBSS MERGE: Ignore Peer MAC: %pM - Unknown Basic Rate.\n", -+ prBssDesc->aucSrcAddr); -+ -+ break; -+ } -+ -+ if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) { -+ DBGLOG(BSS, LOUD, -+ "IBSS MERGE: Ignore Peer MAC: %pM - Capability is not matched.\n", -+ prBssDesc->aucSrcAddr); -+ -+ break; -+ } -+ -+ fgIsCapabilityMatched = TRUE; -+ } while (FALSE); -+ -+ if (!fgIsCapabilityMatched) { -+ -+ if (prStaRec) { -+ /* For Case II - We merge this STA_RECORD in RX Path. -+ * Case IV & V - They change their BSSID after we merge with them. -+ */ -+ -+ DBGLOG(BSS, LOUD, -+ "IBSS MERGE: Ignore Peer MAC: %pM - Capability is not matched.\n", -+ prBssDesc->aucSrcAddr); -+ } -+ -+ return; -+ } -+ -+ DBGLOG(BSS, LOUD, -+ "IBSS MERGE: Peer MAC: %pM - Check capability was passed.\n", -+ prBssDesc->aucSrcAddr); -+ } -+ -+ if (fgIsCheckTSF) { -+#if CFG_SLT_SUPPORT -+ fgIsGoingMerging = TRUE; -+#else -+ if (prBssDesc->fgIsLargerTSF) -+ fgIsGoingMerging = TRUE; -+ else -+ return; -+#endif -+ } -+ -+ if (fgIsGoingMerging) { -+ P_MSG_AIS_IBSS_PEER_FOUND_T prAisIbssPeerFoundMsg; -+ -+ /* 4 <1> We will merge with to this BSS immediately. */ -+ prBssDesc->fgIsConnecting = TRUE; -+ prBssDesc->fgIsConnected = FALSE; -+ -+ /* 4 <2> Setup corresponding STA_RECORD_T */ -+ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, -+ STA_TYPE_ADHOC_PEER, NETWORK_TYPE_AIS_INDEX, prBssDesc); -+ -+ if (!prStaRec) { -+ /* no memory ? */ -+ return; -+ } -+ -+ prStaRec->fgIsMerging = TRUE; -+ -+ /* update RCPI */ -+ prStaRec->ucRCPI = ucRCPI; -+ -+ /* 4 <3> Send Merge Msg to CNM to obtain the channel privilege. */ -+ prAisIbssPeerFoundMsg = (P_MSG_AIS_IBSS_PEER_FOUND_T) -+ cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_IBSS_PEER_FOUND_T)); -+ -+ if (!prAisIbssPeerFoundMsg) { -+ -+ ASSERT(0); /* Can't send Merge Msg */ -+ return; -+ } -+ -+ prAisIbssPeerFoundMsg->rMsgHdr.eMsgId = MID_SCN_AIS_FOUND_IBSS; -+ prAisIbssPeerFoundMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX; -+ prAisIbssPeerFoundMsg->prStaRec = prStaRec; -+ -+ /* Inform AIS to do STATE TRANSITION -+ * For Case I - If AIS in IBSS_ALONE, let it jump to NORMAL_TR after we know the new member. -+ * For Case III, IV - Now this new BSSID wins the TSF, follow it. -+ */ -+ if (fgIsSameBSSID) { -+ prAisIbssPeerFoundMsg->fgIsMergeIn = TRUE; -+ } else { -+#if CFG_SLT_SUPPORT -+ prAisIbssPeerFoundMsg->fgIsMergeIn = TRUE; -+#else -+ prAisIbssPeerFoundMsg->fgIsMergeIn = (prBssDesc->fgIsLargerTSF) ? FALSE : TRUE; -+#endif -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisIbssPeerFoundMsg, MSG_SEND_METHOD_BUF); -+ -+ } -+ -+} /* end of ibssProcessMatchedBeacon() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will check the Capability for Ad-Hoc to decide if we are -+* able to merge with(same capability). -+* -+* @param[in] prBSSDesc Pointer to the BSS Descriptor. -+* -+* @retval WLAN_STATUS_FAILURE Can't pass the check of Capability. -+* @retval WLAN_STATUS_SUCCESS Pass the check of Capability. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS ibssCheckCapabilityForAdHocMode(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ -+ ASSERT(prBssDesc); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ do { -+ /* 4 <1> Check the BSS Basic Rate Set for current AdHoc Mode */ -+ if ((prConnSettings->eAdHocMode == AD_HOC_MODE_11B) && -+ (prBssDesc->u2BSSBasicRateSet & ~RATE_SET_HR_DSSS)) { -+ break; -+ } else if ((prConnSettings->eAdHocMode == AD_HOC_MODE_11A) && -+ (prBssDesc->u2BSSBasicRateSet & ~RATE_SET_OFDM)) { -+ break; -+ } -+ /* 4 <2> Check the Short Slot Time. */ -+#if 0 /* Do not check ShortSlotTime until Wi-Fi define such policy */ -+ if (prConnSettings->eAdHocMode == AD_HOC_MODE_11G) { -+ if (((prConnSettings->fgIsShortSlotTimeOptionEnable) && -+ !(prBssDesc->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) || -+ (!(prConnSettings->fgIsShortSlotTimeOptionEnable) && -+ (prBssDesc->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME))) { -+ break; -+ } -+ } -+#endif -+ -+ /* 4 <3> Check the ATIM window setting. */ -+ if (prBssDesc->u2ATIMWindow) { -+ DBGLOG(BSS, INFO, "AdHoc PS was not supported(ATIM Window: %d)\n", prBssDesc->u2ATIMWindow); -+ break; -+ } -+#if CFG_RSN_MIGRATION -+ /* 4 <4> Check the Security setting. */ -+ if (!rsnPerformPolicySelection(prAdapter, prBssDesc)) -+ break; -+#endif -+ -+ rStatus = WLAN_STATUS_SUCCESS; -+ } while (FALSE); -+ -+ return rStatus; -+ -+} /* end of ibssCheckCapabilityForAdHocMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will initial the BSS_INFO_T for IBSS Mode. -+* -+* @param[in] prBssInfo Pointer to the BSS_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID ibssInitForAdHoc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo) -+{ -+ UINT_8 ucLowestBasicRateIndex; -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+ PUINT_16 pu2BSSID = (PUINT_16) &aucBSSID[0]; -+ UINT_32 i; -+ -+ ASSERT(prBssInfo); -+ ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_IBSS); -+ -+ /* 4 <1> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ -+ prBssInfo->ucNonHTBasicPhyType = (UINT_8) -+ rNonHTAdHocModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; -+ prBssInfo->u2BSSBasicRateSet = rNonHTAdHocModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; -+ -+ prBssInfo->u2OperationalRateSet = rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; -+ -+ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, -+ prBssInfo->u2BSSBasicRateSet, -+ prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen); -+ -+ /* 4 <2> Setup BSSID */ -+ if (!prBssInfo->fgHoldSameBssidForIBSS) { -+ -+ for (i = 0; i < sizeof(aucBSSID) / sizeof(UINT_16); i++) -+ pu2BSSID[i] = (UINT_16) (kalRandomNumber() & 0xFFFF); -+ -+ aucBSSID[0] &= ~0x01; /* 7.1.3.3.3 - The individual/group bit of the address is set to 0. */ -+ aucBSSID[0] |= 0x02; /* 7.1.3.3.3 - The universal/local bit of the address is set to 1. */ -+ -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, aucBSSID); -+ } -+ /* 4 <3> Setup Capability - Short Preamble */ -+ if (rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].fgIsShortPreambleOptionImplemented && -+ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ -+ (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))) { -+ prBssInfo->fgIsShortPreambleAllowed = TRUE; -+ prBssInfo->fgUseShortPreamble = TRUE; -+ } else { -+ prBssInfo->fgIsShortPreambleAllowed = FALSE; -+ prBssInfo->fgUseShortPreamble = FALSE; -+ } -+ -+ /* 4 <4> Setup Capability - Short Slot Time */ -+ /* 7.3.1.4 For IBSS, the Short Slot Time subfield shall be set to 0. */ -+ prBssInfo->fgUseShortSlotTime = FALSE; /* Set to FALSE for AdHoc */ -+ -+ /* 4 <5> Compoase Capability */ -+ prBssInfo->u2CapInfo = CAP_INFO_IBSS; -+ -+ if (prBssInfo->fgIsProtection) -+ prBssInfo->u2CapInfo |= CAP_INFO_PRIVACY; -+ -+ if (prBssInfo->fgIsShortPreambleAllowed) -+ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; -+ -+ if (prBssInfo->fgUseShortSlotTime) -+ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; -+ /* 4 <6> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ -+ rateGetLowestRateIndexFromRateSet(prBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex); -+ -+ prBssInfo->ucHwDefaultFixedRateCode = aucRateIndex2RateCode[PREAMBLE_DEFAULT_LONG_NONE][ucLowestBasicRateIndex]; -+ -+} /* end of ibssInitForAdHoc() */ -+ -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+#if CFG_SUPPORT_AAA -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines for BSS(AP) only */ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will initial the BSS_INFO_T for AP Mode. -+* -+* @param[in] prBssInfo Given related BSS_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssInitForAP(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN BOOLEAN fgIsRateUpdate) -+{ -+ UINT_8 ucLowestBasicRateIndex; -+ -+ P_AC_QUE_PARMS_T prACQueParms; -+ -+ ENUM_WMM_ACI_T eAci; -+ -+ UINT_8 auCWminLog2ForBcast[WMM_AC_INDEX_NUM] = { 4 /*BE*/, 4 /*BK*/, 3 /*VO*/, 2 /*VI*/ }; -+ UINT_8 auCWmaxLog2ForBcast[WMM_AC_INDEX_NUM] = { 10, 10, 4, 3 }; -+ UINT_8 auAifsForBcast[WMM_AC_INDEX_NUM] = { 3, 7, 2, 2 }; -+ UINT_8 auTxopForBcast[WMM_AC_INDEX_NUM] = { 0, 0, 94, 47 }; /* If the AP is OFDM */ -+ -+ UINT_8 auCWminLog2[WMM_AC_INDEX_NUM] = { 4 /*BE*/, 4 /*BK*/, 3 /*VO*/, 2 /*VI*/ }; -+ UINT_8 auCWmaxLog2[WMM_AC_INDEX_NUM] = { 7, 10, 4, 3 }; -+ UINT_8 auAifs[WMM_AC_INDEX_NUM] = { 3, 7, 1, 1 }; -+ UINT_8 auTxop[WMM_AC_INDEX_NUM] = { 0, 0, 94, 47 }; /* If the AP is OFDM */ -+ -+ DEBUGFUNC("bssInitForAP"); -+ DBGLOG(BSS, LOUD, "\n"); -+ -+ ASSERT(prBssInfo); -+ ASSERT((prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) || (prBssInfo->eCurrentOPMode == OP_MODE_BOW)); -+ -+#if 0 -+ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = TRUE; -+ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = CONFIG_BW_20M; -+ prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = CONFIG_BW_20M; -+#endif -+ -+ /* 4 <1> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ -+ prBssInfo->ucNonHTBasicPhyType = (UINT_8) -+ rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; -+ prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; -+ -+ prBssInfo->u2OperationalRateSet = rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; -+ -+ if (fgIsRateUpdate) { -+ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, -+ prBssInfo->u2BSSBasicRateSet, -+ prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen); -+ } -+ /* 4 <2> Setup BSSID */ -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssInfo->aucOwnMacAddr); -+ -+ /* 4 <3> Setup Capability - Short Preamble */ -+ if (rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].fgIsShortPreambleOptionImplemented && -+ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ -+ (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))) { -+ prBssInfo->fgIsShortPreambleAllowed = TRUE; -+ prBssInfo->fgUseShortPreamble = TRUE; -+ } else { -+ prBssInfo->fgIsShortPreambleAllowed = FALSE; -+ prBssInfo->fgUseShortPreamble = FALSE; -+ } -+ -+ /* 4 <4> Setup Capability - Short Slot Time */ -+ prBssInfo->fgUseShortSlotTime = TRUE; -+ -+ /* 4 <5> Compoase Capability */ -+ prBssInfo->u2CapInfo = CAP_INFO_ESS; -+ -+ if (prBssInfo->fgIsProtection) -+ prBssInfo->u2CapInfo |= CAP_INFO_PRIVACY; -+ -+ if (prBssInfo->fgIsShortPreambleAllowed) -+ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; -+ -+ if (prBssInfo->fgUseShortSlotTime) -+ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; -+ /* 4 <6> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ -+ rateGetLowestRateIndexFromRateSet(prBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex); -+ -+ prBssInfo->ucHwDefaultFixedRateCode = aucRateIndex2RateCode[PREAMBLE_DEFAULT_LONG_NONE][ucLowestBasicRateIndex]; -+ -+ /* 4 <7> Fill the EDCA */ -+ -+ prACQueParms = prBssInfo->arACQueParmsForBcast; -+ -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ prACQueParms[eAci].fgIsACMSet = FALSE; -+ prACQueParms[eAci].u2Aifsn = auAifsForBcast[eAci]; -+ prACQueParms[eAci].u2CWmin = BIT(auCWminLog2ForBcast[eAci]) - 1; -+ prACQueParms[eAci].u2CWmax = BIT(auCWmaxLog2ForBcast[eAci]) - 1; -+ prACQueParms[eAci].u2TxopLimit = auTxopForBcast[eAci]; -+ -+ prBssInfo->aucCWminLog2ForBcast[eAci] = auCWminLog2ForBcast[eAci]; /* used to send WMM IE */ -+ prBssInfo->aucCWmaxLog2ForBcast[eAci] = auCWmaxLog2ForBcast[eAci]; -+ -+ DBGLOG(BSS, INFO, "Bcast: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", -+ eAci, prACQueParms[eAci].fgIsACMSet, -+ prACQueParms[eAci].u2Aifsn, -+ prACQueParms[eAci].u2CWmin, -+ prACQueParms[eAci].u2CWmax, prACQueParms[eAci].u2TxopLimit); -+ -+ } -+ -+ prACQueParms = prBssInfo->arACQueParms; -+ -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ prACQueParms[eAci].fgIsACMSet = FALSE; -+ prACQueParms[eAci].u2Aifsn = auAifs[eAci]; -+ prACQueParms[eAci].u2CWmin = BIT(auCWminLog2[eAci]) - 1; -+ prACQueParms[eAci].u2CWmax = BIT(auCWmaxLog2[eAci]) - 1; -+ prACQueParms[eAci].u2TxopLimit = auTxop[eAci]; -+ -+ DBGLOG(BSS, INFO, "eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", -+ eAci, prACQueParms[eAci].fgIsACMSet, -+ prACQueParms[eAci].u2Aifsn, -+ prACQueParms[eAci].u2CWmin, -+ prACQueParms[eAci].u2CWmax, prACQueParms[eAci].u2TxopLimit); -+ } -+ -+ /* Note: Caller should update the EDCA setting to HW by nicQmUpdateWmmParms() it there is no AIS network */ -+ /* Note: In E2, only 4 HW queues. The the Edca parameters should be folow by AIS network */ -+ /* Note: In E3, 8 HW queues. the Wmm parameters should be updated to right queues according to BSS */ -+ -+} /* end of bssInitForAP() */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Update DTIM Count -+* -+* @param[in] eNetTypeIndex Specify which network to update -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssUpdateDTIMCount(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ -+ /* Setup DTIM Count for next TBTT. */ -+ if (prBssInfo->ucDTIMCount > 0) { -+ prBssInfo->ucDTIMCount--; -+ } else { -+ -+ ASSERT(prBssInfo->ucDTIMPeriod > 0); -+ -+ prBssInfo->ucDTIMCount = prBssInfo->ucDTIMPeriod - 1; -+ } -+ } -+ -+} /* end of bssUpdateDTIMIE() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to set the Virtual Bitmap in TIM Information Elements -+* -+* @param[in] prBssInfo Pointer to the BSS_INFO_T. -+* @param[in] u2AssocId The association id to set in Virtual Bitmap. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssSetTIMBitmap(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN UINT_16 u2AssocId) -+{ -+ -+ ASSERT(prBssInfo); -+ -+ if (prBssInfo->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; -+ -+ prP2pSpecificBssInfo = &(prAdapter->rWifiVar.rP2pSpecificBssInfo); -+ -+ /* Use Association ID == 0 for BMCAST indication */ -+ if (u2AssocId == 0) { -+ -+ prP2pSpecificBssInfo->ucBitmapCtrl |= (UINT_8) BIT(0); -+ } else { -+ PUINT_8 pucPartialVirtualBitmap; -+ UINT_8 ucBitmapToSet; -+ -+ /* (u2AssocId / 8) */ -+ pucPartialVirtualBitmap = &prP2pSpecificBssInfo->aucPartialVirtualBitmap[(u2AssocId >> 3)]; -+ ucBitmapToSet = (UINT_8) BIT((u2AssocId % 8)); -+ -+ if (*pucPartialVirtualBitmap & ucBitmapToSet) { -+ /* The virtual bitmap has been set */ -+ return; -+ } -+ -+ *pucPartialVirtualBitmap |= ucBitmapToSet; -+ -+ /* Update u2SmallestAID and u2LargestAID */ -+ if ((u2AssocId < prP2pSpecificBssInfo->u2SmallestAID) || -+ (prP2pSpecificBssInfo->u2SmallestAID == 0)) { -+ prP2pSpecificBssInfo->u2SmallestAID = u2AssocId; -+ } -+ -+ if ((u2AssocId > prP2pSpecificBssInfo->u2LargestAID) || -+ (prP2pSpecificBssInfo->u2LargestAID == 0)) { -+ prP2pSpecificBssInfo->u2LargestAID = u2AssocId; -+ } -+ } -+ } -+ -+} /* end of bssSetTIMBitmap() */ -+#endif -+ -+#endif /* CFG_SUPPORT_AAA */ -+ -+VOID bssCreateStaRecFromAuth(IN P_ADAPTER_T prAdapter) -+{ -+ -+} -+ -+VOID bssUpdateStaRecFromAssocReq(IN P_ADAPTER_T prAdapter) -+{ -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c -new file mode 100644 -index 0000000000000..39af02df2af29 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c -@@ -0,0 +1,738 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm.c#2 -+*/ -+ -+/*! \file "cnm.c" -+ \brief Module of Concurrent Network Management -+ -+ Module of Concurrent Network Management -+*/ -+ -+/* -+** Log: cnm.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Fix possible wrong message when P2P is unregistered -+ * -+ * 11 14 2011 yuche.tsai -+ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. -+ * Fix large network type index assert in FW issue. -+ * -+ * 11 10 2011 cm.chang -+ * NULL -+ * Modify debug message for XLOG -+ * -+ * 11 08 2011 cm.chang -+ * NULL -+ * Add RLM and CNM debug message for XLOG -+ * -+ * 11 01 2011 cm.chang -+ * [WCXRP00001077] [All Wi-Fi][Driver] Fix wrong preferred channel for AP and BOW -+ * Only check AIS channel for P2P and BOW -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * Extension channel of some 5G AP will not follow regulation requirement -+ * -+ * 09 30 2011 cm.chang -+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band -+ * . -+ * -+ * 09 01 2011 cm.chang -+ * [WCXRP00000937] [MT6620 Wi-Fi][Driver][FW] cnm.c line #848 assert when doing monkey test -+ * Print message only in Linux platform for monkey testing -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 06 01 2011 cm.chang -+ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function -+ * Limit AIS to fixed channel same with BOW -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 03 10 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Check if P2P network index is Tethering AP -+ * -+ * 03 10 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel -+ * -+ * 02 17 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * When P2P registried, invoke BOW deactivate function -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Provide function to decide if BSS can be activated or not -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 08 2010 cm.chang -+ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID -+ * Remove CNM channel reover message ID -+ * -+ * 10 13 2010 cm.chang -+ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash. -+ * Add exception handle when cmd buffer is not available -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Fix wrong message ID for channel grant to requester -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Modify CNM message handler for new flow -+ * -+ * 06 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Set 20/40M bandwidth of AP HT OP before association process -+ * -+ * 05 31 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling -+ * -+ * 05 21 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support TCP/UDP/IP Checksum offload feature -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add a new function to send abort message -+ * -+ * 04 27 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * BMC mac address shall be ignored in basic config command -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support change of MAC address by host command -+ * -+ * 04 16 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * adding the wpa-none for ibss beacon. -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fix bug for OBSS scan -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 25 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * use the Rx0 dor event indicate. -+ * -+ * 02 08 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support partial part about cmd basic configuration -+ * -+ * Dec 10 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove conditional compiling FPGA_V5 -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add function cnmFsmEventInit() -+ * -+ * Nov 2 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to initialize variables in CNM_INFO_T. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmInit(P_ADAPTER_T prAdapter) -+{ -+ -+} /* end of cnmInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to initialize variables in CNM_INFO_T. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmUninit(P_ADAPTER_T prAdapter) -+{ -+ -+} /* end of cnmUninit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Before handle the message from other module, it need to obtain -+* the Channel privilege from Channel Manager -+* -+* @param[in] prMsgHdr The message need to be handled. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmChMngrRequestPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_CH_REQ_T prMsgChReq; -+ P_CMD_CH_PRIVILEGE_T prCmdBody; -+ WLAN_STATUS rStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prMsgChReq = (P_MSG_CH_REQ_T) prMsgHdr; -+ -+ prCmdBody = (P_CMD_CH_PRIVILEGE_T) -+ cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_CH_PRIVILEGE_T)); -+ ASSERT(prCmdBody); -+ -+ /* To do: exception handle */ -+ if (!prCmdBody) { -+ DBGLOG(CNM, ERROR, "ChReq: fail to get buf (net=%d, token=%d)\n", -+ prMsgChReq->ucNetTypeIndex, prMsgChReq->ucTokenID); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ DBGLOG(CNM, INFO, "ChReq net=%d token=%d b=%d c=%d s=%d\n", -+ prMsgChReq->ucNetTypeIndex, prMsgChReq->ucTokenID, -+ prMsgChReq->eRfBand, prMsgChReq->ucPrimaryChannel, prMsgChReq->eRfSco); -+ -+ prCmdBody->ucNetTypeIndex = prMsgChReq->ucNetTypeIndex; -+ prCmdBody->ucTokenID = prMsgChReq->ucTokenID; -+ prCmdBody->ucAction = CMD_CH_ACTION_REQ; /* Request */ -+ prCmdBody->ucPrimaryChannel = prMsgChReq->ucPrimaryChannel; -+ prCmdBody->ucRfSco = (UINT_8) prMsgChReq->eRfSco; -+ prCmdBody->ucRfBand = (UINT_8) prMsgChReq->eRfBand; -+ prCmdBody->ucReqType = (UINT_8) prMsgChReq->eReqType; -+ prCmdBody->ucReserved = 0; -+ prCmdBody->u4MaxInterval = prMsgChReq->u4MaxInterval; -+ COPY_MAC_ADDR(prCmdBody->aucBSSID, prMsgChReq->aucBSSID); -+ -+ ASSERT(prCmdBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ /* For monkey testing 20110901 */ -+ if (prCmdBody->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) -+ DBGLOG(CNM, ERROR, "CNM: ChReq with wrong netIdx=%d\n\n", prCmdBody->ucNetTypeIndex); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_CH_PRIVILEGE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_CH_PRIVILEGE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdBody, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+ cnmMemFree(prAdapter, prCmdBody); -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* end of cnmChMngrRequestPrivilege() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Before deliver the message to other module, it need to release -+* the Channel privilege to Channel Manager. -+* -+* @param[in] prMsgHdr The message need to be delivered -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmChMngrAbortPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_CH_ABORT_T prMsgChAbort; -+ P_CMD_CH_PRIVILEGE_T prCmdBody; -+ WLAN_STATUS rStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prMsgChAbort = (P_MSG_CH_ABORT_T) prMsgHdr; -+ -+ prCmdBody = (P_CMD_CH_PRIVILEGE_T) -+ cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_CH_PRIVILEGE_T)); -+ ASSERT(prCmdBody); -+ -+ /* To do: exception handle */ -+ if (!prCmdBody) { -+ DBGLOG(CNM, ERROR, "ChAbort: fail to get buf (net=%d, token=%d)\n", -+ prMsgChAbort->ucNetTypeIndex, prMsgChAbort->ucTokenID); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ DBGLOG(CNM, INFO, "ChAbort net=%d token=%d\n", prMsgChAbort->ucNetTypeIndex, prMsgChAbort->ucTokenID); -+ -+ prCmdBody->ucNetTypeIndex = prMsgChAbort->ucNetTypeIndex; -+ prCmdBody->ucTokenID = prMsgChAbort->ucTokenID; -+ prCmdBody->ucAction = CMD_CH_ACTION_ABORT; /* Abort */ -+ -+ ASSERT(prCmdBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ /* For monkey testing 20110901 */ -+ if (prCmdBody->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) -+ DBGLOG(CNM, ERROR, "CNM: ChAbort with wrong netIdx=%d\n\n", prCmdBody->ucNetTypeIndex); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_CH_PRIVILEGE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_CH_PRIVILEGE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdBody, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+ cnmMemFree(prAdapter, prCmdBody); -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* end of cnmChMngrAbortPrivilege() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmChMngrHandleChEvent(P_ADAPTER_T prAdapter, P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_CH_PRIVILEGE_T prEventBody; -+ P_MSG_CH_GRANT_T prChResp; -+ -+ ASSERT(prAdapter); -+ ASSERT(prEvent); -+ -+ prEventBody = (P_EVENT_CH_PRIVILEGE_T) (prEvent->aucBuffer); -+ prChResp = (P_MSG_CH_GRANT_T) -+ cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_GRANT_T)); -+ ASSERT(prChResp); -+ -+ /* To do: exception handle */ -+ if (!prChResp) { -+ DBGLOG(CNM, ERROR, "ChGrant: fail to get buf (net=%d, token=%d)\n", -+ prEventBody->ucNetTypeIndex, prEventBody->ucTokenID); -+ -+ return; -+ } -+ -+ DBGLOG(CNM, INFO, "ChGrant net=%d token=%d ch=%d sco=%d\n", -+ prEventBody->ucNetTypeIndex, prEventBody->ucTokenID, -+ prEventBody->ucPrimaryChannel, prEventBody->ucRfSco); -+ -+ ASSERT(prEventBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ ASSERT(prEventBody->ucStatus == EVENT_CH_STATUS_GRANT); -+ -+ /* Decide message ID based on network and response status */ -+ if (prEventBody->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) -+ prChResp->rMsgHdr.eMsgId = MID_CNM_AIS_CH_GRANT; -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && (prEventBody->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX)) -+ prChResp->rMsgHdr.eMsgId = MID_CNM_P2P_CH_GRANT; -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (prEventBody->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) -+ prChResp->rMsgHdr.eMsgId = MID_CNM_BOW_CH_GRANT; -+#endif -+ else { -+ cnmMemFree(prAdapter, prChResp); -+ return; -+ } -+ -+ prChResp->ucNetTypeIndex = prEventBody->ucNetTypeIndex; -+ prChResp->ucTokenID = prEventBody->ucTokenID; -+ prChResp->ucPrimaryChannel = prEventBody->ucPrimaryChannel; -+ prChResp->eRfSco = (ENUM_CHNL_EXT_T) prEventBody->ucRfSco; -+ prChResp->eRfBand = (ENUM_BAND_T) prEventBody->ucRfBand; -+ prChResp->eReqType = (ENUM_CH_REQ_TYPE_T) prEventBody->ucReqType; -+ prChResp->u4GrantInterval = prEventBody->u4GrantInterval; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prChResp, MSG_SEND_METHOD_BUF); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is invoked for P2P or BOW networks -+* -+* @param (none) -+* -+* @return TRUE: suggest to adopt the returned preferred channel -+* FALSE: No suggestion. Caller should adopt its preference -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+cnmPreferredChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel, P_ENUM_CHNL_EXT_T prBssSCO) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBand); -+ ASSERT(pucPrimaryChannel); -+ ASSERT(prBssSCO); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ -+ if (RLM_NET_PARAM_VALID(prBssInfo)) { -+ *prBand = prBssInfo->eBand; -+ *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ *prBssSCO = prBssInfo->eBssSCO; -+ -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return TRUE: available channel is limited to return value -+* FALSE: no limited -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN cnmAisInfraChannelFixed(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel) -+{ -+#if CFG_ENABLE_WIFI_DIRECT || (CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_LIMIT_AIS_CHNL) -+ P_BSS_INFO_T prBssInfo; -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX) && p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) { -+ -+ ASSERT(prAdapter->fgIsP2PRegistered); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ -+ *prBand = prBssInfo->eBand; -+ *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ -+ return TRUE; -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_LIMIT_AIS_CHNL -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) { -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]; -+ -+ *prBand = prBssInfo->eBand; -+ *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ -+ return TRUE; -+ } -+#endif -+ -+ return FALSE; -+} -+ -+#if CFG_P2P_LEGACY_COEX_REVISE -+BOOLEAN cnmAisDetectP2PChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel) -+{ -+ P_WIFI_VAR_T prWifiVar = &prAdapter->rWifiVar; -+ P_BSS_INFO_T prP2PBssInfo = &prWifiVar->arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+#if CFG_ENABLE_WIFI_DIRECT -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX) && -+ (prP2PBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED || -+ (prP2PBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && prP2PBssInfo->eIntendOPMode == OP_MODE_NUM))) { -+ *prBand = prP2PBssInfo->eBand; -+ *pucPrimaryChannel = prP2PBssInfo->ucPrimaryChannel; -+#if CFG_SUPPORT_MCC -+ if (nicFreq2ChannelNum(prWifiVar->rConnSettings.u4FreqInKHz * 1000) != *pucPrimaryChannel) { -+ DBGLOG(CNM, INFO, "p2p is running on Channel %d, but supplicant try to run as MCC\n", -+ *pucPrimaryChannel); -+ return FALSE; -+ } -+#endif -+ DBGLOG(CNM, INFO, "p2p is running on Channel %d, supplicant try to run as SCC\n", -+ *pucPrimaryChannel); -+ return TRUE; -+ } -+#endif -+ return FALSE; -+} -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmAisInfraConnectNotify(P_ADAPTER_T prAdapter) -+{ -+#if CFG_ENABLE_BT_OVER_WIFI -+ P_BSS_INFO_T prAisBssInfo, prBowBssInfo; -+ -+ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ prBowBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]; -+ -+ if (RLM_NET_PARAM_VALID(prAisBssInfo) && RLM_NET_PARAM_VALID(prBowBssInfo)) { -+ if (prAisBssInfo->eBand != prBowBssInfo->eBand || -+ prAisBssInfo->ucPrimaryChannel != prBowBssInfo->ucPrimaryChannel) { -+ -+ /* Notify BOW to do deactivation */ -+ bowNotifyAllLinkDisconnected(prAdapter); -+ } -+ } -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return TRUE: permitted -+* FALSE: Not permitted -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN cnmAisIbssIsPermitted(P_ADAPTER_T prAdapter) -+{ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) -+ return FALSE; -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) -+ return FALSE; -+#endif -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return TRUE: permitted -+* FALSE: Not permitted -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN cnmP2PIsPermitted(P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ -+ if (IS_BSS_ACTIVE(prBssInfo) && prBssInfo->eCurrentOPMode == OP_MODE_IBSS) -+ return FALSE; -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) { -+ /* Notify BOW to do deactivation */ -+ bowNotifyAllLinkDisconnected(prAdapter); -+ } -+#endif -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return TRUE: permitted -+* FALSE: Not permitted -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN cnmBowIsPermitted(P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ -+ if (IS_BSS_ACTIVE(prBssInfo) && prBssInfo->eCurrentOPMode == OP_MODE_IBSS) -+ return FALSE; -+#if CFG_ENABLE_WIFI_DIRECT -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) -+ return FALSE; -+#endif -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return TRUE: permitted -+* FALSE: Not permitted -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN cnmBss40mBwPermitted(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx) -+{ -+ P_BSS_INFO_T prBssInfo; -+ UINT_8 i; -+ P_BSS_DESC_T prBssDesc = NULL; -+ -+ /* Note: To support real-time decision instead of current activated-time, -+ * the STA roaming case shall be considered about synchronization -+ * problem. Another variable fgAssoc40mBwAllowed is added to -+ * represent HT capability when association -+ */ -+ for (i = 0; i < NETWORK_TYPE_INDEX_NUM; i++) { -+ if (i != (UINT_8) eNetTypeIdx) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[i]; -+ -+ if (IS_BSS_ACTIVE(prBssInfo) && (prBssInfo->fg40mBwAllowed || prBssInfo->fgAssoc40mBwAllowed)) -+ return FALSE; -+ } -+ } -+ -+ if (eNetTypeIdx == NETWORK_TYPE_AIS_INDEX) -+ prBssDesc = prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc; -+ else if ((eNetTypeIdx == NETWORK_TYPE_P2P_INDEX) && (prAdapter->rWifiVar.prP2pFsmInfo)) -+ prBssDesc = prAdapter->rWifiVar.prP2pFsmInfo->prTargetBss; -+ if (prBssDesc) { -+#if (CFG_FORCE_USE_20BW == 1) -+ if (prBssDesc->eBand == BAND_2G4) -+ return FALSE; -+#endif -+ if (prBssDesc->eSco == CHNL_EXT_SCN) -+ return FALSE; -+ } -+ -+ return TRUE; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c -new file mode 100644 -index 0000000000000..05bd0ff35f7ac ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c -@@ -0,0 +1,1236 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm_mem.c#2 -+*/ -+ -+/*! \file "cnm_mem.c" -+ \brief This file contain the management function of packet buffers and -+ generic memory alloc/free functioin for mailbox message. -+ -+ A data packet has a fixed size of buffer, but a management -+ packet can be equipped with a variable size of buffer. -+*/ -+ -+/* -+** Log: cnm_mem.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 03 14 2012 wh.su -+ * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting -+ * Add code from 2.2 -+ * -+ * 11 17 2011 tsaiyuan.hsu -+ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. -+ * initialize fgNeedResp. -+ * -+ * 11 17 2011 tsaiyuan.hsu -+ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. -+ * avoid deactivating staRec when changing state from 3 to 3. -+ * -+ * 02 01 2011 cm.chang -+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode -+ * . -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * Allocate system RAM if fixed message or mgmt buffer is not available -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver -+ * create branch for Wi-Fi driver v1.1 -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 11 29 2010 cm.chang -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC -+ * for initial TX rate selection of auto-rate algorithm -+ * Sync RCPI of STA_REC to FW as reference of initial TX rate -+ * -+ * 11 25 2010 yuche.tsai -+ * NULL -+ * Update SLT Function for QoS Support and not be affected by fixed rate function. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete -+ * and might leads to BSOD when entering RF test with AIS associated -+ * 1. remove redundant variables in STA_REC structure -+ * 2. add STA-REC uninitialization routine for clearing pending events -+ * -+ * 10 13 2010 cm.chang -+ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash. -+ * Add exception handle when cmd buffer is not available -+ * -+ * 10 12 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * add HT (802.11n) fixed rate support. -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 09 24 2010 wh.su -+ * NULL -+ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning. -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD -+ * when entering RF test with AIS associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Change conditional compiling options for BOW -+ * -+ * 09 10 2010 cm.chang -+ * NULL -+ * Always update Beacon content if FW sync OBSS info -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 19 2010 wh.su -+ * NULL -+ * adding the tx pkt call back handle for countermeasure. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 07 07 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support state of STA record change from 1 to 1 -+ * -+ * 07 05 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Fix correct structure size in cnmStaSendDeactivateCmd() -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) ignore RSN checking when RSN is not turned on. -+ * 2) set STA-REC deactivation callback as NULL -+ * 3) add variable initialization API based on PHY configuration -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * spin lock target revised -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change inner loop index from i to k. -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support sync command of STA_REC -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 05 31 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling -+ * -+ * 05 28 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support checking of duplicated buffer free -+ * -+ * 05 28 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * fixed the ad-hoc wpa-none send non-encrypted frame issue. -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Move define of STA_REC_NUM to config.h and rename to CFG_STA_REC_NUM -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 28 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Modified some MQM-related data structures (SN counter, TX/RX BA table) -+ * -+ * 04 27 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Added new TX/RX BA tables in STA_REC -+ * -+ * 04 27 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Notify MQM, TXM, and RXM upon disconnection . -+ * -+ * 04 26 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Call mqm, txm, rxm functions upon disconnection -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support -+ * * * * * * * * * * and will send Null frame to diagnose connection -+ * -+ * 04 09 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * [BORA00000644] WiFi phase 4 integration -+ * * Added per-TID SN cache in STA_REC -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Different invoking order for WTBL entry of associated AP -+ * -+ * 03 29 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * move the wlan table alloc / free to change state function. -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support power control -+ * -+ * 03 03 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Initialize StaRec->arStaWaitQueue -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add debug message when no available pkt buffer -+ * -+ * 03 01 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Fixed STA_REC initialization bug: prStaRec->au2CachedSeqCtrl[k] -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added fgIsWmmSupported in STA_RECORD_T. -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added fgIsUapsdSupported in STA_RECORD_T -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * add support of Driver STA_RECORD_T activation -+ * -+ * 02 13 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added arTspecTable in STA_REC for TSPEC management -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Enable mgmt buffer debug by default -+ * -+ * 02 12 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added BUFFER_SOURCE_BCN -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 08 2010 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * 1) separate wifi_var_emu.c/.h from wifi_var.c/.h -+ * * * * * * * * * 2) eliminate HIF_EMULATION code sections appeared in wifi_var/cnm_mem -+ * * * * * * * * * 3) use cnmMemAlloc() instead to allocate SRAM buffer -+ * -+ * 12 25 2009 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM) -+ * * * * * * * MQM: BA handling -+ * * * * * * * TXM: Macros updates -+ * * * * * * * RXM: Macros/Duplicate Removal updates -+ * -+ * 12 24 2009 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * 12 21 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support several data buffer banks. -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * .For new FPGA memory size -+ * -+ * Dec 9 2009 MTK02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Removed DBGPRINT -+ * -+ * Dec 9 2009 mtk02752 -+ * [BORA00000368] Integrate HIF part into BORA -+ * add cnmDataPktFree() for emulation loopback purpose -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix warning of null pointer -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add cnmGetStaRecByAddress() and add fgIsInUse flag in STA_RECORD_T -+ * -+ * Nov 23 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Assign ucBufferSource in function cnmMgtPktAlloc() -+ * -+ * Nov 23 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Added packet redispatch function calls -+ * -+ * Nov 13 2009 mtk01084 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * enable packet re-usable in current emulation driver -+ * -+ * Nov 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * 1. Add new function cnmGetStaRecByIndex() -+ * 2. Rename STA_REC_T to STA_RECORD_T -+ * -+ * Nov 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Call cnmDataPktDispatch() in cnmPktFree() -+ * -+ * Nov 2 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove definition of pragma section code -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Oct 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix lint warning -+ * -+ * Oct 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix typo -+ * -+ * Oct 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Oct 8 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static VOID cnmStaRecHandleEventPkt(P_ADAPTER_T prAdapter, P_CMD_INFO_T prCmdInfo, PUINT_8 pucEventBuf); -+ -+static VOID cnmStaSendUpdateCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgNeedResp); -+ -+static VOID cnmStaSendRemoveCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T cnmMgtPktAlloc(P_ADAPTER_T prAdapter, UINT_32 u4Length) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ P_QUE_T prQueList; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList; -+ -+ /* Get a free MSDU_INFO_T */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_REMOVE_HEAD(prQueList, prMsduInfo, P_MSDU_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ -+ if (prMsduInfo) { -+ prMsduInfo->prPacket = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length); -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ -+ if (prMsduInfo->prPacket == NULL) { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ prMsduInfo = NULL; -+ } -+ if (prMsduInfo) { -+ prMsduInfo->eCmdType = COMMAND_TYPE_NUM; -+ prMsduInfo->ucCID = 0xff; -+ prMsduInfo->u4InqueTime = 0; -+ prMsduInfo->ucPacketType = TX_PACKET_NUM; -+ } -+ } else { -+ P_QUE_T prTxingQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; -+ P_TX_TCQ_STATUS_T pTc = (P_TX_TCQ_STATUS_T) NULL; -+ -+ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); -+ pTc = &(prAdapter->rTxCtrl.rTc); -+ -+ DBGLOG(MEM, LOUD, "++dump TxPendingMsdu=%u, Tc0=%d Tc1=%d Tc2=%d Tc3=%d, Tc4=%d Tc5=%d\n", -+ prTxingQue->u4NumElem, pTc->aucFreeBufferCount[TC0_INDEX], -+ pTc->aucFreeBufferCount[TC1_INDEX], pTc->aucFreeBufferCount[TC2_INDEX], -+ pTc->aucFreeBufferCount[TC3_INDEX], pTc->aucFreeBufferCount[TC4_INDEX], -+ pTc->aucFreeBufferCount[TC5_INDEX]); -+ -+ prQueueEntry = QUEUE_GET_HEAD(prTxingQue); -+ -+ while (prQueueEntry) { -+ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; -+ -+ DBGLOG(MEM, LOUD, -+ "msdu type=%u, ucid=%u, type=%d, time=%u, seq=%u, sta=%u\n", -+ prMsduInfo->ucPacketType, -+ prMsduInfo->ucCID, -+ prMsduInfo->eCmdType, -+ prMsduInfo->u4InqueTime, prMsduInfo->ucTxSeqNum, prMsduInfo->ucStaRecIndex); -+ prQueueEntry = QUEUE_GET_NEXT_ENTRY(prQueueEntry); -+ } -+ DBGLOG(MEM, LOUD, "--end dump\n"); -+ } -+ -+#if DBG -+ if (prMsduInfo == NULL) { -+ DBGLOG(MEM, WARN, "MgtDesc#=%u\n", prQueList->u4NumElem); -+ -+#if CFG_DBG_MGT_BUF -+ DBGLOG(MEM, WARN, "rMgtBufInfo: alloc#=%u, free#=%u, null#=%u\n", -+ prAdapter->rMgtBufInfo.u4AllocCount, -+ prAdapter->rMgtBufInfo.u4FreeCount, prAdapter->rMgtBufInfo.u4AllocNullCount); -+#endif -+ -+ DBGLOG(MEM, WARN, "\n"); -+ } -+#endif -+ -+ return prMsduInfo; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmMgtPktFree(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_QUE_T prQueList; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList; -+ -+ ASSERT(prMsduInfo->prPacket); -+ if (prMsduInfo->prPacket) { -+ cnmMemFree(prAdapter, prMsduInfo->prPacket); -+ prMsduInfo->prPacket = NULL; -+ } -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ prMsduInfo->fgIsBasicRate = FALSE; -+ QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry) -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to initial the MGMT/MSG memory pool. -+* -+* \param (none) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmMemInit(P_ADAPTER_T prAdapter) -+{ -+ P_BUF_INFO_T prBufInfo; -+ -+ /* Initialize Management buffer pool */ -+ prBufInfo = &prAdapter->rMgtBufInfo; -+ kalMemZero(prBufInfo, sizeof(prAdapter->rMgtBufInfo)); -+ prBufInfo->pucBuf = prAdapter->pucMgtBufCached; -+ -+ /* Setup available memory blocks. 1 indicates FREE */ -+ prBufInfo->rFreeBlocksBitmap = (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1); -+ -+ /* Initialize Message buffer pool */ -+ prBufInfo = &prAdapter->rMsgBufInfo; -+ kalMemZero(prBufInfo, sizeof(prAdapter->rMsgBufInfo)); -+ prBufInfo->pucBuf = &prAdapter->aucMsgBuf[0]; -+ -+ /* Setup available memory blocks. 1 indicates FREE */ -+ prBufInfo->rFreeBlocksBitmap = (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1); -+ -+ return; -+ -+} /* end of cnmMemInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Allocate MGMT/MSG memory pool. -+* -+* \param[in] eRamType Target RAM type. -+* TCM blk_sz= 16bytes, BUF blk_sz= 256bytes -+* \param[in] u4Length Length of the buffer to allocate. -+* -+* \retval !NULL Pointer to the start address of allocated memory. -+* \retval NULL Fail to allocat memory -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 u4MemAllocCnt = 0, u4MemFreeCnt = 0; -+PVOID cnmMemAlloc(IN P_ADAPTER_T prAdapter, IN ENUM_RAM_TYPE_T eRamType, IN UINT_32 u4Length) -+{ -+ P_BUF_INFO_T prBufInfo; -+ BUF_BITMAP rRequiredBitmap; -+ UINT_32 u4BlockNum; -+ UINT_32 i, u4BlkSzInPower; -+ PVOID pvMemory; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(u4Length); -+ -+ u4MemAllocCnt++; -+ -+ if (eRamType == RAM_TYPE_MSG && u4Length <= 256) { -+ prBufInfo = &prAdapter->rMsgBufInfo; -+ u4BlkSzInPower = MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ -+ u4Length += (MSG_BUF_BLOCK_SIZE - 1); -+ u4BlockNum = u4Length >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ -+ ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS); -+ } else { -+ eRamType = RAM_TYPE_BUF; -+ -+ prBufInfo = &prAdapter->rMgtBufInfo; -+ u4BlkSzInPower = MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ -+ u4Length += (MGT_BUF_BLOCK_SIZE - 1); -+ u4BlockNum = u4Length >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ -+ ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS); -+ } -+ -+#if CFG_DBG_MGT_BUF -+ prBufInfo->u4AllocCount++; -+#endif -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+ if ((u4BlockNum > 0) && (u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS)) { -+ -+ /* Convert number of block into bit cluster */ -+ rRequiredBitmap = BITS(0, u4BlockNum - 1); -+ -+ for (i = 0; i <= (MAX_NUM_OF_BUF_BLOCKS - u4BlockNum); i++) { -+ -+ /* Have available memory blocks */ -+ if ((prBufInfo->rFreeBlocksBitmap & rRequiredBitmap) -+ == rRequiredBitmap) { -+ -+ /* Clear corresponding bits of allocated memory blocks */ -+ prBufInfo->rFreeBlocksBitmap &= ~rRequiredBitmap; -+ -+ /* Store how many blocks be allocated */ -+ prBufInfo->aucAllocatedBlockNum[i] = (UINT_8) u4BlockNum; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, -+ eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+ /* Return the start address of allocated memory */ -+ return (PVOID) (prBufInfo->pucBuf + (i << u4BlkSzInPower)); -+ -+ } -+ -+ rRequiredBitmap <<= 1; -+ } -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+ /* cannot move the allocation between spin_lock_irqsave and spin_unlock_irqrestore */ -+#ifdef LINUX -+ pvMemory = (PVOID) kalMemAlloc(u4Length, VIR_MEM_TYPE); -+ if (pvMemory) -+ kalMemZero(pvMemory, u4Length); -+#else -+ pvMemory = (PVOID) NULL; -+#endif -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+#if CFG_DBG_MGT_BUF -+ prBufInfo->u4AllocNullCount++; -+ -+ if (pvMemory) -+ prAdapter->u4MemAllocDynamicCount++; -+#endif -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+ return pvMemory; -+ -+} /* end of cnmMemAlloc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Release memory to MGT/MSG memory pool. -+* -+* \param pucMemory Start address of previous allocated memory -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmMemFree(IN P_ADAPTER_T prAdapter, IN PVOID pvMemory) -+{ -+ P_BUF_INFO_T prBufInfo; -+ UINT_32 u4BlockIndex; -+ BUF_BITMAP rAllocatedBlocksBitmap; -+ ENUM_RAM_TYPE_T eRamType; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvMemory); -+ if (!pvMemory) -+ return; -+ -+ u4MemFreeCnt++; -+ -+ /* Judge it belongs to which RAM type */ -+ if (((ULONG) pvMemory >= (ULONG)&prAdapter->aucMsgBuf[0]) && -+ ((ULONG) pvMemory <= (ULONG)&prAdapter->aucMsgBuf[MSG_BUFFER_SIZE - 1])) { -+ -+ prBufInfo = &prAdapter->rMsgBufInfo; -+ u4BlockIndex = ((ULONG) pvMemory - (ULONG) prBufInfo->pucBuf) -+ >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS); -+ eRamType = RAM_TYPE_MSG; -+ } else if (((ULONG) pvMemory >= (ULONG) prAdapter->pucMgtBufCached) && -+ ((ULONG) pvMemory <= ((ULONG) prAdapter->pucMgtBufCached + MGT_BUFFER_SIZE - 1))) { -+ prBufInfo = &prAdapter->rMgtBufInfo; -+ u4BlockIndex = ((ULONG) pvMemory - (ULONG) prBufInfo->pucBuf) -+ >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS); -+ eRamType = RAM_TYPE_BUF; -+ } else { -+#ifdef LINUX -+ /* For Linux, it is supported because size is not needed */ -+ kalMemFree(pvMemory, VIR_MEM_TYPE, 0); -+#else -+ /* For Windows, it is not supported because of no size argument */ -+ ASSERT(0); -+#endif -+ -+#if CFG_DBG_MGT_BUF -+ prAdapter->u4MemFreeDynamicCount++; -+#endif -+ return; -+ } -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+#if CFG_DBG_MGT_BUF -+ prBufInfo->u4FreeCount++; -+#endif -+ -+ /* Convert number of block into bit cluster */ -+ ASSERT(prBufInfo->aucAllocatedBlockNum[u4BlockIndex] > 0); -+ -+ rAllocatedBlocksBitmap = BITS(0, prBufInfo->aucAllocatedBlockNum[u4BlockIndex] - 1); -+ rAllocatedBlocksBitmap <<= u4BlockIndex; -+ -+ /* Clear saved block count for this memory segment */ -+ prBufInfo->aucAllocatedBlockNum[u4BlockIndex] = 0; -+ -+ /* Set corresponding bit of released memory block */ -+ prBufInfo->rFreeBlocksBitmap |= rAllocatedBlocksBitmap; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+ return; -+ -+} /* end of cnmMemFree() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaRecInit(P_ADAPTER_T prAdapter) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i; -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = &prAdapter->arStaRec[i]; -+ -+ prStaRec->ucIndex = (UINT_8) i; -+ prStaRec->fgIsInUse = FALSE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaRecUninit(IN P_ADAPTER_T prAdapter) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i; -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = &prAdapter->arStaRec[i]; -+ -+ if (prStaRec->fgIsInUse) -+ cnmStaRecFree(prAdapter, prStaRec, FALSE); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+P_STA_RECORD_T cnmStaRecAlloc(P_ADAPTER_T prAdapter, UINT_8 ucNetTypeIndex) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i, k; -+ -+ ASSERT(prAdapter); -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = &prAdapter->arStaRec[i]; -+ -+ if (!prStaRec->fgIsInUse) { -+ /*---- Initialize STA_REC_T here ----*/ -+ kalMemZero(prStaRec, sizeof(STA_RECORD_T)); -+ prStaRec->ucIndex = (UINT_8) i; -+ prStaRec->ucNetTypeIndex = ucNetTypeIndex; -+ prStaRec->fgIsInUse = TRUE; -+ -+ if (prStaRec->pucAssocReqIe) { -+ kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen); -+ prStaRec->pucAssocReqIe = NULL; -+ prStaRec->u2AssocReqIeLen = 0; -+ } -+ -+ /* Initialize the SN caches for duplicate detection */ -+ for (k = 0; k < TID_NUM + 1; k++) -+ prStaRec->au2CachedSeqCtrl[k] = 0xFFFF; -+ -+ /* Initialize SW TX queues in STA_REC */ -+ for (k = 0; k < STA_WAIT_QUEUE_NUM; k++) -+ LINK_INITIALIZE(&prStaRec->arStaWaitQueue[k]); -+ -+ /* Default enable TX/RX AMPDU */ -+ prStaRec->fgTxAmpduEn = TRUE; -+ prStaRec->fgRxAmpduEn = TRUE; -+ -+#if CFG_ENABLE_PER_STA_STATISTICS && CFG_ENABLE_PKT_LIFETIME_PROFILE -+ prStaRec->u4TotalTxPktsNumber = 0; -+ prStaRec->u4TotalTxPktsTime = 0; -+ prStaRec->u4MaxTxPktsTime = 0; -+#endif -+ -+ for (k = 0; k < NUM_OF_PER_STA_TX_QUEUES; k++) -+ QUEUE_INITIALIZE(&prStaRec->arTxQueue[k]); -+ -+ break; -+ } -+ } -+ -+ return (i < CFG_STA_REC_NUM) ? prStaRec : NULL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaRecFree(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgSyncToChip) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ -+ /* To do: free related resources, e.g. timers, buffers, etc */ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ prStaRec->fgTransmitKeyExist = FALSE; -+ prStaRec->fgSetPwrMgtBit = FALSE; -+ -+ if (prStaRec->pucAssocReqIe) { -+ kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen); -+ prStaRec->pucAssocReqIe = NULL; -+ prStaRec->u2AssocReqIeLen = 0; -+ } -+ -+ qmDeactivateStaRec(prAdapter, prStaRec->ucIndex); -+ -+ if (fgSyncToChip) -+ cnmStaSendRemoveCmd(prAdapter, prStaRec); -+ -+ prStaRec->fgIsInUse = FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaFreeAllStaByNetType(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, BOOLEAN fgSyncToChip) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i; -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i]; -+ -+ if (prStaRec->fgIsInUse && prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex) -+ cnmStaRecFree(prAdapter, prStaRec, fgSyncToChip); -+ } /* end of for loop */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+P_STA_RECORD_T cnmGetStaRecByIndex(P_ADAPTER_T prAdapter, UINT_8 ucIndex) -+{ -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ -+ prStaRec = (ucIndex < CFG_STA_REC_NUM) ? &prAdapter->arStaRec[ucIndex] : NULL; -+ -+ if (prStaRec && prStaRec->fgIsInUse == FALSE) -+ prStaRec = NULL; -+ -+ return prStaRec; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Get STA_RECORD_T by Peer MAC Address(Usually TA). -+* -+* @param[in] pucPeerMacAddr Given Peer MAC Address. -+* -+* @retval Pointer to STA_RECORD_T, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_STA_RECORD_T cnmGetStaRecByAddress(P_ADAPTER_T prAdapter, UINT_8 ucNetTypeIndex, PUINT_8 pucPeerMacAddr) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucPeerMacAddr); -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = &prAdapter->arStaRec[i]; -+ -+ if (prStaRec->fgIsInUse && -+ prStaRec->ucNetTypeIndex == ucNetTypeIndex && -+ EQUAL_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMacAddr)) { -+ break; -+ } -+ } -+ -+ return (i < CFG_STA_REC_NUM) ? prStaRec : NULL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Reset the Status and Reason Code Field to 0 of all Station Records for -+* the specified Network Type -+* -+* @param[in] eNetType Specify Network Type -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaRecResetStatus(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ cnmStaFreeAllStaByNetType(prAdapter, eNetTypeIndex, FALSE); -+ -+#if 0 -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i; -+ -+ ASSERT(prAdapter); -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = &prAdapter->arStaRec[i]; -+ -+ if (prStaRec->fgIsInUse) { -+ if ((NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) && IS_STA_IN_AIS(prStaRec->eStaType)) { -+ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ prStaRec->u2ReasonCode = REASON_CODE_RESERVED; -+ prStaRec->ucJoinFailureCount = 0; -+ prStaRec->fgTransmitKeyExist = FALSE; -+ -+ prStaRec->fgSetPwrMgtBit = FALSE; -+ } -+ -+ /* TODO(Kevin): For P2P and BOW */ -+ } -+ } -+ -+ return; -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will change the ucStaState of STA_RECORD_T and also do -+* event indication to HOST to sync the STA_RECORD_T in driver. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] u4NewState New STATE to change. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaRecChangeState(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, UINT_8 ucNewState) -+{ -+ BOOLEAN fgNeedResp; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ ASSERT(prStaRec->fgIsInUse); -+ -+ /* Do nothing when following state transitions happen, -+ * other 6 conditions should be sync to FW, including 1-->1, 3-->3 -+ */ -+ if ((ucNewState == STA_STATE_2 && prStaRec->ucStaState != STA_STATE_3) || -+ (ucNewState == STA_STATE_1 && prStaRec->ucStaState == STA_STATE_2)) { -+ prStaRec->ucStaState = ucNewState; -+ return; -+ } -+ -+ fgNeedResp = FALSE; -+ if (ucNewState == STA_STATE_3) { -+ secFsmEventStart(prAdapter, prStaRec); -+ if (ucNewState != prStaRec->ucStaState) -+ fgNeedResp = TRUE; -+ } else { -+ if (ucNewState != prStaRec->ucStaState && prStaRec->ucStaState == STA_STATE_3) -+ qmDeactivateStaRec(prAdapter, prStaRec->ucIndex); -+ fgNeedResp = FALSE; -+ } -+ prStaRec->ucStaState = ucNewState; -+ -+ cnmStaSendUpdateCmd(prAdapter, prStaRec, fgNeedResp); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* To do: Confirm if it is invoked here or other location, but it should -+ * be invoked after state sync of STA_REC -+ * Update system operation parameters for AP mode -+ */ -+ if (prAdapter->fgIsP2PRegistered && (IS_STA_IN_P2P(prStaRec))) { -+ P_BSS_INFO_T prBssInfo; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) -+ rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE); -+ } -+#endif -+} -+ -+P_STA_RECORD_T -+cnmStaTheTypeGet(P_ADAPTER_T prAdapter, -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ENUM_STA_TYPE_T eStaType, UINT32 *pu4StartIdx) -+{ -+ P_STA_RECORD_T prStaRec = NULL; -+ UINT_16 i; -+ -+ for (i = *pu4StartIdx; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i]; -+ -+ if (prStaRec->fgIsInUse && -+ prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex && prStaRec->eStaType == eStaType) { -+ i++; -+ break; -+ } -+ -+ prStaRec = NULL; /* reset */ -+ } /* end of for loop */ -+ -+ *pu4StartIdx = i; -+ return prStaRec; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID cnmStaRecHandleEventPkt(P_ADAPTER_T prAdapter, P_CMD_INFO_T prCmdInfo, PUINT_8 pucEventBuf) -+{ -+ P_EVENT_ACTIVATE_STA_REC_T prEventContent; -+ P_STA_RECORD_T prStaRec; -+ -+ prEventContent = (P_EVENT_ACTIVATE_STA_REC_T) pucEventBuf; -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prEventContent->ucStaRecIdx); -+ -+ if (prStaRec && prStaRec->ucStaState == STA_STATE_3 && -+ !kalMemCmp(&prStaRec->aucMacAddr[0], &prEventContent->aucMacAddr[0], MAC_ADDR_LEN)) { -+ -+ qmActivateStaRec(prAdapter, prStaRec); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID cnmStaSendUpdateCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgNeedResp) -+{ -+ P_CMD_UPDATE_STA_RECORD_T prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ ASSERT(prStaRec->fgIsInUse); -+ -+ /* To do: come out a mechanism to limit one STA_REC sync once for AP mode -+ * to avoid buffer empty case when many STAs are associated -+ * simultaneously. -+ */ -+ -+ /* To do: how to avoid 2 times of allocated memory. Use Stack? -+ * One is here, the other is in wlanSendQueryCmd() -+ */ -+ prCmdContent = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_UPDATE_STA_RECORD_T)); -+ ASSERT(prCmdContent); -+ -+ /* To do: exception handle */ -+ if (!prCmdContent) -+ return; -+ -+ prCmdContent->ucIndex = prStaRec->ucIndex; -+ prCmdContent->ucStaType = (UINT_8) prStaRec->eStaType; -+ kalMemCopy(&prCmdContent->aucMacAddr[0], &prStaRec->aucMacAddr[0], MAC_ADDR_LEN); -+ prCmdContent->u2AssocId = prStaRec->u2AssocId; -+ prCmdContent->u2ListenInterval = prStaRec->u2ListenInterval; -+ prCmdContent->ucNetTypeIndex = prStaRec->ucNetTypeIndex; -+ -+ prCmdContent->ucDesiredPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; -+ prCmdContent->u2DesiredNonHTRateSet = prStaRec->u2DesiredNonHTRateSet; -+ prCmdContent->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; -+ prCmdContent->ucMcsSet = prStaRec->ucMcsSet; -+ prCmdContent->ucSupMcs32 = (UINT_8) prStaRec->fgSupMcs32; -+ prCmdContent->u2HtCapInfo = prStaRec->u2HtCapInfo; -+ prCmdContent->ucNeedResp = (UINT_8) fgNeedResp; -+ -+#if !CFG_SLT_SUPPORT -+ if (prAdapter->rWifiVar.eRateSetting != FIXED_RATE_NONE) { -+ /* override rate configuration */ -+ nicUpdateRateParams(prAdapter, -+ prAdapter->rWifiVar.eRateSetting, -+ &(prCmdContent->ucDesiredPhyTypeSet), -+ &(prCmdContent->u2DesiredNonHTRateSet), -+ &(prCmdContent->u2BSSBasicRateSet), -+ &(prCmdContent->ucMcsSet), -+ &(prCmdContent->ucSupMcs32), &(prCmdContent->u2HtCapInfo)); -+ } -+#endif -+ -+ prCmdContent->ucIsQoS = prStaRec->fgIsQoS; -+ prCmdContent->ucIsUapsdSupported = prStaRec->fgIsUapsdSupported; -+ prCmdContent->ucStaState = prStaRec->ucStaState; -+ -+ prCmdContent->ucAmpduParam = prStaRec->ucAmpduParam; -+ prCmdContent->u2HtExtendedCap = prStaRec->u2HtExtendedCap; -+ prCmdContent->u4TxBeamformingCap = prStaRec->u4TxBeamformingCap; -+ prCmdContent->ucAselCap = prStaRec->ucAselCap; -+ prCmdContent->ucRCPI = prStaRec->ucRCPI; -+ -+ prCmdContent->ucUapsdAc = prStaRec->ucBmpTriggerAC | (prStaRec->ucBmpDeliveryAC << 4); -+ prCmdContent->ucUapsdSp = prStaRec->ucUapsdSp; -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_UPDATE_STA_RECORD, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ fgNeedResp, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ fgNeedResp ? cnmStaRecHandleEventPkt : NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_UPDATE_STA_RECORD_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+ cnmMemFree(prAdapter, prCmdContent); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID cnmStaSendRemoveCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec) -+{ -+ CMD_REMOVE_STA_RECORD_T rCmdContent; -+ WLAN_STATUS rStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ -+ rCmdContent.ucIndex = prStaRec->ucIndex; -+ kalMemCopy(&rCmdContent.aucMacAddr[0], &prStaRec->aucMacAddr[0], MAC_ADDR_LEN); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_REMOVE_STA_RECORD, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_REMOVE_STA_RECORD_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) &rCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c -new file mode 100644 -index 0000000000000..8cc9ef9078fe4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c -@@ -0,0 +1,482 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm_timer.c#1 -+*/ -+ -+/*! \file "cnm_timer.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: cnm_timer.c -+ * -+ * 12 13 2011 cm.chang -+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer -+ * Add wake lock if timer timeout value is smaller than 5 seconds -+ * -+ * 02 24 2011 cp.wu -+ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation -+ * because NdisMSleep() won't sleep long enough for specified interval such as 500ms -+ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 05 28 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support sleep notification to host -+ * -+ * 05 19 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add some checking assertions -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Return timer token back to COS when entering wait off state -+ * -+ * 01 11 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Remove compiling warning -+ * -+ * 01 08 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support longer timeout interval to 45 days from 65secu1rwduu`wvpghlqg|fh+fmdkb -+ * -+ * 01 06 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fix system time is 32KHz instead of 1ms -+ * -+ * 01 04 2010 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * For working out the first connection Chariot-verified version -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Place rRootTimer.rNextExpiredSysTime = rExpiredSysTime; before set timer -+ * -+ * Oct 30 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * In cnmTimerInitialize(), just stop timer if it was already created. -+ * -+ * Oct 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Move the external reference for Lint to precomp.h -+ * -+ * Oct 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix lint warning -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the time to do the time out check. -+* -+* \param[in] rTimeout Time out interval from current time. -+* -+* \retval TRUE Success. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static BOOLEAN cnmTimerSetTimer(IN P_ADAPTER_T prAdapter, IN OS_SYSTIME rTimeout) -+{ -+ P_ROOT_TIMER prRootTimer; -+ BOOLEAN fgNeedWakeLock; -+ -+ ASSERT(prAdapter); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ -+ kalSetTimer(prAdapter->prGlueInfo, rTimeout); -+ -+ if (rTimeout <= SEC_TO_SYSTIME(WAKE_LOCK_MAX_TIME)) { -+ fgNeedWakeLock = TRUE; -+ -+ if (!prRootTimer->fgWakeLocked) { -+ KAL_WAKE_LOCK(prAdapter, &prRootTimer->rWakeLock); -+ prRootTimer->fgWakeLocked = TRUE; -+ } -+ } else { -+ fgNeedWakeLock = FALSE; -+ } -+ -+ return fgNeedWakeLock; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to initialize a root timer. -+* -+* \param[in] prAdapter -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerInitialize(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROOT_TIMER prRootTimer; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ -+ /* Note: glue layer have configured timer */ -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ LINK_INITIALIZE(&prRootTimer->rLinkHead); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+ KAL_WAKE_LOCK_INIT(prAdapter, &prRootTimer->rWakeLock, "WLAN Timer"); -+ prRootTimer->fgWakeLocked = FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to destroy a root timer. -+* When WIFI is off, the token shall be returned back to system. -+* -+* \param[in] -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerDestroy(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROOT_TIMER prRootTimer; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ -+ if (prRootTimer->fgWakeLocked) { -+ KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock); -+ prRootTimer->fgWakeLocked = FALSE; -+ } -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prRootTimer->rWakeLock); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ LINK_INITIALIZE(&prRootTimer->rLinkHead); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+ /* Note: glue layer will be responsible for timer destruction */ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to initialize a timer. -+* -+* \param[in] prTimer Pointer to a timer structure. -+* \param[in] pfnFunc Pointer to the call back function. -+* \param[in] u4Data Parameter for call back function. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerInitTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN PFN_MGMT_TIMEOUT_FUNC pfFunc, IN ULONG ulData) -+{ -+ ASSERT(prAdapter); -+ -+ ASSERT(prTimer); -+ -+#if DBG -+ /* Note: NULL function pointer is permitted for HEM POWER */ -+ if (pfFunc == NULL) -+ DBGLOG(CNM, WARN, "Init timer with NULL callback function!\n"); -+#endif -+ -+#if DBG -+ ASSERT(prAdapter->rRootTimer.rLinkHead.prNext); -+ { -+ P_LINK_T prTimerList; -+ P_LINK_ENTRY_T prLinkEntry; -+ P_TIMER_T prPendingTimer; -+ -+ prTimerList = &(prAdapter->rRootTimer.rLinkHead); -+ -+ LINK_FOR_EACH(prLinkEntry, prTimerList) { -+ prPendingTimer = LINK_ENTRY(prLinkEntry, TIMER_T, rLinkEntry); -+ ASSERT(prPendingTimer); -+ ASSERT(prPendingTimer != prTimer); -+ } -+ } -+#endif -+ -+ LINK_ENTRY_INITIALIZE(&prTimer->rLinkEntry); -+ -+ prTimer->pfMgmtTimeOutFunc = pfFunc; -+ prTimer->ulData = ulData; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to stop a timer. -+* -+* \param[in] prTimer Pointer to a timer structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID cnmTimerStopTimer_impl(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN BOOLEAN fgAcquireSpinlock) -+{ -+ P_ROOT_TIMER prRootTimer; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prTimer); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ -+ if (fgAcquireSpinlock) -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+ if (timerPendingTimer(prTimer)) { -+ LINK_REMOVE_KNOWN_ENTRY(&prRootTimer->rLinkHead, &prTimer->rLinkEntry); -+ -+ /* Reduce dummy timeout for power saving, especially HIF activity. -+ * If two or more timers exist and being removed timer is smallest, -+ * this dummy timeout will still happen, but it is OK. -+ */ -+ if (LINK_IS_EMPTY(&prRootTimer->rLinkHead)) { -+ kalCancelTimer(prAdapter->prGlueInfo); -+ -+ if (fgAcquireSpinlock && prRootTimer->fgWakeLocked) { -+ KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock); -+ prRootTimer->fgWakeLocked = FALSE; -+ } -+ } -+ } -+ -+ if (fgAcquireSpinlock) -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to stop a timer. -+* -+* \param[in] prTimer Pointer to a timer structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerStopTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prTimer); -+ -+ cnmTimerStopTimer_impl(prAdapter, prTimer, TRUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to start a timer with wake_lock. -+* -+* \param[in] prTimer Pointer to a timer structure. -+* \param[in] u4TimeoutMs Timeout to issue the timer and call back function -+* (unit: ms). -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerStartTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN UINT_32 u4TimeoutMs) -+{ -+ P_ROOT_TIMER prRootTimer; -+ P_LINK_T prTimerList; -+ OS_SYSTIME rExpiredSysTime, rTimeoutSystime; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prTimer); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ prTimerList = &prRootTimer->rLinkHead; -+ -+ /* If timeout interval is larger than 1 minute, the mod value is set -+ * to the timeout value first, then per minutue. -+ */ -+ if (u4TimeoutMs > MSEC_PER_MIN) { -+ ASSERT(u4TimeoutMs <= ((UINT_32) 0xFFFF * MSEC_PER_MIN)); -+ -+ prTimer->u2Minutes = (UINT_16) (u4TimeoutMs / MSEC_PER_MIN); -+ u4TimeoutMs -= (prTimer->u2Minutes * MSEC_PER_MIN); -+ if (u4TimeoutMs == 0) { -+ u4TimeoutMs = MSEC_PER_MIN; -+ prTimer->u2Minutes--; -+ } -+ } else { -+ prTimer->u2Minutes = 0; -+ } -+ -+ /* The assertion check if MSEC_TO_SYSTIME() may be overflow. */ -+ ASSERT(u4TimeoutMs < (((UINT_32) 0x80000000 - MSEC_PER_SEC) / KAL_HZ)); -+ rTimeoutSystime = MSEC_TO_SYSTIME(u4TimeoutMs); -+ rExpiredSysTime = kalGetTimeTick() + rTimeoutSystime; -+ -+ /* If no timer pending or the fast time interval is used. */ -+ if (LINK_IS_EMPTY(prTimerList) || TIME_BEFORE(rExpiredSysTime, prRootTimer->rNextExpiredSysTime)) { -+ -+ prRootTimer->rNextExpiredSysTime = rExpiredSysTime; -+ cnmTimerSetTimer(prAdapter, rTimeoutSystime); -+ } -+ -+ /* Add this timer to checking list */ -+ prTimer->rExpiredSysTime = rExpiredSysTime; -+ -+ if (!timerPendingTimer(prTimer)) -+ LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry); -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to check the timer list. -+* -+* \param[in] -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerDoTimeOutCheck(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROOT_TIMER prRootTimer; -+ P_LINK_T prTimerList; -+ P_LINK_ENTRY_T prLinkEntry; -+ P_TIMER_T prTimer; -+ OS_SYSTIME rCurSysTime; -+ PFN_MGMT_TIMEOUT_FUNC pfMgmtTimeOutFunc; -+ ULONG ulTimeoutData; -+ BOOLEAN fgNeedWakeLock; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ /* acquire spin lock */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ prTimerList = &prRootTimer->rLinkHead; -+ -+ rCurSysTime = kalGetTimeTick(); -+ -+ /* Set the permitted max timeout value for new one */ -+ prRootTimer->rNextExpiredSysTime = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL; -+ -+ LINK_FOR_EACH(prLinkEntry, prTimerList) { -+ prTimer = LINK_ENTRY(prLinkEntry, TIMER_T, rLinkEntry); -+ ASSERT(prTimer); -+ -+ /* Check if this entry is timeout. */ -+ if (!TIME_BEFORE(rCurSysTime, prTimer->rExpiredSysTime)) { -+ cnmTimerStopTimer_impl(prAdapter, prTimer, FALSE); -+ -+ pfMgmtTimeOutFunc = prTimer->pfMgmtTimeOutFunc; -+ ulTimeoutData = prTimer->ulData; -+ -+ if (prTimer->u2Minutes > 0) { -+ prTimer->u2Minutes--; -+ prTimer->rExpiredSysTime = rCurSysTime + MSEC_TO_SYSTIME(MSEC_PER_MIN); -+ LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry); -+ } else if (pfMgmtTimeOutFunc) { -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ (pfMgmtTimeOutFunc) (prAdapter, ulTimeoutData); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ } -+ -+ /* Search entire list again because of nest del and add timers -+ * and current MGMT_TIMER could be volatile after stopped -+ */ -+ prLinkEntry = (P_LINK_ENTRY_T) prTimerList; -+ -+ prRootTimer->rNextExpiredSysTime = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL; -+ } else if (TIME_BEFORE(prTimer->rExpiredSysTime, prRootTimer->rNextExpiredSysTime)) { -+ prRootTimer->rNextExpiredSysTime = prTimer->rExpiredSysTime; -+ } -+ } /* end of for loop */ -+ -+ /* Setup the prNext timeout event. It is possible the timer was already -+ * set in the above timeout callback function. -+ */ -+ fgNeedWakeLock = FALSE; -+ if (!LINK_IS_EMPTY(prTimerList)) { -+ ASSERT(TIME_AFTER(prRootTimer->rNextExpiredSysTime, rCurSysTime)); -+ -+ fgNeedWakeLock = cnmTimerSetTimer(prAdapter, (OS_SYSTIME) -+ ((INT_32) prRootTimer->rNextExpiredSysTime - (INT_32) rCurSysTime)); -+ } -+ -+ if (prRootTimer->fgWakeLocked && !fgNeedWakeLock) { -+ KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock); -+ prRootTimer->fgWakeLocked = FALSE; -+ } -+ -+ /* release spin lock */ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c -new file mode 100644 -index 0000000000000..c7a23eb018b63 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c -@@ -0,0 +1,816 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/hem_mbox.c#3 -+*/ -+ -+/*! \file "hem_mbox.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: hem_mbox.c -+** -+** 08 31 2012 yuche.tsai -+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device -+** have connected to AP previously,one device reboots automatically with KE -+** Fix possible KE when concurrent & disconnect. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 05 03 2012 cp.wu -+ * [WCXRP00001231] [MT6620 Wi-Fi][MT5931][Driver] Correct SCAN_V2 related debugging facilities within hem_mbox.c -+ * correct for debug message string table by adding missed scan_v2 related definitions. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 17 2012 yuche.tsai -+ * NULL -+ * Update mgmt frame filter setting. -+ * Please also update FW 2.1 -+ * -+ * 01 13 2012 yuche.tsai -+ * NULL -+ * WiFi Hot Spot Tethering for ICS ALPHA testing version. -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Add exception handle for NULL function pointer of mailbox message -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search -+ * for more than one SSID in a single scanning request -+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID support -+ * as well as uProbeDelay in NDIS 6.x driver model -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000696] [Volunteer Patch][MT6620][Driver] Infinite loop issue when RX invitation response. -+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Add invitation support. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 29 2011 cm.chang -+ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning -+ * As CR title -+ * -+ * 02 24 2011 cp.wu -+ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation -+ * because NdisMSleep() won't sleep long enough for specified interval such as 500ms -+ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions -+ * -+ * 02 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update bowString and channel grant. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * Allocate system RAM if fixed message or mgmt buffer is not available -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix Compile Error when DBG is disabled. -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 12 08 2010 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support concurrent networks. -+ * -+ * 11 08 2010 cm.chang -+ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID -+ * Remove CNM channel reover message ID -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * update the frog's new p2p state machine. -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Remove unused message ID -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add P2P Connection Abort Event Message handler. -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 yarco.yang -+ * NULL -+ * Fixed Driver ASSERT at mboxInitMsgMap() -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update for MID_SCN_BOW_SCAN_DONE mboxDummy. -+ * Update saa_fsm for BOW. -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Add CFG_ENABLE_BT_OVER_WIFI. -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add interface for RLM to trigger OBSS-SCAN. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add debug message for newly add P2P message. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add some function entry for P2P FSM under provisioning phase.. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add some events to P2P Module. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Add message box event for P2P device switch on & device discovery. -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * remove unused mailbox message definitions. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * message table should not be commented out by compilation option without modifying header file -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Add wifi direct scan done callback. -+ * -+ * 07 09 2010 cp.wu -+ * -+ * change handler of MID_MNY_CNM_CONNECTION_ABORT from NULL to mboxDummy. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Modify CNM message handler for new flow -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable currently migrated message call-backs. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * restore utility function invoking via hem_mbox to direct calls -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * hem_mbox is migrated. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Fix file merge error -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 29 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed MID_RXM_MQM_QOS_ACTION_FRAME -+ * -+ * 04 29 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed MID_RXM_MQM_BA_ACTION_FRAME -+ * -+ * 04 27 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * MID_RXM_MQM_BA_ACTION_FRAME -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 03 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Develop partial DPD code -+ * -+ * 02 11 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Updated arMsgMapTable for MID_RXM_MQM_QOS_ACTION_FRAME -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * Dec 9 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add hemRunEventScanDone() to arMsgMapTable[] -+ * -+ * Dec 4 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix mboxDummy() didn't free prMsgHdr -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add saaAisJoinComplete event handler -+ * -+ * Dec 2 2009 MTK02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Fixed the handler function name in arMsgMapTable for MID_RXM_MQM_BA_ACTION_FRAME -+ * -+ * Dec 2 2009 MTK02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Added MID_RXM_MQM_BA_ACTION_FRAME to MsgMapTable -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise MSG Handler (remove dummy and add for SAA) -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add aisFsmRunEventAbort() event handler -+ * -+ * Nov 11 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix typo -+ * -+ * Nov 10 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add more MSG_HNDL_ENTRY_T to avoid ASSERT() in mboxInitMsgMap() -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add SCN message and function entry to arMsgMapTable[] -+ * -+ * Nov 2 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix sorting algorithm in mboxInitMsgMap() -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugMsg[] = { -+ (PUINT_8) DISP_STRING("MID_MNY_CNM_CH_REQ"), -+ (PUINT_8) DISP_STRING("MID_MNY_CNM_CH_ABORT"), -+ (PUINT_8) DISP_STRING("MID_CNM_AIS_CH_GRANT"), -+ (PUINT_8) DISP_STRING("MID_CNM_P2P_CH_GRANT"), -+ (PUINT_8) DISP_STRING("MID_CNM_BOW_CH_GRANT"), -+ -+ (PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_REQ"), -+ (PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_REQ_V2"), -+ (PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_CANCEL"), -+ (PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_REQ"), -+ (PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_REQ_V2"), -+ (PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_CANCEL"), -+ (PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_REQ"), -+ (PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_REQ_V2"), -+ (PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_CANCEL"), -+ (PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_REQ"), -+ (PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_REQ_V2"), -+ (PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_CANCEL"), -+ (PUINT_8) DISP_STRING("MID_SCN_AIS_SCAN_DONE"), -+ (PUINT_8) DISP_STRING("MID_SCN_P2P_SCAN_DONE"), -+ (PUINT_8) DISP_STRING("MID_SCN_BOW_SCAN_DONE"), -+ (PUINT_8) DISP_STRING("MID_SCN_RLM_SCAN_DONE"), -+ -+ (PUINT_8) DISP_STRING("MID_OID_AIS_FSM_JOIN_REQ"), -+ (PUINT_8) DISP_STRING("MID_OID_AIS_FSM_ABORT"), -+ (PUINT_8) DISP_STRING("MID_AIS_SAA_FSM_START"), -+ (PUINT_8) DISP_STRING("MID_AIS_SAA_FSM_ABORT"), -+ (PUINT_8) DISP_STRING("MID_SAA_AIS_JOIN_COMPLETE"), -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ (PUINT_8) DISP_STRING("MID_BOW_SAA_FSM_START"), -+ (PUINT_8) DISP_STRING("MID_BOW_SAA_FSM_ABORT"), -+ (PUINT_8) DISP_STRING("MID_SAA_BOW_JOIN_COMPLETE"), -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ (PUINT_8) DISP_STRING("MID_P2P_SAA_FSM_START"), -+ (PUINT_8) DISP_STRING("MID_P2P_SAA_FSM_ABORT"), -+ (PUINT_8) DISP_STRING("MID_SAA_P2P_JOIN_COMPLETE"), -+ -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_FUN_SWITCH"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_DEVICE_DISCOVERY"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_CONNECTION_REQ"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_CONNECTION_ABORT"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_BEACON_UPDATE"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_STOP_AP"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_CHNL_REQ"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_CHNL_ABORT"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_MGMT_TX"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_GROUP_DISSOLVE"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_MGMT_FRAME_REGISTER"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_NET_DEV_REGISTER"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_START_AP"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_UPDATE_IE_BUF"), -+#endif -+ -+#if CFG_SUPPORT_ADHOC -+ /* (PUINT_8)DISP_STRING("MID_AIS_CNM_CREATE_IBSS_REQ"), */ -+ /* (PUINT_8)DISP_STRING("MID_CNM_AIS_CREATE_IBSS_GRANT"), */ -+ /* (PUINT_8)DISP_STRING("MID_AIS_CNM_MERGE_IBSS_REQ"), */ -+ /* (PUINT_8)DISP_STRING("MID_CNM_AIS_MERGE_IBSS_GRANT"), */ -+ (PUINT_8) DISP_STRING("MID_SCN_AIS_FOUND_IBSS"), -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ (PUINT_8) DISP_STRING("MID_SAA_AIS_FSM_ABORT"), -+ (PUINT_8) DISP_STRING("MID_MNY_AIS_REMAIN_ON_CHANNEL"), -+ (PUINT_8) DISP_STRING("MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL"), -+ (PUINT_8) DISP_STRING("MID_MNY_AIS_MGMT_TX") -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+/* This message entry will be re-ordered based on the message ID order -+ * by invoking mboxInitMsgMap() -+ */ -+static MSG_HNDL_ENTRY_T arMsgMapTable[] = { -+ {MID_MNY_CNM_CH_REQ, cnmChMngrRequestPrivilege}, -+ {MID_MNY_CNM_CH_ABORT, cnmChMngrAbortPrivilege}, -+ {MID_CNM_AIS_CH_GRANT, aisFsmRunEventChGrant}, -+#if CFG_ENABLE_WIFI_DIRECT -+ {MID_CNM_P2P_CH_GRANT, p2pFsmRunEventChGrant}, /*set in gl_p2p_init.c */ -+#else -+ {MID_CNM_P2P_CH_GRANT, mboxDummy}, -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ {MID_CNM_BOW_CH_GRANT, bowRunEventChGrant}, -+#else -+ {MID_CNM_BOW_CH_GRANT, mboxDummy}, -+#endif -+ -+ /*--------------------------------------------------*/ -+ /* SCN Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ {MID_AIS_SCN_SCAN_REQ, scnFsmMsgStart}, -+ {MID_AIS_SCN_SCAN_REQ_V2, scnFsmMsgStart}, -+ {MID_AIS_SCN_SCAN_CANCEL, scnFsmMsgAbort}, -+ {MID_P2P_SCN_SCAN_REQ, scnFsmMsgStart}, -+ {MID_P2P_SCN_SCAN_REQ_V2, scnFsmMsgStart}, -+ {MID_P2P_SCN_SCAN_CANCEL, scnFsmMsgAbort}, -+ {MID_BOW_SCN_SCAN_REQ, scnFsmMsgStart}, -+ {MID_BOW_SCN_SCAN_REQ_V2, scnFsmMsgStart}, -+ {MID_BOW_SCN_SCAN_CANCEL, scnFsmMsgAbort}, -+ {MID_RLM_SCN_SCAN_REQ, scnFsmMsgStart}, -+ {MID_RLM_SCN_SCAN_REQ_V2, scnFsmMsgStart}, -+ {MID_RLM_SCN_SCAN_CANCEL, scnFsmMsgAbort}, -+ {MID_SCN_AIS_SCAN_DONE, aisFsmRunEventScanDone}, -+#if CFG_ENABLE_WIFI_DIRECT -+ {MID_SCN_P2P_SCAN_DONE, p2pFsmRunEventScanDone}, /*set in gl_p2p_init.c */ -+#else -+ {MID_SCN_P2P_SCAN_DONE, mboxDummy}, -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ {MID_SCN_BOW_SCAN_DONE, bowResponderScanDone}, -+#else -+ {MID_SCN_BOW_SCAN_DONE, mboxDummy}, -+#endif -+ {MID_SCN_RLM_SCAN_DONE, rlmObssScanDone}, -+ -+ /*--------------------------------------------------*/ -+ /* AIS Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ {MID_OID_AIS_FSM_JOIN_REQ, aisFsmRunEventAbort}, -+ {MID_OID_AIS_FSM_ABORT, aisFsmRunEventAbort}, -+ {MID_AIS_SAA_FSM_START, saaFsmRunEventStart}, -+ {MID_AIS_SAA_FSM_ABORT, saaFsmRunEventAbort}, -+ {MID_SAA_AIS_JOIN_COMPLETE, aisFsmRunEventJoinComplete}, -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ /*--------------------------------------------------*/ -+ /* BOW Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ {MID_BOW_SAA_FSM_START, saaFsmRunEventStart}, -+ {MID_BOW_SAA_FSM_ABORT, saaFsmRunEventAbort}, -+ {MID_SAA_BOW_JOIN_COMPLETE, bowFsmRunEventJoinComplete}, -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT /*set in gl_p2p_init.c */ -+ {MID_P2P_SAA_FSM_START, saaFsmRunEventStart}, -+ {MID_P2P_SAA_FSM_ABORT, saaFsmRunEventAbort}, -+ {MID_SAA_P2P_JOIN_COMPLETE, p2pFsmRunEventJoinComplete}, /* TODO: p2pFsmRunEventJoinComplete */ -+ -+ {MID_MNY_P2P_FUN_SWITCH, p2pFsmRunEventSwitchOPMode}, -+ {MID_MNY_P2P_DEVICE_DISCOVERY, p2pFsmRunEventScanRequest}, -+ {MID_MNY_P2P_CONNECTION_REQ, p2pFsmRunEventConnectionRequest}, -+ {MID_MNY_P2P_CONNECTION_ABORT, p2pFsmRunEventConnectionAbort}, -+ {MID_MNY_P2P_BEACON_UPDATE, p2pFsmRunEventBeaconUpdate}, -+ {MID_MNY_P2P_STOP_AP, p2pFsmRunEventStopAP}, -+ {MID_MNY_P2P_CHNL_REQ, p2pFsmRunEventChannelRequest}, -+ {MID_MNY_P2P_CHNL_ABORT, p2pFsmRunEventChannelAbort}, -+ {MID_MNY_P2P_MGMT_TX, p2pFsmRunEventMgmtFrameTx}, -+ {MID_MNY_P2P_GROUP_DISSOLVE, p2pFsmRunEventDissolve}, -+ {MID_MNY_P2P_MGMT_FRAME_REGISTER, p2pFsmRunEventMgmtFrameRegister}, -+ {MID_MNY_P2P_NET_DEV_REGISTER, p2pFsmRunEventNetDeviceRegister}, -+ {MID_MNY_P2P_START_AP, p2pFsmRunEventStartAP}, -+ {MID_MNY_P2P_MGMT_FRAME_UPDATE, p2pFsmRunEventUpdateMgmtFrame}, -+ {MID_MNY_P2P_EXTEND_LISTEN_INTERVAL, p2pFsmRunEventExtendListen}, -+#if CFG_SUPPORT_WFD -+ {MID_MNY_P2P_WFD_CFG_UPDATE, p2pFsmRunEventWfdSettingUpdate}, -+#endif -+ -+#endif -+ -+#if CFG_SUPPORT_ADHOC -+ {MID_SCN_AIS_FOUND_IBSS, aisFsmRunEventFoundIBSSPeer}, -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ {MID_SAA_AIS_FSM_ABORT, aisFsmRunEventAbort}, -+ {MID_MNY_AIS_REMAIN_ON_CHANNEL, aisFsmRunEventRemainOnChannel}, -+ {MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL, aisFsmRunEventCancelRemainOnChannel}, -+ {MID_MNY_AIS_MGMT_TX, aisFsmRunEventMgmtFrameTx} -+}; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#if DBG -+#define MBOX_HNDL_MSG(prAdapter, prMsg) do { \ -+ ASSERT(arMsgMapTable[prMsg->eMsgId].pfMsgHndl); \ -+ if (arMsgMapTable[prMsg->eMsgId].pfMsgHndl) { \ -+ DBGLOG(CNM, LOUD, "DO MSG [%d: %s]\n", prMsg->eMsgId, apucDebugMsg[prMsg->eMsgId]); \ -+ arMsgMapTable[prMsg->eMsgId].pfMsgHndl(prAdapter, prMsg); \ -+ } \ -+ else { \ -+ DBGLOG(CNM, ERROR, "NULL fptr for MSG [%d]\n", prMsg->eMsgId); \ -+ cnmMemFree(prAdapter, prMsg); \ -+ } \ -+} while (0) -+#else -+#define MBOX_HNDL_MSG(prAdapter, prMsg) do { \ -+ ASSERT(arMsgMapTable[prMsg->eMsgId].pfMsgHndl); \ -+ if (arMsgMapTable[prMsg->eMsgId].pfMsgHndl) { \ -+ DBGLOG(CNM, LOUD, "DO MSG [%d]\n", prMsg->eMsgId); \ -+ arMsgMapTable[prMsg->eMsgId].pfMsgHndl(prAdapter, prMsg); \ -+ } \ -+ else { \ -+ DBGLOG(CNM, ERROR, "NULL fptr for MSG [%d]\n", prMsg->eMsgId); \ -+ cnmMemFree(prAdapter, prMsg); \ -+ } \ -+} while (0) -+#endif -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxInitMsgMap(VOID) -+{ -+ UINT_32 i, idx; -+ MSG_HNDL_ENTRY_T rTempEntry; -+ -+ ASSERT((sizeof(arMsgMapTable) / sizeof(MSG_HNDL_ENTRY_T)) == MID_TOTAL_NUM); -+ -+ for (i = 0; i < MID_TOTAL_NUM; i++) { -+ if (arMsgMapTable[i].eMsgId == (ENUM_MSG_ID_T) i) -+ continue; -+ for (idx = i + 1; idx < MID_TOTAL_NUM; idx++) { -+ if (arMsgMapTable[idx].eMsgId == (ENUM_MSG_ID_T) i) -+ break; -+ } -+ ASSERT(idx < MID_TOTAL_NUM); -+ if (idx >= MID_TOTAL_NUM) -+ continue; -+ -+ /* Swap target entry and current entry */ -+ rTempEntry.eMsgId = arMsgMapTable[idx].eMsgId; -+ rTempEntry.pfMsgHndl = arMsgMapTable[idx].pfMsgHndl; -+ -+ arMsgMapTable[idx].eMsgId = arMsgMapTable[i].eMsgId; -+ arMsgMapTable[idx].pfMsgHndl = arMsgMapTable[i].pfMsgHndl; -+ -+ arMsgMapTable[i].eMsgId = rTempEntry.eMsgId; -+ arMsgMapTable[i].pfMsgHndl = rTempEntry.pfMsgHndl; -+ } -+ -+ /* Verify the correctness of final message map */ -+ for (i = 0; i < MID_TOTAL_NUM; i++) { -+ ASSERT(arMsgMapTable[i].eMsgId == (ENUM_MSG_ID_T) i); -+ while (arMsgMapTable[i].eMsgId != (ENUM_MSG_ID_T) i) -+ ; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxSetup(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId) -+{ -+ P_MBOX_T prMbox; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); -+ ASSERT(prAdapter); -+ -+ prMbox = &(prAdapter->arMbox[eMboxId]); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ LINK_INITIALIZE(&prMbox->rLinkHead); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+mboxSendMsg(IN P_ADAPTER_T prAdapter, -+ IN ENUM_MBOX_ID_T eMboxId, IN P_MSG_HDR_T prMsg, IN EUNM_MSG_SEND_METHOD_T eMethod) -+{ -+ P_MBOX_T prMbox; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); -+ ASSERT(prMsg); -+ ASSERT(prAdapter); -+ -+ prMbox = &(prAdapter->arMbox[eMboxId]); -+ -+ switch (eMethod) { -+ case MSG_SEND_METHOD_BUF: -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ LINK_INSERT_TAIL(&prMbox->rLinkHead, &prMsg->rLinkEntry); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ -+ /* to wake up main service thread */ -+ GLUE_SET_EVENT(prAdapter->prGlueInfo); -+ -+ break; -+ -+ case MSG_SEND_METHOD_UNBUF: -+ MBOX_HNDL_MSG(prAdapter, prMsg); -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxRcvAllMsg(IN P_ADAPTER_T prAdapter, ENUM_MBOX_ID_T eMboxId) -+{ -+ P_MBOX_T prMbox; -+ P_MSG_HDR_T prMsg; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); -+ ASSERT(prAdapter); -+ -+ prMbox = &(prAdapter->arMbox[eMboxId]); -+ -+ while (!LINK_IS_EMPTY(&prMbox->rLinkHead)) { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ LINK_REMOVE_HEAD(&prMbox->rLinkHead, prMsg, P_MSG_HDR_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ -+ ASSERT(prMsg); -+ MBOX_HNDL_MSG(prAdapter, prMsg); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxInitialize(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ /* Initialize Mailbox */ -+ mboxInitMsgMap(); -+ -+ /* Setup/initialize each mailbox */ -+ for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) -+ mboxSetup(prAdapter, i); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxDestroy(IN P_ADAPTER_T prAdapter) -+{ -+ P_MBOX_T prMbox; -+ P_MSG_HDR_T prMsg; -+ UINT_8 i; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) { -+ prMbox = &(prAdapter->arMbox[i]); -+ -+ while (!LINK_IS_EMPTY(&prMbox->rLinkHead)) { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ LINK_REMOVE_HEAD(&prMbox->rLinkHead, prMsg, P_MSG_HDR_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ -+ ASSERT(prMsg); -+ cnmMemFree(prAdapter, prMsg); -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is dummy function to prevent empty arMsgMapTable[] for compiling. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxDummy(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ ASSERT(prAdapter); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c -new file mode 100644 -index 0000000000000..7fb71a199ccf4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c -@@ -0,0 +1,498 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/HS2_DEV_SW/MT6620_WIFI_DRIVER_V2_1_HS_2_0/mgmt/hs20.c#2 -+*/ -+ -+/*! \file "hs20.c" -+ \brief This file including the hotspot 2.0 related function. -+ -+ This file provided the macros and functions library support for the -+ protocol layer hotspot 2.0 related function. -+ -+*/ -+ -+/* -+** Log: hs20.c -+ * -+ */ -+ -+ /******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to generate Interworking IE for Probe Rsp, Bcn, Assoc Req/Rsp. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[out] prMsduInfo Pointer of the Msdu Info -+* -+* \return VOID -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID hs20GenerateInterworkingIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo) -+{ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to generate Roaming Consortium IE for Probe Rsp, Bcn, Assoc Req/Rsp. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[out] prMsduInfo Pointer of the Msdu Info -+* -+* \return VOID -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID hs20GenerateRoamingConsortiumIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo) -+{ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to generate HS2.0 IE for Probe Rsp, Bcn, Assoc Req/Rsp. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[out] prMsduInfo Pointer of the Msdu Info -+* -+* \return VOID -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID hs20GenerateHS20IE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo) -+{ -+ PUINT_8 pucBuffer; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX) -+ return; -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ /* ASSOC INFO IE ID: 221 :0xDD */ -+ if (prAdapter->prGlueInfo->u2HS20AssocInfoIELen) { -+ kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucHS20AssocInfoIE, -+ prAdapter->prGlueInfo->u2HS20AssocInfoIELen); -+ prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2HS20AssocInfoIELen; -+ } -+ -+} -+ -+VOID hs20FillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_HS20_EXT_CAP_T prExtCap; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ /* Add Extended Capabilities IE */ -+ prExtCap = (P_HS20_EXT_CAP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+ prExtCap->ucId = ELEM_ID_EXTENDED_CAP; -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) -+ prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; -+ else -+ prExtCap->ucLength = 3 - ELEM_HDR_LEN; -+ -+ kalMemZero(prExtCap->aucCapabilities, prExtCap->ucLength); -+ -+ prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; -+ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; -+ -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) { -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_BSS_TRANSITION_BIT); -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT); -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); -+ -+ /* For R2 WNM-Notification */ -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); -+ } -+ kalPrint("IE_SIZE(prExtCap) = %d, %d %d\n", IE_SIZE(prExtCap), ELEM_HDR_LEN, ELEM_MAX_LEN_EXT_CAP); -+ ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prExtCap); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to fill up the content of Ext Cap IE bit 31. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[out] pucIE Pointer of the IE buffer -+* -+* \return VOID -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID hs20FillProreqExtCapIE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE) -+{ -+ P_HS20_EXT_CAP_T prExtCap; -+ -+ ASSERT(prAdapter); -+ -+ /* Add Extended Capabilities IE */ -+ prExtCap = (P_HS20_EXT_CAP_T) pucIE; -+ -+ prExtCap->ucId = ELEM_ID_EXTENDED_CAP; -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) -+ prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; -+ else -+ prExtCap->ucLength = 3 - ELEM_HDR_LEN; -+ -+ kalMemZero(prExtCap->aucCapabilities, prExtCap->ucLength); -+ -+ prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; -+ -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) { -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_BSS_TRANSITION_BIT); -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT); -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); -+ -+ /* For R2 WNM-Notification */ -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to fill up the content of HS2.0 IE. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[out] pucIE Pointer of the IE buffer -+* -+* \return VOID -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID hs20FillHS20IE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE) -+{ -+ P_IE_HS20_INDICATION_T prHS20IndicationIe; -+ /* P_HS20_INFO_T prHS20Info; */ -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ -+ /* prHS20Info = &(prAdapter->rWifiVar.rHS20Info); */ -+ -+ prHS20IndicationIe = (P_IE_HS20_INDICATION_T) pucIE; -+ -+ prHS20IndicationIe->ucId = ELEM_ID_VENDOR; -+ prHS20IndicationIe->ucLength = sizeof(IE_HS20_INDICATION_T) - ELEM_HDR_LEN; -+ prHS20IndicationIe->aucOui[0] = aucWfaOui[0]; -+ prHS20IndicationIe->aucOui[1] = aucWfaOui[1]; -+ prHS20IndicationIe->aucOui[2] = aucWfaOui[2]; -+ prHS20IndicationIe->ucType = VENDOR_OUI_TYPE_HS20; -+ prHS20IndicationIe->ucHotspotConfig = 0x00; /* prHS20Info->ucHotspotConfig; */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called while calculating length of hotspot 2.0 indication IE for Probe Request. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[in] pucTargetBSSID Pointer of target HESSID -+* -+* \return the length of composed HS20 IE -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 hs20CalculateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID) -+{ -+ UINT_32 u4IeLength; -+ -+ if (0) /* Todo:: Not HS20 STA */ -+ return 0; -+ -+ u4IeLength = -+ sizeof(IE_HS20_INDICATION_T) + /* sizeof(IE_INTERWORKING_T) */ + (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP); -+ -+ if (!pucTargetBSSID) { -+ /* Do nothing */ -+ /* u4IeLength -= MAC_ADDR_LEN; */ -+ } -+ -+ return u4IeLength; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called while composing hotspot 2.0 indication IE for Probe Request. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[in] pucTargetBSSID Pointer of target HESSID -+* \param[out] prIE Pointer of the IE buffer -+* -+* \return the wlan status -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS hs20GenerateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID, OUT PUINT_8 prIE) -+{ -+ if (0) /* Todo:: Not HS20 STA */ -+ return 0; -+#if 0 -+ P_HS20_INFO_T prHS20Info; -+ -+ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); -+ -+ /* -+ * Generate 802.11u Interworking IE (107) -+ */ -+ hs20FillInterworkingIE(prAdapter, -+ prHS20Info->ucAccessNetworkOptions, -+ prHS20Info->ucVenueGroup, prHS20Info->ucVenueType, pucTargetBSSID, prIE); -+ prIE += IE_SIZE(prIE); -+#endif -+ /* -+ * Generate Ext Cap IE (127) -+ */ -+ hs20FillProreqExtCapIE(prAdapter, prIE); -+ prIE += IE_SIZE(prIE); -+ -+ /* -+ * Generate HS2.0 Indication IE (221) -+ */ -+ hs20FillHS20IE(prAdapter, prIE); -+ prIE += IE_SIZE(prIE); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+BOOLEAN hs20IsGratuitousArp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb) -+{ -+ PUINT_8 pucSenderIP = prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_SENDER_IP_OFFSET; -+ PUINT_8 pucTargetIP = prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_TARGET_IP_OFFSET; -+ PUINT_8 pucSenderMac = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_SNEDER_MAC_OFFSET); -+#if CFG_HS20_DEBUG && 0 -+/* UINT_8 aucIpAllZero[4] = {0,0,0,0}; */ -+/* UINT_8 aucMACAllZero[MAC_ADDR_LEN] = {0,0,0,0,0,0}; */ -+ PUINT_8 pucTargetMac = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_TARGET_MAC_OFFSET); -+#endif -+ -+#if CFG_HS20_DEBUG && 0 -+ PUINT_16 pu2ArpOper = (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_OPERATION_OFFSET); -+ -+ kalPrint("Recv ARP 0x%04X\n", htons(*pu2ArpOper)); -+ kalPrint("SENDER[ %pM ] [%pI4]\n", pucSenderMac, pucSenderIP); -+ kalPrint("TARGET[ %pM ] [%pI4]\n", pucTargetMac, pucTargetIP); -+#endif -+ -+ /* IsGratuitousArp */ -+ if (!kalMemCmp(pucSenderIP, pucTargetIP, 4)) { -+ kalPrint("Drop Gratuitous ARP from [ %pM ] [%pI4]\n", pucSenderMac, pucTargetIP); -+ return TRUE; -+ } -+ return FALSE; -+} -+ -+BOOLEAN hs20IsUnsolicitedNeighborAdv(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb) -+{ -+ PUINT_8 pucIpv6Protocol = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_IP_PROTOCOL_OFFSET); -+ -+ /* kalPrint("pucIpv6Protocol [%02X:%02X]\n", *pucIpv6Protocol, IPV6_PROTOCOL_ICMPV6); */ -+ if (*pucIpv6Protocol == IPV6_PROTOCOL_ICMPV6) { -+ PUINT_8 pucICMPv6Type = -+ ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_LEN + ICMPV6_TYPE_OFFSET); -+ /* kalPrint("pucICMPv6Type [%02X:%02X]\n", *pucICMPv6Type, ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT); */ -+ if (*pucICMPv6Type == ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT) { -+ PUINT_8 pucICMPv6Flag = -+ ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_LEN + ICMPV6_FLAG_OFFSET); -+ PUINT_8 pucSrcMAC = ((PUINT_8) prCurrSwRfb->pvHeader + MAC_ADDR_LEN); -+ -+#if CFG_HS20_DEBUG -+ kalPrint("NAdv Flag [%02X] [R(%d)\\S(%d)\\O(%d)]\n", -+ *pucICMPv6Flag, -+ (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_ROUTER_BIT) >> 7, -+ (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_SOLICITED_BIT) >> 6, -+ (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_OVERWRITE_BIT) >> 5); -+#endif -+ if (!(*pucICMPv6Flag & ICMPV6_FLAG_SOLICITED_BIT)) { -+ kalPrint("Drop Unsolicited Neighbor Advertisement from [%pM]\n", pucSrcMAC); -+ return TRUE; -+ } -+ } -+ } -+ -+ return FALSE; -+} -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+BOOLEAN hs20IsForgedGTKFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb) -+{ -+ /* -+ P_CONNECTION_SETTINGS_T prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ PUINT_8 pucEthDestAddr = prCurrSwRfb->pvHeader; -+ */ -+ /* 3 TODO: Need to verify this function before enable it */ -+ return FALSE; -+ /* -+ if ((prConnSettings->eEncStatus != ENUM_ENCRYPTION_DISABLED) && IS_BMCAST_MAC_ADDR(pucEthDestAddr)) { -+ UINT_8 ucIdx = 0; -+ PUINT_32 prIpAddr, prPacketDA; -+ PUINT_16 pu2PktIpVer = -+ (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + (ETHER_HEADER_LEN - ETHER_TYPE_LEN)); -+ -+ if (*pu2PktIpVer == htons(ETH_P_IPV4)) { -+ if (!prBssInfo->prIpV4NetAddrList) -+ return FALSE; -+ for (ucIdx = 0; ucIdx < prBssInfo->prIpV4NetAddrList->ucAddrCount; ucIdx++) { -+ prIpAddr = (PUINT_32) &prBssInfo->prIpV4NetAddrList->arNetAddr[ucIdx].aucIpAddr[0]; -+ prPacketDA = -+ (PUINT_32) ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + -+ IPV4_HDR_IP_DST_ADDR_OFFSET); -+ -+ if (kalMemCmp(prIpAddr, prPacketDA, 4) == 0) { -+ kalPrint("Drop FORGED IPv4 packet\n"); -+ return TRUE; -+ } -+ } -+ } -+#ifdef CONFIG_IPV6 -+ else if (*pu2PktIpVer == htons(ETH_P_IPV6)) { -+ UINT_8 aucIPv6Mac[MAC_ADDR_LEN]; -+ PUINT_8 pucIdx = -+ prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_IP_DST_ADDR_MAC_HIGH_OFFSET; -+ -+ kalMemCopy(&aucIPv6Mac[0], pucIdx, 3); -+ pucIdx += 5; -+ kalMemCopy(&aucIPv6Mac[3], pucIdx, 3); -+ kalPrint("Get IPv6 frame Dst IP MAC part %pM\n", aucIPv6Mac); -+ if (EQUAL_MAC_ADDR(aucIPv6Mac, prBssInfo->aucOwnMacAddr)) { -+ kalPrint("Drop FORGED IPv6 packet\n"); -+ return TRUE; -+ } -+ } -+#endif -+ } -+ -+ return FALSE; -+ */ -+} -+#endif -+ -+BOOLEAN hs20IsUnsecuredFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb) -+{ -+ PUINT_16 pu2PktIpVer = (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + (ETHER_HEADER_LEN - ETHER_TYPE_LEN)); -+ -+ /* kalPrint("IPVER 0x%4X\n", htons(*pu2PktIpVer)); */ -+#if CFG_HS20_DEBUG & 0 -+ UINT_8 i = 0; -+ -+ kalPrint("==============================================="); -+ for (i = 0; i < 96; i++) { -+ if (!(i % 16)) -+ kalPrint("\n"); -+ kalPrint("%02X ", *((PUINT_8) prCurrSwRfb->pvHeader + i)); -+ } -+ kalPrint("\n"); -+#endif -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ if (hs20IsForgedGTKFrame(prAdapter, prBssInfo, prCurrSwRfb)) -+ return TRUE; -+ -+#endif -+ if (*pu2PktIpVer == htons(ETH_P_ARP)) -+ return hs20IsGratuitousArp(prAdapter, prCurrSwRfb); -+ else if (*pu2PktIpVer == htons(ETH_P_IPV6)) -+ return hs20IsUnsolicitedNeighborAdv(prAdapter, prCurrSwRfb); -+ -+ return FALSE; -+} -+ -+BOOLEAN hs20IsFrameFilterEnabled(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo) -+{ -+#if 1 -+ if (prAdapter->prGlueInfo->fgConnectHS20AP) -+ return TRUE; -+#else -+ PARAM_SSID_T rParamSsid; -+ P_BSS_DESC_T prBssDesc; -+ -+ rParamSsid.u4SsidLen = prBssInfo->ucSSIDLen; -+ COPY_SSID(rParamSsid.aucSsid, rParamSsid.u4SsidLen, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); -+ -+ prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, prBssInfo->aucBSSID, TRUE, &rParamSsid); -+ if (!prBssDesc) -+ return FALSE; -+ -+ if (prBssDesc->fgIsSupportHS20) { -+ if (!(prBssDesc->ucHotspotConfig & ELEM_HS_CONFIG_DGAF_DISABLED_MASK)) -+ return TRUE; -+ -+ /* Disable frame filter only if DGAF == 1 */ -+ return FALSE; -+ -+ } -+#endif -+ -+ /* For Now, always return true to run hs20 check even for legacy AP */ -+ return TRUE; -+} -+ -+WLAN_STATUS hs20SetBssidPool(IN P_ADAPTER_T prAdapter, IN PVOID pvBuffer, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx) -+{ -+ P_PARAM_HS20_SET_BSSID_POOL prParamBssidPool = (P_PARAM_HS20_SET_BSSID_POOL) pvBuffer; -+ P_HS20_INFO_T prHS20Info; -+ UINT_8 ucIdx; -+ -+ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); -+ kalPrint("[%s]Set Bssid Pool! enable[%d] num[%d]\n", __func__, prParamBssidPool->fgIsEnable, -+ prParamBssidPool->ucNumBssidPool); -+ for (ucIdx = 0; ucIdx < prParamBssidPool->ucNumBssidPool; ucIdx++) { -+ COPY_MAC_ADDR(prHS20Info->arBssidPool[ucIdx].aucBSSID, &prParamBssidPool->arBSSID[ucIdx]); -+ kalPrint("[%s][%d][ %pM ]\n", __func__, ucIdx, (prHS20Info->arBssidPool[ucIdx].aucBSSID)); -+ } -+ prHS20Info->fgIsHS2SigmaMode = prParamBssidPool->fgIsEnable; -+ prHS20Info->ucNumBssidPoolEntry = prParamBssidPool->ucNumBssidPool; -+ -+#if 0 -+ wlanClearScanningResult(prAdapter); -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c -new file mode 100644 -index 0000000000000..469a48ebe9c10 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c -@@ -0,0 +1,111 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/mib.c#1 -+*/ -+ -+/*! \file "mib.c" -+ \brief This file includes the mib default vale and functions. -+*/ -+ -+/* -+** Log: mib.c -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add mib.c. -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+NON_HT_PHY_ATTRIBUTE_T rNonHTPhyAttributes[] = { -+ {RATE_SET_HR_DSSS, TRUE, FALSE} -+ , /* For PHY_TYPE_HR_DSSS_INDEX(0) */ -+ {RATE_SET_ERP, TRUE, TRUE} -+ , /* For PHY_TYPE_ERP_INDEX(1) */ -+ {RATE_SET_ERP_P2P, TRUE, TRUE} -+ , /* For PHY_TYPE_ERP_P2P_INDEX(2) */ -+ {RATE_SET_OFDM, FALSE, FALSE} -+ , /* For PHY_TYPE_OFDM_INDEX(3) */ -+}; -+ -+NON_HT_ADHOC_MODE_ATTRIBUTE_T rNonHTAdHocModeAttributes[AD_HOC_MODE_NUM] = { -+ {PHY_TYPE_HR_DSSS_INDEX, BASIC_RATE_SET_HR_DSSS} -+ , /* For AD_HOC_MODE_11B(0) */ -+ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_HR_DSSS_ERP} -+ , /* For AD_HOC_MODE_MIXED_11BG(1) */ -+ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_ERP} -+ , /* For AD_HOC_MODE_11G(2) */ -+ {PHY_TYPE_OFDM_INDEX, BASIC_RATE_SET_OFDM} -+ , /* For AD_HOC_MODE_11A(3) */ -+}; -+ -+NON_HT_AP_MODE_ATTRIBUTE_T rNonHTApModeAttributes[AP_MODE_NUM] = { -+ {PHY_TYPE_HR_DSSS_INDEX, BASIC_RATE_SET_HR_DSSS} -+ , /* For AP_MODE_11B(0) */ -+ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_HR_DSSS_ERP} -+ , /* For AP_MODE_MIXED_11BG(1) */ -+ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_ERP} -+ , /* For AP_MODE_11G(2) */ -+ {PHY_TYPE_ERP_P2P_INDEX, BASIC_RATE_SET_ERP_P2P} -+ , /* For AP_MODE_11G_P2P(3) */ -+ {PHY_TYPE_OFDM_INDEX, BASIC_RATE_SET_OFDM} -+ , /* For AP_MODE_11A(4) */ -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c -new file mode 100644 -index 0000000000000..cb5fbebedd495 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c -@@ -0,0 +1,87 @@ -+/* -+** Id: @(#) p2p_assoc.c@@ -+*/ -+ -+/*! \file "p2p_assoc.c" -+ \brief This file includes the Wi-Fi Direct association-related functions. -+ -+ This file includes the association-related functions. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to compose Common Information Elements for P2P Association -+* Request Frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+PUINT_8 p2pBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer) -+{ -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ /* Fill the SSID element. */ -+ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; -+ -+ /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of -+ * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame. -+ */ -+ -+ COPY_SSID(SSID_IE(pucBuffer)->aucSSID, -+ SSID_IE(pucBuffer)->ucLength, prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ return pucBuffer; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c -new file mode 100644 -index 0000000000000..72a20a322cee6 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c -@@ -0,0 +1,58 @@ -+/* -+** Id: @(#) p2p_bss.c@@ -+*/ -+ -+/*! \file "p2p_bss.c" -+ \brief This file contains the functions for creating p2p BSS(AP). -+ -+ This file contains the functions for BSS(AP). We may create a BSS -+ network, or merge with exist IBSS network and sending Beacon Frame or reply -+ the Probe Response Frame for received Probe Request Frame. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c -new file mode 100644 -index 0000000000000..f8c09e2aa9ded ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c -@@ -0,0 +1,3139 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/mgmt/p2p_fsm.c#61 -+*/ -+ -+/*! \file "p2p_fsm.c" -+ \brief This file defines the FSM for P2P Module. -+ -+ This file defines the FSM for P2P Module. -+*/ -+ -+/* -+** Log: p2p_fsm.c -+** -+** 12 20 2012 yuche.tsai -+** [ALPS00410124] [Rose][Free Test][KE][rlmUpdateParamsForAP]The device reboot automatically -+** and then "Fatal/Kernel" pops up during use data service.(Once) -+** Fix possible NULL station record cause KE under AP mode. -+** May due to variable uninitial. -+** Review: http://mtksap20:8080/go?page=NewReview&reviewid=49970 -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 31 2012 yuche.tsai -+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected -+**to AP previously,one device reboots automatically with KE -+** Fix possible KE when concurrent & disconnect. -+** -+** 08 21 2012 yuche.tsai -+** NULL -+** fix disconnect indication. -+** -+** 08 16 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 14 2012 yuche.tsai -+** NULL -+** Fix p2p bug find on ALPS.JB trunk. -+** -+** 07 27 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update for driver unload KE issue. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Fix the compile flag of enhancement. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000808] [Volunteer Patch][MT6620][Driver/FW] Device discoverability issue fix -+ * Change device discoverability methodology. From driver SCAN to FW lock channel. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Add wifi direct connection enhancement method I, II & VI. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000833] [Volunteer Patch][WiFi Direct][Driver] Service Discovery Frame RX Indicate Issue -+ * Fix Service Discovery Race Condition Issue. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 21 2011 yuche.tsai -+ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. -+ * Fix an issue of accepting connection of GO. -+ * -+ * 06 21 2011 yuche.tsai -+ * [WCXRP00000775] [Volunteer Patch][MT6620][Driver] Dynamic enable SD capability -+ * Drop GAS frame when SD is not enabled. -+ * -+ * 06 20 2011 yuche.tsai -+ * NULL -+ * Fix compile error. -+ * -+ * 06 20 2011 yuche.tsai -+ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. -+ * Fix connection indication twice issue. -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 06 20 2011 yuche.tsai -+ * [WCXRP00000795] [Volunteer Patch][MT6620][Driver] GO can not connect second device issue -+ * Solve P2P GO can not formation with second device issue. -+ * -+ * 06 14 2011 yuche.tsai -+ * NULL -+ * Change disconnect feature. -+ * -+ * 06 10 2011 yuche.tsai -+ * [WCXRP00000775] [Volunteer Patch][MT6620][Driver] Dynamic enable SD capability[WCXRP00000776] -+ * [Need Patch][MT6620][Driver] MT6620 response probe request of P2P device with P2P IE under Hot Spot mode. -+ * 1. Dynamic enable SD capability after P2P supplicant ready. -+ * 2. Avoid response probe respone with p2p IE when under hot spot mode. -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Fix RX SD request under AP mode issue. -+ * -+ * 06 02 2011 cp.wu -+ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction -+ * eliminate unused parameters for SAA-FSM -+ * -+ * 05 26 2011 yuche.tsai -+ * [WCXRP00000745] Support accepting connection after one Group Connection Lost. -+ -+After Group Formation & lost connection, if MT6620 behave as: -+ -+1. GO: It would keep under GO state until been dissolved by supplicant. -+ -+ At this time, other P2P device can use join method to join this group. -+ -+2. GC: It would keep on searching target GO or target device until been dissolved by supplicant. -+ -+At this time, it would ignore other P2P device formation request. -+ -+-- -+ -+Modification: Make driver to accept GO NEGO REQ at this time, to let user decide to accept new connection or not. -+ -+ * [Volunteer Patch][MT6620][Driver] -+ * Driver would indicate connection request, if password ID is not ready but connection request is issued. -+ * -+ * 05 18 2011 yuche.tsai -+ * [WCXRP00000728] [Volunteer Patch][MT6620][Driver] Service Discovery Request TX issue. -+ * A solution for both connection request & IO control. -+ * -+ * 05 16 2011 yuche.tsai -+ * [WCXRP00000728] [Volunteer Patch][MT6620][Driver] Service Discovery Request TX issue. -+ * Fix SD request can not send out issue. -+ * -+ * 05 09 2011 terry.wu -+ * [WCXRP00000711] [MT6620 Wi-Fi][Driver] Set Initial value of StaType in StaRec for Hotspot Client -+ * Set initial value of StaType in StaRec for hotspot client. -+ * -+ * 05 04 2011 yuche.tsai -+ * [WCXRP00000697] [Volunteer Patch][MT6620][Driver] -+ * Bug fix for p2p descriptor is NULL if BSS descriptor is found first. -+ * -+ * 05 04 2011 yuche.tsai -+ * NULL -+ * Support partial persistent group function. -+ * -+ * 05 02 2011 yuche.tsai -+ * [WCXRP00000693] [Volunteer Patch][MT6620][Driver] Clear Formation Flag after TX lifetime timeout. -+ * Clear formation flag after formation timeout. -+ * -+ * 04 20 2011 yuche.tsai -+ * [WCXRP00000668] [Volunteer Patch][MT6620][Driver] Possible race condition -+ * when add scan & query scan result at the same time. -+ * Fix side effect while starting ATGO. -+ * -+ * 04 20 2011 yuche.tsai -+ * NULL -+ * Fix ASSERT issue in FW, side effect of last change. -+ * -+ * 04 19 2011 yuche.tsai -+ * [WCXRP00000668] [Volunteer Patch][MT6620][Driver] Possible race condition -+ * when add scan & query scan result at the same time. -+ * Workaround for multiple device connection, before invitation ready. -+ * -+ * 04 19 2011 yuche.tsai -+ * [WCXRP00000665] [Wifi Direct][MT6620 E4] When use Ralink's dongle to establish wifi direct connection with PBC. -+ * But 6573 always not pop accept option to establish connection. -+ * Support connection indication when GO NEGO REQ doesn't have configure method, instead it has PasswordID. -+ * -+ * 04 18 2011 yuche.tsai -+ * NULL -+ * Fix error. -+ * -+ * 04 14 2011 yuche.tsai -+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. -+ * Fix a connection issue. -+ * -+ * 04 14 2011 yuche.tsai -+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. -+ * Fix the channel issue of AP mode. -+ * -+ * 04 14 2011 yuche.tsai -+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. -+ * Connection flow refine for Sigma test. -+ * -+ * 04 09 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Fix Device discoverability related issue. -+ * -+ * 04 09 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Fix bug for Device Discoverability. -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Fix compile error. -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discoverability support. -+ * -+ * 03 28 2011 yuche.tsai -+ * NULL -+ * Fix a possible issue for retry join when media status connected. -+ * -+ * 03 25 2011 yuche.tsai -+ * NULL -+ * Improve some error handleing. -+ * -+ * 03 24 2011 yuche.tsai -+ * NULL -+ * Assign AID before change STA_REC state to state 3. -+ * -+ * 03 23 2011 yuche.tsai -+ * NULL -+ * Fix Response Rate Issue when TX Auth Rsp Frame under P2P Mode. -+ * -+ * 03 23 2011 yuche.tsai -+ * NULL -+ * Fix issue of connection to one GC. -+ * -+ * 03 23 2011 yuche.tsai -+ * NULL -+ * Fix ASSERT issue when starting Hot-spot. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * When Target Information is not available, change to passive mode. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * Fix one connection issue while using Keypad to connect a GO. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * 1. Fix two issues that may cause kernel panic. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * Fix GC connect to other device issue. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * 1.Shorten the LISTEN interval. -+ * 2. Fix IF address issue when we are GO -+ * 3. Fix LISTEN channel issue. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * Modify formation policy setting. -+ * -+ * 03 21 2011 yuche.tsai -+ * NULL -+ * Solve Listen State doesn't response probe response issue. -+ * -+ * 03 21 2011 yuche.tsai -+ * NULL -+ * Change P2P Connection Request Flow. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Add beacon timeout support. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000583] [Volunteer Patch][MT6620][Driver] P2P connection of the third peer issue -+ * Indicate the correct Group SSID when join on Group. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000583] [Volunteer Patch][MT6620][Driver] P2P connection of the third peer issue -+ * Support the third P2P device to join GO/GC group. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Append P2P IE in Assoc Req, so that GC can be discovered in probe response of GO. -+ * -+ * 03 18 2011 yuche.tsai -+ * [WCXRP00000578] [Volunteer Patch][MT6620][Driver] Separate Connection Request from general IOCTL -+ * Separate connection request from general IOCTL. -+ * -+ * 03 18 2011 yuche.tsai -+ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow -+ * Modify connection flow after Group Formation Complete, or device connect to a GO. -+ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN. -+ * -+ * 03 17 2011 yuche.tsai -+ * NULL -+ * When AIS is connect to an AP, Hot Spot would be enabled under fixed same channel. -+ * -+ * 03 17 2011 yuche.tsai -+ * NULL -+ * Solve the Group Info IE in Probe Response incorrect issue. -+ * -+ * 03 17 2011 yuche.tsai -+ * NULL -+ * Release Channel after Join Complete. -+ * -+ * 03 16 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * enable the protected while at P2P start GO, and skip some security check . -+ * -+ * 03 15 2011 yuche.tsai -+ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue -+ * Fix local configure method issue. -+ * -+ * 03 15 2011 yuche.tsai -+ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue -+ * Fix some configure method issue. -+ * -+ * 03 14 2011 yuche.tsai -+ * NULL -+ * . -+ * -+ * 03 14 2011 yuche.tsai -+ * NULL -+ * Fix password ID issue. -+ * -+ * 03 10 2011 yuche.tsai -+ * NULL -+ * Add P2P API. -+ * -+ * 03 08 2011 yuche.tsai -+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue[WCXRP00000509] -+ * [Volunteer Patch][MT6620][Driver] Kernal panic when remove p2p module. -+ * . -+ * -+ * 03 07 2011 yuche.tsai -+ * [WCXRP00000502] [Volunteer Patch][MT6620][Driver] Fix group ID issue when doing Group Formation. -+ * . -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 04 2011 wh.su -+ * [WCXRP00000510] [MT6620 Wi-Fi] [Driver] Fixed the CTIA enter test mode issue -+ * fixed the p2p action frame type check for device request indication. -+ * -+ * 03 02 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Fix Service Discovery RX packet buffer pointer. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation -+ * Update channel issue when doing GO formation.. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Update Service Discovery Related wlanoid function. -+ * -+ * 02 21 2011 yuche.tsai -+ * [WCXRP00000481] [Volunteer Patch][MT6620][FW] Scan hang under concurrent case. -+ * Fix all BE issue of WSC or P2P IE. -+ * -+ * 02 18 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * fixed the wsc config method mapping to driver used config method issue. -+ * -+ * 02 18 2011 yuche.tsai -+ * [WCXRP00000479] [Volunteer Patch][MT6620][Driver] Probe Response of P2P using 11b rate. -+ * Update basic rate to FW, after P2P is initialed. -+ * -+ * 02 18 2011 yuche.tsai -+ * [WCXRP00000478] [Volunteer Patch][MT6620][Driver] Probe request frame during search -+ * phase do not contain P2P wildcard SSID. -+ * Use P2P Wildcard SSID when scan type of P2P_WILDCARD_SSID is set. -+ * -+ * 02 18 2011 yuche.tsai -+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue -+ * Fix WSC IE BE format issue. -+ * -+ * 02 17 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * append the WSC IE config method attribute at provision discovery request. -+ * -+ * 02 16 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * fixed the probe request send out without WSC IE issue (at P2P). -+ * -+ * 02 16 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * If two station connected to the Hot-Spot and one disconnect, FW would get into an infinite loop -+ * -+ * 02 15 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Fix re-connection issue after RX deauthentication. -+ * -+ * 02 15 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Fix conneciton issue after disconnect with AP. -+ * -+ * 02 12 2011 yuche.tsai -+ * [WCXRP00000441] [Volunteer Patch][MT6620][Driver] BoW can not create desired station type when Hot Spot is enabled. -+ * P2P Create Station Type according to Target BSS capability. -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Support Disassoc & Deauthentication for Hot-Spot. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Indication Related code. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add Support for MLME deauthentication for Hot-Spot. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue -+ * Fix Client Limit Issue. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect -+ * to target station for AAA module. -+ * Disconnect every station client when disolve on P2P group. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * 1. Fix Service Disocvery Logical issue. -+ * 2. Fix a NULL pointer access violation issue when sending deauthentication packet to a class error station. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect -+ * to target station for AAA module. -+ * Workaround of disable P2P network. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000421] [Volunteer Patch][MT6620][Driver] Fix incorrect SSID length Issue -+ * 1. Fixed SSID wrong length issue. -+ * 2. Under Hot Spot configuration, there won't be any P2P IE. -+ * 3. Under Hot Spot configuration, P2P FSM won't get into LISTEN state first. -+ * -+ * 01 27 2011 yuche.tsai -+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. -+ * Modify Start GO flow. -+ * -+ * 01 27 2011 yuche.tsai -+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. -+ * Fix desire phy type set issue. -+ * -+ * 01 27 2011 yuche.tsai -+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. -+ * Add desire phy type set phase I. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix P2P Disconnect Issue. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Function. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix compile error when DBG is disabled. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type Definition. -+ * -+ * 01 19 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Add P2P QoS Support. -+ * -+ * 01 19 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Null NOA attribute setting when no related parameters. -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Modify AAA flow according to CM's comment. -+ * -+ * 01 13 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Resolve Channel ZERO issue. (Uninitialized default channel) -+ * -+ * 01 13 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Update P2P State Debug Message. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Fix bug when allocating message buffer. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Update Phy Type Set. When legacy client is connected, it can use 11b rate, -+ * but if the P2P device is connected, 11b rate is not allowed. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * 1. Modify Channel Acquire Time of AP mode from 5s to 1s. -+ * 2. Call cnmP2pIsPermit() before active P2P network. -+ * 3. Add channel selection support for AP mode. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Fix Bug of reference to NULL pointer. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Modify some behavior of AP mode. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Fix bug of wrong pointer check. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Fix Compile Error. -+ * -+ * 01 11 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Add station record into client list before change it state from STATE_2 to STATE_3. -+ * -+ * 01 05 2011 yuche.tsai -+ * [WCXRP00000345] [MT6620][Volunteer Patch] P2P may issue a SSID specified scan request, -+ * but the SSID length is still invalid. -+ * Specify SSID Type when issue a scan request. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations -+ * to ease physically continuous memory demands -+ * correct typo -+ * -+ * 01 05 2011 george.huang -+ * [WCXRP00000343] [MT6620 Wi-Fi] Add TSF reset path for concurrent operation -+ * modify NOA update path for preventing assertion false alarm. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations -+ * to ease physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 01 03 2011 wh.su -+ * [WCXRP00000326] [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!! -+ * let the p2p ap mode acept a legacy device join. -+ * -+ * 12 22 2010 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Fix Compile Error. -+ * -+ * 12 15 2010 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Refine Connection Flow. -+ * -+ * 12 08 2010 yuche.tsai -+ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in -+ * [WCXRP000000245][MT6620][Driver] Invitation Request Feature Add -+ * -+ * 12 08 2010 yuche.tsai -+ * [WCXRP00000244] [MT6620][Driver] Add station record type for each client when in AP mode. -+ * Change STA Type under AP mode. We would tell if client is a P2P device or a legacy client -+ * by checking the P2P IE in assoc req frame. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * The order of invoking nicUpdateBss() and rlm functions -+ * -+ * 12 02 2010 yuche.tsai -+ * NULL -+ * Update P2P Connection Policy for Invitation. -+ * -+ * 12 02 2010 yuche.tsai -+ * NULL -+ * Update P2P Connection Policy for Invitation & Provision Discovery. -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Invitation & Provision Discovery Indication. -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Update Configure Method indication & selection for Provision Discovery & GO_NEGO_REQ -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Update RCIP value when RX assoc request frame. -+ * -+ * 11 29 2010 yuche.tsai -+ * NULL -+ * Update P2P related function for INVITATION & PROVISION DISCOVERY. -+ * -+ * 11 26 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * Update P2P PS for NOA function. -+ * -+ * 11 25 2010 yuche.tsai -+ * NULL -+ * Update Code for Invitation Related Function. -+ * -+ * 11 17 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] -+ * Set the Tx lowest rate at wlan table for normal operation -+ * fixed some ASSERT check. -+ * -+ * 11 05 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * fixed the p2p role code error. -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * fixed the ASSERT check error -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 10 19 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state -+ * machine[WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android -+ * fixed the compiling error. -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android -+ * adding a code to support Direct GO with a compiling flag . -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000087] [MT6620 Wi-Fi][Driver] Cannot connect to 5GHz AP, driver will cause FW assert. -+ * correct erroneous logic: specifying eBand with incompatible eSco -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * fixed the compiling error. -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * update the frog's new p2p state machine. -+ * -+ * 09 10 2010 wh.su -+ * NULL -+ * fixed the compiling error at WinXP. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Reset Common IE Buffer of P2P INFO when scan request is issued. -+ * If an action frame other than public action frame is received, return direcly. -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 06 2010 wh.su -+ * NULL -+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add P2P Connection Abort Event Message handler. -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 yuche.tsai -+ * NULL -+ * 1. Fix Interface Address from GO Nego Req/Rsp is not correct. -+ * 2. Fix GO mode does not change media state after station connected. -+ * 3. Fix STA don't response probe request when there is a connection request. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 20 2010 kevin.huang -+ * NULL -+ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete() -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Add Glue Layer indication. -+ * -+ * 08 17 2010 yuche.tsai -+ * NULL -+ * Fix compile warning under Linux. -+ * -+ * 08 17 2010 yuche.tsai -+ * NULL -+ * Fix some P2P FSM bug. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add random Interface Address Generation support. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Fix some P2P FSM bug. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Update P2P FSM code for GO Nego. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Join complete indication. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add two boolean in connection request. -+ * Based on these two boolean value, P2P FSM should -+ * decide to do invitation or group formation or start a GO directly. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Update P2P FSM, currently P2P Device Discovery is verified. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Update P2P FSM for group formation. -+ * -+ * 08 03 2010 george.huang -+ * NULL -+ * handle event for updating NOA parameters indicated from FW -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * limit build always needs spin-lock declaration. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add P2P FSM code check in. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Update P2P FSM. -+ * -+ * 07 09 2010 george.huang -+ * -+ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix compile error while enable WIFI_DIRECT support. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Update P2P Function call. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * First draft for migration P2P FSM from FW to Driver. -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support and will send Null frame to diagnose connection -+ * -+ * 03 18 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Rename CFG flag for P2P -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add code to test P2P GO -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add Wi-Fi Direct SSID and P2P GO Test Mode -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Modify code due to BAND_24G define was changed -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Revise data structure to share the same BSS_INFO_T for avoiding coding error -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugP2pState[P2P_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("P2P_STATE_IDLE"), -+ (PUINT_8) DISP_STRING("P2P_STATE_SCAN"), -+ (PUINT_8) DISP_STRING("P2P_STATE_AP_CHANNEL_DETECT"), -+ (PUINT_8) DISP_STRING("P2P_STATE_REQING_CHANNEL"), -+ (PUINT_8) DISP_STRING("P2P_STATE_CHNL_ON_HAND"), -+ (PUINT_8) DISP_STRING("P2P_STATE_GC_JOIN") -+}; -+ -+/*lint -restore */ -+#else -+static UINT_8 apucDebugP2pState[P2P_STATE_NUM] = { -+ P2P_STATE_IDLE, -+ P2P_STATE_SCAN, -+ P2P_STATE_AP_CHANNEL_DETECT, -+ P2P_STATE_REQING_CHANNEL, -+ P2P_STATE_CHNL_ON_HAND, -+ P2P_STATE_GC_JOIN -+}; -+ -+#endif /* DBG */ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/* p2pStateXXX : Processing P2P FSM related action. -+ * p2pFSMXXX : Control P2P FSM flow. -+ * p2pFuncXXX : Function for doing one thing. -+ */ -+VOID p2pFsmInit(IN P_ADAPTER_T prAdapter) -+{ -+ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ ASSERT_BREAK(prP2pFsmInfo != NULL); -+ -+ LINK_INITIALIZE(&(prP2pFsmInfo->rMsgEventQueue)); -+ LINK_INITIALIZE(&(prP2pBssInfo->rStaRecOfClientList)); -+ -+ prP2pFsmInfo->eCurrentState = prP2pFsmInfo->ePreviousState = P2P_STATE_IDLE; -+ prP2pFsmInfo->prTargetBss = NULL; -+ prP2pFsmInfo->fgIsWPSMode = 0; -+ -+ cnmTimerInitTimer(prAdapter, -+ &(prAdapter->rP2pFsmTimeoutTimer), -+ (PFN_MGMT_TIMEOUT_FUNC) p2pFsmRunEventFsmTimeout, (ULONG) prP2pFsmInfo); -+ -+ /* 4 <2> Initiate BSS_INFO_T - common part */ -+ BSS_INFO_INIT(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* 4 <2.1> Initiate BSS_INFO_T - Setup HW ID */ -+ prP2pBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P; -+ prP2pBssInfo->ucHwDefaultFixedRateCode = RATE_OFDM_6M; -+ -+ prP2pBssInfo->ucNonHTBasicPhyType = (UINT_8) -+ rNonHTApModeAttributes[prP2pBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; -+ prP2pBssInfo->u2BSSBasicRateSet = -+ rNonHTApModeAttributes[prP2pBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; -+ -+ prP2pBssInfo->u2OperationalRateSet = -+ rNonHTPhyAttributes[prP2pBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; -+ -+ rateGetDataRatesFromRateSet(prP2pBssInfo->u2OperationalRateSet, -+ prP2pBssInfo->u2BSSBasicRateSet, -+ prP2pBssInfo->aucAllSupportedRates, &prP2pBssInfo->ucAllSupportedRatesLen); -+ -+ prP2pBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH); -+ -+ if (prP2pBssInfo->prBeacon) { -+ prP2pBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; -+ prP2pBssInfo->prBeacon->ucStaRecIndex = 0xFF; /* NULL STA_REC */ -+ prP2pBssInfo->prBeacon->ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ } else { -+ /* Out of memory. */ -+ ASSERT(FALSE); -+ } -+ -+ prP2pBssInfo->eCurrentOPMode = OP_MODE_NUM; -+ -+ prP2pBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; -+ prP2pBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; -+ prP2pBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; -+ prP2pBssInfo->ucPrimaryChannel = P2P_DEFAULT_LISTEN_CHANNEL; -+ prP2pBssInfo->eBand = BAND_2G4; -+ prP2pBssInfo->eBssSCO = CHNL_EXT_SCN; -+ -+ if (prAdapter->rWifiVar.fgSupportQoS) -+ prP2pBssInfo->fgIsQBSS = TRUE; -+ else -+ prP2pBssInfo->fgIsQBSS = FALSE; -+ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ -+ } while (FALSE); -+ -+} /* p2pFsmInit */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The function is used to uninitialize the value in P2P_FSM_INFO_T for -+* P2P FSM operation -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmUninit(IN P_ADAPTER_T prAdapter) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ DEBUGFUNC("p2pFsmUninit()"); -+ DBGLOG(P2P, INFO, "->p2pFsmUninit()\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ p2pFuncSwitchOPMode(prAdapter, prP2pBssInfo, OP_MODE_P2P_DEVICE, TRUE); -+ -+ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); -+ -+ p2pStateAbort_IDLE(prAdapter, prP2pFsmInfo, P2P_STATE_NUM); -+ -+ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ wlanAcquirePowerControl(prAdapter); -+ -+ /* Release all pending CMD queue. */ -+ DBGLOG(P2P, TRACE, "p2pFsmUninit: wlanProcessCommandQueue, num of element:%d\n", -+ (UINT_32) prAdapter->prGlueInfo->rCmdQueue.u4NumElem); -+ wlanProcessCommandQueue(prAdapter, &prAdapter->prGlueInfo->rCmdQueue); -+ -+ wlanReleasePowerControl(prAdapter); -+ -+ /* Release pending mgmt frame, -+ * mgmt frame may be pending by CMD without resource. -+ */ -+ kalClearMgmtFramesByNetType(prAdapter->prGlueInfo, NETWORK_TYPE_P2P_INDEX); -+ -+ /* Clear PendingCmdQue */ -+ wlanReleasePendingCMDbyNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ if (prP2pBssInfo->prBeacon) { -+ cnmMgtPktFree(prAdapter, prP2pBssInfo->prBeacon); -+ prP2pBssInfo->prBeacon = NULL; -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* end of p2pFsmUninit() */ -+ -+VOID p2pFsmStateTransition(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ BOOLEAN fgIsTransOut = (BOOLEAN) FALSE; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ if (!IS_BSS_ACTIVE(prP2pBssInfo)) { -+ if (!cnmP2PIsPermitted(prAdapter)) -+ return; -+ -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ fgIsTransOut = fgIsTransOut ? FALSE : TRUE; -+ -+ if (!fgIsTransOut) { -+#if DBG -+ DBGLOG(P2P, STATE, "TRANSITION: [%s] -> [%s]\n", -+ apucDebugP2pState[prP2pFsmInfo->eCurrentState], -+ apucDebugP2pState[eNextState]); -+#else -+ DBGLOG(P2P, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", -+ DBG_P2P_IDX, apucDebugP2pState[prP2pFsmInfo->eCurrentState], -+ apucDebugP2pState[eNextState]); -+#endif -+ -+ /* Transition into current state. */ -+ prP2pFsmInfo->ePreviousState = prP2pFsmInfo->eCurrentState; -+ prP2pFsmInfo->eCurrentState = eNextState; -+ } -+ -+ switch (prP2pFsmInfo->eCurrentState) { -+ case P2P_STATE_IDLE: -+ if (fgIsTransOut) -+ p2pStateAbort_IDLE(prAdapter, prP2pFsmInfo, eNextState); -+ else -+ fgIsTransOut = p2pStateInit_IDLE(prAdapter, prP2pFsmInfo, prP2pBssInfo, &eNextState); -+ break; -+ case P2P_STATE_SCAN: -+ if (fgIsTransOut) { -+ /* Scan done / scan canceled. */ -+ p2pStateAbort_SCAN(prAdapter, prP2pFsmInfo, eNextState); -+ } else { -+ /* Initial scan request. */ -+ p2pStateInit_SCAN(prAdapter, prP2pFsmInfo); -+ } -+ -+ break; -+ case P2P_STATE_AP_CHANNEL_DETECT: -+ if (fgIsTransOut) { -+ /* Scan done */ -+ /* Get sparse channel result. */ -+ p2pStateAbort_AP_CHANNEL_DETECT(prAdapter, -+ prP2pFsmInfo, prP2pSpecificBssInfo, eNextState); -+ } -+ -+ else { -+ /* Initial passive scan request. */ -+ p2pStateInit_AP_CHANNEL_DETECT(prAdapter, prP2pFsmInfo); -+ } -+ -+ break; -+ case P2P_STATE_REQING_CHANNEL: -+ if (fgIsTransOut) { -+ /* Channel on hand / Channel canceled. */ -+ p2pStateAbort_REQING_CHANNEL(prAdapter, prP2pFsmInfo, eNextState); -+ } else { -+ /* Initial channel request. */ -+ p2pFuncAcquireCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); -+ } -+ -+ break; -+ case P2P_STATE_CHNL_ON_HAND: -+ if (fgIsTransOut) { -+ p2pStateAbort_CHNL_ON_HAND(prAdapter, prP2pFsmInfo, prP2pBssInfo, eNextState); -+ } else { -+ /* Initial channel ready. */ -+ /* Send channel ready event. */ -+ /* Start a FSM timer. */ -+ p2pStateInit_CHNL_ON_HAND(prAdapter, prP2pBssInfo, prP2pFsmInfo); -+ } -+ -+ break; -+ case P2P_STATE_GC_JOIN: -+ if (fgIsTransOut) { -+ /* Join complete / join canceled. */ -+ p2pStateAbort_GC_JOIN(prAdapter, prP2pFsmInfo, &(prP2pFsmInfo->rJoinInfo), eNextState); -+ } else { -+ if (prP2pFsmInfo->prTargetBss == NULL) { -+ ASSERT(FALSE); -+ } else { -+ /* Send request to SAA module. */ -+ p2pStateInit_GC_JOIN(prAdapter, -+ prP2pFsmInfo, -+ prP2pBssInfo, -+ &(prP2pFsmInfo->rJoinInfo), prP2pFsmInfo->prTargetBss); -+ } -+ } -+ -+ break; -+ default: -+ break; -+ } -+ -+ } while (fgIsTransOut); -+ -+} /* p2pFsmStateTransition */ -+ -+VOID p2pFsmRunEventSwitchOPMode(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_MSG_P2P_SWITCH_OP_MODE_T prSwitchOpMode = (P_MSG_P2P_SWITCH_OP_MODE_T) prMsgHdr; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwitchOpMode != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventSwitchOPMode\n"); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ if (prSwitchOpMode->eOpMode >= OP_MODE_NUM) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ /* P2P Device / GC. */ -+ p2pFuncSwitchOPMode(prAdapter, prP2pBssInfo, prSwitchOpMode->eOpMode, TRUE); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventSwitchOPMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to handle scan done event during Device Discovery. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; -+ P_MSG_SCN_SCAN_DONE prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) NULL; -+ ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ /* This scan done event is either for "SCAN" phase or "SEARCH" state or "LISTEN" state. -+ * The scan done for SCAN phase & SEARCH state doesn't imply Device -+ * Discovery over. -+ */ -+ DBGLOG(P2P, TRACE, "P2P Scan Done Event\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; -+ -+ if (prScanDoneMsg->ucSeqNum != prScanReqInfo->ucSeqNumOfScnMsg) { -+ /* Scan Done message sequence number mismatch. -+ * Ignore this event. (P2P FSM issue two scan events.) -+ */ -+ /* The scan request has been cancelled. -+ * Ignore this message. It is possible. -+ */ -+ DBGLOG(P2P, TRACE, "P2P Scan Don SeqNum:%d <-> P2P Fsm SCAN Msg:%d\n", -+ prScanDoneMsg->ucSeqNum, prScanReqInfo->ucSeqNumOfScnMsg); -+ -+ break; -+ } -+ -+ switch (prP2pFsmInfo->eCurrentState) { -+ case P2P_STATE_SCAN: -+ { -+ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); -+ -+ prScanReqInfo->fgIsAbort = FALSE; -+ -+ if (prConnReqInfo->fgIsConnRequest) { -+ prP2pFsmInfo->prTargetBss = p2pFuncKeepOnConnection(prAdapter, -+ &prP2pFsmInfo->rConnReqInfo, -+ &prP2pFsmInfo->rChnlReqInfo, -+ &prP2pFsmInfo->rScanReqInfo); -+ if (prP2pFsmInfo->prTargetBss == NULL) -+ eNextState = P2P_STATE_SCAN; -+ else -+ eNextState = P2P_STATE_REQING_CHANNEL; -+ } else { -+ eNextState = P2P_STATE_IDLE; -+ } -+ -+ } -+ break; -+ case P2P_STATE_AP_CHANNEL_DETECT: -+ eNextState = P2P_STATE_REQING_CHANNEL; -+ break; -+ default: -+ /* Unexpected channel scan done event without being chanceled. */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prScanReqInfo->fgIsScanRequest = FALSE; -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventScanDone */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is call when channel is granted by CNM module from FW. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ P_MSG_CH_GRANT_T prMsgChGrant = (P_MSG_CH_GRANT_T) NULL; -+ UINT_8 ucTokenID = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "P2P Run Event Channel Grant\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr; -+ ucTokenID = prMsgChGrant->ucTokenID; -+ prP2pFsmInfo->u4GrantInterval = prMsgChGrant->u4GrantInterval; -+ -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ if (ucTokenID == prChnlReqInfo->ucSeqNumOfChReq) { -+ ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM; -+ -+ switch (prP2pFsmInfo->eCurrentState) { -+ case P2P_STATE_REQING_CHANNEL: -+ switch (prChnlReqInfo->eChannelReqType) { -+ case CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL: -+ eNextState = P2P_STATE_CHNL_ON_HAND; -+ break; -+ case CHANNEL_REQ_TYPE_GC_JOIN_REQ: -+ eNextState = P2P_STATE_GC_JOIN; -+ break; -+ case CHANNEL_REQ_TYPE_GO_START_BSS: -+ eNextState = P2P_STATE_IDLE; -+ break; -+ default: -+ break; -+ } -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState); -+ break; -+ default: -+ /* Channel is granted under unexpected state. -+ * Driver should cancel channel privileagea before leaving the states. -+ */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ } else { -+ /* Channel requsted, but released. */ -+ /* ASSERT(!prChnlReqInfo->fgIsChannelRequested); */ -+ DBGLOG(P2P, TRACE, "Channel requsted, but released\n"); -+ } -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ return; -+ -+} /* p2pFsmRunEventChGrant */ -+ -+VOID p2pFsmRunEventChannelRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ P_MSG_P2P_CHNL_REQUEST_T prP2pChnlReqMsg = (P_MSG_P2P_CHNL_REQUEST_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prP2pChnlReqMsg = (P_MSG_P2P_CHNL_REQUEST_T) prMsgHdr; -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventChannelRequest\n"); -+ -+ /* Special case of time renewing for same frequency. */ -+ if ((prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND) && -+ (prChnlReqInfo->ucReqChnlNum == prP2pChnlReqMsg->rChannelInfo.ucChannelNum) && -+ (prChnlReqInfo->eBand == prP2pChnlReqMsg->rChannelInfo.eBand) && -+ (prChnlReqInfo->eChnlSco == prP2pChnlReqMsg->eChnlSco)) { -+ -+ ASSERT(prChnlReqInfo->fgIsChannelRequested == TRUE); -+ ASSERT(prChnlReqInfo->eChannelReqType == CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL); -+ -+ prChnlReqInfo->u8Cookie = prP2pChnlReqMsg->u8Cookie; -+ prChnlReqInfo->u4MaxInterval = prP2pChnlReqMsg->u4Duration; -+ -+ /* Re-enter the state. */ -+ eNextState = P2P_STATE_CHNL_ON_HAND; -+ } else { -+ -+ /* Make sure the state is in IDLE state. */ -+ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); -+ -+ /* Cookie can only be assign after abort.(for indication) */ -+ prChnlReqInfo->u8Cookie = prP2pChnlReqMsg->u8Cookie; -+ prChnlReqInfo->ucReqChnlNum = prP2pChnlReqMsg->rChannelInfo.ucChannelNum; -+ prChnlReqInfo->eBand = prP2pChnlReqMsg->rChannelInfo.eBand; -+ prChnlReqInfo->eChnlSco = prP2pChnlReqMsg->eChnlSco; -+ prChnlReqInfo->u4MaxInterval = prP2pChnlReqMsg->u4Duration; -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL; -+ -+ eNextState = P2P_STATE_REQING_CHANNEL; -+ } -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventChannelRequest */ -+ -+VOID p2pFsmRunEventChannelAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_MSG_P2P_CHNL_ABORT_T prChnlAbortMsg = (P_MSG_P2P_CHNL_ABORT_T) NULL; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prChnlAbortMsg = (P_MSG_P2P_CHNL_ABORT_T) prMsgHdr; -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventChannelAbort\n"); -+ -+ if ((prChnlAbortMsg->u8Cookie == prChnlReqInfo->u8Cookie) && (prChnlReqInfo->fgIsChannelRequested)) { -+ -+ ASSERT((prP2pFsmInfo->eCurrentState == P2P_STATE_REQING_CHANNEL || -+ (prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND))); -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventChannelAbort */ -+ -+VOID p2pFsmRunEventScanRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_MSG_P2P_SCAN_REQUEST_T prP2pScanReqMsg = (P_MSG_P2P_SCAN_REQUEST_T) NULL; -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; -+ UINT_32 u4ChnlListSize = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prP2pScanReqMsg = (P_MSG_P2P_SCAN_REQUEST_T) prMsgHdr; -+ prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventScanRequest\n"); -+ -+ /* Make sure the state is in IDLE state. */ -+ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); -+ -+ ASSERT(prScanReqInfo->fgIsScanRequest == FALSE); -+ -+ prScanReqInfo->fgIsAbort = TRUE; -+ prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+ prScanReqInfo->eChannelSet = SCAN_CHANNEL_SPECIFIED; -+ -+ /* Channel List */ -+ prScanReqInfo->ucNumChannelList = prP2pScanReqMsg->u4NumChannel; -+ DBGLOG(P2P, TRACE, "Scan Request Channel List Number: %d\n", prScanReqInfo->ucNumChannelList); -+ if (prScanReqInfo->ucNumChannelList > MAXIMUM_OPERATION_CHANNEL_LIST) { -+ DBGLOG(P2P, TRACE, "Channel List Number Overloaded: %d, change to: %d\n", -+ prScanReqInfo->ucNumChannelList, MAXIMUM_OPERATION_CHANNEL_LIST); -+ prScanReqInfo->ucNumChannelList = MAXIMUM_OPERATION_CHANNEL_LIST; -+ } -+ -+ u4ChnlListSize = sizeof(RF_CHANNEL_INFO_T) * prScanReqInfo->ucNumChannelList; -+ kalMemCopy(prScanReqInfo->arScanChannelList, prP2pScanReqMsg->arChannelListInfo, u4ChnlListSize); -+ -+ /* TODO: I only take the first SSID. Multiple SSID may be needed in the future. */ -+ /* SSID */ -+ if (prP2pScanReqMsg->i4SsidNum >= 1) -+ kalMemCopy(&(prScanReqInfo->rSsidStruct), prP2pScanReqMsg->prSSID, sizeof(P2P_SSID_STRUCT_T)); -+ else -+ prScanReqInfo->rSsidStruct.ucSsidLen = 0; -+ -+ /* IE Buffer */ -+ kalMemCopy(prScanReqInfo->aucIEBuf, prP2pScanReqMsg->pucIEBuf, prP2pScanReqMsg->u4IELen); -+ -+ prScanReqInfo->u4BufLength = prP2pScanReqMsg->u4IELen; -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventScanRequest */ -+ -+VOID p2pFsmRunEventScanAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventScanAbort\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo->eCurrentState == P2P_STATE_SCAN) { -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ -+ prScanReqInfo->fgIsAbort = TRUE; -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventScanAbort */ -+ -+VOID p2pFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventAbort\n"); -+ -+ if (prP2pFsmInfo->eCurrentState != P2P_STATE_IDLE) { -+ -+ if (prP2pFsmInfo->eCurrentState == P2P_STATE_SCAN) { -+ -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ -+ prScanReqInfo->fgIsAbort = TRUE; -+ } else if (prP2pFsmInfo->eCurrentState == P2P_STATE_REQING_CHANNEL) { -+ /* 2012/08/06: frog -+ * Prevent Start GO. -+ */ -+ prP2pBssInfo->eIntendOPMode = OP_MODE_NUM; -+ } -+ /* For other state, is there any special action that should be take before leaving? */ -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ } else { -+ /* P2P State IDLE. */ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ if (prChnlReqInfo->fgIsChannelRequested) -+ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); -+ -+ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); -+ } -+ -+ } while (FALSE); -+ -+} /* p2pFsmRunEventAbort */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to handle FSM Timeout. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventFsmTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) ulParam; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ DBGLOG(P2P, TRACE, "P2P FSM Timeout Event\n"); -+ -+ switch (prP2pFsmInfo->eCurrentState) { -+ case P2P_STATE_IDLE: -+ { -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; -+ -+ if (prChnlReqInfo->fgIsChannelRequested) { -+ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); -+ } else if (IS_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { -+ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ } -+ break; -+ -+/* case P2P_STATE_SCAN: */ -+/* break; */ -+/* case P2P_STATE_AP_CHANNEL_DETECT: */ -+/* break; */ -+/* case P2P_STATE_REQING_CHANNEL: */ -+/* break; */ -+ case P2P_STATE_CHNL_ON_HAND: -+ switch (prP2pFsmInfo->eListenExted) { -+ case P2P_DEV_NOT_EXT_LISTEN: -+ case P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT: -+ DBGLOG(P2P, INFO, "p2p timeout, state==P2P_STATE_CHNL_ON_HAND, eListenExted: %d\n", -+ prP2pFsmInfo->eListenExted); -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN; -+ break; -+ case P2P_DEV_EXT_LISTEN_ING: -+ DBGLOG(P2P, INFO, "p2p timeout, state==P2P_STATE_CHNL_ON_HAND, eListenExted: %d\n", -+ prP2pFsmInfo->eListenExted); -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_CHNL_ON_HAND); -+ prP2pFsmInfo->eListenExted = P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT; -+ break; -+ default: -+ ASSERT(FALSE); -+ DBGLOG(P2P, ERROR, -+ "Current P2P State %d is unexpected for FSM timeout event.\n", -+ prP2pFsmInfo->eCurrentState); -+ } -+ break; -+/* case P2P_STATE_GC_JOIN: */ -+/* break; */ -+ default: -+ break; -+ } -+ -+ } while (FALSE); -+ -+} /* p2pFsmRunEventFsmTimeout */ -+ -+VOID p2pFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_MSG_P2P_MGMT_TX_REQUEST_T prMgmtTxMsg = (P_MSG_P2P_MGMT_TX_REQUEST_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventMgmtFrameTx\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prMgmtTxMsg = (P_MSG_P2P_MGMT_TX_REQUEST_T) prMsgHdr; -+ -+ p2pFuncTxMgmtFrame(prAdapter, -+ &prP2pFsmInfo->rMgmtTxInfo, prMgmtTxMsg->prMgmtMsduInfo, prMgmtTxMsg->u8Cookie); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ return; -+ -+} /* p2pFsmRunEventMgmtTx */ -+ -+VOID p2pFsmRunEventStartAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_MSG_P2P_START_AP_T prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventStartAP\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) prMsgHdr; -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ if (prP2pStartAPMsg->u4BcnInterval) { -+ DBGLOG(P2P, TRACE, "Beacon interval updated to :%u\n", prP2pStartAPMsg->u4BcnInterval); -+ prP2pBssInfo->u2BeaconInterval = (UINT_16) prP2pStartAPMsg->u4BcnInterval; -+ } else if (prP2pBssInfo->u2BeaconInterval == 0) { -+ prP2pBssInfo->u2BeaconInterval = DOT11_BEACON_PERIOD_DEFAULT; -+ } -+ -+ if (prP2pStartAPMsg->u4DtimPeriod) { -+ DBGLOG(P2P, TRACE, "DTIM interval updated to :%u\n", prP2pStartAPMsg->u4DtimPeriod); -+ prP2pBssInfo->ucDTIMPeriod = (UINT_8) prP2pStartAPMsg->u4DtimPeriod; -+ } else if (prP2pBssInfo->ucDTIMPeriod == 0) { -+ prP2pBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; -+ } -+ -+ if (prP2pStartAPMsg->u2SsidLen != 0) { -+ kalMemCopy(prP2pBssInfo->aucSSID, prP2pStartAPMsg->aucSsid, prP2pStartAPMsg->u2SsidLen); -+ kalMemCopy(prP2pSpecificBssInfo->aucGroupSsid, prP2pStartAPMsg->aucSsid, -+ prP2pStartAPMsg->u2SsidLen); -+ prP2pBssInfo->ucSSIDLen = prP2pSpecificBssInfo->u2GroupSsidLen = prP2pStartAPMsg->u2SsidLen; -+ } -+ -+ prP2pBssInfo->eHiddenSsidType = prP2pStartAPMsg->ucHiddenSsidType; -+ -+ /* TODO: JB */ -+ /* Privacy & inactive timeout. */ -+ -+ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || -+ (prP2pBssInfo->eIntendOPMode != OP_MODE_NUM)) { -+ UINT_8 ucPreferedChnl = 0; -+ ENUM_BAND_T eBand = BAND_NULL; -+ ENUM_CHNL_EXT_T eSco = CHNL_EXT_SCN; -+ ENUM_P2P_STATE_T eNextState = P2P_STATE_SCAN; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ if (prP2pFsmInfo->eCurrentState != P2P_STATE_SCAN && -+ prP2pFsmInfo->eCurrentState != P2P_STATE_IDLE) { -+ /* Make sure the state is in IDLE state. */ -+ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); -+ } -+ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 0; -+ DBGLOG(P2P, INFO, -+ "NFC:p2pFsmRunEventStartAP,fgIsGOInitialDone[%d]\n", -+ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone); -+ -+ /* 20120118: Moved to p2pFuncSwitchOPMode(). */ -+ /* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+ /* Leave IDLE state. */ -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* sync with firmware */ -+ /* DBGLOG(P2P, INFO, ("Activate P2P Network.\n")); */ -+ /* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+ /* Key to trigger P2P FSM to allocate channel for AP mode. */ -+ prP2pBssInfo->eIntendOPMode = OP_MODE_ACCESS_POINT; -+ -+ /* Sparse Channel to decide which channel to use. */ -+ if ((cnmPreferredChannel(prAdapter, -+ &eBand, -+ &ucPreferedChnl, -+ &eSco) == FALSE) && (prP2pConnSettings->ucOperatingChnl == 0)) { -+ /* Sparse Channel Detection using passive mode. */ -+ eNextState = P2P_STATE_AP_CHANNEL_DETECT; -+ } else { -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = -+ prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; -+ -+#if 1 -+ /* 2012-01-27: frog - Channel set from upper layer is the first priority. */ -+ /* Because the channel & beacon is decided by p2p_supplicant. */ -+ if (prP2pConnSettings->ucOperatingChnl != 0) { -+ prP2pSpecificBssInfo->ucPreferredChannel = prP2pConnSettings->ucOperatingChnl; -+ prP2pSpecificBssInfo->eRfBand = prP2pConnSettings->eBand; -+ } -+ -+ else { -+ ASSERT(ucPreferedChnl != 0); -+ prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl; -+ prP2pSpecificBssInfo->eRfBand = eBand; -+ } -+#else -+ if (ucPreferedChnl) { -+ prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl; -+ prP2pSpecificBssInfo->eRfBand = eBand; -+ } else { -+ ASSERT(prP2pConnSettings->ucOperatingChnl != 0); -+ prP2pSpecificBssInfo->ucPreferredChannel = prP2pConnSettings->ucOperatingChnl; -+ prP2pSpecificBssInfo->eRfBand = prP2pConnSettings->eBand; -+ } -+ -+#endif -+ prChnlReqInfo->ucReqChnlNum = prP2pSpecificBssInfo->ucPreferredChannel; -+ prChnlReqInfo->eBand = prP2pSpecificBssInfo->eRfBand; -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; -+ -+ DBGLOG(P2P, INFO, "p2pFsmRunEventStartAP GO Scan\n"); -+ } -+ -+ /* If channel is specified, use active scan to shorten the scan time. */ -+ p2pFsmStateTransition(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo, eNextState); -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventStartAP */ -+ -+VOID p2pFsmRunEventNetDeviceRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_P2P_NETDEV_REGISTER_T prNetDevRegisterMsg = (P_MSG_P2P_NETDEV_REGISTER_T) NULL; -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventNetDeviceRegister\n"); -+ -+ prNetDevRegisterMsg = (P_MSG_P2P_NETDEV_REGISTER_T) prMsgHdr; -+ -+ if (prNetDevRegisterMsg->fgIsEnable) { -+ p2pSetMode((prNetDevRegisterMsg->ucMode == 1) ? TRUE : FALSE); -+ -+ if (p2pLaunch(prAdapter->prGlueInfo)) -+ ASSERT(prAdapter->fgIsP2PRegistered); -+ -+ } else { -+ if (prAdapter->fgIsP2PRegistered) -+ p2pRemove(prAdapter->prGlueInfo); -+ -+ } -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventNetDeviceRegister */ -+ -+VOID p2pFsmRunEventUpdateMgmtFrame(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_P2P_MGMT_FRAME_UPDATE_T prP2pMgmtFrameUpdateMsg = (P_MSG_P2P_MGMT_FRAME_UPDATE_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventUpdateMgmtFrame\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prP2pMgmtFrameUpdateMsg = (P_MSG_P2P_MGMT_FRAME_UPDATE_T) prMsgHdr; -+ -+ switch (prP2pMgmtFrameUpdateMsg->eBufferType) { -+ case ENUM_FRAME_TYPE_EXTRA_IE_BEACON: -+ break; -+ case ENUM_FRAME_TYPE_EXTRA_IE_ASSOC_RSP: -+ break; -+ case ENUM_FRAME_TYPE_EXTRA_IE_PROBE_RSP: -+ break; -+ case ENUM_FRAME_TYPE_PROBE_RSP_TEMPLATE: -+ break; -+ case ENUM_FRAME_TYPE_BEACON_TEMPLATE: -+ break; -+ default: -+ break; -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventUpdateMgmtFrame */ -+ -+VOID p2pFsmRunEventBeaconUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_MSG_P2P_BEACON_UPDATE_T prBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventBeaconUpdate\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) prMsgHdr; -+ -+ p2pFuncBeaconUpdate(prAdapter, -+ prP2pBssInfo, -+ &prP2pFsmInfo->rBcnContentInfo, -+ prBcnUpdateMsg->pucBcnHdr, -+ prBcnUpdateMsg->u4BcnHdrLen, -+ prBcnUpdateMsg->pucBcnBody, prBcnUpdateMsg->u4BcnBodyLen); -+ -+ if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) && -+ (prP2pBssInfo->eIntendOPMode == OP_MODE_NUM)) { -+ /* AP is created, Beacon Update. */ -+ /* nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventBeaconUpdate */ -+ -+VOID p2pFsmRunEventStopAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventStopAP\n"); -+ -+ if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) -+ && (prP2pBssInfo->eIntendOPMode == OP_MODE_NUM)) { -+ /* AP is created, Beacon Update. */ -+ -+ p2pFuncDissolve(prAdapter, prP2pBssInfo, TRUE, REASON_CODE_DEAUTH_LEAVING_BSS); -+ -+ DBGLOG(P2P, TRACE, "Stop Beaconing\n"); -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* Reset RLM related field of BSSINFO. */ -+ rlmBssAborted(prAdapter, prP2pBssInfo); -+ } -+ /* 20120118: Moved to p2pFuncSwitchOPMode(). */ -+ /* UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+ /* Enter IDLE state. */ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ DBGLOG(P2P, INFO, "Re activate P2P Network.\n"); -+ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+#if CFG_SUPPORT_WFD -+ p2pFsmRunEventWfdSettingUpdate(prAdapter, NULL); -+#endif -+ -+ /* p2pFsmRunEventAbort(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo); */ -+ p2pFsmStateTransition(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo, P2P_STATE_IDLE); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventStopAP */ -+ -+VOID p2pFsmRunEventConnectionRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ P_MSG_P2P_CONNECTION_REQUEST_T prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; -+ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) prMsgHdr; -+ -+ prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventConnectionRequest\n"); -+ -+ if (prP2pBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ break; -+ -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* Make sure the state is in IDLE state. */ -+ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); -+ -+ /* Update connection request information. */ -+ prConnReqInfo->fgIsConnRequest = TRUE; -+ COPY_MAC_ADDR(prConnReqInfo->aucBssid, prConnReqMsg->aucBssid); -+ kalMemCopy(&(prConnReqInfo->rSsidStruct), &(prConnReqMsg->rSsid), sizeof(P2P_SSID_STRUCT_T)); -+ kalMemCopy(prConnReqInfo->aucIEBuf, prConnReqMsg->aucIEBuf, prConnReqMsg->u4IELen); -+ prConnReqInfo->u4BufLength = prConnReqMsg->u4IELen; -+ -+ /* Find BSS Descriptor first. */ -+ prP2pFsmInfo->prTargetBss = scanP2pSearchDesc(prAdapter, prP2pBssInfo, prConnReqInfo); -+ -+ if (prP2pFsmInfo->prTargetBss == NULL) { -+ /* Update scan parameter... to scan target device. */ -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ -+ DBGLOG(P2P, INFO, "p2pFsmRunEventConnectionRequest,Trigger New Scan\n"); -+ -+ prScanReqInfo->ucNumChannelList = 1; -+ prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+ prScanReqInfo->eChannelSet = SCAN_CHANNEL_SPECIFIED; -+ prScanReqInfo->arScanChannelList[0].ucChannelNum = prConnReqMsg->rChannelInfo.ucChannelNum; -+ kalMemCopy(&(prScanReqInfo->rSsidStruct), &(prConnReqMsg->rSsid), sizeof(P2P_SSID_STRUCT_T)); -+ prScanReqInfo->u4BufLength = 0; /* Prevent other P2P ID in IE. */ -+ prScanReqInfo->fgIsAbort = TRUE; -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN); -+ } else { -+ prChnlReqInfo->u8Cookie = 0; -+ prChnlReqInfo->ucReqChnlNum = prConnReqMsg->rChannelInfo.ucChannelNum; -+ prChnlReqInfo->eBand = prConnReqMsg->rChannelInfo.eBand; -+ prChnlReqInfo->eChnlSco = prConnReqMsg->eChnlSco; -+ prChnlReqInfo->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL; -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GC_JOIN_REQ; -+ DBGLOG(P2P, INFO, "p2pFsmRunEventConnectionRequest, Report the Connecting BSS Again.\n"); -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_REQING_CHANNEL); -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ return; -+ -+} /* p2pFsmRunEventConnectionRequest */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to handle Connection Request from Supplicant. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventConnectionAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_MSG_P2P_CONNECTION_ABORT_T prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; -+ /* P_STA_RECORD_T prTargetStaRec = (P_STA_RECORD_T)NULL; */ -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventConnectionAbort: Connection Abort.\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) prMsgHdr; -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_INFRASTRUCTURE: -+ { -+ UINT_8 aucBCBSSID[] = BC_BSSID; -+ -+ if (!prP2pBssInfo->prStaRecOfAP) { -+ DBGLOG(P2P, TRACE, "GO's StaRec is NULL\n"); -+ break; -+ } -+ if (UNEQUAL_MAC_ADDR(prP2pBssInfo->prStaRecOfAP->aucMacAddr, prDisconnMsg->aucTargetID) -+ && UNEQUAL_MAC_ADDR(prDisconnMsg->aucTargetID, aucBCBSSID)) { -+ DBGLOG(P2P, TRACE, -+ "Unequal MAC ADDR [ %pM : %pM ]\n", -+ prP2pBssInfo->prStaRecOfAP->aucMacAddr, -+ prDisconnMsg->aucTargetID); -+ break; -+ } -+ -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ NULL, NULL, 0, 0, -+ WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY); -+ -+ /* Stop rejoin timer if it is started. */ -+ /* TODO: If it has. */ -+ -+ p2pFuncDisconnect(prAdapter, prP2pBssInfo->prStaRecOfAP, prDisconnMsg->fgSendDeauth, -+ prDisconnMsg->u2ReasonCode); -+ -+ /* prTargetStaRec = prP2pBssInfo->prStaRecOfAP; */ -+ -+ /* Fix possible KE when RX Beacon & call nicPmIndicateBssConnected(). */ -+ /* hit prStaRecOfAP == NULL. */ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ -+ } -+ break; -+ case OP_MODE_ACCESS_POINT: -+ { -+ P_LINK_T prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; -+ /* Search specific client device, and disconnect. */ -+ /* 1. Send deauthentication frame. */ -+ /* 2. Indication: Device disconnect. */ -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; -+ -+ DBGLOG(P2P, TRACE, -+ "Disconnecting with Target ID: %pM\n", -+ prDisconnMsg->aucTargetID); -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry); -+ -+ ASSERT(prCurrStaRec); -+ -+ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prDisconnMsg->aucTargetID)) { -+ -+ DBGLOG(P2P, TRACE, -+ "Disconnecting: %pM\n", -+ prCurrStaRec->aucMacAddr); -+ -+ /* Remove STA from client list. */ -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, -+ &prCurrStaRec->rLinkEntry); -+ -+ /* Glue layer indication. */ -+ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prCurrStaRec, FALSE); */ -+ -+ /* Send deauth & do indication. */ -+ p2pFuncDisconnect(prAdapter, prCurrStaRec, prDisconnMsg->fgSendDeauth, -+ prDisconnMsg->u2ReasonCode); -+ -+ /* prTargetStaRec = prCurrStaRec; */ -+ -+ break; -+ } -+ } -+ -+ } -+ break; -+ case OP_MODE_P2P_DEVICE: -+ default: -+ ASSERT(FALSE); -+ break; -+ } -+ -+ } while (FALSE); -+ -+ /* 20120830 moved into p2pFuncDisconnect() */ -+ /* if ((!prDisconnMsg->fgSendDeauth) && (prTargetStaRec)) { */ -+ /* cnmStaRecFree(prAdapter, prTargetStaRec, TRUE); */ -+ /* } */ -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventConnectionAbort */ -+ -+VOID p2pFsmRunEventDissolve(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ -+ /* TODO: */ -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventDissolve\n"); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -+ -+WLAN_STATUS -+p2pFsmRunEventDeauthTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ ENUM_PARAM_MEDIA_STATE_T eOriMediaStatus; -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ DBGLOG(P2P, INFO, "Deauth TX Done Status: %d, seqNo %d\n", -+ rTxDoneStatus, prMsduInfo->ucTxSeqNum); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (prStaRec == NULL) { -+ DBGLOG(P2P, TRACE, "Station Record NULL, Index:%d\n", prMsduInfo->ucStaRecIndex); -+ break; -+ } -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ eOriMediaStatus = prP2pBssInfo->eConnectionState; -+ /* Change station state. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ /* Reset Station Record Status. */ -+ p2pFuncResetStaRecStatus(prAdapter, prStaRec); -+ -+ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); -+ -+ /**/ cnmStaRecFree(prAdapter, prStaRec, TRUE); -+ -+ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || -+ (prP2pBssInfo->rStaRecOfClientList.u4NumElem == 0)) { -+ DBGLOG(P2P, TRACE, "No More Client, Media Status DISCONNECTED\n"); -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ } -+ -+ /* Because the eConnectionState is changed before Deauth TxDone. Dont Check eConnectionState */ -+ /* if (eOriMediaStatus != prP2pBssInfo->eConnectionState) { */ -+ /* Update Disconnected state to FW. */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ /* } */ -+ -+ } while (FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* p2pFsmRunEventDeauthTxDone */ -+ -+WLAN_STATUS -+p2pFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo = (P_P2P_MGMT_TX_REQ_INFO_T) NULL; -+ BOOLEAN fgIsSuccess = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prMgmtTxReqInfo = &(prP2pFsmInfo->rMgmtTxInfo); -+ -+ if (rTxDoneStatus != TX_RESULT_SUCCESS) { -+ DBGLOG(P2P, INFO, "Mgmt Frame TX Fail, Status: %d, seq NO. %d, Cookie: 0x%llx\n", -+ rTxDoneStatus, prMsduInfo->ucTxSeqNum, prMgmtTxReqInfo->u8Cookie); -+ } else { -+ fgIsSuccess = TRUE; -+ DBGLOG(P2P, TRACE, "Mgmt Frame TX Done.\n"); -+ } -+ -+ if (prMgmtTxReqInfo->prMgmtTxMsdu == prMsduInfo) { -+ kalP2PIndicateMgmtTxStatus(prAdapter->prGlueInfo, -+ prMgmtTxReqInfo->u8Cookie, -+ fgIsSuccess, -+ prMsduInfo->prPacket, (UINT_32) prMsduInfo->u2FrameLength); -+ -+ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; -+ } -+ -+ } while (FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* p2pFsmRunEventMgmtFrameTxDone */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called when JOIN complete message event is received from SAA. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_JOIN_INFO_T prJoinInfo = (P_P2P_JOIN_INFO_T) NULL; -+ P_MSG_JOIN_COMP_T prJoinCompMsg = (P_MSG_JOIN_COMP_T) NULL; -+ P_SW_RFB_T prAssocRspSwRfb = (P_SW_RFB_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ DBGLOG(P2P, TRACE, "P2P Join Complete\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ if (prP2pFsmInfo == NULL) { -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ prJoinInfo = &(prP2pFsmInfo->rJoinInfo); -+ if (prMsgHdr == NULL) -+ return; -+ prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr; -+ prAssocRspSwRfb = prJoinCompMsg->prSwRfb; -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ if (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ prStaRec = prJoinCompMsg->prStaRec; -+ -+ /* Check SEQ NUM */ -+ if (prJoinCompMsg->ucSeqNum == prJoinInfo->ucSeqNumOfReqMsg) { -+ ASSERT(prStaRec == prJoinInfo->prTargetStaRec); -+ prJoinInfo->fgIsJoinComplete = TRUE; -+ -+ if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { -+ -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */ -+ if ((prP2pBssInfo->prStaRecOfAP) && (prP2pBssInfo->prStaRecOfAP != prStaRec)) { -+ cnmStaRecChangeState(prAdapter, prP2pBssInfo->prStaRecOfAP, -+ STA_STATE_1); -+ -+ cnmStaRecFree(prAdapter, prP2pBssInfo->prStaRecOfAP, TRUE); -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ } -+ /* 4 <1.3> Update BSS_INFO_T */ -+ p2pFuncUpdateBssInfoForJOIN(prAdapter, prP2pFsmInfo->prTargetBss, prStaRec, -+ prAssocRspSwRfb); -+ -+ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ DBGLOG(P2P, INFO, "P2P GC Join Success\n"); -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ /* <1.5> Update RSSI if necessary */ -+ nicUpdateRSSI(prAdapter, NETWORK_TYPE_P2P_INDEX, -+ (INT_8) (RCPI_TO_dBm(prStaRec->ucRCPI)), 0); -+#endif -+ -+ /* 4 <1.6> Indicate Connected Event to Host immediately. */ -+ /* Require BSSID, Association ID, Beacon Interval.. from AIS_BSS_INFO_T */ -+ /* p2pIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, */ -+ /* prStaRec->aucMacAddr); */ -+ if (prP2pFsmInfo->prTargetBss) -+ scanReportBss2Cfg80211(prAdapter, OP_MODE_P2P_DEVICE, -+ prP2pFsmInfo->prTargetBss); -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ &prP2pFsmInfo->rConnReqInfo, -+ prJoinInfo->aucIEBuf, prJoinInfo->u4BufLength, -+ prStaRec->u2StatusCode, -+ WLAN_STATUS_MEDIA_CONNECT); -+ -+ } else { -+ /* Join Fail */ -+ /* 4 <2.1> Redo JOIN process with other Auth Type if possible */ -+ if (p2pFuncRetryJOIN(prAdapter, prStaRec, prJoinInfo) == FALSE) { -+ P_BSS_DESC_T prBssDesc; -+ -+ /* Increase Failure Count */ -+ prStaRec->ucJoinFailureCount++; -+ -+ prBssDesc = prP2pFsmInfo->prTargetBss; -+ -+ ASSERT(prBssDesc); -+ ASSERT(prBssDesc->fgIsConnecting); -+ -+ prBssDesc->fgIsConnecting = FALSE; -+ -+ if (prStaRec->ucJoinFailureCount >= 3) { -+ -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ &prP2pFsmInfo->rConnReqInfo, -+ prJoinInfo->aucIEBuf, -+ prJoinInfo->u4BufLength, -+ prStaRec->u2StatusCode, -+ WLAN_STATUS_MEDIA_CONNECT); -+ } else { -+ /* Sometime the GO is not ready to response auth. */ -+ /* Connect it again */ -+ prP2pFsmInfo->prTargetBss = NULL; -+ } -+ DBGLOG(P2P, INFO, "P2P GC Join Failed\n"); -+ -+ } -+ -+ } -+ } -+ } -+ -+ if (prAssocRspSwRfb) -+ nicRxReturnRFB(prAdapter, prAssocRspSwRfb); -+ -+ if (prP2pFsmInfo->eCurrentState == P2P_STATE_GC_JOIN) { -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == -+ PARAM_MEDIA_STATE_CONNECTED) { -+ /* Return to IDLE state. */ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ } else { -+ /* p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); */ -+ /* one more scan */ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN); -+ } -+ } -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventJoinComplete */ -+ -+VOID p2pFsmRunEventMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) prMsgHdr; -+ -+ p2pFuncMgmtFrameRegister(prAdapter, -+ prMgmtFrameRegister->u2FrameType, -+ prMgmtFrameRegister->fgIsRegister, &prP2pFsmInfo->u4P2pPacketFilter); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ return; -+ -+} /* p2pFsmRunEventMgmtFrameRegister */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is call when RX deauthentication frame from the AIR. -+* If we are under STA mode, we would go back to P2P Device. -+* If we are under AP mode, we would stay in AP mode until disconnect event from HOST. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventRxDeauthentication(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) -+{ -+ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ UINT_16 u2ReasonCode = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ if (prStaRec == NULL) -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ if (!prStaRec) -+ break; -+ -+ prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ -+ if (prStaRec->ucStaState == STA_STATE_1) -+ break; -+ -+ DBGLOG(P2P, TRACE, "RX Deauth\n"); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_INFRASTRUCTURE: -+ if (authProcessRxDeauthFrame(prSwRfb, -+ prStaRec->aucMacAddr, &u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ P_WLAN_DEAUTH_FRAME_T prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader; -+ UINT_16 u2IELength = 0; -+ -+ if (prP2pBssInfo->prStaRecOfAP != prStaRec) -+ break; -+ -+ prStaRec->u2ReasonCode = u2ReasonCode; -+ u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + REASON_CODE_FIELD_LEN); -+ -+ ASSERT(prP2pBssInfo->prStaRecOfAP == prStaRec); -+ -+ /* Indicate disconnect to Host. */ -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ NULL, -+ prDeauthFrame->aucInfoElem, u2IELength, u2ReasonCode, -+ WLAN_STATUS_MEDIA_DISCONNECT); -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ DBGLOG(P2P, INFO, "GC RX Deauth Reason: %d\n", u2ReasonCode); -+ -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ } -+ break; -+ case OP_MODE_ACCESS_POINT: -+ /* Delete client from client list. */ -+ if (authProcessRxDeauthFrame(prSwRfb, -+ prP2pBssInfo->aucBSSID, &u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; -+ -+ prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry); -+ -+ ASSERT(prCurrStaRec); -+ -+ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prStaRec->aucMacAddr)) { -+ -+ /* Remove STA from client list. */ -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, -+ &prCurrStaRec->rLinkEntry); -+ -+ /* Indicate to Host. */ -+ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); */ -+ -+ /* Indicate disconnect to Host. */ -+ DBGLOG(P2P, INFO, "GO RX Deauth Reason: %d\n", u2ReasonCode); -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); -+ -+ break; -+ } -+ } -+ } -+ break; -+ case OP_MODE_P2P_DEVICE: -+ default: -+ /* Findout why someone sent deauthentication frame to us. */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "Deauth Reason:%d\n", u2ReasonCode); -+ -+ } while (FALSE); -+} /* p2pFsmRunEventRxDeauthentication */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is call when RX deauthentication frame from the AIR. -+* If we are under STA mode, we would go back to P2P Device. -+* If we are under AP mode, we would stay in AP mode until disconnect event from HOST. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventRxDisassociation(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ UINT_16 u2ReasonCode = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ if (prStaRec == NULL) { -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ if (prStaRec == NULL) -+ break; -+ } -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ if (prStaRec->ucStaState == STA_STATE_1) -+ break; -+ -+ DBGLOG(P2P, TRACE, "RX Disassoc\n"); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_INFRASTRUCTURE: -+ if (assocProcessRxDisassocFrame(prAdapter, -+ prSwRfb, -+ prStaRec->aucMacAddr, -+ &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ P_WLAN_DISASSOC_FRAME_T prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; -+ UINT_16 u2IELength = 0; -+ -+ ASSERT(prP2pBssInfo->prStaRecOfAP == prStaRec); -+ -+ if (prP2pBssInfo->prStaRecOfAP != prStaRec) -+ break; -+ -+ u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + REASON_CODE_FIELD_LEN); -+ -+ /* Indicate disconnect to Host. */ -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ NULL, -+ prDisassocFrame->aucInfoElem, -+ u2IELength, prStaRec->u2ReasonCode, -+ WLAN_STATUS_MEDIA_DISCONNECT); -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ -+ DBGLOG(P2P, INFO, "GC RX Disassoc Reason %d\n", prStaRec->u2ReasonCode); -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, prStaRec->u2ReasonCode); -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ -+ } -+ break; -+ case OP_MODE_ACCESS_POINT: -+ /* Delete client from client list. */ -+ if (assocProcessRxDisassocFrame(prAdapter, -+ prSwRfb, -+ prP2pBssInfo->aucBSSID, &u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; -+ -+ prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry); -+ -+ ASSERT(prCurrStaRec); -+ -+ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prStaRec->aucMacAddr)) { -+ -+ /* Remove STA from client list. */ -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, -+ &prCurrStaRec->rLinkEntry); -+ -+ /* Indicate to Host. */ -+ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); */ -+ -+ /* Indicate disconnect to Host. */ -+ DBGLOG(P2P, INFO, "GO RX Disassoc Reason %d\n", u2ReasonCode); -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); -+ -+ break; -+ } -+ } -+ } -+ break; -+ case OP_MODE_P2P_DEVICE: -+ default: -+ ASSERT(FALSE); -+ break; -+ } -+ -+ } while (FALSE); -+} /* p2pFsmRunEventRxDisassociation */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called when a probe request frame is received. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return boolean value if probe response frame is accepted & need cancel scan request. -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventRxProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL) && (prBssDesc != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ -+ /* There is a connection request. */ -+ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; -+ -+ } while (FALSE); -+ -+} /* p2pFsmRunEventRxProbeResponseFrame */ -+ -+VOID p2pFsmRunEventBeaconTimeout(IN P_ADAPTER_T prAdapter) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventBeaconTimeout: Beacon Timeout\n"); -+ -+ /* Only client mode would have beacon lost event. */ -+ ASSERT(prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE); -+ -+ if (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* Indicate disconnect to Host. */ -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ NULL, NULL, 0, REASON_CODE_DISASSOC_INACTIVITY, -+ WLAN_STATUS_MEDIA_DISCONNECT); -+ -+ if (prP2pBssInfo->prStaRecOfAP != NULL) { -+ P_STA_RECORD_T prStaRec = prP2pBssInfo->prStaRecOfAP; -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, REASON_CODE_DISASSOC_LEAVING_BSS); -+ -+ /* 20120830 moved into p2pFuncDisconnect() */ -+ /* cnmStaRecFree(prAdapter, prP2pBssInfo->prStaRecOfAP, TRUE); */ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ -+ } -+ } -+ } while (FALSE); -+ -+} /* p2pFsmRunEventBeaconTimeout */ -+ -+VOID p2pFsmRunEventExtendListen(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = NULL; -+ struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *prExtListenMsg = NULL; -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prExtListenMsg = (struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *) prMsgHdr; -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ ASSERT_BREAK(prP2pFsmInfo); -+ -+ if (!prExtListenMsg->wait) { -+ DBGLOG(P2P, INFO, "reset listen interval\n"); -+ prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN; -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ if (prP2pFsmInfo && (prP2pFsmInfo->eListenExted == P2P_DEV_NOT_EXT_LISTEN)) { -+ DBGLOG(P2P, INFO, "try to ext listen, p2p state: %d\n", prP2pFsmInfo->eCurrentState); -+ if (prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND) { -+ DBGLOG(P2P, INFO, "here to ext listen interval\n"); -+ prP2pFsmInfo->eListenExted = P2P_DEV_EXT_LISTEN_ING; -+ } -+ } -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+} /* p2pFsmRunEventUpdateMgmtFrame */ -+ -+#if CFG_SUPPORT_WFD -+VOID p2pFsmRunEventWfdSettingUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgSettings = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL; -+ WLAN_STATUS rStatus; -+ -+ DBGLOG(P2P, INFO, "p2pFsmRunEventWfdSettingUpdate\n"); -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL)); -+ -+ if (prMsgHdr != NULL) { -+ prMsgWfdCfgSettings = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) prMsgHdr; -+ prWfdCfgSettings = prMsgWfdCfgSettings->prWfdCfgSettings; -+ } else { -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ } -+ -+ DBGLOG(P2P, INFO, "WFD Enalbe %x info %x state %x flag %x adv %x\n", -+ prWfdCfgSettings->ucWfdEnable, -+ prWfdCfgSettings->u2WfdDevInfo, -+ (UINT_32) prWfdCfgSettings->u4WfdState, -+ (UINT_32) prWfdCfgSettings->u4WfdFlag, -+ (UINT_32) prWfdCfgSettings->u4WfdAdvancedFlag); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_WFD_CTRL, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(WFD_CFG_SETTINGS_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prWfdCfgSettings, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ } while (FALSE); -+ -+ return; -+ -+} -+ -+/* p2pFsmRunEventWfdSettingUpdate */ -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate P2P IE for Beacon frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pGenerateP2P_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (prStaRec != NULL) { -+ if (IS_STA_P2P_TYPE(prStaRec)) { -+ /* Do nothing */ -+ /* TODO: */ -+ } -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* end of p2pGenerateP2P_IEForAssocReq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate P2P IE for Probe Request frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pGenerateP2P_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ ASSERT(prAdapter); -+ ASSERT(pucBuf); -+ -+ /* TODO: */ -+ -+ return; -+ -+} /* end of p2pGenerateP2P_IEForProbReq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to calculate P2P IE length for Beacon frame. -+* -+* @param[in] eNetTypeIndex Specify which network -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return The length of P2P IE added -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 -+p2pCalculateP2P_IELenForProbeReq(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ -+ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) -+ return 0; -+ /* TODO: */ -+ -+ return 0; -+ -+} /* end of p2pCalculateP2P_IELenForProbeReq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Event of Tx Fail of AAA Module. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); -+ -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, REASON_CODE_UNSPECIFIED); -+ -+ /* 20120830 moved into p2puUncDisconnect. */ -+ /* cnmStaRecFree(prAdapter, prStaRec, TRUE); */ -+ -+} /* p2pRunEventAAATxFail */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Event of Successful Completion of AAA Module. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS p2pRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ ENUM_PARAM_MEDIA_STATE_T eOriMediaState; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ eOriMediaState = prP2pBssInfo->eConnectionState; -+ -+ if (prStaRec != NULL) -+ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); -+ else -+ break; -+ -+ if (prP2pBssInfo->rStaRecOfClientList.u4NumElem > P2P_MAXIMUM_CLIENT_COUNT || -+ kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) { -+ rStatus = WLAN_STATUS_RESOURCES; -+ break; -+ } -+ -+ bssAddStaRecToClientList(prAdapter, prP2pBssInfo, prStaRec); -+ -+ prStaRec->u2AssocId = bssAssignAssocID(prStaRec); -+ -+ if (prP2pBssInfo->rStaRecOfClientList.u4NumElem > P2P_MAXIMUM_CLIENT_COUNT || -+ kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) { -+ rStatus = WLAN_STATUS_RESOURCES; -+ break; -+ } -+ DBGLOG(P2P, INFO, "P2P GO Join Complete\n"); -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* Update Connected state to FW. */ -+ if (eOriMediaState != prP2pBssInfo->eConnectionState) -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ } while (FALSE); -+ -+ return rStatus; -+} /* p2pRunEventAAAComplete */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Event of Successful Completion of AAA Module. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS p2pRunEventAAASuccess(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); -+ -+ /* Glue layer indication. */ -+ kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, TRUE); -+ -+ } while (FALSE); -+ -+ return rStatus; -+} /* p2pRunEventAAASuccess */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS p2pRxPublicActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_P2P_PUBLIC_ACTION_FRAME_T prPublicActionFrame = (P_P2P_PUBLIC_ACTION_FRAME_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ ASSERT(prSwRfb); -+ ASSERT(prAdapter); -+ -+ prPublicActionFrame = (P_P2P_PUBLIC_ACTION_FRAME_T) prSwRfb->pvHeader; -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ DBGLOG(P2P, TRACE, "RX Public Action Frame Token:%d.\n", prPublicActionFrame->ucDialogToken); -+ -+ if (prPublicActionFrame->ucCategory != CATEGORY_PUBLIC_ACTION) -+ return rWlanStatus; -+ -+ switch (prPublicActionFrame->ucAction) { -+ case ACTION_PUBLIC_WIFI_DIRECT: -+ break; -+ case ACTION_GAS_INITIAL_REQUEST: -+ case ACTION_GAS_INITIAL_RESPONSE: -+ case ACTION_GAS_COMEBACK_REQUEST: -+ case ACTION_GAS_COMEBACK_RESPONSE: -+ break; -+ default: -+ break; -+ } -+ -+ return rWlanStatus; -+} /* p2pRxPublicActionFrame */ -+ -+WLAN_STATUS p2pRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_P2P_ACTION_FRAME_T prP2pActionFrame = (P_P2P_ACTION_FRAME_T) NULL; -+ UINT_8 aucOui[3] = VENDOR_OUI_WFA_SPECIFIC; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ prP2pActionFrame = (P_P2P_ACTION_FRAME_T) prSwRfb->pvHeader; -+ -+ if (prP2pActionFrame->ucCategory != CATEGORY_VENDOR_SPECIFIC_ACTION) { -+ DBGLOG(P2P, TRACE, "RX Action Frame but not vendor specific.\n"); -+ break; -+ } -+ -+ if ((prP2pActionFrame->ucOuiType != VENDOR_OUI_TYPE_P2P) || -+ (prP2pActionFrame->aucOui[0] != aucOui[0]) || -+ (prP2pActionFrame->aucOui[1] != aucOui[1]) || (prP2pActionFrame->aucOui[2] != aucOui[2])) { -+ DBGLOG(P2P, TRACE, "RX Vendor Specific Action Frame but not P2P Type or not WFA OUI.\n"); -+ break; -+ } -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* p2pRxActionFrame */ -+ -+VOID -+p2pProcessEvent_UpdateNOAParam(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucNetTypeIndex, P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam) -+{ -+ P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; -+ UINT_32 i; -+ BOOLEAN fgNoaAttrExisted = FALSE; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIndex]); -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ prP2pSpecificBssInfo->fgEnableOppPS = prEventUpdateNoaParam->fgEnableOppPS; -+ prP2pSpecificBssInfo->u2CTWindow = prEventUpdateNoaParam->u2CTWindow; -+ prP2pSpecificBssInfo->ucNoAIndex = prEventUpdateNoaParam->ucNoAIndex; -+ prP2pSpecificBssInfo->ucNoATimingCount = prEventUpdateNoaParam->ucNoATimingCount; -+ -+ fgNoaAttrExisted |= prP2pSpecificBssInfo->fgEnableOppPS; -+ -+ DBGLOG(P2P, INFO, "Update NoA Count=%d.\n", prEventUpdateNoaParam->ucNoATimingCount); -+ -+ ASSERT(prP2pSpecificBssInfo->ucNoATimingCount <= P2P_MAXIMUM_NOA_COUNT); -+ -+ for (i = 0; i < prP2pSpecificBssInfo->ucNoATimingCount; i++) { -+ /* in used */ -+ prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse = prEventUpdateNoaParam->arEventNoaTiming[i].fgIsInUse; -+ /* count */ -+ prP2pSpecificBssInfo->arNoATiming[i].ucCount = prEventUpdateNoaParam->arEventNoaTiming[i].ucCount; -+ /* duration */ -+ prP2pSpecificBssInfo->arNoATiming[i].u4Duration = prEventUpdateNoaParam->arEventNoaTiming[i].u4Duration; -+ /* interval */ -+ prP2pSpecificBssInfo->arNoATiming[i].u4Interval = prEventUpdateNoaParam->arEventNoaTiming[i].u4Interval; -+ /* start time */ -+ prP2pSpecificBssInfo->arNoATiming[i].u4StartTime = -+ prEventUpdateNoaParam->arEventNoaTiming[i].u4StartTime; -+ -+ fgNoaAttrExisted |= prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse; -+ } -+ -+ prP2pSpecificBssInfo->fgIsNoaAttrExisted = fgNoaAttrExisted; -+ -+ /* update beacon content by the change */ -+ bssUpdateBeaconContent(prAdapter, ucNetTypeIndex); -+} -+ -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c -new file mode 100644 -index 0000000000000..586a74721b3bf ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c -@@ -0,0 +1,3796 @@ -+#include "precomp.h" -+#include -+ -+#ifdef __GNUC__ -+#pragma GCC diagnostic ignored "-Wformat" -+#endif -+ -+APPEND_VAR_ATTRI_ENTRY_T txAssocRspAttributesTable[] = { -+ {(P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS), NULL, p2pFuncAppendAttriStatusForAssocRsp} /* 0 */ -+ , {(P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING), NULL, p2pFuncAppendAttriExtListenTiming} /* 8 */ -+}; -+ -+APPEND_VAR_IE_ENTRY_T txProbeRspIETable[] = { -+ {(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE} /* 50 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE} /* 42 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE} /* 45 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE} /* 61 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE} /* 48 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE} /* 74 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE} /* 127 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE} /* 221 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE} /* 221 */ -+}; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Function for requesting scan. There is an option to do ACTIVE or PASSIVE scan. -+* -+* @param eScanType - Specify the scan type of the scan request. It can be an ACTIVE/PASSIVE -+* Scan. -+* eChannelSet - Specify the preferred channel set. -+* A FULL scan would request a legacy full channel normal scan.(usually ACTIVE). -+* A P2P_SOCIAL scan would scan 1+6+11 channels.(usually ACTIVE) -+* A SPECIFIC scan would only 1/6/11 channels scan. (Passive Listen/Specific Search) -+* ucChannelNum - A specific channel number. (Only when channel is specified) -+* eBand - A specific band. (Only when channel is specified) -+* -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncRequestScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo) -+{ -+ -+ P_MSG_SCN_SCAN_REQ prScanReq = (P_MSG_SCN_SCAN_REQ) NULL; -+ /*NFC Beam + Indication */ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ BOOLEAN fgIsPureAP = FALSE; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ fgIsPureAP = prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode; -+ -+ DEBUGFUNC("p2pFuncRequestScan()"); -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prScanReqInfo != NULL)); -+ -+ if (prScanReqInfo->eChannelSet == SCAN_CHANNEL_SPECIFIED) { -+ ASSERT_BREAK(prScanReqInfo->ucNumChannelList > 0); -+ DBGLOG(P2P, LOUD, -+ "P2P Scan Request Channel:%d\n", prScanReqInfo->arScanChannelList[0].ucChannelNum); -+ } -+ -+ prScanReq = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); -+ if (!prScanReq) { -+ ASSERT(0); /* Can't trigger SCAN FSM */ -+ break; -+ } -+ -+ prScanReq->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_REQ; -+ prScanReq->ucSeqNum = ++prScanReqInfo->ucSeqNumOfScnMsg; -+ prScanReq->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_P2P_INDEX; -+ prScanReq->eScanType = prScanReqInfo->eScanType; -+ prScanReq->eScanChannel = prScanReqInfo->eChannelSet; -+ prScanReq->u2IELen = 0; -+ -+ /* Copy IE for Probe Request. */ -+ if (prScanReqInfo->u4BufLength > MAX_IE_LENGTH) -+ prScanReqInfo->u4BufLength = MAX_IE_LENGTH; -+ kalMemCopy(prScanReq->aucIE, prScanReqInfo->aucIEBuf, prScanReqInfo->u4BufLength); -+ prScanReq->u2IELen = (UINT_16) prScanReqInfo->u4BufLength; -+ -+ prScanReq->u2ChannelDwellTime = prScanReqInfo->u2PassiveDewellTime; -+ -+ switch (prScanReqInfo->eChannelSet) { -+ case SCAN_CHANNEL_SPECIFIED: -+ { -+ UINT_32 u4Idx = 0; -+ P_RF_CHANNEL_INFO_T prDomainInfo = -+ (P_RF_CHANNEL_INFO_T) prScanReqInfo->arScanChannelList; -+ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; -+ -+ -+ if (prScanReqInfo->ucNumChannelList > MAXIMUM_OPERATION_CHANNEL_LIST) -+ prScanReqInfo->ucNumChannelList = MAXIMUM_OPERATION_CHANNEL_LIST; -+ -+ for (u4Idx = 0; u4Idx < prScanReqInfo->ucNumChannelList; u4Idx++) { -+ prScanReq->arChnlInfoList[u4Idx].ucChannelNum = prDomainInfo->ucChannelNum; -+ prScanReq->arChnlInfoList[u4Idx].eBand = prDomainInfo->eBand; -+ prDomainInfo++; -+ } -+ -+ prScanReq->ucChannelListNum = prScanReqInfo->ucNumChannelList; -+ -+ /*NFC Beam + Indication */ -+ prChnlReqInfo = &prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo; -+ if (prChnlReqInfo->eChannelReqType == CHANNEL_REQ_TYPE_GO_START_BSS && -+ prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && -+ !fgIsPureAP) { -+ prScanReq->ucChannelListNum = 1; -+ prScanReq->arChnlInfoList[0].ucChannelNum = prChnlReqInfo->ucReqChnlNum; -+ prScanReq->arChnlInfoList[0].eBand = prChnlReqInfo->eBand; -+ -+ DBGLOG(P2P, INFO, -+ "NFC:GO Skip Scan and Only Froce on %s[%d]\n", -+ prChnlReqInfo->eBand == 1 ? "2.4G" : "5G", -+ prChnlReqInfo->ucReqChnlNum); -+ } -+ -+ COPY_SSID(prScanReq->aucSSID, -+ prScanReq->ucSSIDLength, -+ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); -+ -+ /* For compatible. */ -+ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, -+ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; -+ } else if (prScanReq->ucSSIDLength != 0) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ } -+ -+ } -+ break; -+ -+ case SCAN_CHANNEL_FULL: -+ { -+ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; -+ -+ COPY_SSID(prScanReq->aucSSID, -+ prScanReq->ucSSIDLength, -+ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); -+ -+ /* For compatible. */ -+ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, -+ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; -+ } else if (prScanReq->ucSSIDLength != 0) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ } -+ } -+ break; -+ -+ case SCAN_CHANNEL_2G4: -+ { -+ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; -+ -+ COPY_SSID(prScanReq->aucSSID, -+ prScanReq->ucSSIDLength, -+ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); -+ -+ /* For compatible. */ -+ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, -+ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; -+ } else if (prScanReq->ucSSIDLength != 0) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ } -+ } -+ break; -+ -+ case SCAN_CHANNEL_P2P_SOCIAL: -+ { -+ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; -+ -+ COPY_SSID(prScanReq->aucSSID, -+ prScanReq->ucSSIDLength, -+ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); -+ -+ /* For compatible. */ -+ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, -+ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; -+ } else if (prScanReq->ucSSIDLength != 0) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ } -+ } -+ break; -+ default: -+ /* Currently there is no other scan channel set. */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReq, MSG_SEND_METHOD_BUF); -+ -+ } while (FALSE); -+ -+} /* p2pFuncRequestScan */ -+ -+VOID p2pFuncCancelScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanInfo) -+{ -+ P_MSG_SCN_SCAN_CANCEL prScanCancelMsg = (P_MSG_SCN_SCAN_CANCEL) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prScanInfo != NULL)); -+ -+ if (!prScanInfo->fgIsScanRequest) -+ break; -+ -+ if (prScanInfo->ucSeqNumOfScnMsg) { -+ /* There is a channel privilege on hand. */ -+ DBGLOG(P2P, TRACE, "P2P Cancel Scan\n"); -+ -+ prScanCancelMsg = -+ (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL)); -+ if (!prScanCancelMsg) { -+ /* Buffer not enough, can not cancel scan request. */ -+ DBGLOG(P2P, TRACE, "Buffer not enough, can not cancel scan.\n"); -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prScanCancelMsg->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_CANCEL; -+ prScanCancelMsg->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ prScanCancelMsg->ucSeqNum = prScanInfo->ucSeqNumOfScnMsg++; -+ prScanCancelMsg->fgIsChannelExt = FALSE; -+ prScanInfo->fgIsScanRequest = FALSE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_BUF); -+ -+ } -+ -+ } while (FALSE); -+ -+} /* p2pFuncCancelScan */ -+ -+VOID -+p2pFuncSwitchOPMode(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_OP_MODE_T eOpMode, IN BOOLEAN fgSyncToFW) -+{ -+ if (!prAdapter) -+ return; -+ if (!prAdapter->prGlueInfo) -+ return; -+ if (prAdapter->prGlueInfo->ulFlag & GLUE_FLAG_HALT) -+ return; -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL) && (eOpMode < OP_MODE_NUM)); -+ -+ if (prP2pBssInfo->eCurrentOPMode != eOpMode) { -+ DBGLOG(P2P, TRACE, -+ "p2pFuncSwitchOPMode: Switch to from %d, to %d.\n", prP2pBssInfo->eCurrentOPMode, -+ eOpMode); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_ACCESS_POINT: -+ p2pFuncDissolve(prAdapter, prP2pBssInfo, TRUE, REASON_CODE_DEAUTH_LEAVING_BSS); -+ -+ p2pFsmRunEventStopAP(prAdapter, NULL); -+ break; -+ default: -+ break; -+ } -+ -+ prP2pBssInfo->eIntendOPMode = eOpMode; -+ prP2pBssInfo->eCurrentOPMode = eOpMode; -+ switch (eOpMode) { -+ case OP_MODE_INFRASTRUCTURE: -+ DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch to Client.\n"); -+ case OP_MODE_ACCESS_POINT: -+/* if (!IS_BSS_ACTIVE(prP2pBssInfo)) { */ -+/* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+/* } */ -+ -+ /* Change interface address. */ -+ if (eOpMode == OP_MODE_ACCESS_POINT) { -+ DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch to AP.\n"); -+ prP2pBssInfo->ucSSIDLen = 0; -+ } -+ -+ COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucInterfaceAddress); -+ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAdapter->rWifiVar.aucInterfaceAddress); -+ -+ break; -+ case OP_MODE_P2P_DEVICE: -+ { -+ /* Change device address. */ -+ DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch back to P2P Device.\n"); -+ -+/* if (!IS_BSS_ACTIVE(prP2pBssInfo)) { */ -+/* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+/* } */ -+ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, -+ prAdapter->rWifiVar.aucDeviceAddress); -+ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAdapter->rWifiVar.aucDeviceAddress); -+ -+ } -+ break; -+ default: -+/* if (IS_BSS_ACTIVE(prP2pBssInfo)) { */ -+/* UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+/* nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+/* } */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ if (1) { -+ P2P_DISCONNECT_INFO rP2PDisInfo; -+ -+ rP2PDisInfo.ucRole = 2; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_P2P_ABORT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(P2P_DISCONNECT_INFO), (PUINT_8)&rP2PDisInfo, NULL, 0); -+ } -+ -+ DBGLOG(P2P, TRACE, -+ "The device address is changed to %pM\n", -+ prP2pBssInfo->aucOwnMacAddr); -+ DBGLOG(P2P, TRACE, "The BSSID is changed to %pM\n", prP2pBssInfo->aucBSSID); -+ -+ /* Update BSS INFO to FW. */ -+ if ((fgSyncToFW) && (eOpMode != OP_MODE_ACCESS_POINT)) -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ } while (FALSE); -+ -+} /* p2pFuncSwitchOPMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will start a P2P Group Owner and send Beacon Frames. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pFuncStartGO(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prBssInfo, -+ IN PUINT_8 pucSsidBuf, -+ IN UINT_8 ucSsidLen, -+ IN UINT_8 ucChannelNum, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN BOOLEAN fgIsPureAP) -+{ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prBssInfo != NULL)); -+ -+ ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT); -+ -+ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 1; -+ DBGLOG(P2P, INFO, -+ "p2pFuncStartGO:NFC Done[%d]\n", -+ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone); -+ /* AP mode started. */ -+ p2pFuncSwitchOPMode(prAdapter, prBssInfo, prBssInfo->eIntendOPMode, FALSE); -+ -+ prBssInfo->eIntendOPMode = OP_MODE_NUM; -+ -+ /* 4 <1.1> Assign SSID */ -+ COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, pucSsidBuf, ucSsidLen); -+ -+ DBGLOG(P2P, TRACE, "GO SSID:%s\n", prBssInfo->aucSSID); -+ -+ /* 4 <1.2> Clear current AP's STA_RECORD_T and current AID */ -+ prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ prBssInfo->u2AssocId = 0; -+ -+ /* 4 <1.3> Setup Channel, Band and Phy Attributes */ -+ prBssInfo->ucPrimaryChannel = ucChannelNum; -+ prBssInfo->eBand = eBand; -+ prBssInfo->eBssSCO = eSco; -+ -+ DBGLOG(P2P, TRACE, "GO Channel:%d\n", ucChannelNum); -+ -+ if (prBssInfo->eBand == BAND_5G) { -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AN); -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A; -+ } else if (fgIsPureAP) { -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN); -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; -+ } else { -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11GN); -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P; -+ } -+ -+ prBssInfo->ucNonHTBasicPhyType = (UINT_8) -+ rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; -+ prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; -+ prBssInfo->u2OperationalRateSet = -+ rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; -+ -+ if (prBssInfo->ucAllSupportedRatesLen == 0) { -+ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, -+ prBssInfo->u2BSSBasicRateSet, -+ prBssInfo->aucAllSupportedRates, -+ &prBssInfo->ucAllSupportedRatesLen); -+ } -+ /* 4 <1.5> Setup MIB for current BSS */ -+ prBssInfo->u2ATIMWindow = 0; -+ prBssInfo->ucBeaconTimeoutCount = 0; -+ -+ /* 3 <2> Update BSS_INFO_T common part */ -+#if CFG_SUPPORT_AAA -+ if (!fgIsPureAP) { -+ prBssInfo->fgIsProtection = TRUE; /* Always enable protection at P2P GO */ -+ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_CCMP); -+ } else { -+ if (kalP2PGetCipher(prAdapter->prGlueInfo)) -+ prBssInfo->fgIsProtection = TRUE; -+ } -+ -+ /* 20120106 frog: I want separate OP_Mode & Beacon TX Function. */ -+ /* p2pFuncSwitchOPMode(prAdapter, prBssInfo, OP_MODE_ACCESS_POINT, FALSE); */ -+ -+ bssInitForAP(prAdapter, prBssInfo, FALSE); -+ -+ nicQmUpdateWmmParms(prAdapter, NETWORK_TYPE_P2P_INDEX); -+#endif /* CFG_SUPPORT_AAA */ -+ -+ /* 3 <3> Set MAC HW */ -+ /* 4 <3.1> Setup channel and bandwidth */ -+ rlmBssInitForAPandIbss(prAdapter, prBssInfo); -+ -+ /* 4 <3.2> Reset HW TSF Update Mode and Beacon Mode */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* 4 <3.3> Update Beacon again for network phy type confirmed. */ -+ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+#if 0 /* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */ -+ { -+ CMD_HOTSPOT_OPTIMIZATION_CONFIG arHotspotOptimizationCfg; -+ -+ arHotspotOptimizationCfg.fgHotspotOptimizationEn = TRUE; -+ arHotspotOptimizationCfg.u4Level = (0x3) << 8 | 0x5; -+ wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_HOTSPOT_OPTIMIZATION, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ NULL, -+ sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG), -+ (PUINT_8)&arHotspotOptimizationCfg, NULL, 0); -+ } -+#endif -+ -+ /* 4 <3.4> Setup BSSID */ -+ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ } while (FALSE); -+ -+} /* p2pFuncStartGO() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform CNM that channel privilege -+* has been released -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncReleaseCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo) -+{ -+ P_MSG_CH_ABORT_T prMsgChRelease = (P_MSG_CH_ABORT_T) NULL; -+ -+ DEBUGFUNC("p2pFuncReleaseCh()"); -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL)); -+ -+ if (!prChnlReqInfo->fgIsChannelRequested) -+ break; -+ -+ DBGLOG(P2P, TRACE, "P2P Release Channel\n"); -+ prChnlReqInfo->fgIsChannelRequested = FALSE; -+ -+ /* 1. return channel privilege to CNM immediately */ -+ prMsgChRelease = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T)); -+ if (!prMsgChRelease) { -+ ASSERT(0); /* Can't release Channel to CNM */ -+ break; -+ } -+ -+ prMsgChRelease->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; -+ prMsgChRelease->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ prMsgChRelease->ucTokenID = prChnlReqInfo->ucSeqNumOfChReq++; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChRelease, MSG_SEND_METHOD_BUF); -+ -+ } while (FALSE); -+ -+} /* p2pFuncReleaseCh */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of CHANNEL_REQ_JOIN Initial. Enter CHANNEL_REQ_JOIN State. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncAcquireCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo) -+{ -+ P_MSG_CH_REQ_T prMsgChReq = (P_MSG_CH_REQ_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL)); -+ -+ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); -+ -+ /* send message to CNM for acquiring channel */ -+ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); -+ -+ if (!prMsgChReq) { -+ ASSERT(0); /* Can't indicate CNM for channel acquiring */ -+ break; -+ } -+ -+ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; -+ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ prMsgChReq->ucTokenID = ++prChnlReqInfo->ucSeqNumOfChReq; -+ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; -+ if (prChnlReqInfo->u4MaxInterval < P2P_EXT_LISTEN_TIME_MS) -+ prMsgChReq->u4MaxInterval = P2P_EXT_LISTEN_TIME_MS; -+ else -+ prMsgChReq->u4MaxInterval = prChnlReqInfo->u4MaxInterval; -+ -+ prMsgChReq->ucPrimaryChannel = prChnlReqInfo->ucReqChnlNum; -+ prMsgChReq->eRfSco = prChnlReqInfo->eChnlSco; -+ prMsgChReq->eRfBand = prChnlReqInfo->eBand; -+ -+ kalMemZero(prMsgChReq->aucBSSID, MAC_ADDR_LEN); -+ -+ /* Channel request join BSSID. */ -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); -+ -+ prChnlReqInfo->fgIsChannelRequested = TRUE; -+ -+ } while (FALSE); -+ -+} /* p2pFuncAcquireCh */ -+ -+#if 0 -+WLAN_STATUS -+p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBcnHdr, -+ IN UINT_32 u4HdrLen, -+ IN PUINT_8 pucBcnBody, IN UINT_32 u4BodyLen, IN UINT_32 u4DtimPeriod, IN UINT_32 u4BcnInterval) -+{ -+ WLAN_STATUS rResultStatus = WLAN_STATUS_INVALID_DATA; -+ P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_MSDU_INFO_T prBcnMsduInfo = (P_MSDU_INFO_T) NULL; -+ PUINT_8 pucTIMBody = (PUINT_8) NULL; -+ UINT_16 u2FrameLength = 0, UINT_16 u2OldBodyLen = 0; -+ UINT_8 aucIEBuf[MAX_IE_LENGTH]; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prBcnMsduInfo = prP2pBssInfo->prBeacon ASSERT_BREAK(prBcnMsduInfo != NULL); -+ -+ /* TODO: Find TIM IE pointer. */ -+ prBcnFrame = prBcnMsduInfo->prPacket; -+ -+ ASSERT_BREAK(prBcnFrame != NULL); -+ -+ do { -+ /* Ori header. */ -+ UINT_16 u2IELength = 0, u2Offset = 0; -+ PUINT_8 pucIEBuf = prBcnFrame->aucInfoElem; -+ -+ u2IELength = prBcnMsduInfo->u2FrameLength - prBcnMsduInfo->ucMacHeaderLength; -+ -+ IE_FOR_EACH(pucIEBuf, u2IELength, u2Offset) { -+ if ((IE_ID(pucIEBuf) == ELEM_ID_TIM) || ((IE_ID(pucIEBuf) > ELEM_ID_IBSS_PARAM_SET))) { -+ pucTIMBody = pucIEBuf; -+ break; -+ } -+ u2FrameLength += IE_SIZE(pucIEBuf); -+ } -+ -+ if (pucTIMBody == NULL) -+ pucTIMBody = pucIEBuf; -+ -+ /* Body not change. */ -+ u2OldBodyLen = (UINT_16) ((UINT_32) pucTIMBody - (UINT_32) prBcnFrame->aucInfoElem); -+ /* Move body. */ -+ kalMemCmp(aucIEBuf, pucTIMBody, u2OldBodyLen); -+ } while (FALSE); -+ -+ if (pucBcnHdr) { -+ kalMemCopy(prBcnMsduInfo->prPacket, pucBcnHdr, u4HdrLen); -+ pucTIMBody = (PUINT_8) ((UINT_32) prBcnMsduInfo->prPacket + u4HdrLen); -+ prBcnMsduInfo->ucMacHeaderLength = (WLAN_MAC_MGMT_HEADER_LEN + -+ (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)); -+ u2FrameLength = u4HdrLen; /* Header + Partial Body. */ -+ } else { -+ /* Header not change. */ -+ u2FrameLength += prBcnMsduInfo->ucMacHeaderLength; -+ } -+ -+ if (pucBcnBody) { -+ kalMemCopy(pucTIMBody, pucBcnBody, u4BodyLen); -+ u2FrameLength += (UINT_16) u4BodyLen; -+ } else { -+ kalMemCopy(pucTIMBody, aucIEBuf, u2OldBodyLen); -+ u2FrameLength += u2OldBodyLen; -+ } -+ -+ /* Frame Length */ -+ prBcnMsduInfo->u2FrameLength = u2FrameLength; -+ prBcnMsduInfo->fgIs802_11 = TRUE; -+ prBcnMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ prP2pBssInfo->u2BeaconInterval = (UINT_16) u4BcnInterval; -+ prP2pBssInfo->ucDTIMPeriod = (UINT_8) u4DtimPeriod; -+ prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo; -+ prBcnMsduInfo->ucPacketType = 3; -+ rResultStatus = nicUpdateBeaconIETemplate(prAdapter, -+ IE_UPD_METHOD_UPDATE_ALL, -+ NETWORK_TYPE_P2P_INDEX, -+ prP2pBssInfo->u2CapInfo, -+ (PUINT_8) prBcnFrame->aucInfoElem, -+ prBcnMsduInfo->u2FrameLength - -+ OFFSET_OF(WLAN_BEACON_FRAME_T, -+ aucInfoElem)); -+ if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ /* AP is created, Beacon Update. */ -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ } while (FALSE); -+ return rResultStatus; -+} /* p2pFuncBeaconUpdate */ -+ -+#else -+WLAN_STATUS -+ p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, -+ IN P_P2P_BEACON_UPDATE_INFO_T prBcnUpdateInfo, -+ IN PUINT_8 pucNewBcnHdr, IN UINT_32 u4NewHdrLen, IN PUINT_8 pucNewBcnBody, IN UINT_32 u4NewBodyLen) -+{ -+WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL; -+P_MSDU_INFO_T prBcnMsduInfo = (P_MSDU_INFO_T) NULL; -+PUINT_8 pucIEBuf = (PUINT_8) NULL; -+PUINT_8 paucIEBuf = (PUINT_8) NULL;/*[MAX_IE_LENGTH]; aucIEBuf*/ -+ -+do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL) && (prBcnUpdateInfo != NULL)); -+ -+ prBcnMsduInfo = prP2pBssInfo->prBeacon; -+ -+#if DBG -+ if (prBcnUpdateInfo->pucBcnHdr != NULL) { -+ ASSERT((UINT_32) prBcnUpdateInfo->pucBcnHdr == -+ ((UINT_32) prBcnMsduInfo->prPacket + MAC_TX_RESERVED_FIELD)); -+ } -+ -+ if (prBcnUpdateInfo->pucBcnBody != NULL) { -+ ASSERT((UINT_32) prBcnUpdateInfo->pucBcnBody == -+ ((UINT_32) prBcnUpdateInfo->pucBcnHdr + (UINT_32) prBcnUpdateInfo->u4BcnHdrLen)); -+ } -+#endif -+ prBcnFrame = (P_WLAN_BEACON_FRAME_T) ((ULONG) prBcnMsduInfo->prPacket + MAC_TX_RESERVED_FIELD); -+ -+ if (!pucNewBcnBody) { -+ /* Old body. */ -+ pucNewBcnBody = prBcnUpdateInfo->pucBcnBody; -+ ASSERT(u4NewBodyLen == 0); -+ u4NewBodyLen = prBcnUpdateInfo->u4BcnBodyLen; -+ } else { -+ prBcnUpdateInfo->u4BcnBodyLen = u4NewBodyLen; -+ } -+ -+ paucIEBuf = kalMemAlloc(MAX_IE_LENGTH, VIR_MEM_TYPE); -+ if (paucIEBuf == NULL) { -+ DBGLOG(P2P, TRACE, "p2p alloc paucIEBuf fail\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* Temp buffer body part. */ -+ kalMemCopy(paucIEBuf, pucNewBcnBody, u4NewBodyLen); -+ -+ if (pucNewBcnHdr) { -+ kalMemCopy(prBcnFrame, pucNewBcnHdr, u4NewHdrLen); -+ prBcnUpdateInfo->pucBcnHdr = (PUINT_8) prBcnFrame; -+ prBcnUpdateInfo->u4BcnHdrLen = u4NewHdrLen; -+ } -+ -+ pucIEBuf = (PUINT_8) ((ULONG) prBcnUpdateInfo->pucBcnHdr + (UINT_32) prBcnUpdateInfo->u4BcnHdrLen); -+ kalMemCopy(pucIEBuf, paucIEBuf, u4NewBodyLen); -+ kalMemFree(paucIEBuf, VIR_MEM_TYPE, MAX_IE_LENGTH); -+ prBcnUpdateInfo->pucBcnBody = pucIEBuf; -+ -+ /* Frame Length */ -+ prBcnMsduInfo->u2FrameLength = (UINT_16) (prBcnUpdateInfo->u4BcnHdrLen + prBcnUpdateInfo->u4BcnBodyLen); -+ -+ prBcnMsduInfo->ucPacketType = 3; -+ prBcnMsduInfo->fgIs802_11 = TRUE; -+ prBcnMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ -+ /* Update BSS INFO related information. */ -+ COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, prBcnFrame->aucSrcAddr); -+ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prBcnFrame->aucBSSID); -+ prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo; -+ -+ p2pFuncParseBeaconContent(prAdapter, -+ prP2pBssInfo, -+ (PUINT_8) prBcnFrame->aucInfoElem, -+ (prBcnMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem))); -+ -+#if 1 -+ /* bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+#else -+ nicUpdateBeaconIETemplate(prAdapter, -+ IE_UPD_METHOD_UPDATE_ALL, -+ NETWORK_TYPE_P2P_INDEX, -+ prBcnFrame->u2CapInfo, -+ (PUINT_8) prBcnFrame->aucInfoElem, -+ (prBcnMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem))); -+#endif -+} while (FALSE); -+ -+return rWlanStatus; -+} /* p2pFuncBeaconUpdate */ -+ -+#endif -+ -+/* TODO: We do not apply IE in deauth frame set from upper layer now. */ -+WLAN_STATUS -+p2pFuncDeauth(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucPeerMacAddr, -+ IN UINT_16 u2ReasonCode, IN PUINT_8 pucIEBuf, IN UINT_16 u2IELen, IN BOOLEAN fgSendDeauth) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_FAILURE; -+ P_STA_RECORD_T prCliStaRec = (P_STA_RECORD_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ BOOLEAN fgIsStaFound = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucPeerMacAddr != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ prCliStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, pucPeerMacAddr); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_ACCESS_POINT: -+ { -+ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ -+ prStaRecOfClientList = &(prP2pBssInfo->rStaRecOfClientList); -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ if ((ULONG) prCliStaRec == (ULONG) prLinkEntry) { -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prCliStaRec->rLinkEntry); -+ fgIsStaFound = TRUE; -+ break; -+ } -+ } -+ -+ } -+ break; -+ case OP_MODE_INFRASTRUCTURE: -+ ASSERT(prCliStaRec == prP2pBssInfo->prStaRecOfAP); -+ if (prCliStaRec != prP2pBssInfo->prStaRecOfAP) -+ break; -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ fgIsStaFound = TRUE; -+ break; -+ default: -+ break; -+ } -+ -+ if (fgIsStaFound) -+ p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDeauth, u2ReasonCode); -+ -+ rWlanStatus = WLAN_STATUS_SUCCESS; -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* p2pFuncDeauth */ -+ -+/* TODO: We do not apply IE in disassoc frame set from upper layer now. */ -+WLAN_STATUS -+p2pFuncDisassoc(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucPeerMacAddr, -+ IN UINT_16 u2ReasonCode, IN PUINT_8 pucIEBuf, IN UINT_16 u2IELen, IN BOOLEAN fgSendDisassoc) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_FAILURE; -+ P_STA_RECORD_T prCliStaRec = (P_STA_RECORD_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ BOOLEAN fgIsStaFound = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucPeerMacAddr != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ prCliStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, pucPeerMacAddr); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_ACCESS_POINT: -+ { -+ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ -+ prStaRecOfClientList = &(prP2pBssInfo->rStaRecOfClientList); -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ if ((ULONG) prCliStaRec == (ULONG) prLinkEntry) { -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prCliStaRec->rLinkEntry); -+ fgIsStaFound = TRUE; -+ /* p2pFuncDisconnect(prAdapter, prCliStaRec, -+ * fgSendDisassoc, u2ReasonCode); */ -+ break; -+ } -+ } -+ -+ } -+ break; -+ case OP_MODE_INFRASTRUCTURE: -+ ASSERT(prCliStaRec == prP2pBssInfo->prStaRecOfAP); -+ if (prCliStaRec != prP2pBssInfo->prStaRecOfAP) -+ break; -+ /* p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDisassoc, u2ReasonCode); */ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ fgIsStaFound = TRUE; -+ break; -+ default: -+ break; -+ } -+ -+ if (fgIsStaFound) { -+ -+ p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDisassoc, u2ReasonCode); -+ /* 20120830 moved into p2pFuncDisconnect(). */ -+ /* cnmStaRecFree(prAdapter, prCliStaRec, TRUE); */ -+ -+ } -+ -+ rWlanStatus = WLAN_STATUS_SUCCESS; -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* p2pFuncDisassoc */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to dissolve from group or one group. (Would not change P2P FSM.) -+* 1. GC: Disconnect from AP. (Send Deauth) -+* 2. GO: Disconnect all STA -+* -+* @param[in] prAdapter Pointer to the adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pFuncDissolve(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode) -+{ -+ DEBUGFUNC("p2pFuncDissolve()"); -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL)); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_INFRASTRUCTURE: -+ /* Reset station record status. */ -+ if (prP2pBssInfo->prStaRecOfAP) { -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ NULL, NULL, 0, REASON_CODE_DEAUTH_LEAVING_BSS, -+ WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY); -+ -+ /* 2012/02/14 frog: After formation before join group, prStaRecOfAP is NULL. */ -+ p2pFuncDisconnect(prAdapter, prP2pBssInfo->prStaRecOfAP, fgSendDeauth, u2ReasonCode); -+ } -+ -+ /* Fix possible KE when RX Beacon & call nicPmIndicateBssConnected(). -+ * hit prStaRecOfAP == NULL. */ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ -+ break; -+ case OP_MODE_ACCESS_POINT: -+ /* Under AP mode, we would net send deauthentication frame to each STA. -+ * We only stop the Beacon & let all stations timeout. -+ */ -+ { -+ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; -+ -+ /* Send deauth. */ -+ authSendDeauthFrame(prAdapter, -+ NULL, (P_SW_RFB_T) NULL, u2ReasonCode, (PFN_TX_DONE_HANDLER) NULL); -+ -+ prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; -+ -+ while (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ P_STA_RECORD_T prCurrStaRec; -+ -+ LINK_REMOVE_HEAD(prStaRecOfClientList, prCurrStaRec, P_STA_RECORD_T); -+ -+ /* Indicate to Host. */ -+ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prCurrStaRec, FALSE); */ -+ -+ p2pFuncDisconnect(prAdapter, prCurrStaRec, TRUE, u2ReasonCode); -+ -+ } -+ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 0; -+ } -+ -+ break; -+ default: -+ return; /* 20110420 -- alreay in Device Mode. */ -+ } -+ -+ /* Make the deauth frame send to FW ASAP. */ -+ wlanAcquirePowerControl(prAdapter); -+ wlanProcessCommandQueue(prAdapter, &prAdapter->prGlueInfo->rCmdQueue); -+ wlanReleasePowerControl(prAdapter); -+ -+ kalMdelay(100); -+ -+ /* Change Connection Status. */ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ } while (FALSE); -+ -+} /* p2pFuncDissolve */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to dissolve from group or one group. (Would not change P2P FSM.) -+* 1. GC: Disconnect from AP. (Send Deauth) -+* 2. GO: Disconnect all STA -+* -+* @param[in] prAdapter Pointer to the adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pFuncDisconnect(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ ENUM_PARAM_MEDIA_STATE_T eOriMediaStatus; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ eOriMediaStatus = prP2pBssInfo->eConnectionState; -+ -+ /* Indicate disconnect. */ -+ /* TODO: */ -+ /* kalP2PGOStationUpdate */ -+ /* kalP2PGCIndicateConnectionStatus */ -+ /* p2pIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, prStaRec->aucMacAddr); */ -+ DBGLOG(P2P, INFO, "p2pFuncDisconnect, eCurrentOPMode: %d, sendDeauth: %s\n", -+ prP2pBssInfo->eCurrentOPMode, fgSendDeauth ? "True" : "False"); -+ if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) -+ kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); -+ -+ if (fgSendDeauth) { -+ /* Send deauth. */ -+ authSendDeauthFrame(prAdapter, -+ prStaRec, -+ (P_SW_RFB_T) NULL, -+ u2ReasonCode, (PFN_TX_DONE_HANDLER) p2pFsmRunEventDeauthTxDone); -+ } else { -+ /* Change station state. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ /* Reset Station Record Status. */ -+ p2pFuncResetStaRecStatus(prAdapter, prStaRec); -+ -+ cnmStaRecFree(prAdapter, prStaRec, TRUE); -+ -+ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || -+ (prP2pBssInfo->rStaRecOfClientList.u4NumElem == 0)) { -+ DBGLOG(P2P, TRACE, "No More Client, Media Status DISCONNECTED\n"); -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ } -+ -+ if (eOriMediaStatus != prP2pBssInfo->eConnectionState) { -+ /* Update Disconnected state to FW. */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ } -+ -+ if (prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) { -+ /* GO: It would stop Beacon TX. GC: Stop all BSS related PS function. */ -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* Reset RLM related field of BSSINFO. */ -+ rlmBssAborted(prAdapter, prP2pBssInfo); -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* p2pFuncDisconnect */ -+ -+/* Action frame categories (IEEE 802.11-2007, 7.3.1.11, Table 7-24) */ -+#define WLAN_ACTION_SPECTRUM_MGMT 0 -+#define WLAN_ACTION_QOS 1 -+#define WLAN_ACTION_DLS 2 -+#define WLAN_ACTION_BLOCK_ACK 3 -+#define WLAN_ACTION_PUBLIC 4 -+#define WLAN_ACTION_RADIO_MEASUREMENT 5 -+#define WLAN_ACTION_FT 6 -+#define WLAN_ACTION_HT 7 -+#define WLAN_ACTION_SA_QUERY 8 -+#define WLAN_ACTION_PROTECTED_DUAL 9 -+#define WLAN_ACTION_WNM 10 -+#define WLAN_ACTION_UNPROTECTED_WNM 11 -+#define WLAN_ACTION_TDLS 12 -+#define WLAN_ACTION_SELF_PROTECTED 15 -+#define WLAN_ACTION_WMM 17 /* WMM Specification 1.1 */ -+#define WLAN_ACTION_VENDOR_SPECIFIC 127 -+ -+/* Public action codes */ -+#define WLAN_PA_20_40_BSS_COEX 0 -+#define WLAN_PA_VENDOR_SPECIFIC 9 -+#define WLAN_PA_GAS_INITIAL_REQ 10 -+#define WLAN_PA_GAS_INITIAL_RESP 11 -+#define WLAN_PA_GAS_COMEBACK_REQ 12 -+#define WLAN_PA_GAS_COMEBACK_RESP 13 -+#define WLAN_TDLS_DISCOVERY_RESPONSE 14 -+ -+/* P2P public action frames */ -+enum p2p_action_frame_type { -+ P2P_GO_NEG_REQ = 0, -+ P2P_GO_NEG_RESP = 1, -+ P2P_GO_NEG_CONF = 2, -+ P2P_INVITATION_REQ = 3, -+ P2P_INVITATION_RESP = 4, -+ P2P_DEV_DISC_REQ = 5, -+ P2P_DEV_DISC_RESP = 6, -+ P2P_PROV_DISC_REQ = 7, -+ P2P_PROV_DISC_RESP = 8 -+}; -+ -+const char *p2p_to_string(enum p2p_action_frame_type p2p_action) -+{ -+ switch (p2p_action) { -+ case P2P_GO_NEG_REQ: -+ return "GO_NEG_REQ"; -+ case P2P_GO_NEG_RESP: -+ return "GO_NEG_RESP"; -+ case P2P_GO_NEG_CONF: -+ return "GO_NEG_CONF"; -+ case P2P_INVITATION_REQ: -+ return "INVITATION_REQ"; -+ case P2P_INVITATION_RESP: -+ return "INVITATION_RESP"; -+ case P2P_DEV_DISC_REQ: -+ return "DEV_DISC_REQ"; -+ case P2P_DEV_DISC_RESP: -+ return "DEV_DISC_RESP"; -+ case P2P_PROV_DISC_REQ: -+ return "PROV_DISC_REQ"; -+ case P2P_PROV_DISC_RESP: -+ return "PROV_DISC_RESP"; -+ } -+ -+ return "UNKNOWN P2P Public Action"; -+} -+const char *pa_to_string(int pa_action) -+{ -+ switch (pa_action) { -+ case WLAN_PA_20_40_BSS_COEX: -+ return "PA_20_40_BSS_COEX"; -+ case WLAN_PA_VENDOR_SPECIFIC: -+ return "PA_VENDOR_SPECIFIC"; -+ case WLAN_PA_GAS_INITIAL_REQ: -+ return "PA_GAS_INITIAL_REQ"; -+ case WLAN_PA_GAS_INITIAL_RESP: -+ return "PA_GAS_INITIAL_RESP"; -+ case WLAN_PA_GAS_COMEBACK_REQ: -+ return "PA_GAS_COMEBACK_REQ"; -+ case WLAN_PA_GAS_COMEBACK_RESP: -+ return "PA_GAS_COMEBACK_RESP"; -+ case WLAN_TDLS_DISCOVERY_RESPONSE: -+ return "TDLS_DISCOVERY_RESPONSE"; -+ } -+ -+ return "UNKNOWN Public Action"; -+} -+ -+const char *action_to_string(int wlan_action) -+{ -+ switch (wlan_action) { -+ case WLAN_ACTION_SPECTRUM_MGMT: -+ return "SPECTRUM_MGMT"; -+ case WLAN_ACTION_QOS: -+ return "QOS"; -+ case WLAN_ACTION_DLS: -+ return "DLS"; -+ case WLAN_ACTION_BLOCK_ACK: -+ return "BLOCK_ACK"; -+ case WLAN_ACTION_PUBLIC: -+ return "PUBLIC"; -+ case WLAN_ACTION_RADIO_MEASUREMENT: -+ return "RADIO_MEASUREMENT"; -+ case WLAN_ACTION_FT: -+ return "FT"; -+ case WLAN_ACTION_HT: -+ return "HT"; -+ case WLAN_ACTION_SA_QUERY: -+ return "SA_QUERY"; -+ case WLAN_ACTION_PROTECTED_DUAL: -+ return "PROTECTED_DUAL"; -+ case WLAN_ACTION_WNM: -+ return "WNM"; -+ case WLAN_ACTION_UNPROTECTED_WNM: -+ return "UNPROTECTED_WNM"; -+ case WLAN_ACTION_TDLS: -+ return "TDLS"; -+ case WLAN_ACTION_SELF_PROTECTED: -+ return "SELF_PROTECTED"; -+ case WLAN_ACTION_WMM: -+ return "WMM"; -+ case WLAN_ACTION_VENDOR_SPECIFIC: -+ return "VENDOR_SPECIFIC"; -+ } -+ -+ return "UNKNOWN Action Frame"; -+} -+ -+VOID p2pFuncTagActionActionP2PFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, -+ IN P_WLAN_ACTION_FRAME prActFrame, -+ IN UINT_8 ucP2pAction, IN UINT_64 u8Cookie) -+{ -+ DBGLOG(P2P, INFO, "Found P2P_%s, SA: %pM - DA: %pM, cookie: 0x%llx, SeqNO: %d\n", -+ p2p_to_string(ucP2pAction), -+ prActFrame->aucSrcAddr, -+ prActFrame->aucDestAddr, -+ u8Cookie, -+ prMgmtTxMsdu->ucTxSeqNum); -+} -+ -+VOID p2pFuncTagActionActionFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, -+ IN P_WLAN_ACTION_FRAME prActFrame, -+ IN UINT_8 ucAction, IN UINT_64 u8Cookie) -+{ -+ PUINT_8 pucVendor = NULL; -+ -+ DBGLOG(P2P, INFO, "Found WLAN_%s, SA: %pM - DA: %pM, cookie: 0x%llx, SeqNo: %d\n", -+ pa_to_string(ucAction), -+ prActFrame->aucSrcAddr, -+ prActFrame->aucDestAddr, -+ u8Cookie, -+ prMgmtTxMsdu->ucTxSeqNum); -+ -+ if (ucAction == WLAN_PA_VENDOR_SPECIFIC) { -+ pucVendor = (PUINT_8)prActFrame + 26; -+ if (*(pucVendor + 0) == 0x50 && -+ *(pucVendor + 1) == 0x6f && -+ *(pucVendor + 2) == 0x9a) { -+ if (*(pucVendor + 3) == 0x09) -+ /* found p2p IE */ -+ p2pFuncTagActionActionP2PFrame(prMgmtTxMsdu, -+ prActFrame, *(pucVendor + 4), u8Cookie); -+ else if (*(pucVendor + 3) == 0x0a) -+ /* found WFD IE */ -+ DBGLOG(P2P, INFO, "Found WFD IE, SA: %pM - DA: %pM\n", -+ prActFrame->aucSrcAddr, -+ prActFrame->aucDestAddr); -+ else -+ DBGLOG(P2P, INFO, "Found Other vendor 0x%x, SA: %pM - DA: %pM\n", -+ *(pucVendor + 3), -+ prActFrame->aucSrcAddr, -+ prActFrame->aucDestAddr); -+ } -+ } -+} -+ -+VOID p2pFuncTagActionCategoryFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, -+ P_WLAN_ACTION_FRAME prActFrame, -+ IN UINT_8 ucCategory, -+ IN UINT_64 u8Cookie) -+{ -+ -+ UINT_8 ucAction = 0; -+ -+ DBGLOG(P2P, INFO, "Found WLAN_ACTION_%s, SA: %pM - DA: %pM, u8Cookie: 0x%llx, SeqNO: %d\n", -+ action_to_string(ucCategory), -+ prActFrame->aucSrcAddr, -+ prActFrame->aucDestAddr, -+ u8Cookie, -+ prMgmtTxMsdu->ucTxSeqNum); -+ -+ if (ucCategory == WLAN_ACTION_PUBLIC) { -+ ucAction = prActFrame->ucAction; -+ p2pFuncTagActionActionFrame(prMgmtTxMsdu, prActFrame, ucAction, u8Cookie); -+ -+ } -+} -+ -+/* -+ * used to debug p2p mgmt frame: -+ * GO Nego Req -+ * GO Nego Res -+ * GO Nego Confirm -+ * GO Invite Req -+ * GO Invite Res -+ * Device Discoverability Req -+ * Device Discoverability Res -+ * Provision Discovery Req -+ * Provision Discovery Res -+ */ -+ -+VOID -+p2pFuncTagMgmtFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie) -+{ -+ /* P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T)NULL; */ -+ P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL; -+ P_WLAN_PROBE_RSP_FRAME_T prProbRspHdr = (P_WLAN_PROBE_RSP_FRAME_T)NULL; -+ UINT_16 u2TxFrameCtrl; -+ P_WLAN_ACTION_FRAME prActFrame; -+ UINT_8 ucCategory; -+ -+ prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); -+ /* -+ * mgmt frame MASK_FC_TYPE = 0 -+ * use MASK_FRAME_TYPE is oK for frame type/subtype judge -+ */ -+ u2TxFrameCtrl = prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE; -+ -+ switch (u2TxFrameCtrl) { -+ case MAC_FRAME_PROBE_RSP: -+ -+ prProbRspHdr = (P_WLAN_PROBE_RSP_FRAME_T) prWlanHdr; -+ DBGLOG(P2P, INFO, "TX Probe Response Frame, SA: %pM - DA: %pM, cookie: 0x%llx, seqNo: %d\n", -+ prProbRspHdr->aucSrcAddr, prProbRspHdr->aucDestAddr, -+ u8Cookie, -+ prMgmtTxMsdu->ucTxSeqNum); -+ -+ break; -+ -+ case MAC_FRAME_ACTION: -+ -+ prActFrame = (P_WLAN_ACTION_FRAME)prWlanHdr; -+ ucCategory = prActFrame->ucCategory; -+ p2pFuncTagActionCategoryFrame(prMgmtTxMsdu, prActFrame, -+ ucCategory, u8Cookie); -+ -+ break; -+ default: -+ DBGLOG(P2P, INFO, "MGMT:, un-tagged frame type: 0x%x, A1: %pM, A2: %pM, A3: %pM seqNo: %d\n", -+ u2TxFrameCtrl, -+ prWlanHdr->aucAddr1, -+ prWlanHdr->aucAddr2, -+ prWlanHdr->aucAddr3, -+ prMgmtTxMsdu->ucTxSeqNum); -+ break; -+ } -+} -+ -+WLAN_STATUS -+p2pFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T) NULL; -+ P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ BOOLEAN fgIsProbrsp = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxReqInfo != NULL)); -+ -+ if (prMgmtTxReqInfo->fgIsMgmtTxRequested) { -+ -+ /* 1. prMgmtTxReqInfo->prMgmtTxMsdu != NULL */ -+ /* Packet on driver, not done yet, drop it. */ -+ prTxMsduInfo = prMgmtTxReqInfo->prMgmtTxMsdu; -+ if (prTxMsduInfo != NULL) { -+ -+ kalP2PIndicateMgmtTxStatus(prAdapter->prGlueInfo, -+ prMgmtTxReqInfo->u8Cookie, -+ FALSE, -+ prTxMsduInfo->prPacket, -+ (UINT_32) prTxMsduInfo->u2FrameLength); -+ -+ /* Leave it to TX Done handler. */ -+ /* cnmMgtPktFree(prAdapter, prTxMsduInfo); */ -+ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; -+ DBGLOG(P2P, INFO, "p2pFuncTxMgmtFrame: Drop MGMT cookie: 0x%llx\n", -+ prMgmtTxReqInfo->u8Cookie); -+ } -+ /* 2. prMgmtTxReqInfo->prMgmtTxMsdu == NULL */ -+ /* Packet transmitted, wait tx done. (cookie issue) */ -+ /* 20120105 frog - use another u8cookie to store this value. */ -+ } -+ -+ ASSERT(prMgmtTxReqInfo->prMgmtTxMsdu == NULL); -+ -+ prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); -+ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, prWlanHdr->aucAddr1); -+ prMgmtTxMsdu->ucNetworkType = (UINT_8) NETWORK_TYPE_P2P_INDEX; -+ -+ switch (prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE) { -+ case MAC_FRAME_PROBE_RSP: -+ DBGLOG(P2P, TRACE, "p2pFuncTxMgmtFrame: TX MAC_FRAME_PROBE_RSP\n"); -+ fgIsProbrsp = TRUE; -+ prMgmtTxMsdu = p2pFuncProcessP2pProbeRsp(prAdapter, prMgmtTxMsdu); -+ break; -+ default: -+ break; -+ } -+ -+ prMgmtTxReqInfo->u8Cookie = u8Cookie; -+ prMgmtTxReqInfo->prMgmtTxMsdu = prMgmtTxMsdu; -+ prMgmtTxReqInfo->fgIsMgmtTxRequested = TRUE; -+ -+ prMgmtTxMsdu->eSrc = TX_PACKET_MGMT; -+ prMgmtTxMsdu->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMgmtTxMsdu->ucStaRecIndex = (prStaRec != NULL) ? (prStaRec->ucIndex) : (0xFF); -+ if (prStaRec != NULL) -+ DBGLOG(P2P, TRACE, "Mgmt with station record: %pM.\n", prStaRec->aucMacAddr); -+ -+ prMgmtTxMsdu->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; /* TODO: undcertain. */ -+ prMgmtTxMsdu->fgIs802_1x = FALSE; -+ prMgmtTxMsdu->fgIs802_11 = TRUE; -+ prMgmtTxMsdu->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMgmtTxMsdu->pfTxDoneHandler = p2pFsmRunEventMgmtFrameTxDone; -+ prMgmtTxMsdu->fgIsBasicRate = TRUE; -+ -+ p2pFuncTagMgmtFrame(prMgmtTxMsdu, u8Cookie); -+ -+ nicTxEnqueueMsdu(prAdapter, prMgmtTxMsdu); -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* p2pFuncTxMgmtFrame */ -+ -+VOID p2pFuncSetChannel(IN P_ADAPTER_T prAdapter, IN P_RF_CHANNEL_INFO_T prRfChannelInfo) -+{ -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prRfChannelInfo != NULL)); -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ prP2pConnSettings->ucOperatingChnl = prRfChannelInfo->ucChannelNum; -+ prP2pConnSettings->eBand = prRfChannelInfo->eBand; -+ -+ } while (FALSE); -+ -+} -+ -+/* p2pFuncSetChannel */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Retry JOIN for AUTH_MODE_AUTO_SWITCH -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @retval TRUE We will retry JOIN -+* @retval FALSE We will not retry JOIN -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pFuncRetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_P2P_JOIN_INFO_T prJoinInfo) -+{ -+ P_MSG_JOIN_REQ_T prJoinReqMsg = (P_MSG_JOIN_REQ_T) NULL; -+ BOOLEAN fgRetValue = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL) && (prJoinInfo != NULL)); -+ -+ /* Retry other AuthType if possible */ -+ if (!prJoinInfo->ucAvailableAuthTypes) -+ break; -+ -+ if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { -+ -+ DBGLOG(P2P, INFO, "RETRY JOIN INIT: Retry Authentication with AuthType == SHARED_KEY.\n"); -+ -+ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; -+ } else { -+ DBGLOG(P2P, ERROR, "RETRY JOIN INIT: Retry Authentication with Unexpected AuthType.\n"); -+ ASSERT(0); -+ break; -+ } -+ -+ prJoinInfo->ucAvailableAuthTypes = 0; /* No more available Auth Types */ -+ -+ /* Trigger SAA to start JOIN process. */ -+ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); -+ if (!prJoinReqMsg) { -+ ASSERT(0); /* Can't trigger SAA FSM */ -+ break; -+ } -+ -+ prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START; -+ prJoinReqMsg->ucSeqNum = ++prJoinInfo->ucSeqNumOfReqMsg; -+ prJoinReqMsg->prStaRec = prStaRec; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); -+ -+ fgRetValue = TRUE; -+ } while (FALSE); -+ -+ return fgRetValue; -+ -+} /* end of p2pFuncRetryJOIN() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will update the contain of BSS_INFO_T for AIS network once -+* the association was completed. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] prAssocRspSwRfb Pointer to SW RFB of ASSOC RESP FRAME. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pFuncUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_DESC_T prBssDesc, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL; -+ UINT_16 u2IELength; -+ PUINT_8 pucIE; -+ -+ DEBUGFUNC("p2pUpdateBssInfoForJOIN()"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ ASSERT(prAssocRspSwRfb); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader; -+ -+ DBGLOG(P2P, INFO, "Update P2P_BSS_INFO_T and apply settings to MAC\n"); -+ -+ /* 3 <1> Update BSS_INFO_T from AIS_FSM_INFO_T or User Settings */ -+ /* 4 <1.1> Setup Operation Mode */ -+ prP2pBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; -+ -+ /* 4 <1.2> Setup SSID */ -+ COPY_SSID(prP2pBssInfo->aucSSID, -+ prP2pBssInfo->ucSSIDLen, prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen); -+ -+ if (prBssDesc == NULL) { -+ /* Target BSS NULL. */ -+ DBGLOG(P2P, TRACE, "Target BSS NULL\n"); -+ return; -+ } -+ -+ if (UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAssocRspFrame->aucBSSID)) -+ ASSERT(FALSE); -+ /* 4 <1.3> Setup Channel, Band */ -+ prP2pBssInfo->ucPrimaryChannel = prBssDesc->ucChannelNum; -+ prP2pBssInfo->eBand = prBssDesc->eBand; -+ -+ /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ -+ /* 4 <2.1> Save current AP's STA_RECORD_T and current AID */ -+ prP2pBssInfo->prStaRecOfAP = prStaRec; -+ prP2pBssInfo->u2AssocId = prStaRec->u2AssocId; -+ -+ /* 4 <2.2> Setup Capability */ -+ prP2pBssInfo->u2CapInfo = prStaRec->u2CapInfo; /* Use AP's Cap Info as BSS Cap Info */ -+ -+ if (prP2pBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) -+ prP2pBssInfo->fgIsShortPreambleAllowed = TRUE; -+ else -+ prP2pBssInfo->fgIsShortPreambleAllowed = FALSE; -+ -+ /* 4 <2.3> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ -+ prP2pBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; -+ -+ prP2pBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; -+ -+ prP2pBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; -+ prP2pBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; -+ -+ /* 3 <3> Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ -+ /* 4 <3.1> Setup BSSID */ -+ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAssocRspFrame->aucBSSID); -+ -+ u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) - -+ (OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN)); -+ pucIE = prAssocRspFrame->aucInfoElem; -+ -+ /* 4 <3.2> Parse WMM and setup QBSS flag */ -+ /* Parse WMM related IEs and configure HW CRs accordingly */ -+ mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+ -+ prP2pBssInfo->fgIsQBSS = prStaRec->fgIsQoS; -+ -+ /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ -+ ASSERT(prBssDesc); -+ -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ -+ /* 4 <4.1> Setup MIB for current BSS */ -+ prP2pBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; -+ /* NOTE: Defer ucDTIMPeriod updating to when beacon is received after connection */ -+ prP2pBssInfo->ucDTIMPeriod = 0; -+ prP2pBssInfo->u2ATIMWindow = 0; -+ -+ prP2pBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_INFRA; -+ -+ /* 4 <4.2> Update HT information and set channel */ -+ /* Record HT related parameters in rStaRec and rBssInfo -+ * Note: it shall be called before nicUpdateBss() -+ */ -+ rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+ -+ /* 4 <4.3> Sync with firmware for BSS-INFO */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* 4 <4.4> *DEFER OPERATION* nicPmIndicateBssConnected() will be invoked */ -+ /* inside scanProcessBeaconAndProbeResp() after 1st beacon is received */ -+ -+} /* end of p2pUpdateBssInfoForJOIN() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Auth Frame and then return -+* the status code to AAA to indicate if need to perform following actions -+* when the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] pprStaRec Pointer to pointer of STA_RECORD_T structure. -+* @param[out] pu2StatusCode The Status Code of Validation Result -+* -+* @retval TRUE Reply the Auth -+* @retval FALSE Don't reply the Auth -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+p2pFuncValidateAuth(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode) -+{ -+ BOOLEAN fgReplyAuth = TRUE; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_WLAN_AUTH_FRAME_T prAuthFrame = (P_WLAN_AUTH_FRAME_T) NULL; -+ -+ DBGLOG(P2P, INFO, "p2pValidate Authentication Frame\n"); -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && -+ (prSwRfb != NULL) && (pprStaRec != NULL) && (pu2StatusCode != NULL)); -+ -+ /* P2P 3.2.8 */ -+ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) -+ || (prP2pBssInfo->eIntendOPMode != OP_MODE_NUM)) { -+ /* We are not under AP Mode yet. */ -+ fgReplyAuth = FALSE; -+ DBGLOG(P2P, WARN, -+ "Current OP mode is not under AP mode. (%d)\n", prP2pBssInfo->eCurrentOPMode); -+ break; -+ } -+ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_P2P_INDEX, prAuthFrame->aucSrcAddr); -+ -+ if (!prStaRec) { -+ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_P2P_INDEX); -+ -+ /* TODO(Kevin): Error handling of allocation of STA_RECORD_T for -+ * exhausted case and do removal of unused STA_RECORD_T. -+ */ -+ /* Sent a message event to clean un-used STA_RECORD_T. */ -+ ASSERT(prStaRec); -+ if (!prStaRec) { -+ DBGLOG(AAA, INFO, "Station Limit Full. Decline a new Authentication.\n"); -+ break; -+ } -+ -+ COPY_MAC_ADDR(prStaRec->aucMacAddr, prAuthFrame->aucSrcAddr); -+ -+ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; -+ -+ prStaRec->u2BSSBasicRateSet = prP2pBssInfo->u2BSSBasicRateSet; -+ -+ prStaRec->u2DesiredNonHTRateSet = RATE_SET_ERP_P2P; -+ -+ prStaRec->u2OperationalRateSet = RATE_SET_ERP_P2P; -+ prStaRec->ucPhyTypeSet = PHY_TYPE_SET_802_11GN; -+ prStaRec->eStaType = STA_TYPE_P2P_GC; -+ -+ /* NOTE(Kevin): Better to change state here, not at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ } else { -+ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; -+ -+ if ((prStaRec->ucStaState > STA_STATE_1) && (IS_STA_IN_P2P(prStaRec))) { -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ p2pFuncResetStaRecStatus(prAdapter, prStaRec); -+ -+ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); -+ } -+ -+ } -+ -+ if (prP2pBssInfo->rStaRecOfClientList.u4NumElem >= P2P_MAXIMUM_CLIENT_COUNT || -+ kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) { -+ /* GROUP limit full. */ -+ /* P2P 3.2.8 */ -+ DBGLOG(P2P, WARN, -+ "Group Limit Full. (%d)\n", (INT_16) prP2pBssInfo->rStaRecOfClientList.u4NumElem); -+ -+ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); -+ -+ cnmStaRecFree(prAdapter, prStaRec, FALSE); -+ fgReplyAuth = TRUE; -+ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_AP_OVERLOAD; -+ break; -+ } -+ /* Hotspot Blacklist */ -+ if (prAuthFrame->aucSrcAddr) { -+ if (kalP2PCmpBlackList(prAdapter->prGlueInfo, prAuthFrame->aucSrcAddr)) { -+ fgReplyAuth = TRUE; -+ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_OUTSIDE_STANDARD; -+ return fgReplyAuth; -+ } -+ } -+ -+ /* prStaRec->eStaType = STA_TYPE_INFRA_CLIENT; */ -+ prStaRec->eStaType = STA_TYPE_P2P_GC; -+ -+ prStaRec->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ -+ prStaRec->ucJoinFailureCount = 0; -+ -+ *pprStaRec = prStaRec; -+ -+ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; -+ -+ } while (FALSE); -+ -+ return fgReplyAuth; -+ -+} /* p2pFuncValidateAuth */ -+ -+VOID p2pFuncResetStaRecStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ do { -+ if ((prAdapter == NULL) || (prStaRec == NULL)) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ prStaRec->u2ReasonCode = REASON_CODE_RESERVED; -+ prStaRec->ucJoinFailureCount = 0; -+ prStaRec->fgTransmitKeyExist = FALSE; -+ -+ prStaRec->fgSetPwrMgtBit = FALSE; -+ -+ } while (FALSE); -+ -+} /* p2pFuncResetStaRecStatus */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The function is used to initialize the value of the connection settings for -+* P2P network -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncInitConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings) -+{ -+ P_DEVICE_TYPE_T prDevType; -+ UINT_8 aucDefaultDevName[] = P2P_DEFAULT_DEV_NAME; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+#if CFG_SUPPORT_CFG_FILE -+ P_WIFI_VAR_T prWifiVar = NULL; -+#endif -+ -+ ASSERT(prP2PConnSettings); -+#if CFG_SUPPORT_CFG_FILE -+ prWifiVar = &(prAdapter->rWifiVar); -+ ASSERT(prWifiVar); -+#endif -+ -+ /* Setup Default Device Name */ -+ prP2PConnSettings->ucDevNameLen = P2P_DEFAULT_DEV_NAME_LEN; -+ kalMemCopy(prP2PConnSettings->aucDevName, aucDefaultDevName, sizeof(aucDefaultDevName)); -+ -+ /* Setup Primary Device Type (Big-Endian) */ -+ prDevType = &prP2PConnSettings->rPrimaryDevTypeBE; -+ -+ prDevType->u2CategoryId = HTONS(P2P_DEFAULT_PRIMARY_CATEGORY_ID); -+ prDevType->u2SubCategoryId = HTONS(P2P_DEFAULT_PRIMARY_SUB_CATEGORY_ID); -+ -+ prDevType->aucOui[0] = aucWfaOui[0]; -+ prDevType->aucOui[1] = aucWfaOui[1]; -+ prDevType->aucOui[2] = aucWfaOui[2]; -+ prDevType->aucOui[3] = VENDOR_OUI_TYPE_WPS; -+ -+ /* Setup Secondary Device Type */ -+ prP2PConnSettings->ucSecondaryDevTypeCount = 0; -+ -+ /* Setup Default Config Method */ -+ prP2PConnSettings->eConfigMethodSelType = ENUM_CONFIG_METHOD_SEL_AUTO; -+ prP2PConnSettings->u2ConfigMethodsSupport = P2P_DEFAULT_CONFIG_METHOD; -+ prP2PConnSettings->u2TargetConfigMethod = 0; -+ prP2PConnSettings->u2LocalConfigMethod = 0; -+ prP2PConnSettings->fgIsPasswordIDRdy = FALSE; -+ -+ /* For Device Capability */ -+ prP2PConnSettings->fgSupportServiceDiscovery = FALSE; -+ prP2PConnSettings->fgSupportClientDiscoverability = TRUE; -+ prP2PConnSettings->fgSupportConcurrentOperation = TRUE; -+ prP2PConnSettings->fgSupportInfraManaged = FALSE; -+ prP2PConnSettings->fgSupportInvitationProcedure = FALSE; -+ -+ /* For Group Capability */ -+#if CFG_SUPPORT_PERSISTENT_GROUP -+ prP2PConnSettings->fgSupportPersistentP2PGroup = TRUE; -+#else -+ prP2PConnSettings->fgSupportPersistentP2PGroup = FALSE; -+#endif -+ prP2PConnSettings->fgSupportIntraBSSDistribution = TRUE; -+ prP2PConnSettings->fgSupportCrossConnection = TRUE; -+ prP2PConnSettings->fgSupportPersistentReconnect = FALSE; -+ -+ prP2PConnSettings->fgSupportOppPS = FALSE; -+ prP2PConnSettings->u2CTWindow = P2P_CTWINDOW_DEFAULT; -+ -+ /* For Connection Settings. */ -+ prP2PConnSettings->eAuthMode = AUTH_MODE_OPEN; -+ -+ prP2PConnSettings->prTargetP2pDesc = NULL; -+ prP2PConnSettings->ucSSIDLen = 0; -+ -+ /* Misc */ -+ prP2PConnSettings->fgIsScanReqIssued = FALSE; -+ prP2PConnSettings->fgIsServiceDiscoverIssued = FALSE; -+ prP2PConnSettings->fgP2pGroupLimit = FALSE; -+ prP2PConnSettings->ucOperatingChnl = 0; -+ prP2PConnSettings->ucListenChnl = 0; -+ prP2PConnSettings->ucTieBreaker = (UINT_8) (kalRandomNumber() & 0x1); -+ -+ prP2PConnSettings->eFormationPolicy = ENUM_P2P_FORMATION_POLICY_AUTO; -+#if CFG_SUPPORT_CFG_FILE -+ /* prP2PConnSettings->fgIsWPSMode = prWifiVar->ucApWpsMode; */ -+ prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = prWifiVar->ucApWpsMode; -+#endif -+} /* p2pFuncInitConnectionSettings */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Assoc Req Frame and then return -+* the status code to AAA to indicate if need to perform following actions -+* when the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu2StatusCode The Status Code of Validation Result -+* -+* @retval TRUE Reply the Assoc Resp -+* @retval FALSE Don't reply the Assoc Resp -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pFuncValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) -+{ -+ BOOLEAN fgReplyAssocResp = TRUE; -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+#if CFG_SUPPORT_WFD -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_WFD_ATTRIBUTE_T prWfdAttribute = (P_WFD_ATTRIBUTE_T) NULL; -+ BOOLEAN fgNeedFree = FALSE; -+#endif -+ /* UINT_16 u2AttriListLen = 0; */ -+ UINT_16 u2WfdDevInfo = 0; -+ P_WFD_DEVICE_INFORMATION_IE_T prAttriWfdDevInfo; -+ -+ /* TODO(Kevin): Call P2P functions to check .. -+ 2. Check we can accept connection from thsi peer -+ a. If we are in PROVISION state, only accept the peer we do the GO formation previously. -+ b. If we are in OPERATION state, only accept the other peer when P2P_GROUP_LIMIT is 0. -+ 3. Check Black List here. -+ */ -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL) && (pu2StatusCode != NULL)); -+ -+ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prStaRec == NULL) { -+ /* Station record should be ready while RX AUTH frame. */ -+ fgReplyAssocResp = FALSE; -+ ASSERT(FALSE); -+ break; -+ } -+ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; -+ -+ prStaRec->u2DesiredNonHTRateSet &= prP2pBssInfo->u2OperationalRateSet; -+ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prP2pBssInfo->ucPhyTypeSet; -+ -+ if (prStaRec->ucDesiredPhyTypeSet == 0) { -+ /* The station only support 11B rate. */ -+ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; -+ break; -+ } -+#if CFG_SUPPORT_WFD && 1 -+ /* LOG_FUNC("Skip check WFD IE because some API is not ready\n"); */ -+ if (!prAdapter->rWifiVar.prP2pFsmInfo) { -+ fgReplyAssocResp = FALSE; -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ DBGLOG(P2P, INFO, "AssocReq, wfd_en %u wfd_info 0x%x wfd_policy 0x%x wfd_flag 0x%x\n", -+ prWfdCfgSettings->ucWfdEnable, prWfdCfgSettings->u2WfdDevInfo, -+ prWfdCfgSettings->u4WfdPolicy, prWfdCfgSettings->u4WfdFlag); /* Eddie */ -+ if (prWfdCfgSettings->ucWfdEnable) { -+ if (prWfdCfgSettings->u4WfdPolicy & BIT(6)) { -+ /* Rejected all. */ -+ break; -+ } -+ -+ /* fgNeedFree = p2pFuncGetAttriList(prAdapter, */ -+ /* VENDOR_OUI_TYPE_WFD, */ -+ /* (PUINT_8)prAssocReqFrame->aucInfoElem, */ -+ /* (prSwRfb->u2PacketLen - OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem)), */ -+ /* (PPUINT_8)&prWfdAttribute, */ -+ /* &u2AttriListLen); */ -+ -+ prAttriWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) -+ p2pFuncGetSpecAttri(prAdapter, -+ VENDOR_OUI_TYPE_WFD, -+ (PUINT_8) prAssocReqFrame->aucInfoElem, -+ (prSwRfb->u2PacketLen - -+ OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem)), -+ WFD_ATTRI_ID_DEV_INFO); -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(5)) && (prAttriWfdDevInfo != NULL)) { -+ /* Rejected with WFD IE. */ -+ break; -+ } -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(0)) && (prAttriWfdDevInfo == NULL)) { -+ /* Rejected without WFD IE. */ -+ break; -+ } -+ -+ if (prAttriWfdDevInfo == NULL) { -+ /* -+ * Without WFD IE. -+ * Do nothing. Accept the connection request. -+ */ -+ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; -+ break; -+ } -+ -+ /* prAttriWfdDevInfo = */ -+ /* (P_WFD_DEVICE_INFORMATION_IE_T)p2pFuncGetSpecAttri(prAdapter, */ -+ /* VENDOR_OUI_TYPE_WFD, */ -+ /* (PUINT_8)prWfdAttribute, */ -+ /* u2AttriListLen, */ -+ /* WFD_ATTRI_ID_DEV_INFO); */ -+ /* if (prAttriWfdDevInfo == NULL) { */ -+ /* No such attribute. */ -+ /* break; */ -+ /* } */ -+ -+ WLAN_GET_FIELD_BE16(&prAttriWfdDevInfo->u2WfdDevInfo, &u2WfdDevInfo); -+ DBGLOG(P2P, INFO, "RX Assoc Req WFD Info:0x%x.\n", u2WfdDevInfo); -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(1)) && ((u2WfdDevInfo & 0x3) == 0x0)) { -+ /* Rejected because of SOURCE. */ -+ break; -+ } -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(2)) && ((u2WfdDevInfo & 0x3) == 0x1)) { -+ /* Rejected because of Primary Sink. */ -+ break; -+ } -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(3)) && ((u2WfdDevInfo & 0x3) == 0x2)) { -+ /* Rejected because of Secondary Sink. */ -+ break; -+ } -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(4)) && ((u2WfdDevInfo & 0x3) == 0x3)) { -+ /* Rejected because of Source & Primary Sink. */ -+ break; -+ } -+ -+ /* Check role */ -+ -+ if ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) && -+ ((prWfdCfgSettings->u2WfdDevInfo & BITS(0, 1)) == 0x3)) { -+ /* P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = -+ * (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T)NULL; */ -+ UINT_16 u2DevInfo = prWfdCfgSettings->u2WfdDevInfo; -+ -+ /* We may change role here if we are dual role */ -+ -+ if ((u2WfdDevInfo & BITS(0, 1)) == 0x00 /* Peer is Source */) { -+ DBGLOG(P2P, INFO, "WFD: Switch role to primary sink\n"); -+ -+ prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1); -+ prWfdCfgSettings->u2WfdDevInfo |= 0x1; -+ -+ /* event to annonce the role is chanaged to P-Sink */ -+ -+ } else if ((u2WfdDevInfo & BITS(0, 1)) == 0x01 /* Peer is P-Sink */) { -+ DBGLOG(P2P, INFO, "WFD: Switch role to source\n"); -+ -+ prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1); -+ /* event to annonce the role is chanaged to Source */ -+ } else { -+ DBGLOG(P2P, INFO, "WFD: Peer role is wrong type(dev 0x%x)\n", -+ (u2DevInfo)); -+ DBGLOG(P2P, INFO, "WFD: Switch role to source\n"); -+ -+ prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1); -+ /* event to annonce the role is chanaged to Source */ -+ } -+ -+ p2pFsmRunEventWfdSettingUpdate(prAdapter, NULL); -+ -+ } /* Dual role p2p->wfd_params->WfdDevInfo */ -+ -+ /* WFD_FLAG_DEV_INFO_VALID */ -+ } -+ /* ucWfdEnable */ -+#endif -+ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; -+ } while (FALSE); -+ -+#if CFG_SUPPORT_WFD -+ if ((prWfdAttribute) && (fgNeedFree)) -+ kalMemFree(prWfdAttribute, VIR_MEM_TYPE, WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE); -+#endif -+ -+ return fgReplyAssocResp; -+ -+} /* p2pFuncValidateAssocReq */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to check the P2P IE -+* -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pFuncParseCheckForP2PInfoElem(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType) -+{ -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ P_IE_WFA_T prWfaIE = (P_IE_WFA_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pucOuiType != NULL)); -+ -+ prWfaIE = (P_IE_WFA_T) pucBuf; -+ -+ if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) { -+ break; -+ } else if (prWfaIE->aucOui[0] != aucWfaOui[0] || -+ prWfaIE->aucOui[1] != aucWfaOui[1] || prWfaIE->aucOui[2] != aucWfaOui[2]) { -+ break; -+ } -+ -+ *pucOuiType = prWfaIE->ucOuiType; -+ -+ return TRUE; -+ } while (FALSE); -+ -+ return FALSE; -+} /* p2pFuncParseCheckForP2PInfoElem */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Probe Request Frame and then return -+* result to BSS to indicate if need to send the corresponding Probe Response -+* Frame if the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu4ControlFlags Control flags for replying the Probe Response -+* -+* @retval TRUE Reply the Probe Response -+* @retval FALSE Don't reply the Probe Response -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pFuncValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags) -+{ -+ BOOLEAN fgIsReplyProbeRsp = FALSE; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ DEBUGFUNC("p2pFuncValidateProbeReq"); -+ DBGLOG(P2P, TRACE, "p2pFuncValidateProbeReq\n"); -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo->u4P2pPacketFilter & PARAM_PACKET_FILTER_PROBE_REQ) { -+ -+ DBGLOG(P2P, TRACE, "report probe req to OS\n"); -+ /* Leave the probe response to p2p_supplicant. */ -+ kalP2PIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb); -+ } -+ -+ } while (FALSE); -+ -+ return fgIsReplyProbeRsp; -+ -+} /* end of p2pFuncValidateProbeReq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Probe Request Frame and then return -+* result to BSS to indicate if need to send the corresponding Probe Response -+* Frame if the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu4ControlFlags Control flags for replying the Probe Response -+* -+* @retval TRUE Reply the Probe Response -+* @retval FALSE Don't reply the Probe Response -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ DEBUGFUNC("p2pFuncValidateProbeReq"); -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo->u4P2pPacketFilter & PARAM_PACKET_FILTER_ACTION_FRAME) { -+ /* Leave the probe response to p2p_supplicant. */ -+ kalP2PIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb); -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* p2pFuncValidateRxMgmtFrame */ -+ -+BOOLEAN p2pFuncIsAPMode(IN P_P2P_FSM_INFO_T prP2pFsmInfo) -+{ -+ if (prP2pFsmInfo) { -+ if (prP2pFsmInfo->fgIsWPSMode == 1) -+ return FALSE; -+ return prP2pFsmInfo->fgIsApMode; -+ } else { -+ return FALSE; -+ } -+} -+ -+/* p2pFuncIsAPMode */ -+ -+VOID -+p2pFuncParseBeaconContent(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN PUINT_8 pucIEInfo, IN UINT_32 u4IELen) -+{ -+ PUINT_8 pucIE = (PUINT_8) NULL; -+ UINT_16 u2Offset = 0; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ BOOLEAN ucNewSecMode = FALSE; -+ BOOLEAN ucOldSecMode = FALSE; -+ UINT_8 ucOuiType; -+ UINT_16 u2SubTypeVersion; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL)); -+ -+ if (u4IELen == 0) -+ break; -+ -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ prP2pSpecificBssInfo->u2AttributeLen = 0; -+ -+ ASSERT_BREAK(pucIEInfo != NULL); -+ -+ pucIE = pucIEInfo; -+ -+ ucOldSecMode = kalP2PGetCipher(prAdapter->prGlueInfo); -+ -+ IE_FOR_EACH(pucIE, u4IELen, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_SSID: -+ { -+ /* 0 */ /* V */ /* Done */ -+ /* DBGLOG(P2P, TRACE, ("SSID update\n")); */ -+ /* SSID is saved when start AP/GO */ -+ /* SSID IE set in beacon from supplicant will not always be */ -+ /* the true since hidden SSID case */ -+ /* -+ COPY_SSID(prP2pBssInfo->aucSSID, -+ prP2pBssInfo->ucSSIDLen, -+ SSID_IE(pucIE)->aucSSID, -+ SSID_IE(pucIE)->ucLength); -+ -+ COPY_SSID(prP2pSpecificBssInfo->aucGroupSsid, -+ prP2pSpecificBssInfo->u2GroupSsidLen, -+ SSID_IE(pucIE)->aucSSID, -+ SSID_IE(pucIE)->ucLength); -+ */ -+ } -+ break; -+ case ELEM_ID_SUP_RATES: -+ { -+ /* 1 */ /* V */ /* Done */ -+ DBGLOG(P2P, TRACE, "Support Rate IE\n"); -+ kalMemCopy(prP2pBssInfo->aucAllSupportedRates, -+ SUP_RATES_IE(pucIE)->aucSupportedRates, -+ SUP_RATES_IE(pucIE)->ucLength); -+ -+ prP2pBssInfo->ucAllSupportedRatesLen = SUP_RATES_IE(pucIE)->ucLength; -+ -+ DBGLOG_MEM8(P2P, TRACE, SUP_RATES_IE(pucIE)->aucSupportedRates, -+ SUP_RATES_IE(pucIE)->ucLength); -+ } -+ break; -+ case ELEM_ID_DS_PARAM_SET: -+ { -+ /* 3 */ /* V */ /* Done */ -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = -+ prAdapter->rWifiVar.prP2PConnSettings; -+ -+ DBGLOG(P2P, TRACE, "DS PARAM IE\n"); -+ -+ ASSERT(prP2pConnSettings->ucOperatingChnl == DS_PARAM_IE(pucIE)->ucCurrChnl); -+ -+ if (prP2pConnSettings->eBand != BAND_2G4) { -+ ASSERT(FALSE); -+ break; -+ } -+ /* prP2pBssInfo->ucPrimaryChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; */ -+ -+ /* prP2pBssInfo->eBand = BAND_2G4; */ -+ } -+ break; -+ case ELEM_ID_TIM: /* 5 */ /* V */ -+ DBGLOG(P2P, TRACE, "TIM IE\n"); -+ TIM_IE(pucIE)->ucDTIMPeriod = prP2pBssInfo->ucDTIMPeriod; -+ break; -+ case ELEM_ID_ERP_INFO: /* 42 */ /* V */ -+ { -+#if 1 -+ /* This IE would dynamic change due to FW detection change is required. */ -+ DBGLOG(P2P, TRACE, "ERP IE will be over write by driver\n"); -+ DBGLOG(P2P, TRACE, " ucERP: %x.\n", ERP_INFO_IE(pucIE)->ucERP); -+ -+#else -+ /* This IE would dynamic change due to FW detection change is required. */ -+ DBGLOG(P2P, TRACE, "ERP IE.\n"); -+ -+ prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11GN; -+ -+ ASSERT(prP2pBssInfo->eBand == BAND_2G4); -+ -+ prP2pBssInfo->fgObssErpProtectMode = -+ ((ERP_INFO_IE(pucIE)->ucERP & ERP_INFO_USE_PROTECTION) ? TRUE : FALSE); -+ -+ prP2pBssInfo->fgErpProtectMode = -+ ((ERP_INFO_IE(pucIE)->ucERP & -+ (ERP_INFO_USE_PROTECTION | ERP_INFO_NON_ERP_PRESENT)) ? TRUE : FALSE); -+#endif -+ -+ } -+ break; -+ case ELEM_ID_HT_CAP: /* 45 */ /* V */ -+ { -+#if 1 -+ DBGLOG(P2P, TRACE, "HT CAP IE would be overwritten by driver\n"); -+ -+ DBGLOG(P2P, TRACE, -+ "HT Cap Info:%x, AMPDU Param:%x\n", HT_CAP_IE(pucIE)->u2HtCapInfo, -+ HT_CAP_IE(pucIE)->ucAmpduParam); -+ -+ DBGLOG(P2P, TRACE, -+ "HT Extended Cap Info%x,TX Beamforming Cap Info%x,Ant Selection Cap Info%x\n", -+ HT_CAP_IE(pucIE)->u2HtExtendedCap, HT_CAP_IE(pucIE)->u4TxBeamformingCap, -+ HT_CAP_IE(pucIE)->ucAselCap); -+#else -+ prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; -+ -+ /* u2HtCapInfo */ -+ if ((HT_CAP_IE(pucIE)->u2HtCapInfo & -+ (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | -+ HT_CAP_INFO_DSSS_CCK_IN_40M)) == 0) { -+ prP2pBssInfo->fgAssoc40mBwAllowed = FALSE; -+ } else { -+ prP2pBssInfo->fgAssoc40mBwAllowed = TRUE; -+ } -+ -+ if ((HT_CAP_IE(pucIE)->u2HtCapInfo & -+ (HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M)) == 0) { -+ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = TRUE; -+ } else { -+ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = FALSE; -+ } -+ -+ /* ucAmpduParam */ -+ DBGLOG(P2P, TRACE, -+ "AMPDU setting from supplicant:0x%x, & default value:0x%x\n", -+ (UINT_8) HT_CAP_IE(pucIE)->ucAmpduParam, -+ (UINT_8) AMPDU_PARAM_DEFAULT_VAL); -+ -+ /* rSupMcsSet */ -+ /* Can do nothing. the field is default value from other configuration. */ -+ /* HT_CAP_IE(pucIE)->rSupMcsSet; */ -+ -+ /* u2HtExtendedCap */ -+ ASSERT(HT_CAP_IE(pucIE)->u2HtExtendedCap == -+ (HT_EXT_CAP_DEFAULT_VAL & -+ ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE))); -+ -+ /* u4TxBeamformingCap */ -+ ASSERT(HT_CAP_IE(pucIE)->u4TxBeamformingCap == TX_BEAMFORMING_CAP_DEFAULT_VAL); -+ -+ /* ucAselCap */ -+ ASSERT(HT_CAP_IE(pucIE)->ucAselCap == ASEL_CAP_DEFAULT_VAL); -+#endif -+ } -+ break; -+ case ELEM_ID_RSN: /* 48 */ /* V */ -+ { -+ RSN_INFO_T rRsnIe; -+ -+ DBGLOG(P2P, TRACE, "RSN IE\n"); -+ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_CCMP); -+ ucNewSecMode = TRUE; -+ -+ if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &rRsnIe)) { -+ prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ prP2pBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; -+ prP2pBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; -+ prP2pBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; -+ prP2pBssInfo->u2RsnSelectedCapInfo = rRsnIe.u2RsnCap; -+ } -+ } -+ break; -+ case ELEM_ID_EXTENDED_SUP_RATES: /* 50 */ /* V */ -+ /* Be attention, -+ * ELEM_ID_SUP_RATES should be placed before ELEM_ID_EXTENDED_SUP_RATES. */ -+ DBGLOG(P2P, TRACE, "Ex Support Rate IE\n"); -+ kalMemCopy(&(prP2pBssInfo->aucAllSupportedRates[prP2pBssInfo->ucAllSupportedRatesLen]), -+ EXT_SUP_RATES_IE(pucIE)->aucExtSupportedRates, -+ EXT_SUP_RATES_IE(pucIE)->ucLength); -+ -+ DBGLOG_MEM8(P2P, TRACE, EXT_SUP_RATES_IE(pucIE)->aucExtSupportedRates, -+ EXT_SUP_RATES_IE(pucIE)->ucLength); -+ -+ prP2pBssInfo->ucAllSupportedRatesLen += EXT_SUP_RATES_IE(pucIE)->ucLength; -+ break; -+ case ELEM_ID_HT_OP: -+ { -+ /* 61 */ /* V */ /* TODO: */ -+#if 1 -+ DBGLOG(P2P, TRACE, "HT OP IE would be overwritten by driver\n"); -+ -+ DBGLOG(P2P, TRACE, -+ " Primary Channel: %x, Info1: %x, Info2: %x, Info3: %x\n", -+ HT_OP_IE(pucIE)->ucPrimaryChannel, HT_OP_IE(pucIE)->ucInfo1, -+ HT_OP_IE(pucIE)->u2Info2, HT_OP_IE(pucIE)->u2Info3); -+#else -+ UINT_16 u2Info2 = 0; -+ -+ prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; -+ -+ DBGLOG(P2P, TRACE, "HT OP IE\n"); -+ -+ /* ucPrimaryChannel. */ -+ ASSERT(HT_OP_IE(pucIE)->ucPrimaryChannel == prP2pBssInfo->ucPrimaryChannel); -+ -+ /* ucInfo1 */ -+ prP2pBssInfo->ucHtOpInfo1 = HT_OP_IE(pucIE)->ucInfo1; -+ -+ /* u2Info2 */ -+ u2Info2 = HT_OP_IE(pucIE)->u2Info2; -+ -+ if (u2Info2 & HT_OP_INFO2_NON_GF_HT_STA_PRESENT) { -+ ASSERT(prP2pBssInfo->eGfOperationMode != GF_MODE_NORMAL); -+ u2Info2 &= ~HT_OP_INFO2_NON_GF_HT_STA_PRESENT; -+ } -+ -+ if (u2Info2 & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT) { -+ prP2pBssInfo->eObssHtProtectMode = HT_PROTECT_MODE_NON_MEMBER; -+ u2Info2 &= ~HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; -+ } -+ -+ switch (u2Info2 & HT_OP_INFO2_HT_PROTECTION) { -+ case HT_PROTECT_MODE_NON_HT: -+ prP2pBssInfo->eHtProtectMode = HT_PROTECT_MODE_NON_HT; -+ break; -+ case HT_PROTECT_MODE_NON_MEMBER: -+ prP2pBssInfo->eHtProtectMode = HT_PROTECT_MODE_NONE; -+ prP2pBssInfo->eObssHtProtectMode = HT_PROTECT_MODE_NON_MEMBER; -+ break; -+ default: -+ prP2pBssInfo->eHtProtectMode = HT_OP_IE(pucIE)->u2Info2; -+ break; -+ } -+ -+ /* u2Info3 */ -+ prP2pBssInfo->u2HtOpInfo3 = HT_OP_IE(pucIE)->u2Info3; -+ -+ /* aucBasicMcsSet */ -+ DBGLOG_MEM8(P2P, TRACE, HT_OP_IE(pucIE)->aucBasicMcsSet, 16); -+#endif -+ } -+ break; -+ case ELEM_ID_OBSS_SCAN_PARAMS: /* 74 */ /* V */ -+ { -+ DBGLOG(P2P, TRACE, -+ "ELEM_ID_OBSS_SCAN_PARAMS IE would be replaced by driver\n"); -+ } -+ break; -+ case ELEM_ID_EXTENDED_CAP: /* 127 */ /* V */ -+ { -+ DBGLOG(P2P, TRACE, "ELEM_ID_EXTENDED_CAP IE would be replaced by driver\n"); -+ } -+ break; -+ case ELEM_ID_VENDOR: /* 221 */ /* V */ -+ DBGLOG(P2P, TRACE, "Vender Specific IE\n"); -+ if (rsnParseCheckForWFAInfoElem -+ (prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) { -+ if ((ucOuiType == VENDOR_OUI_TYPE_WPA) -+ && (u2SubTypeVersion == VERSION_WPA)) { -+ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_TKIP); -+ ucNewSecMode = TRUE; -+ kalMemCopy(prP2pSpecificBssInfo->aucWpaIeBuffer, pucIE, -+ IE_SIZE(pucIE)); -+ prP2pSpecificBssInfo->u2WpaIeLen = IE_SIZE(pucIE); -+ } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 0, pucIE, -+ IE_SIZE(pucIE)); -+ } -+ /* WMM here. */ -+ } else if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) { -+ /* TODO Store the whole P2P IE & generate later. */ -+ /* Be aware that there may be one or more P2P IE. */ -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache -+ [prP2pSpecificBssInfo->u2AttributeLen], pucIE, -+ IE_SIZE(pucIE)); -+ -+ prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE); -+ } else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { -+ -+ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache -+ [prP2pSpecificBssInfo->u2AttributeLen], pucIE, -+ IE_SIZE(pucIE)); -+ -+ prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE); -+ } -+ } else { -+ -+ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache -+ [prP2pSpecificBssInfo->u2AttributeLen], pucIE, -+ IE_SIZE(pucIE)); -+ -+ prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE); -+ DBGLOG(P2P, TRACE, "Driver unprocessed Vender Specific IE\n"); -+ ASSERT(FALSE); -+ } -+ -+ /* TODO: Store other Vender IE except for WMM Param. */ -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "Unprocessed element ID:%d\n", IE_ID(pucIE)); -+ break; -+ } -+ } -+ -+ if (!ucNewSecMode && ucOldSecMode) -+ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_NONE); -+ -+ } while (FALSE); -+ -+} /* p2pFuncParseBeaconContent */ -+ -+P_BSS_DESC_T -+p2pFuncKeepOnConnection(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo, -+ IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo) -+{ -+ P_BSS_DESC_T prTargetBss = (P_BSS_DESC_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && -+ (prConnReqInfo != NULL) && (prChnlReqInfo != NULL) && (prScanReqInfo != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ if (prP2pBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ break; -+ /* Update connection request information. */ -+ ASSERT(prConnReqInfo->fgIsConnRequest == TRUE); -+ -+ /* Find BSS Descriptor first. */ -+ prTargetBss = scanP2pSearchDesc(prAdapter, prP2pBssInfo, prConnReqInfo); -+ -+ if (prTargetBss == NULL) { -+ /* Update scan parameter... to scan target device. */ -+ prScanReqInfo->ucNumChannelList = 1; -+ prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+ prScanReqInfo->eChannelSet = SCAN_CHANNEL_FULL; -+ prScanReqInfo->u4BufLength = 0; /* Prevent other P2P ID in IE. */ -+ prScanReqInfo->fgIsAbort = TRUE; -+ } else { -+ prChnlReqInfo->u8Cookie = 0; -+ prChnlReqInfo->ucReqChnlNum = prTargetBss->ucChannelNum; -+ prChnlReqInfo->eBand = prTargetBss->eBand; -+ prChnlReqInfo->eChnlSco = prTargetBss->eSco; -+ prChnlReqInfo->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL; -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GC_JOIN_REQ; -+ } -+ -+ } while (FALSE); -+ -+ return prTargetBss; -+} /* p2pFuncKeepOnConnection */ -+ -+/* Currently Only for ASSOC Response Frame. */ -+VOID p2pFuncStoreAssocRspIEBuffer(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_JOIN_INFO_T prJoinInfo = (P_P2P_JOIN_INFO_T) NULL; -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL; -+ INT_16 i2IELen = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prSwRfb->pvHeader; -+ -+ if (prAssocRspFrame->u2FrameCtrl != MAC_FRAME_ASSOC_RSP) -+ break; -+ -+ i2IELen = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + -+ CAP_INFO_FIELD_LEN + STATUS_CODE_FIELD_LEN + AID_FIELD_LEN); -+ -+ if (i2IELen <= 0) -+ break; -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prJoinInfo = &(prP2pFsmInfo->rJoinInfo); -+ prJoinInfo->u4BufLength = (UINT_32) i2IELen; -+ -+ kalMemCopy(prJoinInfo->aucIEBuf, prAssocRspFrame->aucInfoElem, prJoinInfo->u4BufLength); -+ -+ } while (FALSE); -+ -+} /* p2pFuncStoreAssocRspIEBuffer */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set Packet Filter. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_NOT_SUPPORTED -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pFuncMgmtFrameRegister(IN P_ADAPTER_T prAdapter, -+ IN UINT_16 u2FrameType, IN BOOLEAN fgIsRegistered, OUT PUINT_32 pu4P2pPacketFilter) -+{ -+ UINT_32 u4NewPacketFilter = 0; -+ -+ DEBUGFUNC("p2pFuncMgmtFrameRegister"); -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ if (pu4P2pPacketFilter) -+ u4NewPacketFilter = *pu4P2pPacketFilter; -+ -+ switch (u2FrameType) { -+ case MAC_FRAME_PROBE_REQ: -+ if (fgIsRegistered) { -+ u4NewPacketFilter |= PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(P2P, TRACE, "Open packet filer probe request\n"); -+ } else { -+ u4NewPacketFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(P2P, TRACE, "Close packet filer probe request\n"); -+ } -+ break; -+ case MAC_FRAME_ACTION: -+ if (fgIsRegistered) { -+ u4NewPacketFilter |= PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(P2P, TRACE, "Open packet filer action frame.\n"); -+ } else { -+ u4NewPacketFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(P2P, TRACE, "Close packet filer action frame.\n"); -+ } -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "Ask frog to add code for mgmt:%x\n", u2FrameType); -+ break; -+ } -+ -+ if (pu4P2pPacketFilter) -+ *pu4P2pPacketFilter = u4NewPacketFilter; -+ -+ /* u4NewPacketFilter |= prAdapter->u4OsPacketFilter; */ -+ -+ prAdapter->u4OsPacketFilter &= ~PARAM_PACKET_FILTER_P2P_MASK; -+ prAdapter->u4OsPacketFilter |= u4NewPacketFilter; -+ -+ DBGLOG(P2P, TRACE, "P2P Set PACKET filter:0x%x\n", prAdapter->u4OsPacketFilter); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_RX_FILTER, -+ TRUE, -+ FALSE, -+ FALSE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(UINT_32), -+ (PUINT_8) &prAdapter->u4OsPacketFilter, -+ &u4NewPacketFilter, sizeof(u4NewPacketFilter) -+ ); -+ -+ } while (FALSE); -+ -+} /* p2pFuncMgmtFrameRegister */ -+ -+VOID p2pFuncUpdateMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN UINT_32 u4OsFilter) -+{ -+ -+ do { -+ -+ prAdapter->rWifiVar.prP2pFsmInfo->u4P2pPacketFilter = u4OsFilter; -+ -+ if ((prAdapter->u4OsPacketFilter & PARAM_PACKET_FILTER_P2P_MASK) ^ u4OsFilter) { -+ -+ prAdapter->u4OsPacketFilter &= ~PARAM_PACKET_FILTER_P2P_MASK; -+ -+ prAdapter->u4OsPacketFilter |= (u4OsFilter & PARAM_PACKET_FILTER_P2P_MASK); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_RX_FILTER, -+ TRUE, -+ FALSE, -+ FALSE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(UINT_32), -+ (PUINT_8) &prAdapter->u4OsPacketFilter, &u4OsFilter, sizeof(u4OsFilter) -+ ); -+ DBGLOG(P2P, TRACE, "P2P Set PACKET filter:0x%x\n", prAdapter->u4OsPacketFilter); -+ } -+ -+ } while (FALSE); -+ -+} /* p2pFuncUpdateMgmtFrameRegister */ -+ -+VOID p2pFuncGetStationInfo(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucMacAddr, OUT P_P2P_STATION_INFO_T prStaInfo) -+{ -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucMacAddr != NULL) && (prStaInfo != NULL)); -+ -+ prStaInfo->u4InactiveTime = 0; -+ prStaInfo->u4RxBytes = 0; -+ prStaInfo->u4TxBytes = 0; -+ prStaInfo->u4RxPackets = 0; -+ prStaInfo->u4TxPackets = 0; -+ /* TODO: */ -+ -+ } while (FALSE); -+ -+} /* p2pFuncGetStationInfo */ -+ -+BOOLEAN -+p2pFuncGetAttriList(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, -+ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen) -+{ -+ BOOLEAN fgIsAllocMem = FALSE; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ UINT_16 u2Offset = 0; -+ P_IE_P2P_T prIe = (P_IE_P2P_T) NULL; -+ PUINT_8 pucAttriListStart = (PUINT_8) NULL; -+ UINT_16 u2AttriListLen = 0, u2BufferSize = 0; -+ BOOLEAN fgBackupAttributes = FALSE; -+ UINT_16 u2CopyLen; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucIE); -+ ASSERT(ppucAttriList); -+ ASSERT(pu2AttriListLen); -+ -+ if (ppucAttriList) -+ *ppucAttriList = NULL; -+ if (pu2AttriListLen) -+ *pu2AttriListLen = 0; -+ -+ if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ aucWfaOui[0] = 0x00; -+ aucWfaOui[1] = 0x50; -+ aucWfaOui[2] = 0xF2; -+ } else if ((ucOuiType != VENDOR_OUI_TYPE_P2P) -+#if CFG_SUPPORT_WFD -+ && (ucOuiType != VENDOR_OUI_TYPE_WFD) -+#endif -+ ) { -+ DBGLOG(P2P, INFO, "Not supported OUI Type to parsing 0x%x\n", ucOuiType); -+ return fgIsAllocMem; -+ } -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ if (ELEM_ID_VENDOR != IE_ID(pucIE)) -+ continue; -+ -+ prIe = (P_IE_P2P_T) pucIE; -+ -+ if (prIe->ucLength <= P2P_OUI_TYPE_LEN) -+ continue; -+ -+ if ((prIe->aucOui[0] == aucWfaOui[0]) && -+ (prIe->aucOui[1] == aucWfaOui[1]) && -+ (prIe->aucOui[2] == aucWfaOui[2]) && (ucOuiType == prIe->ucOuiType)) { -+ -+ if (!pucAttriListStart) { -+ pucAttriListStart = &prIe->aucP2PAttributes[0]; -+ if (prIe->ucLength > P2P_OUI_TYPE_LEN) -+ u2AttriListLen = (UINT_16) (prIe->ucLength - P2P_OUI_TYPE_LEN); -+ else -+ ASSERT(FALSE); -+ continue; -+ } -+/* More than 2 attributes. */ -+ -+ if (FALSE == fgBackupAttributes) { -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = -+ prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ fgBackupAttributes = TRUE; -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache[0], -+ pucAttriListStart, u2AttriListLen); -+ -+ pucAttriListStart = -+ &prP2pSpecificBssInfo->aucAttributesCache[0]; -+ -+ u2BufferSize = P2P_MAXIMUM_ATTRIBUTE_LEN; -+ } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ kalMemCopy(&prP2pSpecificBssInfo->aucWscAttributesCache -+ [0], pucAttriListStart, u2AttriListLen); -+ pucAttriListStart = -+ &prP2pSpecificBssInfo->aucWscAttributesCache[0]; -+ -+ u2BufferSize = WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE; -+ } -+#if CFG_SUPPORT_WFD -+ else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { -+ PUINT_8 pucTmpBuf = (PUINT_8) NULL; -+ -+ pucTmpBuf = (PUINT_8) -+ kalMemAlloc(WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE, -+ VIR_MEM_TYPE); -+ -+ if (pucTmpBuf != NULL) { -+ fgIsAllocMem = TRUE; -+ } else { -+ /* Can't alloca memory for WFD IE relocate. */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ kalMemCopy(pucTmpBuf, -+ pucAttriListStart, u2AttriListLen); -+ -+ pucAttriListStart = pucTmpBuf; -+ -+ u2BufferSize = WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE; -+ } -+#endif -+ else -+ fgBackupAttributes = FALSE; -+ } -+ -+ u2CopyLen = (UINT_16) (prIe->ucLength - P2P_OUI_TYPE_LEN); -+ -+ if ((u2AttriListLen + u2CopyLen) > u2BufferSize) { -+ u2CopyLen = u2BufferSize - u2AttriListLen; -+ DBGLOG(P2P, WARN, -+ "Length of received P2P attributes > maximum cache size.\n"); -+ } -+ -+ if (u2CopyLen) { -+ kalMemCopy((PUINT_8) -+ ((ULONG) pucAttriListStart + -+ (UINT_32) u2AttriListLen), -+ &prIe->aucP2PAttributes[0], u2CopyLen); -+ -+ u2AttriListLen += u2CopyLen; -+ } -+ } /* prIe->aucOui */ -+ } /* IE_FOR_EACH */ -+ -+ if (pucAttriListStart) { -+ PUINT_8 pucAttribute = pucAttriListStart; -+ -+ DBGLOG(P2P, LOUD, "Checking Attribute Length.\n"); -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ P2P_ATTRI_FOR_EACH(pucAttribute, u2AttriListLen, u2Offset); -+ } else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { -+ /* Do nothing */ -+ } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ /* Big Endian: WSC, WFD. */ -+ WSC_ATTRI_FOR_EACH(pucAttribute, u2AttriListLen, u2Offset) { -+ DBGLOG(P2P, LOUD, "Attribute ID:%d, Length:%d.\n", -+ WSC_ATTRI_ID(pucAttribute), WSC_ATTRI_LEN(pucAttribute)); -+ } -+ } else { -+ } -+ -+ ASSERT(u2Offset == u2AttriListLen); -+ -+ if (ppucAttriList) -+ *ppucAttriList = pucAttriListStart; -+ if (pu2AttriListLen) -+ *pu2AttriListLen = u2AttriListLen; -+ -+ } else { -+ if (ppucAttriList) -+ *ppucAttriList = (PUINT_8) NULL; -+ if (pu2AttriListLen) -+ *pu2AttriListLen = 0; -+ } -+ -+ return fgIsAllocMem; -+} /* p2pFuncGetAttriList */ -+ -+P_MSDU_INFO_T p2pFuncProcessP2pProbeRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMgmtTxMsdu) -+{ -+ P_MSDU_INFO_T prRetMsduInfo = prMgmtTxMsdu; -+ P_WLAN_PROBE_RSP_FRAME_T prProbeRspFrame = (P_WLAN_PROBE_RSP_FRAME_T) NULL; -+ PUINT_8 pucIEBuf = (PUINT_8) NULL; -+ UINT_16 u2Offset = 0, u2IELength = 0, u2ProbeRspHdrLen = 0; -+ BOOLEAN fgIsP2PIE = FALSE, fgIsWSCIE = FALSE; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ UINT_16 u2EstimateSize = 0, u2EstimatedExtraIELen = 0; -+ UINT_32 u4IeArraySize = 0, u4Idx = 0; -+ UINT_8 ucOuiType = 0; -+ UINT_16 u2SubTypeVersion = 0; -+ -+ BOOLEAN fgIsPureAP = prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxMsdu != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ /* 3 Make sure this is probe response frame. */ -+ prProbeRspFrame = (P_WLAN_PROBE_RSP_FRAME_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); -+ ASSERT_BREAK((prProbeRspFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_PROBE_RSP); -+ -+ if (prP2pBssInfo->u2BeaconInterval) -+ prProbeRspFrame->u2BeaconInterval = prP2pBssInfo->u2BeaconInterval; -+ -+ /* 3 Get the importent P2P IE. */ -+ u2ProbeRspHdrLen = -+ (WLAN_MAC_MGMT_HEADER_LEN + TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN); -+ pucIEBuf = prProbeRspFrame->aucInfoElem; -+ u2IELength = prMgmtTxMsdu->u2FrameLength - u2ProbeRspHdrLen; -+ -+#if CFG_SUPPORT_WFD -+ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen = 0; -+#endif -+ -+ IE_FOR_EACH(pucIEBuf, u2IELength, u2Offset) { -+ switch (IE_ID(pucIEBuf)) { -+ case ELEM_ID_SSID: -+ { -+ -+ COPY_SSID(prP2pBssInfo->aucSSID, -+ prP2pBssInfo->ucSSIDLen, -+ SSID_IE(pucIEBuf)->aucSSID, SSID_IE(pucIEBuf)->ucLength); -+ } -+ break; -+ case ELEM_ID_VENDOR: -+#if !CFG_SUPPORT_WFD -+ if (rsnParseCheckForWFAInfoElem(prAdapter, pucIEBuf, &ucOuiType, &u2SubTypeVersion)) { -+ if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 2, pucIEBuf, -+ IE_SIZE(pucIEBuf)); -+ fgIsWSCIE = TRUE; -+ } -+ -+ } else if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIEBuf, &ucOuiType)) { -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ /* 2 Note(frog): I use WSC IE buffer for Probe Request to -+ * store the P2P IE for Probe Response. */ -+ kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 1, pucIEBuf, -+ IE_SIZE(pucIEBuf)); -+ fgIsP2PIE = TRUE; -+ } -+ -+ } else { -+ if ((prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen + -+ IE_SIZE(pucIEBuf)) < 512) { -+ kalMemCopy(prAdapter->prGlueInfo->prP2PInfo->aucVenderIE, -+ pucIEBuf, IE_SIZE(pucIEBuf)); -+ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen += -+ IE_SIZE(pucIEBuf); -+ } -+ } -+#else -+ /* Eddie May be WFD */ -+ if (rsnParseCheckForWFAInfoElem -+ (prAdapter, pucIEBuf, &ucOuiType, &u2SubTypeVersion)) { -+ if (ucOuiType == VENDOR_OUI_TYPE_WMM) -+ break; -+ -+ } -+ if ((prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen + IE_SIZE(pucIEBuf)) < -+ 1024) { -+ kalMemCopy(prAdapter->prGlueInfo->prP2PInfo->aucVenderIE + -+ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen, pucIEBuf, -+ IE_SIZE(pucIEBuf)); -+ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen += IE_SIZE(pucIEBuf); -+ } -+#endif -+ break; -+ default: -+ break; -+ } -+ -+ } -+ -+ /* 3 Check the total size & current frame. */ -+ u2EstimateSize = WLAN_MAC_MGMT_HEADER_LEN + -+ TIMESTAMP_FIELD_LEN + -+ BEACON_INTERVAL_FIELD_LEN + -+ CAP_INFO_FIELD_LEN + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + ELEM_MAX_LEN_DS_PARAMETER_SET); -+ -+ u2EstimatedExtraIELen = 0; -+ -+ u4IeArraySize = sizeof(txProbeRspIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); -+ for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) { -+ if (txProbeRspIETable[u4Idx].u2EstimatedFixedIELen) { -+ u2EstimatedExtraIELen += txProbeRspIETable[u4Idx].u2EstimatedFixedIELen; -+ } -+ -+ else { -+ ASSERT(txProbeRspIETable[u4Idx].pfnCalculateVariableIELen); -+ -+ u2EstimatedExtraIELen += -+ (UINT_16) (txProbeRspIETable[u4Idx].pfnCalculateVariableIELen -+ (prAdapter, NETWORK_TYPE_P2P_INDEX, NULL)); -+ } -+ -+ } -+ -+ if (fgIsWSCIE) -+ u2EstimatedExtraIELen += kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 2); -+ -+ if (fgIsP2PIE) { -+ u2EstimatedExtraIELen += kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 1); -+ u2EstimatedExtraIELen += p2pFuncCalculateP2P_IE_NoA(prAdapter, 0, NULL); -+ } -+#if CFG_SUPPORT_WFD -+ u2EstimatedExtraIELen += prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen; -+#endif -+ -+ u2EstimateSize += u2EstimatedExtraIELen; -+ if (u2EstimateSize > (prRetMsduInfo->u2FrameLength)) { -+ prRetMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimateSize); -+ -+ if (prRetMsduInfo == NULL) { -+ DBGLOG(P2P, WARN, "No packet for sending new probe response, use original one\n"); -+ prRetMsduInfo = prMgmtTxMsdu; -+ break; -+ } -+ -+ prRetMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ } -+ /* 3 Compose / Re-compose probe response frame. */ -+ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) -+ ((ULONG) (prRetMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prProbeRspFrame->aucDestAddr, prProbeRspFrame->aucSrcAddr, -+ prProbeRspFrame->aucBSSID, prProbeRspFrame->u2BeaconInterval, -+ fgIsPureAP ? prP2pBssInfo-> -+ u2CapInfo : prProbeRspFrame->u2CapInfo); -+ -+ prRetMsduInfo->u2FrameLength = -+ (WLAN_MAC_MGMT_HEADER_LEN + TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN); -+ -+ bssBuildBeaconProbeRespFrameCommonIEs(prRetMsduInfo, prP2pBssInfo, prProbeRspFrame->aucDestAddr); -+ -+ for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) { -+ if (txProbeRspIETable[u4Idx].pfnAppendIE) -+ txProbeRspIETable[u4Idx].pfnAppendIE(prAdapter, prRetMsduInfo); -+ -+ } -+ -+ if (fgIsWSCIE) { -+ kalP2PGenWSC_IE(prAdapter->prGlueInfo, -+ 2, -+ (PUINT_8) ((ULONG) prRetMsduInfo->prPacket + -+ (UINT_32) prRetMsduInfo->u2FrameLength)); -+ -+ prRetMsduInfo->u2FrameLength += (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 2); -+ } -+ -+ if (fgIsP2PIE) { -+ kalP2PGenWSC_IE(prAdapter->prGlueInfo, -+ 1, -+ (PUINT_8) ((ULONG) prRetMsduInfo->prPacket + -+ (UINT_32) prRetMsduInfo->u2FrameLength)); -+ -+ prRetMsduInfo->u2FrameLength += (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 1); -+ p2pFuncGenerateP2P_IE_NoA(prAdapter, prRetMsduInfo); -+ } -+#if CFG_SUPPORT_WFD -+ if (prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen > 0) { -+ kalMemCopy((PUINT_8) ((ULONG) prRetMsduInfo->prPacket + (UINT_32) prRetMsduInfo->u2FrameLength), -+ prAdapter->prGlueInfo->prP2PInfo->aucVenderIE, -+ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen); -+ prRetMsduInfo->u2FrameLength += (UINT_16) prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen; -+ } -+#endif -+ -+ } while (FALSE); -+ -+ if (prRetMsduInfo != prMgmtTxMsdu) -+ cnmMgtPktFree(prAdapter, prMgmtTxMsdu); -+ -+ return prRetMsduInfo; -+} /* p2pFuncProcessP2pProbeRsp */ -+ -+#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ -+UINT_32 -+p2pFuncCalculateExtra_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ UINT_32 u4IELen = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)); -+ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) -+ break; -+ -+ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ u4IELen = prP2pSpeBssInfo->u2IELenForBCN; -+ -+ } while (FALSE); -+ -+ return u4IELen; -+} /* p2pFuncCalculateP2p_IELenForBeacon */ -+ -+VOID p2pFuncGenerateExtra_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ PUINT_8 pucIEBuf = (PUINT_8) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) -+ break; -+ -+ pucIEBuf = (PUINT_8) ((UINT_32) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ kalMemCopy(pucIEBuf, prP2pSpeBssInfo->aucBeaconIECache, prP2pSpeBssInfo->u2IELenForBCN); -+ -+ prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2IELenForBCN; -+ -+ } while (FALSE); -+ -+} /* p2pFuncGenerateExtra_IEForBeacon */ -+ -+#else -+UINT_32 -+p2pFuncCalculateP2p_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ UINT_32 u4IELen = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)); -+ -+ if (!prAdapter->fgIsP2PRegistered) -+ break; -+ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) -+ break; -+ -+ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ u4IELen = prP2pSpeBssInfo->u2AttributeLen; -+ -+ } while (FALSE); -+ -+ return u4IELen; -+} /* p2pFuncCalculateP2p_IELenForBeacon */ -+ -+VOID p2pFuncGenerateP2p_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ PUINT_8 pucIEBuf = (PUINT_8) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ if (!prAdapter->fgIsP2PRegistered) -+ break; -+ -+ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) -+ break; -+ -+ pucIEBuf = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ kalMemCopy(pucIEBuf, prP2pSpeBssInfo->aucAttributesCache, prP2pSpeBssInfo->u2AttributeLen); -+ -+ prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2AttributeLen; -+ -+ } while (FALSE); -+ -+} /* p2pFuncGenerateP2p_IEForBeacon */ -+ -+UINT_32 -+p2pFuncCalculateWSC_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) -+ return 0; -+ -+ return kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); -+} /* p2pFuncCalculateP2p_IELenForBeacon */ -+ -+VOID p2pFuncGenerateWSC_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ PUINT_8 pucBuffer; -+ UINT_16 u2IELen = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX) -+ return; -+ -+ u2IELen = (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ ASSERT(pucBuffer); -+ -+ /* TODO: Check P2P FSM State. */ -+ kalP2PGenWSC_IE(prAdapter->prGlueInfo, 0, pucBuffer); -+ -+ prMsduInfo->u2FrameLength += u2IELen; -+ -+} /* p2pFuncGenerateP2p_IEForBeacon */ -+ -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to calculate P2P IE length for Beacon frame. -+* -+* @param[in] eNetTypeIndex Specify which network -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return The length of P2P IE added -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 -+p2pFuncCalculateP2p_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ -+ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) -+ return 0; -+ -+ return p2pFuncCalculateP2P_IELen(prAdapter, -+ eNetTypeIndex, -+ prStaRec, -+ txAssocRspAttributesTable, -+ sizeof(txAssocRspAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); -+ -+} /* p2pFuncCalculateP2p_IELenForAssocRsp */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate P2P IE for Beacon frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncGenerateP2p_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ if (!prStaRec) -+ break; -+ -+ if (IS_STA_P2P_TYPE(prStaRec)) { -+ DBGLOG(P2P, TRACE, "Generate NULL P2P IE for Assoc Rsp.\n"); -+ -+ p2pFuncGenerateP2P_IE(prAdapter, -+ TRUE, -+ &prMsduInfo->u2FrameLength, -+ prMsduInfo->prPacket, -+ 1500, -+ txAssocRspAttributesTable, -+ sizeof(txAssocRspAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); -+ } else { -+ -+ DBGLOG(P2P, TRACE, "Legacy device, no P2P IE.\n"); -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* p2pFuncGenerateP2p_IEForAssocRsp */ -+ -+UINT_32 -+p2pFuncCalculateWSC_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ DBGLOG(P2P, TRACE, "p2pFuncCalculateWSC_IELenForAssocRsp\n"); -+ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) -+ return 0; -+ -+ return kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); -+} /* p2pFuncCalculateP2p_IELenForAssocRsp */ -+ -+VOID p2pFuncGenerateWSC_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ PUINT_8 pucBuffer; -+ UINT_16 u2IELen = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX) -+ return; -+ DBGLOG(P2P, TRACE, "p2pFuncGenerateWSC_IEForAssocRsp\n"); -+ -+ u2IELen = (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ ASSERT(pucBuffer); -+ -+ /* TODO: Check P2P FSM State. */ -+ kalP2PGenWSC_IE(prAdapter->prGlueInfo, 0, pucBuffer); -+ -+ prMsduInfo->u2FrameLength += u2IELen; -+ -+} -+ -+/* p2pFuncGenerateP2p_IEForAssocRsp */ -+ -+UINT_32 -+p2pFuncCalculateP2P_IELen(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN P_STA_RECORD_T prStaRec, -+ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize) -+{ -+ -+ UINT_32 u4OverallAttriLen, u4Dummy; -+ UINT_16 u2EstimatedFixedAttriLen; -+ UINT_32 i; -+ -+ /* Overall length of all Attributes */ -+ u4OverallAttriLen = 0; -+ -+ for (i = 0; i < u4AttriTableSize; i++) { -+ u2EstimatedFixedAttriLen = arAppendAttriTable[i].u2EstimatedFixedAttriLen; -+ -+ if (u2EstimatedFixedAttriLen) { -+ u4OverallAttriLen += u2EstimatedFixedAttriLen; -+ } else { -+ ASSERT(arAppendAttriTable[i].pfnCalculateVariableAttriLen); -+ -+ u4OverallAttriLen += arAppendAttriTable[i].pfnCalculateVariableAttriLen(prAdapter, prStaRec); -+ } -+ } -+ -+ u4Dummy = u4OverallAttriLen; -+ u4OverallAttriLen += P2P_IE_OUI_HDR; -+ -+ for (; (u4Dummy > P2P_MAXIMUM_ATTRIBUTE_LEN);) { -+ u4OverallAttriLen += P2P_IE_OUI_HDR; -+ u4Dummy -= P2P_MAXIMUM_ATTRIBUTE_LEN; -+ } -+ -+ return u4OverallAttriLen; -+} /* p2pFuncCalculateP2P_IELen */ -+ -+VOID -+p2pFuncGenerateP2P_IE(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, -+ IN PUINT_8 pucBuf, -+ IN UINT_16 u2BufSize, -+ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize) -+{ -+ PUINT_8 pucBuffer = (PUINT_8) NULL; -+ P_IE_P2P_T prIeP2P = (P_IE_P2P_T) NULL; -+ UINT_32 u4OverallAttriLen; -+ UINT_32 u4AttriLen; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ UINT_8 aucTempBuffer[P2P_MAXIMUM_ATTRIBUTE_LEN]; -+ UINT_32 i; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL)); -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ /* Check buffer length is still enough. */ -+ ASSERT_BREAK((u2BufSize - (*pu2Offset)) >= P2P_IE_OUI_HDR); -+ -+ prIeP2P = (P_IE_P2P_T) pucBuffer; -+ -+ prIeP2P->ucId = ELEM_ID_P2P; -+ -+ prIeP2P->aucOui[0] = aucWfaOui[0]; -+ prIeP2P->aucOui[1] = aucWfaOui[1]; -+ prIeP2P->aucOui[2] = aucWfaOui[2]; -+ prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; -+ -+ (*pu2Offset) += P2P_IE_OUI_HDR; -+ -+ /* Overall length of all Attributes */ -+ u4OverallAttriLen = 0; -+ -+ for (i = 0; i < u4AttriTableSize; i++) { -+ -+ if (arAppendAttriTable[i].pfnAppendAttri) { -+ u4AttriLen = -+ arAppendAttriTable[i].pfnAppendAttri(prAdapter, fgIsAssocFrame, pu2Offset, pucBuf, -+ u2BufSize); -+ -+ u4OverallAttriLen += u4AttriLen; -+ -+ if (u4OverallAttriLen > P2P_MAXIMUM_ATTRIBUTE_LEN) { -+ u4OverallAttriLen -= P2P_MAXIMUM_ATTRIBUTE_LEN; -+ -+ prIeP2P->ucLength = (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN); -+ -+ pucBuffer = -+ (PUINT_8) ((ULONG) prIeP2P + -+ (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN)); -+ -+ prIeP2P = (P_IE_P2P_T) ((ULONG) prIeP2P + -+ (ELEM_HDR_LEN + -+ (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN))); -+ -+ kalMemCopy(aucTempBuffer, pucBuffer, u4OverallAttriLen); -+ -+ prIeP2P->ucId = ELEM_ID_P2P; -+ -+ prIeP2P->aucOui[0] = aucWfaOui[0]; -+ prIeP2P->aucOui[1] = aucWfaOui[1]; -+ prIeP2P->aucOui[2] = aucWfaOui[2]; -+ prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; -+ -+ kalMemCopy(prIeP2P->aucP2PAttributes, aucTempBuffer, u4OverallAttriLen); -+ (*pu2Offset) += P2P_IE_OUI_HDR; -+ } -+ -+ } -+ -+ } -+ -+ prIeP2P->ucLength = (UINT_8) (VENDOR_OUI_TYPE_LEN + u4OverallAttriLen); -+ -+ } while (FALSE); -+ -+} /* p2pFuncGenerateP2P_IE */ -+ -+UINT_32 -+p2pFuncAppendAttriStatusForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ PUINT_8 pucBuffer; -+ P_P2P_ATTRI_STATUS_T prAttriStatus; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ UINT_32 u4AttriLen = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucBuf); -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ if (fgIsAssocFrame) -+ return u4AttriLen; -+ /* TODO: For assoc request P2P IE check in driver & return status in P2P IE. */ -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT(pucBuffer); -+ prAttriStatus = (P_P2P_ATTRI_STATUS_T) pucBuffer; -+ -+ ASSERT(u2BufSize >= ((*pu2Offset) + (UINT_16) u4AttriLen)); -+ -+ prAttriStatus->ucId = P2P_ATTRI_ID_STATUS; -+ WLAN_SET_FIELD_16(&prAttriStatus->u2Length, P2P_ATTRI_MAX_LEN_STATUS); -+ -+ prAttriStatus->ucStatusCode = P2P_STATUS_FAIL_PREVIOUS_PROTOCOL_ERR; -+ -+ u4AttriLen = (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} /* p2pFuncAppendAttriStatusForAssocRsp */ -+ -+UINT_32 -+p2pFuncAppendAttriExtListenTiming(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ P_P2P_ATTRI_EXT_LISTEN_TIMING_T prP2pExtListenTiming = (P_P2P_ATTRI_EXT_LISTEN_TIMING_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ PUINT_8 pucBuffer = NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucBuf); -+ -+ if (fgIsAssocFrame) -+ return u4AttriLen; -+ /* TODO: For extend listen timing. */ -+ -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ u4AttriLen = (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING); -+ -+ ASSERT(u2BufSize >= ((*pu2Offset) + (UINT_16) u4AttriLen)); -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT(pucBuffer); -+ -+ prP2pExtListenTiming = (P_P2P_ATTRI_EXT_LISTEN_TIMING_T) pucBuffer; -+ -+ prP2pExtListenTiming->ucId = P2P_ATTRI_ID_EXT_LISTEN_TIMING; -+ WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2Length, P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING); -+ WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2AvailInterval, prP2pSpecificBssInfo->u2AvailabilityInterval); -+ WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2AvailPeriod, prP2pSpecificBssInfo->u2AvailabilityPeriod); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} /* p2pFuncAppendAttriExtListenTiming */ -+ -+P_IE_HDR_T -+p2pFuncGetSpecIE(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_8 ucElemID, IN PBOOLEAN pfgIsMore) -+{ -+ P_IE_HDR_T prTargetIE = (P_IE_HDR_T) NULL; -+ PUINT_8 pucIE = (PUINT_8) NULL; -+ UINT_16 u2Offset = 0; -+ -+ if (pfgIsMore) -+ *pfgIsMore = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) -+ && (pucIEBuf != NULL)); -+ -+ pucIE = pucIEBuf; -+ -+ IE_FOR_EACH(pucIE, u2BufferLen, u2Offset) { -+ if (IE_ID(pucIE) == ucElemID) { -+ if ((prTargetIE) && (pfgIsMore)) { -+ -+ *pfgIsMore = TRUE; -+ break; -+ } -+ prTargetIE = (P_IE_HDR_T) pucIE; -+ -+ if (pfgIsMore == NULL) -+ break; -+ -+ } -+ } -+ -+ } while (FALSE); -+ -+ return prTargetIE; -+} /* p2pFuncGetSpecIE */ -+ -+P_ATTRIBUTE_HDR_T -+p2pFuncGetSpecAttri(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_16 u2AttriID) -+{ -+ P_IE_P2P_T prP2pIE = (P_IE_P2P_T) NULL; -+ P_ATTRIBUTE_HDR_T prTargetAttri = (P_ATTRIBUTE_HDR_T) NULL; -+ BOOLEAN fgIsMore = FALSE; -+ PUINT_8 pucIE = (PUINT_8) NULL, pucAttri = (PUINT_8) NULL; -+ UINT_16 u2OffsetAttri = 0; -+ UINT_16 u2BufferLenLeft = 0; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ -+ DBGLOG(P2P, INFO, "Check AssocReq Oui type %u attri %u for len %u\n", ucOuiType, u2AttriID, u2BufferLen); -+ -+ ASSERT(prAdapter); -+ ASSERT(pucIEBuf); -+ -+ u2BufferLenLeft = u2BufferLen; -+ pucIE = pucIEBuf; -+ do { -+ fgIsMore = FALSE; -+ prP2pIE = (P_IE_P2P_T) p2pFuncGetSpecIE(prAdapter, -+ pucIE, u2BufferLenLeft, ELEM_ID_VENDOR, &fgIsMore); -+ if (prP2pIE == NULL) -+ continue; -+ -+ ASSERT((ULONG) prP2pIE >= (ULONG) pucIE); -+ -+ u2BufferLenLeft = u2BufferLen - (UINT_16) (((ULONG) prP2pIE) - ((ULONG) pucIEBuf)); -+ -+ DBGLOG(P2P, INFO, "Find vendor id %u len %u oui %u more %u LeftLen %u\n", -+ IE_ID(prP2pIE), IE_LEN(prP2pIE), prP2pIE->ucOuiType, fgIsMore, -+ u2BufferLenLeft); -+ -+ if ((IE_LEN(prP2pIE) > P2P_OUI_TYPE_LEN) && (prP2pIE->ucOuiType == ucOuiType)) { -+ switch (ucOuiType) { -+ case VENDOR_OUI_TYPE_WPS: -+ aucWfaOui[0] = 0x00; -+ aucWfaOui[1] = 0x50; -+ aucWfaOui[2] = 0xF2; -+ break; -+ case VENDOR_OUI_TYPE_P2P: -+ break; -+ case VENDOR_OUI_TYPE_WPA: -+ case VENDOR_OUI_TYPE_WMM: -+ case VENDOR_OUI_TYPE_WFD: -+ default: -+ break; -+ } -+ -+ if ((prP2pIE->aucOui[0] != aucWfaOui[0]) -+ || (prP2pIE->aucOui[1] != aucWfaOui[1]) -+ || (prP2pIE->aucOui[2] != aucWfaOui[2])) -+ continue; -+ -+ u2OffsetAttri = 0; -+ pucAttri = prP2pIE->aucP2PAttributes; -+ -+ if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ WSC_ATTRI_FOR_EACH(pucAttri, -+ (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) { -+ /* LOG_FUNC("WSC: attri id=%u len=%u\n", -+ * WSC_ATTRI_ID(pucAttri), -+ * WSC_ATTRI_LEN(pucAttri)); */ -+ if (WSC_ATTRI_ID(pucAttri) == u2AttriID) { -+ prTargetAttri = -+ (P_ATTRIBUTE_HDR_T) pucAttri; -+ break; -+ } -+ } -+ -+ } else if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ P2P_ATTRI_FOR_EACH(pucAttri, -+ (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) { -+ /* LOG_FUNC("P2P: attri id=%u len=%u\n", -+ * ATTRI_ID(pucAttri), ATTRI_LEN(pucAttri)); */ -+ if (ATTRI_ID(pucAttri) == (UINT_8) u2AttriID) { -+ prTargetAttri = (P_ATTRIBUTE_HDR_T) pucAttri; -+ break; -+ } -+ } -+ } -+#if CFG_SUPPORT_WFD -+ else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { -+ WFD_ATTRI_FOR_EACH(pucAttri, -+ (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) { -+ /* DBGLOG(P2P, INFO, ("WFD: attri id=%u -+ * len=%u\n",WFD_ATTRI_ID(pucAttri), -+ * WFD_ATTRI_LEN(pucAttri))); */ -+ if (ATTRI_ID(pucAttri) == (UINT_8) u2AttriID) { -+ prTargetAttri = -+ (P_ATTRIBUTE_HDR_T) pucAttri; -+ break; -+ } -+ } -+ } -+#endif -+ /* Do nothing */ -+ /* Possible or else. */ -+ } /* ucOuiType */ -+ /* P2P_OUI_TYPE_LEN */ -+ pucIE = (PUINT_8) (((ULONG) prP2pIE) + IE_SIZE(prP2pIE)); -+ /* prP2pIE */ -+ } while (prP2pIE && fgIsMore && u2BufferLenLeft); -+ -+ return prTargetAttri; -+} -+ -+/* p2pFuncGetSpecAttri */ -+ -+WLAN_STATUS -+p2pFuncGenerateBeaconProbeRsp(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prBssInfo, IN P_MSDU_INFO_T prMsduInfo, IN BOOLEAN fgIsProbeRsp) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL; -+/* P_APPEND_VAR_IE_ENTRY_T prAppendIeTable = (P_APPEND_VAR_IE_ENTRY_T)NULL; */ -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prBssInfo != NULL) && (prMsduInfo != NULL)); -+ -+/* txBcnIETable */ -+ -+/* txProbeRspIETable */ -+ -+ prBcnFrame = (P_WLAN_BEACON_FRAME_T) prMsduInfo->prPacket; -+ -+ return nicUpdateBeaconIETemplate(prAdapter, -+ IE_UPD_METHOD_UPDATE_ALL, -+ NETWORK_TYPE_P2P_INDEX, -+ prBssInfo->u2CapInfo, -+ (PUINT_8) prBcnFrame->aucInfoElem, -+ prMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, -+ aucInfoElem)); -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* p2pFuncGenerateBeaconProbeRsp */ -+ -+WLAN_STATUS -+p2pFuncComposeBeaconProbeRspTemplate(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBcnBuffer, -+ IN UINT_32 u4BcnBufLen, -+ IN BOOLEAN fgIsProbeRsp, -+ IN P_P2P_PROBE_RSP_UPDATE_INFO_T prP2pProbeRspInfo, IN BOOLEAN fgSynToFW) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; -+ P_WLAN_MAC_HEADER_T prWlanBcnFrame = (P_WLAN_MAC_HEADER_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ PUINT_8 pucBuffer = (PUINT_8) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBcnBuffer != NULL)); -+ -+ prWlanBcnFrame = (P_WLAN_MAC_HEADER_T) pucBcnBuffer; -+ -+ if ((prWlanBcnFrame->u2FrameCtrl != MAC_FRAME_BEACON) && (!fgIsProbeRsp)) { -+ rWlanStatus = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ else if (prWlanBcnFrame->u2FrameCtrl != MAC_FRAME_PROBE_RSP) { -+ rWlanStatus = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ if (fgIsProbeRsp) { -+ ASSERT_BREAK(prP2pProbeRspInfo != NULL); -+ -+ if (prP2pProbeRspInfo->prProbeRspMsduTemplate) -+ cnmMgtPktFree(prAdapter, prP2pProbeRspInfo->prProbeRspMsduTemplate); -+ -+ prP2pProbeRspInfo->prProbeRspMsduTemplate = cnmMgtPktAlloc(prAdapter, u4BcnBufLen); -+ -+ prMsduInfo = prP2pProbeRspInfo->prProbeRspMsduTemplate; -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucStaRecIndex = 0xFF; -+ prMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ -+ } else { -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prMsduInfo = prP2pBssInfo->prBeacon; -+ -+ if (prMsduInfo == NULL) { -+ rWlanStatus = WLAN_STATUS_FAILURE; -+ break; -+ } -+ -+ if (u4BcnBufLen > (OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH)) { -+ /* Unexpected error, buffer overflow. */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ } -+ -+ pucBuffer = (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ kalMemCopy(pucBuffer, pucBcnBuffer, u4BcnBufLen); -+ -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = (UINT_16) u4BcnBufLen; -+ -+ if (fgSynToFW && prP2pBssInfo) -+ rWlanStatus = p2pFuncGenerateBeaconProbeRsp(prAdapter, prP2pBssInfo, prMsduInfo, fgIsProbeRsp); -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+ -+} /* p2pFuncComposeBeaconTemplate */ -+ -+#if CFG_SUPPORT_WFD -+WLAN_STATUS wfdAdjustResource(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable) -+{ -+#if 1 -+ /* The API shall be called in tx_thread */ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ DBGLOG(P2P, INFO, "wfdAdjustResource %d\n", fgEnable); -+ if (fgEnable) { -+ prQM->au4MinReservedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE; -+ if (QM_GUARANTEED_TC0_RESOURCE > 2) { -+ prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE - 2; -+ prQM->au4GuaranteedTcResource[TC2_INDEX] += 2; -+ } -+ if (QM_GUARANTEED_TC1_RESOURCE > 2) { -+ prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE - 2; -+ prQM->au4GuaranteedTcResource[TC2_INDEX] += 2; -+ } -+ } else { -+ prQM->au4MinReservedTcResource[TC2_INDEX] = QM_MIN_RESERVED_TC2_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE; -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS wfdAdjustThread(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable) -+{ -+#define WFD_TX_THREAD_PRIORITY 70 -+ DBGLOG(P2P, INFO, "wfdAdjustResource %d\n", fgEnable); -+ if (prAdapter->prGlueInfo->main_thread != NULL) { -+ if (fgEnable) { -+#ifdef LINUX -+ /* TODO the change schedule API shall be provided by OS glue layer */ -+ /* Or the API shall be put in os glue layer */ -+ struct sched_param param = {.sched_priority = WFD_TX_THREAD_PRIORITY }; -+ -+ sched_setscheduler(prAdapter->prGlueInfo->main_thread, SCHED_RR, ¶m); -+#endif -+ } else { -+#ifdef LINUX -+ /* TODO the change schedule API shall be provided by OS glue layer */ -+ struct sched_param param = {.sched_priority = 0 }; -+ -+ sched_setscheduler(prAdapter->prGlueInfo->main_thread, SCHED_NORMAL, ¶m); -+#endif -+ } -+ } else { -+ -+ DBGLOG(P2P, WARN, "main_thread is null, please check if the wlanRemove is called in advance\n"); -+ } -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#endif /* CFG_SUPPORT_WFD */ -+ -+WLAN_STATUS wfdChangeMediaState(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx, ENUM_PARAM_MEDIA_STATE_T eConnectionState) -+{ -+#if CFG_SUPPORT_WFD -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ if (prAdapter->fgIsP2PRegistered == FALSE) -+ return WLAN_STATUS_SUCCESS; -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ -+ if ((prWfdCfgSettings->ucWfdEnable) && ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) { -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == -+ PARAM_MEDIA_STATE_CONNECTED) { -+ wfdAdjustResource(prAdapter, TRUE); -+ wfdAdjustThread(prAdapter, TRUE); -+ } else { -+ wfdAdjustResource(prAdapter, FALSE); -+ wfdAdjustThread(prAdapter, FALSE); -+ } -+ -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c -new file mode 100644 -index 0000000000000..991861f736082 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c -@@ -0,0 +1,612 @@ -+#include "p2p_precomp.h" -+ -+#if CFG_SUPPORT_WFD -+#if CFG_SUPPORT_WFD_COMPOSE_IE -+#if 0 -+APPEND_VAR_ATTRI_ENTRY_T txProbeRspWFDAttributesTable[] = { -+ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_EXT_CAPABILITY), NULL, wfdFuncAppendAttriExtCapability} /* 7 */ -+ , {0, wfdFuncCalculateAttriLenSessionInfo, wfdFuncAppendAttriSessionInfo} /* 9 */ -+}; -+ -+APPEND_VAR_ATTRI_ENTRY_T txBeaconWFDAttributesTable[] = { -+ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ -+}; -+ -+APPEND_VAR_ATTRI_ENTRY_T txAssocReqWFDAttributesTable[] = { -+ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ -+}; -+#endif -+ -+APPEND_VAR_ATTRI_ENTRY_T txAssocRspWFDAttributesTable[] = { -+ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ -+ , {0, wfdFuncCalculateAttriLenSessionInfo, wfdFuncAppendAttriSessionInfo} /* 9 */ -+ -+}; -+ -+#endif -+ -+UINT_32 -+p2pCalculate_IEForAssocReq(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL; -+ UINT_32 u4RetValue = 0; -+ -+ do { -+ ASSERT_BREAK((eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) && (prAdapter != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); -+ -+ u4RetValue = prConnReqInfo->u4BufLength; -+ -+ /* ADD HT Capability */ -+ u4RetValue += (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP); -+ -+ /* ADD WMM Information Element */ -+ u4RetValue += (ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_INFO); -+ -+ } while (FALSE); -+ -+ return u4RetValue; -+} /* p2pCalculate_IEForAssocReq */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate P2P IE for Beacon frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pGenerate_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL; -+ PUINT_8 pucIEBuf = (PUINT_8) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); -+ -+ pucIEBuf = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ kalMemCopy(pucIEBuf, prConnReqInfo->aucIEBuf, prConnReqInfo->u4BufLength); -+ -+ prMsduInfo->u2FrameLength += prConnReqInfo->u4BufLength; -+ -+ rlmReqGenerateHtCapIE(prAdapter, prMsduInfo); -+ mqmGenerateWmmInfoIE(prAdapter, prMsduInfo); -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* p2pGenerate_IEForAssocReq */ -+ -+UINT_32 -+wfdFuncAppendAttriDevInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ PUINT_8 pucBuffer = NULL; -+ P_WFD_DEVICE_INFORMATION_IE_T prWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) NULL; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ ASSERT_BREAK((prWfdCfgSettings != NULL)); -+ -+ if ((prWfdCfgSettings->ucWfdEnable == 0) || -+ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) == 0)) { -+ break; -+ } -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ prWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) pucBuffer; -+ -+ prWfdDevInfo->ucElemID = WFD_ATTRI_ID_DEV_INFO; -+ -+ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2WfdDevInfo, prWfdCfgSettings->u2WfdDevInfo); -+ -+ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2SessionMgmtCtrlPort, prWfdCfgSettings->u2WfdControlPort); -+ -+ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2WfdDevMaxSpeed, prWfdCfgSettings->u2WfdMaximumTp); -+ -+ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2Length, WFD_ATTRI_MAX_LEN_DEV_INFO); -+ -+ u4AttriLen = WFD_ATTRI_MAX_LEN_DEV_INFO + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} -+ -+/* wfdFuncAppendAttriDevInfo */ -+ -+UINT_32 -+wfdFuncAppendAttriAssocBssid(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ PUINT_8 pucBuffer = NULL; -+ P_WFD_ASSOCIATED_BSSID_IE_T prWfdAssocBssid = (P_WFD_ASSOCIATED_BSSID_IE_T) NULL; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_BSS_INFO_T prAisBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ ASSERT_BREAK((prWfdCfgSettings != NULL)); -+ -+ if (prWfdCfgSettings->ucWfdEnable == 0) -+ break; -+ -+ /* AIS network. */ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ if ((!IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX)) || -+ (prAisBssInfo->eConnectionState != PARAM_MEDIA_STATE_CONNECTED)) { -+ break; -+ } -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ prWfdAssocBssid = (P_WFD_ASSOCIATED_BSSID_IE_T) pucBuffer; -+ -+ prWfdAssocBssid->ucElemID = WFD_ATTRI_ID_ASSOC_BSSID; -+ -+ WLAN_SET_FIELD_BE16(&prWfdAssocBssid->u2Length, WFD_ATTRI_MAX_LEN_ASSOC_BSSID); -+ -+ COPY_MAC_ADDR(prWfdAssocBssid->aucAssocBssid, prAisBssInfo->aucBSSID); -+ -+ u4AttriLen = WFD_ATTRI_MAX_LEN_ASSOC_BSSID + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} -+ -+/* wfdFuncAppendAttriAssocBssid */ -+ -+UINT_32 -+wfdFuncAppendAttriCoupledSinkInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ PUINT_8 pucBuffer = NULL; -+ P_WFD_COUPLE_SINK_INFORMATION_IE_T prWfdCoupleSinkInfo = (P_WFD_COUPLE_SINK_INFORMATION_IE_T) NULL; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ ASSERT_BREAK((prWfdCfgSettings != NULL)); -+ -+ if ((prWfdCfgSettings->ucWfdEnable == 0) || -+ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_SINK_INFO_VALID) == 0)) { -+ break; -+ } -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ prWfdCoupleSinkInfo = (P_WFD_COUPLE_SINK_INFORMATION_IE_T) pucBuffer; -+ -+ prWfdCoupleSinkInfo->ucElemID = WFD_ATTRI_ID_COUPLED_SINK_INFO; -+ -+ WLAN_SET_FIELD_BE16(&prWfdCoupleSinkInfo->u2Length, WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO); -+ -+ COPY_MAC_ADDR(prWfdCoupleSinkInfo->aucCoupleSinkMac, prWfdCfgSettings->aucWfdCoupleSinkAddress); -+ -+ prWfdCoupleSinkInfo->ucCoupleSinkStatusBp = prWfdCfgSettings->ucWfdCoupleSinkStatus; -+ -+ u4AttriLen = WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} -+ -+/* wfdFuncAppendAttriCoupledSinkInfo */ -+ -+UINT_32 -+wfdFuncAppendAttriExtCapability(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ PUINT_8 pucBuffer = NULL; -+ P_WFD_EXTENDED_CAPABILITY_IE_T prWfdExtCapability = (P_WFD_EXTENDED_CAPABILITY_IE_T) NULL; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ ASSERT_BREAK((prWfdCfgSettings != NULL)); -+ -+ if ((prWfdCfgSettings->ucWfdEnable == 0) || -+ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_EXT_CAPABILITY_VALID) == 0)) { -+ break; -+ } -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ prWfdExtCapability = (P_WFD_EXTENDED_CAPABILITY_IE_T) pucBuffer; -+ -+ prWfdExtCapability->ucElemID = WFD_ATTRI_ID_EXT_CAPABILITY; -+ -+ WLAN_SET_FIELD_BE16(&prWfdExtCapability->u2Length, WFD_ATTRI_MAX_LEN_EXT_CAPABILITY); -+ -+ WLAN_SET_FIELD_BE16(&prWfdExtCapability->u2WfdExtCapabilityBp, prWfdCfgSettings->u2WfdExtendCap); -+ -+ u4AttriLen = WFD_ATTRI_MAX_LEN_EXT_CAPABILITY + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} -+ -+/* wfdFuncAppendAttriExtCapability */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to calculate length of Channel List Attribute -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return The length of Attribute added -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 wfdFuncCalculateAttriLenSessionInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ UINT_16 u2AttriLen = 0; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ if (prWfdCfgSettings->ucWfdEnable == 0) -+ break; -+ -+ u2AttriLen = prWfdCfgSettings->u2WfdSessionInformationIELen + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ return (UINT_32) u2AttriLen; -+ -+} /* wfdFuncCalculateAttriLenSessionInfo */ -+ -+UINT_32 -+wfdFuncAppendAttriSessionInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ PUINT_8 pucBuffer = NULL; -+ P_WFD_SESSION_INFORMATION_IE_T prWfdSessionInfo = (P_WFD_SESSION_INFORMATION_IE_T) NULL; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ ASSERT_BREAK((prWfdCfgSettings != NULL)); -+ -+ if ((prWfdCfgSettings->ucWfdEnable == 0) || (prWfdCfgSettings->u2WfdSessionInformationIELen == 0)) -+ break; -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ prWfdSessionInfo = (P_WFD_SESSION_INFORMATION_IE_T) pucBuffer; -+ -+ prWfdSessionInfo->ucElemID = WFD_ATTRI_ID_SESSION_INFO; -+ -+ /* TODO: Check endian issue? */ -+ kalMemCopy(prWfdSessionInfo->pucWfdDevInfoDesc, prWfdCfgSettings->aucWfdSessionInformationIE, -+ prWfdCfgSettings->u2WfdSessionInformationIELen); -+ -+ WLAN_SET_FIELD_16(&prWfdSessionInfo->u2Length, prWfdCfgSettings->u2WfdSessionInformationIELen); -+ -+ u4AttriLen = prWfdCfgSettings->u2WfdSessionInformationIELen + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} -+ -+/* wfdFuncAppendAttriSessionInfo */ -+ -+#if CFG_SUPPORT_WFD_COMPOSE_IE -+VOID -+wfdFuncGenerateWfd_IE(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, -+ IN PUINT_8 pucBuf, -+ IN UINT_16 u2BufSize, -+ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize) -+{ -+ -+ PUINT_8 pucBuffer = (PUINT_8) NULL; -+ P_IE_WFD_T prIeWFD = (P_IE_WFD_T) NULL; -+ UINT_32 u4OverallAttriLen; -+ UINT_32 u4AttriLen; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ UINT_8 aucTempBuffer[P2P_MAXIMUM_ATTRIBUTE_LEN]; -+ UINT_32 i; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL)); -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ /* Check buffer length is still enough. */ -+ ASSERT_BREAK((u2BufSize - (*pu2Offset)) >= WFD_IE_OUI_HDR); -+ -+ prIeWFD = (P_IE_WFD_T) pucBuffer; -+ -+ prIeWFD->ucId = ELEM_ID_WFD; -+ -+ prIeWFD->aucOui[0] = aucWfaOui[0]; -+ prIeWFD->aucOui[1] = aucWfaOui[1]; -+ prIeWFD->aucOui[2] = aucWfaOui[2]; -+ prIeWFD->ucOuiType = VENDOR_OUI_TYPE_WFD; -+ -+ (*pu2Offset) += WFD_IE_OUI_HDR; -+ -+ /* Overall length of all Attributes */ -+ u4OverallAttriLen = 0; -+ -+ for (i = 0; i < u4AttriTableSize; i++) { -+ -+ if (arAppendAttriTable[i].pfnAppendAttri) { -+ u4AttriLen = -+ arAppendAttriTable[i].pfnAppendAttri(prAdapter, fgIsAssocFrame, pu2Offset, pucBuf, -+ u2BufSize); -+ -+ u4OverallAttriLen += u4AttriLen; -+ -+ if (u4OverallAttriLen > P2P_MAXIMUM_ATTRIBUTE_LEN) { -+ u4OverallAttriLen -= P2P_MAXIMUM_ATTRIBUTE_LEN; -+ -+ prIeWFD->ucLength = (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN); -+ -+ pucBuffer = -+ (PUINT_8) ((ULONG) prIeWFD + (WFD_IE_OUI_HDR + P2P_MAXIMUM_ATTRIBUTE_LEN)); -+ -+ prIeWFD = -+ (P_IE_WFD_T) ((ULONG) prIeWFD + -+ (WFD_IE_OUI_HDR + P2P_MAXIMUM_ATTRIBUTE_LEN)); -+ -+ kalMemCopy(aucTempBuffer, pucBuffer, u4OverallAttriLen); -+ -+ prIeWFD->ucId = ELEM_ID_WFD; -+ -+ prIeWFD->aucOui[0] = aucWfaOui[0]; -+ prIeWFD->aucOui[1] = aucWfaOui[1]; -+ prIeWFD->aucOui[2] = aucWfaOui[2]; -+ prIeWFD->ucOuiType = VENDOR_OUI_TYPE_WFD; -+ -+ kalMemCopy(prIeWFD->aucWFDAttributes, aucTempBuffer, u4OverallAttriLen); -+ (*pu2Offset) += WFD_IE_OUI_HDR; -+ } -+ -+ } -+ -+ } -+ -+ prIeWFD->ucLength = (UINT_8) (VENDOR_OUI_TYPE_LEN + u4OverallAttriLen); -+ -+ } while (FALSE); -+ -+} /* wfdFuncGenerateWfd_IE */ -+ -+#endif /* CFG_SUPPORT_WFD_COMPOSE_IE */ -+ -+UINT_32 -+wfdFuncCalculateWfdIELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ -+#if CFG_SUPPORT_WFD_COMPOSE_IE -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ if (!IS_STA_P2P_TYPE(prStaRec) || (prWfdCfgSettings->ucWfdEnable == 0)) -+ return 0; -+ -+ return p2pFuncCalculateP2P_IELen(prAdapter, -+ eNetTypeIndex, -+ prStaRec, -+ txAssocRspWFDAttributesTable, -+ sizeof(txAssocRspWFDAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); -+ -+#else -+ return 0; -+#endif -+} /* wfdFuncCalculateWfdIELenForAssocRsp */ -+ -+VOID wfdFuncGenerateWfdIEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ -+#if CFG_SUPPORT_WFD_COMPOSE_IE -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_STA_RECORD_T prStaRec; -+ -+ do { -+ ASSERT_BREAK((prMsduInfo != NULL) && (prAdapter != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (!prStaRec) { -+ ASSERT(FALSE); -+ } else if (IS_STA_P2P_TYPE(prStaRec)) { -+ -+ if (prWfdCfgSettings->ucWfdEnable == 0) -+ break; -+ if ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) == 0) -+ break; -+ -+ wfdFuncGenerateWfd_IE(prAdapter, -+ FALSE, -+ &prMsduInfo->u2FrameLength, -+ prMsduInfo->prPacket, -+ 1500, -+ txAssocRspWFDAttributesTable, -+ sizeof(txAssocRspWFDAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); -+ } -+ } while (FALSE); -+ -+ return; -+#else -+ -+ return; -+#endif -+} /* wfdFuncGenerateWfdIEForAssocRsp */ -+ -+VOID p2pFuncComposeNoaAttribute(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ -+ P_IE_P2P_T prIeP2P; -+ P_P2P_ATTRI_NOA_T prNoaAttr = NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = NULL; -+ P_NOA_DESCRIPTOR_T prNoaDesc = NULL; -+ -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ UINT_32 u4AttributeLen; -+ UINT_32 u4NumOfNoaDesc = 0; -+ UINT_32 i = 0; -+ /*P2P IE format */ -+ prIeP2P = (P_IE_P2P_T) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ prIeP2P->ucId = ELEM_ID_P2P; -+ prIeP2P->aucOui[0] = aucWfaOui[0]; -+ prIeP2P->aucOui[1] = aucWfaOui[1]; -+ prIeP2P->aucOui[2] = aucWfaOui[2]; -+ prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; -+ -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ /*P2P Attribute--NoA */ -+ prNoaAttr = (P_P2P_ATTRI_NOA_T) prIeP2P->aucP2PAttributes; -+ -+ prNoaAttr->ucId = P2P_ATTRI_ID_NOTICE_OF_ABSENCE; -+ prNoaAttr->ucIndex = prP2pSpecificBssInfo->ucNoAIndex; -+ /*OPP*/ if (prP2pSpecificBssInfo->fgEnableOppPS) { -+ prNoaAttr->ucCTWOppPSParam = P2P_CTW_OPPPS_PARAM_OPPPS_FIELD | -+ (prP2pSpecificBssInfo->u2CTWindow & P2P_CTW_OPPPS_PARAM_CTWINDOW_MASK); -+ } else { -+ prNoaAttr->ucCTWOppPSParam = 0; -+ } -+ /*NoA Description */ -+ DBGLOG(P2P, INFO, "Compose NoA count=%d.\n", prP2pSpecificBssInfo->ucNoATimingCount); -+ for (i = 0; i < prP2pSpecificBssInfo->ucNoATimingCount; i++) { -+ if (prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse) { -+ -+ prNoaDesc = (P_NOA_DESCRIPTOR_T) &prNoaAttr->aucNoADesc[u4NumOfNoaDesc]; -+ -+ prNoaDesc->ucCountType = prP2pSpecificBssInfo->arNoATiming[i].ucCount; -+ prNoaDesc->u4Duration = prP2pSpecificBssInfo->arNoATiming[i].u4Duration; -+ prNoaDesc->u4Interval = prP2pSpecificBssInfo->arNoATiming[i].u4Interval; -+ prNoaDesc->u4StartTime = prP2pSpecificBssInfo->arNoATiming[i].u4StartTime; -+ -+ u4NumOfNoaDesc++; -+ } -+ } -+ -+ /* include "index" + "OppPs Params" + "NOA descriptors" */ -+ prNoaAttr->u2Length = 2 + u4NumOfNoaDesc * sizeof(NOA_DESCRIPTOR_T); -+ u4NumOfNoaDesc++; -+ -+ /* include "Attribute ID" + "Length" + "index" + "OppPs Params" + "NOA descriptors" */ -+ u4AttributeLen = P2P_ATTRI_HDR_LEN + prNoaAttr->u2Length; -+ -+ prIeP2P->ucLength = VENDOR_OUI_TYPE_LEN + u4AttributeLen; -+ prMsduInfo->u2FrameLength += (ELEM_HDR_LEN + prIeP2P->ucLength); -+ -+} -+ -+UINT_32 p2pFuncCalculateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN UINT_32 ucBssIdx, IN P_STA_RECORD_T prStaRec) -+{ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = NULL; -+ UINT_8 ucIdx; -+ UINT_32 u4NumOfNoaDesc = 0; -+ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) -+ return 0; -+ -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ for (ucIdx = 0; ucIdx < prP2pSpecificBssInfo->ucNoATimingCount; ucIdx++) { -+ if (prP2pSpecificBssInfo->arNoATiming[ucIdx].fgIsInUse) -+ u4NumOfNoaDesc++; -+ } -+ -+ /* include "index" + "OppPs Params" + "NOA descriptors" */ -+ /* include "Attribute ID" + "Length" + "index" + "OppPs Params" + "NOA descriptors" */ -+ -+ return P2P_ATTRI_LEN_NOTICE_OF_ABSENCE + (u4NumOfNoaDesc * sizeof(NOA_DESCRIPTOR_T)); -+} -+ -+VOID p2pFuncGenerateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) { /* Hotspot */ -+ return; -+ } -+ -+ /* Compose NoA attribute */ -+ p2pFuncComposeNoaAttribute(prAdapter, -+ prMsduInfo /*prMsduInfo->ucBssIndex, prIeP2P->aucP2PAttributes, &u4AttributeLen */); -+ -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c -new file mode 100644 -index 0000000000000..f25df82d9ca76 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c -@@ -0,0 +1,905 @@ -+/* -+** Id: @(#) p2p_rlm.c@@ -+*/ -+ -+/*! \file "p2p_rlm.c" -+ \brief -+ -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Init AP Bss -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmBssInitForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ ENUM_BAND_T eBand; -+ UINT_8 ucChannel; -+ ENUM_CHNL_EXT_T eSCO; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) -+ return; -+ -+ /* Operation band, channel shall be ready before invoking this function. -+ * Bandwidth may be ready if other network is connected -+ */ -+ prBssInfo->fg40mBwAllowed = FALSE; -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ prBssInfo->eBssSCO = CHNL_EXT_SCN; -+ -+ if (RLM_AP_IS_BW_40_ALLOWED(prAdapter, prBssInfo)) { -+ /* In this case, the first BSS's SCO is 40MHz and known, so AP can -+ * apply 40MHz bandwidth, but the first BSS's SCO may be changed -+ * later if its Beacon lost timeout occurs -+ */ -+ if (cnmPreferredChannel(prAdapter, &eBand, &ucChannel, &eSCO) && -+ eSCO != CHNL_EXT_SCN && ucChannel == prBssInfo->ucPrimaryChannel && eBand == prBssInfo->eBand) { -+ prBssInfo->eBssSCO = eSCO; -+ } else if (cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex)) { -+ prBssInfo->eBssSCO = rlmDecideScoForAP(prAdapter, prBssInfo); -+ } -+ -+ if (prBssInfo->eBssSCO != CHNL_EXT_SCN) { -+ prBssInfo->fg40mBwAllowed = TRUE; -+ prBssInfo->fgAssoc40mBwAllowed = TRUE; -+ -+ prBssInfo->ucHtOpInfo1 = (UINT_8) -+ (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH); -+ -+ rlmUpdateBwByChListForAP(prAdapter, prBssInfo); -+ } -+ } -+ -+ DBGLOG(RLM, INFO, "WLAN AP SCO=%d\n", prBssInfo->eBssSCO); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe response (GO, IBSS) and association response -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmRspGenerateObssScanIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_IE_OBSS_SCAN_PARAM_T prObssScanIe; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ if (RLM_NET_IS_11N(prBssInfo) && !RLM_NET_IS_BOW(prBssInfo) && -+ prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && -+ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) && -+ prBssInfo->eBand == BAND_2G4 && prBssInfo->eBssSCO != CHNL_EXT_SCN) { -+ -+ prObssScanIe = (P_IE_OBSS_SCAN_PARAM_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+ /* Add 20/40 BSS coexistence IE */ -+ prObssScanIe->ucId = ELEM_ID_OBSS_SCAN_PARAMS; -+ prObssScanIe->ucLength = sizeof(IE_OBSS_SCAN_PARAM_T) - ELEM_HDR_LEN; -+ -+ prObssScanIe->u2ScanPassiveDwell = dot11OBSSScanPassiveDwell; -+ prObssScanIe->u2ScanActiveDwell = dot11OBSSScanActiveDwell; -+ prObssScanIe->u2TriggerScanInterval = dot11BSSWidthTriggerScanInterval; -+ prObssScanIe->u2ScanPassiveTotalPerChnl = dot11OBSSScanPassiveTotalPerChannel; -+ prObssScanIe->u2ScanActiveTotalPerChnl = dot11OBSSScanActiveTotalPerChannel; -+ prObssScanIe->u2WidthTransDelayFactor = dot11BSSWidthChannelTransitionDelayFactor; -+ prObssScanIe->u2ScanActivityThres = dot11OBSSScanActivityThreshold; -+ -+ ASSERT(IE_SIZE(prObssScanIe) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prObssScanIe); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P GO. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rlmUpdateBwByChListForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ UINT_8 ucLevel; -+ BOOLEAN fgBwChange; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ fgBwChange = FALSE; -+ -+ if (prBssInfo->eBssSCO == CHNL_EXT_SCN) -+ return fgBwChange; -+ -+ ucLevel = rlmObssChnlLevel(prBssInfo, prBssInfo->eBand, prBssInfo->ucPrimaryChannel, prBssInfo->eBssSCO); -+ -+ if (ucLevel == CHNL_LEVEL0) { -+ /* Forced to 20MHz, so extended channel is SCN and STA width is zero */ -+ prBssInfo->fgObssActionForcedTo20M = TRUE; -+ -+ if (prBssInfo->ucHtOpInfo1 != (UINT_8) CHNL_EXT_SCN) { -+ prBssInfo->ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN; -+ fgBwChange = TRUE; -+ } -+ -+ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, OBSS_20_40M_TIMEOUT * MSEC_PER_SEC); -+ } -+ -+ /* Clear up all channel lists */ -+ prBssInfo->auc2G_20mReqChnlList[0] = 0; -+ prBssInfo->auc2G_NonHtChnlList[0] = 0; -+ prBssInfo->auc2G_PriChnlList[0] = 0; -+ prBssInfo->auc2G_SecChnlList[0] = 0; -+ prBssInfo->auc5G_20mReqChnlList[0] = 0; -+ prBssInfo->auc5G_NonHtChnlList[0] = 0; -+ prBssInfo->auc5G_PriChnlList[0] = 0; -+ prBssInfo->auc5G_SecChnlList[0] = 0; -+ -+ return fgBwChange; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessPublicAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) -+{ -+ P_ACTION_20_40_COEXIST_FRAME prRxFrame; -+ P_IE_20_40_COEXIST_T prCoexist; -+ P_IE_INTOLERANT_CHNL_REPORT_T prChnlReport; -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ PUINT_8 pucIE; -+ UINT_16 u2IELength, u2Offset; -+ UINT_8 i, j; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxFrame = (P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader; -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prRxFrame->ucAction != ACTION_PUBLIC_20_40_COEXIST || -+ !prStaRec || prStaRec->ucStaState != STA_STATE_3 || -+ prSwRfb->u2PacketLen < (WLAN_MAC_MGMT_HEADER_LEN + 5) || -+ HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) != NETWORK_TYPE_P2P_INDEX) { -+ return; -+ } -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ ASSERT(prBssInfo); -+ -+ if (!IS_BSS_ACTIVE(prBssInfo) || -+ prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT || prBssInfo->eBssSCO == CHNL_EXT_SCN) { -+ return; -+ } -+ -+ prCoexist = &prRxFrame->rBssCoexist; -+ if (prCoexist->ucData & (BSS_COEXIST_40M_INTOLERANT | BSS_COEXIST_20M_REQ)) { -+ ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_20mReqChnlList[i] == prBssInfo->ucPrimaryChannel) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_20mReqChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_20mReqChnlList[i] = prBssInfo->ucPrimaryChannel; -+ prBssInfo->auc2G_20mReqChnlList[0]++; -+ } -+ } -+ -+ /* Process intolerant channel report IE */ -+ pucIE = (PUINT_8) &prRxFrame->rChnlReport; -+ u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_MGMT_HEADER_LEN + 5); -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_20_40_INTOLERANT_CHNL_REPORT: -+ prChnlReport = (P_IE_INTOLERANT_CHNL_REPORT_T) pucIE; -+ -+ if (prChnlReport->ucLength <= 1) -+ break; -+ -+ /* To do: process regulatory class. Now we assume 2.4G band */ -+ -+ for (j = 0; j < prChnlReport->ucLength - 1; j++) { -+ /* Update non-HT channel list */ -+ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_NonHtChnlList[i] == prChnlReport->aucChannelList[j]) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_NonHtChnlList[i] = prChnlReport->aucChannelList[j]; -+ prBssInfo->auc2G_NonHtChnlList[0]++; -+ } -+ } -+ break; -+ -+ default: -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ if (rlmUpdateBwByChListForAP(prAdapter, prBssInfo)) { -+ bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex); -+ rlmSyncOperationParams(prAdapter, prBssInfo); -+ } -+ -+ /* Check if OBSS scan exemption response should be sent */ -+ if (prCoexist->ucData & BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ) -+ rlmObssScanExemptionRsp(prAdapter, prBssInfo, prSwRfb); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessHtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) -+{ -+ P_ACTION_NOTIFY_CHNL_WIDTH_FRAME prRxFrame; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxFrame = (P_ACTION_NOTIFY_CHNL_WIDTH_FRAME) prSwRfb->pvHeader; -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prRxFrame->ucAction != ACTION_HT_NOTIFY_CHANNEL_WIDTH || -+ !prStaRec || prStaRec->ucStaState != STA_STATE_3 || -+ prSwRfb->u2PacketLen < sizeof(ACTION_NOTIFY_CHNL_WIDTH_FRAME)) { -+ return; -+ } -+ -+ /* To do: depending regulation class 13 and 14 based on spec -+ * Note: (ucChannelWidth==1) shall restored back to original capability, -+ * not current setting to 40MHz BW here -+ */ -+ if (prRxFrame->ucChannelWidth == 0) -+ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; -+ else if (prRxFrame->ucChannelWidth == 1) -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmHandleObssStatusEventPkt(P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prObssStatus); -+ ASSERT(prObssStatus->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prObssStatus->ucNetTypeIndex]; -+ ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT); -+ -+ prBssInfo->fgObssErpProtectMode = (BOOLEAN) prObssStatus->ucObssErpProtectMode; -+ prBssInfo->eObssHtProtectMode = (ENUM_HT_PROTECT_MODE_T) prObssStatus->ucObssHtProtectMode; -+ prBssInfo->eObssGfOperationMode = (ENUM_GF_MODE_T) prObssStatus->ucObssGfOperationMode; -+ prBssInfo->fgObssRifsOperationMode = (BOOLEAN) prObssStatus->ucObssRifsOperationMode; -+ prBssInfo->fgObssBeaconForcedTo20M = (BOOLEAN) prObssStatus->ucObssBeaconForcedTo20M; -+ -+ /* Check if Beacon content need to be updated */ -+ rlmUpdateParamsForAP(prAdapter, prBssInfo, TRUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief It is only for AP mode in NETWORK_TYPE_P2P_INDEX. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmUpdateParamsForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon) -+{ -+ P_LINK_T prStaList; -+ P_STA_RECORD_T prStaRec; -+ BOOLEAN fgErpProtectMode, fgSta40mIntolerant; -+ BOOLEAN fgUseShortPreamble, fgUseShortSlotTime; -+ ENUM_HT_PROTECT_MODE_T eHtProtectMode; -+ ENUM_GF_MODE_T eGfOperationMode; -+ UINT_8 ucHtOpInfo1; -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ P_GLUE_INFO_T prGlueInfo; -+#endif -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ if (!IS_BSS_ACTIVE(prBssInfo) || prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) -+ return; -+ -+ fgErpProtectMode = FALSE; -+ eHtProtectMode = HT_PROTECT_MODE_NONE; -+ eGfOperationMode = GF_MODE_NORMAL; -+ fgSta40mIntolerant = FALSE; -+ fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed; -+ fgUseShortSlotTime = TRUE; -+ ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN; -+ -+ prStaList = &prBssInfo->rStaRecOfClientList; -+ -+ LINK_FOR_EACH_ENTRY(prStaRec, prStaList, rLinkEntry, STA_RECORD_T) { -+ /* ASSERT(prStaRec); */ -+ if (!prStaRec) { -+ DBGLOG(P2P, TRACE, "prStaRec is NULL in rlmUpdateParamsForAP()\n"); -+ break; -+ } -+ if (prStaRec->fgIsInUse && prStaRec->ucStaState == STA_STATE_3 && -+ prStaRec->ucNetTypeIndex == prBssInfo->ucNetTypeIndex) { -+ if (!(prStaRec->ucPhyTypeSet & (PHY_TYPE_SET_802_11GN | PHY_TYPE_SET_802_11A))) { -+ /* B-only mode, so mode 1 (ERP protection) */ -+ fgErpProtectMode = TRUE; -+ } -+ -+ if (!(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { -+ /* BG-only or A-only */ -+ eHtProtectMode = HT_PROTECT_MODE_NON_HT; -+ } else if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) { -+ /* 20MHz-only */ -+ /* -+ The HT Protection field may be set to 20 MHz protection -+ mode only if the following are true: -+ \A1X All STAs detected (by any means) in the primary channel -+ and all STAs detected (by any means) in the secondary -+ channel are HT STAs and all STAs that are members of -+ this BSS are HT STAs, and -+ \A1X This BSS is a 20/40 MHz BSS, and -+ \A1X There is at least one 20 MHz HT STA associated with this BSS. -+ */ -+ if (eHtProtectMode == HT_PROTECT_MODE_NONE && prBssInfo->fgAssoc40mBwAllowed) -+ eHtProtectMode = HT_PROTECT_MODE_20M; -+ } -+ -+ if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_HT_GF)) -+ eGfOperationMode = GF_MODE_PROTECT; -+ -+ if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)) -+ fgUseShortPreamble = FALSE; -+ -+ if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) -+ fgUseShortSlotTime = FALSE; -+ -+ if (prStaRec->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) -+ fgSta40mIntolerant = TRUE; -+ } -+ } /* end of LINK_FOR_EACH_ENTRY */ -+ -+ /* Check if HT operation IE about 20/40M bandwidth shall be updated */ -+ if (prBssInfo->eBssSCO != CHNL_EXT_SCN) { -+ if (/*!LINK_IS_EMPTY(prStaList) && */ !fgSta40mIntolerant && -+ !prBssInfo->fgObssActionForcedTo20M && !prBssInfo->fgObssBeaconForcedTo20M) { -+ -+ ucHtOpInfo1 = (UINT_8) -+ (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH); -+ } -+ } -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ prGlueInfo = prAdapter->prGlueInfo; -+ if (prGlueInfo->prP2PInfo->u4PsLevel & BITS(8, 15)) -+ fgErpProtectMode = TRUE; -+#endif -+ -+ /* Check if any new parameter may be updated */ -+ if (prBssInfo->fgErpProtectMode != fgErpProtectMode || -+ prBssInfo->eHtProtectMode != eHtProtectMode || -+ prBssInfo->eGfOperationMode != eGfOperationMode || -+ prBssInfo->ucHtOpInfo1 != ucHtOpInfo1 || -+ prBssInfo->fgUseShortPreamble != fgUseShortPreamble || -+ prBssInfo->fgUseShortSlotTime != fgUseShortSlotTime) { -+ -+ prBssInfo->fgErpProtectMode = fgErpProtectMode; -+ prBssInfo->eHtProtectMode = eHtProtectMode; -+ prBssInfo->eGfOperationMode = eGfOperationMode; -+ prBssInfo->ucHtOpInfo1 = ucHtOpInfo1; -+ prBssInfo->fgUseShortPreamble = fgUseShortPreamble; -+ prBssInfo->fgUseShortSlotTime = fgUseShortSlotTime; -+ -+ if (fgUseShortSlotTime) -+ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; -+ else -+ prBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME; -+ -+ rlmSyncOperationParams(prAdapter, prBssInfo); -+ fgUpdateBeacon = TRUE; -+ } -+ -+ /* Update Beacon content if related IE content is changed */ -+ if (fgUpdateBeacon) -+ bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Initial the channel list from the domain information. -+* This function is called after P2P initial and Domain information changed. -+* Make sure the device is disconnected while changing domain information. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return boolean value if probe response frame is -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmFuncInitialChannelList(IN P_ADAPTER_T prAdapter) -+{ -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_DOMAIN_INFO_ENTRY prDomainInfoEntry = (P_DOMAIN_INFO_ENTRY) NULL; -+ P_DOMAIN_SUBBAND_INFO prDomainSubBand = (P_DOMAIN_SUBBAND_INFO) NULL; -+ P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) NULL; -+ UINT_32 u4Idx = 0, u4IdxII = 0; -+ UINT_8 ucBufferSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE; -+#if 0 -+ UINT_8 ucSocialChnlSupport = 0, ucAutoChnl = 0; -+#endif -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; -+#if 0 -+ ucAutoChnl = prP2pConnSetting->ucOperatingChnl; -+#endif -+ -+ prDomainInfoEntry = rlmDomainGetDomainInfo(prAdapter); -+ -+ ASSERT_BREAK((prDomainInfoEntry != NULL) && (prP2pConnSetting != NULL)); -+ -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; -+ -+ for (u4Idx = 0; u4Idx < MAX_SUBBAND_NUM; u4Idx++) { -+ prDomainSubBand = &prDomainInfoEntry->rSubBand[u4Idx]; -+ -+ if (((prDomainSubBand->ucBand == BAND_5G) && (!prAdapter->fgEnable5GBand)) || -+ (prDomainSubBand->ucBand == BAND_NULL)) { -+ continue; -+ } -+ -+ if (ucBufferSize < (P2P_ATTRI_LEN_CHANNEL_ENTRY + prDomainSubBand->ucNumChannels)) { -+ /* Buffer is not enough to include all supported channels. */ -+ break; /* for */ -+ } -+ -+ prChannelEntryField->ucRegulatoryClass = prDomainSubBand->ucRegClass; -+ prChannelEntryField->ucNumberOfChannels = prDomainSubBand->ucNumChannels; -+ -+ for (u4IdxII = 0; u4IdxII < prDomainSubBand->ucNumChannels; u4IdxII++) { -+ prChannelEntryField->aucChannelList[u4IdxII] = prDomainSubBand->ucFirstChannelNum + -+ (u4IdxII * prDomainSubBand->ucChannelSpan); -+ -+#if 0 -+ switch (prChannelEntryField->aucChannelList[u4IdxII]) { -+ case 1: -+ ucSocialChnlSupport = 1; -+ break; -+ case 6: -+ ucSocialChnlSupport = 6; -+ break; -+ case 11: -+ ucSocialChnlSupport = 11; -+ break; -+ default: -+ break; -+ } -+ -+#endif -+ } -+ -+ if (ucBufferSize >= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels)) -+ ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels); -+ else -+ break; -+ -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryField + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG) -+ prChannelEntryField->ucNumberOfChannels); -+ -+ } -+ -+#if 0 -+ if (prP2pConnSetting->ucListenChnl == 0) { -+ prP2pConnSetting->ucListenChnl = P2P_DEFAULT_LISTEN_CHANNEL; -+ -+ if (ucSocialChnlSupport != 0) { -+ /* 1. User Not Set LISTEN channel. -+ * 2. Social channel is not empty. -+ */ -+ prP2pConnSetting->ucListenChnl = ucSocialChnlSupport; -+ } -+ } -+#endif -+ -+ /* TODO: 20110921 frog - */ -+ /* If LISTEN channel is not set, -+ * a random supported channel would be set. -+ * If no social channel is supported, DEFAULT channel would be set. -+ */ -+ -+ prP2pConnSetting->ucRfChannelListSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE - ucBufferSize; -+ -+#if 0 -+ if (prP2pConnSetting->ucOperatingChnl == 0) { /* User not set OPERATE channel. */ -+ -+ if (scnQuerySparseChannel(prAdapter, NULL, &ucAutoChnl)) -+ break; /* while */ -+ -+ ucBufferSize = prP2pConnSetting->ucRfChannelListSize; -+ -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; -+ -+ while (ucBufferSize != 0) { -+ if (prChannelEntryField->ucNumberOfChannels != 0) { -+ ucAutoChnl = prChannelEntryField->aucChannelList[0]; -+ break; /* while */ -+ } -+ -+ else { -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((UINT_32) prChannelEntryField + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (UINT_32)prChannelEntryField->ucNumberOfChannels); -+ -+ ucBufferSize -= -+ (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels); -+ } -+ -+ } -+ -+ } -+#endif -+ /* We assume user would not set a channel not in the channel list. -+ * If so, the operating channel still depends on target device supporting capability. -+ */ -+ -+ /* TODO: 20110921 frog - */ -+ /* If the Operating channel is not set, a channel from supported channel list is set automatically. -+ * If there is no supported channel in channel list, a DEFAULT channel is set. -+ */ -+ -+ } while (FALSE); -+ -+#if 0 -+ prP2pConnSetting->ucOperatingChnl = ucAutoChnl; -+#endif -+ -+} /* rlmFuncInitialChannelList */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find a common channel list from the local channel list info & target channel list info. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return boolean value if probe response frame is -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rlmFuncCommonChannelList(IN P_ADAPTER_T prAdapter, -+ IN P_CHANNEL_ENTRY_FIELD_T prChannelEntryII, IN UINT_8 ucChannelListSize) -+{ -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_CHANNEL_ENTRY_FIELD_T prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) NULL, prChannelEntryIII = -+ (P_CHANNEL_ENTRY_FIELD_T) NULL; -+ UINT_8 aucCommonChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE] = {0}; -+ UINT_8 ucOriChnlSize = 0, ucNewChnlSize = 0; -+ -+ do { -+ -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T) aucCommonChannelList; -+ -+ while (ucChannelListSize > 0) { -+ -+ prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; -+ ucOriChnlSize = prP2pConnSetting->ucRfChannelListSize; -+ -+ while (ucOriChnlSize > 0) { -+ if (prChannelEntryI->ucRegulatoryClass == prChannelEntryII->ucRegulatoryClass) { -+ prChannelEntryIII->ucRegulatoryClass = prChannelEntryI->ucRegulatoryClass; -+ /* TODO: Currently we assume that the regulatory class the same, -+ * the channels are the same. */ -+ kalMemCopy(prChannelEntryIII->aucChannelList, prChannelEntryII->aucChannelList, -+ prChannelEntryII->ucNumberOfChannels); -+ prChannelEntryIII->ucNumberOfChannels = prChannelEntryII->ucNumberOfChannels; -+ -+ ucNewChnlSize += -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryIII->ucNumberOfChannels; -+ -+ prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryIII + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG)prChannelEntryIII->ucNumberOfChannels); -+ } -+ -+ ucOriChnlSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryI->ucNumberOfChannels); -+ -+ prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryI + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG) -+ prChannelEntryI->ucNumberOfChannels); -+ -+ } -+ -+ ucChannelListSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryII->ucNumberOfChannels); -+ -+ prChannelEntryII = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryII + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG) prChannelEntryII->ucNumberOfChannels); -+ -+ } -+ -+ kalMemCopy(prP2pConnSetting->aucChannelEntriesField, aucCommonChannelList, ucNewChnlSize); -+ prP2pConnSetting->ucRfChannelListSize = ucNewChnlSize; -+ -+ } while (FALSE); -+ -+} /* rlmFuncCommonChannelList */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 rlmFuncFindOperatingClass(IN P_ADAPTER_T prAdapter, IN UINT_8 ucChannelNum) -+{ -+ UINT_8 ucRegulatoryClass = 0, ucBufferSize = 0; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) NULL; -+ UINT_32 u4Idx = 0; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; -+ ucBufferSize = prP2pConnSetting->ucRfChannelListSize; -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; -+ -+ while (ucBufferSize != 0) { -+ -+ for (u4Idx = 0; u4Idx < prChannelEntryField->ucNumberOfChannels; u4Idx++) { -+ if (prChannelEntryField->aucChannelList[u4Idx] == ucChannelNum) { -+ ucRegulatoryClass = prChannelEntryField->ucRegulatoryClass; -+ break; -+ } -+ -+ } -+ -+ if (ucRegulatoryClass != 0) -+ break; /* while */ -+ -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryField + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG)prChannelEntryField->ucNumberOfChannels); -+ -+ ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels); -+ -+ } -+ -+ } while (FALSE); -+ -+ return ucRegulatoryClass; -+} /* rlmFuncFindOperatingClass */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+rlmFuncFindAvailableChannel(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucCheckChnl, -+ IN PUINT_8 pucSuggestChannel, IN BOOLEAN fgIsSocialChannel, IN BOOLEAN fgIsDefaultChannel) -+{ -+ BOOLEAN fgIsResultAvailable = FALSE; -+ P_CHANNEL_ENTRY_FIELD_T prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ UINT_8 ucBufferSize = 0, ucIdx = 0, ucChannelSelected = 0; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ if (fgIsDefaultChannel) -+ ucChannelSelected = P2P_DEFAULT_LISTEN_CHANNEL; -+ -+ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; -+ ucBufferSize = prP2pConnSetting->ucRfChannelListSize; -+ prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; -+ -+ while ((ucBufferSize != 0) && (!fgIsResultAvailable)) { -+ -+ for (ucIdx = 0; ucIdx < prChannelEntry->ucNumberOfChannels; ucIdx++) { -+ if ((!fgIsSocialChannel) || -+ (prChannelEntry->aucChannelList[ucIdx] == 1) || -+ (prChannelEntry->aucChannelList[ucIdx] == 6) || -+ (prChannelEntry->aucChannelList[ucIdx] == 11)) { -+ -+ if (prChannelEntry->aucChannelList[ucIdx] <= 11) { -+ /* 2.4G. */ -+ ucChannelSelected = prChannelEntry->aucChannelList[ucIdx]; -+ } else if ((prChannelEntry->aucChannelList[ucIdx] < 52) && -+ (prChannelEntry->aucChannelList[ucIdx] > 14)) { -+ /* 2.4G + 5G. */ -+ ucChannelSelected = prChannelEntry->aucChannelList[ucIdx]; -+ } -+ -+ if (ucChannelSelected == ucCheckChnl) { -+ fgIsResultAvailable = TRUE; -+ break; -+ } -+ } -+ -+ } -+ -+ ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntry->ucNumberOfChannels); -+ -+ prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntry + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG) prChannelEntry->ucNumberOfChannels); -+ -+ } -+ -+ if ((!fgIsResultAvailable) && (pucSuggestChannel != NULL)) { -+ DBGLOG(P2P, TRACE, -+ "The request channel %d is not available, sugguested channel:%d\n", ucCheckChnl, -+ ucChannelSelected); -+ /* Given a suggested channel. */ -+ *pucSuggestChannel = ucChannelSelected; -+ } -+ -+ } while (FALSE); -+ -+ return fgIsResultAvailable; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_CHNL_EXT_T rlmDecideScoForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ P_DOMAIN_SUBBAND_INFO prSubband; -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ UINT_8 ucSecondChannel, i, j; -+ ENUM_CHNL_EXT_T eSCO; -+ -+ eSCO = CHNL_EXT_SCN; -+ -+ if (prBssInfo->eBand == BAND_2G4) { -+ if (prBssInfo->ucPrimaryChannel != 14) -+ eSCO = (prBssInfo->ucPrimaryChannel > 7) ? CHNL_EXT_SCB : CHNL_EXT_SCA; -+ } else { -+ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); -+ ASSERT(prDomainInfo); -+ -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ prSubband = &prDomainInfo->rSubBand[i]; -+ if (prSubband->ucBand == prBssInfo->eBand) { -+ for (j = 0; j < prSubband->ucNumChannels; j++) { -+ if ((prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan) -+ == prBssInfo->ucPrimaryChannel) { -+ eSCO = (j & 1) ? CHNL_EXT_SCB : CHNL_EXT_SCA; -+ break; -+ } -+ } -+ -+ if (j < prSubband->ucNumChannels) -+ break; /* Found */ -+ } -+ } -+ } -+ -+ /* Check if it is boundary channel and 40MHz BW is permitted */ -+ if (eSCO != CHNL_EXT_SCN) { -+ ucSecondChannel = (eSCO == CHNL_EXT_SCA) ? -+ (prBssInfo->ucPrimaryChannel + 4) : (prBssInfo->ucPrimaryChannel - 4); -+ -+ if (!rlmDomainIsLegalChannel(prAdapter, prBssInfo->eBand, ucSecondChannel)) -+ eSCO = CHNL_EXT_SCN; -+ } -+ -+ return eSCO; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c -new file mode 100644 -index 0000000000000..154f1e5db0f73 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c -@@ -0,0 +1,313 @@ -+/* -+** Id: @(#) gl_p2p_cfg80211.c@@ -+*/ -+ -+/*! \file gl_p2p_cfg80211.c -+ \brief Main routines of Linux driver interface for Wi-Fi Direct -+ using cfg80211 interface -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+static UINT_8 rlmObssChnlLevelIn2G4(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); -+ -+static UINT_8 rlmObssChnlLevelIn5G(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Different concurrent network has itself channel lists, and -+* concurrent networks should have been recorded in channel lists. -+* If role of active P2P is GO, assume associated AP of AIS will -+* record our Beacon for P2P GO because of same channel. -+* -+* Note: If we have scenario of different channel in the future, -+* the internal FW communication channel shall be established. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 rlmObssChnlLevel(P_BSS_INFO_T prBssInfo, ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) -+{ -+ UINT_8 ucChannelLevel; -+ -+ ASSERT(prBssInfo); -+ -+ if (eBand == BAND_2G4) { -+ ucChannelLevel = rlmObssChnlLevelIn2G4(prBssInfo, ucPriChannel, eExtend); -+ -+ /* (TBD) If concurrent networks permit different channel, extra -+ * channel judgement should be added. Please refer to -+ * previous version of this file. -+ */ -+ } else if (eBand == BAND_5G) { -+ ucChannelLevel = rlmObssChnlLevelIn5G(prBssInfo, ucPriChannel, eExtend); -+ -+ /* (TBD) If concurrent networks permit different channel, extra -+ * channel judgement should be added. Please refer to -+ * previous version of this file. -+ */ -+ } else { -+ ucChannelLevel = CHNL_LEVEL0; -+ } -+ -+ return ucChannelLevel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static UINT_8 rlmObssChnlLevelIn2G4(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) -+{ -+ UINT_8 i, ucChannelLevel; -+ UINT_8 ucSecChannel, ucCenterChannel; -+ UINT_8 ucAffectedChnl_L, ucAffectedChnl_H; -+ -+ ASSERT(prBssInfo); -+ -+ ucChannelLevel = CHNL_LEVEL2; -+ -+ /* Calculate center channel for 2.4G band */ -+ if (eExtend == CHNL_EXT_SCA) { -+ ucCenterChannel = ucPriChannel + 2; -+ ucSecChannel = ucPriChannel + 4; -+ } else if (eExtend == CHNL_EXT_SCB) { -+ ucCenterChannel = ucPriChannel - 2; -+ ucSecChannel = ucPriChannel - 4; -+ } else { -+ return CHNL_LEVEL0; -+ } -+ ASSERT(ucCenterChannel >= 1 && ucCenterChannel <= 14); -+ -+ /* Calculated low/upper channels in affected freq range */ -+ ucAffectedChnl_L = (ucCenterChannel <= AFFECTED_CHNL_OFFSET) ? 1 : (ucCenterChannel - AFFECTED_CHNL_OFFSET); -+ -+ ucAffectedChnl_H = (ucCenterChannel >= (14 - AFFECTED_CHNL_OFFSET)) ? -+ 14 : (ucCenterChannel + AFFECTED_CHNL_OFFSET); -+ -+ /* Check intolerant (Non-HT) channel list */ -+ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if ((prBssInfo->auc2G_NonHtChnlList[i] >= ucAffectedChnl_L && -+ prBssInfo->auc2G_NonHtChnlList[i] <= ucAffectedChnl_H) && -+ prBssInfo->auc2G_NonHtChnlList[i] != ucPriChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_2G4_level_end; -+ } -+ } -+ -+ /* Check 20M BW request channel list */ -+ ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if ((prBssInfo->auc2G_20mReqChnlList[i] >= ucAffectedChnl_L && -+ prBssInfo->auc2G_20mReqChnlList[i] <= ucAffectedChnl_H)) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_2G4_level_end; -+ } -+ } -+ -+ /* Check 2.4G primary channel list */ -+ ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if ((prBssInfo->auc2G_PriChnlList[i] >= ucAffectedChnl_L && -+ prBssInfo->auc2G_PriChnlList[i] <= ucAffectedChnl_H) && -+ prBssInfo->auc2G_PriChnlList[i] != ucPriChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_2G4_level_end; -+ } -+ } -+ -+ /* Check 2.4G secondary channel list */ -+ ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if ((prBssInfo->auc2G_SecChnlList[i] >= ucAffectedChnl_L && -+ prBssInfo->auc2G_SecChnlList[i] <= ucAffectedChnl_H) && -+ prBssInfo->auc2G_SecChnlList[i] != ucSecChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_2G4_level_end; -+ } -+ } -+ -+L_2G4_level_end: -+ -+ return ucChannelLevel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static UINT_8 rlmObssChnlLevelIn5G(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) -+{ -+ UINT_8 i, ucChannelLevel; -+ UINT_8 ucSecChannel; -+ -+ ASSERT(prBssInfo); -+ -+ ucChannelLevel = CHNL_LEVEL2; -+ -+ /* Calculate center channel for 2.4G band */ -+ if (eExtend == CHNL_EXT_SCA) -+ ucSecChannel = ucPriChannel + 4; -+ else if (eExtend == CHNL_EXT_SCB) -+ ucSecChannel = ucPriChannel - 4; -+ else -+ return CHNL_LEVEL0; -+ ASSERT(ucSecChannel >= 36); -+ -+ /* Check 5G primary channel list */ -+ ASSERT(prBssInfo->auc5G_PriChnlList[0] <= CHNL_LIST_SZ_5G); -+ for (i = 1; i <= prBssInfo->auc5G_PriChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) { -+ if (prBssInfo->auc5G_PriChnlList[i] == ucSecChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_5G_level_end; -+ } else if (prBssInfo->auc5G_PriChnlList[i] == ucPriChannel) { -+ ucChannelLevel = CHNL_LEVEL1; -+ } -+ } -+ -+ /* Check non-HT channel list */ -+ ASSERT(prBssInfo->auc5G_NonHtChnlList[0] <= CHNL_LIST_SZ_5G); -+ for (i = 1; i <= prBssInfo->auc5G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) { -+ if (prBssInfo->auc5G_NonHtChnlList[i] == ucSecChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_5G_level_end; -+ } else if (prBssInfo->auc5G_NonHtChnlList[i] == ucPriChannel) { -+ ucChannelLevel = CHNL_LEVEL1; -+ } -+ } -+ -+ /* Check secondary channel list */ -+ ASSERT(prBssInfo->auc5G_SecChnlList[0] <= CHNL_LIST_SZ_5G); -+ for (i = 1; i <= prBssInfo->auc5G_SecChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) { -+ if (prBssInfo->auc5G_SecChnlList[i] == ucPriChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_5G_level_end; -+ } -+ } -+ -+L_5G_level_end: -+ -+ return ucChannelLevel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmObssScanExemptionRsp(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ P_ACTION_20_40_COEXIST_FRAME prTxFrame; -+ -+ /* To do: need an algorithm to do judgement. Now always reject request */ -+ -+ prMsduInfo = (P_MSDU_INFO_T)cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN); -+ if (prMsduInfo == NULL) -+ return; -+ -+ DBGLOG(RLM, INFO, "Send 20/40 coexistence rsp frame!\n"); -+ -+ prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) prMsduInfo->prPacket; -+ -+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; -+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, ((P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader)->aucSrcAddr); -+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); -+ -+ prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION; -+ prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST; -+ -+ /* To do: find correct algorithm */ -+ prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE; -+ prTxFrame->rBssCoexist.ucLength = 1; -+ prTxFrame->rBssCoexist.ucData = 0; -+ -+ ASSERT((WLAN_MAC_HEADER_LEN + 5) <= PUBLIC_ACTION_MAX_LEN); -+ -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prSwRfb->ucStaRecIdx; -+ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_HTC_LEN + 5; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ /* Send them to HW queue */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c -new file mode 100644 -index 0000000000000..b5bd23965fe35 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c -@@ -0,0 +1,756 @@ -+/* -+** Id: @(#) p2p_scan.c@@ -+*/ -+ -+/*! \file "p2p_scan.c" -+ \brief This file defines the p2p scan profile and the processing function of -+ scan result for SCAN Module. -+ -+ The SCAN Profile selection is part of SCAN MODULE and responsible for defining -+ SCAN Parameters - e.g. MIN_CHANNEL_TIME, number of scan channels. -+ In this file we also define the process of SCAN Result including adding, searching -+ and removing SCAN record from the list. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+P_P2P_DEVICE_DESC_T -+scanSearchTargetP2pDesc(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDeviceID[], IN PP_BSS_DESC_T pprBssDesc) -+{ -+ -+ P_P2P_DEVICE_DESC_T prTargetP2pDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ P_SCAN_INFO_T prScanInfo = (P_SCAN_INFO_T) NULL; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucDeviceID); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* 4 <1> The outer loop to search for a candidate. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ /* Loop for each prBssDesc */ -+ prTargetP2pDesc = scanFindP2pDeviceDesc(prAdapter, prBssDesc, aucDeviceID, TRUE, FALSE); -+ -+ if (prTargetP2pDesc != NULL) -+ break; -+ } -+ -+ if ((pprBssDesc) && (prTargetP2pDesc != NULL)) { -+ /* Only valid if prTargetP2pDesc is not NULL. */ -+ *pprBssDesc = prBssDesc; -+ } -+ -+ return prTargetP2pDesc; -+} /* scanSearchTargetP2pDesc */ -+ -+VOID scanInvalidAllP2pClientDevice(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ -+ LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) { -+ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); -+ -+ if (prTargetDesc->fgDevInfoValid) -+ prTargetDesc->fgDevInfoValid = FALSE; -+ } -+ -+} /* scanRenewP2pClientDevice */ -+ -+VOID scanRemoveInvalidP2pClientDevice(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL, prNexEntry = (P_LINK_ENTRY_T) NULL; -+ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ LINK_FOR_EACH_SAFE(prLinkEntry, prNexEntry, &prBssDesc->rP2pDeviceList) { -+ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); -+ -+ if (!prTargetDesc->fgDevInfoValid) { -+ LINK_REMOVE_KNOWN_ENTRY(&prBssDesc->rP2pDeviceList, prLinkEntry); -+ if ((prP2pConnSettings) && (prP2pConnSettings->prTargetP2pDesc == prTargetDesc)) -+ prP2pConnSettings->prTargetP2pDesc = NULL; -+ kalMemFree(prTargetDesc, VIR_MEM_TYPE, sizeof(P2P_DEVICE_DESC_T)); -+ } -+ } -+ -+} /* scanRenewP2pClientDevice */ -+ -+P_P2P_DEVICE_DESC_T -+scanFindP2pDeviceDesc(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_DESC_T prBssDesc, -+ IN UINT_8 aucMacAddr[], IN BOOLEAN fgIsDeviceAddr, IN BOOLEAN fgAddIfNoFound) -+{ -+ -+ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prBssDesc != NULL) && (aucMacAddr != NULL)); -+ -+ LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) { -+ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); -+ -+ if (fgIsDeviceAddr) { -+ if (EQUAL_MAC_ADDR(prTargetDesc->aucDeviceAddr, aucMacAddr)) -+ break; -+ } else { -+ if (EQUAL_MAC_ADDR(prTargetDesc->aucInterfaceAddr, aucMacAddr)) -+ break; -+ } -+ -+ prTargetDesc = NULL; -+ } -+ -+ if ((fgAddIfNoFound) && (prTargetDesc == NULL)) { -+ /* Target Not Found. */ -+ /* TODO: Use memory pool in the future. */ -+ prTargetDesc = kalMemAlloc(sizeof(P2P_DEVICE_DESC_T), VIR_MEM_TYPE); -+ -+ if (prTargetDesc) { -+ kalMemZero(prTargetDesc, sizeof(P2P_DEVICE_DESC_T)); -+ LINK_ENTRY_INITIALIZE(&(prTargetDesc->rLinkEntry)); -+ COPY_MAC_ADDR(prTargetDesc->aucDeviceAddr, aucMacAddr); -+ LINK_INSERT_TAIL(&prBssDesc->rP2pDeviceList, &prTargetDesc->rLinkEntry); -+ prTargetDesc->fgDevInfoValid = TRUE; -+ } else { -+ ASSERT(FALSE); -+ } -+ } -+ -+ } while (FALSE); -+ -+ return prTargetDesc; -+} /* scanFindP2pDeviceDesc */ -+ -+P_P2P_DEVICE_DESC_T scanGetP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ -+ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssDesc); -+ -+ if (prBssDesc->prP2pDesc == NULL) { -+ -+ prTargetDesc = kalMemAlloc(sizeof(P2P_DEVICE_DESC_T), VIR_MEM_TYPE); -+ -+ if (prTargetDesc) { -+ kalMemZero(prTargetDesc, sizeof(P2P_DEVICE_DESC_T)); -+ LINK_ENTRY_INITIALIZE(&(prTargetDesc->rLinkEntry)); -+ LINK_INSERT_TAIL(&prBssDesc->rP2pDeviceList, &prTargetDesc->rLinkEntry); -+ prTargetDesc->fgDevInfoValid = TRUE; -+ prBssDesc->prP2pDesc = prTargetDesc; -+ /* We are not sure the SrcAddr is Device Address or Interface Address. */ -+ COPY_MAC_ADDR(prTargetDesc->aucDeviceAddr, prBssDesc->aucSrcAddr); -+ COPY_MAC_ADDR(prTargetDesc->aucInterfaceAddr, prBssDesc->aucSrcAddr); -+ } else { -+ -+ ASSERT(FALSE); -+ } -+ } else { -+ prTargetDesc = prBssDesc->prP2pDesc; -+ } -+ -+ return prTargetDesc; -+ -+} /* scanFindP2pDeviceDesc */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to Event Packet -+* -+* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host. -+* @retval WLAN_STATUS_FAILURE It is not a valid Scan Result. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scanUpdateP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_P2P_DEVICE_DESC_T prP2pDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ P_P2P_ATTRIBUTE_T prP2pAttribute = (P_P2P_ATTRIBUTE_T) NULL; -+ UINT_16 u2AttributeLen = 0; -+ UINT_32 u4Idx = 0; -+ BOOLEAN fgUpdateDevInfo = FALSE; -+ -+ P_DEVICE_NAME_TLV_T prP2pDevName = (P_DEVICE_NAME_TLV_T) NULL; -+ P_P2P_ATTRI_GROUP_INFO_T prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) NULL; -+ -+ ASSERT(prAdapter); -+ -+ prP2pDesc = scanGetP2pDeviceDesc(prAdapter, prBssDesc); -+ -+ if (!prP2pDesc) { -+ ASSERT(FALSE); -+ return fgUpdateDevInfo; -+ } -+ -+ p2pGetP2PAttriList(prAdapter, prBssDesc->aucIEBuf, prBssDesc->u2IELength, (PPUINT_8) & prP2pAttribute, -+ &u2AttributeLen); -+ -+ while (u2AttributeLen >= P2P_ATTRI_HDR_LEN) { -+ switch (prP2pAttribute->ucId) { -+ case P2P_ATTRI_ID_P2P_CAPABILITY: /* Beacon, Probe Response */ -+ { -+ P_P2P_ATTRI_CAPABILITY_T prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) NULL; -+ -+ prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) prP2pAttribute; -+ ASSERT(prP2pAttriCapability->u2Length == 2); -+ -+ prP2pDesc->ucDeviceCapabilityBitmap = prP2pAttriCapability->ucDeviceCap; -+ prP2pDesc->ucGroupCapabilityBitmap = prP2pAttriCapability->ucGroupCap; -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_DEV_ID: /* Beacon */ -+ { -+ P_P2P_ATTRI_DEV_ID_T prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) NULL; -+ -+ prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) prP2pAttribute; -+ ASSERT(prP2pAttriDevID->u2Length == P2P_ATTRI_MAX_LEN_P2P_DEV_ID); -+ -+ kalMemCopy(prP2pDesc->aucDeviceAddr, prP2pAttriDevID->aucDevAddr, MAC_ADDR_LEN); -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_DEV_INFO: /* Probe Response */ -+ { -+ P_P2P_ATTRI_DEV_INFO_T prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) NULL; -+ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; -+ UINT_16 u2NameLen = 0, u2Id = 0; -+ -+ fgUpdateDevInfo = TRUE; -+ -+ prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) prP2pAttribute; -+ -+ kalMemCopy(prP2pDesc->aucDeviceAddr, prP2pAttriDevInfo->aucDevAddr, MAC_ADDR_LEN); -+ -+ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->u2ConfigMethodsBE, &prP2pDesc->u2ConfigMethod); -+ -+ prP2pDevType = &prP2pDesc->rPriDevType; -+ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId, -+ &prP2pDevType->u2CategoryID); -+ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId, -+ &prP2pDevType->u2SubCategoryID); -+ -+ ASSERT(prP2pAttriDevInfo->ucNumOfSecondaryDevType <= -+ P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT); -+ /* TODO: Fixme if secondary device type is more than 2. */ -+ prP2pDesc->ucSecDevTypeNum = 0; -+ for (u4Idx = 0; u4Idx < prP2pAttriDevInfo->ucNumOfSecondaryDevType; u4Idx++) { -+ if (u4Idx < P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT) { -+ prP2pDevType = &(prP2pDesc->arSecDevType[u4Idx]); -+ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo-> -+ arSecondaryDevTypeListBE[u4Idx].u2CategoryId, -+ &prP2pDevType->u2CategoryID); -+ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo-> -+ arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId, -+ &prP2pDevType->u2SubCategoryID); -+ prP2pDesc->ucSecDevTypeNum++; -+ } -+ -+ } -+ prP2pDevName = -+ (P_DEVICE_NAME_TLV_T) ((PUINT_8) prP2pAttriDevInfo->arSecondaryDevTypeListBE + -+ (u4Idx * sizeof(DEVICE_TYPE_T))); -+ WLAN_GET_FIELD_BE16(&prP2pDevName->u2Length, &u2NameLen); -+ WLAN_GET_FIELD_BE16(&prP2pDevName->u2Id, &u2Id); -+ ASSERT(u2Id == WPS_ATTRI_ID_DEVICE_NAME); -+ if (u2NameLen > WPS_ATTRI_MAX_LEN_DEVICE_NAME) -+ u2NameLen = WPS_ATTRI_MAX_LEN_DEVICE_NAME; -+ prP2pDesc->u2NameLength = u2NameLen; -+ kalMemCopy(prP2pDesc->aucName, prP2pDevName->aucName, prP2pDesc->u2NameLength); -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_GROUP_INFO: /* Probe Response */ -+ prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) prP2pAttribute; -+ break; -+ case P2P_ATTRI_ID_NOTICE_OF_ABSENCE: -+ break; -+ case P2P_ATTRI_ID_EXT_LISTEN_TIMING: -+ /* TODO: Not implement yet. */ -+ /* ASSERT(FALSE); */ -+ break; -+ default: -+ break; -+ } -+ -+ u2AttributeLen -= (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN); -+ -+ prP2pAttribute = -+ (P_P2P_ATTRIBUTE_T) ((UINT_32) prP2pAttribute + (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN)); -+ -+ } -+ -+ if (prP2pAttriGroupInfo != NULL) { -+ P_P2P_CLIENT_INFO_DESC_T prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) NULL; -+ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; -+ -+ scanInvalidAllP2pClientDevice(prAdapter, prBssDesc); -+ -+ /* GO/Device itself. */ -+ prP2pDesc->fgDevInfoValid = TRUE; -+ -+ prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) prP2pAttriGroupInfo->arClientDesc; -+ u2AttributeLen = prP2pAttriGroupInfo->u2Length; -+ -+ while (u2AttributeLen > 0) { -+ prP2pDesc = -+ scanFindP2pDeviceDesc(prAdapter, prBssDesc, prClientInfoDesc->aucDevAddr, TRUE, TRUE); -+ -+ if (!prP2pDesc) { -+ ASSERT(FALSE); -+ break; /* while */ -+ } -+ -+ prP2pDesc->fgDevInfoValid = TRUE; -+ -+ /* Basic size for P2P client info descriptor. */ -+ ASSERT(u2AttributeLen >= 25); -+ if (u2AttributeLen < 25) { -+ DBGLOG(P2P, WARN, "Length incorrect warning.\n"); -+ break; -+ } -+ COPY_MAC_ADDR(prP2pDesc->aucInterfaceAddr, prClientInfoDesc->aucIfAddr); -+ -+ prP2pDesc->ucDeviceCapabilityBitmap = prClientInfoDesc->ucDeviceCap; -+ -+ WLAN_GET_FIELD_BE16(&prClientInfoDesc->u2ConfigMethodsBE, &prP2pDesc->u2ConfigMethod); -+ -+ prP2pDevType = &(prP2pDesc->rPriDevType); -+ WLAN_GET_FIELD_BE16(&prClientInfoDesc->rPrimaryDevTypeBE.u2CategoryId, -+ &prP2pDevType->u2CategoryID); -+ WLAN_GET_FIELD_BE16(&prClientInfoDesc->rPrimaryDevTypeBE.u2SubCategoryId, -+ &prP2pDevType->u2SubCategoryID); -+ -+ ASSERT(prClientInfoDesc->ucNumOfSecondaryDevType <= P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT); -+ prP2pDesc->ucSecDevTypeNum = 0; -+ for (u4Idx = 0; u4Idx < prClientInfoDesc->ucNumOfSecondaryDevType; u4Idx++) { -+ if (u4Idx < P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT) { -+ prP2pDevType = &(prP2pDesc->arSecDevType[u4Idx]); -+ WLAN_GET_FIELD_BE16(&prClientInfoDesc-> -+ arSecondaryDevTypeListBE[u4Idx].u2CategoryId, -+ &prP2pDevType->u2CategoryID); -+ WLAN_GET_FIELD_BE16(&prClientInfoDesc-> -+ arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId, -+ &prP2pDevType->u2SubCategoryID); -+ prP2pDesc->ucSecDevTypeNum++; -+ } -+ -+ } -+ prP2pDevName = -+ (P_DEVICE_NAME_TLV_T) (prClientInfoDesc->arSecondaryDevTypeListBE + -+ (u4Idx * sizeof(DEVICE_TYPE_T))); -+ WLAN_GET_FIELD_BE16(&prP2pDevName->u2Length, &prP2pDesc->u2NameLength); -+ if (prP2pDesc->u2NameLength > WPS_ATTRI_MAX_LEN_DEVICE_NAME) -+ prP2pDesc->u2NameLength = WPS_ATTRI_MAX_LEN_DEVICE_NAME; -+ -+ kalMemCopy(prP2pDesc->aucName, prP2pDevName->aucName, prP2pDesc->u2NameLength); -+ -+ u2AttributeLen -= (prClientInfoDesc->ucLength + P2P_CLIENT_INFO_DESC_HDR_LEN); -+ prClientInfoDesc = -+ (P_P2P_CLIENT_INFO_DESC_T) ((UINT_32) prClientInfoDesc + -+ (UINT_32) prClientInfoDesc->ucLength + -+ P2P_CLIENT_INFO_DESC_HDR_LEN); -+ } -+ -+ scanRemoveInvalidP2pClientDevice(prAdapter, prBssDesc); -+ } -+ -+ return fgUpdateDevInfo; -+} /* end of scanAddP2pDeviceInfo() */ -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to Event Packet -+* -+* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host. -+* @retval WLAN_STATUS_FAILURE It is not a valid Scan Result. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS scanSendDeviceDiscoverEvent(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb) -+{ -+ EVENT_P2P_DEV_DISCOVER_RESULT_T rEventDevInfo; -+#if 1 -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ -+ LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) { -+ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); -+ -+ COPY_MAC_ADDR(rEventDevInfo.aucDeviceAddr, prTargetDesc->aucDeviceAddr); -+ COPY_MAC_ADDR(rEventDevInfo.aucInterfaceAddr, prTargetDesc->aucInterfaceAddr); -+ -+ rEventDevInfo.ucDeviceCapabilityBitmap = prTargetDesc->ucDeviceCapabilityBitmap; -+ rEventDevInfo.ucGroupCapabilityBitmap = prTargetDesc->ucGroupCapabilityBitmap; -+ rEventDevInfo.u2ConfigMethod = prTargetDesc->u2ConfigMethod; -+ -+ kalMemCopy(&rEventDevInfo.rPriDevType, &prTargetDesc->rPriDevType, sizeof(P2P_DEVICE_TYPE_T)); -+ -+ kalMemCopy(rEventDevInfo.arSecDevType, -+ prTargetDesc->arSecDevType, (prTargetDesc->ucSecDevTypeNum * sizeof(P2P_DEVICE_TYPE_T))); -+ -+ rEventDevInfo.ucSecDevTypeNum = prTargetDesc->ucSecDevTypeNum; -+ -+ rEventDevInfo.u2NameLength = prTargetDesc->u2NameLength; -+ kalMemCopy(rEventDevInfo.aucName, prTargetDesc->aucName, prTargetDesc->u2NameLength); -+ -+ COPY_MAC_ADDR(rEventDevInfo.aucBSSID, prBssDesc->aucBSSID); -+ -+ if (prTargetDesc == prBssDesc->prP2pDesc) -+ nicRxAddP2pDevice(prAdapter, &rEventDevInfo, prBssDesc->aucIEBuf, prBssDesc->u2IELength); -+ else -+ nicRxAddP2pDevice(prAdapter, &rEventDevInfo, NULL, 0); -+ } -+ -+ kalP2PIndicateFound(prAdapter->prGlueInfo); -+ -+#else -+ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ P_P2P_ATTRIBUTE_T prP2pAttribute = (P_P2P_ATTRIBUTE_T) NULL; -+ UINT_16 u2AttributeLen = 0; -+ UINT_32 u4Idx = 0; -+ P_P2P_ATTRI_GROUP_INFO_T prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) NULL; -+ P_DEVICE_NAME_TLV_T prP2pDevName = (P_DEVICE_NAME_TLV_T) NULL; -+ -+ ASSERT(prAdapter); -+ -+ prP2pSpecificBssInfo = &prAdapter->rWifiVar.rP2pSpecificBssInfo; -+ -+#if 1 -+ p2pGetP2PAttriList(prAdapter, prBssDesc->aucIEBuf, prBssDesc->u2IELength, (PPUINT_8) & prP2pAttribute, -+ &u2AttributeLen); -+#else -+ prP2pAttribute = (P_P2P_ATTRIBUTE_T) &prP2pSpecificBssInfo->aucAttributesCache[0]; -+ u2AttributeLen = prP2pSpecificBssInfo->u2AttributeLen; -+#endif -+ rEventDevInfo.fgDevInfoValid = FALSE; -+ -+ while (u2AttributeLen >= P2P_ATTRI_HDR_LEN) { -+ switch (prP2pAttribute->ucId) { -+ case P2P_ATTRI_ID_P2P_CAPABILITY: -+ { -+ P_P2P_ATTRI_CAPABILITY_T prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) NULL; -+ -+ prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) prP2pAttribute; -+ ASSERT(prP2pAttriCapability->u2Length == 2); -+ rEventDevInfo.ucDeviceCapabilityBitmap = prP2pAttriCapability->ucDeviceCap; -+ rEventDevInfo.ucGroupCapabilityBitmap = prP2pAttriCapability->ucGroupCap; -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_DEV_ID: -+ { -+ P_P2P_ATTRI_DEV_ID_T prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) NULL; -+ -+ prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) prP2pAttribute; -+ ASSERT(prP2pAttriDevID->u2Length == 6); -+ kalMemCopy(rEventDevInfo.aucCommunicateAddr, prP2pAttriDevID->aucDevAddr, MAC_ADDR_LEN); -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_DEV_INFO: -+ { -+ P_P2P_ATTRI_DEV_INFO_T prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) NULL; -+ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; -+ -+ prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) prP2pAttribute; -+ rEventDevInfo.fgDevInfoValid = TRUE; -+ kalMemCopy(rEventDevInfo.aucCommunicateAddr, prP2pAttriDevInfo->aucDevAddr, -+ MAC_ADDR_LEN); -+ rEventDevInfo.u2ConfigMethod = prP2pAttriDevInfo->u2ConfigMethodsBE; -+ -+ prP2pDevType = &rEventDevInfo.rPriDevType; -+ prP2pDevType->u2CategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId; -+ prP2pDevType->u2SubCategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId; -+ -+ ASSERT(prP2pAttriDevInfo->ucNumOfSecondaryDevType <= 2); -+ /* TODO: Fixme if secondary device type is more than 2. */ -+ for (u4Idx = 0; u4Idx < prP2pAttriDevInfo->ucNumOfSecondaryDevType; u4Idx++) { -+ /* TODO: Current sub device type can only support 2. */ -+ prP2pDevType = &rEventDevInfo.arSecDevType[u4Idx]; -+ prP2pDevType->u2CategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId; -+ prP2pDevType->u2SubCategoryID = -+ prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId; -+ } -+ -+ prP2pDevName = -+ (P_DEVICE_NAME_TLV_T) (prP2pAttriDevInfo->arSecondaryDevTypeListBE + -+ (u4Idx * sizeof(DEVICE_TYPE_T))); -+ ASSERT(prP2pDevName->u2Id == 0x1011); -+ ASSERT(prP2pDevName->u2Length <= 32); -+ /* TODO: Fixme if device name length is longer than 32 bytes. */ -+ kalMemCopy(rEventDevInfo.aucName, prP2pDevName->aucName, prP2pDevName->u2Length); -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_GROUP_INFO: -+ prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) prP2pAttribute; -+ break; -+ } -+ -+ u2AttributeLen -= (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN); -+ -+ prP2pAttribute = -+ (P_P2P_ATTRIBUTE_T) ((UINT_32) prP2pAttribute + (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN)); -+ -+ } -+ -+ nicRxAddP2pDevice(prAdapter, &rEventDevInfo); -+ -+ if (prP2pAttriGroupInfo != NULL) { -+ P_P2P_CLIENT_INFO_DESC_T prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) NULL; -+ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; -+ -+ prClientInfoDesc = prP2pAttriGroupInfo->arClientDesc; -+ u2AttributeLen = prP2pAttriGroupInfo->u2Length; -+ -+ while (u2AttributeLen > 0) { -+ /* Basic size for P2P client info descriptor. */ -+ ASSERT(u2AttributeLen >= 25); -+ rEventDevInfo.fgDevInfoValid = TRUE; -+ kalMemCopy(rEventDevInfo.aucCommunicateAddr, prClientInfoDesc->aucIfAddr, MAC_ADDR_LEN); -+ rEventDevInfo.ucDeviceCapabilityBitmap = prClientInfoDesc->ucDeviceCap; -+ rEventDevInfo.u2ConfigMethod = prClientInfoDesc->u2ConfigMethodsBE; -+ -+ prP2pDevType = &rEventDevInfo.rPriDevType; -+ prP2pDevType->u2CategoryID = prClientInfoDesc->rPrimaryDevTypeBE.u2CategoryId; -+ prP2pDevType->u2SubCategoryID = prClientInfoDesc->rPrimaryDevTypeBE.u2SubCategoryId; -+ -+ ASSERT(prClientInfoDesc->ucNumOfSecondaryDevType <= 2); -+ /* TODO: Fixme if secondary device type is more than 2. */ -+ for (u4Idx = 0; u4Idx < prClientInfoDesc->ucNumOfSecondaryDevType; u4Idx++) { -+ /* TODO: Current sub device type can only support 2. */ -+ prP2pDevType = &rEventDevInfo.arSecDevType[u4Idx]; -+ prP2pDevType->u2CategoryID = -+ prClientInfoDesc->arSecondaryDevTypeListBE[u4Idx].u2CategoryId; -+ prP2pDevType->u2SubCategoryID = -+ prClientInfoDesc->arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId; -+ } -+ -+ prP2pDevName = -+ (P_DEVICE_NAME_TLV_T) (prClientInfoDesc->arSecondaryDevTypeListBE + -+ (u4Idx * sizeof(DEVICE_TYPE_T))); -+ ASSERT(prP2pDevName->u2Id == 0x1011); -+ ASSERT(prP2pDevName->u2Length <= 32); -+ /* TODO: Fixme if device name length is longer than 32 bytes. */ -+ kalMemCopy(&rEventDevInfo.aucName, prP2pDevName->aucName, prP2pDevName->u2Length); -+ -+ nicRxAddP2pDevice(prAdapter, &rEventDevInfo); -+ -+ u2AttributeLen -= prP2pAttriGroupInfo->u2Length; -+ prP2pAttriGroupInfo = prP2pAttriGroupInfo + prP2pAttriGroupInfo->u2Length + 1; -+ } -+ -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+} /* scanSendDeviceDiscoverEvent */ -+ -+VOID -+scanP2pProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, -+ IN P_WLAN_STATUS prStatus, -+ IN P_BSS_DESC_T prBssDesc, IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame) -+{ -+ BOOLEAN fgIsSkipThisBeacon; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ fgIsSkipThisBeacon = FALSE; -+ if (prBssDesc->fgIsP2PPresent) { -+ if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && /* P2P GC */ -+ (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) && /* Connected */ -+ ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) { /* TX Beacon */ -+ -+ fgIsSkipThisBeacon = TRUE; -+ } -+ -+ if ((!prP2pBssInfo->ucDTIMPeriod) && /* First time. */ -+ fgIsSkipThisBeacon && (EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, -+ prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen))) { /* SSID Match */ -+ prP2pBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; -+ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ do { -+ RF_CHANNEL_INFO_T rChannelInfo; -+ -+ ASSERT_BREAK((prSwRfb != NULL) && (prBssDesc != NULL)); -+ -+ if (((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) != MAC_FRAME_PROBE_RSP)) { -+ /* Only report Probe Response frame to supplicant. */ -+ /* Probe response collect much more information. */ -+ -+ if (fgIsSkipThisBeacon || prBssDesc->eBand == BAND_2G4) -+ break; -+ } -+ -+ rChannelInfo.ucChannelNum = prBssDesc->ucChannelNum; -+ rChannelInfo.eBand = prBssDesc->eBand; -+ prBssDesc->fgIsP2PReport = TRUE; -+ -+ DBGLOG(P2P, INFO, "indicate %s [%d]\n", prBssDesc->aucSSID, prBssDesc->ucChannelNum); -+ -+ kalP2PIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prSwRfb->pvHeader, -+ (UINT_32) prSwRfb->u2PacketLen, -+ &rChannelInfo, RCPI_TO_dBm(prBssDesc->ucRCPI)); -+ -+ } while (FALSE); -+ } -+} -+ -+VOID scnEventReturnChannel(IN P_ADAPTER_T prAdapter, IN UINT_8 ucScnSeqNum) -+{ -+ -+ CMD_SCAN_CANCEL rCmdScanCancel; -+ -+ /* send cancel message to firmware domain */ -+ rCmdScanCancel.ucSeqNum = ucScnSeqNum; -+ rCmdScanCancel.ucIsExtChannel = (UINT_8) FALSE; -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_CANCEL, -+ TRUE, -+ FALSE, FALSE, NULL, NULL, sizeof(CMD_SCAN_CANCEL), (PUINT_8)&rCmdScanCancel, NULL, 0); -+ -+} /* scnEventReturnChannel */ -+ -+VOID scanRemoveAllP2pBssDesc(IN P_ADAPTER_T prAdapter) -+{ -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ P_BSS_DESC_T prBSSDescNext; -+ -+ ASSERT(prAdapter); -+ -+ prBSSDescList = &(prAdapter->rWifiVar.rScanInfo.rBSSDescList); -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ scanRemoveP2pBssDesc(prAdapter, prBssDesc); -+ } -+} /* scanRemoveAllP2pBssDesc */ -+ -+VOID scanRemoveP2pBssDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ -+ -+} /* scanRemoveP2pBssDesc */ -+ -+P_BSS_DESC_T -+scanP2pSearchDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo) -+{ -+ P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T) NULL, prBssDesc = (P_BSS_DESC_T) NULL; -+ P_LINK_T prBssDescList = (P_LINK_T) NULL; -+ -+ do { -+ if ((prAdapter == NULL) || (prP2pBssInfo == NULL) || (prConnReqInfo == NULL)) -+ break; -+ -+ prBssDescList = &(prAdapter->rWifiVar.rScanInfo.rBSSDescList); -+ -+ DBGLOG(P2P, LOUD, "Connecting to BSSID: %pM\n", prConnReqInfo->aucBssid); -+ DBGLOG(P2P, LOUD, "Connecting to SSID:%s, length:%d\n", -+ prConnReqInfo->rSsidStruct.aucSsid, prConnReqInfo->rSsidStruct.ucSsidLen); -+ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBssDescList, rLinkEntry, BSS_DESC_T) { -+ DBGLOG(P2P, LOUD, "Checking BSS: %pM\n", prBssDesc->aucBSSID); -+ -+ if (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE) { -+ DBGLOG(P2P, LOUD, "Ignore mismatch BSS type.\n"); -+ continue; -+ } -+ -+ if (UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnReqInfo->aucBssid)) { -+ DBGLOG(P2P, LOUD, "Ignore mismatch BSSID.\n"); -+ continue; -+ } -+ -+ /* SSID should be the same? SSID is vary for each connection. so... */ -+ if (UNEQUAL_SSID(prConnReqInfo->rSsidStruct.aucSsid, -+ prConnReqInfo->rSsidStruct.ucSsidLen, -+ prBssDesc->aucSSID, prBssDesc->ucSSIDLen)) { -+ -+ DBGLOG(P2P, TRACE, -+ "Connecting to BSSID: %pM\n", prConnReqInfo->aucBssid); -+ DBGLOG(P2P, TRACE, -+ "Connecting to SSID:%s, length:%d\n", prConnReqInfo->rSsidStruct.aucSsid, -+ prConnReqInfo->rSsidStruct.ucSsidLen); -+ DBGLOG(P2P, TRACE, -+ "Checking SSID:%s, length:%d\n", prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ DBGLOG(P2P, TRACE, "Ignore mismatch SSID, (But BSSID match).\n"); -+ ASSERT(FALSE); -+ continue; -+ } -+ -+ if (!prBssDesc->fgIsP2PPresent) { -+ DBGLOG(P2P, ERROR, "SSID, BSSID, BSSTYPE match, but no P2P IE present.\n"); -+ continue; -+ } -+ -+ /* Final decision. */ -+ prCandidateBssDesc = prBssDesc; -+ break; -+ } -+ -+ } while (FALSE); -+ -+ return prCandidateBssDesc; -+} /* scanP2pSearchDesc */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c -new file mode 100644 -index 0000000000000..befb9978f4735 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c -@@ -0,0 +1,466 @@ -+#include "p2p_precomp.h" -+ -+BOOLEAN -+p2pStateInit_IDLE(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_BSS_INFO_T prP2pBssInfo, OUT P_ENUM_P2P_STATE_T peNextState) -+{ -+ BOOLEAN fgIsTransOut = FALSE; -+/* P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T)NULL; */ -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && -+ (prP2pFsmInfo != NULL) && (prP2pBssInfo != NULL) && (peNextState != NULL)); -+ -+ if ((prP2pBssInfo->eIntendOPMode == OP_MODE_ACCESS_POINT) -+ && IS_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ fgIsTransOut = TRUE; -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; -+ -+ DBGLOG(P2P, INFO, "p2pStateInit_IDLE GO Scan\n"); -+ *peNextState = P2P_STATE_REQING_CHANNEL; -+ -+ } else { -+#if 0 -+ else -+ if (IS_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { -+ -+ ASSERT((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) || -+ (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE)); -+ -+ prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; -+ -+ if (prChnlReqInfo->fgIsChannelRequested) { -+ /* Start a timer for return channel. */ -+ DBGLOG(P2P, TRACE, "start a GO channel timer.\n"); -+ } -+ -+ } -+#endif -+ cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), 5000); -+ } -+ -+ } while (FALSE); -+ -+ return fgIsTransOut; -+} /* p2pStateInit_IDLE */ -+ -+VOID p2pStateAbort_IDLE(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; -+ -+ if (prChnlReqInfo->fgIsChannelRequested) { -+ /* Release channel before timeout. */ -+ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); -+ } -+ -+ /* Stop timer for leaving this state. */ -+ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); -+ -+ } while (FALSE); -+ -+} /* p2pStateAbort_IDLE */ -+ -+VOID p2pStateInit_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_FSM_INFO_T prP2pFsmInfo) -+{ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ /* Store the original channel info. */ -+ prChnlReqInfo->ucOriChnlNum = prP2pBssInfo->ucPrimaryChannel; -+ prChnlReqInfo->eOriBand = prP2pBssInfo->eBand; -+ prChnlReqInfo->eOriChnlSco = prP2pBssInfo->eBssSCO; -+ -+ /* RX Probe Request would check primary channel. */ -+ prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucReqChnlNum; -+ prP2pBssInfo->eBand = prChnlReqInfo->eBand; -+ prP2pBssInfo->eBssSCO = prChnlReqInfo->eChnlSco; -+ -+ DBGLOG(P2P, TRACE, "start a channel on hand timer.\n"); -+ if (prP2pFsmInfo->eListenExted != P2P_DEV_EXT_LISTEN_ING) { -+ cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), -+ prChnlReqInfo->u4MaxInterval); -+ -+ kalP2PIndicateChannelReady(prAdapter->prGlueInfo, -+ prChnlReqInfo->u8Cookie, -+ prChnlReqInfo->ucReqChnlNum, -+ prChnlReqInfo->eBand, prChnlReqInfo->eChnlSco, prChnlReqInfo->u4MaxInterval); -+ } else -+ cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), -+ (P2P_EXT_LISTEN_TIME_MS - prChnlReqInfo->u4MaxInterval)); -+ } while (FALSE); -+ -+} /* p2pStateInit_CHNL_ON_HAND */ -+ -+VOID -+p2pStateAbort_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); -+ -+ /* Restore the original channel info. */ -+ prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucOriChnlNum; -+ prP2pBssInfo->eBand = prChnlReqInfo->eOriBand; -+ prP2pBssInfo->eBssSCO = prChnlReqInfo->eOriChnlSco; -+ -+ DBGLOG(P2P, INFO, "p2p state trans abort chann on hand, eListenExted: %d, eNextState: %d\n", -+ prP2pFsmInfo->eListenExted, eNextState); -+ if (prP2pFsmInfo->eListenExted != P2P_DEV_EXT_LISTEN_ING || -+ eNextState != P2P_STATE_CHNL_ON_HAND) { -+ /* Here maybe have a bug, when it's extlistening, a new remain_on_channel -+ was sent to driver? need to verify */ -+ prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN; -+ /* Indicate channel return. */ -+ kalP2PIndicateChannelExpired(prAdapter->prGlueInfo, &prP2pFsmInfo->rChnlReqInfo); -+ -+ /* Return Channel. */ -+ p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); -+ } -+ -+ } while (FALSE); -+} /* p2pStateAbort_CHNL_ON_HAND */ -+ -+VOID -+p2pStateAbort_REQING_CHANNEL(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL) && (eNextState < P2P_STATE_NUM)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ if (eNextState == P2P_STATE_IDLE) { -+ if (prP2pBssInfo->eIntendOPMode == OP_MODE_ACCESS_POINT) { -+ /* Intend to be AP. */ -+ /* Setup for AP mode. */ -+ p2pFuncStartGO(prAdapter, -+ prP2pBssInfo, -+ prP2pSpecificBssInfo->aucGroupSsid, -+ prP2pSpecificBssInfo->u2GroupSsidLen, -+ prP2pSpecificBssInfo->ucPreferredChannel, -+ prP2pSpecificBssInfo->eRfBand, -+ prP2pSpecificBssInfo->eRfSco, prP2pFsmInfo->fgIsApMode); -+ -+ } else { -+ /* Return Channel. */ -+ p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); -+ } -+ -+ } -+ -+ } while (FALSE); -+ -+} /* p2pStateInit_AP_CHANNEL_DETECT */ -+ -+VOID p2pStateInit_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo) -+{ -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ -+ prScanReqInfo->eScanType = SCAN_TYPE_PASSIVE_SCAN; -+ prScanReqInfo->eChannelSet = SCAN_CHANNEL_2G4; -+ prScanReqInfo->u2PassiveDewellTime = 50; /* 50ms for passive channel load detection */ -+ prScanReqInfo->fgIsAbort = TRUE; -+ prScanReqInfo->fgIsScanRequest = TRUE; -+ prScanReqInfo->ucNumChannelList = 0; -+ prScanReqInfo->u4BufLength = 0; -+ prScanReqInfo->rSsidStruct.ucSsidLen = 0; -+ -+ p2pFuncRequestScan(prAdapter, prScanReqInfo); -+ -+ } while (FALSE); -+ -+} /* p2pStateInit_AP_CHANNEL_DETECT */ -+ -+VOID -+p2pStateAbort_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ do { -+ -+ if (eNextState == P2P_STATE_REQING_CHANNEL) { -+ UINT_8 ucPreferedChnl = 0; -+ ENUM_BAND_T eBand = BAND_NULL; -+ ENUM_CHNL_EXT_T eSco = CHNL_EXT_SCN; -+ -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ /* Determine the channel for AP. */ -+ if (cnmPreferredChannel(prAdapter, &eBand, &ucPreferedChnl, &eSco) == FALSE) { -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ ucPreferedChnl = prP2pConnSettings->ucOperatingChnl; -+ if (ucPreferedChnl == 0) { -+ -+ if (scnQuerySparseChannel(prAdapter, &eBand, &ucPreferedChnl) == FALSE) { -+ -+ /* What to do? */ -+ ASSERT(FALSE); -+ /* TODO: Pick up a valid channel from channel list. */ -+ ucPreferedChnl = 1; -+ eBand = BAND_2G4; -+ } -+ } -+ } -+ -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; -+ -+ DBGLOG(P2P, INFO, "p2pStateAbort_AP_CHANNEL_DETECT GO Scan\n"); -+ prChnlReqInfo->ucReqChnlNum = prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl; -+ prChnlReqInfo->eBand = prP2pSpecificBssInfo->eRfBand = eBand; -+ prChnlReqInfo->eChnlSco = prP2pSpecificBssInfo->eRfSco = eSco; -+ } else { -+ p2pFuncCancelScan(prAdapter, &(prP2pFsmInfo->rScanReqInfo)); -+ } -+ -+ } while (FALSE); -+ -+} /* p2pStateAbort_AP_CHANNEL_DETECT */ -+ -+VOID p2pStateInit_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo) -+{ -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prScanReqInfo = &prP2pFsmInfo->rScanReqInfo; -+ -+ prScanReqInfo->fgIsScanRequest = TRUE; -+ -+ p2pFuncRequestScan(prAdapter, prScanReqInfo); -+ -+ } while (FALSE); -+ -+} /* p2pStateInit_SCAN */ -+ -+VOID p2pStateAbort_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ /* 1. Scan cancel. (Make sure the scan request is invalid. */ -+ p2pFuncCancelScan(prAdapter, &(prP2pFsmInfo->rScanReqInfo)); -+ -+ /* Scan done indication. */ -+ kalP2PIndicateScanDone(prAdapter->prGlueInfo, prP2pFsmInfo->rScanReqInfo.fgIsAbort); -+ } while (FALSE); -+ -+} /* p2pStateAbort_SCAN */ -+ -+VOID -+p2pStateInit_GC_JOIN(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_MSG_JOIN_REQ_T prJoinReqMsg = (P_MSG_JOIN_REQ_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && -+ (prP2pFsmInfo != NULL) && -+ (prP2pBssInfo != NULL) && (prJoinInfo != NULL) && (prBssDesc != NULL)); -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ if (prBssDesc->ucSSIDLen) { -+ COPY_SSID(prP2pConnSettings->aucSSID, -+ prP2pConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ } -+ /* Setup a join timer. */ -+ DBGLOG(P2P, TRACE, "Start a join init timer\n"); -+ cnmTimerStartTimer(prAdapter, -+ &(prAdapter->rP2pFsmTimeoutTimer), -+ (prP2pFsmInfo->u4GrantInterval - AIS_JOIN_CH_GRANT_THRESHOLD)); -+ -+ /* 2 <1> We are goin to connect to this BSS */ -+ prBssDesc->fgIsConnecting = TRUE; -+ -+ /* 2 <2> Setup corresponding STA_RECORD_T */ -+ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, -+ (prBssDesc->fgIsP2PPresent ? (STA_TYPE_P2P_GO) -+ : (STA_TYPE_LEGACY_AP)), NETWORK_TYPE_P2P_INDEX, prBssDesc); -+ -+ if (prStaRec == NULL) { -+ DBGLOG(P2P, TRACE, "Create station record fail\n"); -+ break; -+ } -+ -+ prJoinInfo->prTargetStaRec = prStaRec; -+ prJoinInfo->fgIsJoinComplete = FALSE; -+ prJoinInfo->u4BufLength = 0; -+ -+ /* 2 <2.1> Sync. to FW domain */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ if (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ prStaRec->fgIsReAssoc = FALSE; -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ switch (prP2pConnSettings->eAuthMode) { -+ case AUTH_MODE_OPEN: /* Note: Omit break here. */ -+ case AUTH_MODE_WPA: -+ case AUTH_MODE_WPA_PSK: -+ case AUTH_MODE_WPA2: -+ case AUTH_MODE_WPA2_PSK: -+ prJoinInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ break; -+ case AUTH_MODE_SHARED: -+ prJoinInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_SHARED_KEY; -+ break; -+ case AUTH_MODE_AUTO_SWITCH: -+ DBGLOG(P2P, LOUD, "JOIN INIT: eAuthMode == AUTH_MODE_AUTO_SWITCH\n"); -+ prJoinInfo->ucAvailableAuthTypes = (UINT_8) (AUTH_TYPE_OPEN_SYSTEM | -+ AUTH_TYPE_SHARED_KEY); -+ break; -+ default: -+ ASSERT(!(prP2pConnSettings->eAuthMode == AUTH_MODE_WPA_NONE)); -+ DBGLOG(P2P, ERROR, "JOIN INIT: Auth Algorithm : %d was not supported by JOIN\n", -+ prP2pConnSettings->eAuthMode); -+ /* TODO(Kevin): error handling ? */ -+ return; -+ } -+ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; -+ } else { -+ ASSERT(FALSE); -+ /* TODO: Shall we considering ROAMIN case for P2P Device?. */ -+ } -+ -+ /* 2 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes. */ -+ if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) { -+ -+ DBGLOG(P2P, TRACE, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); -+ -+ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; -+ } else if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { -+ -+ DBGLOG(P2P, TRACE, "JOIN INIT: Try to do Authentication with AuthType == SHARED_KEY.\n"); -+ -+ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; -+ } else if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION) { -+ -+ DBGLOG(P2P, TRACE, -+ "JOIN INIT: Try to do Authentication with AuthType == FAST_BSS_TRANSITION.\n"); -+ -+ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION; -+ } else { -+ ASSERT(0); -+ } -+ -+ /* 4 <5> Overwrite Connection Setting for eConnectionPolicy == ANY (Used by Assoc Req) */ -+ if (prBssDesc->ucSSIDLen) { -+ COPY_SSID(prJoinInfo->rSsidStruct.aucSsid, -+ prJoinInfo->rSsidStruct.ucSsidLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ } -+ /* 2 <5> Backup desired channel. */ -+ -+ /* 2 <6> Send a Msg to trigger SAA to start JOIN process. */ -+ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); -+ -+ if (!prJoinReqMsg) { -+ DBGLOG(P2P, TRACE, "Allocation Join Message Fail\n"); -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START; -+ prJoinReqMsg->ucSeqNum = ++prJoinInfo->ucSeqNumOfReqMsg; -+ prJoinReqMsg->prStaRec = prStaRec; -+ -+ /* TODO: Consider fragmentation info in station record. */ -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); -+ -+ } while (FALSE); -+ -+} /* p2pStateInit_GC_JOIN */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of JOIN Abort. Leave JOIN State & Abort JOIN. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pStateAbort_GC_JOIN(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ P_MSG_JOIN_ABORT_T prJoinAbortMsg = (P_MSG_JOIN_ABORT_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL) && (prJoinInfo != NULL)); -+ -+ if (prJoinInfo->fgIsJoinComplete == FALSE) { -+ -+ prJoinAbortMsg = -+ (P_MSG_JOIN_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_ABORT_T)); -+ if (!prJoinAbortMsg) { -+ DBGLOG(P2P, TRACE, "Fail to allocate join abort message buffer\n"); -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prJoinAbortMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_ABORT; -+ prJoinAbortMsg->ucSeqNum = prJoinInfo->ucSeqNumOfReqMsg; -+ prJoinAbortMsg->prStaRec = prJoinInfo->prTargetStaRec; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ } -+ -+ /* Stop Join Timer. */ -+ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); -+ -+ /* Release channel requested. */ -+ p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* p2pStateAbort_GC_JOIN */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c -new file mode 100644 -index 0000000000000..72fa52e761da5 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c -@@ -0,0 +1,915 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/privacy.c#1 -+*/ -+ -+/*! \file "privacy.c" -+ \brief This file including the protocol layer privacy function. -+ -+ This file provided the macros and functions library support for the -+ protocol layer security setting from rsn.c and nic_privacy.c -+ -+*/ -+ -+/* -+** Log: privacy.c -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 10 20 2011 terry.wu -+ * NULL -+ * Fix Hotspot deauth send failed. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 06 28 2011 tsaiyuan.hsu -+ * [WCXRP00000819] [MT6620 Wi-Fi][Driver] check if staRec is NULL or not in secCheckClassError -+ * check if staRec is NULL or not in secCheckClassError. -+ * -+ * 06 09 2011 tsaiyuan.hsu -+ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size -+ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T -+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 20 2010 wh.su -+ * -+ * adding the wapi code. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable RX management frame handling. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * adding the compiling flag for migration. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 05 28 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * fixed the ad-hoc wpa-none send non-encrypted frame issue. -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. -+ * -+ * 04 29 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * adjsut the pre-authentication code. -+ * -+ * 04 22 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * fixed the wpi same key id rx issue and fixed the remove wep key issue. -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Send Deauth for Class 3 Error and Leave Network Support -+ * -+ * 04 15 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * remove the assert code for allow ad-hoc pkt. -+ * -+ * 04 13 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the Klocwork error and refine the class error message. -+ * -+ * 03 04 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Code refine, and remove non-used code. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, -+ * and modify the security related callback function prototype. -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Refine the variable and parameter for security. -+ * -+ * 02 26 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * change the waning message shown level, and clear the global transmit flag for CMD INFRASTRUCTURE. -+ * -+ * 02 25 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * For support the WHQL test, do the remove key code refine. -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 12 25 2009 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM) -+ * * * * * * * * * MQM: BA handling -+ * * * * * * * * * TXM: Macros updates -+ * * * * * * * * * RXM: Macros/Duplicate Removal updates -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 11 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * modify the cmd with result return -+ * -+ * Dec 11 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * fixed the value not initialize issue -+ * -+ * Dec 10 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * change the cmd return type -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the function to update the auth mode and encryption status for cmd build connection -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some code for wapi mode -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the call to check the 4th and eapol error report frame -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * rename the function name -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the code for parsing the EAPoL frame, and do some code refine -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the class error check -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the cmd_802_11_pmkid code -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * doing some function rename, and adding the code for cmd CMD_ADD_REMOVE_KEY -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the clear pmkid function -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix eStaType check for AIS -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the ap selection related code -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_PRIVACY_MIGRATION -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to initialize the privacy-related -+* parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] ucNetTypeIdx Pointer to netowrk type index -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secInit(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIdx) -+{ -+ UINT_8 i; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("secInit"); -+ -+ ASSERT(prAdapter); -+ -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ prBssInfo->u4RsnSelectedGroupCipher = 0; -+ prBssInfo->u4RsnSelectedPairwiseCipher = 0; -+ prBssInfo->u4RsnSelectedAKMSuite = 0; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ -+ prBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; -+ prBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; -+ prBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]; -+ -+ prBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; -+ prBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; -+ prBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; -+#endif -+ -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[0].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_WEP40; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[1].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_TKIP; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[2].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_CCMP; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[3].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_WEP104; -+ -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[4].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_WEP40; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[5].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_TKIP; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[6].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_CCMP; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[7].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_WEP104; -+ -+ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[i].dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[0].dot11RSNAConfigAuthenticationSuite = -+ WPA_AKM_SUITE_NONE; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[1].dot11RSNAConfigAuthenticationSuite = -+ WPA_AKM_SUITE_802_1X; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[2].dot11RSNAConfigAuthenticationSuite = -+ WPA_AKM_SUITE_PSK; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[3].dot11RSNAConfigAuthenticationSuite = -+ RSN_AKM_SUITE_NONE; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[4].dot11RSNAConfigAuthenticationSuite = -+ RSN_AKM_SUITE_802_1X; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[5].dot11RSNAConfigAuthenticationSuite = -+ RSN_AKM_SUITE_PSK; -+ -+#if CFG_SUPPORT_802_11W -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[6].dot11RSNAConfigAuthenticationSuite = -+ RSN_AKM_SUITE_802_1X_SHA256; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[7].dot11RSNAConfigAuthenticationSuite = -+ RSN_AKM_SUITE_PSK_SHA256; -+#endif -+ -+ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i].dot11RSNAConfigAuthenticationSuiteEnabled = -+ FALSE; -+ } -+ -+ secClearPmkid(prAdapter); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisSpecBssInfo->rPreauthenticationTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) rsnIndicatePmkidCand, (ULONG) NULL); -+ -+#if CFG_SUPPORT_802_11W -+ cnmTimerInitTimer(prAdapter, -+ &prAisSpecBssInfo->rSaQueryTimer, (PFN_MGMT_TIMEOUT_FUNC) rsnStartSaQueryTimer, (ULONG) NULL); -+#endif -+ -+ prAisSpecBssInfo->fgCounterMeasure = FALSE; -+ prAisSpecBssInfo->ucWEPDefaultKeyID = 0; -+ -+#if 0 -+ for (i = 0; i < WTBL_SIZE; i++) { -+ g_prWifiVar->arWtbl[i].fgUsed = FALSE; -+ g_prWifiVar->arWtbl[i].prSta = NULL; -+ g_prWifiVar->arWtbl[i].ucNetTypeIdx = NETWORK_TYPE_INDEX_NUM; -+ -+ } -+ nicPrivacyInitialize((UINT_8) NETWORK_TYPE_INDEX_NUM); -+#endif -+} /* secInit */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "Rx Class Error" to SEC_FSM for -+* JOIN Module. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prSwRfb Pointer to the SW RFB. -+* -+* \return FALSE Class Error -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secCheckClassError(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_STA_RECORD_T prStaRec) -+{ -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ if (!prStaRec) -+ return FALSE; -+ -+ eNetTypeIndex = prStaRec->ucNetTypeIndex; -+ if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex)) -+ return FALSE; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]; -+ if ((STA_STATE_3 != prStaRec->ucStaState) && prBssInfo->fgIsNetAbsent == FALSE) { -+ /*(IS_AP_STA(prStaRec) || IS_CLIENT_STA(prStaRec))) { */ -+ -+#if 0 /* by scott's suggestions, do not put work-around in JB2,we need to find the root cause */ -+ /* work-around for CR ALPS00816361 */ -+ if (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ DBGLOG(RSN, INFO, -+ "p2p> skip to send Deauth to MAC:[%pM] for Rx Class 3.\n", -+ prStaRec->aucMacAddr); -+ return TRUE; -+ } -+#endif -+ -+ if (WLAN_STATUS_SUCCESS == authSendDeauthFrame(prAdapter, -+ prStaRec, -+ NULL, -+ REASON_CODE_CLASS_3_ERR, -+ (PFN_TX_DONE_HANDLER) NULL)) -+ -+ DBGLOG(RSN, INFO, "Send Deauth to [ %pM ] for Rx Class 3 Error.\n", -+ prStaRec->aucMacAddr); -+ else -+ DBGLOG(RSN, INFO, "Host sends Deauth to [ %pM ] for Rx Class 3 fail.\n", -+ prStaRec->aucMacAddr); -+ return FALSE; -+ } -+ -+ return secRxPortControlCheck(prAdapter, prSwRfb); -+} /* end of secCheckClassError() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to setting the sta port status. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prSta Pointer to the sta -+* \param[in] fgPortBlock The port status -+* -+* \retval none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secSetPortBlocked(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgPortBlock) -+{ -+ if (prSta == NULL) -+ return; -+ -+ prSta->fgPortBlock = fgPortBlock; -+ -+ DBGLOG(RSN, TRACE, -+ "The STA %pM port %s\n", prSta->aucMacAddr, fgPortBlock == TRUE ? "BLOCK" : " OPEN"); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to report the sta port status. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prSta Pointer to the sta -+* \param[out] fgPortBlock The port status -+* -+* \return TRUE sta exist, FALSE sta not exist -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secGetPortStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, OUT PBOOLEAN pfgPortStatus) -+{ -+ if (prSta == NULL) -+ return FALSE; -+ -+ *pfgPortStatus = prSta->fgPortBlock; -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to handle Peer device Tx Security process MSDU. -+* -+* \param[in] prMsduInfo pointer to the packet info pointer -+* -+* \retval TRUE Accept the packet -+* \retval FALSE Refuse the MSDU packet due port blocked -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN /* ENUM_PORT_CONTROL_RESULT */ -+secTxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(prStaRec); -+ -+ if (prStaRec) { -+ -+ /* Todo:: */ -+ if (prMsduInfo->fgIs802_1x) -+ return TRUE; -+ -+ if (prStaRec->fgPortBlock == TRUE) { -+ DBGLOG(SEC, TRACE, "Drop Tx packet due Port Control!\n"); -+ return FALSE; -+ } -+#if CFG_SUPPORT_WAPI -+ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) -+ return TRUE; -+#endif -+ if (IS_STA_IN_AIS(prStaRec)) { -+ if (!prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist && -+ (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED)) { -+ DBGLOG(SEC, TRACE, "Drop Tx packet due the key is removed!!!\n"); -+ return FALSE; -+ } -+ } -+ } -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to handle The Rx Security process MSDU. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prSWRfb SW rfb pinter -+* -+* \retval TRUE Accept the packet -+* \retval FALSE Refuse the MSDU packet due port control -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secRxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb) -+{ -+ ASSERT(prSWRfb); -+ -+#if 0 -+ /* whsu:Todo: Process MGMT and DATA */ -+ if (prSWRfb->prStaRec) { -+ if (prSWRfb->prStaRec->fgPortBlock == TRUE) { -+ if (1 /* prSWRfb->fgIsDataFrame and not 1x */ && -+ (g_prWifiVar->rConnSettings.eAuthMode >= AUTH_MODE_WPA)) { -+ /* DBGLOG(SEC, WARN, ("Drop Rx data due port control !\r\n")); */ -+ return TRUE; /* Todo: whsu FALSE; */ -+ } -+ /* if (!RX_STATUS_IS_PROTECT(prSWRfb->prRxStatus)) { */ -+ /* DBGLOG(RSN, WARN, ("Drop rcv non-encrypted data frame!\n")); */ -+ /* return FALSE; */ -+ /* } */ -+ } -+ } else { -+ } -+#endif -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine will enable/disable the cipher suite -+* -+* \param[in] prAdapter Pointer to the adapter object data area. -+* \param[in] u4CipherSuitesFlags flag for cipher suite -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secSetCipherSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4CipherSuitesFlags) -+{ -+ UINT_32 i; -+ P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY prEntry; -+ P_IEEE_802_11_MIB_T prMib; -+ -+ ASSERT(prAdapter); -+ -+ prMib = &prAdapter->rMib; -+ -+ ASSERT(prMib); -+ -+ if (u4CipherSuitesFlags == CIPHER_FLAG_NONE) { -+ /* Disable all the pairwise cipher suites. */ -+ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) -+ prMib->dot11RSNAConfigPairwiseCiphersTable[i].dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ -+ /* Update the group cipher suite. */ -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_NONE; -+ -+ return; -+ } -+ -+ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) { -+ prEntry = &prMib->dot11RSNAConfigPairwiseCiphersTable[i]; -+ -+ switch (prEntry->dot11RSNAConfigPairwiseCipher) { -+ case WPA_CIPHER_SUITE_WEP40: -+ case RSN_CIPHER_SUITE_WEP40: -+ if (u4CipherSuitesFlags & CIPHER_FLAG_WEP40) -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; -+ else -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ break; -+ -+ case WPA_CIPHER_SUITE_TKIP: -+ case RSN_CIPHER_SUITE_TKIP: -+ if (u4CipherSuitesFlags & CIPHER_FLAG_TKIP) -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; -+ else -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ break; -+ -+ case WPA_CIPHER_SUITE_CCMP: -+ case RSN_CIPHER_SUITE_CCMP: -+ if (u4CipherSuitesFlags & CIPHER_FLAG_CCMP) -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; -+ else -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ break; -+ -+ case WPA_CIPHER_SUITE_WEP104: -+ case RSN_CIPHER_SUITE_WEP104: -+ if (u4CipherSuitesFlags & CIPHER_FLAG_WEP104) -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; -+ else -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ break; -+ default: -+ break; -+ } -+ } -+ -+ /* Update the group cipher suite. */ -+ if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_CCMP, &i)) -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_CCMP; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_TKIP, &i)) -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_TKIP; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP104, &i)) -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_WEP104; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP40, &i)) -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_WEP40; -+ else -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_NONE; -+ -+} /* secSetCipherSuite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to handle The 2nd Tx EAPoL Frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prMsduInfo pointer to the packet info pointer -+* \param[in] pucPayload pointer to the 1x hdr -+* \param[in] u2PayloadLen the 1x payload length -+* -+* \retval TRUE Accept the packet -+* \retval FALSE Refuse the MSDU packet due port control -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+secProcessEAPOL(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec, IN PUINT_8 pucPayload, IN UINT_16 u2PayloadLen) -+{ -+ P_EAPOL_KEY prEapol = (P_EAPOL_KEY) NULL; -+ P_IEEE_802_1X_HDR pr1xHdr; -+ UINT_16 u2KeyInfo; -+ -+ ASSERT(prMsduInfo); -+ ASSERT(prStaRec); -+ -+ /* prStaRec = &(g_arStaRec[prMsduInfo->ucStaRecIndex]); */ -+ ASSERT(prStaRec); -+ -+ if (prStaRec && IS_AP_STA(prStaRec)) { -+ pr1xHdr = (P_IEEE_802_1X_HDR) pucPayload; -+ if ((pr1xHdr->ucType == 3) /* EAPoL key */ && ((u2PayloadLen - 4) > sizeof(EAPOL_KEY))) { -+ prEapol = (P_EAPOL_KEY) ((PUINT_32) (pucPayload + 4)); -+ WLAN_GET_FIELD_BE16(prEapol->aucKeyInfo, &u2KeyInfo); -+ if ((prEapol->ucType == 254) && (u2KeyInfo & MASK_2ND_EAPOL)) { -+ if (u2KeyInfo & WPA_KEY_INFO_SECURE) { -+ /* 4th EAPoL check at secHandleTxDoneCallback() */ -+ /* DBGLOG(RSN, TRACE, ("Tx 4th EAPoL frame\r\n")); */ -+ } else if (u2PayloadLen == 123 /* Not include LLC */) { -+ DBGLOG(RSN, INFO, "Tx 2nd EAPoL frame\r\n"); -+ secFsmEvent2ndEapolTx(prAdapter, prStaRec); -+ } -+ } -+ } -+ } -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will handle the 4th EAPoL Tx done and mic Error Report frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pMsduInfo Pointer to the Msdu Info -+* \param[in] rStatus The Tx done status -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+secHandleTxDoneCallback(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec, IN WLAN_STATUS rStatus) -+{ -+ PUINT_8 pucPayload; -+ P_IEEE_802_1X_HDR pr1xHdr = (P_IEEE_802_1X_HDR) NULL; -+ P_EAPOL_KEY prEapol = (P_EAPOL_KEY) NULL; -+ UINT_16 u2KeyInfo; -+ UINT_16 u2PayloadLen; -+ -+ DEBUGFUNC("secHandleTxDoneCallback"); -+ -+ ASSERT(prMsduInfo); -+ /* Todo:: Notice if using the TX free immediate after send to firmware, the payload may not correcttly!!!! */ -+ -+ ASSERT(prStaRec); -+ -+ /* Todo:: This call back may not need because the order of set key and send 4th 1x can be make sure */ -+ /* Todo:: Notice the LLC offset */ -+#if 1 -+ pucPayload = (PUINT_8) prMsduInfo->prPacket; -+ ASSERT(pucPayload); -+ -+ u2PayloadLen = prMsduInfo->u2FrameLength; -+ -+ if (0 /* prMsduInfo->fgIs1xFrame */) { -+ -+ if (prStaRec && IS_AP_STA(prStaRec)) { -+ pr1xHdr = (P_IEEE_802_1X_HDR) (PUINT_32) (pucPayload + 8); -+ if ((pr1xHdr->ucType == 3) /* EAPoL key */ && ((u2PayloadLen - 4) > sizeof(EAPOL_KEY))) { -+ prEapol = (P_EAPOL_KEY) (PUINT_32) (pucPayload + 12); -+ WLAN_GET_FIELD_BE16(prEapol->aucKeyInfo, &u2KeyInfo); -+ if ((prEapol->ucType == 254) && (u2KeyInfo & MASK_2ND_EAPOL)) { -+ if (prStaRec->rSecInfo.fg2nd1xSend == TRUE -+ && u2PayloadLen == -+ 107 /* include LLC *//* u2KeyInfo & WPA_KEY_INFO_SECURE */) { -+ DBGLOG(RSN, INFO, "Tx 4th EAPoL frame\r\n"); -+ secFsmEvent4ndEapolTxDone(prAdapter, prStaRec); -+ } else if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgCheckEAPoLTxDone) { -+ DBGLOG(RSN, INFO, "Tx EAPoL Error report frame\r\n"); -+ /* secFsmEventEapolTxDone(prAdapter, (UINT_32)prMsduInfo->prStaRec); */ -+ } -+ } -+ } -+ } -+ -+ } -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to initialize the pmkid parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secClearPmkid(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("secClearPmkid"); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ DBGLOG(RSN, TRACE, "secClearPmkid\n"); -+ prAisSpecBssInfo->u4PmkidCandicateCount = 0; -+ prAisSpecBssInfo->u4PmkidCacheCount = 0; -+ kalMemZero((PVOID) prAisSpecBssInfo->arPmkidCandicate, sizeof(PMKID_CANDICATE_T) * CFG_MAX_PMKID_CACHE); -+ kalMemZero((PVOID) prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Whether WPA, or WPA2 but not WPA-None is enabled. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* \retval BOOLEAN -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secRsnKeyHandshakeEnabled(IN P_ADAPTER_T prAdapter) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ ASSERT(prAdapter); -+ -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ -+ ASSERT(prConnSettings); -+ -+ ASSERT(prConnSettings->eEncStatus < ENUM_ENCRYPTION3_KEY_ABSENT); -+ -+ if (prConnSettings->eEncStatus == ENUM_ENCRYPTION_DISABLED) -+ return FALSE; -+ -+ ASSERT(prConnSettings->eAuthMode < AUTH_MODE_NUM); -+ if ((prConnSettings->eAuthMode >= AUTH_MODE_WPA) && (prConnSettings->eAuthMode != AUTH_MODE_WPA_NONE)) -+ return TRUE; -+ -+ return FALSE; -+} /* secRsnKeyHandshakeEnabled */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Return whether the transmit key alread installed. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prSta Pointer the sta record -+* -+* \retval TRUE Default key or Transmit key installed -+* FALSE Default key or Transmit key not installed -+* -+* \note: -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secTransmitKeyExist(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ ASSERT(prSta); -+ -+ if (prSta->fgTransmitKeyExist) -+ return TRUE; -+ else -+ return FALSE; -+} /* secTransmitKeyExist */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Whether 802.11 privacy is enabled. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* \retval BOOLEAN -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secEnabledInAis(IN P_ADAPTER_T prAdapter) -+{ -+ DEBUGFUNC("secEnabled"); -+ -+ ASSERT(prAdapter->rWifiVar.rConnSettings.eEncStatus < ENUM_ENCRYPTION3_KEY_ABSENT); -+ -+ switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) { -+ case ENUM_ENCRYPTION_DISABLED: -+ return FALSE; -+ case ENUM_ENCRYPTION1_ENABLED: -+ case ENUM_ENCRYPTION2_ENABLED: -+ case ENUM_ENCRYPTION3_ENABLED: -+ return TRUE; -+ default: -+ DBGLOG(RSN, TRACE, "Unknown encryption setting %d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus); -+ break; -+ } -+ return FALSE; -+} /* secEnabled */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the privacy bit at mac header for TxM -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prMsdu the msdu for known the sta record -+* -+* \return TRUE the privacy need to set -+* FALSE the privacy no need to set -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secIsProtectedFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsdu, IN P_STA_RECORD_T prStaRec) -+{ -+ ASSERT(prAdapter); -+ -+ ASSERT(prMsdu); -+ -+ ASSERT(prStaRec); -+ /* prStaRec = &(g_arStaRec[prMsdu->ucStaRecIndex]); */ -+ -+ if (prStaRec == NULL) { -+ if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist) -+ return TRUE; -+ return FALSE; /* No privacy bit */ -+ } -+ -+ /* Todo:: */ -+ if (0 /* prMsdu->fgIs1xFrame */) { -+ if (IS_STA_IN_AIS(prStaRec) && prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) { -+ DBGLOG(RSN, LOUD, "For AIS Legacy 1x, always not encryped\n"); -+ return FALSE; -+ } else if (!prStaRec->fgTransmitKeyExist) { -+ DBGLOG(RSN, LOUD, "1x Not Protected.\n"); -+ return FALSE; -+ } else if (prStaRec->rSecInfo.fgKeyStored) { -+ DBGLOG(RSN, LOUD, "1x not Protected due key stored!\n"); -+ return FALSE; -+ } -+ DBGLOG(RSN, LOUD, "1x Protected.\n"); -+ return TRUE; -+ } -+ if (!prStaRec->fgTransmitKeyExist) { -+ /* whsu , check for AIS only */ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA && -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist) { -+ DBGLOG(RSN, LOUD, "Protected\n"); -+ return TRUE; -+ } -+ } else { -+ DBGLOG(RSN, LOUD, "Protected.\n"); -+ return TRUE; -+ } -+ -+ /* No sec or key is removed!!! */ -+ return FALSE; -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c -new file mode 100644 -index 0000000000000..fd0a8772a6665 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c -@@ -0,0 +1,497 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rate.c#1 -+*/ -+ -+/*! \file "rate.c" -+ \brief This file contains the transmission rate handling routines. -+ -+ This file contains the transmission rate handling routines for setting up -+ ACK/CTS Rate, Highest Tx Rate, Lowest Tx Rate, Initial Tx Rate and do -+ conversion between Rate Set and Data Rates. -+*/ -+ -+/* -+** Log: rate.c -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add rate.c. -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update comments -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix DBGLOG -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** \main\maintrunk.MT5921\12 2008-12-19 17:19:32 GMT mtk01461 -+** Fix the problem that do not ASSERT the length of Supported Rate IE == 8 -+** \main\maintrunk.MT5921\11 2008-12-01 18:17:42 GMT mtk01088 -+** fixed the lint "possible using null pointer" warning -+** \main\maintrunk.MT5921\10 2008-08-20 00:16:36 GMT mtk01461 -+** Update for Driver Review -+** \main\maintrunk.MT5921\9 2008-04-13 21:17:13 GMT mtk01461 -+** Revise GEN Link Speed OID -+** \main\maintrunk.MT5921\8 2008-03-28 10:40:13 GMT mtk01461 -+** Add rateGetRateSetFromDataRates() for set desired rate OID -+** \main\maintrunk.MT5921\7 2008-03-26 09:16:20 GMT mtk01461 -+** Add adopt operational rate as ACK rate if BasicRateSet was not found -+** Add comments -+** \main\maintrunk.MT5921\6 2008-02-21 15:01:39 GMT mtk01461 -+** Add initial rate according rx signal quality support -+** \main\maintrunk.MT5921\5 2008-01-07 15:06:44 GMT mtk01461 -+** Fix typo of rate adaptation of CtrlResp Frame -+** \main\maintrunk.MT5921\4 2007-10-25 18:05:12 GMT mtk01461 -+** Add VOIP SCAN Support & Refine Roaming -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* The list of valid data rates. */ -+const UINT_8 aucDataRate[] = { -+ RATE_1M, /* RATE_1M_INDEX = 0 */ -+ RATE_2M, /* RATE_2M_INDEX */ -+ RATE_5_5M, /* RATE_5_5M_INDEX */ -+ RATE_11M, /* RATE_11M_INDEX */ -+ RATE_22M, /* RATE_22M_INDEX */ -+ RATE_33M, /* RATE_33M_INDEX */ -+ RATE_6M, /* RATE_6M_INDEX */ -+ RATE_9M, /* RATE_9M_INDEX */ -+ RATE_12M, /* RATE_12M_INDEX */ -+ RATE_18M, /* RATE_18M_INDEX */ -+ RATE_24M, /* RATE_24M_INDEX */ -+ RATE_36M, /* RATE_36M_INDEX */ -+ RATE_48M, /* RATE_48M_INDEX */ -+ RATE_54M, /* RATE_54M_INDEX */ -+ RATE_HT_PHY /* RATE_HT_PHY_INDEX */ -+}; -+ -+static const UINT_8 aucDefaultAckCtsRateIndex[RATE_NUM] = { -+ RATE_1M_INDEX, /* RATE_1M_INDEX = 0 */ -+ RATE_2M_INDEX, /* RATE_2M_INDEX */ -+ RATE_5_5M_INDEX, /* RATE_5_5M_INDEX */ -+ RATE_11M_INDEX, /* RATE_11M_INDEX */ -+ RATE_1M_INDEX, /* RATE_22M_INDEX - Not supported */ -+ RATE_1M_INDEX, /* RATE_33M_INDEX - Not supported */ -+ RATE_6M_INDEX, /* RATE_6M_INDEX */ -+ RATE_6M_INDEX, /* RATE_9M_INDEX */ -+ RATE_12M_INDEX, /* RATE_12M_INDEX */ -+ RATE_12M_INDEX, /* RATE_18M_INDEX */ -+ RATE_24M_INDEX, /* RATE_24M_INDEX */ -+ RATE_24M_INDEX, /* RATE_36M_INDEX */ -+ RATE_24M_INDEX, /* RATE_48M_INDEX */ -+ RATE_24M_INDEX /* RATE_54M_INDEX */ -+}; -+ -+const BOOLEAN afgIsOFDMRate[RATE_NUM] = { -+ FALSE, /* RATE_1M_INDEX = 0 */ -+ FALSE, /* RATE_2M_INDEX */ -+ FALSE, /* RATE_5_5M_INDEX */ -+ FALSE, /* RATE_11M_INDEX */ -+ FALSE, /* RATE_22M_INDEX - Not supported */ -+ FALSE, /* RATE_33M_INDEX - Not supported */ -+ TRUE, /* RATE_6M_INDEX */ -+ TRUE, /* RATE_9M_INDEX */ -+ TRUE, /* RATE_12M_INDEX */ -+ TRUE, /* RATE_18M_INDEX */ -+ TRUE, /* RATE_24M_INDEX */ -+ TRUE, /* RATE_36M_INDEX */ -+ TRUE, /* RATE_48M_INDEX */ -+ TRUE /* RATE_54M_INDEX */ -+}; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Convert the given Supported Rate & Extended Supported Rate IE to the -+* Operational Rate Set and Basic Rate Set, and also check if any Basic -+* Rate Code is unknown by driver. -+* -+* @param[in] prIeSupportedRate Pointer to the Supported Rate IE -+* @param[in] prIeExtSupportedRate Pointer to the Ext Supported Rate IE -+* @param[out] pu2OperationalRateSet Pointer to the Operational Rate Set -+* @param[out] pu2BSSBasicRateSet Pointer to the Basic Rate Set -+* @param[out] pfgIsUnknownBSSBasicRate Pointer to a Flag to indicate that Basic -+* Rate Set has unknown Rate Code -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rateGetRateSetFromIEs(IN P_IE_SUPPORTED_RATE_T prIeSupportedRate, -+ IN P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate, -+ OUT PUINT_16 pu2OperationalRateSet, -+ OUT PUINT_16 pu2BSSBasicRateSet, OUT PBOOLEAN pfgIsUnknownBSSBasicRate) -+{ -+ UINT_16 u2OperationalRateSet = 0; -+ UINT_16 u2BSSBasicRateSet = 0; -+ BOOLEAN fgIsUnknownBSSBasicRate = FALSE; -+ UINT_8 ucRate; -+ UINT_32 i, j; -+ -+ ASSERT(pu2OperationalRateSet); -+ ASSERT(pu2BSSBasicRateSet); -+ ASSERT(pfgIsUnknownBSSBasicRate); -+ -+ if (prIeSupportedRate) { -+ /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8. -+ * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B), -+ * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" -+ */ -+ /* ASSERT(prIeSupportedRate->ucLength <= ELEM_MAX_LEN_SUP_RATES); */ -+ ASSERT(prIeSupportedRate->ucLength <= RATE_NUM); -+ -+ for (i = 0; i < prIeSupportedRate->ucLength; i++) { -+ ucRate = prIeSupportedRate->aucSupportedRates[i] & RATE_MASK; -+ -+ /* Search all valid data rates */ -+ for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) { -+ if (ucRate == aucDataRate[j]) { -+ u2OperationalRateSet |= BIT(j); -+ -+ if (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT) -+ u2BSSBasicRateSet |= BIT(j); -+ -+ break; -+ } -+ } -+ -+ if ((j == sizeof(aucDataRate) / sizeof(UINT_8)) && -+ (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT)) { -+ fgIsUnknownBSSBasicRate = TRUE; /* A data rate not list in the aucDataRate[] */ -+ } -+ } -+ } -+ -+ if (prIeExtSupportedRate) { -+ /* ASSERT(prIeExtSupportedRate->ucLength <= ELEM_MAX_LEN_EXTENDED_SUP_RATES); */ -+ -+ for (i = 0; i < prIeExtSupportedRate->ucLength; i++) { -+ ucRate = prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_MASK; -+ -+ /* Search all valid data rates */ -+ for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) { -+ if (ucRate == aucDataRate[j]) { -+ u2OperationalRateSet |= BIT(j); -+ -+ if (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT) -+ u2BSSBasicRateSet |= BIT(j); -+ -+ break; -+ } -+ } -+ -+ if ((j == sizeof(aucDataRate) / sizeof(UINT_8)) && -+ (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT)) { -+ fgIsUnknownBSSBasicRate = TRUE; /* A data rate not list in the aucDataRate[] */ -+ } -+ } -+ } -+ -+ *pu2OperationalRateSet = u2OperationalRateSet; -+ *pu2BSSBasicRateSet = u2BSSBasicRateSet; -+ *pfgIsUnknownBSSBasicRate = fgIsUnknownBSSBasicRate; -+ -+ return; -+ -+} /* end of rateGetRateSetFromIEs() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Convert the given Operational Rate Set & Basic Rate Set to the Rate Code -+* Format for used in (Ext)Supportec Rate IE. -+* -+* @param[in] u2OperationalRateSet Operational Rate Set -+* @param[in] u2BSSBasicRateSet Basic Rate Set -+* @param[out] pucDataRates Pointer to the Data Rate Buffer -+* @param[out] pucDataRatesLen Pointer to the Data Rate Buffer Length -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rateGetDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet, -+ IN UINT_16 u2BSSBasicRateSet, OUT PUINT_8 pucDataRates, OUT PUINT_8 pucDataRatesLen) -+{ -+ UINT_32 i, j; -+ -+ ASSERT(pucDataRates); -+ ASSERT(pucDataRatesLen); -+ -+ ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet)); -+ -+ for (i = RATE_1M_INDEX, j = 0; i < RATE_NUM; i++) { -+ if (u2OperationalRateSet & BIT(i)) { -+ -+ *(pucDataRates + j) = aucDataRate[i]; -+ -+ if (u2BSSBasicRateSet & BIT(i)) -+ *(pucDataRates + j) |= RATE_BASIC_BIT; -+ -+ j++; -+ } -+ } -+ -+ *pucDataRatesLen = (UINT_8) j; -+ -+ return; -+ -+} /* end of rateGetDataRatesFromRateSet() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Get the highest rate from given Rate Set. -+* -+* \param[in] u2RateSet Rate Set -+* \param[out] pucHighestRateIndex Pointer to buffer of the Highest Rate Index -+* -+* \retval TRUE Highest Rate Index was found -+* \retval FALSE Highest Rate Index was not found -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rateGetHighestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucHighestRateIndex) -+{ -+ INT_32 i; -+ -+ ASSERT(pucHighestRateIndex); -+ -+ for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) { -+ if (u2RateSet & BIT(i)) { -+ *pucHighestRateIndex = (UINT_8) i; -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+ -+} /* end of rateGetHighestRateIndexFromRateSet() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Get the lowest rate from given Rate Set. -+* -+* \param[in] u2RateSet Rate Set -+* \param[out] pucLowestRateIndex Pointer to buffer of the Lowest Rate Index -+* -+* \retval TRUE Lowest Rate Index was found -+* \retval FALSE Lowest Rate Index was not found -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rateGetLowestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucLowestRateIndex) -+{ -+ UINT_32 i; -+ -+ ASSERT(pucLowestRateIndex); -+ -+ for (i = RATE_1M_INDEX; i <= RATE_54M_INDEX; i++) { -+ if (u2RateSet & BIT(i)) { -+ *pucLowestRateIndex = (UINT_8) i; -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+ -+} /* end of rateGetLowestRateIndexFromRateSet() */ -+ -+#if 0 /* NOTE(Kevin): For reference */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Convert the given Data Rates to the Rate Set. -+* -+* \param[in] pucDataRates Pointer to the Data Rates -+* \param[in] ucDataRatesLen Length of given Data Rates -+* \param[out] pu2RateSet Pointer to the Rate Set -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rateGetRateSetFromDataRates(IN PUINT_8 pucDataRates, IN UINT_8 ucDataRatesLen, OUT PUINT_16 pu2RateSet) -+{ -+ UINT_16 u2RateSet = 0; -+ UINT_8 ucRate; -+ UINT_32 i, j; -+ -+ ASSERT(pucDataRates); -+ ASSERT(pu2RateSet); -+ -+ if (pucDataRates) { -+ for (i = 0; i < ucDataRatesLen; i++) { -+ ucRate = pucDataRates[i] & RATE_MASK; -+ -+ /* Search all valid data rates */ -+ for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) { -+ if (ucRate == aucDataRate[j]) { -+ u2RateSet |= BIT(j); -+ break; -+ } -+ } -+ } -+ } -+ -+ *pu2RateSet = u2RateSet; -+ -+ return; -+ -+} /* end of rateGetRateSetFromDataRates() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Parse the Operational Rate Set and Basic Rate Set to get the corresponding -+* ACK/CTS(Respnose) TX Rates. -+* -+* \param[in] u2OperationalRateSet Operational Rate Set -+* \param[in] u2BSSBasicRateSet Basic Rate Set -+* \param[out] aucAckCtsRateIndex Pointer to the Ack/Cts Data Rate Buffer -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rateSetAckCtsDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet, -+ IN UINT_16 u2BSSBasicRateSet, IN OUT UINT_8 aucAckCtsRateIndex[]) -+{ -+ INT_32 i, j; -+ -+ ASSERT(aucAckCtsRateIndex); -+ ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet)); -+ -+ /* Setup default ACK/CTS response rate */ -+ kalMemCopy(aucAckCtsRateIndex, (PVOID) aucDefaultAckCtsRateIndex, sizeof(aucDefaultAckCtsRateIndex)); -+ -+ for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) { -+ if (u2OperationalRateSet & BIT(i)) { -+ for (j = i; j >= RATE_1M_INDEX; j--) { -+ if (u2BSSBasicRateSet & BIT(j)) { -+ /* Reply ACK Frame at the same Modulation Scheme. */ -+ if ((afgIsOFDMRate[i] && afgIsOFDMRate[j]) || -+ (!afgIsOFDMRate[i] && !afgIsOFDMRate[j])) -+ aucAckCtsRateIndex[i] = (UINT_8) j; -+ break; -+ } -+ } -+ -+ /* NOTE(Kevin 2008/03/25): Following code is used for those AP which has -+ * NULL BasicRateSet. -+ * e.g. If input Operational Rate Set = [18M 12M 9M], Basic Rate Set = NULL. -+ * Originally we'll get Ack Rate for [18M 12M 9M] is [12M 12M "6M"]. -+ * Now we'll get Ack Rate for [18M 12M 9M] is [12M 12M 9M], -+ * The Ack Rate for Tx Rates which are not list in Operational Rate Set is still -+ * use highest mandatory rate as default. -+ */ -+ if (j < RATE_1M_INDEX) { /* The ACK/CTS rate was not found in BasicRateSet */ -+ if (!(BIT(aucAckCtsRateIndex[i]) & u2OperationalRateSet)) -+ aucAckCtsRateIndex[i] = (UINT_8) i; -+ } -+ } -+ } -+ -+ return; -+ -+} /* end of rateSetAckCtsDataRatesFromRateSet() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Get the proper initial rate from Rate Set according to given RCPI value -+* -+* \param[in] u2RateSet Rate Set -+* \param[in] rRcpi RCPI value from AP or Peer STA -+* \param[out] pucInitialRateIndex Pointer to buffer of the initial Rate Index -+* -+* \retval TRUE Initial Rate Index was found -+* \retval FALSE Initial Rate Index was not found -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rateGetBestInitialRateIndex(IN UINT_16 u2RateSet, IN RCPI rRcpi, OUT PUINT_8 pucInitialRateIndex) -+{ -+ UINT_16 u2InitRateSet; -+ INT_32 i; -+ -+ ASSERT(pucInitialRateIndex); -+ -+ DBGLOG(MGT, TRACE, "rRcpi = %d\n", rRcpi); -+ -+ if (rRcpi >= RCPI_100) { /* Best Signal */ -+ u2InitRateSet = INITIAL_RATE_SET(RCPI_100); -+ } else if (rRcpi >= RCPI_80) { /* Better Signal */ -+ u2InitRateSet = INITIAL_RATE_SET(RCPI_80); -+ } else if (rRcpi >= RCPI_60) { /* Good Signal */ -+ u2InitRateSet = INITIAL_RATE_SET(RCPI_60); -+ } else { /* Worse Signal */ -+ /* NOTE(Kevin): If return FALSE, we should assign the BSS Basic Rate Index -+ * (prBssInfo->ucBasicRateIndex) to the initial rate. It was determined in -+ * function - bssUpdateTxRateForControlFrame(). -+ */ -+ return FALSE; -+ } -+ -+ u2RateSet &= u2InitRateSet; -+ -+ for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) { -+ if (u2RateSet & BIT(i)) { -+ *pucInitialRateIndex = (UINT_8) i; -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+ -+} /* end of rateGetBestInitialRateIndex() */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c -new file mode 100644 -index 0000000000000..244346983f405 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c -@@ -0,0 +1,1858 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm.c#2 -+*/ -+ -+/*! \file "rlm.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: rlm.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Check length HT cap IE about RX associate request frame -+ * -+ * 11 10 2011 cm.chang -+ * NULL -+ * Modify debug message for XLOG -+ * -+ * 11 08 2011 cm.chang -+ * NULL -+ * Add RLM and CNM debug message for XLOG -+ * -+ * 11 03 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * Fix preamble type of STA mode -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * Not send ERP IE if peer STA is 802.11b-only -+ * -+ * 10 11 2011 cm.chang -+ * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter -+ * Ignore HT OP IE if its length field is not valid -+ * -+ * 09 28 2011 cm.chang -+ * NULL -+ * Add length check to reduce possibility to adopt wrong IE -+ * -+ * 09 20 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * Handle client mode about preamble type and slot time -+ * -+ * 09 01 2011 cm.chang -+ * [WCXRP00000971] [MT6620 Wi-Fi][Driver][FW] Not set Beacon timeout interval when CPTT -+ * Final channel number only adopts the field from assoc response -+ * -+ * 06 10 2011 cm.chang -+ * [WCXRP00000773] [MT6620 Wi-Fi][Driver] Workaround some AP fill primary channel field with its secondary channel -+ * If DS IE exists, ignore the primary channel field in HT OP IE -+ * -+ * 05 03 2011 cm.chang -+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number -+ * Fix compiling error -+ * -+ * 05 02 2011 cm.chang -+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number -+ * Refine range of valid channel number -+ * -+ * 05 02 2011 cm.chang -+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number -+ * Check if channel is valided before record ing BSS channel -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 03 29 2011 cm.chang -+ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning -+ * As CR title -+ * -+ * 01 24 2011 cm.chang -+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode -+ * and stop ampdu timer when sta_rec is freed -+ * Process received 20/40 coexistence action frame for AP mode -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver -+ * create branch for Wi-Fi driver v1.1 -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 10 15 2010 cm.chang -+ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash. -+ * Add exception handle when no mgmt buffer in free build -+ * -+ * 10 08 2010 cm.chang -+ * NULL -+ * When 20M only setting, ignore OBSS IE -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Change conditional compiling options for BOW -+ * -+ * 09 10 2010 cm.chang -+ * NULL -+ * Always update Beacon content if FW sync OBSS info -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Temporary add rlmUpdateParamByStaForBow() and rlmBssInitForBow(). -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Add CFG_ENABLE_BT_OVER_WIFI. -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Fix compile error while enabling WiFi Direct function. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 06 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fix channel ID definition in RFB status to primary channel instead of center channel -+ * -+ * 06 02 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add TX short GI compiling option -+ * -+ * 06 02 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Roll back to remove CFG_SUPPORT_BCM_TEST. -+ * -+ * 06 01 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Update BCM Test and RW configuration. -+ * -+ * 05 31 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add some compiling options to control 11n functions -+ * -+ * 05 28 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Set RTS threshold of 2K bytes initially -+ * -+ * 05 18 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Ad-hoc Beacon should not carry HT OP and OBSS IEs -+ * -+ * 05 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Process 20/40 coexistence public action frame in AP mode -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft support for 20/40M bandwidth for AP mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 04 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Utilize status of swRfb to know channel number and band -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Different invoking order for WTBL entry of associated AP -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add virtual test for OBSS scan -+ * -+ * 04 02 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Process Beacon only ready for infra STA now -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Not carry HT cap when being associated with b/g only AP -+ * -+ * 03 24 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * fixed some WHQL testing error. -+ * -+ * 03 15 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Provide draft measurement and quiet functions -+ * -+ * 03 09 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * If bss is not 11n network, zero WTBL HT parameters -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * To support CFG_SUPPORT_BCM_STP -+ * -+ * 03 02 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Generate HT IE only depending on own phyTypeSet -+ * -+ * 03 02 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Not fill HT related IE if BssInfo does not include 11n phySet -+ * -+ * 03 01 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * To store field AMPDU Parameters in STA_REC -+ * -+ * 02 26 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Enable RDG RX, but disable RDG TX for IOT and LongNAV -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Modify the parameter of rlmRecAssocRspHtInfo function -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix prBssInfo->ucPrimaryChannel handle for assoc resp -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add some function to process HT operation -+ * -+ * Nov 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Call rlmStatisticsInit() to handle MIB counters -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static VOID rlmFillHtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); -+ -+static VOID rlmFillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); -+ -+static VOID rlmFillHtOpIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); -+ -+static UINT_8 rlmRecIeInfoForClient(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+static BOOLEAN -+rlmRecBcnFromNeighborForClient(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+static BOOLEAN -+rlmRecBcnInfoForClient(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+static VOID rlmBssReset(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmFsmEventInit(P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* Note: assume TIMER_T structures are reset to zero or stopped -+ * before invoking this function. -+ */ -+ -+ /* Initialize OBSS FSM */ -+ rlmObssInit(prAdapter); -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ rlmDomainCheckCountryPowerLimitTable(prAdapter); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmFsmEventUninit(P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prBssInfo; -+ UINT_8 ucNetIdx; -+ -+ ASSERT(prAdapter); -+ -+ RLM_NET_FOR_EACH(ucNetIdx) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx]; -+ ASSERT(prBssInfo); -+ -+ /* Note: all RLM timers will also be stopped. -+ * Now only one OBSS scan timer. -+ */ -+ rlmBssReset(prAdapter, prBssInfo); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe request, association request -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmReqGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && -+ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) -+ rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe request, association request -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmReqGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && -+ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) -+ rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo); -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ else if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) -+ hs20FillExtCapIE(prAdapter, prBssInfo, prMsduInfo); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe response (GO, IBSS) and association response -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmRspGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) -+ rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe response (GO, IBSS) and association response -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmRspGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) -+ rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe response (GO, IBSS) and association response -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmRspGenerateHtOpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) -+ rlmFillHtOpIE(prAdapter, prBssInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe response (GO, IBSS) and association response -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmRspGenerateErpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ P_IE_ERP_T prErpIe; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ if (RLM_NET_IS_11GN(prBssInfo) && prBssInfo->eBand == BAND_2G4 && -+ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11GN))) { -+ prErpIe = (P_IE_ERP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+ /* Add ERP IE */ -+ prErpIe->ucId = ELEM_ID_ERP_INFO; -+ prErpIe->ucLength = 1; -+ -+ prErpIe->ucERP = prBssInfo->fgObssErpProtectMode ? ERP_INFO_USE_PROTECTION : 0; -+ -+ if (prBssInfo->fgErpProtectMode) -+ prErpIe->ucERP |= (ERP_INFO_NON_ERP_PRESENT | ERP_INFO_USE_PROTECTION); -+ -+ /* Handle barker preamble */ -+ if (!prBssInfo->fgUseShortPreamble) -+ prErpIe->ucERP |= ERP_INFO_BARKER_PREAMBLE_MODE; -+ -+ ASSERT(IE_SIZE(prErpIe) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_ERP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prErpIe); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT32 -+rlmFillHtCapIEByParams(BOOLEAN fg40mAllowed, -+ BOOLEAN fgShortGIDisabled, -+ UINT_8 u8SupportRxSgi20, -+ UINT_8 u8SupportRxSgi40, -+ UINT_8 u8SupportRxGf, UINT_8 u8SupportRxSTBC, ENUM_OP_MODE_T eCurrentOPMode, UINT_8 *pOutBuf) -+{ -+ P_IE_HT_CAP_T prHtCap; -+ P_SUP_MCS_SET_FIELD prSupMcsSet; -+ -+ ASSERT(pOutBuf); -+ -+ prHtCap = (P_IE_HT_CAP_T) pOutBuf; -+ -+ /* Add HT capabilities IE */ -+ prHtCap->ucId = ELEM_ID_HT_CAP; -+ prHtCap->ucLength = sizeof(IE_HT_CAP_T) - ELEM_HDR_LEN; -+ -+ prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL; -+ if (!fg40mAllowed) { -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | -+ HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_DSSS_CCK_IN_40M); -+ } -+ if (fgShortGIDisabled) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); -+ -+ if (u8SupportRxSgi20 == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M); -+ if (u8SupportRxSgi40 == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_40M); -+ if (u8SupportRxGf == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_HT_GF); -+ if (u8SupportRxSTBC == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_RX_STBC_1_SS); -+ prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL; -+ -+ prSupMcsSet = &prHtCap->rSupMcsSet; -+ kalMemZero((PVOID)&prSupMcsSet->aucRxMcsBitmask[0], SUP_MCS_RX_BITMASK_OCTET_NUM); -+ -+ prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7); -+ -+ if (fg40mAllowed) -+ prSupMcsSet->aucRxMcsBitmask[32 / 8] = BIT(0); /* MCS32 */ -+ prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE; -+ prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL; -+ -+ prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL; -+ if (!fg40mAllowed || eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ prHtCap->u2HtExtendedCap &= ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE); -+ -+ prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL; -+ -+ prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL; -+ -+ ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP)); -+ -+ return IE_SIZE(prHtCap); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID rlmFillHtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_IE_HT_CAP_T prHtCap; -+/* P_SUP_MCS_SET_FIELD prSupMcsSet; */ -+ BOOLEAN fg40mAllowed; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ ASSERT(prMsduInfo); -+ -+ fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed; -+ -+ prHtCap = (P_IE_HT_CAP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+#if 0 -+ /* Add HT capabilities IE */ -+ prHtCap->ucId = ELEM_ID_HT_CAP; -+ prHtCap->ucLength = sizeof(IE_HT_CAP_T) - ELEM_HDR_LEN; -+ -+ prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL; -+ if (!fg40mAllowed) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | -+ HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_DSSS_CCK_IN_40M); -+ if (prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); -+ -+ if (prAdapter->rWifiVar.u8SupportRxSgi20 == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M); -+ if (prAdapter->rWifiVar.u8SupportRxSgi40 == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_40M); -+ if (prAdapter->rWifiVar.u8SupportRxGf == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_HT_GF); -+ -+ prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL; -+ -+ prSupMcsSet = &prHtCap->rSupMcsSet; -+ kalMemZero((PVOID)&prSupMcsSet->aucRxMcsBitmask[0], SUP_MCS_RX_BITMASK_OCTET_NUM); -+ -+ prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7); -+ -+ if (fg40mAllowed) -+ prSupMcsSet->aucRxMcsBitmask[32 / 8] = BIT(0); /* MCS32 */ -+ prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE; -+ prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL; -+ -+ prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL; -+ if (!fg40mAllowed || prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ prHtCap->u2HtExtendedCap &= ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE); -+ -+ prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL; -+ -+ prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL; -+ -+ ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prHtCap); -+#else -+ -+ prMsduInfo->u2FrameLength += rlmFillHtCapIEByParams(fg40mAllowed, -+ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled, -+ prAdapter->rWifiVar.u8SupportRxSgi20, -+ prAdapter->rWifiVar.u8SupportRxSgi40, -+ prAdapter->rWifiVar.u8SupportRxGf, -+ prAdapter->rWifiVar.u8SupportRxSTBC, -+ prBssInfo->eCurrentOPMode, (UINT_8 *) prHtCap); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID rlmFillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) -+{ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ P_HS20_EXT_CAP_T prHsExtCap; -+#else -+ P_EXT_CAP_T prExtCap; -+#endif -+ BOOLEAN fg40mAllowed; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ prHsExtCap = (P_HS20_EXT_CAP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ prHsExtCap->ucId = ELEM_ID_EXTENDED_CAP; -+ -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) -+ prHsExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; -+ else -+ prHsExtCap->ucLength = 3 - ELEM_HDR_LEN; -+ -+ kalMemZero(prHsExtCap->aucCapabilities, sizeof(prHsExtCap->aucCapabilities)); -+ -+ prHsExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; -+ -+ if (!fg40mAllowed) -+ prHsExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT; -+ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ prHsExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; -+ -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) { -+ SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); -+ -+ /* For R2 WNM-Notification */ -+ SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); -+ } -+ -+ ASSERT(IE_SIZE(prHsExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prHsExtCap); -+ -+#else -+ /* Add Extended Capabilities IE */ -+ prExtCap = (P_EXT_CAP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+ prExtCap->ucId = ELEM_ID_EXTENDED_CAP; -+ -+ prExtCap->ucLength = 3 - ELEM_HDR_LEN; -+ kalMemZero(prExtCap->aucCapabilities, sizeof(prExtCap->aucCapabilities)); -+ -+ prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; -+ -+ if (!fg40mAllowed) -+ prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT; -+ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; -+ -+ ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prExtCap); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT32 rlmFillHtOpIeBody(P_BSS_INFO_T prBssInfo, UINT_8 *pFme) -+{ -+ P_IE_HT_OP_T prHtOp; -+ UINT_16 i; -+ -+ prHtOp = (P_IE_HT_OP_T) pFme; -+ -+ /* Add HT operation IE */ -+ prHtOp->ucId = ELEM_ID_HT_OP; -+ prHtOp->ucLength = sizeof(IE_HT_OP_T) - ELEM_HDR_LEN; -+ -+ /* RIFS and 20/40 bandwidth operations are included */ -+ prHtOp->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ prHtOp->ucInfo1 = prBssInfo->ucHtOpInfo1; -+ -+ /* Decide HT protection mode field */ -+ if (prBssInfo->eHtProtectMode == HT_PROTECT_MODE_NON_HT) -+ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_HT; -+ else if (prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) -+ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_MEMBER; -+ else { -+ /* It may be SYS_PROTECT_MODE_NONE or SYS_PROTECT_MODE_20M */ -+ prHtOp->u2Info2 = (UINT_8) prBssInfo->eHtProtectMode; -+ } -+ -+ if (prBssInfo->eGfOperationMode != GF_MODE_NORMAL) { -+ /* It may be GF_MODE_PROTECT or GF_MODE_DISALLOWED -+ * Note: it will also be set in ad-hoc network -+ */ -+ prHtOp->u2Info2 |= HT_OP_INFO2_NON_GF_HT_STA_PRESENT; -+ } -+ -+ if (0 /* Regulatory class 16 */ && -+ prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) { -+ /* (TBD) It is HT_PROTECT_MODE_NON_MEMBER, so require protection -+ * although it is possible to have no protection by spec. -+ */ -+ prHtOp->u2Info2 |= HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; -+ } -+ -+ prHtOp->u2Info3 = prBssInfo->u2HtOpInfo3; /* To do: handle L-SIG TXOP */ -+ -+ /* No basic MCSx are needed temporarily */ -+ for (i = 0; i < 16; i++) -+ prHtOp->aucBasicMcsSet[i] = 0; -+ -+ return sizeof(IE_HT_OP_T); -+} -+ -+static VOID rlmFillHtOpIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) -+{ -+/* P_IE_HT_OP_T prHtOp; */ -+/* UINT_16 i; */ -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ ASSERT(prMsduInfo); -+ -+ prMsduInfo->u2FrameLength += rlmFillHtOpIeBody(prBssInfo, -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength)); -+#if 0 -+ prHtOp = (P_IE_HT_OP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+ /* Add HT operation IE */ -+ prHtOp->ucId = ELEM_ID_HT_OP; -+ prHtOp->ucLength = sizeof(IE_HT_OP_T) - ELEM_HDR_LEN; -+ -+ /* RIFS and 20/40 bandwidth operations are included */ -+ prHtOp->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ prHtOp->ucInfo1 = prBssInfo->ucHtOpInfo1; -+ -+ /* Decide HT protection mode field */ -+ if (prBssInfo->eHtProtectMode == HT_PROTECT_MODE_NON_HT) -+ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_HT; -+ else if (prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) -+ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_MEMBER; -+ else { -+ /* It may be SYS_PROTECT_MODE_NONE or SYS_PROTECT_MODE_20M */ -+ prHtOp->u2Info2 = (UINT_8) prBssInfo->eHtProtectMode; -+ } -+ -+ if (prBssInfo->eGfOperationMode != GF_MODE_NORMAL) { -+ /* It may be GF_MODE_PROTECT or GF_MODE_DISALLOWED -+ * Note: it will also be set in ad-hoc network -+ */ -+ prHtOp->u2Info2 |= HT_OP_INFO2_NON_GF_HT_STA_PRESENT; -+ } -+ -+ if (0 /* Regulatory class 16 */ && -+ prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) { -+ /* (TBD) It is HT_PROTECT_MODE_NON_MEMBER, so require protection -+ * although it is possible to have no protection by spec. -+ */ -+ prHtOp->u2Info2 |= HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; -+ } -+ -+ prHtOp->u2Info3 = prBssInfo->u2HtOpInfo3; /* To do: handle L-SIG TXOP */ -+ -+ /* No basic MCSx are needed temporarily */ -+ for (i = 0; i < 16; i++) -+ prHtOp->aucBasicMcsSet[i] = 0; -+ -+ ASSERT(IE_SIZE(prHtOp) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prHtOp); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function should be invoked to update parameters of associated AP. -+* (Association response and Beacon) -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static UINT_8 rlmRecIeInfoForClient(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ UINT_16 u2Offset; -+ P_STA_RECORD_T prStaRec; -+ P_IE_HT_CAP_T prHtCap; -+ P_IE_HT_OP_T prHtOp; -+ P_IE_OBSS_SCAN_PARAM_T prObssScnParam; -+ UINT_8 ucERP, ucPrimaryChannel; -+#if CFG_SUPPORT_QUIET && 0 -+ BOOLEAN fgHasQuietIE = FALSE; -+#endif -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ ASSERT(pucIE); -+ -+ prStaRec = prBssInfo->prStaRecOfAP; -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return 0; -+ -+ prBssInfo->fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed; -+ ucPrimaryChannel = 0; -+ prObssScnParam = NULL; -+ -+ /* Note: HT-related members in staRec may not be zero before, so -+ * if following IE does not exist, they are still not zero. -+ * These HT-related parameters are valid only when the corresponding -+ * BssInfo supports 802.11n, i.e., RLM_NET_IS_11N() -+ */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_HT_CAP: -+ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) -+ break; -+ prHtCap = (P_IE_HT_CAP_T) pucIE; -+ prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; -+ prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE; -+ -+ prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; -+ prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; -+ prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; -+ prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap; -+ prStaRec->ucAselCap = prHtCap->ucAselCap; -+ break; -+ -+ case ELEM_ID_HT_OP: -+ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) -+ break; -+ prHtOp = (P_IE_HT_OP_T) pucIE; -+ /* Workaround that some APs fill primary channel field by its -+ * secondary channel, but its DS IE is correct 20110610 -+ */ -+ if (ucPrimaryChannel == 0) -+ ucPrimaryChannel = prHtOp->ucPrimaryChannel; -+ prBssInfo->ucHtOpInfo1 = prHtOp->ucInfo1; -+ prBssInfo->u2HtOpInfo2 = prHtOp->u2Info2; -+ prBssInfo->u2HtOpInfo3 = prHtOp->u2Info3; -+ -+ if (!prBssInfo->fg40mBwAllowed) -+ prBssInfo->ucHtOpInfo1 &= ~(HT_OP_INFO1_SCO | HT_OP_INFO1_STA_CHNL_WIDTH); -+ -+ if ((prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) -+ prBssInfo->eBssSCO = (ENUM_CHNL_EXT_T)(prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO); -+ -+ prBssInfo->eHtProtectMode = (ENUM_HT_PROTECT_MODE_T) -+ (prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_HT_PROTECTION); -+ -+ /* To do: process regulatory class 16 */ -+ if ((prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT) -+ && 0 /* && regulatory class is 16 */) -+ prBssInfo->eGfOperationMode = GF_MODE_DISALLOWED; -+ else if (prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_NON_GF_HT_STA_PRESENT) -+ prBssInfo->eGfOperationMode = GF_MODE_PROTECT; -+ else -+ prBssInfo->eGfOperationMode = GF_MODE_NORMAL; -+ -+ prBssInfo->eRifsOperationMode = -+ (prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_RIFS_MODE) ? RIFS_MODE_NORMAL : RIFS_MODE_DISALLOWED; -+ -+ break; -+ -+ case ELEM_ID_20_40_BSS_COEXISTENCE: -+ if (!RLM_NET_IS_11N(prBssInfo)) -+ break; -+ /* To do: store if scanning exemption grant to BssInfo */ -+ break; -+ -+ case ELEM_ID_OBSS_SCAN_PARAMS: -+ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_OBSS_SCAN_PARAM_T) - 2)) -+ break; -+ /* Store OBSS parameters to BssInfo */ -+ prObssScnParam = (P_IE_OBSS_SCAN_PARAM_T) pucIE; -+ break; -+ -+ case ELEM_ID_EXTENDED_CAP: -+ if (!RLM_NET_IS_11N(prBssInfo)) -+ break; -+ /* To do: store extended capability (PSMP, coexist) to BssInfo */ -+ break; -+ -+ case ELEM_ID_ERP_INFO: -+ if (IE_LEN(pucIE) != (sizeof(IE_ERP_T) - 2) || prBssInfo->eBand != BAND_2G4) -+ break; -+ ucERP = ERP_INFO_IE(pucIE)->ucERP; -+ prBssInfo->fgErpProtectMode = (ucERP & ERP_INFO_USE_PROTECTION) ? TRUE : FALSE; -+ -+ if (ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) -+ prBssInfo->fgUseShortPreamble = FALSE; -+ break; -+ -+ case ELEM_ID_DS_PARAM_SET: -+ if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) -+ ucPrimaryChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; -+ break; -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+ case ELEM_ID_CH_SW_ANNOUNCEMENT: -+ { -+ rlmProcessChannelSwitchIE(prAdapter, (P_IE_CHANNEL_SWITCH_T) pucIE); -+ } -+ break; -+ -+#if CFG_SUPPORT_QUIET && 0 -+ /* Note: RRM code should be moved to independent RRM function by -+ * component design rule. But we attach it to RLM temporarily -+ */ -+ case ELEM_ID_QUIET: -+ rrmQuietHandleQuietIE(prBssInfo, (P_IE_QUIET_T) pucIE); -+ fgHasQuietIE = TRUE; -+ break; -+#endif -+#endif -+ -+ default: -+ break; -+ } /* end of switch */ -+ } /* end of IE_FOR_EACH */ -+ -+ /* Some AP will have wrong channel number (255) when running time. -+ * Check if correct channel number information. 20110501 -+ */ -+ if ((prBssInfo->eBand == BAND_2G4 && ucPrimaryChannel > 14) || -+ (prBssInfo->eBand != BAND_2G4 && (ucPrimaryChannel >= 200 || ucPrimaryChannel <= 14))) -+ ucPrimaryChannel = 0; -+#if CFG_SUPPORT_QUIET && 0 -+ if (!fgHasQuietIE) -+ rrmQuietIeNotExist(prAdapter, prBssInfo); -+#endif -+ -+ /* Check if OBSS scan process will launch */ -+ if (!prAdapter->fgEnOnlineScan || !prObssScnParam || -+ !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH) || -+ prBssInfo->eBand != BAND_2G4 || !prBssInfo->fg40mBwAllowed) { -+ -+ /* Note: it is ok not to stop rObssScanTimer() here */ -+ prBssInfo->u2ObssScanInterval = 0; -+ } else { -+ if (prObssScnParam->u2TriggerScanInterval < OBSS_SCAN_MIN_INTERVAL) -+ prObssScnParam->u2TriggerScanInterval = OBSS_SCAN_MIN_INTERVAL; -+ if (prBssInfo->u2ObssScanInterval != prObssScnParam->u2TriggerScanInterval) { -+ -+ prBssInfo->u2ObssScanInterval = prObssScnParam->u2TriggerScanInterval; -+ -+ /* Start timer to trigger OBSS scanning */ -+ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, -+ prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); -+ } -+ } -+ -+ return ucPrimaryChannel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief AIS or P2P GC. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static BOOLEAN -+rlmRecBcnFromNeighborForClient(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ UINT_16 u2Offset, i; -+ UINT_8 ucPriChannel, ucSecChannel; -+ ENUM_CHNL_EXT_T eSCO; -+ BOOLEAN fgHtBss, fg20mReq; -+ -+ if ((prAdapter == NULL) -+ || (pucIE == NULL) -+ || (prBssInfo == NULL) -+ || (prSwRfb == NULL)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ /* Record it to channel list to change 20/40 bandwidth */ -+ ucPriChannel = 0; -+ eSCO = CHNL_EXT_SCN; -+ -+ fgHtBss = FALSE; -+ fg20mReq = FALSE; -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_HT_CAP: -+ { -+ P_IE_HT_CAP_T prHtCap; -+ -+ if (IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) -+ break; -+ -+ prHtCap = (P_IE_HT_CAP_T) pucIE; -+ if (prHtCap->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) -+ fg20mReq = TRUE; -+ fgHtBss = TRUE; -+ break; -+ } -+ case ELEM_ID_HT_OP: -+ { -+ P_IE_HT_OP_T prHtOp; -+ -+ if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) -+ break; -+ -+ prHtOp = (P_IE_HT_OP_T) pucIE; -+ /* Workaround that some APs fill primary channel field by its -+ * secondary channel, but its DS IE is correct 20110610 -+ */ -+ if (ucPriChannel == 0) -+ ucPriChannel = prHtOp->ucPrimaryChannel; -+ -+ if ((prHtOp->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) -+ eSCO = (ENUM_CHNL_EXT_T) (prHtOp->ucInfo1 & HT_OP_INFO1_SCO); -+ break; -+ } -+ case ELEM_ID_20_40_BSS_COEXISTENCE: -+ { -+ P_IE_20_40_COEXIST_T prCoexist; -+ -+ if (IE_LEN(pucIE) != (sizeof(IE_20_40_COEXIST_T) - 2)) -+ break; -+ -+ prCoexist = (P_IE_20_40_COEXIST_T) pucIE; -+ if (prCoexist->ucData & BSS_COEXIST_40M_INTOLERANT) -+ fg20mReq = TRUE; -+ break; -+ } -+ case ELEM_ID_DS_PARAM_SET: -+ if (IE_LEN(pucIE) != (sizeof(IE_DS_PARAM_SET_T) - 2)) -+ break; -+ ucPriChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; -+ break; -+ -+ default: -+ break; -+ } -+ } -+ -+ /* To do: Update channel list and 5G band. All channel lists have the same -+ * update procedure. We should give it the entry pointer of desired -+ * channel list. -+ */ -+ if (HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr) != BAND_2G4) -+ return FALSE; -+ -+ if (ucPriChannel == 0 || ucPriChannel > 14) -+ ucPriChannel = HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr); -+ -+ if (fgHtBss) { -+ ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_PriChnlList[i] == ucPriChannel) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_PriChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_PriChnlList[i] = ucPriChannel; -+ prBssInfo->auc2G_PriChnlList[0]++; -+ } -+ -+ /* Update secondary channel */ -+ if (eSCO != CHNL_EXT_SCN) { -+ ucSecChannel = (eSCO == CHNL_EXT_SCA) ? (ucPriChannel + 4) : (ucPriChannel - 4); -+ -+ ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_SecChnlList[i] == ucSecChannel) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_SecChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_SecChnlList[i] = ucSecChannel; -+ prBssInfo->auc2G_SecChnlList[0]++; -+ } -+ } -+ -+ /* Update 20M bandwidth request channels */ -+ if (fg20mReq) { -+ ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_20mReqChnlList[i] == ucPriChannel) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_20mReqChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_20mReqChnlList[i] = ucPriChannel; -+ prBssInfo->auc2G_20mReqChnlList[0]++; -+ } -+ } -+ } else { -+ /* Update non-HT channel list */ -+ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_NonHtChnlList[i] == ucPriChannel) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_NonHtChnlList[i] = ucPriChannel; -+ prBssInfo->auc2G_NonHtChnlList[0]++; -+ } -+ -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief AIS or P2P GC. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static BOOLEAN -+rlmRecBcnInfoForClient(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ if ((prAdapter == NULL) -+ || (pucIE == NULL) -+ || (prBssInfo == NULL) -+ || (prSwRfb == NULL)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+#if 0 /* SW migration 2010/8/20 */ -+ /* Note: we shall not update parameters when scanning, otherwise -+ * channel and bandwidth will not be correct or asserted failure -+ * during scanning. -+ * Note: remove channel checking. All received Beacons should be processed -+ * if measurement or other actions are executed in adjacent channels -+ * and Beacon content checking mechanism is not disabled. -+ */ -+ if (IS_SCAN_ACTIVE() -+ /* || prBssInfo->ucPrimaryChannel != CHNL_NUM_BY_SWRFB(prSwRfb) */ -+ ) { -+ return FALSE; -+ } -+#endif -+ -+ /* Handle change of slot time */ -+ prBssInfo->u2CapInfo = ((P_WLAN_BEACON_FRAME_T) (prSwRfb->pvHeader))->u2CapInfo; -+ prBssInfo->fgUseShortSlotTime = (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE; -+ -+ rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessBcn(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ P_BSS_INFO_T prBssInfo; -+ BOOLEAN fgNewParameter; -+ UINT_8 ucNetIdx; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ fgNewParameter = FALSE; -+ -+ /* When concurrent networks exist, GO shall have the same handle as -+ * the other BSS, so the Beacon shall be processed for bandwidth and -+ * protection mechanism. -+ * Note1: we do not have 2 AP (GO) cases simultaneously now. -+ * Note2: If we are GO, concurrent AIS AP should detect it and reflect -+ * action in its Beacon, so AIS STA just follows Beacon from AP. -+ */ -+ RLM_NET_FOR_EACH_NO_BOW(ucNetIdx) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx]; -+ ASSERT(prBssInfo); -+ -+ if (IS_BSS_ACTIVE(prBssInfo)) { -+ if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && -+ prBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* P2P client or AIS infra STA */ -+ if (EQUAL_MAC_ADDR(prBssInfo->aucBSSID, ((P_WLAN_MAC_MGMT_HEADER_T) -+ (prSwRfb->pvHeader))->aucBSSID)) { -+ -+ fgNewParameter = rlmRecBcnInfoForClient(prAdapter, -+ prBssInfo, prSwRfb, pucIE, u2IELength); -+ } else { -+ fgNewParameter = rlmRecBcnFromNeighborForClient(prAdapter, -+ prBssInfo, prSwRfb, pucIE, -+ u2IELength); -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if (prAdapter->fgIsP2PRegistered && -+ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT || -+ prBssInfo->eCurrentOPMode == OP_MODE_P2P_DEVICE)) { -+ /* AP scan to check if 20/40M bandwidth is permitted */ -+ rlmRecBcnFromNeighborForClient(prAdapter, prBssInfo, prSwRfb, pucIE, u2IELength); -+ } -+#endif -+ else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ /* Do nothing */ -+ /* To do: Ad-hoc */ -+ } -+ -+ /* Appy new parameters if necessary */ -+ if (fgNewParameter) { -+ DBGLOG(RLM, TRACE, "rlmProcessBcn\n"); -+ rlmSyncOperationParams(prAdapter, prBssInfo); -+ fgNewParameter = FALSE; -+ } -+ } /* end of IS_BSS_ACTIVE() */ -+ } /* end of RLM_NET_FOR_EACH_NO_BOW */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function should be invoked after judging successful association. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessAssocRsp(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ UINT_8 ucPriChannel; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return; -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ ASSERT(prStaRec == prBssInfo->prStaRecOfAP); -+ -+ /* To do: the invoked function is used to clear all members. It may be -+ * done by center mechanism in invoker. -+ */ -+ rlmBssReset(prAdapter, prBssInfo); -+ -+ prBssInfo->fgUseShortSlotTime = (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE; -+ -+ ucPriChannel = rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength); -+ if (ucPriChannel > 0) -+ prBssInfo->ucPrimaryChannel = ucPriChannel; -+ -+ if (!RLM_NET_IS_11N(prBssInfo) || !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) -+ prBssInfo->fg40mBwAllowed = FALSE; -+ -+ /* Note: Update its capabilities to WTBL by cnmStaRecChangeState(), which -+ * shall be invoked afterwards. -+ * Update channel, bandwidth and protection mode by nicUpdateBss() -+ */ -+#if 1 -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ -+ DBGLOG(P2P, WARN, "Force P2P BW to 20\n"); -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ } -+#endif -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function should be invoked after judging successful association. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmFillSyncCmdParam(P_CMD_SET_BSS_RLM_PARAM_T prCmdBody, P_BSS_INFO_T prBssInfo) -+{ -+ ASSERT(prCmdBody && prBssInfo); -+ if (!prCmdBody || !prBssInfo) -+ return; -+ -+ prCmdBody->ucNetTypeIndex = prBssInfo->ucNetTypeIndex; -+ prCmdBody->ucRfBand = (UINT_8) prBssInfo->eBand; -+ prCmdBody->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ prCmdBody->ucRfSco = (UINT_8) prBssInfo->eBssSCO; -+ prCmdBody->ucErpProtectMode = (UINT_8) prBssInfo->fgErpProtectMode; -+ prCmdBody->ucHtProtectMode = (UINT_8) prBssInfo->eHtProtectMode; -+ prCmdBody->ucGfOperationMode = (UINT_8) prBssInfo->eGfOperationMode; -+ prCmdBody->ucTxRifsMode = (UINT_8) prBssInfo->eRifsOperationMode; -+ prCmdBody->u2HtOpInfo3 = prBssInfo->u2HtOpInfo3; -+ prCmdBody->u2HtOpInfo2 = prBssInfo->u2HtOpInfo2; -+ prCmdBody->ucHtOpInfo1 = prBssInfo->ucHtOpInfo1; -+ prCmdBody->ucUseShortPreamble = prBssInfo->fgUseShortPreamble; -+ prCmdBody->ucUseShortSlotTime = prBssInfo->fgUseShortSlotTime; -+ prCmdBody->ucCheckId = 0x72; -+ -+ if (RLM_NET_PARAM_VALID(prBssInfo)) { -+ DBGLOG(RLM, INFO, "N=%d b=%d c=%d s=%d e=%d h=%d I=0x%02x l=%d p=%d\n", -+ prCmdBody->ucNetTypeIndex, prCmdBody->ucRfBand, -+ prCmdBody->ucPrimaryChannel, prCmdBody->ucRfSco, -+ prCmdBody->ucErpProtectMode, prCmdBody->ucHtProtectMode, -+ prCmdBody->ucHtOpInfo1, prCmdBody->ucUseShortSlotTime, -+ prCmdBody->ucUseShortPreamble); -+ } else { -+ DBGLOG(RLM, TRACE, "N=%d closed\n", prCmdBody->ucNetTypeIndex); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will operation parameters based on situations of -+* concurrent networks. Channel, bandwidth, protection mode, supported -+* rate will be modified. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ P_CMD_SET_BSS_RLM_PARAM_T prCmdBody; -+ WLAN_STATUS rStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ prCmdBody = (P_CMD_SET_BSS_RLM_PARAM_T) -+ cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_BSS_RLM_PARAM_T)); -+ ASSERT(prCmdBody); -+ -+ /* To do: exception handle */ -+ if (!prCmdBody) { -+ DBGLOG(RLM, WARN, "No buf for sync RLM params (Net=%d)\n", prBssInfo->ucNetTypeIndex); -+ return; -+ } -+ -+ rlmFillSyncCmdParam(prCmdBody, prBssInfo); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_BSS_RLM_PARAM, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_SET_BSS_RLM_PARAM_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdBody, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+ cnmMemFree(prAdapter, prCmdBody); -+} -+ -+#if CFG_SUPPORT_AAA -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function should be invoked after judging successful association. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessAssocReq(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2Offset; -+ P_IE_HT_CAP_T prHtCap; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return; -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_HT_CAP: -+ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) -+ break; -+ prHtCap = (P_IE_HT_CAP_T) pucIE; -+ prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; -+ prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE; -+ -+ prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; -+ prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; -+ prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; -+ prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap; -+ prStaRec->ucAselCap = prHtCap->ucAselCap; -+ break; -+ -+ default: -+ break; -+ } /* end of switch */ -+ } /* end of IE_FOR_EACH */ -+} -+#endif /* CFG_SUPPORT_AAA */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief It is for both STA and AP modes -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmBssInitForAPandIbss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) -+ rlmBssInitForAP(prAdapter, prBssInfo); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief It is for both STA and AP modes -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmBssAborted(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ rlmBssReset(prAdapter, prBssInfo); -+ -+ prBssInfo->fg40mBwAllowed = FALSE; -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ -+ /* Assume FW state is updated by CMD_ID_SET_BSS_INFO, so -+ * the sync CMD is not needed here. -+ */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief All RLM timers will also be stopped. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID rlmBssReset(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ /* HT related parameters */ -+ prBssInfo->ucHtOpInfo1 = 0; /* RIFS disabled. 20MHz */ -+ prBssInfo->u2HtOpInfo2 = 0; -+ prBssInfo->u2HtOpInfo3 = 0; -+ -+ prBssInfo->eBssSCO = 0; -+ prBssInfo->fgErpProtectMode = 0; -+ prBssInfo->eHtProtectMode = 0; -+ prBssInfo->eGfOperationMode = 0; -+ prBssInfo->eRifsOperationMode = 0; -+ -+ /* OBSS related parameters */ -+ prBssInfo->auc2G_20mReqChnlList[0] = 0; -+ prBssInfo->auc2G_NonHtChnlList[0] = 0; -+ prBssInfo->auc2G_PriChnlList[0] = 0; -+ prBssInfo->auc2G_SecChnlList[0] = 0; -+ prBssInfo->auc5G_20mReqChnlList[0] = 0; -+ prBssInfo->auc5G_NonHtChnlList[0] = 0; -+ prBssInfo->auc5G_PriChnlList[0] = 0; -+ prBssInfo->auc5G_SecChnlList[0] = 0; -+ -+ /* All RLM timers will also be stopped */ -+ cnmTimerStopTimer(prAdapter, &prBssInfo->rObssScanTimer); -+ prBssInfo->u2ObssScanInterval = 0; -+ -+ prBssInfo->fgObssErpProtectMode = 0; /* GO only */ -+ prBssInfo->eObssHtProtectMode = 0; /* GO only */ -+ prBssInfo->eObssGfOperationMode = 0; /* GO only */ -+ prBssInfo->fgObssRifsOperationMode = 0; /* GO only */ -+ prBssInfo->fgObssActionForcedTo20M = 0; /* GO only */ -+ prBssInfo->fgObssBeaconForcedTo20M = 0; /* GO only */ -+} -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function handle spectrum management action frame -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessSpecMgtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) -+{ -+ P_ACTION_CHANNEL_SWITCH_FRAME prRxFrame; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ DBGLOG(RLM, INFO, "[5G DFS]rlmProcessSpecMgtAction \r\n"); -+ -+ prRxFrame = (P_ACTION_CHANNEL_SWITCH_FRAME) prSwRfb->pvHeader; -+ DBGLOG(RLM, INFO, "[5G DFS]prRxFrame->ucAction[%d] \r\n", prRxFrame->ucAction); -+ if (prRxFrame->ucAction == ACTION_CHNL_SWITCH) -+ rlmProcessChannelSwitchIE(prAdapter, (P_IE_CHANNEL_SWITCH_T) prRxFrame->aucInfoElem); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function process Channel Switch IE -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessChannelSwitchIE(P_ADAPTER_T prAdapter, P_IE_CHANNEL_SWITCH_T prChannelSwitchIE) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prChannelSwitchIE); -+ -+ DBGLOG(RLM, INFO, "[5G DFS] rlmProcessChannelSwitchIE \r\n"); -+ DBGLOG(RLM, INFO, "[5G DFS] ucChannelSwitchMode[%d], ucChannelSwitchCount[%d], ucNewChannelNum[%d] \r\n", -+ prChannelSwitchIE->ucChannelSwitchMode, -+ prChannelSwitchIE->ucChannelSwitchCount, prChannelSwitchIE->ucNewChannelNum); -+ if (prChannelSwitchIE->ucChannelSwitchMode == 1) { -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ DBGLOG(RLM, INFO, "[5G DFS] switch channel [%d]->[%d] \r\n", prAisBssInfo->ucPrimaryChannel, -+ prChannelSwitchIE->ucNewChannelNum); -+ prAisBssInfo->ucPrimaryChannel = prChannelSwitchIE->ucNewChannelNum; -+ nicUpdateBss(prAdapter, prAisBssInfo->ucNetTypeIndex); -+ } -+ -+} -+ -+#endif -+ -+#if (CFG_SUPPORT_TXR_ENC == 1) -+VOID -+rlmTxRateEnhanceConfig( -+ P_ADAPTER_T prAdapter -+ ) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ CMD_RLM_INFO_T rTxRInfo; -+ UINT_32 u4SetInfoLen = 0; -+ -+ -+ /* init */ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* suggestion from Tsaiyuan.Hsu */ -+ kalMemZero(&rTxRInfo, sizeof(CMD_RLM_INFO_T)); -+ rTxRInfo.fgIsErrRatioEnhanceApplied = TRUE; -+ rTxRInfo.ucErrRatio2LimitMinRate = 3; -+ rTxRInfo.ucMinLegacyRateIdx = 2; -+ rTxRInfo.cMinRssiThreshold = -60; -+ rTxRInfo.fgIsRtsApplied = TRUE; -+ rTxRInfo.ucRecoverTime = 60; -+ -+ DBGLOG(RLM, INFO, "Enable tx rate enhance function\n"); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetTxRateInfo, -+ &rTxRInfo, -+ sizeof(rTxRInfo), -+ TRUE, -+ TRUE, -+ TRUE, -+ FALSE, -+ &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(RLM, WARN, "set tx rate advance info fail 0x%lx\n", rStatus); -+} -+ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a command to TX Auto Rate module. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rlmCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ UINT_32 u4Subcmd; -+ -+ -+ /* parse TAR sub-command */ -+ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(RLM, INFO, " sub command = %u\n", (UINT32)u4Subcmd); -+ -+ /* handle different sub-command */ -+ switch (u4Subcmd) { -+ case 0x00: /* configure */ -+ /* iwpriv wlan0 set_str_cmd 1_0_0_1_3_2_60_1_60 */ -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ CMD_RLM_INFO_T rTxRInfo; -+ UINT_32 u4SetInfoLen = 0; -+ -+ kalMemZero(&rTxRInfo, sizeof(CMD_RLM_INFO_T)); -+ rTxRInfo.u4Version = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.fgIsErrRatioEnhanceApplied = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.ucErrRatio2LimitMinRate = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.ucMinLegacyRateIdx = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.cMinRssiThreshold = 0 - CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.fgIsRtsApplied = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.ucRecoverTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(RLM, INFO, " rlmCmd = %u %u %u %u %d %u %u\n", -+ rTxRInfo.u4Version, -+ rTxRInfo.fgIsErrRatioEnhanceApplied, -+ rTxRInfo.ucErrRatio2LimitMinRate, -+ rTxRInfo.ucMinLegacyRateIdx, -+ rTxRInfo.cMinRssiThreshold, -+ rTxRInfo.fgIsRtsApplied, -+ rTxRInfo.ucRecoverTime)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetTxRateInfo, -+ &rTxRInfo, -+ sizeof(rTxRInfo), -+ TRUE, -+ TRUE, -+ TRUE, -+ FALSE, -+ &u4SetInfoLen); -+ break; -+ -+ default: -+ break; -+ } -+} -+#endif /* CFG_SUPPORT_TXR_ENC */ -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c -new file mode 100644 -index 0000000000000..5e127488ea499 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c -@@ -0,0 +1,1791 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_domain.c#1 -+*/ -+ -+/*! \file "rlm_domain.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: rlm_domain.c -+ * -+ * 11 10 2011 cm.chang -+ * NULL -+ * Modify debug message for XLOG -+ * -+ * 09 29 2011 cm.chang -+ * NULL -+ * Change the function prototype of rlmDomainGetChnlList() -+ * -+ * 09 23 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Let channel number to zero if band is illegal -+ * -+ * 09 22 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Exclude channel list with illegal band -+ * -+ * 09 15 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use defined country group to have a change to add new group -+ * -+ * 09 08 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 06 01 2011 cm.chang -+ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function -+ * Provide legal channel function based on domain -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Add beacon timeout support for WiFi Direct Network. -+ * -+ * 03 02 2011 terry.wu -+ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration -+ * Export rlmDomainGetDomainInfo for p2p driver. -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 03 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Filter out not supported RF freq when reporting available chnl list -+ * -+ * 01 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+ * -+ * 01 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Provide query function about full channel list. -+ * -+ * Dec 1 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+#include "rlm_txpwr_init.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/* The following country or domain shall be set from host driver. -+ * And host driver should pass specified DOMAIN_INFO_ENTRY to MT6620 as -+ * the channel list of being a STA to do scanning/searching AP or being an -+ * AP to choose an adequate channel if auto-channel is set. -+ */ -+ -+/* Define mapping tables between country code and its channel set -+ */ -+static const UINT_16 g_u2CountryGroup0[] = { -+ COUNTRY_CODE_AO, COUNTRY_CODE_BZ, COUNTRY_CODE_BJ, COUNTRY_CODE_BT, -+ COUNTRY_CODE_BO, COUNTRY_CODE_BI, COUNTRY_CODE_CM, COUNTRY_CODE_CF, -+ COUNTRY_CODE_TD, COUNTRY_CODE_KM, COUNTRY_CODE_CD, COUNTRY_CODE_CG, -+ COUNTRY_CODE_CI, COUNTRY_CODE_DJ, COUNTRY_CODE_GQ, COUNTRY_CODE_ER, -+ COUNTRY_CODE_FJ, COUNTRY_CODE_GA, COUNTRY_CODE_GM, COUNTRY_CODE_GN, -+ COUNTRY_CODE_GW, COUNTRY_CODE_RKS, COUNTRY_CODE_KG, COUNTRY_CODE_LY, -+ COUNTRY_CODE_MG, COUNTRY_CODE_ML, COUNTRY_CODE_NR, COUNTRY_CODE_NC, -+ COUNTRY_CODE_ST, COUNTRY_CODE_SC, COUNTRY_CODE_SL, COUNTRY_CODE_SB, -+ COUNTRY_CODE_SO, COUNTRY_CODE_SR, COUNTRY_CODE_SZ, COUNTRY_CODE_TJ, -+ COUNTRY_CODE_TG, COUNTRY_CODE_TO, COUNTRY_CODE_TM, COUNTRY_CODE_TV, -+ COUNTRY_CODE_VU, COUNTRY_CODE_YE -+}; -+ -+static const UINT_16 g_u2CountryGroup1[] = { -+ COUNTRY_CODE_AS, COUNTRY_CODE_AI, COUNTRY_CODE_BM, COUNTRY_CODE_CA, -+ COUNTRY_CODE_KY, COUNTRY_CODE_GU, COUNTRY_CODE_FM, COUNTRY_CODE_PR, -+ COUNTRY_CODE_US, COUNTRY_CODE_VI -+}; -+ -+static const UINT_16 g_u2CountryGroup2[] = { -+ COUNTRY_CODE_AR, COUNTRY_CODE_AU, COUNTRY_CODE_AZ, COUNTRY_CODE_BW, -+ COUNTRY_CODE_KH, COUNTRY_CODE_CX, COUNTRY_CODE_CO, COUNTRY_CODE_CR, -+#if (CFG_CN_SUPPORT_CLASS121 == 1) -+ COUNTRY_CODE_CN, -+#endif -+ COUNTRY_CODE_EC, COUNTRY_CODE_GD, COUNTRY_CODE_GT, COUNTRY_CODE_HK, -+ COUNTRY_CODE_KI, COUNTRY_CODE_LB, COUNTRY_CODE_LR, COUNTRY_CODE_MN, -+ COUNTRY_CODE_AN, COUNTRY_CODE_NZ, COUNTRY_CODE_NI, COUNTRY_CODE_PW, -+ COUNTRY_CODE_PY, COUNTRY_CODE_PE, COUNTRY_CODE_PH, COUNTRY_CODE_WS, -+ COUNTRY_CODE_SG, COUNTRY_CODE_LK, COUNTRY_CODE_TH, COUNTRY_CODE_TT, -+ COUNTRY_CODE_UY, COUNTRY_CODE_VN -+}; -+ -+static const UINT_16 g_u2CountryGroup3[] = { -+ COUNTRY_CODE_AW, COUNTRY_CODE_LA, COUNTRY_CODE_SA, COUNTRY_CODE_AE, -+ COUNTRY_CODE_UG -+}; -+ -+static const UINT_16 g_u2CountryGroup4[] = { COUNTRY_CODE_MM }; -+ -+static const UINT_16 g_u2CountryGroup5[] = { -+ COUNTRY_CODE_AL, COUNTRY_CODE_DZ, COUNTRY_CODE_AD, COUNTRY_CODE_AT, -+ COUNTRY_CODE_BY, COUNTRY_CODE_BE, COUNTRY_CODE_BA, COUNTRY_CODE_VG, -+ COUNTRY_CODE_BG, COUNTRY_CODE_CV, COUNTRY_CODE_HR, COUNTRY_CODE_CY, -+ COUNTRY_CODE_CZ, COUNTRY_CODE_DK, COUNTRY_CODE_EE, COUNTRY_CODE_ET, -+ COUNTRY_CODE_FI, COUNTRY_CODE_FR, COUNTRY_CODE_GF, COUNTRY_CODE_PF, -+ COUNTRY_CODE_TF, COUNTRY_CODE_GE, COUNTRY_CODE_DE, COUNTRY_CODE_GH, -+ COUNTRY_CODE_GR, COUNTRY_CODE_GP, COUNTRY_CODE_HU, COUNTRY_CODE_IS, -+ COUNTRY_CODE_IQ, COUNTRY_CODE_IE, COUNTRY_CODE_IT, COUNTRY_CODE_KE, -+ COUNTRY_CODE_LV, COUNTRY_CODE_LS, COUNTRY_CODE_LI, COUNTRY_CODE_LT, -+ COUNTRY_CODE_LU, COUNTRY_CODE_MK, COUNTRY_CODE_MT, COUNTRY_CODE_MQ, -+ COUNTRY_CODE_MR, COUNTRY_CODE_MU, COUNTRY_CODE_YT, COUNTRY_CODE_MD, -+ COUNTRY_CODE_MC, COUNTRY_CODE_ME, COUNTRY_CODE_MS, COUNTRY_CODE_NL, -+ COUNTRY_CODE_NO, COUNTRY_CODE_OM, COUNTRY_CODE_PL, COUNTRY_CODE_PT, -+ COUNTRY_CODE_RE, COUNTRY_CODE_RO, COUNTRY_CODE_MF, COUNTRY_CODE_SM, -+ COUNTRY_CODE_SN, COUNTRY_CODE_RS, COUNTRY_CODE_SK, COUNTRY_CODE_SI, -+ COUNTRY_CODE_ZA, COUNTRY_CODE_ES, COUNTRY_CODE_SE, COUNTRY_CODE_CH, -+ COUNTRY_CODE_TR, COUNTRY_CODE_TC, COUNTRY_CODE_GB, COUNTRY_CODE_VA, -+ COUNTRY_CODE_EU -+}; -+ -+static const UINT_16 g_u2CountryGroup6[] = { COUNTRY_CODE_JP }; -+ -+static const UINT_16 g_u2CountryGroup7[] = { -+ COUNTRY_CODE_AM, COUNTRY_CODE_IL, COUNTRY_CODE_KW, COUNTRY_CODE_MA, -+ COUNTRY_CODE_NE, COUNTRY_CODE_TN, COUNTRY_CODE_MA -+}; -+ -+static const UINT_16 g_u2CountryGroup8[] = { COUNTRY_CODE_NP }; -+ -+static const UINT_16 g_u2CountryGroup9[] = { COUNTRY_CODE_AF }; -+ -+static const UINT_16 g_u2CountryGroup10[] = { -+ COUNTRY_CODE_AG, COUNTRY_CODE_BS, COUNTRY_CODE_BH, COUNTRY_CODE_BB, -+ COUNTRY_CODE_BN, COUNTRY_CODE_CL, COUNTRY_CODE_EG, -+#if (CFG_CN_SUPPORT_CLASS121 == 0) -+ COUNTRY_CODE_CN, -+#endif -+ COUNTRY_CODE_SV, COUNTRY_CODE_IN, COUNTRY_CODE_MY, COUNTRY_CODE_MV, -+ COUNTRY_CODE_PA, COUNTRY_CODE_VE, COUNTRY_CODE_ZM -+}; -+ -+static const UINT_16 g_u2CountryGroup11[] = { COUNTRY_CODE_JO, COUNTRY_CODE_PG }; -+ -+static const UINT_16 g_u2CountryGroup12[] = { -+ COUNTRY_CODE_BF, COUNTRY_CODE_GY, COUNTRY_CODE_HT, COUNTRY_CODE_HN, -+ COUNTRY_CODE_JM, COUNTRY_CODE_MO, COUNTRY_CODE_MW, COUNTRY_CODE_PK, -+ COUNTRY_CODE_QA, COUNTRY_CODE_RW, COUNTRY_CODE_KN, COUNTRY_CODE_TZ -+}; -+ -+static const UINT_16 g_u2CountryGroup13[] = { COUNTRY_CODE_ID }; -+ -+static const UINT_16 g_u2CountryGroup14[] = { COUNTRY_CODE_KR }; -+ -+static const UINT_16 g_u2CountryGroup15[] = { COUNTRY_CODE_NG }; -+ -+static const UINT_16 g_u2CountryGroup16[] = { -+ COUNTRY_CODE_BD, COUNTRY_CODE_BR, COUNTRY_CODE_DM, COUNTRY_CODE_DO, -+ COUNTRY_CODE_FK, COUNTRY_CODE_KZ, COUNTRY_CODE_MX, COUNTRY_CODE_MZ, -+ COUNTRY_CODE_NA, COUNTRY_CODE_RU, COUNTRY_CODE_LC, COUNTRY_CODE_VC, -+ COUNTRY_CODE_UA, COUNTRY_CODE_UZ, COUNTRY_CODE_ZW -+}; -+ -+static const UINT_16 g_u2CountryGroup17[] = { COUNTRY_CODE_MP }; -+ -+static const UINT_16 g_u2CountryGroup18[] = { COUNTRY_CODE_TW }; -+ -+static const UINT_16 g_u2CountryGroup19[] = { -+ COUNTRY_CODE_CK, COUNTRY_CODE_CU, COUNTRY_CODE_TL, COUNTRY_CODE_FO, -+ COUNTRY_CODE_GI, COUNTRY_CODE_GG, COUNTRY_CODE_IR, COUNTRY_CODE_IM, -+ COUNTRY_CODE_JE, COUNTRY_CODE_KP, COUNTRY_CODE_MH, COUNTRY_CODE_NU, -+ COUNTRY_CODE_NF, COUNTRY_CODE_PS, COUNTRY_CODE_PN, COUNTRY_CODE_PM, -+ COUNTRY_CODE_SS, COUNTRY_CODE_SD, COUNTRY_CODE_SY -+}; -+ -+static const UINT_16 g_u2CountryGroup20[] = { -+ COUNTRY_CODE_DF, COUNTRY_CODE_FF -+ /* When country code is not found and no matched NVRAM setting, -+ * this domain info will be used. -+ */ -+}; -+ -+static const UINT_16 g_u2CountryGroup21[] = { -+ COUNTRY_CODE_UDF -+}; -+ -+DOMAIN_INFO_ENTRY arSupportedRegDomains[] = { -+ { -+ (PUINT_16) g_u2CountryGroup0, sizeof(g_u2CountryGroup0) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_LOW_NA */ -+ {118, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_MID_NA */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup1, sizeof(g_u2CountryGroup1) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} -+ , /* CH_SET_2G4_1_11 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup2, sizeof(g_u2CountryGroup2) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup3, sizeof(g_u2CountryGroup3) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} -+ , /* CH_SET_UNII_UPPER_149_161 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup4, sizeof(g_u2CountryGroup4) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup5, sizeof(g_u2CountryGroup5) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup6, sizeof(g_u2CountryGroup6) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ {82, BAND_2G4, CHNL_SPAN_5, 14, 1, FALSE} -+ , /* CH_SET_2G4_14_14 */ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup7, sizeof(g_u2CountryGroup7) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup8, sizeof(g_u2CountryGroup8) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} -+ , /* CH_SET_UNII_UPPER_149_161 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup9, sizeof(g_u2CountryGroup9) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_MID_NA */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup10, sizeof(g_u2CountryGroup10) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup11, sizeof(g_u2CountryGroup11) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_MID_NA */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup12, sizeof(g_u2CountryGroup12) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_LOW_NA */ -+ {118, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_MID_NA */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup13, sizeof(g_u2CountryGroup13) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_LOW_NA */ -+ {118, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_MID_NA */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} -+ , /* CH_SET_UNII_UPPER_149_161 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup14, sizeof(g_u2CountryGroup14) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 8, FALSE} -+ , /* CH_SET_UNII_WW_100_128 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} -+ , /* CH_SET_UNII_UPPER_149_161 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup15, sizeof(g_u2CountryGroup15) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup16, sizeof(g_u2CountryGroup16) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup17, sizeof(g_u2CountryGroup17) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} -+ , /* CH_SET_2G4_1_11 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup18, sizeof(g_u2CountryGroup18) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} -+ , /* CH_SET_2G4_1_11 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, FALSE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup19, sizeof(g_u2CountryGroup19) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ /* Note: Default group if no matched country code */ -+ (PUINT_16) g_u2CountryGroup20, sizeof(g_u2CountryGroup20) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ /* Note: for customer configured their own scanning list and passive scan list */ -+ (PUINT_16) g_u2CountryGroup21, sizeof(g_u2CountryGroup21) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 12, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 0, FALSE} -+ , -+ {118, BAND_5G, CHNL_SPAN_20, 52, 0, FALSE} -+ , -+ {121, BAND_5G, CHNL_SPAN_20, 100, 0, FALSE} -+ , -+ {125, BAND_5G, CHNL_SPAN_20, 149, 0, FALSE} -+ , -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+}; -+ -+static UINT_16 g_u2CountryGroup0_Passive[] = { -+ COUNTRY_CODE_UDF -+}; -+ -+DOMAIN_INFO_ENTRY arSupportedRegDomains_Passive[] = { -+ { -+ /* Default passive scan channel table is empty */ -+ COUNTRY_CODE_NULL, 0, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 11, 0, 0}, /* CH_SET_2G4_1_14 */ -+ {82, BAND_2G4, CHNL_SPAN_5, 5, 0, 0}, -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 0, 0}, /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 0, 0}, /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 0, 0}, /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 0, 0}, /* CH_SET_UNII_UPPER_149_173 */ -+ } -+ }, -+ { -+ /* User Defined passive scan channel table */ -+ g_u2CountryGroup0_Passive, 0, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 12, 1, 0}, /* CH_SET_2G4_1_14 */ -+ {82, BAND_2G4, CHNL_SPAN_5, 5, 0, 0}, -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 0, 0}, /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 0, 0}, /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 0, 0}, /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 0, 0}, /* CH_SET_UNII_UPPER_149_173 */ -+ } -+ } -+}; -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+SUBBAND_CHANNEL_T g_rRlmSubBand[] = { -+ -+ {BAND_2G4_LOWER_BOUND, BAND_2G4_UPPER_BOUND, 1, 0} -+ , /* 2.4G */ -+ {UNII1_LOWER_BOUND, UNII1_UPPER_BOUND, 2, 0} -+ , /* ch36,38,40,..,48 */ -+ {UNII2A_LOWER_BOUND, UNII2A_UPPER_BOUND, 2, 0} -+ , /* ch52,54,56,..,64 */ -+ {UNII2C_LOWER_BOUND, UNII2C_UPPER_BOUND, 2, 0} -+ , /* ch100,102,104,...,144 */ -+ {UNII3_LOWER_BOUND, UNII3_UPPER_BOUND, 2, 0} -+ /* ch149,151,153,....,173 */ -+}; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in/out] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+P_DOMAIN_INFO_ENTRY rlmDomainGetDomainInfo(P_ADAPTER_T prAdapter) -+{ -+#define REG_DOMAIN_DEF_IDX 20 /* Default country domain */ -+#define REG_DOMAIN_GROUP_NUM \ -+ (sizeof(arSupportedRegDomains) / sizeof(DOMAIN_INFO_ENTRY)) -+ -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ P_REG_INFO_T prRegInfo; -+ UINT_16 u2TargetCountryCode; -+ UINT_16 i, j; -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->prDomainInfo) -+ return prAdapter->prDomainInfo; -+ -+ prRegInfo = &prAdapter->prGlueInfo->rRegInfo; -+ -+ DBGLOG(RLM, TRACE, "eRegChannelListMap=%d, u2CountryCode=0x%04x\n", -+ prRegInfo->eRegChannelListMap, -+ prAdapter->rWifiVar.rConnSettings.u2CountryCode); -+ -+ /* -+ * Domain info can be specified by given idx of arSupportedRegDomains table, -+ * customized, or searched by country code, -+ * only one is set among these three methods in NVRAM. -+ */ -+ if (prRegInfo->eRegChannelListMap == REG_CH_MAP_TBL_IDX && -+ prRegInfo->ucRegChannelListIndex < REG_DOMAIN_GROUP_NUM) { -+ /* by given table idx */ -+ DBGLOG(RLM, TRACE, "ucRegChannelListIndex=%d\n", prRegInfo->ucRegChannelListIndex); -+ prDomainInfo = &arSupportedRegDomains[prRegInfo->ucRegChannelListIndex]; -+ } else if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) { -+ /* by customized */ -+ prDomainInfo = &prRegInfo->rDomainInfo; -+ } else { -+ /* by country code */ -+ u2TargetCountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; -+ -+ for (i = 0; i < REG_DOMAIN_GROUP_NUM; i++) { -+ prDomainInfo = &arSupportedRegDomains[i]; -+ -+ if ((prDomainInfo->u4CountryNum && prDomainInfo->pu2CountryGroup) || -+ prDomainInfo->u4CountryNum == 0) { -+ for (j = 0; j < prDomainInfo->u4CountryNum; j++) { -+ if (prDomainInfo->pu2CountryGroup[j] == u2TargetCountryCode) -+ break; -+ } -+ if (j < prDomainInfo->u4CountryNum) -+ break; /* Found */ -+ } -+ } -+ -+ /* If no matched country code, use the default country domain */ -+ if (i >= REG_DOMAIN_GROUP_NUM) { -+ DBGLOG(RLM, INFO, "No matched country code, use the default country domain\n"); -+ prDomainInfo = &arSupportedRegDomains[REG_DOMAIN_DEF_IDX]; -+ } -+ } -+ -+ prAdapter->prDomainInfo = prDomainInfo; -+ return prDomainInfo; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in/out] The input variable pointed by pucNumOfChannel is the max -+* arrary size. The return value indciates meaning list size. -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rlmDomainGetChnlList(P_ADAPTER_T prAdapter, -+ ENUM_BAND_T eSpecificBand, BOOLEAN fgNoDfs, -+ UINT_8 ucMaxChannelNum, PUINT_8 pucNumOfChannel, P_RF_CHANNEL_INFO_T paucChannelList) -+{ -+ UINT_8 i, j, ucNum; -+ P_DOMAIN_SUBBAND_INFO prSubband; -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(paucChannelList); -+ ASSERT(pucNumOfChannel); -+ -+ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); -+ ASSERT(prDomainInfo); -+ -+ ucNum = 0; -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ prSubband = &prDomainInfo->rSubBand[i]; -+ -+ if (prSubband->ucBand == BAND_NULL || prSubband->ucBand >= BAND_NUM || -+ (prSubband->ucBand == BAND_5G && !prAdapter->fgEnable5GBand)) -+ continue; -+ -+ if (fgNoDfs == TRUE && prSubband->fgDfs == TRUE) -+ continue; -+ -+ if (eSpecificBand == BAND_NULL || prSubband->ucBand == eSpecificBand) { -+ for (j = 0; j < prSubband->ucNumChannels; j++) { -+ if (ucNum >= ucMaxChannelNum) -+ break; -+ paucChannelList[ucNum].eBand = prSubband->ucBand; -+ paucChannelList[ucNum].ucChannelNum = -+ prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan; -+ ucNum++; -+ } -+ } -+ } -+ -+ *pucNumOfChannel = ucNum; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainSendCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid) -+{ -+ rlmDomainSendDomainInfoCmd(prAdapter, fgIsOid); -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ rlmDomainSendPwrLimitCmd(prAdapter); -+#endif -+ rlmDomainSendPassiveScanInfoCmd(prAdapter, fgIsOid); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainSendDomainInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid) -+{ -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ P_CMD_SET_DOMAIN_INFO_T prCmd; -+ P_DOMAIN_SUBBAND_INFO prSubBand; -+ UINT_8 i; -+ -+ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); -+ ASSERT(prDomainInfo); -+ -+ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_DOMAIN_INFO_T)); -+ if (!prCmd) { -+ DBGLOG(RLM, ERROR, "Alloc cmd buffer failed\n"); -+ return; -+ } -+ kalMemZero(prCmd, sizeof(CMD_SET_DOMAIN_INFO_T)); -+ -+ prCmd->u2CountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; -+ prCmd->u2IsSetPassiveScan = 0; -+ prCmd->uc2G4Bandwidth = prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode; -+ prCmd->uc5GBandwidth = prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode; -+ prCmd->aucReserved[0] = 0; -+ prCmd->aucReserved[1] = 0; -+ -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ prSubBand = &prDomainInfo->rSubBand[i]; -+ -+ prCmd->rSubBand[i].ucRegClass = prSubBand->ucRegClass; -+ prCmd->rSubBand[i].ucBand = prSubBand->ucBand; -+ -+ if (prSubBand->ucBand != BAND_NULL && prSubBand->ucBand < BAND_NUM) { -+ prCmd->rSubBand[i].ucChannelSpan = prSubBand->ucChannelSpan; -+ prCmd->rSubBand[i].ucFirstChannelNum = prSubBand->ucFirstChannelNum; -+ prCmd->rSubBand[i].ucNumChannels = prSubBand->ucNumChannels; -+ } -+ } -+ -+ /* Set domain info to chip */ -+ wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_DOMAIN_INFO, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ fgIsOid, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_SET_DOMAIN_INFO_T), /* u4SetQueryInfoLen */ -+ (PUINT_8)prCmd, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ cnmMemFree(prAdapter, prCmd); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainSendPassiveScanInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid) -+{ -+#define REG_DOMAIN_PASSIVE_DEF_IDX 0 -+#define REG_DOMAIN_PASSIVE_UDF_IDX 1 -+ -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ P_CMD_SET_DOMAIN_INFO_T prCmd; -+ P_DOMAIN_SUBBAND_INFO prSubBand; -+ UINT_8 i; -+ -+ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_DOMAIN_INFO_T)); -+ if (!prCmd) { -+ DBGLOG(RLM, ERROR, "Alloc cmd buffer failed\n"); -+ return; -+ } -+ kalMemZero(prCmd, sizeof(CMD_SET_DOMAIN_INFO_T)); -+ -+ prCmd->u2CountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; -+ prCmd->u2IsSetPassiveScan = 1; -+ prCmd->uc2G4Bandwidth = prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode; -+ prCmd->uc5GBandwidth = prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode; -+ prCmd->aucReserved[0] = 0; -+ prCmd->aucReserved[1] = 0; -+ -+ DBGLOG(RLM, TRACE, "u2CountryCode=0x%04x\n", prAdapter->rWifiVar.rConnSettings.u2CountryCode); -+ -+ if (prAdapter->rWifiVar.rConnSettings.u2CountryCode == COUNTRY_CODE_UDF) -+ prDomainInfo = &arSupportedRegDomains_Passive[REG_DOMAIN_PASSIVE_UDF_IDX]; -+ else -+ prDomainInfo = &arSupportedRegDomains_Passive[REG_DOMAIN_PASSIVE_DEF_IDX]; -+ -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ prSubBand = &prDomainInfo->rSubBand[i]; -+ -+ prCmd->rSubBand[i].ucRegClass = prSubBand->ucRegClass; -+ prCmd->rSubBand[i].ucBand = prSubBand->ucBand; -+ -+ if (prSubBand->ucBand != BAND_NULL && prSubBand->ucBand < BAND_NUM) { -+ prCmd->rSubBand[i].ucChannelSpan = prSubBand->ucChannelSpan; -+ prCmd->rSubBand[i].ucFirstChannelNum = prSubBand->ucFirstChannelNum; -+ prCmd->rSubBand[i].ucNumChannels = prSubBand->ucNumChannels; -+ } -+ } -+ -+ /* Set passive scan channel info to chip */ -+ wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_DOMAIN_INFO, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ fgIsOid, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_SET_DOMAIN_INFO_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmd, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ cnmMemFree(prAdapter, prCmd); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in/out] -+* -+* \return TRUE Legal channel -+* FALSE Illegal channel for current regulatory domain -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rlmDomainIsLegalChannel(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, UINT_8 ucChannel) -+{ -+ UINT_8 i, j; -+ P_DOMAIN_SUBBAND_INFO prSubband; -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ -+ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); -+ ASSERT(prDomainInfo); -+ -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ prSubband = &prDomainInfo->rSubBand[i]; -+ -+ if (prSubband->ucBand == BAND_5G && !prAdapter->fgEnable5GBand) -+ continue; -+ -+ if (prSubband->ucBand == eBand) { -+ for (j = 0; j < prSubband->ucNumChannels; j++) { -+ if ((prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan) -+ == ucChannel) { -+ return TRUE; -+ } -+ } -+ } -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in/out] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+UINT_32 rlmDomainSupOperatingClassIeFill(PUINT_8 pBuf) -+{ -+ /* -+ The Country element should only be included for Status Code 0 (Successful). -+ */ -+ UINT_32 u4IeLen; -+ UINT_8 aucClass[12] = { 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, 0x1b, -+ 0x1c, 0x1e, 0x20, 0x21 -+ }; -+ -+ /* -+ The Supported Operating Classes element is used by a STA to advertise the -+ operating classes that it is capable of operating with in this country. -+ -+ The Country element (see 8.4.2.10) allows a STA to configure its PHY and MAC -+ for operation when the operating triplet of Operating Extension Identifier, -+ Operating Class, and Coverage Class fields is present. -+ */ -+ SUP_OPERATING_CLASS_IE(pBuf)->ucId = ELEM_ID_SUP_OPERATING_CLASS; -+ SUP_OPERATING_CLASS_IE(pBuf)->ucLength = 1 + sizeof(aucClass); -+ SUP_OPERATING_CLASS_IE(pBuf)->ucCur = 0x0c; /* 0x51 */ -+ kalMemCopy(SUP_OPERATING_CLASS_IE(pBuf)->ucSup, aucClass, sizeof(aucClass)); -+ u4IeLen = (SUP_OPERATING_CLASS_IE(pBuf)->ucLength + 2); -+ pBuf += u4IeLen; -+ -+ COUNTRY_IE(pBuf)->ucId = ELEM_ID_COUNTRY_INFO; -+ COUNTRY_IE(pBuf)->ucLength = 6; -+ COUNTRY_IE(pBuf)->aucCountryStr[0] = 0x55; -+ COUNTRY_IE(pBuf)->aucCountryStr[1] = 0x53; -+ COUNTRY_IE(pBuf)->aucCountryStr[2] = 0x20; -+ COUNTRY_IE(pBuf)->arCountryStr[0].ucFirstChnlNum = 1; -+ COUNTRY_IE(pBuf)->arCountryStr[0].ucNumOfChnl = 11; -+ COUNTRY_IE(pBuf)->arCountryStr[0].cMaxTxPwrLv = 0x1e; -+ u4IeLen += (COUNTRY_IE(pBuf)->ucLength + 2); -+ -+ return u4IeLen; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (fgValid) : 0 -> inValid, 1 -> Valid -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rlmDomainCheckChannelEntryValid(P_ADAPTER_T prAdapter, UINT_8 ucCentralCh) -+{ -+ BOOLEAN fgValid = FALSE; -+ UINT_8 ucTemp = 0; -+ UINT_8 i; -+ /*Check Power limit table channel efficient or not */ -+ -+ for (i = POWER_LIMIT_2G4; i < POWER_LIMIT_SUBAND_NUM; i++) { -+ if ((ucCentralCh >= g_rRlmSubBand[i].ucStartCh) && (ucCentralCh <= g_rRlmSubBand[i].ucEndCh)) -+ ucTemp = (ucCentralCh - g_rRlmSubBand[i].ucStartCh) % g_rRlmSubBand[i].ucInterval; -+ } -+ -+#if 0 -+ /*2.4G, ex 1, 2, 3 */ -+ if (ucCentralCh >= BAND_2G4_LOWER_BOUND && ucCentralCh <= BAND_2G4_UPPER_BOUND) -+ ucTemp = 0; -+ /*FCC- Spec : Band UNII-1, ex 36, 38, 40.... */ -+ else if (ucCentralCh >= UNII1_LOWER_BOUND && ucCentralCh <= UNII1_UPPER_BOUND) -+ ucTemp = (ucCentralCh - UNII1_LOWER_BOUND) % 2; -+ /*FCC- Spec : Band UNII-2A, ex 52, 54, 56.... */ -+ else if (ucCentralCh >= UNII2A_LOWER_BOUND && ucCentralCh <= UNII2A_UPPER_BOUND) -+ ucTemp = (ucCentralCh - UNII2A_LOWER_BOUND) % 2; -+ /*FCC- Spec : Band UNII-2C, ex 100, 102, 104.... */ -+ else if (ucCentralCh >= UNII2C_LOWER_BOUND && ucCentralCh <= UNII2C_UPPER_BOUND) -+ ucTemp = (ucCentralCh - UNII2C_LOWER_BOUND) % 2; -+ /*FCC- Spec : Band UNII-3, ex 149, 151, 153... */ -+ else if (ucCentralCh >= UNII3_LOWER_BOUND && ucCentralCh <= UNII3_UPPER_BOUND) -+ ucTemp = (ucCentralCh - UNII3_LOWER_BOUND) % 2; -+#endif -+ if (ucTemp == 0) -+ fgValid = TRUE; -+ return fgValid; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 rlmDomainGetCenterChannel(ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) -+{ -+ UINT_8 ucCenterChannel; -+ -+ if (eExtend == CHNL_EXT_SCA) -+ ucCenterChannel = ucPriChannel + 2; -+ else if (eExtend == CHNL_EXT_SCB) -+ ucCenterChannel = ucPriChannel - 2; -+ else -+ ucCenterChannel = ucPriChannel; -+ -+ return ucCenterChannel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+rlmDomainIsValidRfSetting(P_ADAPTER_T prAdapter, -+ ENUM_BAND_T eBand, -+ UINT_8 ucPriChannel, -+ ENUM_CHNL_EXT_T eExtend, -+ ENUM_CHANNEL_WIDTH_T eChannelWidth, UINT_8 ucChannelS1, UINT_8 ucChannelS2) -+{ -+ UINT_8 ucCenterChannel; -+ BOOLEAN fgValidChannel = TRUE; -+ BOOLEAN fgValidBW = TRUE; -+ BOOLEAN fgValidRfSetting = TRUE; -+ UINT_32 u4PrimaryOffset; -+ -+ /*DBG msg for Channel InValid */ -+ if (eChannelWidth == CW_20_40MHZ) { -+ ucCenterChannel = rlmDomainGetCenterChannel(eBand, ucPriChannel, eExtend); -+ -+ /* Check Central Channel Valid or Not */ -+ fgValidChannel = rlmDomainCheckChannelEntryValid(prAdapter, ucCenterChannel); -+ if (fgValidChannel == FALSE) -+ DBGLOG(RLM, WARN, "Rf: CentralCh=%d\n", ucCenterChannel); -+ } else if (eChannelWidth == CW_80MHZ) { -+ ucCenterChannel = ucChannelS1; -+ -+ /* Check Central Channel Valid or Not */ -+ fgValidChannel = rlmDomainCheckChannelEntryValid(prAdapter, ucCenterChannel); -+ if (fgValidChannel == FALSE) -+ DBGLOG(RLM, WARN, "Rf: CentralCh=%d\n", ucCenterChannel); -+ } else if (eChannelWidth == CW_160MHZ) { -+ ucCenterChannel = ucChannelS2; -+ -+ /* Check Central Channel Valid or Not */ -+ /*TODo */ -+ } -+ -+ /* Check BW Setting Correct or Not */ -+ if (eBand == BAND_2G4) { -+ if (eChannelWidth != CW_20_40MHZ) { -+ fgValidBW = FALSE; -+ DBGLOG(RLM, WARN, "Rf: B=%d, W=%d\n", eBand, eChannelWidth); -+ } -+ } else { -+ if (eChannelWidth == CW_80MHZ) { -+ u4PrimaryOffset = CAL_CH_OFFSET_80M(ucPriChannel, ucCenterChannel); -+ if (u4PrimaryOffset > 4) { -+ fgValidBW = FALSE; -+ DBGLOG(RLM, WARN, "Rf: PriOffSet=%d, W=%d\n", u4PrimaryOffset, eChannelWidth); -+ } -+ } else if (eChannelWidth == CW_160MHZ) { -+ u4PrimaryOffset = CAL_CH_OFFSET_160M(ucPriChannel, ucCenterChannel); -+ if (u4PrimaryOffset > 8) { -+ fgValidBW = FALSE; -+ DBGLOG(RLM, WARN, "Rf: PriOffSet=%d, W=%d\n", u4PrimaryOffset, eChannelWidth); -+ } -+ } -+ } -+ -+ if ((fgValidBW == FALSE) || (fgValidChannel == FALSE)) -+ fgValidRfSetting = FALSE; -+ -+ return fgValidRfSetting; -+ -+} -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (fgValid) : 0 -> inValid, 1 -> Valid -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+rlmDomainCheckPowerLimitValid(P_ADAPTER_T prAdapter, -+ COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION rPowerLimitTableConfiguration, -+ UINT_8 ucPwrLimitNum) -+{ -+ UINT_8 i; -+ BOOLEAN fgValid = TRUE; -+ PINT_8 prPwrLimit; -+ -+ prPwrLimit = &rPowerLimitTableConfiguration.aucPwrLimit[0]; -+ -+ for (i = 0; i < ucPwrLimitNum; i++, prPwrLimit++) { -+ if (*prPwrLimit > MAX_TX_POWER || *prPwrLimit < MIN_TX_POWER) { -+ fgValid = FALSE; -+ break; /*Find out Wrong Power limit */ -+ } -+ } -+ return fgValid; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainCheckCountryPowerLimitTable(P_ADAPTER_T prAdapter) -+{ -+ UINT_8 i, j; -+ UINT_16 u2CountryCodeTable, u2CountryCodeCheck; -+ BOOLEAN fgChannelValid = FALSE; -+ BOOLEAN fgPowerLimitValid = FALSE; -+ BOOLEAN fgEntryRepetetion = FALSE; -+ BOOLEAN fgTableValid = TRUE; -+ -+ /*Configuration Table Check */ -+ for (i = 0; i < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); i++) { -+ /*Table Country Code */ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], &u2CountryCodeTable); -+ -+ /*Repetition Entry Check */ -+ for (j = i + 1; -+ j < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); -+ j++) { -+ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[j].aucCountryCode[0], &u2CountryCodeCheck); -+ if (((g_rRlmPowerLimitConfiguration[i].ucCentralCh) == -+ g_rRlmPowerLimitConfiguration[j].ucCentralCh) -+ && (u2CountryCodeTable == u2CountryCodeCheck)) { -+ fgEntryRepetetion = TRUE; -+ DBGLOG(RLM, LOUD, "Domain: Configuration Repetition CC=%c%c, Ch=%d\n", -+ g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], -+ g_rRlmPowerLimitConfiguration[i].aucCountryCode[1], -+ g_rRlmPowerLimitConfiguration[i].ucCentralCh); -+ } -+ } -+ -+ /*Channel Number Check */ -+ fgChannelValid = -+ rlmDomainCheckChannelEntryValid(prAdapter, g_rRlmPowerLimitConfiguration[i].ucCentralCh); -+ -+ /*Power Limit Check */ -+ fgPowerLimitValid = -+ rlmDomainCheckPowerLimitValid(prAdapter, g_rRlmPowerLimitConfiguration[i], PWR_LIMIT_NUM); -+ -+ if (fgChannelValid == FALSE || fgPowerLimitValid == FALSE) { -+ fgTableValid = FALSE; -+ DBGLOG(RLM, LOUD, "Domain: CC=%c%c, Ch=%d, Limit: %d,%d,%d,%d,%d\n", -+ g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], -+ g_rRlmPowerLimitConfiguration[i].aucCountryCode[1], -+ g_rRlmPowerLimitConfiguration[i].ucCentralCh, -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK], -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M], -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M], -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M], -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]); -+ } -+ -+ if (u2CountryCodeTable == COUNTRY_CODE_NULL) { -+ DBGLOG(RLM, LOUD, "Domain: Full search down\n"); -+ break; /*End of country table entry */ -+ } -+ -+ } -+ -+ if (fgEntryRepetetion == FALSE) -+ DBGLOG(RLM, TRACE, "Domain: Configuration Table no Repetiton.\n"); -+ -+ /*Configuration Table no error */ -+ if (fgTableValid == TRUE) -+ prAdapter->fgIsPowerLimitTableValid = TRUE; -+ else -+ prAdapter->fgIsPowerLimitTableValid = FALSE; -+ -+ /*Default Table Check */ -+ fgEntryRepetetion = FALSE; -+ for (i = 0; i < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); i++) { -+ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[i].aucCountryCode[0], &u2CountryCodeTable); -+ -+ for (j = i + 1; j < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); j++) { -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[j].aucCountryCode[0], &u2CountryCodeCheck); -+ if (u2CountryCodeTable == u2CountryCodeCheck) { -+ fgEntryRepetetion = TRUE; -+ DBGLOG(RLM, LOUD, -+ "Domain: Default Repetition CC=%c%c\n", -+ g_rRlmPowerLimitDefault[j].aucCountryCode[0], -+ g_rRlmPowerLimitDefault[j].aucCountryCode[1]); -+ } -+ } -+ } -+ if (fgEntryRepetetion == FALSE) -+ DBGLOG(RLM, TRACE, "Domain: Default Table no Repetiton.\n"); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (u2TableIndex) : if 0xFFFF -> No Table Match -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_16 rlmDomainPwrLimitDefaultTableDecision(P_ADAPTER_T prAdapter, UINT_16 u2CountryCode) -+{ -+ -+ UINT_16 i; -+ UINT_16 u2CountryCodeTable = COUNTRY_CODE_NULL; -+ UINT_16 u2TableIndex = POWER_LIMIT_TABLE_NULL; /* No Table Match */ -+ -+ /*Default Table Index */ -+ for (i = 0; i < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); i++) { -+ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[i].aucCountryCode[0], &u2CountryCodeTable); -+ -+ if (u2CountryCodeTable == u2CountryCode) { -+ u2TableIndex = i; -+ break; /*match country code */ -+ } else if (u2CountryCodeTable == COUNTRY_CODE_NULL) { -+ u2TableIndex = i; -+ break; /*find last one country- Default */ -+ } -+ } -+ -+ DBGLOG(RLM, TRACE, "Domain: Default Table Index = %d\n", u2TableIndex); -+ -+ return u2TableIndex; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainBuildCmdByDefaultTable(P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd, UINT_16 u2DefaultTableIndex) -+{ -+ UINT_8 i, k; -+ P_COUNTRY_POWER_LIMIT_TABLE_DEFAULT prPwrLimitSubBand; -+ P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit; -+ -+ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; -+ prPwrLimitSubBand = &g_rRlmPowerLimitDefault[u2DefaultTableIndex]; -+ -+ /*Build power limit cmd by default table information */ -+ -+ for (i = POWER_LIMIT_2G4; i < POWER_LIMIT_SUBAND_NUM; i++) { -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[i] < MAX_TX_POWER) { -+ for (k = g_rRlmSubBand[i].ucStartCh; k <= g_rRlmSubBand[i].ucEndCh; -+ k += g_rRlmSubBand[i].ucInterval) { -+ if ((prPwrLimitSubBand->ucPwrUnit & BIT(i)) == 0) { -+ prCmdPwrLimit->ucCentralCh = k; -+ prCmdPwrLimit->cPwrLimitCCK = -+ prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit20 = -+ prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit40 = -+ prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit80 = -+ prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit160 = -+ prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ -+ } else { -+ /* ex: 40MHz power limit(mW\MHz) = 20MHz power limit(mW\MHz) * 2 -+ * ---> 40MHz power limit(dBm) = 20MHz power limit(dBm) + 6; */ -+ prCmdPwrLimit->ucCentralCh = k; -+ prCmdPwrLimit->cPwrLimitCCK = prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit20 = prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit40 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 6; -+ if (prCmdPwrLimit->cPwrLimit40 > MAX_TX_POWER) -+ prCmdPwrLimit->cPwrLimit40 = MAX_TX_POWER; -+ prCmdPwrLimit->cPwrLimit80 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 12; -+ if (prCmdPwrLimit->cPwrLimit80 > MAX_TX_POWER) -+ prCmdPwrLimit->cPwrLimit80 = MAX_TX_POWER; -+ prCmdPwrLimit->cPwrLimit160 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 18; -+ if (prCmdPwrLimit->cPwrLimit160 > MAX_TX_POWER) -+ prCmdPwrLimit->cPwrLimit160 = MAX_TX_POWER; -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+ } -+ } -+ -+#if 0 -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_2G4] < MAX_TX_POWER) { -+ for (i = BAND_2G4_LOWER_BOUND; i <= BAND_2G4_UPPER_BOUND; i++) { -+ prCmdPwrLimit->ucCentralCh = i; -+ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_2G4], -+ PWR_LIMIT_NUM); -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+ -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII1] < MAX_TX_POWER) { -+ if (prCmd->u2CountryCode != COUNTRY_CODE_KR) { -+ for (i = UNII1_LOWER_BOUND; i <= UNII1_UPPER_BOUND; i += 2) { -+ prCmdPwrLimit->ucCentralCh = i; -+ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, -+ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII1], PWR_LIMIT_NUM); -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } else { -+ for (i = UNII1_LOWER_BOUND; i <= UNII1_UPPER_BOUND; i += 2) { -+ /* ex: 40MHz power limit(mW\MHz) = 20MHz power limit(mW\MHz) * 2 -+ * ---> 40MHz power limit(dBm) = 20MHz power limit(dBm) + 6; */ -+ prCmdPwrLimit->ucCentralCh = i; -+ prCmdPwrLimit->cPwrLimitCCK = -+ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1; -+ prCmdPwrLimit->cPwrLimit20 = -+ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1; -+ prCmdPwrLimit->cPwrLimit40 = -+ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 6; -+ prCmdPwrLimit->cPwrLimit80 = -+ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 12; -+ prCmdPwrLimit->cPwrLimit160 = -+ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 18; -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+ } -+ -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2A] < MAX_TX_POWER) { -+ for (i = UNII2A_LOWER_BOUND; i <= UNII2A_UPPER_BOUND; i += 2) { -+ prCmdPwrLimit->ucCentralCh = i; -+ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, -+ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2A], PWR_LIMIT_NUM); -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+ -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2C] < MAX_TX_POWER) { -+ for (i = UNII2C_LOWER_BOUND; i <= UNII2C_UPPER_BOUND; i += 2) { -+ prCmdPwrLimit->ucCentralCh = i; -+ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, -+ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2C], PWR_LIMIT_NUM); -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII3] < MAX_TX_POWER) { -+ for (i = UNII3_LOWER_BOUND; i <= UNII3_UPPER_BOUND; i += 2) { -+ prCmdPwrLimit->ucCentralCh = i; -+ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, -+ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII3], PWR_LIMIT_NUM); -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainBuildCmdByConfigTable(P_ADAPTER_T prAdapter, P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd) -+{ -+ UINT_8 i, k; -+ UINT_16 u2CountryCodeTable = COUNTRY_CODE_NULL; -+ P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit; -+ BOOLEAN fgChannelValid; -+ -+ /*Build power limit cmd by configuration table information */ -+ -+ for (i = 0; i < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); i++) { -+ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], &u2CountryCodeTable); -+ -+ fgChannelValid = -+ rlmDomainCheckChannelEntryValid(prAdapter, g_rRlmPowerLimitConfiguration[i].ucCentralCh); -+ -+ if (u2CountryCodeTable == COUNTRY_CODE_NULL) { -+ DBGLOG(RLM, TRACE, "Domain: full search configuration table done.\n"); -+ break; /*end of configuration table */ -+ } else if ((u2CountryCodeTable == prCmd->u2CountryCode) && (fgChannelValid == TRUE)) { -+ -+ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; -+ -+ if (prCmd->ucNum != 0) { -+ for (k = 0; k < prCmd->ucNum; k++) { -+ if (prCmdPwrLimit->ucCentralCh == -+ g_rRlmPowerLimitConfiguration[i].ucCentralCh) { -+ -+ /*Cmd setting (Default table information) and -+ Configuration table has repetition channel entry, -+ ex : Default table (ex: 2.4G, limit = 20dBm) --> ch1~14 limit =20dBm, -+ Configuration table (ex: ch1, limit = 22dBm) --> ch 1 = 22 dBm -+ Cmd final setting --> ch1 = 22dBm, ch12~14 = 20dBm -+ */ -+ prCmdPwrLimit->cPwrLimitCCK = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK]; -+ prCmdPwrLimit->cPwrLimit20 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M]; -+ prCmdPwrLimit->cPwrLimit40 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M]; -+ prCmdPwrLimit->cPwrLimit80 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M]; -+ prCmdPwrLimit->cPwrLimit160 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]; -+ -+ DBGLOG(RLM, LOUD, -+ "Domain: CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", -+ ((prCmd->u2CountryCode & 0xff00) >> 8), -+ (prCmd->u2CountryCode & 0x00ff), prCmdPwrLimit->ucCentralCh, -+ prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20, -+ prCmdPwrLimit->cPwrLimit40, prCmdPwrLimit->cPwrLimit80, -+ prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag); -+ -+ break; -+ } -+ prCmdPwrLimit++; -+ } -+ if (k == prCmd->ucNum) { -+ -+ /*Full search cmd (Default table setting) no match channey, -+ ex : Default table (ex: 2.4G, limit = 20dBm) --> ch1~14 limit =20dBm, -+ Configuration table (ex: ch36, limit = 22dBm) --> ch 36 = 22 dBm -+ Cmd final setting --> ch1~14 = 20dBm, ch36= 22dBm -+ */ -+ prCmdPwrLimit->cPwrLimitCCK = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK]; -+ prCmdPwrLimit->cPwrLimit20 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M]; -+ prCmdPwrLimit->cPwrLimit40 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M]; -+ prCmdPwrLimit->cPwrLimit80 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M]; -+ prCmdPwrLimit->cPwrLimit160 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]; -+ prCmd->ucNum++; -+ -+ DBGLOG(RLM, LOUD, -+ "Domain: Full CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", -+ ((prCmd->u2CountryCode & 0xff00) >> 8), (prCmd->u2CountryCode & 0x00ff), -+ prCmdPwrLimit->ucCentralCh, prCmdPwrLimit->cPwrLimitCCK, -+ prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40, -+ prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160, -+ prCmdPwrLimit->ucFlag); -+ -+ } -+ } else { -+ -+ /*Default table power limit value are 63--> cmd table no channel entry -+ ex : Default table (ex: 2.4G, limit = 63Bm) --> no channel entry in cmd, -+ Configuration table (ex: ch36, limit = 22dBm) --> ch 36 = 22 dBm -+ Cmd final setting --> ch36= 22dBm -+ */ -+ prCmdPwrLimit->ucCentralCh = g_rRlmPowerLimitConfiguration[i].ucCentralCh; -+ prCmdPwrLimit->cPwrLimitCCK = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK]; -+ prCmdPwrLimit->cPwrLimit20 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M]; -+ prCmdPwrLimit->cPwrLimit40 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M]; -+ prCmdPwrLimit->cPwrLimit80 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M]; -+ prCmdPwrLimit->cPwrLimit160 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]; -+ prCmd->ucNum++; -+ -+ DBGLOG(RLM, LOUD, "Domain: Default table power limit value are 63.\n"); -+ DBGLOG(RLM, LOUD, "Domain: CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", -+ ((prCmd->u2CountryCode & 0xff00) >> 8), -+ (prCmd->u2CountryCode & 0x00ff), prCmdPwrLimit->ucCentralCh, -+ prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20, -+ prCmdPwrLimit->cPwrLimit40, prCmdPwrLimit->cPwrLimit80, -+ prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag); -+ -+ } -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainSendPwrLimitCmd(P_ADAPTER_T prAdapter) -+{ -+ P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd; -+ UINT_8 i; -+ UINT_16 u2DefaultTableIndex; -+ UINT_32 u4SetCmdTableMaxSize; -+ UINT_32 u4SetQueryInfoLen; -+ P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit; /* for print usage */ -+ -+ u4SetCmdTableMaxSize = -+ sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) + -+ MAX_CMD_SUPPORT_CHANNEL_NUM * sizeof(CMD_CHANNEL_POWER_LIMIT); -+ -+ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4SetCmdTableMaxSize); -+ -+ if (!prCmd) { -+ DBGLOG(RLM, ERROR, "Domain: no buf to send cmd\n"); -+ return; -+ } -+ kalMemZero(prCmd, u4SetCmdTableMaxSize); -+ -+ u2DefaultTableIndex = -+ rlmDomainPwrLimitDefaultTableDecision(prAdapter, prAdapter->rWifiVar.rConnSettings.u2CountryCode); -+ -+ if (u2DefaultTableIndex != POWER_LIMIT_TABLE_NULL) { -+ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[u2DefaultTableIndex].aucCountryCode[0], -+ &prCmd->u2CountryCode); -+ -+ prCmd->ucNum = 0; -+ -+ if (prCmd->u2CountryCode != COUNTRY_CODE_NULL) { -+ /*Command - default table information */ -+ rlmDomainBuildCmdByDefaultTable(prCmd, u2DefaultTableIndex); -+ -+ /*Command - configuration table information */ -+ rlmDomainBuildCmdByConfigTable(prAdapter, prCmd); -+ } -+ } -+#if 0 -+ u4SetCmdTableMaxSize = -+ sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) + -+ MAX_CMD_SUPPORT_CHANNEL_NUM * sizeof(CMD_CHANNEL_POWER_LIMIT); -+ -+ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4SetCmdTableMaxSize); -+ ASSERT(prCmd); -+ -+ /* To do: exception handle */ -+ if (!prCmd) { -+ DBGLOG(RLM, ERROR, "Domain: no buf to send cmd\n"); -+ return; -+ } -+ kalMemZero(prCmd, u4SetCmdTableMaxSize); /* TODO memzero */ -+ -+ if (u2TableIndex != POWER_LIMIT_TABLE_NULL && u2TableIndex < MAX_DEFAULT_TABLE_COUNTRY_NUM) { -+ -+ prCmd->u2CountryCode = (((UINT_16) g_rRlmCountryPowerLimitTable[u2TableIndex].aucCountryCode[0]) << 8) | -+ (((UINT_16) g_rRlmCountryPowerLimitTable[u2TableIndex].aucCountryCode[1]) & BITS(0, 7)); -+ prChPwrLimit = &g_rRlmCountryPowerLimitTable[u2TableIndex].rChannelPowerLimit[0]; -+ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; -+ prCmd->ucNum = 0; -+ for (i = 0; i < MAX_CMD_SUPPORT_CHANNEL_NUM; i++) { -+ -+ if (prChPwrLimit->ucCentralCh != ENDCH) { -+ -+ /*Check Power limit table channel efficient or not */ -+ fgChannelValid = rlmDomainCheckChannelEntryValid(prAdapter, prChPwrLimit->ucCentralCh); -+ -+ /*Cmd set up */ -+ if (fgChannelValid) { -+ kalMemCopy(prCmdPwrLimit, prChPwrLimit, sizeof(CMD_CHANNEL_POWER_LIMIT)); -+ DBGLOG(RLM, INFO, -+ "Domain: ValidCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", -+ prCmdPwrLimit->ucCentralCh, prCmdPwrLimit->cPwrLimitCCK, -+ prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40, -+ prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160, -+ prCmdPwrLimit->ucFlag); -+ prCmd->ucNum++; -+ prCmdPwrLimit++; -+ } else { -+ DBGLOG(RLM, INFO, -+ "Domain: Non-Ch=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", -+ prChPwrLimit->ucCentralCh, prChPwrLimit->cPwrLimitCCK, -+ prChPwrLimit->cPwrLimit20, prChPwrLimit->cPwrLimit40, -+ prChPwrLimit->cPwrLimit80, prChPwrLimit->cPwrLimit160, -+ prChPwrLimit->ucFlag); -+ } -+ prChPwrLimit++; -+ } else { -+ /*End of the chanel entry */ -+ break; -+ } -+ }; -+ } -+#endif -+ -+ if (prCmd->u2CountryCode != 0) { -+ DBGLOG(RLM, INFO, -+ "Domain: ValidCC =%c%c, ChNum=%d\n", ((prCmd->u2CountryCode & 0xff00) >> 8), -+ (prCmd->u2CountryCode & 0x00ff), prCmd->ucNum); -+ } else { -+ DBGLOG(RLM, INFO, "Domain: ValidCC =0x%04x, ucNum=%d\n", prCmd->u2CountryCode, prCmd->ucNum); -+ } -+ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; -+ -+ for (i = 0; i < prCmd->ucNum; i++) { -+ DBGLOG(RLM, TRACE, "Domain: Ch=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", prCmdPwrLimit->ucCentralCh, -+ prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40, -+ prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag); -+ prCmdPwrLimit++; -+ } -+ -+ u4SetQueryInfoLen = -+ (sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) + (prCmd->ucNum) * sizeof(CMD_CHANNEL_POWER_LIMIT)); -+ -+ /* Update domain info to chip */ -+ if (prCmd->ucNum <= MAX_CMD_SUPPORT_CHANNEL_NUM) { -+ wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_COUNTRY_POWER_LIMIT, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ u4SetQueryInfoLen, /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmd, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ } else -+ DBGLOG(RLM, ERROR, "Domain: illegal power limit table"); -+ -+ cnmMemFree(prAdapter, prCmd); -+ -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c -new file mode 100644 -index 0000000000000..8450124a3f38e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c -@@ -0,0 +1,436 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_obss.c#2 -+*/ -+ -+/*! \file "rlm_obss.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: rlm_obss.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Avoid possible OBSS scan when BSS is switched -+ * -+ * 11 08 2011 cm.chang -+ * NULL -+ * Add RLM and CNM debug message for XLOG -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * Regulation class is changed to 81 in 20_40_coexistence action frame -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 03 29 2011 cm.chang -+ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning -+ * As CR title -+ * -+ * 01 24 2011 cm.chang -+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame -+ * in AP mode and stop ampdu timer when sta_rec is freed -+ * Process received 20/40 coexistence action frame for AP mode -+ * -+ * 01 13 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Refine function when rcv a 20/40M public action frame -+ * -+ * 01 13 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * Use SCO of BSS_INFO to replace user-defined setting variables -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * use definition macro to replace hard-coded constant -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Change conditional compiling options for BOW -+ * -+ * 09 10 2010 cm.chang -+ * NULL -+ * Always update Beacon content if FW sync OBSS info -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Fix compile error while enabling WiFi Direct function. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 05 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Process 20/40 coexistence public action frame in AP mode -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft support for 20/40M bandwidth for AP mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add more ASSERT to check exception -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add virtual test for OBSS scan -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * To support CFG_SUPPORT_BCM_STP -+ * -+ * 02 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support PCO in STA mode -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static VOID rlmObssScanTimeout(P_ADAPTER_T prAdapter, ULONG ulData); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmObssInit(P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prBssInfo; -+ UINT_8 ucNetIdx; -+ -+ RLM_NET_FOR_EACH(ucNetIdx) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx]; -+ ASSERT(prBssInfo); -+ -+ cnmTimerInitTimer(prAdapter, &prBssInfo->rObssScanTimer, rlmObssScanTimeout, (ULONG) prBssInfo); -+ } /* end of RLM_NET_FOR_EACH */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rlmObssUpdateChnlLists(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) -+{ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmObssScanDone(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SCN_SCAN_DONE prScanDoneMsg; -+ P_BSS_INFO_T prBssInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ P_ACTION_20_40_COEXIST_FRAME prTxFrame; -+ UINT_16 i, u2PayloadLen; -+ -+ ASSERT(prMsgHdr); -+ -+ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prScanDoneMsg->ucNetTypeIndex]; -+ ASSERT(prBssInfo); -+ -+ DBGLOG(RLM, INFO, "OBSS Scan Done (NetIdx=%d, Mode=%d)\n", -+ prScanDoneMsg->ucNetTypeIndex, prBssInfo->eCurrentOPMode); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* AP mode */ -+ if ((prAdapter->fgIsP2PRegistered) && -+ (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex)) && -+ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { -+ return; -+ } -+#endif -+ -+ /* STA mode */ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || -+ !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) { -+ DBGLOG(RLM, WARN, "OBSS Scan Done (NetIdx=%d) -- Aborted!!\n", prBssInfo->ucNetTypeIndex); -+ return; -+ } -+ -+ /* To do: check 2.4G channel list to decide if obss mgmt should be -+ * sent to associated AP. Note: how to handle concurrent network? -+ * To do: invoke rlmObssChnlLevel() to decide if 20/40 BSS coexistence -+ * management frame is needed. -+ */ -+ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); -+ if ((prBssInfo->auc2G_20mReqChnlList[0] > 0 || prBssInfo->auc2G_NonHtChnlList[0] > 0) && prMsduInfo != NULL) { -+ DBGLOG(RLM, INFO, "Send 20/40 coexistence mgmt(20mReq=%d, NonHt=%d)\n", -+ prBssInfo->auc2G_20mReqChnlList[0], prBssInfo->auc2G_NonHtChnlList[0]); -+ -+ prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) -+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; -+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); -+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); -+ -+ prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION; -+ prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST; -+ -+ /* To do: find correct algorithm */ -+ prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE; -+ prTxFrame->rBssCoexist.ucLength = 1; -+ prTxFrame->rBssCoexist.ucData = (prBssInfo->auc2G_20mReqChnlList[0] > 0) ? BSS_COEXIST_20M_REQ : 0; -+ -+ u2PayloadLen = 2 + 3; -+ -+ if (prBssInfo->auc2G_NonHtChnlList[0] > 0) { -+ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); -+ -+ prTxFrame->rChnlReport.ucId = ELEM_ID_20_40_INTOLERANT_CHNL_REPORT; -+ prTxFrame->rChnlReport.ucLength = prBssInfo->auc2G_NonHtChnlList[0] + 1; -+ prTxFrame->rChnlReport.ucRegulatoryClass = 81; /* 2.4GHz, ch1~13 */ -+ for (i = 0; i < prBssInfo->auc2G_NonHtChnlList[0] && i < CHNL_LIST_SZ_2G; i++) -+ prTxFrame->rChnlReport.aucChannelList[i] = prBssInfo->auc2G_NonHtChnlList[i + 1]; -+ -+ u2PayloadLen += IE_SIZE(&prTxFrame->rChnlReport); -+ } -+ ASSERT((WLAN_MAC_HEADER_LEN + u2PayloadLen) <= PUBLIC_ACTION_MAX_LEN); -+ -+ /* Clear up channel lists in 2.4G band */ -+ prBssInfo->auc2G_20mReqChnlList[0] = 0; -+ prBssInfo->auc2G_NonHtChnlList[0] = 0; -+ -+ /* 4 Update information of MSDU_INFO_T */ -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ -+ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; -+ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ /* 4 Enqueue the frame to send this action frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ } -+ /* end of prMsduInfo != NULL */ -+ if (prBssInfo->u2ObssScanInterval > 0) { -+ DBGLOG(RLM, INFO, "Set OBSS timer (NetIdx=%d, %d sec)\n", -+ prBssInfo->ucNetTypeIndex, prBssInfo->u2ObssScanInterval); -+ -+ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID rlmObssScanTimeout(P_ADAPTER_T prAdapter, ULONG ulData) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ prBssInfo = (P_BSS_INFO_T) ulData; -+ ASSERT(prBssInfo); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex))) { -+ -+ /* AP mode */ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ -+ prBssInfo->fgObssActionForcedTo20M = FALSE; -+ -+ /* Check if Beacon content need to be updated */ -+ rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE); -+ -+ return; -+ } -+#if CFG_SUPPORT_WFD -+ /* WFD streaming */ -+ else { -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = -+ &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ P_BSS_INFO_T prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ -+ /* If WFD is enabled & connected */ -+ if (prWfdCfgSettings->ucWfdEnable && -+ (prWfdCfgSettings->u4WfdFlag & BIT(0)) && RLM_NET_PARAM_VALID(prP2pBssInfo)) { -+ -+ /* Skip OBSS scan */ -+ prBssInfo->u2ObssScanInterval = 0; -+ -+ DBGLOG(RLM, INFO, "WFD is running. Stop net[%u] OBSS scan.\n", -+ (UINT_32) prBssInfo->ucNetTypeIndex); -+ -+ return; -+ } -+ } -+#endif -+ } -+#endif /* end of CFG_ENABLE_WIFI_DIRECT */ -+ -+ /* STA mode */ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || -+ !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) { -+ DBGLOG(RLM, WARN, "OBSS Scan timeout (NetIdx=%d) -- Aborted!!\n", prBssInfo->ucNetTypeIndex); -+ return; -+ } -+ -+ rlmObssTriggerScan(prAdapter, prBssInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmObssTriggerScan(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ P_MSG_SCN_SCAN_REQ prScanReqMsg; -+ -+ ASSERT(prBssInfo); -+ -+ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) -+ cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); -+ ASSERT(prScanReqMsg); -+ -+ if (!prScanReqMsg) { -+ DBGLOG(RLM, WARN, "No buf for OBSS scan (NetIdx=%d)!!\n", prBssInfo->ucNetTypeIndex); -+ -+ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); -+ return; -+ } -+ -+ /* It is ok that ucSeqNum is set to fixed value because the same network -+ * OBSS scan interval is limited to OBSS_SCAN_MIN_INTERVAL (min 10 sec) -+ * and scan module don't care seqNum of OBSS scanning -+ */ -+ prScanReqMsg->rMsgHdr.eMsgId = MID_RLM_SCN_SCAN_REQ; -+ prScanReqMsg->ucSeqNum = 0x33; -+ prScanReqMsg->ucNetTypeIndex = prBssInfo->ucNetTypeIndex; -+ prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD; -+ prScanReqMsg->ucSSIDLength = 0; -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; -+ prScanReqMsg->u2IELen = 0; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); -+ -+ DBGLOG(RLM, INFO, "Timeout to trigger OBSS scan (NetIdx=%d)!!\n", prBssInfo->ucNetTypeIndex); -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c -new file mode 100644 -index 0000000000000..d3c5133970956 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c -@@ -0,0 +1,105 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_protection.c#1 -+*/ -+ -+/*! \file "rlm_protection.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: rlm_protection.c -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 05 28 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Set RTS threshold of 2K bytes initially -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 03 31 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Enable RTS threshold temporarily for AMPDU -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * To support CFG_SUPPORT_BCM_STP -+ * -+ * 02 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support PCO in STA mode -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 01 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c -new file mode 100644 -index 0000000000000..3f088c2839936 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c -@@ -0,0 +1,539 @@ -+/* -+** Id: -+*/ -+ -+/*! \file "roaming_fsm.c" -+ \brief This file defines the FSM for Roaming MODULE. -+ -+ This file defines the FSM for Roaming MODULE. -+*/ -+ -+/* -+** Log: roaming_fsm.c -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 08 31 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * remove obsolete code. -+ * -+ * 08 15 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * add swcr in driver reg, 0x9fxx0000, to disable roaming . -+ * -+ * 03 16 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * remove obsolete definition and unused variables. -+ * -+ * 02 26 2011 tsaiyuan.hsu -+ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support -+ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_SUPPORT_ROAMING -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugRoamingState[ROAMING_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("ROAMING_STATE_IDLE"), -+ (PUINT_8) DISP_STRING("ROAMING_STATE_DECISION"), -+ (PUINT_8) DISP_STRING("ROAMING_STATE_DISCOVERY"), -+ (PUINT_8) DISP_STRING("ROAMING_STATE_ROAM") -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* -+#define ROAMING_ENABLE_CHECK(_roam) \ -+{ \ -+ if (!(_roam->fgIsEnableRoaming)) \ -+ return; \ -+} -+*/ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialize the value in ROAMING_FSM_INFO_T for ROAMING FSM operation -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmInit(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ DBGLOG(ROAMING, LOUD, "->roamingFsmInit(): Current Time = %u\n", kalGetTimeTick()); -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* 4 <1> Initiate FSM */ -+ prRoamingFsmInfo->fgIsEnableRoaming = prConnSettings->fgIsEnableRoaming; -+ prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE; -+ prRoamingFsmInfo->rRoamingDiscoveryUpdateTime = 0; -+ -+} /* end of roamingFsmInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Uninitialize the value in AIS_FSM_INFO_T for AIS FSM operation -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmUninit(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ -+ DBGLOG(ROAMING, LOUD, "->roamingFsmUninit(): Current Time = %u\n", kalGetTimeTick()); -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE; -+ -+} /* end of roamingFsmUninit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Send commands to firmware -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* [IN P_ROAMING_PARAM_T] prParam -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmSendCmd(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ WLAN_STATUS rStatus; -+ -+ DBGLOG(ROAMING, LOUD, "->roamingFsmSendCmd(): Current Time = %u\n", kalGetTimeTick()); -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_ROAMING_TRANSIT, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(ROAMING_PARAM_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prParam, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+} /* end of roamingFsmSendCmd() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Update the recent time when ScanDone occurred -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmScanResultsUpdate(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ /* Check Roaming Conditions */ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ DBGLOG(ROAMING, LOUD, "->roamingFsmScanResultsUpdate(): Current Time = %u", kalGetTimeTick()); -+ -+ GET_CURRENT_SYSTIME(&prRoamingFsmInfo->rRoamingDiscoveryUpdateTime); -+ -+} /* end of roamingFsmScanResultsUpdate() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The Core FSM engine of ROAMING for AIS Infra. -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* [IN ENUM_ROAMING_STATE_T] eNextState Enum value of next AIS STATE -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_ROAMING_STATE_T eNextState) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T ePreviousState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ do { -+ -+ /* Do entering Next State */ -+#if DBG -+ DBGLOG(ROAMING, STATE, "TRANSITION: [%s] -> [%s]\n", -+ apucDebugRoamingState[prRoamingFsmInfo->eCurrentState], -+ apucDebugRoamingState[eNextState]); -+#else -+ DBGLOG(ROAMING, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", -+ DBG_ROAMING_IDX, prRoamingFsmInfo->eCurrentState, eNextState); -+#endif -+ /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */ -+ ePreviousState = prRoamingFsmInfo->eCurrentState; -+ prRoamingFsmInfo->eCurrentState = eNextState; -+ -+ fgIsTransition = (BOOLEAN) FALSE; -+ -+ /* Do tasks of the State that we just entered */ -+ switch (prRoamingFsmInfo->eCurrentState) { -+ /* NOTE(Kevin): we don't have to rearrange the sequence of following -+ * switch case. Instead I would like to use a common lookup table of array -+ * of function pointer to speed up state search. -+ */ -+ case ROAMING_STATE_IDLE: -+ case ROAMING_STATE_DECISION: -+ break; -+ -+ case ROAMING_STATE_DISCOVERY: -+ { -+ OS_SYSTIME rCurrentTime; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prRoamingFsmInfo->rRoamingDiscoveryUpdateTime, -+ SEC_TO_SYSTIME(ROAMING_DISCOVERY_TIMEOUT_SEC))) { -+ DBGLOG(ROAMING, LOUD, "roamingFsmSteps: DiscoveryUpdateTime Timeout"); -+ aisFsmRunEventRoamingDiscovery(prAdapter, TRUE); -+ } else { -+ DBGLOG(ROAMING, LOUD, "roamingFsmSteps: DiscoveryUpdateTime Updated"); -+#if CFG_SUPPORT_ROAMING_ENC -+ if (prAdapter->fgIsRoamingEncEnabled == TRUE) -+ aisFsmRunEventRoamingDiscovery(prAdapter, TRUE); -+ else -+#endif /* CFG_SUPPORT_ROAMING_ENC */ -+ aisFsmRunEventRoamingDiscovery(prAdapter, FALSE); -+ } -+ } -+ break; -+ -+ case ROAMING_STATE_ROAM: -+ break; -+ -+ default: -+ ASSERT(0); /* Make sure we have handle all STATEs */ -+ } -+ } while (fgIsTransition); -+ -+ return; -+ -+} /* end of roamingFsmSteps() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Transit to Decision state after join completion -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmRunEventStart(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T eNextState; -+ P_BSS_INFO_T prAisBssInfo; -+ ROAMING_PARAM_T rParam; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ /* Check Roaming Conditions */ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ if (prAisBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ return; -+ -+ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING START: Current Time = %u\n", kalGetTimeTick()); -+ -+ /* IDLE, ROAM -> DECISION */ -+ /* Errors as DECISION, DISCOVERY -> DECISION */ -+ if (!(prRoamingFsmInfo->eCurrentState == ROAMING_STATE_IDLE || -+ prRoamingFsmInfo->eCurrentState == ROAMING_STATE_ROAM)) -+ return; -+ -+ eNextState = ROAMING_STATE_DECISION; -+ if (eNextState != prRoamingFsmInfo->eCurrentState) { -+ rParam.u2Event = ROAMING_EVENT_START; -+ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); -+ -+ /* Step to next state */ -+ roamingFsmSteps(prAdapter, eNextState); -+ } -+ -+} /* end of roamingFsmRunEventStart() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Transit to Discovery state when deciding to find a candidate -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmRunEventDiscovery(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T eNextState; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ /* Check Roaming Conditions */ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING DISCOVERY: Current Time = %u Reason = %u\n", -+ kalGetTimeTick(), prParam->u2Reason); -+ -+ /* DECISION -> DISCOVERY */ -+ /* Errors as IDLE, DISCOVERY, ROAM -> DISCOVERY */ -+ if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DECISION) -+ return; -+#if CFG_SUPPORT_ROAMING_ENC -+ prRoamingFsmInfo->RoamingEntryTimeoutSkipCount = 0; -+#endif -+ -+ eNextState = ROAMING_STATE_DISCOVERY; -+ /* DECISION -> DISCOVERY */ -+ if (eNextState != prRoamingFsmInfo->eCurrentState) { -+ P_BSS_INFO_T prAisBssInfo; -+ P_BSS_DESC_T prBssDesc; -+ -+ /* sync. rcpi with firmware */ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ if (prBssDesc) -+ prBssDesc->ucRCPI = (UINT_8) (prParam->u2Data & 0xff); -+ -+ roamingFsmSteps(prAdapter, eNextState); -+ } -+ -+} /* end of roamingFsmRunEventDiscovery() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Transit to Roam state after Scan Done -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmRunEventRoam(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T eNextState; -+ ROAMING_PARAM_T rParam; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ /* Check Roaming Conditions */ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING ROAM: Current Time = %u\n", kalGetTimeTick()); -+ -+ /* IDLE, ROAM -> DECISION */ -+ /* Errors as IDLE, DECISION, ROAM -> ROAM */ -+ if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DISCOVERY) -+ return; -+ -+ eNextState = ROAMING_STATE_ROAM; -+ /* DISCOVERY -> ROAM */ -+ if (eNextState != prRoamingFsmInfo->eCurrentState) { -+ rParam.u2Event = ROAMING_EVENT_ROAM; -+ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); -+ -+ /* Step to next state */ -+ roamingFsmSteps(prAdapter, eNextState); -+ } -+ -+} /* end of roamingFsmRunEventRoam() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Transit to Decision state as being failed to find out any candidate -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmRunEventFail(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T eNextState; -+ ROAMING_PARAM_T rParam; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ /* Check Roaming Conditions */ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING FAIL: reason %x Current Time = %u\n", u4Param, kalGetTimeTick()); -+ -+ /* IDLE, ROAM -> DECISION */ -+ /* Errors as IDLE, DECISION, DISCOVERY -> DECISION */ -+ if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_ROAM) -+ return; -+ -+ eNextState = ROAMING_STATE_DECISION; -+ /* ROAM -> DECISION */ -+ if (eNextState != prRoamingFsmInfo->eCurrentState) { -+ rParam.u2Event = ROAMING_EVENT_FAIL; -+ rParam.u2Data = (UINT_16) (u4Param & 0xffff); -+ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); -+ -+ /* Step to next state */ -+ roamingFsmSteps(prAdapter, eNextState); -+ } -+ -+} /* end of roamingFsmRunEventFail() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Transit to Idle state as beging aborted by other moduels, AIS -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmRunEventAbort(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T eNextState; -+ ROAMING_PARAM_T rParam; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING ABORT: Current Time = %u\n", kalGetTimeTick()); -+ -+ eNextState = ROAMING_STATE_IDLE; -+ /* IDLE, DECISION, DISCOVERY, ROAM -> IDLE */ -+ if (eNextState != prRoamingFsmInfo->eCurrentState) { -+ rParam.u2Event = ROAMING_EVENT_ABORT; -+ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); -+ -+ /* Step to next state */ -+ roamingFsmSteps(prAdapter, eNextState); -+ } -+ -+} /* end of roamingFsmRunEventAbort() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process events from firmware -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* [IN P_ROAMING_PARAM_T] prParam -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS roamingFsmProcessEvent(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam) -+{ -+ DBGLOG(ROAMING, LOUD, "ROAMING Process Events: Current Time = %u\n", kalGetTimeTick()); -+ -+ if (ROAMING_EVENT_DISCOVERY == prParam->u2Event) -+ roamingFsmRunEventDiscovery(prAdapter, prParam); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c -new file mode 100644 -index 0000000000000..eedd8d12f2fd3 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c -@@ -0,0 +1,2533 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rsn.c#2 -+*/ -+ -+/*! \file "rsn.c" -+ \brief This file including the 802.11i, wpa and wpa2(rsn) related function. -+ -+ This file provided the macros and functions library support the wpa/rsn ie parsing, -+ cipher and AKM check to help the AP seleced deciding, tkip mic error handler and rsn PMKID support. -+*/ -+ -+/* -+** Log: rsn.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 03 09 2012 chinglan.wang -+ * NULL -+ * Fix the condition error. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode -+ * adding the code for check STA privacy bit at AP mode, . -+ * -+ * 12 24 2010 chinglan.wang -+ * NULL -+ * [MT6620][Wi-Fi] Modify the key management in the driver for WPS function. -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver -+ * create branch for Wi-Fi driver v1.1 -+ * -+ * 11 05 2010 wh.su -+ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value -+ * fixed the.pmkid value mismatch issue -+ * -+ * 11 03 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Refine the HT rate disallow TKIP pairwise cipher . -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T -+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 29 2010 yuche.tsai -+ * NULL -+ * Fix compile error, remove unused pointer in rsnGenerateRSNIE(). -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 24 2010 wh.su -+ * NULL -+ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning. -+ * -+ * 09 06 2010 wh.su -+ * NULL -+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. -+ * -+ * 08 30 2010 wh.su -+ * NULL -+ * remove non-used code. -+ * -+ * 08 19 2010 wh.su -+ * NULL -+ * adding the tx pkt call back handle for countermeasure. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable RX management frame handling. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * [WPD00003840] [MT6620 5931] Security migration -+ * migration from firmware. -+ * -+ * 05 27 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * not indicate pmkid candidate while no new one scanned. -+ * -+ * 04 29 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * adjsut the pre-authentication code. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, -+ * and modify the security related callback function prototype. -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * change the name -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * using the Rx0 port to indicate event -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * refine the code for generate the WPA/RSN IE for assoc req -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust code for pmkid event -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the code for event (mic error and pmkid indicate) and do some function rename -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some security function -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some security feature, including pmkid -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_RSN_MIGRATION -+ -+/* extern PHY_ATTRIBUTE_T rPhyAttributes[]; */ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to parse RSN IE. -+* -+* \param[in] prInfoElem Pointer to the RSN IE -+* \param[out] prRsnInfo Pointer to the BSSDescription structure to store the -+** RSN information from the given RSN IE -+* -+* \retval TRUE - Succeeded -+* \retval FALSE - Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnParseRsnIE(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prRsnInfo) -+{ -+ UINT_32 i; -+ INT_32 u4RemainRsnIeLen; -+ UINT_16 u2Version; -+ UINT_16 u2Cap = 0; -+ UINT_32 u4GroupSuite = RSN_CIPHER_SUITE_CCMP; -+ UINT_16 u2PairSuiteCount = 0; -+ UINT_16 u2AuthSuiteCount = 0; -+ PUINT_8 pucPairSuite = NULL; -+ PUINT_8 pucAuthSuite = NULL; -+ PUINT_8 cp; -+ -+ DEBUGFUNC("rsnParseRsnIE"); -+ -+ ASSERT(prInfoElem); -+ ASSERT(prRsnInfo); -+ -+ /* Verify the length of the RSN IE. */ -+ if (prInfoElem->ucLength < 2) { -+ DBGLOG(RSN, TRACE, "RSN IE length too short (length=%d)\n", prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ /* Check RSN version: currently, we only support version 1. */ -+ WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); -+ if (u2Version != 1) { -+ DBGLOG(RSN, TRACE, "Unsupported RSN IE version: %d\n", u2Version); -+ return FALSE; -+ } -+ -+ cp = (PUCHAR) & prInfoElem->u4GroupKeyCipherSuite; -+ u4RemainRsnIeLen = (INT_32) prInfoElem->ucLength - 2; -+ -+ do { -+ if (u4RemainRsnIeLen == 0) -+ break; -+ -+ /* Parse the Group Key Cipher Suite field. */ -+ if (u4RemainRsnIeLen < 4) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in group cipher suite (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_32(cp, &u4GroupSuite); -+ cp += 4; -+ u4RemainRsnIeLen -= 4; -+ -+ if (u4RemainRsnIeLen == 0) -+ break; -+ -+ /* Parse the Pairwise Key Cipher Suite Count field. */ -+ if (u4RemainRsnIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in pairwise cipher suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); -+ cp += 2; -+ u4RemainRsnIeLen -= 2; -+ -+ /* Parse the Pairwise Key Cipher Suite List field. */ -+ i = (UINT_32) u2PairSuiteCount * 4; -+ if (u4RemainRsnIeLen < (INT_32) i) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in pairwise cipher suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucPairSuite = cp; -+ -+ cp += i; -+ u4RemainRsnIeLen -= (INT_32) i; -+ -+ if (u4RemainRsnIeLen == 0) -+ break; -+ -+ /* Parse the Authentication and Key Management Cipher Suite Count field. */ -+ if (u4RemainRsnIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in auth & key mgt suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); -+ cp += 2; -+ u4RemainRsnIeLen -= 2; -+ -+ /* Parse the Authentication and Key Management Cipher Suite List -+ field. */ -+ i = (UINT_32) u2AuthSuiteCount * 4; -+ if (u4RemainRsnIeLen < (INT_32) i) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in auth & key mgt suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucAuthSuite = cp; -+ -+ cp += i; -+ u4RemainRsnIeLen -= (INT_32) i; -+ -+ if (u4RemainRsnIeLen == 0) -+ break; -+ -+ /* Parse the RSN u2Capabilities field. */ -+ if (u4RemainRsnIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in RSN capabilities (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2Cap); -+ } while (FALSE); -+ -+ /* Save the RSN information for the BSS. */ -+ prRsnInfo->ucElemId = ELEM_ID_RSN; -+ -+ prRsnInfo->u2Version = u2Version; -+ -+ prRsnInfo->u4GroupKeyCipherSuite = u4GroupSuite; -+ -+ DBGLOG(RSN, LOUD, "RSN: version %d, group key cipher suite %02x-%02x-%02x-%02x\n", -+ u2Version, (UCHAR) (u4GroupSuite & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); -+ -+ if (pucPairSuite) { -+ /* The information about the pairwise key cipher suites is present. */ -+ if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) -+ u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES; -+ -+ prRsnInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucPairSuite, &prRsnInfo->au4PairwiseKeyCipherSuite[i]); -+ pucPairSuite += 4; -+ -+ DBGLOG(RSN, LOUD, "RSN: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the pairwise key cipher suites is not present. -+ Use the default chipher suite for RSN: CCMP. */ -+ prRsnInfo->u4PairwiseKeyCipherSuiteCount = 1; -+ prRsnInfo->au4PairwiseKeyCipherSuite[0] = RSN_CIPHER_SUITE_CCMP; -+ -+ DBGLOG(RSN, LOUD, "RSN: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ if (pucAuthSuite) { -+ /* The information about the authentication and key management suites -+ is present. */ -+ if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) -+ u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES; -+ -+ prRsnInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucAuthSuite, &prRsnInfo->au4AuthKeyMgtSuite[i]); -+ pucAuthSuite += 4; -+ -+ DBGLOG(RSN, LOUD, "RSN: AKM suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[i] & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the authentication and key management suites -+ is not present. Use the default AKM suite for RSN. */ -+ prRsnInfo->u4AuthKeyMgtSuiteCount = 1; -+ prRsnInfo->au4AuthKeyMgtSuite[0] = RSN_AKM_SUITE_802_1X; -+ -+ DBGLOG(RSN, LOUD, "RSN: AKM suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[0] & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ prRsnInfo->u2RsnCap = u2Cap; -+#if CFG_SUPPORT_802_11W -+ prRsnInfo->fgRsnCapPresent = TRUE; -+#endif -+ DBGLOG(RSN, LOUD, "RSN cap: 0x%04x\n", prRsnInfo->u2RsnCap); -+ -+ return TRUE; -+} /* rsnParseRsnIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to parse WPA IE. -+* -+* \param[in] prInfoElem Pointer to the WPA IE. -+* \param[out] prWpaInfo Pointer to the BSSDescription structure to store the -+* WPA information from the given WPA IE. -+* -+* \retval TRUE Succeeded. -+* \retval FALSE Failed. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnParseWpaIE(IN P_ADAPTER_T prAdapter, IN P_WPA_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prWpaInfo) -+{ -+ UINT_32 i; -+ INT_32 u4RemainWpaIeLen; -+ UINT_16 u2Version; -+ UINT_16 u2Cap = 0; -+ UINT_32 u4GroupSuite = WPA_CIPHER_SUITE_TKIP; -+ UINT_16 u2PairSuiteCount = 0; -+ UINT_16 u2AuthSuiteCount = 0; -+ PUCHAR pucPairSuite = NULL; -+ PUCHAR pucAuthSuite = NULL; -+ PUCHAR cp; -+ BOOLEAN fgCapPresent = FALSE; -+ -+ DEBUGFUNC("rsnParseWpaIE"); -+ -+ ASSERT(prInfoElem); -+ ASSERT(prWpaInfo); -+ -+ /* Verify the length of the WPA IE. */ -+ if (prInfoElem->ucLength < 6) { -+ DBGLOG(RSN, TRACE, "WPA IE length too short (length=%d)\n", prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ /* Check WPA version: currently, we only support version 1. */ -+ WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); -+ if (u2Version != 1) { -+ DBGLOG(RSN, TRACE, "Unsupported WPA IE version: %d\n", u2Version); -+ return FALSE; -+ } -+ -+ cp = (PUCHAR) &prInfoElem->u4GroupKeyCipherSuite; -+ u4RemainWpaIeLen = (INT_32) prInfoElem->ucLength - 6; -+ -+ do { -+ if (u4RemainWpaIeLen == 0) -+ break; -+ -+ /* WPA_OUI : 4 -+ Version : 2 -+ GroupSuite : 4 -+ PairwiseCount: 2 -+ PairwiseSuite: 4 * pairSuiteCount -+ AuthCount : 2 -+ AuthSuite : 4 * authSuiteCount -+ Cap : 2 */ -+ -+ /* Parse the Group Key Cipher Suite field. */ -+ if (u4RemainWpaIeLen < 4) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in group cipher suite (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_32(cp, &u4GroupSuite); -+ cp += 4; -+ u4RemainWpaIeLen -= 4; -+ -+ if (u4RemainWpaIeLen == 0) -+ break; -+ -+ /* Parse the Pairwise Key Cipher Suite Count field. */ -+ if (u4RemainWpaIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in pairwise cipher suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); -+ cp += 2; -+ u4RemainWpaIeLen -= 2; -+ -+ /* Parse the Pairwise Key Cipher Suite List field. */ -+ i = (UINT_32) u2PairSuiteCount * 4; -+ if (u4RemainWpaIeLen < (INT_32) i) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in pairwise cipher suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucPairSuite = cp; -+ -+ cp += i; -+ u4RemainWpaIeLen -= (INT_32) i; -+ -+ if (u4RemainWpaIeLen == 0) -+ break; -+ -+ /* Parse the Authentication and Key Management Cipher Suite Count -+ field. */ -+ if (u4RemainWpaIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in auth & key mgt suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); -+ cp += 2; -+ u4RemainWpaIeLen -= 2; -+ -+ /* Parse the Authentication and Key Management Cipher Suite List -+ field. */ -+ i = (UINT_32) u2AuthSuiteCount * 4; -+ if (u4RemainWpaIeLen < (INT_32) i) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in auth & key mgt suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucAuthSuite = cp; -+ -+ cp += i; -+ u4RemainWpaIeLen -= (INT_32) i; -+ -+ if (u4RemainWpaIeLen == 0) -+ break; -+ -+ /* Parse the WPA u2Capabilities field. */ -+ if (u4RemainWpaIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in WPA capabilities (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ fgCapPresent = TRUE; -+ WLAN_GET_FIELD_16(cp, &u2Cap); -+ u4RemainWpaIeLen -= 2; -+ } while (FALSE); -+ -+ /* Save the WPA information for the BSS. */ -+ -+ prWpaInfo->ucElemId = ELEM_ID_WPA; -+ -+ prWpaInfo->u2Version = u2Version; -+ -+ prWpaInfo->u4GroupKeyCipherSuite = u4GroupSuite; -+ -+ DBGLOG(RSN, LOUD, "WPA: version %d, group key cipher suite %02x-%02x-%02x-%02x\n", -+ u2Version, (UCHAR) (u4GroupSuite & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); -+ -+ if (pucPairSuite) { -+ /* The information about the pairwise key cipher suites is present. */ -+ if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) -+ u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES; -+ -+ prWpaInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucPairSuite, &prWpaInfo->au4PairwiseKeyCipherSuite[i]); -+ pucPairSuite += 4; -+ -+ DBGLOG(RSN, LOUD, "WPA: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the pairwise key cipher suites is not present. -+ Use the default chipher suite for WPA: TKIP. */ -+ prWpaInfo->u4PairwiseKeyCipherSuiteCount = 1; -+ prWpaInfo->au4PairwiseKeyCipherSuite[0] = WPA_CIPHER_SUITE_TKIP; -+ -+ DBGLOG(RSN, LOUD, "WPA: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ if (pucAuthSuite) { -+ /* The information about the authentication and key management suites -+ is present. */ -+ if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) -+ u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES; -+ -+ prWpaInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucAuthSuite, &prWpaInfo->au4AuthKeyMgtSuite[i]); -+ pucAuthSuite += 4; -+ -+ DBGLOG(RSN, LOUD, "WPA: AKM suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[i] & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the authentication and key management suites -+ is not present. Use the default AKM suite for WPA. */ -+ prWpaInfo->u4AuthKeyMgtSuiteCount = 1; -+ prWpaInfo->au4AuthKeyMgtSuite[0] = WPA_AKM_SUITE_802_1X; -+ -+ DBGLOG(RSN, LOUD, "WPA: AKM suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[0] & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ if (fgCapPresent) { -+ prWpaInfo->fgRsnCapPresent = TRUE; -+ prWpaInfo->u2RsnCap = u2Cap; -+ DBGLOG(RSN, LOUD, "WPA: RSN cap: 0x%04x\n", prWpaInfo->u2RsnCap); -+ } else { -+ prWpaInfo->fgRsnCapPresent = FALSE; -+ prWpaInfo->u2RsnCap = 0; -+ } -+ -+ return TRUE; -+} /* rsnParseWpaIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to search the desired pairwise -+* cipher suite from the MIB Pairwise Cipher Suite -+* configuration table. -+* -+* \param[in] u4Cipher The desired pairwise cipher suite to be searched -+* \param[out] pu4Index Pointer to the index of the desired pairwise cipher in -+* the table -+* -+* \retval TRUE - The desired pairwise cipher suite is found in the table. -+* \retval FALSE - The desired pairwise cipher suite is not found in the -+* table. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnSearchSupportedCipher(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Cipher, OUT PUINT_32 pu4Index) -+{ -+ UINT_8 i; -+ P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY prEntry; -+ -+ DEBUGFUNC("rsnSearchSupportedCipher"); -+ -+ ASSERT(pu4Index); -+ -+ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) { -+ prEntry = &prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[i]; -+ if (prEntry->dot11RSNAConfigPairwiseCipher == u4Cipher && -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled) { -+ *pu4Index = i; -+ return TRUE; -+ } -+ } -+ return FALSE; -+} /* rsnSearchSupportedCipher */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Whether BSS RSN is matched from upper layer set. -+* -+* \param[in] prAdapter Pointer to the Adapter structure, BSS RSN Information -+* -+* \retval BOOLEAN -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnIsSuitableBSS(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_T prBssRsnInfo) -+{ -+ UINT_8 i = 0; -+ -+ DEBUGFUNC("rsnIsSuitableBSS"); -+ -+ do { -+ -+ if ((prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite & 0x000000FF) != -+ GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite)) { -+ DBGLOG(RSN, TRACE, "Break by GroupKeyCipherSuite\n"); -+ break; -+ } -+ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { -+ if (((prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] & 0x000000FF) != -+ GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])) -+ && (i == prBssRsnInfo->u4PairwiseKeyCipherSuiteCount - 1)) { -+ DBGLOG(RSN, TRACE, "Break by PairwiseKeyCipherSuite\n"); -+ break; -+ } -+ } -+ for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++) { -+ if (((prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] & 0x000000FF) != -+ GET_SELECTOR_TYPE(prBssRsnInfo->au4AuthKeyMgtSuite[0])) -+ && (i == prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1)) { -+ DBGLOG(RSN, TRACE, "Break by AuthKeyMgtSuite\n"); -+ break; -+ } -+ } -+ return TRUE; -+ } while (FALSE); -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to search the desired -+* authentication and key management (AKM) suite from the -+* MIB Authentication and Key Management Suites table. -+* -+* \param[in] u4AkmSuite The desired AKM suite to be searched -+* \param[out] pu4Index Pointer to the index of the desired AKM suite in the -+* table -+* -+* \retval TRUE The desired AKM suite is found in the table. -+* \retval FALSE The desired AKM suite is not found in the table. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnSearchAKMSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4AkmSuite, OUT PUINT_32 pu4Index) -+{ -+ UINT_8 i; -+ P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry; -+ -+ DEBUGFUNC("rsnSearchAKMSuite"); -+ -+ ASSERT(pu4Index); -+ -+ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { -+ prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i]; -+ if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite && -+ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled) { -+ *pu4Index = i; -+ return TRUE; -+ } -+ } -+ return FALSE; -+} /* rsnSearchAKMSuite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to perform RSNA or TSN policy -+* selection for a given BSS. -+* -+* \param[in] prBss Pointer to the BSS description -+* -+* \retval TRUE - The RSNA/TSN policy selection for the given BSS is -+* successful. The selected pairwise and group cipher suites -+* are returned in the BSS description. -+* \retval FALSE - The RSNA/TSN policy selection for the given BSS is failed. -+* The driver shall not attempt to join the given BSS. -+* -+* \note The Encrypt status matched score will save to bss for final ap select. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss) -+{ -+#if CFG_SUPPORT_802_11W -+ INT_32 i; -+ UINT_32 j; -+#else -+ UINT_32 i, j; -+#endif -+ BOOLEAN fgSuiteSupported; -+ UINT_32 u4PairwiseCipher = 0; -+ UINT_32 u4GroupCipher = 0; -+ UINT_32 u4AkmSuite = 0; -+ P_RSN_INFO_T prBssRsnInfo; -+ ENUM_NETWORK_TYPE_INDEX_T eNetwotkType; -+ BOOLEAN fgIsWpsActive = (BOOLEAN) FALSE; -+ -+ DEBUGFUNC("rsnPerformPolicySelection"); -+ -+ ASSERT(prBss); -+ -+ DBGLOG(RSN, TRACE, "rsnPerformPolicySelection\n"); -+ /* Todo:: */ -+ eNetwotkType = NETWORK_TYPE_AIS_INDEX; -+ -+ prBss->u4RsnSelectedPairwiseCipher = 0; -+ prBss->u4RsnSelectedGroupCipher = 0; -+ prBss->u4RsnSelectedAKMSuite = 0; -+ prBss->ucEncLevel = 0; -+ -+#if CFG_SUPPORT_WPS -+ fgIsWpsActive = kalWSCGetActiveState(prAdapter->prGlueInfo); -+ -+ /* CR1640, disable the AP select privacy check */ -+ if (fgIsWpsActive && -+ (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) && -+ (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA)) { -+ DBGLOG(RSN, TRACE, "-- Skip the Protected BSS check\n"); -+ return TRUE; -+ } -+#endif -+ -+ /* Protection is not required in this BSS. */ -+ if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) == 0) { -+ -+ if (secEnabledInAis(prAdapter) == FALSE) { -+ DBGLOG(RSN, TRACE, "-- No Protected BSS\n"); -+ return TRUE; -+ } -+ DBGLOG(RSN, TRACE, "-- Protected BSS\n"); -+ return FALSE; -+ -+ } -+ -+ /* Protection is required in this BSS. */ -+ if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) != 0) { -+ if (secEnabledInAis(prAdapter) == FALSE) { -+ DBGLOG(RSN, TRACE, "-- Protected BSS\n"); -+ return FALSE; -+ } -+ } -+ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA || -+ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK || -+ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) { -+ -+ if (prBss->fgIEWPA) { -+ prBssRsnInfo = &prBss->rWPAInfo; -+ } else { -+ DBGLOG(RSN, TRACE, "WPA Information Element does not exist.\n"); -+ return FALSE; -+ } -+ } else if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2 || -+ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK) { -+ -+ if (prBss->fgIERSN) { -+ prBssRsnInfo = &prBss->rRSNInfo; -+ } else { -+ DBGLOG(RSN, TRACE, "RSN Information Element does not exist.\n"); -+ return FALSE; -+ } -+ } else if (prAdapter->rWifiVar.rConnSettings.eEncStatus != ENUM_ENCRYPTION1_ENABLED) { -+ /* If the driver is configured to use WEP only, ignore this BSS. */ -+ DBGLOG(RSN, TRACE, "-- Not WEP-only legacy BSS %d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus); -+ return FALSE; -+ } else if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED) { -+ /* If the driver is configured to use WEP only, use this BSS. */ -+ DBGLOG(RSN, TRACE, "-- WEP-only legacy BSS, fgIERSN %d, fgIEWPA %d\n", -+ prBss->fgIERSN, prBss->fgIEWPA); -+ /* if this BSS was configured to WPA/WPA2, don't select this AP */ -+ return (prBss->fgIERSN || prBss->fgIEWPA) ? FALSE : TRUE; -+ } -+ -+ if (!rsnIsSuitableBSS(prAdapter, prBssRsnInfo)) { -+ DBGLOG(RSN, TRACE, "RSN info check no matched\n"); -+ return FALSE; -+ } -+ -+ if (prBssRsnInfo->u4PairwiseKeyCipherSuiteCount == 1 && -+ GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[0]) == CIPHER_SUITE_NONE) { -+ /* Since the pairwise cipher use the same cipher suite as the group -+ cipher in the BSS, we check the group cipher suite against the -+ current encryption status. */ -+ fgSuiteSupported = FALSE; -+ -+ switch (prBssRsnInfo->u4GroupKeyCipherSuite) { -+ case WPA_CIPHER_SUITE_CCMP: -+ case RSN_CIPHER_SUITE_CCMP: -+ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) -+ fgSuiteSupported = TRUE; -+ break; -+ -+ case WPA_CIPHER_SUITE_TKIP: -+ case RSN_CIPHER_SUITE_TKIP: -+ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION2_ENABLED) -+ fgSuiteSupported = TRUE; -+ break; -+ -+ case WPA_CIPHER_SUITE_WEP40: -+ case WPA_CIPHER_SUITE_WEP104: -+ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED) -+ fgSuiteSupported = TRUE; -+ break; -+ } -+ -+ if (fgSuiteSupported) { -+ u4PairwiseCipher = WPA_CIPHER_SUITE_NONE; -+ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; -+ } -+#if DBG -+ else { -+ DBGLOG(RSN, TRACE, "Inproper encryption status %d for group-key-only BSS\n", -+ prAdapter->rWifiVar.rConnSettings.eEncStatus); -+ } -+#endif -+ } else { -+ fgSuiteSupported = FALSE; -+ -+ DBGLOG(RSN, TRACE, "eEncStatus %d %d 0x%x\n", prAdapter->rWifiVar.rConnSettings.eEncStatus, -+ (UINT_32) prBssRsnInfo->u4PairwiseKeyCipherSuiteCount, -+ (UINT_32) prBssRsnInfo->au4PairwiseKeyCipherSuite[0]); -+ /* Select pairwise/group ciphers */ -+ switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) { -+ case ENUM_ENCRYPTION3_ENABLED: -+ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { -+ if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) -+ == CIPHER_SUITE_CCMP) { -+ u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i]; -+ } -+ } -+ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; -+ break; -+ -+ case ENUM_ENCRYPTION2_ENABLED: -+ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { -+ if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) -+ == CIPHER_SUITE_TKIP) { -+ u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i]; -+ } -+ } -+ if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == CIPHER_SUITE_CCMP) -+ DBGLOG(RSN, TRACE, "Cannot join CCMP BSS\n"); -+ else -+ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; -+ break; -+ -+ case ENUM_ENCRYPTION1_ENABLED: -+ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { -+ if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) -+ == CIPHER_SUITE_WEP40 || -+ GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) -+ == CIPHER_SUITE_WEP104) { -+ u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i]; -+ } -+ } -+ if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == -+ CIPHER_SUITE_CCMP || -+ GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == CIPHER_SUITE_TKIP) { -+ DBGLOG(RSN, TRACE, "Cannot join CCMP/TKIP BSS\n"); -+ } else { -+ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; -+ } -+ break; -+ -+ default: -+ break; -+ } -+ } -+ -+ /* Exception handler */ -+ /* If we cannot find proper pairwise and group cipher suites to join the -+ BSS, do not check the supported AKM suites. */ -+ if (u4PairwiseCipher == 0 || u4GroupCipher == 0) { -+ DBGLOG(RSN, TRACE, "Failed to select pairwise/group cipher (0x%08x/0x%08x)\n", -+ u4PairwiseCipher, u4GroupCipher); -+ return FALSE; -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (eNetwotkType == NETWORK_TYPE_P2P_INDEX)) { -+ if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP || -+ u4GroupCipher != RSN_CIPHER_SUITE_CCMP || u4AkmSuite != RSN_AKM_SUITE_PSK) { -+ DBGLOG(RSN, TRACE, "Failed to select pairwise/group cipher for P2P network (0x%08x/0x%08x)\n", -+ u4PairwiseCipher, u4GroupCipher); -+ return FALSE; -+ } -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (eNetwotkType == NETWORK_TYPE_BOW_INDEX) { -+ if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP || -+ u4GroupCipher != RSN_CIPHER_SUITE_CCMP || u4AkmSuite != RSN_AKM_SUITE_PSK) { -+ /* Do nothing */ -+ } -+ DBGLOG(RSN, TRACE, -+ "Failed to select pairwise/group cipher for BT over Wi-Fi network (0x%08x/0x%08x)\n", -+ u4PairwiseCipher, u4GroupCipher); -+ return FALSE; -+ } -+#endif -+ -+ /* Verify if selected pairwisse cipher is supported */ -+ fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4PairwiseCipher, &i); -+ -+ /* Verify if selected group cipher is supported */ -+ if (fgSuiteSupported) -+ fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4GroupCipher, &i); -+ -+ if (!fgSuiteSupported) { -+ DBGLOG(RSN, TRACE, "Failed to support selected pairwise/group cipher (0x%08x/0x%08x)\n", -+ u4PairwiseCipher, u4GroupCipher); -+ return FALSE; -+ } -+ -+ /* Select AKM */ -+ /* If the driver cannot support any authentication suites advertised in -+ the given BSS, we fail to perform RSNA policy selection. */ -+ /* Attempt to find any overlapping supported AKM suite. */ -+#if CFG_SUPPORT_802_11W -+ if (i != 0) -+ for (i = (prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1); i >= 0; i--) { -+#else -+ for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++) { -+#endif -+ if (rsnSearchAKMSuite(prAdapter, prBssRsnInfo->au4AuthKeyMgtSuite[i], &j)) { -+ u4AkmSuite = prBssRsnInfo->au4AuthKeyMgtSuite[i]; -+ break; -+ } -+ } -+ -+ if (u4AkmSuite == 0) { -+ DBGLOG(RSN, TRACE, "Cannot support any AKM suites\n"); -+ return FALSE; -+ } -+ -+ DBGLOG(RSN, TRACE, "Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n", -+ (UINT_8) (u4PairwiseCipher & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF), -+ (UINT_8) (u4GroupCipher & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF)); -+ -+ DBGLOG(RSN, TRACE, "Selected AKM suite: %02x-%02x-%02x-%02x\n", -+ (UINT_8) (u4AkmSuite & 0x000000FF), -+ (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF), -+ (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF), (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF)); -+ -+#if CFG_SUPPORT_802_11W -+ DBGLOG(RSN, TRACE, "MFP setting = %d\n ", kalGetMfpSetting(prAdapter->prGlueInfo)); -+ -+ if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) { -+ if (!prBssRsnInfo->fgRsnCapPresent) { -+ DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required Capability.\n"); -+ return FALSE; -+ } else if (!(prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC)) { -+ DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required\n"); -+ return FALSE; -+ } -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; -+ } else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) { -+ if (prBssRsnInfo->u2RsnCap && ((prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR) || -+ (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC))) { -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; -+ } else { -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE; -+ } -+ } else { -+ if (prBssRsnInfo->fgRsnCapPresent && (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR)) { -+ DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required Capability\n"); -+ return FALSE; -+ } -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE; -+ } -+ DBGLOG(RSN, TRACE, "fgMgmtProtection = %d\n ", prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection); -+#endif -+ -+ if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_CCMP) { -+ prBss->ucEncLevel = 3; -+ } else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_TKIP) { -+ prBss->ucEncLevel = 2; -+ } else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP40 || -+ GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP104) { -+ prBss->ucEncLevel = 1; -+ } else { -+ ASSERT(FALSE); -+ } -+ prBss->u4RsnSelectedPairwiseCipher = u4PairwiseCipher; -+ prBss->u4RsnSelectedGroupCipher = u4GroupCipher; -+ prBss->u4RsnSelectedAKMSuite = u4AkmSuite; -+ -+ return TRUE; -+ -+} /* rsnPerformPolicySelection */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to generate WPA IE for beacon frame. -+* -+* \param[in] pucIeStartAddr Pointer to put the generated WPA IE. -+* -+* \return The append WPA-None IE length -+* \note -+* Called by: JOIN module, compose beacon IE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGenerateWpaNoneIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ UINT_32 i; -+ P_WPA_INFO_ELEM_T prWpaIE; -+ UINT_32 u4Suite; -+ UINT_16 u2SuiteCount; -+ PUINT_8 cp, cp2; -+ UINT_8 ucExpendedLen = 0; -+ PUINT_8 pucBuffer; -+ ENUM_NETWORK_TYPE_INDEX_T eNetworkId; -+ -+ DEBUGFUNC("rsnGenerateWpaNoneIE"); -+ -+ ASSERT(prMsduInfo); -+ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode != AUTH_MODE_WPA_NONE) -+ return; -+ -+ eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType; -+ -+ if (eNetworkId != NETWORK_TYPE_AIS_INDEX) -+ return; -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ ASSERT(pucBuffer); -+ -+ prWpaIE = (P_WPA_INFO_ELEM_T) (pucBuffer); -+ -+ /* Start to construct a WPA IE. */ -+ /* Fill the Element ID field. */ -+ prWpaIE->ucElemId = ELEM_ID_WPA; -+ -+ /* Fill the OUI and OUI Type fields. */ -+ prWpaIE->aucOui[0] = 0x00; -+ prWpaIE->aucOui[1] = 0x50; -+ prWpaIE->aucOui[2] = 0xF2; -+ prWpaIE->ucOuiType = VENDOR_OUI_TYPE_WPA; -+ -+ /* Fill the Version field. */ -+ WLAN_SET_FIELD_16(&prWpaIE->u2Version, 1); /* version 1 */ -+ ucExpendedLen = 6; -+ -+ /* Fill the Pairwise Key Cipher Suite List field. */ -+ u2SuiteCount = 0; -+ cp = (PUINT_8) &prWpaIE->aucPairwiseKeyCipherSuite1[0]; -+ -+ if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_CCMP, &i)) -+ u4Suite = WPA_CIPHER_SUITE_CCMP; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_TKIP, &i)) -+ u4Suite = WPA_CIPHER_SUITE_TKIP; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP104, &i)) -+ u4Suite = WPA_CIPHER_SUITE_WEP104; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP40, &i)) -+ u4Suite = WPA_CIPHER_SUITE_WEP40; -+ else -+ u4Suite = WPA_CIPHER_SUITE_TKIP; -+ -+ WLAN_SET_FIELD_32(cp, u4Suite); -+ u2SuiteCount++; -+ ucExpendedLen += 4; -+ cp += 4; -+ -+ /* Fill the Group Key Cipher Suite field as the same in pair-wise key. */ -+ WLAN_SET_FIELD_32(&prWpaIE->u4GroupKeyCipherSuite, u4Suite); -+ ucExpendedLen += 4; -+ -+ /* Fill the Pairwise Key Cipher Suite Count field. */ -+ WLAN_SET_FIELD_16(&prWpaIE->u2PairwiseKeyCipherSuiteCount, u2SuiteCount); -+ ucExpendedLen += 2; -+ -+ cp2 = cp; -+ -+ /* Fill the Authentication and Key Management Suite List field. */ -+ u2SuiteCount = 0; -+ cp += 2; -+ -+ if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_802_1X, &i)) -+ u4Suite = WPA_AKM_SUITE_802_1X; -+ else if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_PSK, &i)) -+ u4Suite = WPA_AKM_SUITE_PSK; -+ else -+ u4Suite = WPA_AKM_SUITE_NONE; -+ -+ /* This shall be the only available value for current implementation */ -+ ASSERT(u4Suite == WPA_AKM_SUITE_NONE); -+ -+ WLAN_SET_FIELD_32(cp, u4Suite); -+ u2SuiteCount++; -+ ucExpendedLen += 4; -+ cp += 4; -+ -+ /* Fill the Authentication and Key Management Suite Count field. */ -+ WLAN_SET_FIELD_16(cp2, u2SuiteCount); -+ ucExpendedLen += 2; -+ -+ /* Fill the Length field. */ -+ prWpaIE->ucLength = (UINT_8) ucExpendedLen; -+ -+ /* Increment the total IE length for the Element ID and Length fields. */ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ -+} /* rsnGenerateWpaNoneIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to generate WPA IE for -+* associate request frame. -+* -+* \param[in] prCurrentBss The Selected BSS description -+* -+* \retval The append WPA IE length -+* -+* \note -+* Called by: AIS module, Associate request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGenerateWPAIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ PUCHAR cp; -+ PUINT_8 pucBuffer; -+ ENUM_NETWORK_TYPE_INDEX_T eNetworkId; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; -+ -+ DEBUGFUNC("rsnGenerateWPAIE"); -+ -+ ASSERT(prMsduInfo); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ ASSERT(pucBuffer); -+ -+ eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType; -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ /* if (eNetworkId != NETWORK_TYPE_AIS_INDEX) */ -+ /* return; */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((1 /* prCurrentBss->fgIEWPA */ && -+ ((prAdapter->fgIsP2PRegistered) && -+ (eNetworkId == NETWORK_TYPE_P2P_INDEX) && -+ (kalP2PGetTkipCipher(prAdapter->prGlueInfo)))) || -+ ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || -+ (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK))) { -+#else -+ if ((1 /* prCurrentBss->fgIEWPA */ && -+ ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || -+ (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK)))) { -+#endif -+ if (prP2pSpecificBssInfo->u2WpaIeLen != 0) { -+ kalMemCopy(pucBuffer, prP2pSpecificBssInfo->aucWpaIeBuffer, prP2pSpecificBssInfo->u2WpaIeLen); -+ prMsduInfo->u2FrameLength += prP2pSpecificBssInfo->u2WpaIeLen; -+ return; -+ } -+ -+ /* Construct a WPA IE for association request frame. */ -+ WPA_IE(pucBuffer)->ucElemId = ELEM_ID_WPA; -+ WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED; -+ WPA_IE(pucBuffer)->aucOui[0] = 0x00; -+ WPA_IE(pucBuffer)->aucOui[1] = 0x50; -+ WPA_IE(pucBuffer)->aucOui[2] = 0xF2; -+ WPA_IE(pucBuffer)->ucOuiType = VENDOR_OUI_TYPE_WPA; -+ WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2Version, 1); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) { -+ WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite, WPA_CIPHER_SUITE_TKIP); -+ } else -+#endif -+ WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite, -+ prAdapter->rWifiVar. -+ arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedGroupCipher); -+ -+ cp = (PUCHAR) &WPA_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0]; -+ -+ WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1); -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) { -+ WLAN_SET_FIELD_32(cp, WPA_CIPHER_SUITE_TKIP); -+ } else -+#endif -+ WLAN_SET_FIELD_32(cp, -+ prAdapter->rWifiVar. -+ arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedPairwiseCipher); -+ cp += 4; -+ -+ WLAN_SET_FIELD_16(cp, 1); -+ cp += 2; -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) { -+ WLAN_SET_FIELD_32(cp, WPA_AKM_SUITE_PSK); -+ } else -+#endif -+ WLAN_SET_FIELD_32(cp, -+ prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedAKMSuite); -+ cp += 4; -+ -+ WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED; -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ } -+ -+} /* rsnGenerateWPAIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to generate RSN IE for -+* associate request frame. -+* -+* \param[in] prMsduInfo The Selected BSS description -+* -+* \retval The append RSN IE length -+* -+* \note -+* Called by: AIS module, P2P module, BOW module Associate request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGenerateRSNIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ UINT_32 u4Entry; -+ PUCHAR cp; -+ /* UINT_8 ucExpendedLen = 0; */ -+ PUINT_8 pucBuffer; -+ ENUM_NETWORK_TYPE_INDEX_T eNetworkId; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("rsnGenerateRSNIE"); -+ -+ ASSERT(prMsduInfo); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ ASSERT(pucBuffer); -+ -+ /* Todo:: network id */ -+ eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType; -+ -+ if ( -+#if CFG_ENABLE_WIFI_DIRECT -+ ((prAdapter->fgIsP2PRegistered) && -+ (eNetworkId == NETWORK_TYPE_P2P_INDEX) && (kalP2PGetCcmpCipher(prAdapter->prGlueInfo))) || -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ (eNetworkId == NETWORK_TYPE_BOW_INDEX) || -+#endif -+ (eNetworkId == NETWORK_TYPE_AIS_INDEX /* prCurrentBss->fgIERSN */ && -+ ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) || -+ (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK)))) { -+ /* Construct a RSN IE for association request frame. */ -+ RSN_IE(pucBuffer)->ucElemId = ELEM_ID_RSN; -+ RSN_IE(pucBuffer)->ucLength = ELEM_ID_RSN_LEN_FIXED; -+ WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2Version, 1); /* Version */ -+ WLAN_SET_FIELD_32(&RSN_IE(pucBuffer)->u4GroupKeyCipherSuite, -+ prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedGroupCipher); /* Group key suite */ -+ cp = (PUCHAR) &RSN_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0]; -+ WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1); -+ WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedPairwiseCipher); -+ cp += 4; -+ WLAN_SET_FIELD_16(cp, 1); /* AKM suite count */ -+ cp += 2; -+ WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedAKMSuite); /* AKM suite */ -+ cp += 4; -+ WLAN_SET_FIELD_16(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u2RsnSelectedCapInfo);/* Capabilities */ -+#if CFG_SUPPORT_802_11W -+ if (eNetworkId == NETWORK_TYPE_AIS_INDEX && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection) { -+ if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) -+ WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC | ELEM_WPA_CAP_MFPR); /* Capabilities */ -+ else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) -+ WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC); /* Capabilities */ -+ } -+#endif -+ cp += 2; -+ -+ if (eNetworkId == NETWORK_TYPE_AIS_INDEX) { -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ if (!prStaRec) { -+ DBGLOG(RSN, TRACE, "rsnGenerateRSNIE: prStaRec is NULL\n"); -+ return; -+ } -+ } -+ -+ if (eNetworkId == NETWORK_TYPE_AIS_INDEX && -+ rsnSearchPmkidEntry(prAdapter, prStaRec->aucMacAddr, &u4Entry)) { -+ /* DBGLOG(RSN, TRACE, ("Add Pmk at assoc req\n")); */ -+ /* DBGLOG(RSN, TRACE, ("addr %pM PMKID %pM\n", */ -+ /* (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arBSSID),*/ -+ /* (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arPMKID))); */ -+ if (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].fgPmkidExist) { -+ RSN_IE(pucBuffer)->ucLength = 38; -+ WLAN_SET_FIELD_16(cp, 1); /* PMKID count */ -+ cp += 2; -+ DBGLOG(RSN, TRACE, -+ "BSSID %pM ind=%d\n", prStaRec->aucMacAddr, (UINT_32) u4Entry); -+ DBGLOG(RSN, TRACE, "use PMKID %pM\n", -+ (prAdapter->rWifiVar.rAisSpecificBssInfo. -+ arPmkidCache[u4Entry].rBssidInfo.arPMKID)); -+ kalMemCopy(cp, -+ (PVOID) prAdapter->rWifiVar.rAisSpecificBssInfo. -+ arPmkidCache[u4Entry].rBssidInfo.arPMKID, sizeof(PARAM_PMKID_VALUE)); -+ /* ucExpendedLen = 40; */ -+ } else { -+ WLAN_SET_FIELD_16(cp, 0); /* PMKID count */ -+ /* ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2; */ -+#if CFG_SUPPORT_802_11W -+ cp += 2; -+ RSN_IE(pucBuffer)->ucLength += 2; -+#endif -+ } -+ } else { -+ WLAN_SET_FIELD_16(cp, 0); /* PMKID count */ -+ /* ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2; */ -+#if CFG_SUPPORT_802_11W -+ cp += 2; -+ RSN_IE(pucBuffer)->ucLength += 2; -+#endif -+ } -+ -+#if CFG_SUPPORT_802_11W -+ if ((eNetworkId == NETWORK_TYPE_AIS_INDEX) -+ && (kalGetMfpSetting(prAdapter->prGlueInfo) != -+ RSN_AUTH_MFP_DISABLED) /* (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) */) { -+ WLAN_SET_FIELD_32(cp, RSN_CIPHER_SUITE_AES_128_CMAC); -+ cp += 4; -+ RSN_IE(pucBuffer)->ucLength += 4; -+ } -+#endif -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ } -+ -+} /* rsnGenerateRSNIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Parse the given IE buffer and check if it is WFA IE and return Type and -+* SubType for further process. -+* -+* \param[in] pucBuf Pointer to the buffer of WFA Information Element. -+* \param[out] pucOuiType Pointer to the storage of OUI Type. -+* \param[out] pu2SubTypeVersion Pointer to the storage of OUI SubType and Version. -+ -+* \retval TRUE Parse IE ok -+* \retval FALSE Parse IE fail -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+rsnParseCheckForWFAInfoElem(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType, OUT PUINT_16 pu2SubTypeVersion) -+{ -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ P_IE_WFA_T prWfaIE; -+ -+ ASSERT(pucBuf); -+ ASSERT(pucOuiType); -+ ASSERT(pu2SubTypeVersion); -+ prWfaIE = (P_IE_WFA_T) pucBuf; -+ -+ do { -+ if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) { -+ break; -+ } else if (prWfaIE->aucOui[0] != aucWfaOui[0] || -+ prWfaIE->aucOui[1] != aucWfaOui[1] || prWfaIE->aucOui[2] != aucWfaOui[2]) { -+ break; -+ } -+ -+ *pucOuiType = prWfaIE->ucOuiType; -+ WLAN_GET_FIELD_16(&prWfaIE->aucOuiSubTypeVersion[0], pu2SubTypeVersion); -+ -+ return TRUE; -+ } while (FALSE); -+ -+ return FALSE; -+ -+} /* end of rsnParseCheckForWFAInfoElem() */ -+ -+#if CFG_SUPPORT_AAA -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Parse the given IE buffer and check if it is RSN IE with CCMP PSK -+* -+* \param[in] prAdapter Pointer to Adapter -+* \param[in] prSwRfb Pointer to the rx buffer -+* \param[in] pIE Pointer rthe buffer of Information Element. -+* \param[out] prStatusCode Pointer to the return status code. -+ -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe, PUINT_16 pu2StatusCode) -+{ -+ -+ RSN_INFO_T rRsnIe; -+ -+ ASSERT(prAdapter); -+ ASSERT(prIe); -+ ASSERT(pu2StatusCode); -+ -+ *pu2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT; -+ -+ if (rsnParseRsnIE(prAdapter, prIe, &rRsnIe)) { -+ if ((rRsnIe.u4PairwiseKeyCipherSuiteCount != 1) -+ || (rRsnIe.au4PairwiseKeyCipherSuite[0] != RSN_CIPHER_SUITE_CCMP)) { -+ *pu2StatusCode = STATUS_CODE_INVALID_PAIRWISE_CIPHER; -+ return; -+ } -+ if (rRsnIe.u4GroupKeyCipherSuite != RSN_CIPHER_SUITE_CCMP) { -+ *pu2StatusCode = STATUS_CODE_INVALID_GROUP_CIPHER; -+ return; -+ } -+ if ((rRsnIe.u4AuthKeyMgtSuiteCount != 1) || (rRsnIe.au4AuthKeyMgtSuite[0] != RSN_AKM_SUITE_PSK)) { -+ *pu2StatusCode = STATUS_CODE_INVALID_AKMP; -+ return; -+ } -+ -+ DBGLOG(RSN, TRACE, "RSN with CCMP-PSK\n"); -+ *pu2StatusCode = WLAN_STATUS_SUCCESS; -+ } -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to generate an authentication event to NDIS. -+* -+* \param[in] u4Flags Authentication event: \n -+* PARAM_AUTH_REQUEST_REAUTH 0x01 \n -+* PARAM_AUTH_REQUEST_KEYUPDATE 0x02 \n -+* PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 \n -+* PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E \n -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGenMicErrorEvent(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgFlags) -+{ -+ P_PARAM_AUTH_EVENT_T prAuthEvent; -+ -+ DEBUGFUNC("rsnGenMicErrorEvent"); -+ -+ prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer; -+ -+ /* Status type: Authentication Event */ -+ prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION; -+ -+ /* Authentication request */ -+ prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T); -+ kalMemCopy((PVOID) prAuthEvent->arRequest[0].arBssid, -+ (PVOID) prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].aucBSSID, MAC_ADDR_LEN); -+ -+ if (fgFlags == TRUE) -+ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR; -+ else -+ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID) prAuthEvent, -+ sizeof(PARAM_STATUS_INDICATION_T) + sizeof(PARAM_AUTH_REQUEST_T)); -+ -+} /* rsnGenMicErrorEvent */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to handle TKIP MIC failures. -+* -+* \param[in] adapter_p Pointer to the adapter object data area. -+* \param[in] prSta Pointer to the STA which occur MIC Error -+* \param[in] fgErrorKeyType type of error key -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnTkipHandleMICFailure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgErrorKeyType) -+{ -+ /* UINT_32 u4RsnaCurrentMICFailTime; */ -+ /* P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; */ -+ -+ DEBUGFUNC("rsnTkipHandleMICFailure"); -+ -+ ASSERT(prAdapter); -+#if 1 -+ rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); -+ -+ nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, Param_PowerModeCAM, FALSE); -+ -+ /* Generate authentication request event. */ -+ DBGLOG(RSN, INFO, "Generate TKIP MIC error event (type: 0%d)\n", fgErrorKeyType); -+#else -+ ASSERT(prSta); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ /* Record the MIC error occur time. */ -+ GET_CURRENT_SYSTIME(&u4RsnaCurrentMICFailTime); -+ -+ /* Generate authentication request event. */ -+ DBGLOG(RSN, INFO, "Generate TKIP MIC error event (type: 0%d)\n", fgErrorKeyType); -+ -+ /* If less than 60 seconds have passed since a previous TKIP MIC failure, -+ disassociate from the AP and wait for 60 seconds before (re)associating -+ with the same AP. */ -+ if (prAisSpecBssInfo->u4RsnaLastMICFailTime != 0 && -+ !CHECK_FOR_TIMEOUT(u4RsnaCurrentMICFailTime, -+ prAisSpecBssInfo->u4RsnaLastMICFailTime, SEC_TO_SYSTIME(TKIP_COUNTERMEASURE_SEC))) { -+ /* If less than 60 seconds expired since last MIC error, we have to -+ block traffic. */ -+ -+ DBGLOG(RSN, INFO, "Start blocking traffic!\n"); -+ rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); -+ -+ secFsmEventStartCounterMeasure(prAdapter, prSta); -+ } else { -+ rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); -+ DBGLOG(RSN, INFO, "First TKIP MIC error!\n"); -+ } -+ -+ COPY_SYSTIME(prAisSpecBssInfo->u4RsnaLastMICFailTime, u4RsnaCurrentMICFailTime); -+#endif -+} /* rsnTkipHandleMICFailure */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to select a list of BSSID from -+* the scan results for PMKID candidate list. -+* -+* \param[in] prBssDesc the BSS Desc at scan result list -+* \param[out] pu4CandidateCount Pointer to the number of selected candidates. -+* It is set to zero if no BSSID matches our requirement. -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnSelectPmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_AIS_BSS_INFO_T prAisBssInfo; -+ -+ DEBUGFUNC("rsnSelectPmkidCandidateList"); -+ -+ ASSERT(prBssDesc); -+ -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ -+ /* Search a BSS with the same SSID from the given BSS description set. */ -+ /* DBGLOG(RSN, TRACE, ("Check scan result [%pM]\n", */ -+ /* prBssDesc->aucBSSID)); */ -+ -+ if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, -+ prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) { -+ DBGLOG(RSN, TRACE, "-- SSID not matched\n"); -+ return; -+ } -+#if 0 -+ if ((prBssDesc->u2BSSBasicRateSet & -+ ~(rPhyAttributes[prAisBssInfo->ePhyType].u2SupportedRateSet)) || prBssDesc->fgIsUnknownBssBasicRate) { -+ DBGLOG(RSN, TRACE, "-- Rate set not matched\n"); -+ return; -+ } -+ -+ if (/* prBssDesc->u4RsnSelectedPairwiseCipher != prAisBssInfo->u4RsnSelectedPairwiseCipher || */ -+ prBssDesc->u4RsnSelectedGroupCipher != prAisBssInfo->u4RsnSelectedGroupCipher /*|| -+ prBssDesc->u4RsnSelectedAKMSuite != prAisBssInfo->u4RsnSelectedAKMSuite */) { -+ DBGLOG(RSN, TRACE, "-- Encrypt status not matched for PMKID\n"); -+ return; -+ } -+#endif -+ -+ rsnUpdatePmkidCandidateList(prAdapter, prBssDesc); -+ -+} /* rsnSelectPmkidCandidateList */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to select a list of BSSID from -+* the scan results for PMKID candidate list. -+* -+* \param[in] prBssDesc the BSS DESC at scan result list -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnUpdatePmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ UINT_32 i; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("rsnUpdatePmkidCandidateList"); -+ -+ ASSERT(prBssDesc); -+ -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, -+ prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) { -+ DBGLOG(RSN, TRACE, "-- SSID not matched\n"); -+ return; -+ } -+ -+ for (i = 0; i < CFG_MAX_PMKID_CACHE; i++) { -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)) -+ return; -+ } -+ -+ /* If the number of selected BSSID exceed MAX_NUM_PMKID_CACHE(16), -+ then we only store MAX_NUM_PMKID_CACHE(16) in PMKID cache */ -+ if ((prAisSpecBssInfo->u4PmkidCandicateCount + 1) > CFG_MAX_PMKID_CACHE) -+ prAisSpecBssInfo->u4PmkidCandicateCount--; -+ -+ i = prAisSpecBssInfo->u4PmkidCandicateCount; -+ -+ COPY_MAC_ADDR((PVOID) prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, (PVOID) prBssDesc->aucBSSID); -+ -+ if (prBssDesc->u2RsnCap & MASK_RSNIE_CAP_PREAUTH) { -+ prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 1; -+ DBGLOG(RSN, TRACE, "Add %pM with pre-auth to candidate list\n", -+ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)); -+ } else { -+ prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 0; -+ DBGLOG(RSN, TRACE, "Add %pM without pre-auth to candidate list\n", -+ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)); -+ } -+ -+ prAisSpecBssInfo->u4PmkidCandicateCount++; -+ -+} /* rsnUpdatePmkidCandidateList */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to search the desired entry in -+* PMKID cache according to the BSSID -+* -+* \param[in] pucBssid Pointer to the BSSID -+* \param[out] pu4EntryIndex Pointer to place the found entry index -+* -+* \retval TRUE, if found one entry for specified BSSID -+* \retval FALSE, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnSearchPmkidEntry(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBssid, OUT PUINT_32 pu4EntryIndex) -+{ -+ UINT_32 i; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("rsnSearchPmkidEntry"); -+ -+ ASSERT(pucBssid); -+ ASSERT(pu4EntryIndex); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ if (prAisSpecBssInfo->u4PmkidCacheCount > CFG_MAX_PMKID_CACHE) -+ return FALSE; -+ -+ ASSERT(prAisSpecBssInfo->u4PmkidCacheCount <= CFG_MAX_PMKID_CACHE); -+ -+ /* Search for desired BSSID */ -+ for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) { -+ if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, pucBssid, MAC_ADDR_LEN)) -+ break; -+ } -+ -+ /* If desired BSSID is found, then set the PMKID */ -+ if (i < prAisSpecBssInfo->u4PmkidCacheCount) { -+ *pu4EntryIndex = i; -+ -+ return TRUE; -+ } -+ -+ return FALSE; -+} /* rsnSearchPmkidEntry */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to check if there is difference -+* between PMKID candicate list and PMKID cache. If there -+* is new candicate that no cache entry is available, then -+* add a new entry for the new candicate in the PMKID cache -+* and set the PMKID indication flag to TRUE. -+* -+* \retval TRUE, if new member in the PMKID candicate list -+* \retval FALSe, if no new member in the PMKID candicate list -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnCheckPmkidCandicate(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ UINT_32 i; /* Index for PMKID candicate */ -+ UINT_32 j; /* Indix for PMKID cache */ -+ BOOLEAN status = FALSE; -+ -+ DEBUGFUNC("rsnCheckPmkidCandicate"); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ /* Check for each candicate */ -+ for (i = 0; i < prAisSpecBssInfo->u4PmkidCandicateCount; i++) { -+ for (j = 0; j < prAisSpecBssInfo->u4PmkidCacheCount; j++) { -+ if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID, -+ prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, MAC_ADDR_LEN)) { -+ /* DBGLOG(RSN, TRACE, ("%pM at PMKID cache!!\n", -+ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid))); */ -+ break; -+ } -+ } -+ -+ /* No entry found in PMKID cache for the candicate, add new one */ -+ if (j == prAisSpecBssInfo->u4PmkidCacheCount -+ && prAisSpecBssInfo->u4PmkidCacheCount < CFG_MAX_PMKID_CACHE) { -+ DBGLOG(RSN, TRACE, -+ "Add %pM to PMKID cache!!\n", -+ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)); -+ kalMemCopy((PVOID) prAisSpecBssInfo-> -+ arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].rBssidInfo.arBSSID, -+ (PVOID) prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, MAC_ADDR_LEN); -+ prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].fgPmkidExist = FALSE; -+ prAisSpecBssInfo->u4PmkidCacheCount++; -+ -+ status = TRUE; -+ } -+ } -+ -+ return status; -+} /* rsnCheckPmkidCandicate */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to wait a duration to indicate the pre-auth AP candicate -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnIndicatePmkidCand(IN P_ADAPTER_T prAdapter, IN ULONG ulParm) -+{ -+ DBGLOG(RSN, EVENT, "Security - Time to indicate the PMKID cand.\n"); -+ -+ /* If the authentication mode is WPA2 and indication PMKID flag -+ is available, then we indicate the PMKID candidate list to NDIS and -+ clear the flag, indicatePMKID */ -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED && -+ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) { -+ rsnGeneratePmkidIndication(prAdapter); -+ } -+ -+} /* end of rsnIndicatePmkidCand() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to check the BSS Desc at scan result -+* with pre-auth cap at wpa2 mode. If there -+* is candicate that no cache entry is available, then -+* add a new entry for the new candicate in the PMKID cache -+* and set the PMKID indication flag to TRUE. -+* -+* \param[in] prBss The BSS Desc at scan result -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnCheckPmkidCache(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss) -+{ -+ P_AIS_BSS_INFO_T prAisBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ DEBUGFUNC("rsnCheckPmkidCandicate"); -+ -+ ASSERT(prBss); -+ -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ if ((prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) && -+ (prConnSettings->eAuthMode == AUTH_MODE_WPA2)) { -+ rsnSelectPmkidCandidateList(prAdapter, prBss); -+ -+ /* Set indication flag of PMKID to TRUE, and then connHandleNetworkConnection() -+ will indicate this later */ -+ if (rsnCheckPmkidCandicate(prAdapter)) { -+ DBGLOG(RSN, TRACE, "Prepare a timer to indicate candidate PMKID Candidate\n"); -+ cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer); -+ cnmTimerStartTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer, -+ SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC)); -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to generate an PMKID candidate list -+* indication to NDIS. -+* -+* \param[in] prAdapter Pointer to the adapter object data area. -+* \param[in] u4Flags PMKID candidate list event: -+* PARAM_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGeneratePmkidIndication(IN P_ADAPTER_T prAdapter) -+{ -+ P_PARAM_STATUS_INDICATION_T prStatusEvent; -+ P_PARAM_PMKID_CANDIDATE_LIST_T prPmkidEvent; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; -+ UINT_8 i, j = 0, count = 0; -+ UINT_32 u4LenOfUsedBuffer; -+ -+ DEBUGFUNC("rsnGeneratePmkidIndication"); -+ -+ ASSERT(prAdapter); -+ -+ prStatusEvent = (P_PARAM_STATUS_INDICATION_T) prAdapter->aucIndicationEventBuffer; -+ -+ /* Status type: PMKID Candidatelist Event */ -+ prStatusEvent->eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST; -+ ASSERT(prStatusEvent); -+ -+ prPmkidEvent = (P_PARAM_PMKID_CANDIDATE_LIST_T) (&prStatusEvent->eStatusType + 1); -+ ASSERT(prPmkidEvent); -+ -+ prAisSpecificBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prAisSpecificBssInfo); -+ -+ for (i = 0; i < prAisSpecificBssInfo->u4PmkidCandicateCount; i++) { -+ for (j = 0; j < prAisSpecificBssInfo->u4PmkidCacheCount; j++) { -+ if (EQUAL_MAC_ADDR(prAisSpecificBssInfo->arPmkidCache[j].rBssidInfo.arBSSID, -+ prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid) && -+ (prAisSpecificBssInfo->arPmkidCache[j].fgPmkidExist == TRUE)) { -+ break; -+ } -+ } -+ if (count >= CFG_MAX_PMKID_CACHE) -+ break; -+ -+ if (j == prAisSpecificBssInfo->u4PmkidCacheCount) { -+ kalMemCopy((PVOID) prPmkidEvent->arCandidateList[count].arBSSID, -+ (PVOID) prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid, PARAM_MAC_ADDR_LEN); -+ prPmkidEvent->arCandidateList[count].u4Flags = -+ prAisSpecificBssInfo->arPmkidCandicate[i].u4PreAuthFlags; -+ DBGLOG(RSN, TRACE, "%pM %d\n", (prPmkidEvent->arCandidateList[count].arBSSID), -+ (UINT_32) prPmkidEvent->arCandidateList[count].u4Flags); -+ count++; -+ } -+ } -+ -+ /* PMKID Candidate List */ -+ prPmkidEvent->u4Version = 1; -+ prPmkidEvent->u4NumCandidates = count; -+ DBGLOG(RSN, TRACE, "rsnGeneratePmkidIndication #%d\n", (UINT_32) prPmkidEvent->u4NumCandidates); -+ u4LenOfUsedBuffer = sizeof(ENUM_STATUS_TYPE_T) + (2 * sizeof(UINT_32)) + -+ (count * sizeof(PARAM_PMKID_CANDIDATE_T)); -+ /* dumpMemory8((PUINT_8)prAdapter->aucIndicationEventBuffer, u4LenOfUsedBuffer); */ -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID) prAdapter->aucIndicationEventBuffer, u4LenOfUsedBuffer); -+ -+} /* rsnGeneratePmkidIndication */ -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to generate WSC IE for -+* associate request frame. -+* -+* \param[in] prCurrentBss The Selected BSS description -+* -+* \retval The append WSC IE length -+* -+* \note -+* Called by: AIS module, Associate request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGenerateWSCIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ PUINT_8 pucBuffer; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX) -+ return; -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ /* ASSOC INFO IE ID: 221 :0xDD */ -+ if (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) { -+ kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWSCAssocInfoIE, -+ prAdapter->prGlueInfo->u2WSCAssocInfoIELen); -+ prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WSCAssocInfoIELen; -+ } -+ -+} -+#endif -+ -+#if CFG_SUPPORT_802_11W -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to check if the Bip Key installed or not -+* -+* \param[in] -+* prAdapter -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 rsnCheckBipKeyInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ if (prStaRec && prStaRec->ucNetTypeIndex == (UINT_8) NETWORK_TYPE_AIS_INDEX) -+ return prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled; -+ else -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to check the Sa query timeout. -+* -+* -+* \note -+* Called by: AIS module, Handle by Sa Quert timeout -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 rsnCheckSaQueryTimeout(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; -+ UINT_32 now; -+ -+ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prBssSpecInfo); -+ -+ GET_CURRENT_SYSTIME(&now); -+ -+ if (CHECK_FOR_TIMEOUT(now, prBssSpecInfo->u4SaQueryStart, TU_TO_MSEC(1000))) { -+ LOG_FUNC("association SA Query timed out\n"); -+ -+ prBssSpecInfo->ucSaQueryTimedOut = 1; -+ kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, -+ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); -+ prBssSpecInfo->pucSaQueryTransId = NULL; -+ prBssSpecInfo->u4SaQueryCount = 0; -+ cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer); -+ /* Re-connect */ -+ DBGLOG(RSN, TRACE, "DisBy11w\n"); -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to start the 802.11w sa query timer. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnStartSaQueryTimer(IN P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ P_ACTION_SA_QUERY_FRAME prTxFrame; -+ UINT_16 u2PayloadLen; -+ PUINT_8 pucTmp = NULL; -+ UINT_8 ucTransId[ACTION_SA_QUERY_TR_ID_LEN]; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ ASSERT(prBssInfo); -+ -+ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prBssSpecInfo); -+ -+ LOG_FUNC("MFP: Start Sa Query\n"); -+ -+ if (prBssSpecInfo->u4SaQueryCount > 0 && rsnCheckSaQueryTimeout(prAdapter)) { -+ LOG_FUNC("MFP: u4SaQueryCount count =%d\n", prBssSpecInfo->u4SaQueryCount); -+ return; -+ } -+ -+ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); -+ -+ if (!prMsduInfo) -+ return; -+ -+ prTxFrame = (P_ACTION_SA_QUERY_FRAME) -+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; -+ prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; -+ -+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); -+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); -+ -+ prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION; -+ prTxFrame->ucAction = ACTION_SA_QUERY_REQUEST; -+ -+ if (prBssSpecInfo->u4SaQueryCount == 0) -+ GET_CURRENT_SYSTIME(&prBssSpecInfo->u4SaQueryStart); -+ -+ if (prBssSpecInfo->u4SaQueryCount) { -+ pucTmp = kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE); -+ if (!pucTmp) { -+ DBGLOG(RSN, ERROR, "MFP: Fail to alloc tmp buffer for backup sa query id\n"); -+ return; -+ } -+ kalMemCopy(pucTmp, prBssSpecInfo->pucSaQueryTransId, -+ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); -+ } -+ -+ kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, -+ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); -+ -+ ucTransId[0] = (UINT_8) (kalRandomNumber() & 0xFF); -+ ucTransId[1] = (UINT_8) (kalRandomNumber() & 0xFF); -+ -+ kalMemCopy(prTxFrame->ucTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN); -+ -+ prBssSpecInfo->u4SaQueryCount++; -+ -+ prBssSpecInfo->pucSaQueryTransId = -+ kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE); -+ if (!prBssSpecInfo->pucSaQueryTransId) { -+ DBGLOG(RSN, ERROR, "MFP: Fail to alloc buffer for sa query id list\n"); -+ return; -+ } -+ -+ if (pucTmp) { -+ kalMemCopy(prBssSpecInfo->pucSaQueryTransId, pucTmp, -+ (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN); -+ kalMemCopy(&prBssSpecInfo->pucSaQueryTransId -+ [(prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN], ucTransId, -+ ACTION_SA_QUERY_TR_ID_LEN); -+ kalMemFree(pucTmp, VIR_MEM_TYPE, (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN); -+ } else { -+ kalMemCopy(prBssSpecInfo->pucSaQueryTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN); -+ } -+ -+ u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN; -+ -+ /* 4 Update information of MSDU_INFO_T */ -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ -+ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; -+ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ /* 4 Enqueue the frame to send this action frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ DBGLOG(RSN, TRACE, -+ "Set SA Query timer %d (%d sec)\n", prBssSpecInfo->u4SaQueryCount, prBssInfo->u2ObssScanInterval); -+ -+ cnmTimerStartTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer, TU_TO_MSEC(201)); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to start the 802.11w sa query. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnStartSaQuery(IN P_ADAPTER_T prAdapter) -+{ -+ rsnStartSaQueryTimer(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to stop the 802.11w sa query. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnStopSaQuery(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; -+ -+ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prBssSpecInfo); -+ -+ cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer); -+ kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, -+ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); -+ prBssSpecInfo->pucSaQueryTransId = NULL; -+ prBssSpecInfo->u4SaQueryCount = 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to process the 802.11w sa query action frame. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnSaQueryRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ P_ACTION_SA_QUERY_FRAME prRxFrame = NULL; -+ UINT_16 u2PayloadLen; -+ P_STA_RECORD_T prStaRec; -+ P_ACTION_SA_QUERY_FRAME prTxFrame; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ ASSERT(prBssInfo); -+ -+ prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader; -+ if (!prRxFrame) -+ return; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Received SA Query Request from %pM\n", prStaRec->aucMacAddr); -+ -+ DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) { -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Ignore SA Query Request from unassociated STA %pM\n", -+ prStaRec->aucMacAddr); -+ return; -+ } -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Sending SA Query Response to %pM\n", prStaRec->aucMacAddr); -+ -+ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); -+ -+ if (!prMsduInfo) -+ return; -+ -+ prTxFrame = (P_ACTION_SA_QUERY_FRAME) -+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; -+ /* SA Query always with protected */ -+ prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; -+ -+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); -+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); -+ -+ prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION; -+ prTxFrame->ucAction = ACTION_SA_QUERY_RESPONSE; -+ -+ kalMemCopy(prTxFrame->ucTransId, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); -+ -+ u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN; -+ -+ /* 4 Update information of MSDU_INFO_T */ -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ -+ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; -+ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ /* 4 Enqueue the frame to send this action frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to process the 802.11w sa query action frame. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnSaQueryAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; -+ P_ACTION_SA_QUERY_FRAME prRxFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_32 i; -+ -+ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prBssSpecInfo); -+ -+ prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader; -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prSwRfb->u2PacketLen < ACTION_SA_QUERY_TR_ID_LEN) { -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Too short SA Query Action frame (len=%u)\n", -+ prSwRfb->u2PacketLen); -+ return; -+ } -+ -+ if (prRxFrame->ucAction == ACTION_SA_QUERY_REQUEST) { -+ rsnSaQueryRequest(prAdapter, prSwRfb); -+ return; -+ } -+ -+ if (prRxFrame->ucAction != ACTION_SA_QUERY_RESPONSE) { -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Unexpected SA Query " "Action %d\n", prRxFrame->ucAction); -+ return; -+ } -+ -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Received SA Query Response from %pM\n", prStaRec->aucMacAddr); -+ -+ DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); -+ -+ /* MLME-SAQuery.confirm */ -+ -+ for (i = 0; i < prBssSpecInfo->u4SaQueryCount; i++) { -+ if (kalMemCmp(prBssSpecInfo->pucSaQueryTransId + -+ i * ACTION_SA_QUERY_TR_ID_LEN, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN) == 0) -+ break; -+ } -+ -+ if (i >= prBssSpecInfo->u4SaQueryCount) { -+ DBGLOG(RSN, TRACE, "IEEE 802.11: No matching SA Query " "transaction identifier found\n"); -+ return; -+ } -+ -+ DBGLOG(RSN, TRACE, "Reply to pending SA Query received\n"); -+ -+ rsnStopSaQuery(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to process the 802.11w mgmt frame. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnCheckRxMgmt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN UINT_8 ucSubtype) -+{ -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ BOOLEAN fgUnicast = TRUE; -+ BOOLEAN fgRobustAction = FALSE; -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ -+ if ((HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) && -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection /* Use MFP */) { -+ -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame; -+ -+ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; -+ -+ if (prAssocReqFrame->aucDestAddr[0] & BIT(0)) -+ fgUnicast = FALSE; -+ -+ LOG_FUNC("QM RX MGT: rsnCheckRxMgmt = %d 0x%x %d ucSubtype=%x\n", fgUnicast, prHifRxHdr->ucReserved, -+ (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC), ucSubtype); -+ -+ if (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC) { -+ /* "Dropped unprotected Robust Action frame from an MFP STA" */ -+ /* exclude Public Action */ -+ if (ucSubtype == 13 /* 0x1011: MAC_FRAME_ACTION */) { -+ UINT_8 ucAction = *prSwRfb->pucRecvBuff; -+ -+ if (ucAction != CATEGORY_PUBLIC_ACTION && ucAction != CATEGORY_HT_ACTION) { -+#if DBG && CFG_RX_PKTS_DUMP -+ LOG_FUNC("QM RX MGT: UnProtected Robust Action frame = %d\n", ucAction); -+#endif -+ fgRobustAction = TRUE; -+ return TRUE; -+ } -+ } -+ if (fgUnicast && ((ucSubtype == 10 /* 0x1010: MAC_FRAME_DISASSOC */) -+ || (ucSubtype == 12 /* 0x1100: MAC_FRAME_DEAUTH */))) { -+ LOG_FUNC("QM RX MGT: rsnStartSaQuery\n"); -+ /* MFP test plan 5.3.3.5 */ -+ rsnStartSaQuery(prAdapter); -+ return TRUE; -+ } -+ } -+#if 0 -+ else { -+ if (fgUnicast && ((ucSubtype == MAC_FRAME_DISASSOC) || (ucSubtype == MAC_FRAME_DEAUTH))) { -+ /* This done by function handler */ -+ /* kalIndicateStatusAndComplete(prAdapter->prGlueInfo, */ -+ /* WLAN_STATUS_MEDIA_DISCONNECT, */ -+ /* NULL, */ -+ /* 0); */ -+ } -+ } -+#endif -+ } -+ return FALSE; -+} -+#endif -+ -+#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE -+static BOOLEAN rsnCheckWpaRsnInfo(P_BSS_INFO_T prBss, P_RSN_INFO_T prWpaRsnInfo) -+{ -+ UINT_32 i = 0; -+ -+ if (prWpaRsnInfo->u4GroupKeyCipherSuite != prBss->u4RsnSelectedGroupCipher) { -+ DBGLOG(RSN, INFO, "GroupCipherSuite change, old=0x%04x, new=0x%04x\n", -+ prBss->u4RsnSelectedGroupCipher, prWpaRsnInfo->u4GroupKeyCipherSuite); -+ return TRUE; -+ } -+ for (; i < prWpaRsnInfo->u4AuthKeyMgtSuiteCount; i++) -+ if (prBss->u4RsnSelectedAKMSuite == prWpaRsnInfo->au4AuthKeyMgtSuite[i]) -+ break; -+ if (i == prWpaRsnInfo->u4AuthKeyMgtSuiteCount) { -+ DBGLOG(RSN, INFO, "KeyMgmt change, not find 0x%04x in new beacon\n", prBss->u4RsnSelectedAKMSuite); -+ return TRUE; -+ } -+ -+ for (i = 0; i < prWpaRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) -+ if (prBss->u4RsnSelectedPairwiseCipher == prWpaRsnInfo->au4PairwiseKeyCipherSuite[i]) -+ break; -+ if (i == prWpaRsnInfo->u4PairwiseKeyCipherSuiteCount) { -+ DBGLOG(RSN, INFO, "Pairwise Cipher change, not find 0x%04x in new beacon\n", -+ prBss->u4RsnSelectedPairwiseCipher); -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+BOOLEAN rsnCheckSecurityModeChanged(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_BSS_DESC_T prBssDesc) -+{ -+ ENUM_PARAM_AUTH_MODE_T eAuthMode = prAdapter->rWifiVar.rConnSettings.eAuthMode; -+ -+ switch (eAuthMode) { -+ case AUTH_MODE_OPEN: /* original is open system */ -+ if ((prBssDesc->u2CapInfo & CAP_INFO_PRIVACY) && !prAdapter->prGlueInfo->rWpaInfo.fgPrivacyInvoke) { -+ DBGLOG(RSN, INFO, "security change, open->privacy\n"); -+ return TRUE; -+ } -+ break; -+ case AUTH_MODE_SHARED: /* original is WEP */ -+ case AUTH_MODE_AUTO_SWITCH: -+ if ((prBssDesc->u2CapInfo & CAP_INFO_PRIVACY) == 0) { -+ DBGLOG(RSN, INFO, "security change, WEP->open\n"); -+ return TRUE; -+ } else if (prBssDesc->fgIERSN || prBssDesc->fgIEWPA) { -+ DBGLOG(RSN, INFO, "security change, WEP->WPA/WPA2\n"); -+ return TRUE; -+ } -+ break; -+ case AUTH_MODE_WPA: /*original is WPA */ -+ case AUTH_MODE_WPA_PSK: -+ case AUTH_MODE_WPA_NONE: -+ if (prBssDesc->fgIEWPA) -+ return rsnCheckWpaRsnInfo(prBssInfo, &prBssDesc->rWPAInfo); -+ DBGLOG(RSN, INFO, "security change, WPA->%s\n", -+ prBssDesc->fgIERSN ? "WPA2" : -+ (prBssDesc->u2CapInfo & CAP_INFO_PRIVACY ? "WEP" : "OPEN")); -+ return TRUE; -+ case AUTH_MODE_WPA2: /*original is WPA2 */ -+ case AUTH_MODE_WPA2_PSK: -+ if (prBssDesc->fgIERSN) -+ return rsnCheckWpaRsnInfo(prBssInfo, &prBssDesc->rRSNInfo); -+ DBGLOG(RSN, INFO, "security change, WPA2->%s\n", -+ prBssDesc->fgIEWPA ? "WPA" : -+ (prBssDesc->u2CapInfo & CAP_INFO_PRIVACY ? "WEP" : "OPEN")); -+ return TRUE; -+ default: -+ DBGLOG(RSN, WARN, "unknowned eAuthMode=%d\n", eAuthMode); -+ break; -+ } -+ /*DBGLOG(RSN, INFO, ("rsnCheckSecurityModeChanged, eAuthMode=%d, u2CapInfo=0x%02x, fgIEWPA=%d, fgIERSN=%d\n", -+ eAuthMode, prBssDesc->u2CapInfo, prBssDesc->fgIEWPA, prBssDesc->fgIERSN)); */ -+ return FALSE; -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c -new file mode 100644 -index 0000000000000..596ede60d7887 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c -@@ -0,0 +1,1788 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/saa_fsm.c#2 -+*/ -+ -+/*! \file "saa_fsm.c" -+ \brief This file defines the FSM for SAA MODULE. -+ -+ This file defines the FSM for SAA MODULE. -+*/ -+ -+/* -+** Log: saa_fsm.c -+** -+** 09 04 2013 cp.wu -+** fix typo -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 04 20 2012 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * correct macro -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 04 2011 cp.wu -+ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT -+ * for REASSOCIATED cases as an explicit trigger for Android framework -+ * 1. for DEAUTH/DISASSOC cases, indicate for DISCONNECTION immediately. -+ * 2. (Android only) when reassociation-and-non-roaming cases happened, -+ * indicate an extra DISCONNECT indication to Android Wi-Fi framework -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 09 30 2011 cm.chang -+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band -+ * Add debug message about 40MHz bandwidth allowed -+ * -+ * 05 12 2011 cp.wu -+ * [WCXRP00000720] [MT6620 Wi-Fi][Driver] Do not do any further operation in case STA-REC -+ * has been invalidated before SAA-FSM starts to roll -+ * check for valid STA-REC before SAA-FSM starts to roll. -+ * -+ * 04 21 2011 terry.wu -+ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame -+ * Add network type parameter to authSendAuthFrame. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 03 31 2011 puff.wen -+ * NULL -+ * . -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add RX deauthentication & disassociation process under Hot-Spot mode. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix compile error of after Station Type Macro modification. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 11 29 2010 cp.wu -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC -+ * for initial TX rate selection of auto-rate algorithm -+ * update ucRcpi of STA_RECORD_T for AIS when -+ * 1) Beacons for IBSS merge is received -+ * 2) Associate Response for a connecting peer is received -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete -+ * and might leads to BSOD when entering RF test with AIS associated -+ * 1. remove redundant variables in STA_REC structure -+ * 2. add STA-REC uninitialization routine for clearing pending events -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update for MID_SCN_BOW_SCAN_DONE mboxDummy. -+ * Update saa_fsm for BOW. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * Add support for P2P join event start. -+ * -+ * 07 12 2010 cp.wu -+ * -+ * SAA will take a record for tracking request sequence number. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync. with main branch for resetting to state 1 when associating with another AP -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * refine TX-DONE callback. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix compile error when enable WiFi Direct function. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * saa_fsm.c is migrated. -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * -+ * * * Add Connection Policy - Any and Rx Burst Deauth Support for WHQL -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support of Driver STA_RECORD_T activation -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 12 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fix compile warning due to declared but not used -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 08 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Refine Debug Label -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update comment -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * rename the function -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise MGMT Handler with Retain Status -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugAAState[AA_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("AA_STATE_IDLE"), -+ (PUINT_8) DISP_STRING("SAA_STATE_SEND_AUTH1"), -+ (PUINT_8) DISP_STRING("SAA_STATE_WAIT_AUTH2"), -+ (PUINT_8) DISP_STRING("SAA_STATE_SEND_AUTH3"), -+ (PUINT_8) DISP_STRING("SAA_STATE_WAIT_AUTH4"), -+ (PUINT_8) DISP_STRING("SAA_STATE_SEND_ASSOC1"), -+ (PUINT_8) DISP_STRING("SAA_STATE_WAIT_ASSOC2"), -+ (PUINT_8) DISP_STRING("AAA_STATE_SEND_AUTH2"), -+ (PUINT_8) DISP_STRING("AAA_STATE_SEND_AUTH4"), -+ (PUINT_8) DISP_STRING("AAA_STATE_SEND_ASSOC2"), -+ (PUINT_8) DISP_STRING("AA_STATE_RESOURCE") -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The Core FSM engine of SAA Module. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] eNextState The value of Next State -+* @param[in] prRetainedSwRfb Pointer to the retained SW_RFB_T for JOIN Success -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+saaFsmSteps(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN ENUM_AA_STATE_T eNextState, IN P_SW_RFB_T prRetainedSwRfb) -+{ -+ ENUM_AA_STATE_T ePreviousState; -+ BOOLEAN fgIsTransition; -+ -+ ASSERT(prStaRec); -+ if (!prStaRec) { -+ return; -+ } -+ -+ do { -+ -+#if DBG -+ DBGLOG(SAA, STATE, "TRANSITION: [%s] -> [%s]\n", -+ apucDebugAAState[prStaRec->eAuthAssocState], apucDebugAAState[eNextState]); -+#else -+ DBGLOG(SAA, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", -+ DBG_SAA_IDX, prStaRec->eAuthAssocState, eNextState); -+#endif -+ ePreviousState = prStaRec->eAuthAssocState; -+ -+ /* NOTE(Kevin): This is the only place to change the eAuthAssocState(except initial) */ -+ prStaRec->eAuthAssocState = eNextState; -+ -+ fgIsTransition = (BOOLEAN) FALSE; -+ switch (prStaRec->eAuthAssocState) { -+ case AA_STATE_IDLE: -+ if (ePreviousState != prStaRec->eAuthAssocState) { /* Only trigger this event once */ -+ -+ if (prRetainedSwRfb) { -+ if (saaFsmSendEventJoinComplete(prAdapter, -+ WLAN_STATUS_SUCCESS, -+ prStaRec, -+ prRetainedSwRfb) == WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ } else { -+ eNextState = AA_STATE_RESOURCE; -+ fgIsTransition = TRUE; -+ } -+ } else { -+ if (saaFsmSendEventJoinComplete(prAdapter, -+ WLAN_STATUS_FAILURE, -+ prStaRec, -+ NULL) == WLAN_STATUS_RESOURCES) { -+ eNextState = AA_STATE_RESOURCE; -+ fgIsTransition = TRUE; -+ } -+ } -+ -+ } -+ -+ /* Free allocated TCM memory */ -+ if (prStaRec->prChallengeText) { -+ cnmMemFree(prAdapter, prStaRec->prChallengeText); -+ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; -+ } -+ break; -+ -+ case SAA_STATE_SEND_AUTH1: -+ { -+ /* Do tasks in INIT STATE */ -+ if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) { -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; -+ -+ eNextState = AA_STATE_IDLE; -+ fgIsTransition = TRUE; -+ } else { -+ prStaRec->ucTxAuthAssocRetryCount++; -+ -+ /* Update Station Record - Class 1 Flag */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+#if !CFG_SUPPORT_AAA -+ if (authSendAuthFrame(prAdapter, -+ prStaRec, AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS) { -+#else -+ if (authSendAuthFrame(prAdapter, -+ prStaRec, -+ prStaRec->ucNetTypeIndex, -+ NULL, -+ AUTH_TRANSACTION_SEQ_1, -+ STATUS_CODE_RESERVED) != WLAN_STATUS_SUCCESS) { -+#endif /* CFG_SUPPORT_AAA */ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU)); -+ } -+ } -+ } -+ break; -+ -+ case SAA_STATE_WAIT_AUTH2: -+ break; -+ -+ case SAA_STATE_SEND_AUTH3: -+ { -+ /* Do tasks in INIT STATE */ -+ if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) { -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; -+ -+ eNextState = AA_STATE_IDLE; -+ fgIsTransition = TRUE; -+ } else { -+ prStaRec->ucTxAuthAssocRetryCount++; -+ -+#if !CFG_SUPPORT_AAA -+ if (authSendAuthFrame(prAdapter, -+ prStaRec, AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS) { -+#else -+ if (authSendAuthFrame(prAdapter, -+ prStaRec, -+ prStaRec->ucNetTypeIndex, -+ NULL, -+ AUTH_TRANSACTION_SEQ_3, -+ STATUS_CODE_RESERVED) != WLAN_STATUS_SUCCESS) { -+#endif /* CFG_SUPPORT_AAA */ -+ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU)); -+ } -+ } -+ } -+ break; -+ -+ case SAA_STATE_WAIT_AUTH4: -+ break; -+ -+ case SAA_STATE_SEND_ASSOC1: -+ /* Do tasks in INIT STATE */ -+ if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) { -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT; -+ -+ eNextState = AA_STATE_IDLE; -+ fgIsTransition = TRUE; -+ } else { -+ prStaRec->ucTxAuthAssocRetryCount++; -+ -+ if (assocSendReAssocReqFrame(prAdapter, prStaRec) != WLAN_STATUS_SUCCESS) { -+ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ TU_TO_MSEC(TX_ASSOCIATION_RETRY_TIMEOUT_TU)); -+ } -+ } -+ -+ break; -+ -+ case SAA_STATE_WAIT_ASSOC2: -+ break; -+ -+ case AA_STATE_RESOURCE: -+ /* TODO(Kevin) Can setup a timer and send message later */ -+ break; -+ -+ default: -+ DBGLOG(SAA, ERROR, "Unknown AA STATE\n"); -+ ASSERT(0); -+ break; -+ } -+ -+ } while (fgIsTransition); -+ -+ return; -+ -+} /* end of saaFsmSteps() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send Event to AIS/BOW/P2P -+* -+* @param[in] rJoinStatus To indicate JOIN success or failure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] prSwRfb Pointer to the SW_RFB_T -+ -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+saaFsmSendEventJoinComplete(IN P_ADAPTER_T prAdapter, -+ IN WLAN_STATUS rJoinStatus, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ -+ /* Store limitation about 40Mhz bandwidth capability during association */ -+ if (prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ -+ if (rJoinStatus == WLAN_STATUS_SUCCESS) -+ prBssInfo->fg40mBwAllowed = prBssInfo->fgAssoc40mBwAllowed; -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ } -+ -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+ P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg; -+ -+ prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T)); -+ if (!prSaaFsmCompMsg) -+ return WLAN_STATUS_RESOURCES; -+ -+ prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE; -+ prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; -+ prSaaFsmCompMsg->rJoinStatus = rJoinStatus; -+ prSaaFsmCompMsg->prStaRec = prStaRec; -+ prSaaFsmCompMsg->prSwRfb = prSwRfb; -+ -+ /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { -+ P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg; -+ -+ prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T)); -+ if (!prSaaFsmCompMsg) -+ return WLAN_STATUS_RESOURCES; -+ -+ prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE; -+ prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; -+ prSaaFsmCompMsg->rJoinStatus = rJoinStatus; -+ prSaaFsmCompMsg->prStaRec = prStaRec; -+ prSaaFsmCompMsg->prSwRfb = prSwRfb; -+ -+ /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) { -+ /* @TODO: BOW handler */ -+ -+ P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg; -+ -+ prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T)); -+ if (!prSaaFsmCompMsg) -+ return WLAN_STATUS_RESOURCES; -+ -+ prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE; -+ prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; -+ prSaaFsmCompMsg->rJoinStatus = rJoinStatus; -+ prSaaFsmCompMsg->prStaRec = prStaRec; -+ prSaaFsmCompMsg->prSwRfb = prSwRfb; -+ -+ /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ else { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+} /* end of saaFsmSendEventJoinComplete() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Start Event to SAA FSM. -+* -+* @param[in] prMsgHdr Message of Join Request for a particular STA. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SAA_FSM_START_T prSaaFsmStartMsg; -+ P_STA_RECORD_T prStaRec; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prSaaFsmStartMsg = (P_MSG_SAA_FSM_START_T) prMsgHdr; -+ prStaRec = prSaaFsmStartMsg->prStaRec; -+ -+ if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) { -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ ASSERT(prStaRec); -+ -+ DBGLOG(SAA, LOUD, "EVENT-START: Trigger SAA FSM.\n"); -+ -+ /* record sequence number of request message */ -+ prStaRec->ucAuthAssocReqSeqNum = prSaaFsmStartMsg->ucSeqNum; -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ /* 4 <1> Validation of SAA Start Event */ -+ if (!IS_AP_STA(prStaRec)) { -+ -+ DBGLOG(SAA, ERROR, "EVENT-START: STA Type - %d was not supported.\n", prStaRec->eStaType); -+ -+ /* Ignore the return value because don't care the prSwRfb */ -+ saaFsmSendEventJoinComplete(prAdapter, WLAN_STATUS_FAILURE, prStaRec, NULL); -+ -+ return; -+ } -+ /* 4 <2> The previous JOIN process is not completed ? */ -+ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { -+ DBGLOG(SAA, ERROR, "EVENT-START: Reentry of SAA Module.\n"); -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+ } -+ /* 4 <3> Reset Status Code and Time */ -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ -+ /* Update the record join time. */ -+ GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime); -+ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ if (prStaRec->prChallengeText) { -+ cnmMemFree(prAdapter, prStaRec->prChallengeText); -+ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; -+ } -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+#if CFG_PRIVACY_MIGRATION -+ /* 4 <4> Init the sec fsm */ -+ secFsmInit(prAdapter, prStaRec); -+#endif -+ -+ /* 4 <5> Reset the STA STATE */ -+ /* Update Station Record - Class 1 Flag */ -+ /* NOTE(Kevin): Moved to AIS FSM for Reconnect issue - -+ * We won't deactivate the same STA_RECORD_T and then activate it again for the -+ * case of reconnection. -+ */ -+ /* cnmStaRecChangeState(prStaRec, STA_STATE_1); */ -+ -+ /* 4 <6> Decide if this BSS 20/40M bandwidth is allowed */ -+ if (prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ -+ if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) -+ && (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { -+ prBssInfo->fgAssoc40mBwAllowed = cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex); -+ } else { -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ } -+ DBGLOG(RLM, INFO, "STA 40mAllowed=%d\n", prBssInfo->fgAssoc40mBwAllowed); -+ } -+ /* 4 <7> Trigger SAA FSM */ -+ if (prStaRec->ucStaState == STA_STATE_1) -+ saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_AUTH1, (P_SW_RFB_T) NULL); -+ else if (prStaRec->ucStaState == STA_STATE_2 || prStaRec->ucStaState == STA_STATE_3) -+ saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_ASSOC1, (P_SW_RFB_T) NULL); -+ -+} /* end of saaFsmRunEventStart() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle TxDone(Auth1/Auth3/AssocReq) Event of SAA FSM. -+* -+* @param[in] prMsduInfo Pointer to the MSDU_INFO_T. -+* @param[in] rTxDoneStatus Return TX status of the Auth1/Auth3/AssocReq frame. -+* -+* @retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+saaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ -+ P_STA_RECORD_T prStaRec; -+ ENUM_AA_STATE_T eNextState; -+ -+ ASSERT(prMsduInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (!prStaRec) { -+ DBGLOG(SAA, INFO, "EVENT-TX DONE: Status %d, Invalid StaRec\n", rTxDoneStatus); -+ return WLAN_STATUS_INVALID_PACKET; -+ } -+ -+ ASSERT(prStaRec); -+ -+ DBGLOG(SAA, INFO, "EVENT-TX DONE: Status: %d, eAuthAssocState: %d , SeqNO: %d ", -+ rTxDoneStatus, prStaRec->eAuthAssocState, -+ prMsduInfo->ucTxSeqNum); -+ -+ eNextState = prStaRec->eAuthAssocState; -+ -+ switch (prStaRec->eAuthAssocState) { -+ case SAA_STATE_SEND_AUTH1: -+ { -+ /* Strictly check the outgoing frame is matched with current AA STATE */ -+ if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS) -+ break; -+ -+ if (rTxDoneStatus == TX_RESULT_SUCCESS) { -+ eNextState = SAA_STATE_WAIT_AUTH2; -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU)); -+ } -+ -+ /* if TX was successful, change to next state. -+ * if TX was failed, do retry if possible. -+ */ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ } -+ break; -+ -+ case SAA_STATE_SEND_AUTH3: -+ { -+ /* Strictly check the outgoing frame is matched with current JOIN STATE */ -+ if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS) -+ break; -+ -+ if (rTxDoneStatus == TX_RESULT_SUCCESS) { -+ eNextState = SAA_STATE_WAIT_AUTH4; -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU)); -+ } -+ -+ /* if TX was successful, change to next state. -+ * if TX was failed, do retry if possible. -+ */ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ } -+ break; -+ -+ case SAA_STATE_SEND_ASSOC1: -+ { -+ /* Strictly check the outgoing frame is matched with current SAA STATE */ -+ if (assocCheckTxReAssocReqFrame(prAdapter, prMsduInfo) != WLAN_STATUS_SUCCESS) -+ break; -+ -+ if (rTxDoneStatus == TX_RESULT_SUCCESS) { -+ eNextState = SAA_STATE_WAIT_ASSOC2; -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &(prStaRec->rTxReqDoneOrRxRespTimer), -+ TU_TO_MSEC(DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU)); -+ } -+ /* if TX was successful, change to next state. -+ * if TX was failed, do retry if possible. -+ */ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ } -+ break; -+ -+ default: -+ break; /* Ignore other cases */ -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of saaFsmRunEventTxDone() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send Tx Request Timeout Event to SAA FSM. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventTxReqTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return; -+ -+ DBGLOG(SAA, LOUD, "EVENT-TIMER: TX REQ TIMEOUT, Current Time = %u\n", kalGetTimeTick()); -+ -+ switch (prStaRec->eAuthAssocState) { -+ case SAA_STATE_SEND_AUTH1: -+ case SAA_STATE_SEND_AUTH3: -+ case SAA_STATE_SEND_ASSOC1: -+ saaFsmSteps(prAdapter, prStaRec, prStaRec->eAuthAssocState, (P_SW_RFB_T) NULL); -+ break; -+ -+ default: -+ return; -+ } -+ -+} /* end of saaFsmRunEventTxReqTimeOut() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send Rx Response Timeout Event to SAA FSM. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventRxRespTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ ENUM_AA_STATE_T eNextState; -+ -+ DBGLOG(SAA, LOUD, "EVENT-TIMER: RX RESP TIMEOUT, Current Time = %u\n", kalGetTimeTick()); -+ -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return; -+ -+ eNextState = prStaRec->eAuthAssocState; -+ -+ switch (prStaRec->eAuthAssocState) { -+ case SAA_STATE_WAIT_AUTH2: -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; -+ -+ /* Pull back to earlier state to do retry */ -+ eNextState = SAA_STATE_SEND_AUTH1; -+ break; -+ -+ case SAA_STATE_WAIT_AUTH4: -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; -+ -+ /* Pull back to earlier state to do retry */ -+ eNextState = SAA_STATE_SEND_AUTH3; -+ break; -+ -+ case SAA_STATE_WAIT_ASSOC2: -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT; -+ -+ /* Pull back to earlier state to do retry */ -+ eNextState = SAA_STATE_SEND_ASSOC1; -+ break; -+ -+ default: -+ break; /* Ignore other cases */ -+ } -+ -+ if (eNextState != prStaRec->eAuthAssocState) -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ -+} /* end of saaFsmRunEventRxRespTimeOut() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx Auth Response Frame and then -+* trigger SAA FSM. -+* -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2StatusCode; -+ ENUM_AA_STATE_T eNextState; -+ -+ ASSERT(prSwRfb); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ /* We should have the corresponding Sta Record. */ -+ if (!prStaRec) { -+ /* Peter: we can handle the packet without station record */ -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ if (!IS_AP_STA(prStaRec)) -+ return; -+ -+ switch (prStaRec->eAuthAssocState) { -+ case SAA_STATE_SEND_AUTH1: -+ case SAA_STATE_WAIT_AUTH2: -+ /* Check if the incoming frame is what we are waiting for */ -+ if (authCheckRxAuthFrameStatus(prAdapter, -+ prSwRfb, AUTH_TRANSACTION_SEQ_2, &u2StatusCode) == WLAN_STATUS_SUCCESS) { -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = u2StatusCode; -+ -+ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { -+ -+ authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb); -+ -+ if (prStaRec->ucAuthAlgNum == (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY) { -+ -+ eNextState = SAA_STATE_SEND_AUTH3; -+ } else { -+ /* Update Station Record - Class 2 Flag */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ -+ eNextState = SAA_STATE_SEND_ASSOC1; -+ } -+ } else { -+ DBGLOG(SAA, INFO, "Auth Req was rejected by [ %pM ], Status Code = %d\n", -+ (prStaRec->aucMacAddr), u2StatusCode); -+ -+ eNextState = AA_STATE_IDLE; -+ } -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ } -+ break; -+ -+ case SAA_STATE_SEND_AUTH3: -+ case SAA_STATE_WAIT_AUTH4: -+ /* Check if the incoming frame is what we are waiting for */ -+ if (authCheckRxAuthFrameStatus(prAdapter, -+ prSwRfb, AUTH_TRANSACTION_SEQ_4, &u2StatusCode) == WLAN_STATUS_SUCCESS) { -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = u2StatusCode; -+ -+ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { -+ -+ authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb); /* Add for 802.11r handling */ -+ -+ /* Update Station Record - Class 2 Flag */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ -+ eNextState = SAA_STATE_SEND_ASSOC1; -+ } else { -+ DBGLOG(SAA, INFO, "Auth Req was rejected by [ %pM ], Status Code = %d\n", -+ (prStaRec->aucMacAddr), u2StatusCode); -+ -+ eNextState = AA_STATE_IDLE; -+ } -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ } -+ break; -+ -+ default: -+ break; /* Ignore other cases */ -+ } -+ -+} /* end of saaFsmRunEventRxAuth() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx (Re)Association Response Frame and then -+* trigger SAA FSM. -+* -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS if the status code was not success -+* @retval WLAN_STATUS_BUFFER_RETAINED if the status code was success -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS saaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2StatusCode; -+ ENUM_AA_STATE_T eNextState; -+ P_SW_RFB_T prRetainedSwRfb = (P_SW_RFB_T) NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prSwRfb); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ /* We should have the corresponding Sta Record. */ -+ if (!prStaRec) { -+ ASSERT(0); -+ return rStatus; -+ } -+ -+ if (!IS_AP_STA(prStaRec)) -+ return rStatus; -+ -+ switch (prStaRec->eAuthAssocState) { -+ case SAA_STATE_SEND_ASSOC1: -+ case SAA_STATE_WAIT_ASSOC2: -+ /* TRUE if the incoming frame is what we are waiting for */ -+ if (assocCheckRxReAssocRspFrameStatus(prAdapter, prSwRfb, &u2StatusCode) == WLAN_STATUS_SUCCESS) { -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = u2StatusCode; -+ -+ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { -+ -+ /* Update Station Record - Class 3 Flag */ -+ /* NOTE(Kevin): Moved to AIS FSM for roaming issue - -+ * We should deactivate the STA_RECORD_T of previous AP before -+ * activate new one in Driver. -+ */ -+ /* cnmStaRecChangeState(prStaRec, STA_STATE_3); */ -+ -+ prStaRec->ucJoinFailureCount = 0; /* Clear history. */ -+ -+ prRetainedSwRfb = prSwRfb; -+ rStatus = WLAN_STATUS_PENDING; -+ } else { -+ DBGLOG(SAA, INFO, "Assoc Req was rejected by [ %pM ], Status Code = %d\n", -+ (prStaRec->aucMacAddr), u2StatusCode); -+ } -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ /* update RCPI */ -+ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; -+ -+ eNextState = AA_STATE_IDLE; -+ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, prRetainedSwRfb); -+ } -+ break; -+ -+ default: -+ break; /* Ignore other cases */ -+ } -+ -+ return rStatus; -+ -+} /* end of saaFsmRunEventRxAssoc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will check the incoming Deauth Frame. -+* -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always not retain deauthentication frames -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS saaFsmRunEventRxDeauth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; -+ -+ ASSERT(prSwRfb); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ if (prStaRec == NULL) -+ return WLAN_STATUS_FAILURE; -+ -+ prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader; -+ DBGLOG(SAA, INFO, "Rx Deauth frame from BSSID=[ %pM ].\n", prDeauthFrame->aucBSSID); -+ -+ do { -+ if (IS_STA_IN_AIS(prStaRec)) { -+ P_AIS_BSS_INFO_T prAisBssInfo; -+ -+ if (!IS_AP_STA(prStaRec)) -+ break; -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ if (prStaRec->ucStaState <= STA_STATE_1) -+ break; -+ -+ /* Check if this is the AP we are associated or associating with */ -+ if (authProcessRxDeauthFrame(prSwRfb, -+ prStaRec->aucMacAddr, -+ &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ -+ DBGLOG(SAA, INFO, "Deauth reason = %d\n", prStaRec->u2ReasonCode); -+ -+ if (STA_STATE_2 <= prStaRec->ucStaState) { -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ -+ /* NOTE(Kevin): Change state immediately to avoid starvation of -+ * MSG buffer because of too many deauth frames before changing -+ * the STA state. -+ */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ prAisAbortMsg = -+ (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) -+ break; -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT; -+ prAisAbortMsg->ucReasonOfDisconnect = -+ DISCONNECT_REASON_CODE_DEAUTHENTICATED; -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ -+ mboxSendMsg(prAdapter, -+ MBOX_ID_0, -+ (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ } else { -+ -+ /* TODO(Kevin): Joining Abort */ -+ } -+ prAisBssInfo->u2DeauthReason = prStaRec->u2ReasonCode; -+ -+ } -+ -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+ /* TODO(Kevin) */ -+ p2pFsmRunEventRxDeauthentication(prAdapter, prStaRec, prSwRfb); -+ } -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (IS_STA_IN_BOW(prStaRec)) -+ bowRunEventRxDeAuth(prAdapter, prStaRec, prSwRfb); -+#endif -+ else -+ ASSERT(0); -+ -+ } while (FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of saaFsmRunEventRxDeauth() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will check the incoming Disassociation Frame. -+* -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always not retain disassociation frames -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS saaFsmRunEventRxDisassoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_WLAN_DISASSOC_FRAME_T prDisassocFrame; -+ -+ ASSERT(prSwRfb); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ if (prStaRec == NULL) -+ return WLAN_STATUS_FAILURE; -+ -+ prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; -+ DBGLOG(SAA, INFO, "Rx Disassoc frame from BSSID=[ %pM ].\n", (prDisassocFrame->aucBSSID)); -+ -+ do { -+ if (IS_STA_IN_AIS(prStaRec)) { -+ P_AIS_BSS_INFO_T prAisBssInfo; -+ -+ if (!IS_AP_STA(prStaRec)) -+ break; -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ if (prStaRec->ucStaState <= STA_STATE_1) -+ break; -+ -+ /* Check if this is the AP we are associated or associating with */ -+ if (assocProcessRxDisassocFrame(prAdapter, -+ prSwRfb, -+ prStaRec->aucMacAddr, -+ &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ -+ DBGLOG(SAA, INFO, "Disassoc reason = %d\n", prStaRec->u2ReasonCode); -+ -+ if (STA_STATE_3 <= prStaRec->ucStaState) { -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ /* NOTE(Chaozhong): Change state immediately to avoid starvation of -+ * MSG buffer because of too many disassoc frames before changing -+ * the STA state. -+ */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ -+ prAisAbortMsg = -+ (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) -+ break; -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT; -+ prAisAbortMsg->ucReasonOfDisconnect = -+ DISCONNECT_REASON_CODE_DISASSOCIATED; -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ -+ mboxSendMsg(prAdapter, -+ MBOX_ID_0, -+ (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ } else { -+ -+ /* TODO(Kevin): Joining Abort */ -+ } -+ prAisBssInfo->u2DeauthReason = prStaRec->u2ReasonCode; -+ -+ } -+ -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+ /* TODO(Kevin) */ -+ p2pFsmRunEventRxDisassociation(prAdapter, prStaRec, prSwRfb); -+ } -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (IS_STA_IN_BOW(prStaRec)) { -+ /* Do nothing */ -+ /* TODO(Kevin) */ -+ } -+#endif -+ else -+ ASSERT(0); -+ -+ } while (FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of saaFsmRunEventRxDisassoc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Abort Event to SAA FSM. -+* -+* @param[in] prMsgHdr Message of Abort Request for a particular STA. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SAA_FSM_ABORT_T prSaaFsmAbortMsg; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prMsgHdr); -+ -+ prSaaFsmAbortMsg = (P_MSG_SAA_FSM_ABORT_T) prMsgHdr; -+ prStaRec = prSaaFsmAbortMsg->prStaRec; -+ -+ ASSERT(prStaRec); -+ if (!prStaRec) { -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ DBGLOG(SAA, LOUD, "EVENT-ABORT: Stop SAA FSM.\n"); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ /* Cancel JOIN relative Timer */ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { -+#if DBG -+ DBGLOG(SAA, LOUD, "EVENT-ABORT: Previous Auth/Assoc State == %s.\n", -+ apucDebugAAState[prStaRec->eAuthAssocState]); -+#else -+ DBGLOG(SAA, LOUD, "EVENT-ABORT: Previous Auth/Assoc State == %d.\n", prStaRec->eAuthAssocState); -+#endif -+ } -+#if 0 -+ /* For the Auth/Assoc State to IDLE */ -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+#else -+ /* Free this StaRec */ -+ cnmStaRecFree(prAdapter, prStaRec, FALSE); -+#endif -+ -+} /* end of saaFsmRunEventAbort() */ -+ -+/* TODO(Kevin): following code will be modified and move to AIS FSM */ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will send Join Timeout Event to JOIN FSM. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \retval WLAN_STATUS_FAILURE Fail because of Join Timeout -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS joinFsmRunEventJoinTimeOut(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("joinFsmRunEventJoinTimeOut"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ -+ DBGLOG(JOIN, EVENT, "JOIN EVENT: JOIN TIMEOUT\n"); -+ -+ /* Get a Station Record if possible, TA == BSSID for AP */ -+ prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID); -+ -+ /* We have renew this Sta Record when in JOIN_STATE_INIT */ -+ ASSERT(prStaRec); -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT; -+ -+ /* Increase Failure Count */ -+ prStaRec->ucJoinFailureCount++; -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prJoinInfo->ucTxAuthAssocRetryCount = 0; -+ -+ /* Cancel other JOIN relative Timer */ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); -+ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); -+ -+ /* Restore original setting from current BSS_INFO_T */ -+ if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) -+ joinAdoptParametersFromCurrentBss(prAdapter); -+ -+ /* Pull back to IDLE */ -+ joinFsmSteps(prAdapter, JOIN_STATE_IDLE); -+ -+ return WLAN_STATUS_FAILURE; -+ -+} /* end of joinFsmRunEventJoinTimeOut() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will adopt the parameters from Peer BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinAdoptParametersFromPeerBss(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_BSS_DESC_T prBssDesc; -+ -+ DEBUGFUNC("joinAdoptParametersFromPeerBss"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ prBssDesc = prJoinInfo->prBssDesc; -+ -+ /* 4 <1> Adopt Peer BSS' PHY TYPE */ -+ prAdapter->eCurrentPhyType = prBssDesc->ePhyType; -+ -+ DBGLOG(JOIN, INFO, "Target BSS[%s]'s PhyType = %s\n", -+ prBssDesc->aucSSID, (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? "ERP" : "HR_DSSS"); -+ -+ /* 4 <2> Adopt Peer BSS' Frequency(Band/Channel) */ -+ DBGLOG(JOIN, INFO, "Target BSS's Channel = %d, Band = %d\n", prBssDesc->ucChannelNum, prBssDesc->eBand); -+ -+ nicSwitchChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum, 10); -+ -+ prJoinInfo->fgIsParameterAdopted = TRUE; -+ -+} /* end of joinAdoptParametersFromPeerBss() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will adopt the parameters from current associated BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinAdoptParametersFromCurrentBss(IN P_ADAPTER_T prAdapter) -+{ -+ /* P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo; */ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ prBssInfo = &prAdapter->rBssInfo; -+ -+ /* 4 <1> Adopt current BSS' PHY TYPE */ -+ prAdapter->eCurrentPhyType = prBssInfo->ePhyType; -+ -+ /* 4 <2> Adopt current BSS' Frequency(Band/Channel) */ -+ DBGLOG(JOIN, INFO, "Current BSS's Channel = %d, Band = %d\n", prBssInfo->ucChnl, prBssInfo->eBand); -+ -+ nicSwitchChannel(prAdapter, prBssInfo->eBand, prBssInfo->ucChnl, 10); -+} /* end of joinAdoptParametersFromCurrentBss() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will update all the SW variables and HW MCR registers after -+* the association with target BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinComplete(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_BSS_DESC_T prBssDesc; -+ P_PEER_BSS_INFO_T prPeerBssInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_STA_RECORD_T prStaRec; -+ P_TX_CTRL_T prTxCtrl; -+#if CFG_SUPPORT_802_11D -+ P_IE_COUNTRY_T prIECountry; -+#endif -+ -+ DEBUGFUNC("joinComplete"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ prBssDesc = prJoinInfo->prBssDesc; -+ prPeerBssInfo = &prAdapter->rPeerBssInfo; -+ prBssInfo = &prAdapter->rBssInfo; -+ prConnSettings = &prAdapter->rConnSettings; -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+/* 4 <1> Update Connecting & Connected Flag of BSS_DESC_T. */ -+ /* Remove previous AP's Connection Flags if have */ -+ scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, prBssInfo->aucBSSID); -+ -+ prBssDesc->fgIsConnected = TRUE; /* Mask as Connected */ -+ -+ if (prBssDesc->fgIsHiddenSSID) { -+ /* NOTE(Kevin): This is for the case of Passive Scan and the target BSS didn't -+ * broadcast SSID on its Beacon Frame. -+ */ -+ COPY_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prAdapter->rConnSettings.aucSSID, prAdapter->rConnSettings.ucSSIDLen); -+ -+ if (prBssDesc->ucSSIDLen) -+ prBssDesc->fgIsHiddenSSID = FALSE; -+#if DBG -+ else -+ ASSERT(0); -+#endif /* DBG */ -+ -+ DBGLOG(JOIN, INFO, "Hidden SSID! - Update SSID : %s\n", prBssDesc->aucSSID); -+ } -+/* 4 <2> Update BSS_INFO_T from BSS_DESC_T */ -+ /* 4 <2.A> PHY Type */ -+ prBssInfo->ePhyType = prBssDesc->ePhyType; -+ -+ /* 4 <2.B> BSS Type */ -+ prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE; -+ -+ /* 4 <2.C> BSSID */ -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID); -+ -+ DBGLOG(JOIN, INFO, "JOIN to BSSID: [%pM]\n", prBssDesc->aucBSSID); -+ -+ /* 4 <2.D> SSID */ -+ COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ -+ /* 4 <2.E> Channel / Band information. */ -+ prBssInfo->eBand = prBssDesc->eBand; -+ prBssInfo->ucChnl = prBssDesc->ucChannelNum; -+ -+ /* 4 <2.F> RSN/WPA information. */ -+ secFsmRunEventStart(prAdapter); -+ prBssInfo->u4RsnSelectedPairwiseCipher = prBssDesc->u4RsnSelectedPairwiseCipher; -+ prBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher; -+ prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; -+ -+ if (secRsnKeyHandshakeEnabled()) -+ prBssInfo->fgIsWPAorWPA2Enabled = TRUE; -+ else -+ prBssInfo->fgIsWPAorWPA2Enabled = FALSE; -+ -+ /* 4 <2.G> Beacon interval. */ -+ prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; -+ -+ /* 4 <2.H> DTIM period. */ -+ prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod; -+ -+ /* 4 <2.I> ERP Information */ -+ if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) && /* Our BSS's PHY_TYPE is ERP now. */ -+ (prBssDesc->fgIsERPPresent)) { -+ -+ prBssInfo->fgIsERPPresent = TRUE; -+ prBssInfo->ucERP = prBssDesc->ucERP; /* Save the ERP for later check */ -+ } else { /* Some AP, may send ProbeResp without ERP IE. Thus prBssDesc->fgIsERPPresent is FALSE. */ -+ prBssInfo->fgIsERPPresent = FALSE; -+ prBssInfo->ucERP = 0; -+ } -+ -+#if CFG_SUPPORT_802_11D -+ /* 4 <2.J> Country inforamtion of the associated AP */ -+ if (prConnSettings->fgMultiDomainCapabilityEnabled) { -+ DOMAIN_INFO_ENTRY rDomainInfo; -+ -+ if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) { -+ if (prBssDesc->prIECountry) { -+ prIECountry = prBssDesc->prIECountry; -+ -+ domainParseCountryInfoElem(prIECountry, &prBssInfo->rDomainInfo); -+ -+ /* use the domain get from the BSS info */ -+ prBssInfo->fgIsCountryInfoPresent = TRUE; -+ nicSetupOpChnlList(prAdapter, prBssInfo->rDomainInfo.u2CountryCode, FALSE); -+ } else { -+ /* use the domain get from the scan result */ -+ prBssInfo->fgIsCountryInfoPresent = TRUE; -+ nicSetupOpChnlList(prAdapter, rDomainInfo.u2CountryCode, FALSE); -+ } -+ } -+ } -+#endif -+ -+ /* 4 <2.K> Signal Power of the associated AP */ -+ prBssInfo->rRcpi = prBssDesc->rRcpi; -+ prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi); -+ GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime); -+ -+ /* 4 <2.L> Capability Field of the associated AP */ -+ prBssInfo->u2CapInfo = prBssDesc->u2CapInfo; -+ -+ DBGLOG(JOIN, INFO, "prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n", -+ prBssInfo->fgIsERPPresent, prBssInfo->ucERP, prBssInfo->rRcpi, prBssInfo->rRssi); -+ -+/* 4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC */ -+ /* 4 <3.A> Association ID */ -+ prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId; -+ -+ /* 4 <3.B> WMM Information */ -+ if (prAdapter->fgIsEnableWMM && (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) { -+ -+ prBssInfo->fgIsWmmAssoc = TRUE; -+ prTxCtrl->rTxQForVoipAccess = TXQ_AC3; -+ -+ qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE); -+ -+ if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) { -+ kalMemCopy(&prBssInfo->rWmmInfo, &prPeerBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); -+ } else { -+ kalMemCopy(&prBssInfo->rWmmInfo, -+ &prPeerBssInfo->rWmmInfo, -+ sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams)); -+ } -+ } else { -+ prBssInfo->fgIsWmmAssoc = FALSE; -+ prTxCtrl->rTxQForVoipAccess = TXQ_AC1; -+ -+ kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); -+ } -+ -+ /* 4 <3.C> Operational Rate Set & BSS Basic Rate Set */ -+ prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet; -+ prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet; -+ -+ /* 4 <3.D> Short Preamble */ -+ if (prBssInfo->fgIsERPPresent) { -+ -+ /* NOTE(Kevin 2007/12/24): Truth Table. -+ * Short Preamble Bit in -+ * Final Driver Setting(Short) -+ * TRUE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp) -+ * TRUE FALSE TRUE FALSE -+ * FALSE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp) -+ * FALSE FALSE TRUE FALSE -+ * TRUE TRUE FALSE TRUE(follow ERP) -+ * TRUE TRUE TRUE FALSE(follow ERP) -+ * FALSE TRUE FALSE FALSE(shouldn't have such case, and we should set to FALSE) -+ * FALSE TRUE TRUE FALSE(we should set to FALSE) -+ */ -+ if ((prPeerBssInfo->fgIsShortPreambleAllowed) && -+ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || -+ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) && -+ (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { -+ -+ prBssInfo->fgIsShortPreambleAllowed = TRUE; -+ -+ if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) -+ prBssInfo->fgUseShortPreamble = FALSE; -+ else -+ prBssInfo->fgUseShortPreamble = TRUE; -+ } else { -+ prBssInfo->fgIsShortPreambleAllowed = FALSE; -+ prBssInfo->fgUseShortPreamble = FALSE; -+ } -+ } else { -+ /* NOTE(Kevin 2007/12/24): Truth Table. -+ * Short Preamble Bit in -+ * Final Driver Setting(Short) -+ * TRUE FALSE FALSE -+ * FALSE FALSE FALSE -+ * TRUE TRUE TRUE -+ * FALSE TRUE(status success) TRUE -+ * --> Honor the result of prPeerBssInfo. -+ */ -+ -+ prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble = -+ prPeerBssInfo->fgIsShortPreambleAllowed; -+ } -+ -+ DBGLOG(JOIN, INFO, "prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n", -+ prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble); -+ -+ /* 4 <3.E> Short Slot Time */ -+ prBssInfo->fgUseShortSlotTime = prPeerBssInfo->fgUseShortSlotTime; /* AP support Short Slot Time */ -+ -+ DBGLOG(JOIN, INFO, "prBssInfo->fgUseShortSlotTime = %d\n", prBssInfo->fgUseShortSlotTime); -+ -+ nicSetSlotTime(prAdapter, -+ prBssInfo->ePhyType, -+ ((prConnSettings->fgIsShortSlotTimeOptionEnable && -+ prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE)); -+ -+ /* 4 <3.F> Update Tx Rate for Control Frame */ -+ bssUpdateTxRateForControlFrame(prAdapter); -+ -+ /* 4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition). */ -+ /* if (prAdapter->fgIsEnableRoaming) */ /* NOTE(Kevin): Always prepare info for roaming */ -+ { -+ -+ if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM) -+ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM; -+ else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) -+ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY; -+ -+ prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes; -+ -+ /* Set the stable time of the associated BSS. We won't do roaming decision -+ * during the stable time. -+ */ -+ SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime, -+ SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC)); -+ } -+ -+ /* 4 <3.H> Update Parameter for TX Fragmentation Threshold */ -+#if CFG_TX_FRAGMENT -+ txFragInfoUpdate(prAdapter); -+#endif /* CFG_TX_FRAGMENT */ -+ -+/* 4 <4> Update STA_RECORD_T */ -+ /* Get a Station Record if possible */ -+ prStaRec = staRecGetStaRecordByAddr(prAdapter, prBssDesc->aucBSSID); -+ -+ if (prStaRec) { -+ UINT_16 u2OperationalRateSet, u2DesiredRateSet; -+ -+ /* 4 <4.A> Desired Rate Set */ -+ u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet & -+ prBssInfo->u2OperationalRateSet); -+ -+ u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet); -+ if (u2DesiredRateSet) { -+ prStaRec->u2DesiredRateSet = u2DesiredRateSet; -+ } else { -+ /* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */ -+ prStaRec->u2DesiredRateSet = u2OperationalRateSet; -+ } -+ -+ /* Try to set the best initial rate for this entry */ -+ if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet, -+ prStaRec->rRcpi, &prStaRec->ucCurrRate1Index)) { -+ -+ if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet, &prStaRec->ucCurrRate1Index)) -+ ASSERT(0); -+ } -+ -+ DBGLOG(JOIN, INFO, "prStaRec->ucCurrRate1Index = %d\n", prStaRec->ucCurrRate1Index); -+ -+ /* 4 <4.B> Preamble Mode */ -+ prStaRec->fgIsShortPreambleOptionEnable = prBssInfo->fgUseShortPreamble; -+ -+ /* 4 <4.C> QoS Flag */ -+ prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc; -+ } -+#if DBG -+ else -+ ASSERT(0); -+#endif /* DBG */ -+ -+/* 4 <5> Update NIC */ -+ /* 4 <5.A> Update BSSID & Operation Mode */ -+ nicSetupBSS(prAdapter, prBssInfo); -+ -+ /* 4 <5.B> Update WLAN Table. */ -+ if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) -+ ASSERT(FALSE); -+ /* 4 <5.C> Update Desired Rate Set for BT. */ -+#if CFG_TX_FRAGMENT -+ if (prConnSettings->fgIsEnableTxAutoFragmentForBT) -+ txRateSetInitForBT(prAdapter, prStaRec); -+#endif /* CFG_TX_FRAGMENT */ -+ -+ /* 4 <5.D> TX AC Parameter and TX/RX Queue Control */ -+ if (prBssInfo->fgIsWmmAssoc) { -+ -+#if CFG_TX_AGGREGATE_HW_FIFO -+ nicTxAggregateTXQ(prAdapter, FALSE); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo); -+ } else { -+ -+#if CFG_TX_AGGREGATE_HW_FIFO -+ nicTxAggregateTXQ(prAdapter, TRUE); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter); -+ -+ nicTxNonQoSUpdateTXQParameters(prAdapter, prBssInfo->ePhyType); -+ } -+ -+#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN -+ { -+ prTxCtrl->fgBlockTxDuringJoin = FALSE; -+ -+#if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */ -+ nicTxFlushStopQueues(prAdapter, (UINT_8) TXQ_DATA_MASK, (UINT_8) NULL); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ nicTxRetransmitOfSendWaitQue(prAdapter); -+ -+ if (prTxCtrl->fgIsPacketInOsSendQueue) -+ nicTxRetransmitOfOsSendQue(prAdapter); -+#if CFG_SDIO_TX_ENHANCE -+ halTxLeftClusteredMpdu(prAdapter); -+#endif /* CFG_SDIO_TX_ENHANCE */ -+ -+ } -+#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */ -+ -+/* 4 <6> Setup CONNECTION flag. */ -+ prAdapter->eConnectionState = MEDIA_STATE_CONNECTED; -+ prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED; -+ -+ if (prJoinInfo->fgIsReAssoc) -+ prAdapter->fgBypassPortCtrlForRoaming = TRUE; -+ else -+ prAdapter->fgBypassPortCtrlForRoaming = FALSE; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, (PVOID) NULL, 0); -+ -+} /* end of joinComplete() */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c -new file mode 100644 -index 0000000000000..2c9ccbe82dd1b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c -@@ -0,0 +1,3103 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan.c#3 -+*/ -+ -+/*! \file "scan.c" -+ \brief This file defines the scan profile and the processing function of -+ scan result for SCAN Module. -+ -+ The SCAN Profile selection is part of SCAN MODULE and responsible for defining -+ SCAN Parameters - e.g. MIN_CHANNEL_TIME, number of scan channels. -+ In this file we also define the process of SCAN Result including adding, searching -+ and removing SCAN record from the list. -+*/ -+ -+/* -+** Log: scan.c -+** -+** 01 30 2013 yuche.tsai -+** [ALPS00451578] [JB2][WFD][Case Fail][JE][MR1]?????????[Java (JE),660,-1361051648,99, -+** /data/core/,0,system_server_crash,system_server]JE happens when try to connect WFD.(4/5) -+** Fix possible old scan result indicate to supplicant after formation. -+** -+** 01 16 2013 yuche.tsai -+** [ALPS00431980] [WFD]Aupus one ?play game 10 minitues?wfd connection automaticlly disconnect -+** Fix possible FW assert issue. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 25 2012 cp.wu -+ * [WCXRP00001258] [MT6620][MT5931][MT6628][Driver] Do not use stale scan result for deciding connection target -+ * drop off scan result which is older than 5 seconds when choosing which BSS to join -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 16 2012 cp.wu -+ * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band -+ * configuration with corresponding network configuration -+ * correct typo. -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration -+ * with corresponding network configuration -+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred -+ * band configuration corresponding to network type. -+ * -+ * 12 05 2011 cp.wu -+ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path -+ * add CONNECT_BY_BSSID policy -+ * -+ * 11 23 2011 cp.wu -+ * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection -+ * add compile option to disable beacon content change detection. -+ * -+ * 11 04 2011 cp.wu -+ * [WCXRP00001085] [MT6628 Wi-Fi][Driver] deprecate old BSS-DESC if timestamp -+ * is reset with received beacon/probe response frames -+ * deprecate old BSS-DESC when timestamp in received beacon/probe response frames showed a smaller value than before -+ * -+ * 10 11 2011 cm.chang -+ * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter -+ * Ignore HT OP IE if its length field is not valid -+ * -+ * 09 30 2011 cp.wu -+ * [WCXRP00001021] [MT5931][Driver] Correct scan result generation for conversion between BSS type and operation mode -+ * correct type casting issue. -+ * -+ * 08 23 2011 yuche.tsai -+ * NULL -+ * Fix multicast address list issue. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 08 10 2011 cp.wu -+ * [WCXRP00000922] [MT6620 Wi-Fi][Driver] traverse whole BSS-DESC list for removing -+ * traverse whole BSS-DESC list because BSSID is not unique anymore. -+ * -+ * 07 12 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * for multiple BSS descriptior detecting issue: -+ * 1) check BSSID for infrastructure network -+ * 2) check SSID for AdHoc network -+ * -+ * 07 12 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * check for BSSID for beacons used to update DTIM -+ * -+ * 07 12 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * do not check BSS descriptor for connected flag due to linksys's hidden -+ * SSID will use another BSS descriptor and never connected -+ * -+ * 07 11 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * just pass beacons with the same BSSID. -+ * -+ * 07 11 2011 wh.su -+ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define -+ * for make sure the value is initialize, for customer not enable WAPI -+ * For make sure wapi initial value is set. -+ * -+ * 06 28 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * Do not check for SSID as beacon content change due to the existence of -+ * single BSSID with multiple SSID AP configuration -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * 1. correct logic -+ * 2. replace only BSS-DESC which doesn't have a valid SSID. -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID -+ * settings to work around some tricky AP which use space character as hidden SSID -+ * remove unused temporal variable reference. -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID -+ * settings to work around some tricky AP which use space character as hidden SSID -+ * allow to have a single BSSID with multiple SSID to be presented in scanning result -+ * -+ * 06 02 2011 cp.wu -+ * [WCXRP00000757] [MT6620 Wi-Fi][Driver][SCN] take use of RLM API to filter out BSS in disallowed channels -+ * filter out BSS in disallowed channel by -+ * 1. do not add to scan result array if BSS is at disallowed channel -+ * 2. do not allow to search for BSS-DESC in disallowed channels -+ * -+ * 05 02 2011 cm.chang -+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number -+ * Refine range of valid channel number -+ * -+ * 05 02 2011 cp.wu -+ * [MT6620 Wi-Fi][Driver] Take parsed result for channel information instead of -+ * hardware channel number passed from firmware domain -+ * take parsed result for generating scanning result with channel information. -+ * -+ * 05 02 2011 cm.chang -+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number -+ * Check if channel is valided before record ing BSS channel -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 03 25 2011 yuche.tsai -+ * NULL -+ * Always update Bss Type, for Bss Type for P2P Network is changing every time. -+ * -+ * 03 23 2011 yuche.tsai -+ * NULL -+ * Fix concurrent issue when AIS scan result would overwrite p2p scan result. -+ * -+ * 03 14 2011 cp.wu -+ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently -+ * filtering out other BSS coming from adjacent channels -+ * -+ * 03 11 2011 chinglan.wang -+ * [WCXRP00000537] [MT6620 Wi-Fi][Driver] Can not connect to 802.11b/g/n mixed AP with WEP security. -+ * . -+ * -+ * 03 11 2011 cp.wu -+ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently -+ * When fixed channel operation is necessary, AIS-FSM would scan and only connect for BSS on the specific channel -+ * -+ * 02 24 2011 cp.wu -+ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep() -+ * won't sleep long enough for specified interval such as 500ms -+ * implement beacon change detection by checking SSID and supported rate. -+ * -+ * 02 22 2011 yuche.tsai -+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue -+ * Fix WSC big endian issue. -+ * -+ * 02 21 2011 terry.wu -+ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P -+ * Clean P2P scan list while removing P2P. -+ * -+ * 01 27 2011 yuche.tsai -+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. -+ * Fix scan channel extension issue when p2p module is not registered. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 21 2011 cp.wu -+ * [WCXRP00000380] [MT6620 Wi-Fi][Driver] SSID information should come from buffered -+ * BSS_DESC_T rather than using beacon-carried information -+ * SSID should come from buffered prBssDesc rather than beacon-carried information -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Fix compile error. -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Memfree for P2P Descriptor & P2P Descriptor List. -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Free P2P Descriptor List & Descriptor under BSS Descriptor. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc -+ * and vmalloc implementations to ease physically continuous memory demands -+ * 1) correct typo in scan.c -+ * 2) TX descriptors, RX descriptos and management buffer should use virtually -+ * continuous buffer instead of physically continuous one -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc -+ * and vmalloc implementations to ease physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * while being unloaded, clear all pending interrupt then set LP-own to firmware -+ * -+ * 12 21 2010 cp.wu -+ * [WCXRP00000280] [MT6620 Wi-Fi][Driver] Enable BSS selection with best RCPI policy in SCN module -+ * SCN: enable BEST RSSI selection policy support -+ * -+ * 11 29 2010 cp.wu -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC -+ * for initial TX rate selection of auto-rate algorithm -+ * update ucRcpi of STA_RECORD_T for AIS when -+ * 1) Beacons for IBSS merge is received -+ * 2) Associate Response for a connecting peer is received -+ * -+ * 11 03 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Refine the HT rate disallow TKIP pairwise cipher . -+ * -+ * 10 12 2010 cp.wu -+ * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out -+ * beacons which is received on the folding frequency -+ * trust HT IE if available for 5GHz band -+ * -+ * 10 11 2010 cp.wu -+ * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out -+ * beacons which is received on the folding frequency -+ * add timing and strenght constraint for filtering out beacons with same SSID/TA but received on different channels -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * update the frog's new p2p state machine. -+ * -+ * 10 01 2010 yuche.tsai -+ * NULL -+ * [MT6620 P2P] Fix Big Endian Issue when parse P2P device name TLV. -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate unused variables which lead gcc to argue -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * When indicate scan result, append IE buffer information in the scan result. -+ * -+ * 09 03 2010 yuche.tsai -+ * NULL -+ * 1. Update Beacon RX count when running SLT. -+ * 2. Ignore Beacon when running SLT, would not update information from Beacon. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * 1. Fix P2P Descriptor List to be a link list, to avoid link corrupt after Bss Descriptor Free. -+ * 2.. Fix P2P Device Name Length BE issue. -+ * -+ * 08 23 2010 yuche.tsai -+ * NULL -+ * Add P2P Device Found Indication to supplicant -+ * -+ * 08 20 2010 cp.wu -+ * NULL -+ * reset BSS_DESC_T variables before parsing IE due to peer might have been reconfigured. -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Workaround for P2P Descriptor Infinite loop issue. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Modify code of processing Probe Resonse frame for P2P. -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Add function to get P2P descriptor of BSS descriptor directly. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Modify Scan result processing for P2P module. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Update P2P Device Discovery result add function. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add support for Probe Request & Response parsing. -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Fix compile error for SCAN module while disabling P2P feature. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * SCN module is now able to handle multiple concurrent scanning requests -+ * -+ * 07 15 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * driver no longer generates probe request frames -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * remove timer in DRV-SCN. -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, -+ * other request will be directly dropped by returning BUSY -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) ignore RSN checking when RSN is not turned on. -+ * 2) set STA-REC deactivation callback as NULL -+ * 3) add variable initialization API based on PHY configuration -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * correct BSS_DESC_T initialization after allocated. -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) for event packet, no need to fill RFB. -+ * 2) when wlanAdapterStart() failed, no need to initialize state machines -+ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan uninitialization procedure -+ * -+ * 06 30 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * if beacon/probe-resp is received in 2.4GHz bands and there is ELEM_ID_DS_PARAM_SET IE available, -+ * trust IE instead of RMAC information -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 28 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * send MMPDU in basic rate. -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * modify Beacon/ProbeResp to complete parsing, -+ * because host software has looser memory usage restriction -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * integrate . -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * comment out RLM APIs by CFG_RLM_MIGRATION. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Update P2P Function call. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * RSN/PRIVACY compilation flag awareness correction -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * specify correct value for management frames. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix compile error when enable P2P function. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * correct when ADHOC support is turned on. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan.c. -+ * -+ * 06 04 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * [PM] Support U-APSD for STA mode -+ * -+ * 05 28 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * adding the TKIP disallow join a HT AP code. -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add more chance of JOIN retry for BG_SCAN -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 29 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * adjsut the pre-authentication code. -+ * -+ * 04 27 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support and will send Null frame to diagnose connection -+ * -+ * 04 13 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add new HW CH macro support -+ * -+ * 04 06 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the firmware return the broadcast frame at wrong tc. -+ * -+ * 03 29 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * let the rsn wapi IE always parsing. -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Not carry HT cap when being associated with b/g only AP -+ * -+ * 03 18 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Solve the compile warning for 'return non-void' function -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * * * * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Refine the variable and parameter for security. -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Fix No PKT_INFO_T issue -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Update outgoing ProbeRequest Frame's TX data rate -+ * -+ * 02 23 2010 wh.su -+ * [BORA00000592][MT6620 Wi-Fi] Adding the security related code for driver -+ * refine the scan procedure, reduce the WPA and WAPI IE parsing, and move the parsing to the time for join. -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+ * -+ * 01 20 2010 kevin.huang -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Add PHASE_2_INTEGRATION_WORK_AROUND and CFG_SUPPORT_BCM flags -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 08 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * -+ * Refine Beacon processing, add read RF channel from RX Status -+ * -+ * 01 04 2010 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * For working out the first connection Chariot-verified version -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Modify u2EstimatedExtraIELen for probe request -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add HT cap IE to probe request -+ * -+ * Dec 7 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix lint warning -+ * -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update the process of SCAN Result by adding more Phy Attributes -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function and code for meet the new define -+ * -+ * Nov 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Rename u4RSSI to i4RSSI -+ * -+ * Nov 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Report event of scan result to host -+ * -+ * Nov 26 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix SCAN Record update -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise MGMT Handler with Retain Status and Integrate with TXM -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add (Ext)Support Rate Set IE to ProbeReq -+ * -+ * Nov 20 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Removed the use of SW_RFB->u2FrameLength -+ * -+ * Nov 20 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix uninitial aucMacAddress[] for ProbeReq -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add scanSearchBssDescByPolicy() -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add Send Probe Request Frame -+ * -+ * Oct 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define REPLICATED_BEACON_TIME_THRESHOLD (3000) -+#define REPLICATED_BEACON_FRESH_PERIOD (10000) -+#define REPLICATED_BEACON_STRENGTH_THRESHOLD (32) -+ -+#define ROAMING_NO_SWING_RCPI_STEP (10) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used by SCN to initialize its variables -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnInit(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_BSS_DESC_T prBSSDesc; -+ PUINT_8 pucBSSBuff; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ pucBSSBuff = &prScanInfo->aucScanBuffer[0]; -+ -+ DBGLOG(SCN, INFO, "->scnInit()\n"); -+ -+ /* 4 <1> Reset STATE and Message List */ -+ prScanInfo->eCurrentState = SCAN_STATE_IDLE; -+ -+ prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0; -+ -+ LINK_INITIALIZE(&prScanInfo->rPendingMsgList); -+ -+ /* 4 <2> Reset link list of BSS_DESC_T */ -+ kalMemZero((PVOID) pucBSSBuff, SCN_MAX_BUFFER_SIZE); -+ -+ LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList); -+ LINK_INITIALIZE(&prScanInfo->rBSSDescList); -+ -+ for (i = 0; i < CFG_MAX_NUM_BSS_LIST; i++) { -+ -+ prBSSDesc = (P_BSS_DESC_T) pucBSSBuff; -+ -+ LINK_INSERT_TAIL(&prScanInfo->rFreeBSSDescList, &prBSSDesc->rLinkEntry); -+ -+ pucBSSBuff += ALIGN_4(sizeof(BSS_DESC_T)); -+ } -+ /* Check if the memory allocation consist with this initialization function */ -+ ASSERT(((ULONG) pucBSSBuff - (ULONG)&prScanInfo->aucScanBuffer[0]) == SCN_MAX_BUFFER_SIZE); -+ -+ /* reset freest channel information */ -+ prScanInfo->fgIsSparseChannelValid = FALSE; -+ -+ /* reset NLO state */ -+ prScanInfo->fgNloScanning = FALSE; -+ prScanInfo->fgPscnOnnning = FALSE; -+ -+ prScanInfo->prPscnParam = kalMemAlloc(sizeof(PSCN_PARAM_T), VIR_MEM_TYPE); -+ if (prScanInfo->prPscnParam) -+ kalMemZero(prScanInfo->prPscnParam, sizeof(PSCN_PARAM_T)); -+ -+} /* end of scnInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used by SCN to uninitialize its variables -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnUninit(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ DBGLOG(SCN, INFO, "->scnUninit()\n"); -+ -+ /* 4 <1> Reset STATE and Message List */ -+ prScanInfo->eCurrentState = SCAN_STATE_IDLE; -+ -+ prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0; -+ -+ /* NOTE(Kevin): Check rPendingMsgList ? */ -+ -+ /* 4 <2> Reset link list of BSS_DESC_T */ -+ LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList); -+ LINK_INITIALIZE(&prScanInfo->rBSSDescList); -+ -+ kalMemFree(prScanInfo->prPscnParam, VIR_MEM_TYPE, sizeof(PSCN_PARAM_T)); -+ -+} /* end of scnUninit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to given BSSID -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucBSSID Given BSSID. -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanSearchBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) -+{ -+ return scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, FALSE, NULL); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to given BSSID -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucBSSID Given BSSID. -+* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) -+* @param[in] prSsid Specified SSID -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T -+scanSearchBssDescByBssidAndSsid(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 aucBSSID[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucBSSID); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { -+ if (fgCheckSsid == FALSE || prSsid == NULL) -+ return prBssDesc; -+ -+ if (EQUAL_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen)) { -+ return prBssDesc; -+ } else if (prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) { -+ prDstBssDesc = prBssDesc; -+ } else { -+ /* 20120206 frog: Equal BSSID but not SSID, SSID not hidden, -+ * SSID must be updated. */ -+ COPY_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen); -+ return prBssDesc; -+ } -+ } -+ } -+ -+ return prDstBssDesc; -+ -+} /* end of scanSearchBssDescByBssid() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to given Transmitter Address. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucSrcAddr Given Source Address(TA). -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanSearchBssDescByTA(IN P_ADAPTER_T prAdapter, IN UINT_8 aucSrcAddr[]) -+{ -+ return scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, FALSE, NULL); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to given Transmitter Address. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucSrcAddr Given Source Address(TA). -+* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) -+* @param[in] prSsid Specified SSID -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T -+scanSearchBssDescByTAAndSsid(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucSrcAddr); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if (EQUAL_MAC_ADDR(prBssDesc->aucSrcAddr, aucSrcAddr)) { -+ if (fgCheckSsid == FALSE || prSsid == NULL) -+ return prBssDesc; -+ -+ if (EQUAL_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen)) { -+ return prBssDesc; -+ } else if (prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) { -+ prDstBssDesc = prBssDesc; -+ } -+ -+ } -+ } -+ -+ return prDstBssDesc; -+ -+} /* end of scanSearchBssDescByTA() */ -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to given BSSID -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucBSSID Given BSSID. -+* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) -+* @param[in] prSsid Specified SSID -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanSearchBssDescByBssidAndLatestUpdateTime(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL; -+ OS_SYSTIME rLatestUpdateTime = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucBSSID); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { -+ if (!rLatestUpdateTime || CHECK_FOR_EXPIRATION(prBssDesc->rUpdateTime, rLatestUpdateTime)) { -+ prDstBssDesc = prBssDesc; -+ COPY_SYSTIME(rLatestUpdateTime, prBssDesc->rUpdateTime); -+ } -+ } -+ } -+ -+ return prDstBssDesc; -+ -+} /* end of scanSearchBssDescByBssid() */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to -+* given eBSSType, BSSID and Transmitter Address -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame. -+* @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame. -+* @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame. -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T -+scanSearchExistingBssDesc(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BSS_TYPE_T eBSSType, IN UINT_8 aucBSSID[], IN UINT_8 aucSrcAddr[]) -+{ -+ return scanSearchExistingBssDescWithSsid(prAdapter, eBSSType, aucBSSID, aucSrcAddr, FALSE, NULL); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to -+* given eBSSType, BSSID and Transmitter Address -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame. -+* @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame. -+* @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame. -+* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) -+* @param[in] prSsid Specified SSID -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T -+scanSearchExistingBssDescWithSsid(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BSS_TYPE_T eBSSType, -+ IN UINT_8 aucBSSID[], -+ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_BSS_DESC_T prBssDesc, prIBSSBssDesc; -+ P_LINK_T prBSSDescList; -+ P_LINK_T prFreeBSSDescList; -+ -+ -+ ASSERT(prAdapter); -+ ASSERT(aucSrcAddr); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ switch (eBSSType) { -+ case BSS_TYPE_P2P_DEVICE: -+ fgCheckSsid = FALSE; -+ case BSS_TYPE_INFRASTRUCTURE: -+ case BSS_TYPE_BOW_DEVICE: -+ { -+ prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid); -+ -+ /* if (eBSSType == prBssDesc->eBSSType) */ -+ -+ return prBssDesc; -+ } -+ -+ case BSS_TYPE_IBSS: -+ { -+ prIBSSBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid); -+ prBssDesc = scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, fgCheckSsid, prSsid); -+ -+ /* NOTE(Kevin): -+ * Rules to maintain the SCAN Result: -+ * For AdHoc - -+ * CASE I We have TA1(BSSID1), but it change its BSSID to BSSID2 -+ * -> Update TA1 entry's BSSID. -+ * CASE II We have TA1(BSSID1), and get TA1(BSSID1) again -+ * -> Update TA1 entry's contain. -+ * CASE III We have a SCAN result TA1(BSSID1), and TA2(BSSID2). Sooner or -+ * later, TA2 merge into TA1, we get TA2(BSSID1) -+ * -> Remove TA2 first and then replace TA1 entry's TA with TA2, -+ * Still have only one entry of BSSID. -+ * CASE IV We have a SCAN result TA1(BSSID1), and another TA2 also merge into BSSID1. -+ * -> Replace TA1 entry's TA with TA2, Still have only one entry. -+ * CASE V New IBSS -+ * -> Add this one to SCAN result. -+ */ -+ if (prBssDesc) { -+ if ((!prIBSSBssDesc) || /* CASE I */ -+ (prBssDesc == prIBSSBssDesc)) { /* CASE II */ -+ -+ return prBssDesc; -+ } /* CASE III */ -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); -+ -+ return prIBSSBssDesc; -+ } -+ -+ if (prIBSSBssDesc) { /* CASE IV */ -+ -+ return prIBSSBssDesc; -+ } -+ /* CASE V */ -+ break; /* Return NULL; */ -+ } -+ -+ default: -+ break; -+ } -+ -+ return (P_BSS_DESC_T) NULL; -+ -+} /* end of scanSearchExistingBssDesc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Delete BSS Descriptors from current list according to given Remove Policy. -+* -+* @param[in] u4RemovePolicy Remove Policy. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scanRemoveBssDescsByPolicy(IN P_ADAPTER_T prAdapter, IN UINT_32 u4RemovePolicy) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_LINK_T prFreeBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ -+ ASSERT(prAdapter); -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; -+ -+ /* DBGLOG(SCN, TRACE, ("Before Remove - Number Of SCAN Result = %ld\n", */ -+ /* prBSSDescList->u4NumElem)); */ -+ -+ if (u4RemovePolicy & SCN_RM_POLICY_TIMEOUT) { -+ P_BSS_DESC_T prBSSDescNext; -+ OS_SYSTIME rCurrentTime; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && -+ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { -+ /* Don't remove the one currently we are connected. */ -+ continue; -+ } -+ -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, -+ SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC))) { -+ -+ /* DBGLOG(SCN, TRACE, ("Remove TIMEOUT BSS DESC(%#x): -+ * MAC: %pM, Current Time = %08lx, Update Time = %08lx\n", */ -+ /* prBssDesc, prBssDesc->aucBSSID, rCurrentTime, prBssDesc->rUpdateTime)); */ -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); -+ } -+ } -+ } else if (u4RemovePolicy & SCN_RM_POLICY_OLDEST_HIDDEN) { -+ P_BSS_DESC_T prBssDescOldest = (P_BSS_DESC_T) NULL; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && -+ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { -+ /* Don't remove the one currently we are connected. */ -+ continue; -+ } -+ -+ if (!prBssDesc->fgIsHiddenSSID) -+ continue; -+ -+ if (!prBssDescOldest) { /* 1st element */ -+ prBssDescOldest = prBssDesc; -+ continue; -+ } -+ -+ if (TIME_BEFORE(prBssDesc->rUpdateTime, prBssDescOldest->rUpdateTime)) -+ prBssDescOldest = prBssDesc; -+ } -+ -+ if (prBssDescOldest) { -+ -+ /* DBGLOG(SCN, TRACE, ("Remove OLDEST HIDDEN BSS DESC(%#x): -+ * MAC: %pM, Update Time = %08lx\n", */ -+ /* prBssDescOldest, prBssDescOldest->aucBSSID, prBssDescOldest->rUpdateTime)); */ -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescOldest); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescOldest->rLinkEntry); -+ } -+ } else if (u4RemovePolicy & SCN_RM_POLICY_SMART_WEAKEST) { -+ P_BSS_DESC_T prBssDescWeakest = (P_BSS_DESC_T) NULL; -+ P_BSS_DESC_T prBssDescWeakestSameSSID = (P_BSS_DESC_T) NULL; -+ UINT_32 u4SameSSIDCount = 0; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && -+ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { -+ /* Don't remove the one currently we are connected. */ -+ continue; -+ } -+ -+ if ((!prBssDesc->fgIsHiddenSSID) && -+ (EQUAL_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen))) { -+ -+ u4SameSSIDCount++; -+ -+ if (!prBssDescWeakestSameSSID) -+ prBssDescWeakestSameSSID = prBssDesc; -+ else if (prBssDesc->ucRCPI < prBssDescWeakestSameSSID->ucRCPI) -+ prBssDescWeakestSameSSID = prBssDesc; -+ } -+ -+ if (!prBssDescWeakest) { /* 1st element */ -+ prBssDescWeakest = prBssDesc; -+ continue; -+ } -+ -+ if (prBssDesc->ucRCPI < prBssDescWeakest->ucRCPI) -+ prBssDescWeakest = prBssDesc; -+ -+ } -+ -+ if ((u4SameSSIDCount >= SCN_BSS_DESC_SAME_SSID_THRESHOLD) && (prBssDescWeakestSameSSID)) -+ prBssDescWeakest = prBssDescWeakestSameSSID; -+ -+ if (prBssDescWeakest) { -+ -+ /* DBGLOG(SCN, TRACE, ("Remove WEAKEST BSS DESC(%#x): MAC: %pM, Update Time = %08lx\n", */ -+ /* prBssDescOldest, prBssDescOldest->aucBSSID, prBssDescOldest->rUpdateTime)); */ -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescWeakest); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescWeakest->rLinkEntry); -+ } -+ } else if (u4RemovePolicy & SCN_RM_POLICY_ENTIRE) { -+ P_BSS_DESC_T prBSSDescNext; -+ -+ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && -+ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { -+ /* Don't remove the one currently we are connected. */ -+ continue; -+ } -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); -+ } -+ -+ } -+ -+ return; -+ -+} /* end of scanRemoveBssDescsByPolicy() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Delete BSS Descriptors from current list according to given BSSID. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucBSSID Given BSSID. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scanRemoveBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_LINK_T prFreeBSSDescList; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ P_BSS_DESC_T prBSSDescNext; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucBSSID); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; -+ -+ /* Check if such BSS Descriptor exists in a valid list */ -+ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); -+ -+ /* BSSID is not unique, so need to traverse whols link-list */ -+ } -+ } -+ -+} /* end of scanRemoveBssDescByBssid() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Delete BSS Descriptors from current list according to given band configuration -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eBand Given band -+* @param[in] eNetTypeIndex AIS - Remove IBSS/Infrastructure BSS -+* BOW - Remove BOW BSS -+* P2P - Remove P2P BSS -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+scanRemoveBssDescByBandAndNetwork(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_LINK_T prFreeBSSDescList; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ P_BSS_DESC_T prBSSDescNext; -+ BOOLEAN fgToRemove; -+ -+ ASSERT(prAdapter); -+ ASSERT(eBand <= BAND_NUM); -+ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; -+ -+ if (eBand == BAND_NULL) -+ return; /* no need to do anything, keep all scan result */ -+ -+ /* Check if such BSS Descriptor exists in a valid list */ -+ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ fgToRemove = FALSE; -+ -+ if (prBssDesc->eBand == eBand) { -+ switch (eNetTypeIndex) { -+ case NETWORK_TYPE_AIS_INDEX: -+ if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) -+ || (prBssDesc->eBSSType == BSS_TYPE_IBSS)) { -+ fgToRemove = TRUE; -+ } -+ break; -+ -+ case NETWORK_TYPE_P2P_INDEX: -+ if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) -+ fgToRemove = TRUE; -+ break; -+ -+ case NETWORK_TYPE_BOW_INDEX: -+ if (prBssDesc->eBSSType == BSS_TYPE_BOW_DEVICE) -+ fgToRemove = TRUE; -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+ } -+ -+ if (fgToRemove == TRUE) { -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); -+ } -+ } -+ -+} /* end of scanRemoveBssDescByBand() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Clear the CONNECTION FLAG of a specified BSS Descriptor. -+* -+* @param[in] aucBSSID Given BSSID. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scanRemoveConnFlagOfBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucBSSID); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { -+ prBssDesc->fgIsConnected = FALSE; -+ prBssDesc->fgIsConnecting = FALSE; -+ -+ /* BSSID is not unique, so need to traverse whols link-list */ -+ } -+ } -+ -+ return; -+ -+} /* end of scanRemoveConnectionFlagOfBssDescByBssid() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Allocate new BSS_DESC_T -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* -+* @return Pointer to BSS Descriptor, if has free space. NULL, if has no space. -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanAllocateBssDesc(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prFreeBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; -+ -+ LINK_REMOVE_HEAD(prFreeBSSDescList, prBssDesc, P_BSS_DESC_T); -+ -+ if (prBssDesc) { -+ P_LINK_T prBSSDescList; -+ -+ kalMemZero(prBssDesc, sizeof(BSS_DESC_T)); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ LINK_INITIALIZE(&(prBssDesc->rP2pDeviceList)); -+ prBssDesc->fgIsP2PPresent = FALSE; -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* NOTE(Kevin): In current design, this new empty BSS_DESC_T will be -+ * inserted to BSSDescList immediately. -+ */ -+ LINK_INSERT_TAIL(prBSSDescList, &prBssDesc->rLinkEntry); -+ } -+ -+ return prBssDesc; -+ -+} /* end of scanAllocateBssDesc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This API parses Beacon/ProbeResp frame and insert extracted BSS_DESC_T -+* with IEs into prAdapter->rWifiVar.rScanInfo.aucScanBuffer -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to the receiving frame buffer. -+* -+* @return Pointer to BSS Descriptor -+* NULL if the Beacon/ProbeResp frame is invalid -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanAddToBssDesc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_DESC_T prBssDesc = NULL; -+ UINT_16 u2CapInfo; -+ ENUM_BSS_TYPE_T eBSSType = BSS_TYPE_INFRASTRUCTURE; -+ -+ PUINT_8 pucIE; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ -+ P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) NULL; -+ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; -+ P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL; -+ P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_8 ucHwChannelNum = 0; -+ UINT_8 ucIeDsChannelNum = 0; -+ UINT_8 ucIeHtChannelNum = 0; -+ BOOLEAN fgIsValidSsid = FALSE, fgEscape = FALSE; -+ PARAM_SSID_T rSsid; -+ UINT_64 u8Timestamp; -+ BOOLEAN fgIsNewBssDesc = FALSE; -+ -+ UINT_32 i; -+ UINT_8 ucSSIDChar; -+ -+ UINT_8 ucOuiType; -+ UINT_16 u2SubTypeVersion; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader; -+ -+ WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2CapInfo, &u2CapInfo); -+ WLAN_GET_FIELD_64(&prWlanBeaconFrame->au4Timestamp[0], &u8Timestamp); -+ -+ /* decide BSS type */ -+ switch (u2CapInfo & CAP_INFO_BSS_TYPE) { -+ case CAP_INFO_ESS: -+ /* It can also be Group Owner of P2P Group. */ -+ eBSSType = BSS_TYPE_INFRASTRUCTURE; -+ break; -+ -+ case CAP_INFO_IBSS: -+ eBSSType = BSS_TYPE_IBSS; -+ break; -+ case 0: -+ /* The P2P Device shall set the ESS bit of the Capabilities field -+ * in the Probe Response fame to 0 and IBSS bit to 0. (3.1.2.1.1) */ -+ eBSSType = BSS_TYPE_P2P_DEVICE; -+ break; -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ /* @TODO: add rule to identify BOW beacons */ -+#endif -+ -+ default: -+ DBGLOG(SCN, ERROR, "wrong bss type %d\n", (INT_32)(u2CapInfo & CAP_INFO_BSS_TYPE)); -+ return NULL; -+ } -+ -+ /* 4 <1.1> Pre-parse SSID IE */ -+ pucIE = prWlanBeaconFrame->aucInfoElem; -+ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (UINT_16) OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]); -+ -+ if (u2IELength > CFG_IE_BUFFER_SIZE) -+ u2IELength = CFG_IE_BUFFER_SIZE; -+ kalMemZero(&rSsid, sizeof(rSsid)); -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_SSID: -+ if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID) { -+ ucSSIDChar = '\0'; -+ -+ /* D-Link DWL-900AP+ */ -+ if (IE_LEN(pucIE) == 0) -+ fgIsValidSsid = FALSE; -+ /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */ -+ /* Linksys WRK54G/WL520g - (IE_LEN(pucIE) == n) && -+ * (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */ -+ else { -+ for (i = 0; i < IE_LEN(pucIE); i++) -+ ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i]; -+ -+ if (ucSSIDChar) -+ fgIsValidSsid = TRUE; -+ } -+ -+ /* Update SSID to BSS Descriptor only if SSID is not hidden. */ -+ if (fgIsValidSsid == TRUE) { -+ COPY_SSID(rSsid.aucSsid, -+ rSsid.u4SsidLen, SSID_IE(pucIE)->aucSSID, SSID_IE(pucIE)->ucLength); -+ } -+ } -+ fgEscape = TRUE; -+ break; -+ default: -+ break; -+ } -+ -+ if (fgEscape == TRUE) -+ break; -+ } -+ if (fgIsValidSsid) -+ DBGLOG(SCN, EVENT, "%s %pM channel %d\n", rSsid.aucSsid, prWlanBeaconFrame->aucBSSID, -+ HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr)); -+ else -+ DBGLOG(SCN, EVENT, "hidden ssid, %pM channel %d\n", prWlanBeaconFrame->aucBSSID, -+ HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr)); -+ /* 4 <1.2> Replace existing BSS_DESC_T or allocate a new one */ -+ prBssDesc = scanSearchExistingBssDescWithSsid(prAdapter, -+ eBSSType, -+ (PUINT_8) prWlanBeaconFrame->aucBSSID, -+ (PUINT_8) prWlanBeaconFrame->aucSrcAddr, -+ fgIsValidSsid, fgIsValidSsid == TRUE ? &rSsid : NULL); -+ -+ if (prBssDesc == (P_BSS_DESC_T) NULL) { -+ fgIsNewBssDesc = TRUE; -+ -+ do { -+ /* 4 <1.2.1> First trial of allocation */ -+ prBssDesc = scanAllocateBssDesc(prAdapter); -+ if (prBssDesc) -+ break; -+ /* 4 <1.2.2> Hidden is useless, remove the oldest hidden ssid. (for passive scan) */ -+ scanRemoveBssDescsByPolicy(prAdapter, -+ (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_OLDEST_HIDDEN)); -+ -+ /* 4 <1.2.3> Second tail of allocation */ -+ prBssDesc = scanAllocateBssDesc(prAdapter); -+ if (prBssDesc) -+ break; -+ /* 4 <1.2.4> Remove the weakest one */ -+ /* If there are more than half of BSS which has the same ssid as connection -+ * setting, remove the weakest one from them. -+ * Else remove the weakest one. -+ */ -+ scanRemoveBssDescsByPolicy(prAdapter, -+ (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_SMART_WEAKEST)); -+ -+ /* 4 <1.2.5> reallocation */ -+ prBssDesc = scanAllocateBssDesc(prAdapter); -+ if (prBssDesc) -+ break; -+ /* 4 <1.2.6> no space, should not happen */ -+ DBGLOG(SCN, ERROR, "no bss desc available after remove policy\n"); -+ return NULL; -+ -+ } while (FALSE); -+ -+ } else { -+ OS_SYSTIME rCurrentTime; -+ -+ /* WCXRP00000091 */ -+ /* if the received strength is much weaker than the original one, */ -+ /* ignore it due to it might be received on the folding frequency */ -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ -+ if (prBssDesc->eBSSType != eBSSType) { -+ prBssDesc->eBSSType = eBSSType; -+ } else if (HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr) != prBssDesc->ucChannelNum && -+ prBssDesc->ucRCPI > prSwRfb->prHifRxHdr->ucRcpi) { -+ /* for signal strength is too much weaker and previous beacon is not stale */ -+ if ((prBssDesc->ucRCPI - prSwRfb->prHifRxHdr->ucRcpi) >= REPLICATED_BEACON_STRENGTH_THRESHOLD && -+ (rCurrentTime - prBssDesc->rUpdateTime) <= REPLICATED_BEACON_FRESH_PERIOD) { -+ DBGLOG(SCN, EVENT, "rssi is too much weaker and previous one is fresh\n"); -+ return prBssDesc; -+ } -+ /* for received beacons too close in time domain */ -+ else if (rCurrentTime - prBssDesc->rUpdateTime <= REPLICATED_BEACON_TIME_THRESHOLD) { -+ DBGLOG(SCN, EVENT, "receive beacon/probe reponses too close\n"); -+ return prBssDesc; -+ } -+ } -+ -+ /* if Timestamp has been reset, re-generate BSS DESC 'cause AP should have reset itself */ -+ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && u8Timestamp < prBssDesc->u8TimeStamp.QuadPart) { -+ BOOLEAN fgIsConnected, fgIsConnecting; -+ -+ /* set flag for indicating this is a new BSS-DESC */ -+ fgIsNewBssDesc = TRUE; -+ -+ /* backup 2 flags for APs which reset timestamp unexpectedly */ -+ fgIsConnected = prBssDesc->fgIsConnected; -+ fgIsConnecting = prBssDesc->fgIsConnecting; -+ scanRemoveBssDescByBssid(prAdapter, prBssDesc->aucBSSID); -+ -+ prBssDesc = scanAllocateBssDesc(prAdapter); -+ if (!prBssDesc) -+ return NULL; -+ -+ /* restore */ -+ prBssDesc->fgIsConnected = fgIsConnected; -+ prBssDesc->fgIsConnecting = fgIsConnecting; -+ } -+ } -+#if 1 -+ -+ prBssDesc->u2RawLength = prSwRfb->u2PacketLen; -+ if (prBssDesc->u2RawLength > CFG_RAW_BUFFER_SIZE) -+ prBssDesc->u2RawLength = CFG_RAW_BUFFER_SIZE; -+ kalMemCopy(prBssDesc->aucRawBuf, prWlanBeaconFrame, prBssDesc->u2RawLength); -+#endif -+ -+ /* NOTE: Keep consistency of Scan Record during JOIN process */ -+ if ((fgIsNewBssDesc == FALSE) && prBssDesc->fgIsConnecting) { -+ DBGLOG(SCN, INFO, "we're connecting this BSS(%pM) now, don't update it\n", -+ prBssDesc->aucBSSID); -+ return prBssDesc; -+ } -+ /* 4 <2> Get information from Fixed Fields */ -+ prBssDesc->eBSSType = eBSSType; /* Update the latest BSS type information. */ -+ -+ COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prWlanBeaconFrame->aucSrcAddr); -+ -+ COPY_MAC_ADDR(prBssDesc->aucBSSID, prWlanBeaconFrame->aucBSSID); -+ -+ prBssDesc->u8TimeStamp.QuadPart = u8Timestamp; -+ -+ WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2BeaconInterval, &prBssDesc->u2BeaconInterval); -+ -+ prBssDesc->u2CapInfo = u2CapInfo; -+ -+ /* 4 <2.1> Retrieve IEs for later parsing */ -+ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (UINT_16) OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]); -+ -+ if (u2IELength > CFG_IE_BUFFER_SIZE) { -+ u2IELength = CFG_IE_BUFFER_SIZE; -+ prBssDesc->fgIsIEOverflow = TRUE; -+ } else { -+ prBssDesc->fgIsIEOverflow = FALSE; -+ } -+ prBssDesc->u2IELength = u2IELength; -+ -+ kalMemCopy(prBssDesc->aucIEBuf, prWlanBeaconFrame->aucInfoElem, u2IELength); -+ -+ /* 4 <2.2> reset prBssDesc variables in case that AP has been reconfigured */ -+ prBssDesc->fgIsERPPresent = FALSE; -+ prBssDesc->fgIsHTPresent = FALSE; -+ prBssDesc->eSco = CHNL_EXT_SCN; -+ prBssDesc->fgIEWAPI = FALSE; -+#if CFG_RSN_MIGRATION -+ prBssDesc->fgIERSN = FALSE; -+#endif -+#if CFG_PRIVACY_MIGRATION -+ prBssDesc->fgIEWPA = FALSE; -+#endif -+ -+ /* 4 <3.1> Full IE parsing on SW_RFB_T */ -+ pucIE = prWlanBeaconFrame->aucInfoElem; -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_SSID: -+ if ((!prIeSsid) && /* NOTE(Kevin): for Atheros IOT #1 */ -+ (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) { -+ BOOLEAN fgIsHiddenSSID = FALSE; -+ -+ ucSSIDChar = '\0'; -+ -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ -+ /* D-Link DWL-900AP+ */ -+ if (IE_LEN(pucIE) == 0) -+ fgIsHiddenSSID = TRUE; -+ /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */ -+ /* Linksys WRK54G/WL520g - (IE_LEN(pucIE) == n) && -+ * (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */ -+ else { -+ for (i = 0; i < IE_LEN(pucIE); i++) -+ ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i]; -+ -+ if (!ucSSIDChar) -+ fgIsHiddenSSID = TRUE; -+ } -+ -+ /* Update SSID to BSS Descriptor only if SSID is not hidden. */ -+ if (!fgIsHiddenSSID) { -+ COPY_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, -+ SSID_IE(pucIE)->aucSSID, SSID_IE(pucIE)->ucLength); -+ } -+#if 0 -+ /* -+ After we connect to a hidden SSID, prBssDesc->aucSSID[] will -+ not be empty and prBssDesc->ucSSIDLen will not be 0, -+ so maybe we need to empty prBssDesc->aucSSID[] and set -+ prBssDesc->ucSSIDLen to 0 in prBssDesc to avoid that -+ UI still displays hidden SSID AP in scan list after -+ we disconnect the hidden SSID AP. -+ */ -+ else { -+ prBssDesc->aucSSID[0] = '\0'; -+ prBssDesc->ucSSIDLen = 0; -+ } -+#endif -+ -+ } -+ break; -+ -+ case ELEM_ID_SUP_RATES: -+ /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8. -+ * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B), -+ * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" -+ */ -+ /* TP-LINK will set extra and incorrect ie with ELEM_ID_SUP_RATES */ -+ if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM)) -+ prIeSupportedRate = SUP_RATES_IE(pucIE); -+ break; -+ -+ case ELEM_ID_DS_PARAM_SET: -+ if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) -+ ucIeDsChannelNum = DS_PARAM_IE(pucIE)->ucCurrChnl; -+ break; -+ -+ case ELEM_ID_TIM: -+ if (IE_LEN(pucIE) <= ELEM_MAX_LEN_TIM) -+ prBssDesc->ucDTIMPeriod = TIM_IE(pucIE)->ucDTIMPeriod; -+ break; -+ -+ case ELEM_ID_IBSS_PARAM_SET: -+ if (IE_LEN(pucIE) == ELEM_MAX_LEN_IBSS_PARAMETER_SET) -+ prBssDesc->u2ATIMWindow = IBSS_PARAM_IE(pucIE)->u2ATIMWindow; -+ break; -+ -+#if 0 /* CFG_SUPPORT_802_11D */ -+ case ELEM_ID_COUNTRY_INFO: -+ prBssDesc->prIECountry = (P_IE_COUNTRY_T) pucIE; -+ break; -+#endif -+ -+ case ELEM_ID_ERP_INFO: -+ if (IE_LEN(pucIE) == ELEM_MAX_LEN_ERP) -+ prBssDesc->fgIsERPPresent = TRUE; -+ break; -+ -+ case ELEM_ID_EXTENDED_SUP_RATES: -+ if (!prIeExtSupportedRate) -+ prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); -+ break; -+ -+#if CFG_RSN_MIGRATION -+ case ELEM_ID_RSN: -+ if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &prBssDesc->rRSNInfo)) { -+ prBssDesc->fgIERSN = TRUE; -+ prBssDesc->u2RsnCap = prBssDesc->rRSNInfo.u2RsnCap; -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) -+ rsnCheckPmkidCache(prAdapter, prBssDesc); -+ } -+ break; -+#endif -+ -+ case ELEM_ID_HT_CAP: -+ prBssDesc->fgIsHTPresent = TRUE; -+ break; -+ -+ case ELEM_ID_HT_OP: -+ if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) -+ break; -+ -+ if ((((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) { -+ prBssDesc->eSco = (ENUM_CHNL_EXT_T) -+ (((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO); -+ } -+ ucIeHtChannelNum = ((P_IE_HT_OP_T) pucIE)->ucPrimaryChannel; -+ -+ break; -+ -+#if CFG_SUPPORT_WAPI -+ case ELEM_ID_WAPI: -+ if (wapiParseWapiIE(WAPI_IE(pucIE), &prBssDesc->rIEWAPI)) -+ prBssDesc->fgIEWAPI = TRUE; -+ break; -+#endif -+ -+ case ELEM_ID_VENDOR: /* ELEM_ID_P2P, ELEM_ID_WMM */ -+#if CFG_PRIVACY_MIGRATION -+ if (rsnParseCheckForWFAInfoElem(prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) { -+ if ((ucOuiType == VENDOR_OUI_TYPE_WPA) && (u2SubTypeVersion == VERSION_WPA)) { -+ -+ if (rsnParseWpaIE(prAdapter, WPA_IE(pucIE), &prBssDesc->rWPAInfo)) -+ prBssDesc->fgIEWPA = TRUE; -+ } -+ } -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) { -+ if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) { -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) -+ prBssDesc->fgIsP2PPresent = TRUE; -+ } -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ break; -+ -+ /* no default */ -+ } -+ } -+ -+ /* 4 <3.2> Save information from IEs - SSID */ -+ /* Update Flag of Hidden SSID for used in SEARCH STATE. */ -+ -+ /* NOTE(Kevin): in current driver, the ucSSIDLen == 0 represent -+ * all cases of hidden SSID. -+ * If the fgIsHiddenSSID == TRUE, it means we didn't get the ProbeResp with -+ * valid SSID. -+ */ -+ if (prBssDesc->ucSSIDLen == 0) -+ prBssDesc->fgIsHiddenSSID = TRUE; -+ else -+ prBssDesc->fgIsHiddenSSID = FALSE; -+ -+ /* 4 <3.3> Check rate information in related IEs. */ -+ if (prIeSupportedRate || prIeExtSupportedRate) { -+ rateGetRateSetFromIEs(prIeSupportedRate, -+ prIeExtSupportedRate, -+ &prBssDesc->u2OperationalRateSet, -+ &prBssDesc->u2BSSBasicRateSet, &prBssDesc->fgIsUnknownBssBasicRate); -+ } -+ /* 4 <4> Update information from HIF RX Header */ -+ { -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ -+ ASSERT(prHifRxHdr); -+ -+ /* 4 <4.1> Get TSF comparison result */ -+ prBssDesc->fgIsLargerTSF = HIF_RX_HDR_GET_TCL_FLAG(prHifRxHdr); -+ -+ /* 4 <4.2> Get Band information */ -+ prBssDesc->eBand = HIF_RX_HDR_GET_RF_BAND(prHifRxHdr); -+ -+ /* 4 <4.2> Get channel and RCPI information */ -+ ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prHifRxHdr); -+ -+ if (BAND_2G4 == prBssDesc->eBand) { -+ -+ /* Update RCPI if in right channel */ -+ if (ucIeDsChannelNum >= 1 && ucIeDsChannelNum <= 14) { -+ -+ /* Receive Beacon/ProbeResp frame from adjacent channel. */ -+ if ((ucIeDsChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) -+ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; -+ /* trust channel information brought by IE */ -+ prBssDesc->ucChannelNum = ucIeDsChannelNum; -+ } else if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum <= 14) { -+ /* Receive Beacon/ProbeResp frame from adjacent channel. */ -+ if ((ucIeHtChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) -+ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; -+ /* trust channel information brought by IE */ -+ prBssDesc->ucChannelNum = ucIeHtChannelNum; -+ } else { -+ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; -+ -+ prBssDesc->ucChannelNum = ucHwChannelNum; -+ } -+ } -+ /* 5G Band */ -+ else { -+ if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum < 200) { -+ /* Receive Beacon/ProbeResp frame from adjacent channel. */ -+ if ((ucIeHtChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) -+ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; -+ /* trust channel information brought by IE */ -+ prBssDesc->ucChannelNum = ucIeHtChannelNum; -+ } else { -+ /* Always update RCPI */ -+ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; -+ -+ prBssDesc->ucChannelNum = ucHwChannelNum; -+ } -+ } -+ } -+ -+ /* 4 <5> PHY type setting */ -+ prBssDesc->ucPhyTypeSet = 0; -+ -+ if (BAND_2G4 == prBssDesc->eBand) { -+ /* check if support 11n */ -+ if (prBssDesc->fgIsHTPresent) -+ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT; -+ -+ /* if not 11n only */ -+ if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) { -+ /* check if support 11g */ -+ if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) || prBssDesc->fgIsERPPresent) -+ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_ERP; -+ -+ /* if not 11g only */ -+ if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_OFDM)) { -+ /* check if support 11b */ -+ if ((prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS)) -+ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS; -+ } -+ } -+ } else { /* (BAND_5G == prBssDesc->eBande) */ -+ /* check if support 11n */ -+ if (prBssDesc->fgIsHTPresent) -+ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT; -+ -+ /* if not 11n only */ -+ if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) { -+ /* Support 11a definitely */ -+ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; -+ -+ ASSERT(!(prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS)); -+ } -+ } -+ -+ /* 4 <6> Update BSS_DESC_T's Last Update TimeStamp. */ -+ GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime); -+ -+ return prBssDesc; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to scan result for query -+* -+* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host. -+* @retval WLAN_STATUS_FAILURE It is not a valid Scan Result. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS scanAddScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX]; -+ P_WLAN_BEACON_FRAME_T prWlanBeaconFrame; -+ PARAM_MAC_ADDRESS rMacAddr; -+ PARAM_SSID_T rSsid; -+ ENUM_PARAM_NETWORK_TYPE_T eNetworkType; -+ PARAM_802_11_CONFIG_T rConfiguration; -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ UINT_8 ucRateLen = 0; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ if (prBssDesc->eBand == BAND_2G4) { -+ if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) -+ || prBssDesc->fgIsERPPresent) { -+ eNetworkType = PARAM_NETWORK_TYPE_OFDM24; -+ } else { -+ eNetworkType = PARAM_NETWORK_TYPE_DS; -+ } -+ } else { -+ ASSERT(prBssDesc->eBand == BAND_5G); -+ eNetworkType = PARAM_NETWORK_TYPE_OFDM5; -+ } -+ -+ if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) { -+ /* NOTE(Kevin): Not supported by WZC(TBD) */ -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader; -+ COPY_MAC_ADDR(rMacAddr, prWlanBeaconFrame->aucBSSID); -+ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ -+ rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T); -+ rConfiguration.u4BeaconPeriod = (UINT_32) prWlanBeaconFrame->u2BeaconInterval; -+ rConfiguration.u4ATIMWindow = prBssDesc->u2ATIMWindow; -+ rConfiguration.u4DSConfig = nicChannelNum2Freq(prBssDesc->ucChannelNum); -+ rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); -+ -+ rateGetDataRatesFromRateSet(prBssDesc->u2OperationalRateSet, 0, aucRatesEx, &ucRateLen); -+ -+ /* NOTE(Kevin): Set unused entries, if any, at the end of the array to 0. -+ * from OID_802_11_BSSID_LIST -+ */ -+ for (i = ucRateLen; i < sizeof(aucRatesEx) / sizeof(aucRatesEx[0]); i++) -+ aucRatesEx[i] = 0; -+ -+ switch (prBssDesc->eBSSType) { -+ case BSS_TYPE_IBSS: -+ eOpMode = NET_TYPE_IBSS; -+ break; -+ -+ case BSS_TYPE_INFRASTRUCTURE: -+ case BSS_TYPE_P2P_DEVICE: -+ case BSS_TYPE_BOW_DEVICE: -+ default: -+ eOpMode = NET_TYPE_INFRA; -+ break; -+ } -+ -+ DBGLOG(SCN, TRACE, "ind %s %d\n", prBssDesc->aucSSID, prBssDesc->ucChannelNum); -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ { -+ if (flgTdlsTestExtCapElm == TRUE) { -+ /* only for RALINK AP */ -+ UINT8 *pucElm = (UINT8 *) (prSwRfb->pvHeader + prSwRfb->u2PacketLen); -+ -+ kalMemCopy(pucElm - 9, aucTdlsTestExtCapElm, 7); -+ prSwRfb->u2PacketLen -= 2; -+/* prSwRfb->u2PacketLen += 7; */ -+ -+ DBGLOG(TDLS, INFO, -+ " %s: append ext cap element to %pM\n", -+ __func__, prBssDesc->aucBSSID); -+ } -+ } -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ if (prAdapter->rWifiVar.rScanInfo.fgNloScanning && -+ test_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prAdapter->ulSuspendFlag)) { -+ UINT_8 i = 0; -+ P_BSS_DESC_T *pprPendBssDesc = &prScanInfo->rNloParam.aprPendingBssDescToInd[0]; -+ -+ for (; i < SCN_SSID_MATCH_MAX_NUM; i++) { -+ if (pprPendBssDesc[i]) -+ continue; -+ DBGLOG(SCN, INFO, -+ "indicate bss[%pM] before wiphy resume, need to indicate again after wiphy resume\n", -+ prBssDesc->aucBSSID); -+ pprPendBssDesc[i] = prBssDesc; -+ break; -+ } -+ } -+ -+ kalIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prSwRfb->pvHeader, -+ prSwRfb->u2PacketLen, prBssDesc->ucChannelNum, RCPI_TO_dBm(prBssDesc->ucRCPI)); -+ -+ nicAddScanResult(prAdapter, -+ rMacAddr, -+ &rSsid, -+ prWlanBeaconFrame->u2CapInfo & CAP_INFO_PRIVACY ? 1 : 0, -+ RCPI_TO_dBm(prBssDesc->ucRCPI), -+ eNetworkType, -+ &rConfiguration, -+ eOpMode, -+ aucRatesEx, -+ prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen, -+ (PUINT_8) ((ULONG) (prSwRfb->pvHeader) + WLAN_MAC_MGMT_HEADER_LEN)); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of scanAddScanResult() */ -+ -+#if 1 -+ -+BOOLEAN scanCheckBssIsLegal(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc) -+{ -+ BOOLEAN fgAddToScanResult = FALSE; -+ ENUM_BAND_T eBand = 0; -+ UINT_8 ucChannel = 0; -+ -+ ASSERT(prAdapter); -+ /* check the channel is in the legal doamin */ -+ if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == TRUE) { -+ /* check ucChannelNum/eBand for adjacement channel filtering */ -+ if (cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE && -+ (eBand != prBssDesc->eBand || ucChannel != prBssDesc->ucChannelNum)) { -+ fgAddToScanResult = FALSE; -+ } else { -+ fgAddToScanResult = TRUE; -+ } -+ } -+ return fgAddToScanResult; -+ -+} -+ -+VOID scanReportBss2Cfg80211(IN P_ADAPTER_T prAdapter, IN ENUM_BSS_TYPE_T eBSSType, IN P_BSS_DESC_T SpecificprBssDesc) -+{ -+ P_SCAN_INFO_T prScanInfo = (P_SCAN_INFO_T) NULL; -+ P_LINK_T prBSSDescList = (P_LINK_T) NULL; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ RF_CHANNEL_INFO_T rChannelInfo; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ DBGLOG(SCN, TRACE, "scanReportBss2Cfg80211\n"); -+ -+ if (SpecificprBssDesc) { -+ { -+ /* check BSSID is legal channel */ -+ if (!scanCheckBssIsLegal(prAdapter, SpecificprBssDesc)) { -+ DBGLOG(SCN, TRACE, "Remove specific SSID[%s %d]\n", -+ SpecificprBssDesc->aucSSID, SpecificprBssDesc->ucChannelNum); -+ return; -+ } -+ -+ DBGLOG(SCN, TRACE, "Report Specific SSID[%s]\n", SpecificprBssDesc->aucSSID); -+ if (eBSSType == BSS_TYPE_INFRASTRUCTURE) { -+ -+ kalIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) SpecificprBssDesc->aucRawBuf, -+ SpecificprBssDesc->u2RawLength, -+ SpecificprBssDesc->ucChannelNum, -+ RCPI_TO_dBm(SpecificprBssDesc->ucRCPI)); -+ } else { -+ -+ rChannelInfo.ucChannelNum = SpecificprBssDesc->ucChannelNum; -+ rChannelInfo.eBand = SpecificprBssDesc->eBand; -+ kalP2PIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) SpecificprBssDesc->aucRawBuf, -+ SpecificprBssDesc->u2RawLength, -+ &rChannelInfo, RCPI_TO_dBm(SpecificprBssDesc->ucRCPI)); -+ -+ } -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ SpecificprBssDesc->fgIsP2PReport = FALSE; -+#endif -+ } -+ } else { -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ /* 4 Auto Channel Selection:Record the AP Number */ -+ P_PARAM_CHN_LOAD_INFO prChnLoad; -+ UINT_8 ucIdx = 0; -+ -+ if (((prBssDesc->ucChannelNum > 0) && (prBssDesc->ucChannelNum <= 48)) -+ || (prBssDesc->ucChannelNum >= 147) /*non-DFS Channel */) { -+ if (prBssDesc->ucChannelNum <= HW_CHNL_NUM_MAX_2G4) { -+ ucIdx = prBssDesc->ucChannelNum - 1; -+ } else if (prBssDesc->ucChannelNum <= 48) { -+ ucIdx = (UINT_8) (HW_CHNL_NUM_MAX_2G4 + (prBssDesc->ucChannelNum - 34) / 4); -+ } else { -+ ucIdx = -+ (UINT_8) (HW_CHNL_NUM_MAX_2G4 + 4 + (prBssDesc->ucChannelNum - 149) / 4); -+ } -+ -+ if (ucIdx < MAX_AUTO_CHAL_NUM) { -+ prChnLoad = (P_PARAM_CHN_LOAD_INFO) & -+ (prAdapter->rWifiVar.rChnLoadInfo.rEachChnLoad[ucIdx]); -+ prChnLoad->ucChannel = prBssDesc->ucChannelNum; -+ prChnLoad->u2APNum++; -+ } else { -+ DBGLOG(SCN, WARN, "ACS: ChIdx > MAX_AUTO_CHAL_NUM\n"); -+ } -+ -+ } -+#endif -+ /* check BSSID is legal channel */ -+ if (!scanCheckBssIsLegal(prAdapter, prBssDesc)) { -+ DBGLOG(SCN, TRACE, "Remove SSID[%s %d]\n", -+ prBssDesc->aucSSID, prBssDesc->ucChannelNum); -+ -+ continue; -+ } -+ -+ if ((prBssDesc->eBSSType == eBSSType) -+#if CFG_ENABLE_WIFI_DIRECT -+ || ((eBSSType == BSS_TYPE_P2P_DEVICE) && (prBssDesc->fgIsP2PReport == TRUE)) -+#endif -+ ) { -+ -+ DBGLOG(SCN, TRACE, "Report ALL SSID[%s %d]\n", -+ prBssDesc->aucSSID, prBssDesc->ucChannelNum); -+ -+ if (eBSSType == BSS_TYPE_INFRASTRUCTURE) { -+ if (prBssDesc->u2RawLength != 0) { -+ kalIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prBssDesc->aucRawBuf, -+ prBssDesc->u2RawLength, -+ prBssDesc->ucChannelNum, -+ RCPI_TO_dBm(prBssDesc->ucRCPI)); -+ kalMemZero(prBssDesc->aucRawBuf, CFG_RAW_BUFFER_SIZE); -+ prBssDesc->u2RawLength = 0; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ prBssDesc->fgIsP2PReport = FALSE; -+#endif -+ } -+ } else { -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prBssDesc->fgIsP2PReport == TRUE) { -+#endif -+ rChannelInfo.ucChannelNum = prBssDesc->ucChannelNum; -+ rChannelInfo.eBand = prBssDesc->eBand; -+ -+ kalP2PIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prBssDesc->aucRawBuf, -+ prBssDesc->u2RawLength, -+ &rChannelInfo, RCPI_TO_dBm(prBssDesc->ucRCPI)); -+ -+ /* do not clear it then we can pass the bss in Specific report */ -+ /* kalMemZero(prBssDesc->aucRawBuf,CFG_RAW_BUFFER_SIZE); */ -+ -+ /* -+ the BSS entry will not be cleared after scan done. -+ So if we dont receive the BSS in next scan, we cannot -+ pass it. We use u2RawLength for the purpose. -+ */ -+ /* prBssDesc->u2RawLength=0; */ -+#if CFG_ENABLE_WIFI_DIRECT -+ prBssDesc->fgIsP2PReport = FALSE; -+ } -+#endif -+ } -+ } -+ -+ } -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit = TRUE; -+#endif -+ -+ } -+ -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Parse the content of given Beacon or ProbeResp Frame. -+* -+* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS if not report this SW_RFB_T to host -+* @retval WLAN_STATUS_PENDING if report this SW_RFB_T to host as scan result -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS scanProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_BSS_INFO_T prAisBssInfo; -+ P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) NULL; -+#if CFG_SLT_SUPPORT -+ P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL; -+#endif -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ /* 4 <0> Ignore invalid Beacon Frame */ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < -+ (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)) { -+ /* to debug beacon length too small issue */ -+ UINT_32 u4MailBox0; -+ -+ nicGetMailbox(prAdapter, 0, &u4MailBox0); -+ DBGLOG(SCN, WARN, "if conn sys also get less length (0x5a means yes) %x\n", (UINT_32) u4MailBox0); -+ DBGLOG(SCN, WARN, "u2PacketLen %d, u2HeaderLen %d, payloadLen %d\n", -+ prSwRfb->u2PacketLen, prSwRfb->u2HeaderLen, -+ prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen); -+ /* dumpMemory8(prSwRfb->pvHeader, prSwRfb->u2PacketLen); */ -+ -+#ifndef _lint -+ ASSERT(0); -+#endif /* _lint */ -+ return rStatus; -+ } -+#if CFG_SLT_SUPPORT -+ prSltInfo = &prAdapter->rWifiVar.rSltInfo; -+ -+ if (prSltInfo->fgIsDUT) { -+ DBGLOG(SCN, INFO, "\n\rBCN: RX\n"); -+ prSltInfo->u4BeaconReceiveCnt++; -+ return WLAN_STATUS_SUCCESS; -+ } else { -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader; -+ -+ /*ALPS01475157: don't show SSID on scan list for multicast MAC AP */ -+ if (IS_BMCAST_MAC_ADDR(prWlanBeaconFrame->aucSrcAddr)) { -+ DBGLOG(SCN, WARN, "received beacon/probe response from multicast AP\n"); -+ return rStatus; -+ } -+ -+ /* 4 <1> Parse and add into BSS_DESC_T */ -+ prBssDesc = scanAddToBssDesc(prAdapter, prSwRfb); -+ -+ if (prBssDesc) { -+ /* 4 <1.1> Beacon Change Detection for Connected BSS */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED && -+ ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS) -+ || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA)) && -+ EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) && -+ EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, prAisBssInfo->aucSSID, -+ prAisBssInfo->ucSSIDLen)) { -+ BOOLEAN fgNeedDisconnect = FALSE; -+ -+#if CFG_SUPPORT_BEACON_CHANGE_DETECTION -+ /* <1.1.2> check if supported rate differs */ -+ if (prAisBssInfo->u2OperationalRateSet != prBssDesc->u2OperationalRateSet) -+ fgNeedDisconnect = TRUE; -+#endif -+#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE -+ if ( -+#if CFG_SUPPORT_WAPI -+ (prAdapter->rWifiVar.rConnSettings.fgWapiMode == TRUE && -+ !wapiPerformPolicySelection(prAdapter, prBssDesc)) || -+#endif -+ rsnCheckSecurityModeChanged(prAdapter, prAisBssInfo, prBssDesc)) { -+ DBGLOG(SCN, INFO, "Beacon security mode change detected\n"); -+ fgNeedDisconnect = FALSE; -+ aisBssSecurityChanged(prAdapter); -+ } -+#endif -+ -+ /* <1.1.3> beacon content change detected, disconnect immediately */ -+ if (fgNeedDisconnect == TRUE) -+ aisBssBeaconTimeout(prAdapter); -+ } -+ /* 4 <1.1> Update AIS_BSS_INFO */ -+ if (((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS) -+ || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA))) { -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* *not* checking prBssDesc->fgIsConnected anymore, -+ * due to Linksys AP uses " " as hidden SSID, and would have different BSS descriptor */ -+ if ((!prAisBssInfo->ucDTIMPeriod) && -+ EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) && -+ (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && -+ ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) { -+ -+ prAisBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; -+ -+ /* sync with firmware for beacon information */ -+ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ } -+ } -+#if CFG_SUPPORT_ADHOC -+ if (EQUAL_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, -+ prConnSettings->aucSSID, -+ prConnSettings->ucSSIDLen) && -+ (prBssDesc->eBSSType == BSS_TYPE_IBSS) && (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS)) { -+ ibssProcessMatchedBeacon(prAdapter, prAisBssInfo, prBssDesc, -+ prSwRfb->prHifRxHdr->ucRcpi); -+ } -+#endif /* CFG_SUPPORT_ADHOC */ -+ } -+ -+ rlmProcessBcn(prAdapter, -+ prSwRfb, -+ ((P_WLAN_BEACON_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem, -+ (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (UINT_16) (OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]))); -+ -+ /* 4 <3> Send SW_RFB_T to HIF when we perform SCAN for HOST */ -+ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE || prBssDesc->eBSSType == BSS_TYPE_IBSS) { -+ /* for AIS, send to host */ -+ if (prConnSettings->fgIsScanReqIssued || prAdapter->rWifiVar.rScanInfo.fgNloScanning) { -+ BOOLEAN fgAddToScanResult; -+ -+ fgAddToScanResult = scanCheckBssIsLegal(prAdapter, prBssDesc); -+ -+ if (fgAddToScanResult == TRUE) -+ rStatus = scanAddScanResult(prAdapter, prBssDesc, prSwRfb); -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ scanP2pProcessBeaconAndProbeResp(prAdapter, prSwRfb, &rStatus, prBssDesc, prWlanBeaconFrame); -+#endif -+ } -+ -+ return rStatus; -+ -+} /* end of scanProcessBeaconAndProbeResp() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Search the Candidate of BSS Descriptor for JOIN(Infrastructure) or -+* MERGE(AdHoc) according to current Connection Policy. -+* -+* \return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanSearchBssDescByPolicy(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ P_SCAN_INFO_T prScanInfo; -+ -+ P_LINK_T prBSSDescList; -+ -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ P_BSS_DESC_T prPrimaryBssDesc = (P_BSS_DESC_T) NULL; -+ P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T) NULL; -+ -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_STA_RECORD_T prPrimaryStaRec; -+ P_STA_RECORD_T prCandidateStaRec = (P_STA_RECORD_T) NULL; -+ -+ OS_SYSTIME rCurrentTime; -+ -+ /* The first one reach the check point will be our candidate */ -+ BOOLEAN fgIsFindFirst = (BOOLEAN) FALSE; -+ -+ BOOLEAN fgIsFindBestRSSI = (BOOLEAN) FALSE; -+ BOOLEAN fgIsFindBestEncryptionLevel = (BOOLEAN) FALSE; -+ /* BOOLEAN fgIsFindMinChannelLoad = (BOOLEAN)FALSE; */ -+ -+ /* TODO(Kevin): Support Min Channel Load */ -+ /* UINT_8 aucChannelLoad[CHANNEL_NUM] = {0}; */ -+ -+ BOOLEAN fgIsFixedChannel; -+ ENUM_BAND_T eBand = 0; -+ UINT_8 ucChannel = 0; -+ -+ ASSERT(prAdapter); -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ prAisSpecBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ -+ /* check for fixed channel operation */ -+ if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+#if CFG_P2P_LEGACY_COEX_REVISE -+ fgIsFixedChannel = cnmAisDetectP2PChannel(prAdapter, &eBand, &ucChannel); -+#else -+ fgIsFixedChannel = cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel); -+#endif -+ } else { -+ fgIsFixedChannel = FALSE; -+ } -+ -+#if DBG -+ if (prConnSettings->ucSSIDLen < ELEM_MAX_LEN_SSID) -+ prConnSettings->aucSSID[prConnSettings->ucSSIDLen] = '\0'; -+#endif -+ -+ DBGLOG(SCN, INFO, "SEARCH: Bss Num: %d, Look for SSID: %s, %pM Band=%d, channel=%d\n", -+ (UINT_32) prBSSDescList->u4NumElem, prConnSettings->aucSSID, -+ (prConnSettings->aucBSSID), eBand, ucChannel); -+ -+ /* 4 <1> The outer loop to search for a candidate. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ /* TODO(Kevin): Update Minimum Channel Load Information here */ -+ -+ DBGLOG(SCN, TRACE, "SEARCH: [ %pM ], SSID:%s\n", -+ prBssDesc->aucBSSID, prBssDesc->aucSSID); -+ -+ /* 4 <2> Check PHY Type and attributes */ -+ /* 4 <2.1> Check Unsupported BSS PHY Type */ -+ if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) { -+ DBGLOG(SCN, TRACE, "SEARCH: Ignore unsupported ucPhyTypeSet = %x\n", prBssDesc->ucPhyTypeSet); -+ continue; -+ } -+ /* 4 <2.2> Check if has unknown NonHT BSS Basic Rate Set. */ -+ if (prBssDesc->fgIsUnknownBssBasicRate) -+ continue; -+ /* 4 <2.3> Check if fixed operation cases should be aware */ -+ if (fgIsFixedChannel == TRUE && (prBssDesc->eBand != eBand || prBssDesc->ucChannelNum != ucChannel)) -+ continue; -+ /* 4 <2.4> Check if the channel is legal under regulatory domain */ -+ if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == FALSE) -+ continue; -+ /* 4 <2.5> Check if this BSS_DESC_T is stale */ -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, -+ SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC))) { -+ -+ BOOLEAN fgIsNeedToCheckTimeout = TRUE; -+ -+#if CFG_SUPPORT_ROAMING -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ if ((prRoamingFsmInfo->eCurrentState == ROAMING_STATE_DISCOVERY) || -+ (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_ROAM)) { -+ if (++prRoamingFsmInfo->RoamingEntryTimeoutSkipCount < -+ ROAMING_ENTRY_TIMEOUT_SKIP_COUNT_MAX) { -+ fgIsNeedToCheckTimeout = FALSE; -+ DBGLOG(SCN, INFO, "SEARCH: Romaing skip SCN_BSS_DESC_REMOVE_TIMEOUT_SEC\n"); -+ } -+ } -+#endif -+ -+ if (fgIsNeedToCheckTimeout == TRUE) { -+ DBGLOG(SCN, TRACE, "Ignore stale bss %pM\n", prBssDesc->aucBSSID); -+ continue; -+ } -+ } -+ /* 4 <3> Check if reach the excessive join retry limit */ -+ /* NOTE(Kevin): STA_RECORD_T is recorded by TA. */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex, prBssDesc->aucSrcAddr); -+ -+ if (prStaRec) { -+ /* NOTE(Kevin): -+ * The Status Code is the result of a Previous Connection Request, -+ * we use this as SCORE for choosing a proper -+ * candidate (Also used for compare see <6>) -+ * The Reason Code is an indication of the reason why AP reject us, -+ * we use this Code for "Reject" -+ * a SCAN result to become our candidate(Like a blacklist). -+ */ -+#if 0 /* TODO(Kevin): */ -+ if (prStaRec->u2ReasonCode != REASON_CODE_RESERVED) { -+ DBGLOG(SCN, INFO, "SEARCH: Ignore BSS with previous Reason Code = %d\n", -+ prStaRec->u2ReasonCode); -+ continue; -+ } else -+#endif -+ if (prStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) { -+ /* NOTE(Kevin): greedy association - after timeout, we'll still -+ * try to associate to the AP whose STATUS of conection attempt -+ * was not success. -+ * We may also use (ucJoinFailureCount x JOIN_RETRY_INTERVAL_SEC) for -+ * time bound. -+ */ -+ if ((prStaRec->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) || -+ (CHECK_FOR_TIMEOUT(rCurrentTime, -+ prStaRec->rLastJoinTime, -+ SEC_TO_SYSTIME(JOIN_RETRY_INTERVAL_SEC)))) { -+ -+ /* NOTE(Kevin): Every JOIN_RETRY_INTERVAL_SEC interval, we can retry -+ * JOIN_MAX_RETRY_FAILURE_COUNT times. -+ */ -+ if (prStaRec->ucJoinFailureCount >= JOIN_MAX_RETRY_FAILURE_COUNT) -+ prStaRec->ucJoinFailureCount = 0; -+ DBGLOG(SCN, INFO, -+ "SEARCH: Try to join BSS again,Status Code=%d (Curr=%u/Last Join=%u)\n", -+ prStaRec->u2StatusCode, rCurrentTime, prStaRec->rLastJoinTime); -+ } else { -+ DBGLOG(SCN, INFO, -+ "SEARCH: Ignore BSS which reach maximum Join Retry Count = %d\n", -+ JOIN_MAX_RETRY_FAILURE_COUNT); -+ continue; -+ } -+ -+ } -+ } -+ /* 4 <4> Check for various NETWORK conditions */ -+ if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+ -+ /* 4 <4.1> Check BSS Type for the corresponding Operation Mode in Connection Setting */ -+ /* NOTE(Kevin): For NET_TYPE_AUTO_SWITCH, we will always pass following check. */ -+ if (((prConnSettings->eOPMode == NET_TYPE_INFRA) && -+ (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE)) -+#if CFG_SUPPORT_ADHOC -+ || ((prConnSettings->eOPMode == NET_TYPE_IBSS -+ || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) -+ && (prBssDesc->eBSSType != BSS_TYPE_IBSS)) -+#endif -+ ) { -+ -+ DBGLOG(SCN, TRACE, "Cur OPMode %d, Ignore eBSSType = %d\n", -+ prConnSettings->eOPMode, prBssDesc->eBSSType); -+ continue; -+ } -+ /* 4 <4.2> Check AP's BSSID if OID_802_11_BSSID has been set. */ -+ if ((prConnSettings->fgIsConnByBssidIssued) && -+ (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)) { -+ -+ if (UNEQUAL_MAC_ADDR(prConnSettings->aucBSSID, prBssDesc->aucBSSID)) { -+ -+ DBGLOG(SCN, TRACE, "SEARCH: Ignore due to BSSID was not matched!\n"); -+ continue; -+ } -+ } -+#if CFG_SUPPORT_ADHOC -+ /* 4 <4.3> Check for AdHoc Mode */ -+ if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { -+ OS_SYSTIME rCurrentTime; -+ -+ /* 4 <4.3.1> Check if this SCAN record has been updated recently for IBSS. */ -+ /* NOTE(Kevin): Because some STA may change its BSSID frequently after it -+ * create the IBSS - e.g. IPN2220, so we need to make sure we get the new one. -+ * For BSS, if the old record was matched, however it won't be able to pass -+ * the Join Process later. -+ */ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, -+ SEC_TO_SYSTIME(SCN_ADHOC_BSS_DESC_TIMEOUT_SEC))) { -+ DBGLOG(SCN, LOUD, -+ "SEARCH: Skip old record of BSS Descriptor - BSSID:[%pM]\n\n", -+ prBssDesc->aucBSSID); -+ continue; -+ } -+ /* 4 <4.3.2> Check Peer's capability */ -+ if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) { -+ -+ if (prPrimaryBssDesc) -+ DBGLOG(SCN, INFO, -+ "SEARCH: BSS DESC MAC: %pM, not supported AdHoc Mode.\n", -+ prPrimaryBssDesc->aucBSSID); -+ -+ continue; -+ } -+ /* 4 <4.3.3> Compare TSF */ -+ if (prBssInfo->fgIsBeaconActivated && -+ UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID)) { -+ -+ DBGLOG(SCN, LOUD, -+ "SEARCH: prBssDesc->fgIsLargerTSF = %d\n", prBssDesc->fgIsLargerTSF); -+ -+ if (!prBssDesc->fgIsLargerTSF) { -+ DBGLOG(SCN, INFO, -+ "SEARCH: Ignore BSS DESC MAC: [ %pM ], Smaller TSF\n", -+ prBssDesc->aucBSSID); -+ continue; -+ } -+ } -+ } -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ } -+#if 0 /* TODO(Kevin): For IBSS */ -+ /* 4 <2.c> Check if this SCAN record has been updated recently for IBSS. */ -+ /* NOTE(Kevin): Because some STA may change its BSSID frequently after it -+ * create the IBSS, so we need to make sure we get the new one. -+ * For BSS, if the old record was matched, however it won't be able to pass -+ * the Join Process later. -+ */ -+ if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { -+ OS_SYSTIME rCurrentTime; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, -+ SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) { -+ DBGLOG(SCAN, TRACE, "Skip old record of BSS Descriptor - BSSID:[%pM]\n\n", -+ prBssDesc->aucBSSID); -+ continue; -+ } -+ } -+ -+ if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) && -+ (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)) { -+ OS_SYSTIME rCurrentTime; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, -+ SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) { -+ DBGLOG(SCAN, TRACE, "Skip old record of BSS Descriptor - BSSID:[%pM]\n\n", -+ (prBssDesc->aucBSSID)); -+ continue; -+ } -+ } -+ /* 4 <4B> Check for IBSS AdHoc Mode. */ -+ /* Skip if one or more BSS Basic Rate are not supported by current AdHocMode */ -+ if (prPrimaryBssDesc->eBSSType == BSS_TYPE_IBSS) { -+ /* 4 <4B.1> Check if match the Capability of current IBSS AdHoc Mode. */ -+ if (ibssCheckCapabilityForAdHocMode(prAdapter, prPrimaryBssDesc) == WLAN_STATUS_FAILURE) { -+ -+ DBGLOG(SCAN, TRACE, -+ "Ignore BSS DESC MAC: %pM, Capability not supported for AdHoc Mode.\n", -+ prPrimaryBssDesc->aucBSSID); -+ -+ continue; -+ } -+ /* 4 <4B.2> IBSS Merge Decision Flow for SEARCH STATE. */ -+ if (prAdapter->fgIsIBSSActive && -+ UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prPrimaryBssDesc->aucBSSID)) { -+ -+ if (!fgIsLocalTSFRead) { -+ NIC_GET_CURRENT_TSF(prAdapter, &rCurrentTsf); -+ -+ DBGLOG(SCAN, TRACE, -+ "\n\nCurrent TSF : %08lx-%08lx\n\n", -+ rCurrentTsf.u.HighPart, rCurrentTsf.u.LowPart); -+ } -+ -+ if (rCurrentTsf.QuadPart > prPrimaryBssDesc->u8TimeStamp.QuadPart) { -+ DBGLOG(SCAN, TRACE, -+ "Ignore BSS DESC MAC: [%pM], Current BSSID: [%pM].\n", -+ prPrimaryBssDesc->aucBSSID, prBssInfo->aucBSSID); -+ -+ DBGLOG(SCAN, TRACE, -+ "\n\nBSS's TSF : %08lx-%08lx\n\n", -+ prPrimaryBssDesc->u8TimeStamp.u.HighPart, -+ prPrimaryBssDesc->u8TimeStamp.u.LowPart); -+ -+ prPrimaryBssDesc->fgIsLargerTSF = FALSE; -+ continue; -+ } else { -+ prPrimaryBssDesc->fgIsLargerTSF = TRUE; -+ } -+ -+ } -+ } -+ /* 4 <5> Check the Encryption Status. */ -+ if (rsnPerformPolicySelection(prPrimaryBssDesc)) { -+ -+ if (prPrimaryBssDesc->ucEncLevel > 0) { -+ fgIsFindBestEncryptionLevel = TRUE; -+ -+ fgIsFindFirst = FALSE; -+ } -+ } else { -+ /* Can't pass the Encryption Status Check, get next one */ -+ continue; -+ } -+ -+ /* For RSN Pre-authentication, update the PMKID canidate list for -+ same SSID and encrypt status */ -+ /* Update PMKID candicate list. */ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) { -+ rsnUpdatePmkidCandidateList(prPrimaryBssDesc); -+ if (prAdapter->rWifiVar.rAisBssInfo.u4PmkidCandicateCount) -+ prAdapter->rWifiVar.rAisBssInfo.fgIndicatePMKID = rsnCheckPmkidCandicate(); -+ } -+#endif -+ -+ prPrimaryBssDesc = (P_BSS_DESC_T) NULL; -+ -+ /* 4 <6> Check current Connection Policy. */ -+ switch (prConnSettings->eConnectionPolicy) { -+ case CONNECT_BY_SSID_BEST_RSSI: -+ /* Choose Hidden SSID to join only if the `fgIsEnableJoin...` is TRUE */ -+ if (prAdapter->rWifiVar.fgEnableJoinToHiddenSSID && prBssDesc->fgIsHiddenSSID) { -+ /* NOTE(Kevin): following if () statement means that -+ * If Target is hidden, then we won't connect when user specify SSID_ANY policy. -+ */ -+ if (prConnSettings->ucSSIDLen) { -+ prPrimaryBssDesc = prBssDesc; -+ fgIsFindBestRSSI = TRUE; -+ } -+ -+ } else if (EQUAL_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, -+ prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) { -+ prPrimaryBssDesc = prBssDesc; -+ fgIsFindBestRSSI = TRUE; -+ -+ DBGLOG(SCN, TRACE, "SEARCH: fgIsFindBestRSSI=TRUE, %d, prPrimaryBssDesc=[ %pM ]\n", -+ prBssDesc->ucRCPI, prPrimaryBssDesc->aucBSSID); -+ } -+ break; -+ -+ case CONNECT_BY_SSID_ANY: -+ /* NOTE(Kevin): In this policy, we don't know the desired -+ * SSID from user, so we should exclude the Hidden SSID from scan list. -+ * And because we refuse to connect to Hidden SSID node at the beginning, so -+ * when the JOIN Module deal with a BSS_DESC_T which has fgIsHiddenSSID == TRUE, -+ * then the Connection Settings must be valid without doubt. -+ */ -+ if (!prBssDesc->fgIsHiddenSSID) { -+ prPrimaryBssDesc = prBssDesc; -+ fgIsFindFirst = TRUE; -+ } -+ break; -+ -+ case CONNECT_BY_BSSID: -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnSettings->aucBSSID)) -+ prPrimaryBssDesc = prBssDesc; -+ break; -+ -+ default: -+ break; -+ } -+ -+ /* Primary Candidate was not found */ -+ if (prPrimaryBssDesc == NULL) -+ continue; -+ /* 4 <7> Check the Encryption Status. */ -+ if (prPrimaryBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { -+#if CFG_SUPPORT_WAPI -+ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) { -+ DBGLOG(SCN, TRACE, "SEARCH: fgWapiMode == 1\n"); -+ -+ if (wapiPerformPolicySelection(prAdapter, prPrimaryBssDesc)) { -+ fgIsFindFirst = TRUE; -+ } else { -+ /* Can't pass the Encryption Status Check, get next one */ -+ DBGLOG(SCN, TRACE, "SEARCH: WAPI cannot pass the Encryption Status Check!\n"); -+ continue; -+ } -+ } else -+#endif -+#if CFG_RSN_MIGRATION -+ if (rsnPerformPolicySelection(prAdapter, prPrimaryBssDesc)) { -+ if (prAisSpecBssInfo->fgCounterMeasure) { -+ DBGLOG(RSN, INFO, "Skip while at counter measure period!!!\n"); -+ continue; -+ } -+ -+ if (prPrimaryBssDesc->ucEncLevel > 0) { -+ fgIsFindBestEncryptionLevel = TRUE; -+ fgIsFindFirst = FALSE; -+ } -+#if 0 -+ /* Update PMKID candicate list. */ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) { -+ rsnUpdatePmkidCandidateList(prPrimaryBssDesc); -+ if (prAisSpecBssInfo->u4PmkidCandicateCount) { -+ if (rsnCheckPmkidCandicate()) { -+ DBGLOG(RSN, WARN, -+ "Prepare a timer to indicate candidate %pM\n", -+ (prAisSpecBssInfo->arPmkidCache -+ [prAisSpecBssInfo->u4PmkidCacheCount]. -+ rBssidInfo.aucBssid))); -+ cnmTimerStopTimer(&prAisSpecBssInfo->rPreauthenticationTimer); -+ cnmTimerStartTimer(&prAisSpecBssInfo->rPreauthenticationTimer, -+ SEC_TO_MSEC -+ (WAIT_TIME_IND_PMKID_CANDICATE_SEC)); -+ } -+ } -+ } -+#endif -+ } else { -+ /* Can't pass the Encryption Status Check, get next one */ -+ continue; -+ } -+#endif -+ } else { -+ /* Todo:: P2P and BOW Policy Selection */ -+ } -+ -+ prPrimaryStaRec = prStaRec; -+ -+ /* 4 <8> Compare the Candidate and the Primary Scan Record. */ -+ if (!prCandidateBssDesc) { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ -+ /* 4 <8.1> Condition - Get the first matched one. */ -+ if (fgIsFindFirst) -+ break; -+ } else { -+#if 0 /* TODO(Kevin): For security(TBD) */ -+ /* 4 <6B> Condition - Choose the one with best Encryption Score. */ -+ if (fgIsFindBestEncryptionLevel) { -+ if (prCandidateBssDesc->ucEncLevel < prPrimaryBssDesc->ucEncLevel) { -+ -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } -+ -+ /* If reach here, that means they have the same Encryption Score. -+ */ -+ -+ /* 4 <6C> Condition - Give opportunity to the one we didn't connect before. */ -+ /* For roaming, only compare the candidates other than current associated BSSID. */ -+ if (!prCandidateBssDesc->fgIsConnected && !prPrimaryBssDesc->fgIsConnected) { -+ if ((prCandidateStaRec != (P_STA_RECORD_T) NULL) && -+ (prCandidateStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) { -+ -+ DBGLOG(SCAN, TRACE, -+ "So far -BSS DESC MAC: %pM has nonzero Status Code = %d\n", -+ prCandidateBssDesc->aucBSSID, -+ prCandidateStaRec->u2StatusCode); -+ -+ if (prPrimaryStaRec != (P_STA_RECORD_T) NULL) { -+ if (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) { -+ -+ /* Give opportunity to the one with smaller rLastJoinTime */ -+ if (TIME_BEFORE(prCandidateStaRec->rLastJoinTime, -+ prPrimaryStaRec->rLastJoinTime)) { -+ continue; -+ } -+ /* We've connect to CANDIDATE recently, -+ * let us try PRIMARY now */ -+ else { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } -+ /* PRIMARY's u2StatusCode = 0 */ -+ else { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } -+ /* PRIMARY has no StaRec - We didn't connet to PRIMARY before */ -+ else { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } else { -+ if ((prPrimaryStaRec != (P_STA_RECORD_T) NULL) && -+ (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) { -+ continue; -+ } -+ } -+ } -+#endif -+ -+ /* 4 <6D> Condition - Visible SSID win Hidden SSID. */ -+ if (prCandidateBssDesc->fgIsHiddenSSID) { -+ if (!prPrimaryBssDesc->fgIsHiddenSSID) { -+ prCandidateBssDesc = prPrimaryBssDesc; /* The non Hidden SSID win. */ -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } else { -+ if (prPrimaryBssDesc->fgIsHiddenSSID) -+ continue; -+ } -+ -+ /* 4 <6E> Condition - Choose the one with better RCPI(RSSI). */ -+ if (fgIsFindBestRSSI) { -+ /* TODO(Kevin): We shouldn't compare the actual value, we should -+ * allow some acceptable tolerance of some RSSI percentage here. -+ */ -+ DBGLOG(SCN, TRACE, -+ "Candidate [%pM]: RCPI = %d, joinFailCnt=%d, Primary [%pM]: RCPI = %d, joinFailCnt=%d\n", -+ prCandidateBssDesc->aucBSSID, -+ prCandidateBssDesc->ucRCPI, prCandidateBssDesc->ucJoinFailureCount, -+ prPrimaryBssDesc->aucBSSID, -+ prPrimaryBssDesc->ucRCPI, prPrimaryBssDesc->ucJoinFailureCount); -+ -+ ASSERT(!(prCandidateBssDesc->fgIsConnected && prPrimaryBssDesc->fgIsConnected)); -+ if (prPrimaryBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) { -+ /* give a chance to do join if join fail before -+ * SCN_BSS_DECRASE_JOIN_FAIL_CNT_SEC seconds -+ */ -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rJoinFailTime, -+ SEC_TO_SYSTIME(SCN_BSS_JOIN_FAIL_CNT_RESET_SEC))) { -+ prBssDesc->ucJoinFailureCount = SCN_BSS_JOIN_FAIL_THRESOLD - -+ SCN_BSS_JOIN_FAIL_RESET_STEP; -+ DBGLOG(SCN, INFO, -+ "decrease join fail count for Bss %pM to %u, timeout second %d\n", -+ prBssDesc->aucBSSID, prBssDesc->ucJoinFailureCount, -+ SCN_BSS_JOIN_FAIL_CNT_RESET_SEC); -+ } -+ } -+ -+ /* NOTE: To prevent SWING, -+ * we do roaming only if target AP has at least 5dBm larger than us. */ -+ if (prCandidateBssDesc->fgIsConnected) { -+ if (prCandidateBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP <= -+ prPrimaryBssDesc->ucRCPI && -+ prPrimaryBssDesc->ucJoinFailureCount < SCN_BSS_JOIN_FAIL_THRESOLD) { -+ -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } else if (prPrimaryBssDesc->fgIsConnected) { -+ if (prCandidateBssDesc->ucRCPI < -+ (prPrimaryBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP) || -+ (prCandidateBssDesc->ucJoinFailureCount >= -+ SCN_BSS_JOIN_FAIL_THRESOLD)) { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } else if (prPrimaryBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) -+ continue; -+ else if (prCandidateBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD || -+ prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI) { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } -+#if 0 -+ /* If reach here, that means they have the same Encryption Score, and -+ * both RSSI value are close too. -+ */ -+ /* 4 <6F> Seek the minimum Channel Load for less interference. */ -+ if (fgIsFindMinChannelLoad) { -+ /* Do nothing */ -+ /* TODO(Kevin): Check which one has minimum channel load in its channel */ -+ } -+#endif -+ } -+ } -+ -+ -+ if (prCandidateBssDesc != NULL) { -+ DBGLOG(SCN, INFO, -+ "SEARCH: Candidate BSS: %pM\n", prCandidateBssDesc->aucBSSID); -+ } -+ -+ return prCandidateBssDesc; -+ -+} /* end of scanSearchBssDescByPolicy() */ -+ -+#if CFG_SUPPORT_AGPS_ASSIST -+VOID scanReportScanResultToAgps(P_ADAPTER_T prAdapter) -+{ -+ P_LINK_T prBSSDescList = &prAdapter->rWifiVar.rScanInfo.rBSSDescList; -+ P_BSS_DESC_T prBssDesc = NULL; -+ P_AGPS_AP_LIST_T prAgpsApList; -+ P_AGPS_AP_INFO_T prAgpsInfo; -+ P_SCAN_INFO_T prScanInfo = &prAdapter->rWifiVar.rScanInfo; -+ UINT_8 ucIndex = 0; -+ -+ prAgpsApList = kalMemAlloc(sizeof(AGPS_AP_LIST_T), VIR_MEM_TYPE); -+ if (!prAgpsApList) -+ return; -+ -+ prAgpsInfo = &prAgpsApList->arApInfo[0]; -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ if (prBssDesc->rUpdateTime < prScanInfo->rLastScanCompletedTime) -+ continue; -+ COPY_MAC_ADDR(prAgpsInfo->aucBSSID, prBssDesc->aucBSSID); -+ prAgpsInfo->ePhyType = AGPS_PHY_G; -+ prAgpsInfo->u2Channel = prBssDesc->ucChannelNum; -+ prAgpsInfo->i2ApRssi = RCPI_TO_dBm(prBssDesc->ucRCPI); -+ prAgpsInfo++; -+ ucIndex++; -+ if (ucIndex == 32) -+ break; -+ } -+ prAgpsApList->ucNum = ucIndex; -+ GET_CURRENT_SYSTIME(&prScanInfo->rLastScanCompletedTime); -+ /* DBGLOG(SCN, INFO, ("num of scan list:%d\n", ucIndex)); */ -+ kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_AP_LIST, (PUINT_8) prAgpsApList, sizeof(AGPS_AP_LIST_T)); -+ kalMemFree(prAgpsApList, VIR_MEM_TYPE, sizeof(AGPS_AP_LIST_T)); -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c -new file mode 100644 -index 0000000000000..fac9f94428dd9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c -@@ -0,0 +1,2136 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan_fsm.c#1 -+*/ -+ -+/*! \file "scan_fsm.c" -+ \brief This file defines the state transition function for SCAN FSM. -+ -+ The SCAN FSM is part of SCAN MODULE and responsible for performing basic SCAN -+ behavior as metioned in IEEE 802.11 2007 11.1.3.1 & 11.1.3.2 . -+*/ -+ -+/* -+** Log: scan_fsm.c -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 14 2011 yuche.tsai -+ * [WCXRP00001095] [Volunteer Patch][Driver] Always Scan before enable Hot-Spot. -+ * Fix bug when unregister P2P network.. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search -+ * for more than one SSID in a single scanning request -+ * free mailbox message afte parsing is completed. -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search -+ * for more than one SSID in a single scanning request -+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID support -+ * as well as uProbeDelay in NDIS 6.x driver model -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000604] [MT6620 Wi-Fi][Driver] Surpress Klockwork Warning -+ * surpress klock warning with code path rewritten -+ * -+ * 03 18 2011 cm.chang -+ * [WCXRP00000576] [MT6620 Wi-Fi][Driver][FW] Remove P2P compile option in scan req/cancel command -+ * As CR title -+ * -+ * 02 18 2011 yuche.tsai -+ * [WCXRP00000478] [Volunteer Patch][MT6620][Driver] Probe request frame -+ * during search phase do not contain P2P wildcard SSID. -+ * Take P2P wildcard SSID into consideration. -+ * -+ * 01 27 2011 yuche.tsai -+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. -+ * Fix scan channel extension issue when p2p module is not registered. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix Compile Error when DBG is disabled. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add interface for RLM to trigger OBSS-SCAN. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Fix bug for processing queued scan request. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add a function for returning channel. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Update SCAN FSM for support P2P Device discovery scan. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add option of channel extension while cancelling scan request. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 20 2010 cp.wu -+ * -+ * pass band information for scan in an efficient way by mapping ENUM_BAND_T into UINT_8.. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * due to FW/DRV won't be sync. precisely, some strict assertions should be eased. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * SCN module is now able to handle multiple concurrent scanning requests -+ * -+ * 07 16 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * bugfix for SCN migration -+ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue -+ * 2) before AIS issues scan request, network(BSS) needs to be activated first -+ * 3) only invoke COPY_SSID when using specified SSID for scan -+ * -+ * 07 15 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * driver no longer generates probe request frames -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * pass band with channel number information as scan parameter -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * remove timer in DRV-SCN. -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, -+ * other request will be directly dropped by returning BUSY -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * when returning to SCAN_IDLE state, send a correct message to source FSM. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * comment out RLM APIs by CFG_RLM_MIGRATION. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan_fsm into building. -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine the order of Stop TX Queue and Switch Channel -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Update pause/resume/flush API to new Bitmap API -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 03 18 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Ignore the PROBE_DELAY state if the value of Probe Delay == 0 -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb -+ * -+ * 01 08 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add set RX Filter to receive BCN from different BSSID during SCAN -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Nov 25 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove flag of CFG_TEST_MGMT_FSM -+ * -+ * Nov 20 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Change parameter of scanSendProbeReqFrames() -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update scnFsmSteps() -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix typo -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugScanState[SCAN_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("SCAN_STATE_IDLE"), -+ (PUINT_8) DISP_STRING("SCAN_STATE_SCANNING"), -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+#define CURRENT_PSCN_VERSION 1 -+#define RSSI_MARGIN_DEFAULT 5 -+#define MAX_PERIOD 200000 -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_SCAN_STATE_T eNextState) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ P_MSG_HDR_T prMsgHdr; -+ -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ do { -+ -+#if DBG -+ DBGLOG(SCN, STATE, "TRANSITION: [%s] -> [%s]\n", -+ apucDebugScanState[prScanInfo->eCurrentState], apucDebugScanState[eNextState]); -+#else -+ DBGLOG(SCN, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", -+ DBG_SCN_IDX, prScanInfo->eCurrentState, eNextState); -+#endif -+ -+ /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */ -+ prScanInfo->eCurrentState = eNextState; -+ -+ fgIsTransition = (BOOLEAN) FALSE; -+ -+ switch (prScanInfo->eCurrentState) { -+ case SCAN_STATE_IDLE: -+ /* check for pending scanning requests */ -+ if (!LINK_IS_EMPTY(&(prScanInfo->rPendingMsgList))) { -+ /* load next message from pending list as scan parameters */ -+ LINK_REMOVE_HEAD(&(prScanInfo->rPendingMsgList), prMsgHdr, P_MSG_HDR_T); -+ -+ if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ -+ || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ -+ || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ -+ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { -+ scnFsmHandleScanMsg(prAdapter, (P_MSG_SCN_SCAN_REQ) prMsgHdr); -+ } else { -+ scnFsmHandleScanMsgV2(prAdapter, (P_MSG_SCN_SCAN_REQ_V2) prMsgHdr); -+ } -+ -+ /* switch to next state */ -+ eNextState = SCAN_STATE_SCANNING; -+ fgIsTransition = TRUE; -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ } -+ break; -+ -+ case SCAN_STATE_SCANNING: -+ if (prScanParam->fgIsScanV2 == FALSE) -+ scnSendScanReq(prAdapter); -+ else -+ scnSendScanReqV2(prAdapter); -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ -+ } -+ } while (fgIsTransition); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Generate CMD_ID_SCAN_REQ command -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnSendScanReqExtCh(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ /*CMD_SCAN_REQ_EXT_CH rCmdScanReq;*/ -+ P_CMD_SCAN_REQ_EXT_CH prCmdScanReq; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_EXT_CH), VIR_MEM_TYPE); -+ if (prCmdScanReq == NULL) -+ return; -+ -+ /* send command packet for scan */ -+ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_EXT_CH)); -+ -+ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; -+ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; -+ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; -+ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; -+ -+ if (prScanParam->ucSSIDNum == 1) { -+ COPY_SSID(prCmdScanReq->aucSSID, -+ prCmdScanReq->ucSSIDLength, -+ prScanParam->aucSpecifiedSSID[0], prScanParam->ucSpecifiedSSIDLen[0]); -+ } -+ -+ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; -+ -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ /* P2P would use: -+ * 1. Specified Listen Channel of passive scan for LISTEN state. -+ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. (Target != NULL) -+ */ -+ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; -+ -+ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { -+ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; -+ -+ prCmdScanReq->arChannelList[i].ucChannelNum = -+ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; -+#endif -+ -+ if (prScanParam->u2IELen <= MAX_IE_LENGTH) -+ prCmdScanReq->u2IELen = prScanParam->u2IELen; -+ else -+ prCmdScanReq->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_REQ, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ OFFSET_OF(CMD_SCAN_REQ_EXT_CH, aucIE) + prCmdScanReq->u2IELen, -+ (PUINT_8) prCmdScanReq, NULL, 0); -+ /* sanity check for some scan parameters */ -+ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) -+ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); -+ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) -+ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); -+ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && -+ prCmdScanReq->ucChannelListNum != 0) -+ kalSendAeeWarning("wlan", -+ "channel list is not NULL but channel type is not specified"); -+ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) -+ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); -+ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ -+ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); -+ else if (prCmdScanReq->ucSSIDLength > 32) -+ kalSendAeeWarning("wlan", "wrong ssid length %d", prCmdScanReq->ucSSIDLength); -+ -+ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_EXT_CH)); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Generate CMD_ID_SCAN_REQ command -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnSendScanReq(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ /*CMD_SCAN_REQ rCmdScanReq;*/ -+ P_CMD_SCAN_REQ prCmdScanReq; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ if (prScanParam->ucChannelListNum > 32) { -+ scnSendScanReqExtCh(prAdapter); -+ } else { -+ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ), VIR_MEM_TYPE); -+ if (prCmdScanReq == NULL) { -+ DBGLOG(SCN, INFO, "alloc CmdScanReq fail"); -+ return; -+ } -+ /* send command packet for scan */ -+ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ)); -+ -+ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; -+ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; -+ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; -+ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; -+ -+ if (prScanParam->ucSSIDNum == 1) { -+ COPY_SSID(prCmdScanReq->aucSSID, -+ prCmdScanReq->ucSSIDLength, -+ prScanParam->aucSpecifiedSSID[0], prScanParam->ucSpecifiedSSIDLen[0]); -+ } -+ -+ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; -+ -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ /* P2P would use: -+ * 1. Specified Listen Channel of passive scan for LISTEN state. -+ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. -+ * (Target != NULL) -+ */ -+ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; -+ -+ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { -+ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; -+ -+ prCmdScanReq->arChannelList[i].ucChannelNum = -+ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; -+#endif -+#if CFG_ENABLE_FAST_SCAN -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) -+ prCmdScanReq->u2ChannelDwellTime = CFG_FAST_SCAN_DWELL_TIME; -+#endif -+ if (prScanParam->u2IELen <= MAX_IE_LENGTH) -+ prCmdScanReq->u2IELen = prScanParam->u2IELen; -+ else -+ prCmdScanReq->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_REQ, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ OFFSET_OF(CMD_SCAN_REQ, aucIE) + prCmdScanReq->u2IELen, -+ (PUINT_8) prCmdScanReq, NULL, 0); -+ /* sanity check for some scan parameters */ -+ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) -+ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); -+ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) -+ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); -+ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && -+ prCmdScanReq->ucChannelListNum != 0) -+ kalSendAeeWarning("wlan", -+ "channel list is not NULL but channel type is not specified"); -+ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) -+ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); -+ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ -+ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); -+ else if (prCmdScanReq->ucSSIDLength > 32) -+ kalSendAeeWarning("wlan", "wrong ssid length %d", prCmdScanReq->ucSSIDLength); -+ -+ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ)); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Generate CMD_ID_SCAN_REQ_V2 command -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnSendScanReqV2ExtCh(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ /*CMD_SCAN_REQ_V2_EXT_CH rCmdScanReq;*/ -+ P_CMD_SCAN_REQ_V2_EXT_CH prCmdScanReq; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_V2_EXT_CH), VIR_MEM_TYPE); -+ if (prCmdScanReq == NULL) -+ return; -+ -+ /* send command packet for scan */ -+ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_V2_EXT_CH)); -+ -+ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; -+ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; -+ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; -+ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; -+ -+ for (i = 0; i < prScanParam->ucSSIDNum; i++) { -+ COPY_SSID(prCmdScanReq->arSSID[i].aucSsid, -+ prCmdScanReq->arSSID[i].u4SsidLen, -+ prScanParam->aucSpecifiedSSID[i], prScanParam->ucSpecifiedSSIDLen[i]); -+ } -+ -+ prCmdScanReq->u2ProbeDelayTime = (UINT_8) prScanParam->u2ProbeDelayTime; -+ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; -+ -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ /* P2P would use: -+ * 1. Specified Listen Channel of passive scan for LISTEN state. -+ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. (Target != NULL) -+ */ -+ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; -+ -+ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { -+ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; -+ -+ prCmdScanReq->arChannelList[i].ucChannelNum = -+ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; -+#endif -+ -+ if (prScanParam->u2IELen <= MAX_IE_LENGTH) -+ prCmdScanReq->u2IELen = prScanParam->u2IELen; -+ else -+ prCmdScanReq->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_REQ_V2, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ OFFSET_OF(CMD_SCAN_REQ_V2_EXT_CH, aucIE) + prCmdScanReq->u2IELen, -+ (PUINT_8) prCmdScanReq, NULL, 0); -+ /* sanity check for some scan parameters */ -+ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) -+ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); -+ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) -+ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); -+ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && -+ prCmdScanReq->ucChannelListNum != 0) -+ kalSendAeeWarning("wlan", -+ "channel list is not NULL but channel type is not specified"); -+ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) -+ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); -+ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ -+ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); -+ -+ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_V2_EXT_CH)); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Generate CMD_ID_SCAN_REQ_V2 command -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnSendScanReqV2(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ /*CMD_SCAN_REQ_V2 rCmdScanReq;*/ -+ P_CMD_SCAN_REQ_V2 prCmdScanReq; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ if (prScanParam->ucChannelListNum > 32) { -+ scnSendScanReqV2ExtCh(prAdapter); -+ } else { -+ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_V2), VIR_MEM_TYPE); -+ if (prCmdScanReq == NULL) { -+ DBGLOG(SCN, INFO, "alloc CmdScanReq v2 fail"); -+ return; -+ } -+ /* send command packet for scan */ -+ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_V2)); -+ -+ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; -+ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; -+ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; -+ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; -+ -+ for (i = 0; i < prScanParam->ucSSIDNum; i++) { -+ COPY_SSID(prCmdScanReq->arSSID[i].aucSsid, -+ prCmdScanReq->arSSID[i].u4SsidLen, -+ prScanParam->aucSpecifiedSSID[i], prScanParam->ucSpecifiedSSIDLen[i]); -+ } -+ -+ prCmdScanReq->u2ProbeDelayTime = (UINT_8) prScanParam->u2ProbeDelayTime; -+ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; -+ -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ /* P2P would use: -+ * 1. Specified Listen Channel of passive scan for LISTEN state. -+ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. -+ * (Target != NULL) -+ */ -+ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; -+ -+ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { -+ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; -+ -+ prCmdScanReq->arChannelList[i].ucChannelNum = -+ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; -+#endif -+ if (prScanParam->u2IELen <= MAX_IE_LENGTH) -+ prCmdScanReq->u2IELen = prScanParam->u2IELen; -+ else -+ prCmdScanReq->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_REQ_V2, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ OFFSET_OF(CMD_SCAN_REQ_V2, aucIE) + prCmdScanReq->u2IELen, -+ (PUINT_8) prCmdScanReq, NULL, 0); -+ /* sanity check for some scan parameters */ -+ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) -+ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); -+ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) -+ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); -+ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && -+ prCmdScanReq->ucChannelListNum != 0) -+ kalSendAeeWarning("wlan", -+ "channel list is not NULL but channel type is not specified"); -+ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) -+ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); -+ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ -+ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); -+ -+ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_V2)); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmMsgStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ -+ ASSERT(prMsgHdr); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ if (prScanInfo->eCurrentState == SCAN_STATE_IDLE) { -+ if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ -+ || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ -+ || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { -+ scnFsmHandleScanMsg(prAdapter, (P_MSG_SCN_SCAN_REQ) prMsgHdr); -+ } else if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2 -+ || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2 -+ || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2 -+ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) { -+ scnFsmHandleScanMsgV2(prAdapter, (P_MSG_SCN_SCAN_REQ_V2) prMsgHdr); -+ } else { -+ /* should not deliver to this function */ -+ ASSERT(0); -+ } -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ scnFsmSteps(prAdapter, SCAN_STATE_SCANNING); -+ } else { -+ LINK_INSERT_TAIL(&prScanInfo->rPendingMsgList, &prMsgHdr->rLinkEntry); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmMsgAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SCN_SCAN_CANCEL prScanCancel; -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ CMD_SCAN_CANCEL rCmdScanCancel; -+ -+ ASSERT(prMsgHdr); -+ -+ prScanCancel = (P_MSG_SCN_SCAN_CANCEL) prMsgHdr; -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ if (prScanInfo->eCurrentState != SCAN_STATE_IDLE) { -+ if (prScanCancel->ucSeqNum == prScanParam->ucSeqNum && -+ prScanCancel->ucNetTypeIndex == (UINT_8) prScanParam->eNetTypeIndex) { -+ /* send cancel message to firmware domain */ -+ rCmdScanCancel.ucSeqNum = prScanParam->ucSeqNum; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ rCmdScanCancel.ucIsExtChannel = (UINT_8) prScanCancel->fgIsChannelExt; -+ else -+ rCmdScanCancel.ucIsExtChannel = (UINT_8) FALSE; -+#endif -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_CANCEL, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_SCAN_CANCEL), (PUINT_8) &rCmdScanCancel, NULL, 0); -+ -+ /* generate scan-done event for caller */ -+ scnFsmGenerateScanDoneMsg(prAdapter, -+ prScanParam->ucSeqNum, -+ (UINT_8) prScanParam->eNetTypeIndex, SCAN_STATUS_CANCELLED); -+ -+ /* switch to next pending scan */ -+ scnFsmSteps(prAdapter, SCAN_STATE_IDLE); -+ } else { -+ scnFsmRemovePendingMsg(prAdapter, prScanCancel->ucSeqNum, prScanCancel->ucNetTypeIndex); -+ } -+ } -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Scan Message Parsing (Legacy) -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmHandleScanMsg(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ prScanReqMsg) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ ASSERT(prScanReqMsg); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ prScanParam->eScanType = prScanReqMsg->eScanType; -+ prScanParam->eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) prScanReqMsg->ucNetTypeIndex; -+ prScanParam->ucSSIDType = prScanReqMsg->ucSSIDType; -+ if (prScanParam->ucSSIDType & (SCAN_REQ_SSID_SPECIFIED | SCAN_REQ_SSID_P2P_WILDCARD)) { -+ prScanParam->ucSSIDNum = 1; -+ -+ COPY_SSID(prScanParam->aucSpecifiedSSID[0], -+ prScanParam->ucSpecifiedSSIDLen[0], prScanReqMsg->aucSSID, prScanReqMsg->ucSSIDLength); -+ -+ /* reset SSID length to zero for rest array entries */ -+ for (i = 1; i < SCN_SSID_MAX_NUM; i++) -+ prScanParam->ucSpecifiedSSIDLen[i] = 0; -+ } else { -+ prScanParam->ucSSIDNum = 0; -+ -+ for (i = 0; i < SCN_SSID_MAX_NUM; i++) -+ prScanParam->ucSpecifiedSSIDLen[i] = 0; -+ } -+ -+ prScanParam->u2ProbeDelayTime = 0; -+ prScanParam->eScanChannel = prScanReqMsg->eScanChannel; -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ if (prScanReqMsg->ucChannelListNum <= MAXIMUM_OPERATION_CHANNEL_LIST) -+ prScanParam->ucChannelListNum = prScanReqMsg->ucChannelListNum; -+ else -+ prScanParam->ucChannelListNum = MAXIMUM_OPERATION_CHANNEL_LIST; -+ -+ kalMemCopy(prScanParam->arChnlInfoList, -+ prScanReqMsg->arChnlInfoList, sizeof(RF_CHANNEL_INFO_T) * prScanParam->ucChannelListNum); -+ } -+ -+ if (prScanReqMsg->u2IELen <= MAX_IE_LENGTH) -+ prScanParam->u2IELen = prScanReqMsg->u2IELen; -+ else -+ prScanParam->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prScanParam->aucIE, prScanReqMsg->aucIE, prScanParam->u2IELen); -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prScanParam->u2PassiveListenInterval = prScanReqMsg->u2ChannelDwellTime; -+#endif -+ prScanParam->ucSeqNum = prScanReqMsg->ucSeqNum; -+ -+ if (prScanReqMsg->rMsgHdr.eMsgId == MID_RLM_SCN_SCAN_REQ) -+ prScanParam->fgIsObssScan = TRUE; -+ else -+ prScanParam->fgIsObssScan = FALSE; -+ -+ prScanParam->fgIsScanV2 = FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Scan Message Parsing - V2 with multiple SSID support -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmHandleScanMsgV2(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ_V2 prScanReqMsg) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ ASSERT(prScanReqMsg); -+ ASSERT(prScanReqMsg->ucSSIDNum <= SCN_SSID_MAX_NUM); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ prScanParam->eScanType = prScanReqMsg->eScanType; -+ prScanParam->eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) prScanReqMsg->ucNetTypeIndex; -+ prScanParam->ucSSIDType = prScanReqMsg->ucSSIDType; -+ prScanParam->ucSSIDNum = prScanReqMsg->ucSSIDNum; -+ -+ for (i = 0; i < prScanReqMsg->ucSSIDNum; i++) { -+ COPY_SSID(prScanParam->aucSpecifiedSSID[i], -+ prScanParam->ucSpecifiedSSIDLen[i], -+ prScanReqMsg->prSsid[i].aucSsid, (UINT_8) prScanReqMsg->prSsid[i].u4SsidLen); -+ } -+ -+ prScanParam->u2ProbeDelayTime = prScanReqMsg->u2ProbeDelay; -+ prScanParam->eScanChannel = prScanReqMsg->eScanChannel; -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ if (prScanReqMsg->ucChannelListNum <= MAXIMUM_OPERATION_CHANNEL_LIST) -+ prScanParam->ucChannelListNum = prScanReqMsg->ucChannelListNum; -+ else -+ prScanParam->ucChannelListNum = MAXIMUM_OPERATION_CHANNEL_LIST; -+ -+ kalMemCopy(prScanParam->arChnlInfoList, -+ prScanReqMsg->arChnlInfoList, sizeof(RF_CHANNEL_INFO_T) * prScanParam->ucChannelListNum); -+ } -+ -+ if (prScanReqMsg->u2IELen <= MAX_IE_LENGTH) -+ prScanParam->u2IELen = prScanReqMsg->u2IELen; -+ else -+ prScanParam->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prScanParam->aucIE, prScanReqMsg->aucIE, prScanParam->u2IELen); -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prScanParam->u2PassiveListenInterval = prScanReqMsg->u2ChannelDwellTime; -+#endif -+ prScanParam->ucSeqNum = prScanReqMsg->ucSeqNum; -+ -+ if (prScanReqMsg->rMsgHdr.eMsgId == MID_RLM_SCN_SCAN_REQ) -+ prScanParam->fgIsObssScan = TRUE; -+ else -+ prScanParam->fgIsObssScan = FALSE; -+ -+ prScanParam->fgIsScanV2 = TRUE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Remove pending scan request -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmRemovePendingMsg(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ P_MSG_HDR_T prPendingMsgHdr, prPendingMsgHdrNext, prRemoveMsgHdr = NULL; -+ P_LINK_ENTRY_T prRemoveLinkEntry = NULL; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ /* traverse through rPendingMsgList for removal */ -+ LINK_FOR_EACH_ENTRY_SAFE(prPendingMsgHdr, -+ prPendingMsgHdrNext, &(prScanInfo->rPendingMsgList), rLinkEntry, MSG_HDR_T) { -+ if (prPendingMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ -+ || prPendingMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ -+ || prPendingMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ -+ || prPendingMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { -+ P_MSG_SCN_SCAN_REQ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) prPendingMsgHdr; -+ -+ if (ucSeqNum == prScanReqMsg->ucSeqNum && ucNetTypeIndex == prScanReqMsg->ucNetTypeIndex) { -+ prRemoveLinkEntry = &(prScanReqMsg->rMsgHdr.rLinkEntry); -+ prRemoveMsgHdr = prPendingMsgHdr; -+ } -+ } else if (prPendingMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2 -+ || prPendingMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2 -+ || prPendingMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2 -+ || prPendingMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) { -+ P_MSG_SCN_SCAN_REQ_V2 prScanReqMsgV2 = (P_MSG_SCN_SCAN_REQ_V2) prPendingMsgHdr; -+ -+ if (ucSeqNum == prScanReqMsgV2->ucSeqNum && ucNetTypeIndex == prScanReqMsgV2->ucNetTypeIndex) { -+ prRemoveLinkEntry = &(prScanReqMsgV2->rMsgHdr.rLinkEntry); -+ prRemoveMsgHdr = prPendingMsgHdr; -+ } -+ } -+ -+ if (prRemoveLinkEntry) { -+ /* generate scan-done event for caller */ -+ scnFsmGenerateScanDoneMsg(prAdapter, ucSeqNum, ucNetTypeIndex, SCAN_STATUS_CANCELLED); -+ -+ /* remove from pending list */ -+ LINK_REMOVE_KNOWN_ENTRY(&(prScanInfo->rPendingMsgList), prRemoveLinkEntry); -+ cnmMemFree(prAdapter, prRemoveMsgHdr); -+ -+ break; -+ } -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnEventScanDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_SCAN_DONE prScanDone) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ /* buffer empty channel information */ -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_FULL || prScanParam->eScanChannel == SCAN_CHANNEL_2G4) { -+ if (prScanDone->ucSparseChannelValid) { -+ prScanInfo->fgIsSparseChannelValid = TRUE; -+ prScanInfo->rSparseChannel.eBand = (ENUM_BAND_T) prScanDone->rSparseChannel.ucBand; -+ prScanInfo->rSparseChannel.ucChannelNum = prScanDone->rSparseChannel.ucChannelNum; -+ } else { -+ prScanInfo->fgIsSparseChannelValid = FALSE; -+ } -+ } -+ -+ if (prScanInfo->eCurrentState == SCAN_STATE_SCANNING && prScanDone->ucSeqNum == prScanParam->ucSeqNum) { -+ /* generate scan-done event for caller */ -+ scnFsmGenerateScanDoneMsg(prAdapter, -+ prScanParam->ucSeqNum, (UINT_8) prScanParam->eNetTypeIndex, SCAN_STATUS_DONE); -+ -+ /* switch to next pending scan */ -+ scnFsmSteps(prAdapter, SCAN_STATE_IDLE); -+ } else { -+ DBGLOG(SCN, WARN, "Unexpected SCAN-DONE event: SeqNum = %d, Current State = %d\n", -+ prScanDone->ucSeqNum, prScanInfo->eCurrentState); -+ } -+ -+} /* end of scnEventScanDone */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+scnFsmGenerateScanDoneMsg(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex, IN ENUM_SCAN_STATUS eScanStatus) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ P_MSG_SCN_SCAN_DONE prScanDoneMsg; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ DBGLOG(SCN, INFO, "Rcv Scan Done, NetIdx %d, Obss %d, Status %d, Seq %d\n", -+ ucNetTypeIndex, prScanParam->fgIsObssScan, eScanStatus, ucSeqNum); -+ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_DONE)); -+ if (!prScanDoneMsg) { -+ ASSERT(0); /* Can't indicate SCAN FSM Complete */ -+ return; -+ } -+ -+ if (prScanParam->fgIsObssScan == TRUE) { -+ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_RLM_SCAN_DONE; -+ } else { -+ switch ((ENUM_NETWORK_TYPE_INDEX_T) ucNetTypeIndex) { -+ case NETWORK_TYPE_AIS_INDEX: -+ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_AIS_SCAN_DONE; -+ break; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ case NETWORK_TYPE_P2P_INDEX: -+ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_P2P_SCAN_DONE; -+ break; -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ case NETWORK_TYPE_BOW_INDEX: -+ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_BOW_SCAN_DONE; -+ break; -+#endif -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+ } -+ -+ prScanDoneMsg->ucSeqNum = ucSeqNum; -+ prScanDoneMsg->ucNetTypeIndex = ucNetTypeIndex; -+ prScanDoneMsg->eScanStatus = eScanStatus; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanDoneMsg, MSG_SEND_METHOD_BUF); -+ -+} /* end of scnFsmGenerateScanDoneMsg() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Query for most sparse channel -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnQuerySparseChannel(IN P_ADAPTER_T prAdapter, P_ENUM_BAND_T prSparseBand, PUINT_8 pucSparseChannel) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ if (prScanInfo->fgIsSparseChannelValid == TRUE) { -+ if (prSparseBand) -+ *prSparseBand = prScanInfo->rSparseChannel.eBand; -+ -+ if (pucSparseChannel) -+ *pucSparseChannel = prScanInfo->rSparseChannel.ucChannelNum; -+ -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Event handler for NLO done event -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnEventNloDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_NLO_DONE_T prNloDone) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_NLO_PARAM_T prNloParam; -+ P_SCAN_PARAM_T prScanParam; -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prNloParam = &prScanInfo->rNloParam; -+ prScanParam = &prNloParam->rScanParam; -+ -+ if (prScanInfo->fgNloScanning == TRUE) { -+ DBGLOG(SCN, INFO, "scnEventNloDone Current State = %d\n", prScanInfo->eCurrentState); -+ -+ kalSchedScanResults(prAdapter->prGlueInfo); -+ -+ if (prNloParam->fgStopAfterIndication == TRUE) -+ prScanInfo->fgNloScanning = FALSE; -+ -+ kalMemZero(&prNloParam->aprPendingBssDescToInd[0], -+ CFG_SCAN_SSID_MATCH_MAX_NUM * sizeof(P_BSS_DESC_T)); -+ } else { -+ DBGLOG(SCN, INFO, "Unexpected NLO-DONE event\n"); -+ } -+ -+} -+ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for starting scheduled scan -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+scnFsmSchedScanRequest(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucSsidNum, -+ IN P_PARAM_SSID_T prSsid, IN UINT_32 u4IeLength, IN PUINT_8 pucIe, IN UINT_16 u2Interval) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_NLO_PARAM_T prNloParam; -+ P_SCAN_PARAM_T prScanParam; -+ P_CMD_NLO_REQ prCmdNloReq; -+ UINT_32 i, j; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prNloParam = &prScanInfo->rNloParam; -+ prScanParam = &prNloParam->rScanParam; -+ -+ if (prScanInfo->fgNloScanning) { -+ DBGLOG(SCN, INFO, "prScanInfo->fgNloScanning == TRUE already scanning\n"); -+ return TRUE; -+ } -+ -+ prScanInfo->fgNloScanning = TRUE; -+ -+ /* 1. load parameters */ -+ prScanParam->ucSeqNum++; -+ /* prScanParam->ucBssIndex = prAdapter->prAisBssInfo->ucBssIndex; */ -+ -+ prNloParam->fgStopAfterIndication = TRUE; -+ prNloParam->ucFastScanIteration = 0; -+ prNloParam->u2FastScanPeriod = u2Interval; -+ prNloParam->u2SlowScanPeriod = u2Interval; -+ -+ if (prScanParam->ucSSIDNum > CFG_SCAN_SSID_MAX_NUM) -+ prScanParam->ucSSIDNum = CFG_SCAN_SSID_MAX_NUM; -+ else -+ prScanParam->ucSSIDNum = ucSsidNum; -+ -+ if (prNloParam->ucMatchSSIDNum > CFG_SCAN_SSID_MATCH_MAX_NUM) -+ prNloParam->ucMatchSSIDNum = CFG_SCAN_SSID_MATCH_MAX_NUM; -+ else -+ prNloParam->ucMatchSSIDNum = ucSsidNum; -+ -+ for (i = 0; i < prNloParam->ucMatchSSIDNum; i++) { -+ if (i < CFG_SCAN_SSID_MAX_NUM) { -+ COPY_SSID(prScanParam->aucSpecifiedSSID[i], -+ prScanParam->ucSpecifiedSSIDLen[i], prSsid[i].aucSsid, (UINT_8) prSsid[i].u4SsidLen); -+ } -+ -+ COPY_SSID(prNloParam->aucMatchSSID[i], -+ prNloParam->ucMatchSSIDLen[i], prSsid[i].aucSsid, (UINT_8) prSsid[i].u4SsidLen); -+ -+ prNloParam->aucCipherAlgo[i] = 0; -+ prNloParam->au2AuthAlgo[i] = 0; -+ -+ for (j = 0; j < SCN_NLO_NETWORK_CHANNEL_NUM; j++) -+ prNloParam->aucChannelHint[i][j] = 0; -+ } -+ -+ /* 2. prepare command for sending */ -+ prCmdNloReq = (P_CMD_NLO_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_NLO_REQ) + prScanParam->u2IELen); -+ -+ if (!prCmdNloReq) { -+ ASSERT(0); /* Can't initiate NLO operation */ -+ return FALSE; -+ } -+ -+ /* 3. send command packet for NLO operation */ -+ kalMemZero(prCmdNloReq, sizeof(CMD_NLO_REQ)); -+ -+ prCmdNloReq->ucSeqNum = prScanParam->ucSeqNum; -+ /* prCmdNloReq->ucBssIndex = prScanParam->ucBssIndex; */ -+ -+ prCmdNloReq->ucNetworkType = prScanParam->eNetTypeIndex; -+ prCmdNloReq->ucScanType = (UINT_8) prScanParam->eScanType; -+ -+ prCmdNloReq->fgStopAfterIndication = prNloParam->fgStopAfterIndication; -+ prCmdNloReq->ucFastScanIteration = prNloParam->ucFastScanIteration; -+ prCmdNloReq->u2FastScanPeriod = prNloParam->u2FastScanPeriod; -+ prCmdNloReq->u2SlowScanPeriod = prNloParam->u2SlowScanPeriod; -+ prCmdNloReq->ucEntryNum = prNloParam->ucMatchSSIDNum; -+ for (i = 0; i < prNloParam->ucMatchSSIDNum; i++) { -+ COPY_SSID(prCmdNloReq->arNetworkList[i].aucSSID, -+ prCmdNloReq->arNetworkList[i].ucSSIDLength, -+ prNloParam->aucMatchSSID[i], prNloParam->ucMatchSSIDLen[i]); -+ -+ prCmdNloReq->arNetworkList[i].ucCipherAlgo = prNloParam->aucCipherAlgo[i]; -+ prCmdNloReq->arNetworkList[i].u2AuthAlgo = prNloParam->au2AuthAlgo[i]; -+ -+ for (j = 0; j < SCN_NLO_NETWORK_CHANNEL_NUM; j++) -+ prCmdNloReq->arNetworkList[i].ucNumChannelHint[j] = prNloParam->aucChannelHint[i][j]; -+ } -+ -+ if (prScanParam->u2IELen <= MAX_IE_LENGTH) -+ prCmdNloReq->u2IELen = prScanParam->u2IELen; -+ else -+ prCmdNloReq->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prCmdNloReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdNloReq->u2IELen); -+#if !CFG_SUPPORT_GSCN -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_NLO_REQ, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_NLO_REQ) + prCmdNloReq->u2IELen, (PUINT_8) prCmdNloReq, NULL, 0); -+ -+#else -+ scnPSCNFsm(prAdapter, PSCN_RESET, prCmdNloReq, NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE); -+#endif -+ cnmMemFree(prAdapter, (PVOID) prCmdNloReq); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for stopping scheduled scan -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmSchedScanStopRequest(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_NLO_PARAM_T prNloParam; -+ P_SCAN_PARAM_T prScanParam; -+ CMD_NLO_CANCEL rCmdNloCancel; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prNloParam = &prScanInfo->rNloParam; -+ prScanParam = &prNloParam->rScanParam; -+ -+ /* send cancel message to firmware domain */ -+ rCmdNloCancel.ucSeqNum = prScanParam->ucSeqNum; -+ -+#if !CFG_SUPPORT_GSCN -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_NLO_CANCEL, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetStopSchedScan, -+ nicOidCmdTimeoutCommon, sizeof(CMD_NLO_CANCEL), (PUINT_8)(&rCmdNloCancel), NULL, 0); -+#else -+ -+ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, NULL, TRUE, FALSE, FALSE, FALSE); -+#endif -+ -+ prScanInfo->fgNloScanning = FALSE; -+ -+ return TRUE; -+} -+ -+#if CFG_SUPPORT_GSCN -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set PSCN action -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmPSCNAction(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPscanAct) -+{ -+ CMD_SET_PSCAN_ENABLE rCmdPscnAction; -+ P_SCAN_INFO_T prScanInfo; -+ -+ DBGLOG(SCN, TRACE, "scnFsmPSCNAction Act = %d\n", ucPscanAct); -+ -+ rCmdPscnAction.ucPscanAct = ucPscanAct; -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ if (ucPscanAct == DISABLE) -+ prScanInfo->fgPscnOnnning = FALSE; -+ if (ucPscanAct == ENABLE) -+ prScanInfo->fgPscnOnnning = TRUE; -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PSCN_ENABLE, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SET_PSCAN_ENABLE), (PUINT_8) &rCmdPscnAction, NULL, 0); -+ -+ DBGLOG(SCN, INFO, "scnFsmPSCNAction Act = %d is Set to FW\n", ucPscanAct); -+ return TRUE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set PSCN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmPSCNSetParam(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) -+{ -+ UINT_8 i, j; -+ -+ i = 0; -+ j = 0; -+ -+ ASSERT(prAdapter); -+ /*prCmdPscnParam->u4BasePeriod = prCmdPscnParam->u4BasePeriod;*/ -+#if 0 -+ DBGLOG(SCN, TRACE, -+ "rCmdPscnParam: Period[%u],NumCache[%u],Threshold[%u],NumBkts[%u],fgGSCN[%d] fgNLO[%d] fgBatch[%d]\n", -+ prCmdPscnParam->rCmdGscnReq.u4BasePeriod, prCmdPscnParam->rCmdGscnReq.ucNumScnToCache, -+ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold, prCmdPscnParam->rCmdGscnReq.u4NumBuckets, -+ prCmdPscnParam->fgGScnEnable, prCmdPscnParam->fgNLOScnEnable, prCmdPscnParam->fgBatchScnEnable)); -+ -+ for (i = 0; i < prCmdPscnParam->rCmdGscnReq.u4NumBuckets; i++) { -+ DBGLOG(SCN, TRACE, "rCmdPscnParam.rCmdGscnParam.arChannelBucket[%d] has channel: ", i); -+ DBGLOG(SCN, TRACE, -+ "band[%u], Index[%u] NumChannels[%u], ucBktFreqMultiple[%u] Flag[%u]\n", -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].eBand, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].u2BucketIndex, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucBucketFreqMultiple, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucReportFlag)); -+ for (j = 0; j < prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels; j++) -+ DBGLOG(SCN, TRACE, -+ " %d, ", prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].arChannelList[j].ucChannel); -+ DBGLOG(SCN, TRACE, "\n"); -+ } -+#endif -+ -+ if (1 /*prScanInfo->fgPscnOnnning == FALSE */) { -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PSCAN_PARAM, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SET_PSCAN_PARAM), (PUINT_8) prCmdPscnParam, NULL, 0); -+ -+ DBGLOG(SCN, TRACE, "CMD_ID_SET_PSCAN_PARAM is set to FW !!!!!!!!!!\n"); -+ return TRUE; -+ } -+ return FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set hotlist -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmPSCNSetHotlist(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_HOTLIST_BSSID prCmdPscnAddHotlist) -+{ -+ CMD_SET_PSCAN_ADD_HOTLIST_BSSID rCmdPscnAddHotlist; -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ memcpy(&rCmdPscnAddHotlist.aucMacAddr, &(prCmdPscnAddHotlist->aucMacAddr), sizeof(MAC_ADDR_LEN)); -+ -+ /* rCmdPscnAddHotlist.aucMacAddr = prCmdPscnAddHotlist->aucMacAddr; */ -+ rCmdPscnAddHotlist.ucFlags = prCmdPscnAddHotlist->ucFlags; -+ -+ if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) { -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PSCN_ADD_HOTLIST_BSSID, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_SET_PSCAN_ADD_HOTLIST_BSSID), (PUINT_8) &rCmdPscnAddHotlist, NULL, 0); -+ return TRUE; -+ } -+ /* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */ -+ return FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set CMD_ID_SET_PSCN_ADD_SW_BSSID -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmPSCNAddSWCBssId(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_SWC_BSSID prCmdPscnAddSWCBssId) -+{ -+ CMD_SET_PSCAN_ADD_SWC_BSSID rCmdPscnAddSWCBssId; -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ memcpy(&rCmdPscnAddSWCBssId.aucMacAddr, &(prCmdPscnAddSWCBssId->aucMacAddr), sizeof(MAC_ADDR_LEN)); -+ -+ /* rCmdPscnAddSWCBssId.aucMacAddr = prCmdPscnAddSWCBssId->aucMacAddr; */ -+ rCmdPscnAddSWCBssId.i4RssiHighThreshold = prCmdPscnAddSWCBssId->i4RssiHighThreshold; -+ rCmdPscnAddSWCBssId.i4RssiLowThreshold = prCmdPscnAddSWCBssId->i4RssiLowThreshold; -+ -+ if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) { -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PSCN_ADD_SW_BSSID, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_SET_PSCAN_ADD_SWC_BSSID), (PUINT_8) &rCmdPscnAddSWCBssId, NULL, 0); -+ return TRUE; -+ } -+ /* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */ -+ return FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set CMD_ID_SET_PSCN_MAC_ADDR -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmPSCNSetMacAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_MAC_ADDR prCmdPscnSetMacAddr) -+{ -+ CMD_SET_PSCAN_MAC_ADDR rCmdPscnSetMacAddr; -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ /* rCmdPscnSetMacAddr.aucMacAddr = prCmdPscnSetMacAddr->aucMacAddr; */ -+ memcpy(&rCmdPscnSetMacAddr.aucMacAddr, &(prCmdPscnSetMacAddr->aucMacAddr), sizeof(MAC_ADDR_LEN)); -+ -+ rCmdPscnSetMacAddr.ucFlags = prCmdPscnSetMacAddr->ucFlags; -+ rCmdPscnSetMacAddr.ucVersion = prCmdPscnSetMacAddr->ucVersion; -+ -+ if (1 /* (prScanInfo->fgPscnOnnning == TRUE */) { -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PSCN_MAC_ADDR, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, sizeof(CMD_SET_PSCAN_MAC_ADDR), (PUINT_8) &rCmdPscnSetMacAddr, NULL, 0); -+ return TRUE; -+ } -+ /* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */ -+ return FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set GSCN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam) -+{ -+ /*CMD_GSCN_REQ_T rCmdGscnParam;*/ -+ P_CMD_GSCN_REQ_T rCmdGscnParamp; -+ P_SCAN_INFO_T prScanInfo; -+ UINT_8 ucChannelBuckIndex; -+ UINT_8 i; -+ -+ ASSERT(prAdapter); -+ rCmdGscnParamp = kalMemAlloc(sizeof(CMD_GSCN_REQ_T), VIR_MEM_TYPE); -+ if (rCmdGscnParamp == NULL) { -+ DBGLOG(SCN, INFO, "alloc CmdGscnParam fail\n"); -+ return TRUE; -+ } -+ kalMemZero(rCmdGscnParamp, sizeof(CMD_GSCN_REQ_T)); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ rCmdGscnParamp->u4NumBuckets = prCmdGscnParam->num_buckets; -+ rCmdGscnParamp->u4BasePeriod = prCmdGscnParam->base_period; -+ DBGLOG(SCN, INFO, -+ "u4BasePeriod[%d], u4NumBuckets[%d]\n", rCmdGscnParamp->u4BasePeriod, rCmdGscnParamp->u4NumBuckets); -+ for (ucChannelBuckIndex = 0; ucChannelBuckIndex < prCmdGscnParam->num_buckets; ucChannelBuckIndex++) { -+ DBGLOG(SCN, TRACE, "assign channels to bucket[%d]\n", ucChannelBuckIndex); -+ for (i = 0; i < prCmdGscnParam->buckets[ucChannelBuckIndex].num_channels; i++) { -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucChannel = -+ (UINT_8) nicFreq2ChannelNum(prCmdGscnParam->buckets[ucChannelBuckIndex]. -+ channels[i].channel * 1000); -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucPassive = -+ (UINT_8) prCmdGscnParam->buckets[ucChannelBuckIndex].channels[i].passive; -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].u4DwellTimeMs = -+ (UINT_8) prCmdGscnParam->buckets[ucChannelBuckIndex].channels[i].dwellTimeMs; -+ -+ DBGLOG(SCN, TRACE, "[ucChannel %d, ucPassive %d, u4DwellTimeMs %d\n", -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucChannel, -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucPassive, -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].u4DwellTimeMs); -+ -+ } -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].u2BucketIndex = -+ (UINT_16) prCmdGscnParam->buckets[ucChannelBuckIndex].bucket; -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].eBand = -+ prCmdGscnParam->buckets[ucChannelBuckIndex].band; -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucBucketFreqMultiple = -+ (prCmdGscnParam->buckets[ucChannelBuckIndex].period / prCmdGscnParam->base_period); -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucNumChannels = -+ prCmdGscnParam->buckets[ucChannelBuckIndex].num_channels; -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucReportFlag = -+ prCmdGscnParam->buckets[ucChannelBuckIndex].report_events; -+ -+ /* printk("\n"); */ -+ } -+ -+ DBGLOG(SCN, INFO, "scnSetGSCNParam ---> scnPSCNFsm PSCN_RESET\n"); -+ -+ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, rCmdGscnParamp, NULL, FALSE, FALSE, FALSE, FALSE); -+ kalMemFree(rCmdGscnParamp, VIR_MEM_TYPE, sizeof(CMD_GSCN_REQ_T)); -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Combine PNO Scan params into PSCAN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID -+scnSubCombineNLOtoPSCN(IN P_ADAPTER_T prAdapter, -+ IN P_CMD_NLO_REQ prNewCmdNloReq, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ if (prNewCmdNloReq) { -+ prCmdPscnParam->fgNLOScnEnable = TRUE; -+ memcpy(&prCmdPscnParam->rCmdNloReq, prNewCmdNloReq, sizeof(CMD_NLO_REQ)); -+ } else if (prScanInfo->prPscnParam->fgNLOScnEnable) { -+ memcpy(&prCmdPscnParam->rCmdNloReq, &prScanInfo->prPscnParam->rCurrentCmdNloReq, sizeof(CMD_NLO_REQ)); -+ } else -+ prCmdPscnParam->fgNLOScnEnable = FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Combine Batcht Scan params into PSCAN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID -+scnSubCombineBatchSCNtoPSCN(IN P_ADAPTER_T prAdapter, -+ IN P_CMD_BATCH_REQ_T prNewCmdBatchReq, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ if (prNewCmdBatchReq) { -+ prCmdPscnParam->fgBatchScnEnable = TRUE; -+ memcpy(&prCmdPscnParam->rCmdBatchReq, prNewCmdBatchReq, sizeof(CMD_BATCH_REQ_T)); -+ } else if (prScanInfo->prPscnParam->fgBatchScnEnable) { -+ memcpy(&prCmdPscnParam->rCmdBatchReq, &prScanInfo->prPscnParam->rCurrentCmdBatchReq, -+ sizeof(CMD_BATCH_REQ_T)); -+ } else -+ prCmdPscnParam->fgBatchScnEnable = FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Combine GSCN Scan params into PSCAN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID -+scnSubCombineGSCNtoPSCN(IN P_ADAPTER_T prAdapter, -+ IN P_CMD_GSCN_REQ_T prNewCmdGscnReq, -+ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ UINT_32 ucPeriodMin = MAX_PERIOD; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prCmdPscnParam->fgGScnEnable = FALSE; -+ -+ DBGLOG(SCN, TRACE, "scnSubCombineGSCNtoPSCN fgGScnParamSet %d fgGScnConfigSet %d\n", -+ prScanInfo->fgGScnParamSet, prScanInfo->fgGScnConfigSet); -+ -+ if (prNewCmdGscnReq) { -+ DBGLOG(SCN, INFO, "setup prNewCmdGscnReq\n"); -+ prScanInfo->fgGScnParamSet = TRUE; -+ memcpy(&prCmdPscnParam->rCmdGscnReq, prNewCmdGscnReq, sizeof(CMD_GSCN_REQ_T)); -+ if (ucPeriodMin > prNewCmdGscnReq->u4BasePeriod) -+ prCmdPscnParam->u4BasePeriod = prNewCmdGscnReq->u4BasePeriod; -+ } else if (prScanInfo->fgGScnParamSet) { -+ DBGLOG(SCN, INFO, "no new prNewCmdGscnReq but there is a old one\n"); -+ memcpy(&prCmdPscnParam->rCmdGscnReq, &prScanInfo->prPscnParam->rCurrentCmdGscnReq, -+ sizeof(CMD_GSCN_REQ_T)); -+ prCmdPscnParam->u4BasePeriod = prScanInfo->prPscnParam->u4BasePeriod; -+ } else -+ prScanInfo->fgGScnParamSet = FALSE; -+ -+ if (prNewCmdGscnConfig) { -+ DBGLOG(SCN, INFO, "set up prNewCmdGscnConfig\n"); -+ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ prScanInfo->fgGScnConfigSet = TRUE; -+ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold = prNewCmdGscnConfig->u4BufferThreshold; -+ prCmdPscnParam->rCmdGscnReq.ucNumScnToCache = (UINT_8) prNewCmdGscnConfig->u4NumScnToCache; -+ } else if (prScanInfo->fgGScnConfigSet) { -+ DBGLOG(SCN, INFO, "no new prNewCmdGscnConfig but there is a old one\n"); -+ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold = -+ prScanInfo->prPscnParam->rCurrentCmdGscnReq.u4BufferThreshold; -+ prCmdPscnParam->rCmdGscnReq.ucNumScnToCache = -+ (UINT_8) prScanInfo->prPscnParam->rCurrentCmdGscnReq.ucNumScnToCache; -+ } else -+ prScanInfo->fgGScnConfigSet = FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Combine GSCN Scan params into PSCAN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID -+scnRemoveFromPSCN(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgRemoveNLOfromPSCN, -+ IN BOOLEAN fgRemoveBatchSCNfromPSCN, -+ IN BOOLEAN fgRemoveGSCNfromPSCN, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ UINT_8 ucPscanAct = DISABLE; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ { -+ DBGLOG(SCN, INFO, "remove NLO or Batch or GSCN from PSCN--->NLO=%d, BSN=%d, GSN=%d\n", -+ fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN); -+ -+ if (fgRemoveNLOfromPSCN) { -+ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ prCmdPscnParam->fgNLOScnEnable = FALSE; -+ kalMemZero(&prCmdPscnParam->rCmdNloReq, sizeof(CMD_NLO_REQ)); -+ kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdNloReq, sizeof(CMD_NLO_REQ)); -+ } -+ if (fgRemoveBatchSCNfromPSCN) { -+ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ prCmdPscnParam->fgBatchScnEnable = FALSE; -+ kalMemZero(&prCmdPscnParam->rCmdBatchReq, sizeof(CMD_BATCH_REQ_T)); -+ kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdBatchReq, sizeof(CMD_BATCH_REQ_T)); -+ } -+ if (fgRemoveGSCNfromPSCN) { -+ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ prCmdPscnParam->fgGScnEnable = FALSE; -+ prScanInfo->fgGScnParamSet = FALSE; -+ kalMemZero(&prCmdPscnParam->rCmdGscnReq, sizeof(CMD_GSCN_REQ_T)); -+ kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdGscnReq, sizeof(CMD_GSCN_REQ_T)); -+ } -+ -+ if (!fgRemoveNLOfromPSCN && !fgRemoveBatchSCNfromPSCN && !fgRemoveGSCNfromPSCN) { -+ /* prCmdPscnParam->fgIsPeriodicallyScn = FALSE; */ -+ prScanInfo->fgPscnOnnning = FALSE; -+ scnFsmPSCNSetParam(prAdapter, prCmdPscnParam); -+ scnFsmPSCNAction(prAdapter, ucPscanAct); -+ } else { -+ /* prCmdPscnParam->fgIsPeriodicallyScn = TRUE; */ -+ scnFsmPSCNSetParam(prAdapter, prCmdPscnParam); -+ DBGLOG(SCN, INFO, " disable NLO or GSCN or Batch but fgIsPeriodicallyScn = TRUE <-----\n"); -+ } -+ } -+ -+} -+ -+#if 1 -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Combine GSCN , Batch, PNO Scan params into PSCAN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+BOOLEAN -+scnCombineParamsIntoPSCN(IN P_ADAPTER_T prAdapter, -+ IN P_CMD_NLO_REQ prNewCmdNloReq, -+ IN P_CMD_BATCH_REQ_T prNewCmdBatchReq, -+ IN P_CMD_GSCN_REQ_T prNewCmdGscnReq, -+ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, -+ IN BOOLEAN fgRemoveNLOfromPSCN, -+ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ /* CMD_SET_PSCAN_PARAM rCmdPscnParam; */ -+ P_CMD_SET_PSCAN_PARAM prCmdPscnParam; -+ /* UINT_8 i, j = 0; */ -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prCmdPscnParam = (P_CMD_SET_PSCAN_PARAM) kalMemAlloc(sizeof(CMD_SET_PSCAN_PARAM), VIR_MEM_TYPE); -+ if (!prCmdPscnParam) { -+ DBGLOG(SCN, ERROR, "Can not alloc memory for PARAM_WIFI_GSCAN_CMD_PARAMS\n"); -+ return -ENOMEM; -+ } -+ kalMemZero(prCmdPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ -+ prCmdPscnParam->ucVersion = CURRENT_PSCN_VERSION; -+ -+ if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) { -+ scnRemoveFromPSCN(prAdapter, -+ fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN, prCmdPscnParam); -+ } else { -+ DBGLOG(SCN, INFO, "combine GSCN or Batch or NLO to PSCN --->\n"); -+ -+ scnSubCombineNLOtoPSCN(prAdapter, prNewCmdNloReq, prCmdPscnParam); -+ scnSubCombineBatchSCNtoPSCN(prAdapter, prNewCmdBatchReq, prCmdPscnParam); -+ if (prNewCmdGscnReq) -+ scnSubCombineGSCNtoPSCN(prAdapter, prNewCmdGscnReq, NULL, prCmdPscnParam); -+ if (prNewCmdGscnConfig) -+ scnSubCombineGSCNtoPSCN(prAdapter, NULL, prNewCmdGscnConfig, prCmdPscnParam); -+ /* scnFsmPSCNSetParam(prAdapter, prCmdPscnParam); */ -+ -+#if 0 -+ DBGLOG(SCN, TRACE, "combine GSCN or Batch or NLO to PSCN <--- rCmdPscnParam\n"); -+ DBGLOG(SCN, TRACE, -+ "Period[%u], NumCache[%u], Threshold[%u], NumBuckets[%u],GSCNEn[%d] NLOEn[%d] BatchEn[%d]\n", -+ prCmdPscnParam->rCmdGscnReq.u4BasePeriod, prCmdPscnParam->rCmdGscnReq.ucNumScnToCache, -+ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold, prCmdPscnParam->rCmdGscnReq.u4NumBuckets, -+ prCmdPscnParam->fgGScnEnable, prCmdPscnParam->fgNLOScnEnable, -+ prCmdPscnParam->fgBatchScnEnable)); -+ -+ for (i = 0; i < prCmdPscnParam->rCmdGscnReq.u4NumBuckets; i++) { -+ DBGLOG(SCN, TRACE, "rCmdPscnParam.rCmdGscnParam.arChannelBucket[%d] has channel: ", i); -+ DBGLOG(SCN, TRACE, -+ "band[%u], ChnBkt[%u] NumChns[%u], BktFreqMltpl[%u] Flag[%u]\n", -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].eBand, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].u2BucketIndex, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucBucketFreqMultiple, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucReportFlag)); -+ for (j = 0; j < prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels; j++) { -+ DBGLOG(SCN, TRACE, " %d, ", -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].arChannelList[j].ucChannel); -+ } -+ DBGLOG(SCN, TRACE, "\n"); -+ } -+#endif -+ } -+ -+ memcpy(prScanInfo->prPscnParam, prCmdPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ kalMemFree(prCmdPscnParam, VIR_MEM_TYPE, sizeof(CMD_SET_PSCAN_PARAM)); -+ return TRUE; -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set CMD_ID_SET_PSCN_MAC_ADDR -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmSetGSCNConfig(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_SCN_COFIG_T prCmdGscnScnConfig) -+{ -+ CMD_GSCN_SCN_COFIG_T rCmdGscnScnConfig; -+ -+ ASSERT(prAdapter); -+ memcpy(&rCmdGscnScnConfig, prCmdGscnScnConfig, sizeof(CMD_GSCN_SCN_COFIG_T)); -+ DBGLOG(SCN, TRACE, "rCmdGscnScnConfig: u4BufferThreshold; [%d] ucNumApPerScn [%d] ucNumScnToCache [%d]\n", -+ rCmdGscnScnConfig.u4BufferThreshold, -+ rCmdGscnScnConfig.ucNumApPerScn, -+ rCmdGscnScnConfig.u4NumScnToCache); -+ -+ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, &rCmdGscnScnConfig, FALSE, FALSE, FALSE, FALSE); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set CMD_ID_SET_PSCN_MAC_ADDR -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmGetGSCNResult(IN P_ADAPTER_T prAdapter, IN P_CMD_GET_GSCAN_RESULT_T prGetGscnScnResultCmd) -+{ -+ CMD_GET_GSCAN_RESULT_T rGetGscnScnResultCmd; -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ memcpy(&rGetGscnScnResultCmd, prGetGscnScnResultCmd, sizeof(CMD_GET_GSCAN_RESULT_T)); -+ DBGLOG(SCN, INFO, "rGetGscnScnResultCmd: ucGetNum [%d] fgFlush [%d]\n", -+ rGetGscnScnResultCmd.u4Num, rGetGscnScnResultCmd.ucFlush); -+ -+ if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) { -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_GSCN_SCN_RESULT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, sizeof(CMD_GET_GSCAN_RESULT_T), (PUINT_8) &rGetGscnScnResultCmd, NULL, 0); -+ return TRUE; -+ } -+ /* debug msg, No PSCN, Sched SCAN GSCN ongoing ??? */ -+ return FALSE; -+ -+} -+ -+VOID -+scnPSCNFsm(IN P_ADAPTER_T prAdapter, -+ ENUM_PSCAN_STATE_T eNextPSCNState, -+ IN P_CMD_NLO_REQ prCmdNloReq, -+ IN P_CMD_BATCH_REQ_T prCmdBatchReq, -+ IN P_CMD_GSCN_REQ_T prCmdGscnReq, -+ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, -+ IN BOOLEAN fgRemoveNLOfromPSCN, -+ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN, IN BOOLEAN fgEnableGSCN) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ BOOLEAN fgTransitionState = FALSE; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ do { -+ fgTransitionState = FALSE; -+ -+ DBGLOG(SCN, STATE, "eCurrentPSCNState=%d, eNextPSCNState=%d\n", -+ prScanInfo->eCurrentPSCNState, eNextPSCNState); -+ -+ switch (prScanInfo->eCurrentPSCNState) { -+ case PSCN_IDLE: -+ if (eNextPSCNState == PSCN_RESET) { -+ if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) { -+ DBGLOG(SCN, TRACE, "Unexpected remove NLO/BATCH/GSCN request\n"); -+ eNextPSCNState = PSCN_IDLE; -+ break; -+ } -+ -+ if (prCmdNloReq || prCmdBatchReq) { -+ DBGLOG(SCN, TRACE, "PSCN_IDLE->PSCN_RESET,.... scnFsmPSCNActionDISABLE\n"); -+ /*TBD check PSCAN is ongoing */ -+ scnFsmPSCNAction(prAdapter, DISABLE); -+ break; -+ } -+ -+ } else if (eNextPSCNState == PSCN_SCANNING) { -+ if (fgEnableGSCN) { -+ if (prScanInfo->fgPscnOnnning) -+ scnFsmPSCNAction(prAdapter, DISABLE); -+ if (prScanInfo->fgGScnParamSet) { -+ DBGLOG(SCN, TRACE, -+ "PSCN_IDLE->PSCN_SCANNING,.... scnFsmPSCNActionENABLE\n"); -+ prScanInfo->prPscnParam->fgGScnEnable = TRUE; -+ scnFsmPSCNSetParam(prAdapter, -+ (P_CMD_SET_PSCAN_PARAM)prScanInfo->prPscnParam); -+ scnFsmPSCNAction(prAdapter, ENABLE); -+ eNextPSCNState = PSCN_SCANNING; -+ } -+ } -+ } -+ break; -+ -+ case PSCN_RESET: -+ scnCombineParamsIntoPSCN(prAdapter, -+ prCmdNloReq, -+ prCmdBatchReq, -+ prCmdGscnReq, -+ prNewCmdGscnConfig, -+ fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN); -+ -+ if (!prScanInfo->prPscnParam->fgNLOScnEnable && !prScanInfo->prPscnParam->fgBatchScnEnable -+ && !prScanInfo->prPscnParam->fgGScnEnable) { -+ DBGLOG(SCN, TRACE, -+ "PSCN_RESET->PSCN_IDLE,.... fgNLOScnEnable/fgBatchScnEnable/fgGScnEnable false\n"); -+ eNextPSCNState = PSCN_IDLE; -+ } else { -+ if (prScanInfo->prPscnParam->fgNLOScnEnable -+ || prScanInfo->prPscnParam->fgBatchScnEnable) { -+ scnFsmPSCNSetParam(prAdapter, (P_CMD_SET_PSCAN_PARAM) prScanInfo->prPscnParam); -+ scnFsmPSCNAction(prAdapter, ENABLE); -+ eNextPSCNState = PSCN_SCANNING; -+ DBGLOG(SCN, TRACE, -+ "PSCN_RESET->PSCN_SCANNING,.... fgNLOScnEnable/fgBatchScnEnable ENABLE\n"); -+ } -+ } -+ break; -+ -+ case PSCN_SCANNING: -+ if (eNextPSCNState == PSCN_RESET) { -+ if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) { -+ DBGLOG(SCN, TRACE, -+ "PSCN_SCANNING->PSCN_RESET,.... fgRemoveNLOfromPSCN/fgRemoveBatchSCNfromPSCN/fgRemoveGSCNfromPSCN\n"); -+ scnFsmPSCNAction(prAdapter, DISABLE); -+ break; -+ } -+ -+ if (prCmdNloReq || prCmdBatchReq || prCmdGscnReq || prNewCmdGscnConfig) { -+ DBGLOG(SCN, TRACE, -+ "PSCN_SCANNING->PSCN_RESET,.... prCmdNloReq/prCmdBatchReq/prCmdGscnReq/prNewCmdGscnConfig\n"); -+ scnFsmPSCNAction(prAdapter, DISABLE); -+ break; -+ } -+ -+ } else if (eNextPSCNState == PSCN_SCANNING) { -+ if (fgEnableGSCN) { -+ if (prScanInfo->prPscnParam->fgGScnEnable && (!prScanInfo->fgPscnOnnning)) { -+ DBGLOG(SCN, TRACE, -+ "PSCN_SCANNING->PSCN_SCANNING,.... fgGScnEnable/!fgPscnOnnning\n"); -+ /* scnFsmPSCNAction(prAdapter, ENABLE); */ -+ eNextPSCNState = PSCN_SCANNING; -+ } else { -+ -+ DBGLOG(SCN, TRACE, -+ "PSCN_SCANNING->PSCN_SCANNING,.... fgGScnEnable/!fgPscnOnnning\n"); -+ } -+ } -+ } -+ eNextPSCNState = PSCN_SCANNING; -+ break; -+ -+ default: -+ DBGLOG(SCN, WARN, "Unexpected state\n"); -+ ASSERT(0); -+ break; -+ } -+ -+ DBGLOG(SCN, STATE, "eCurrentState %d , eNextPSCNState %d\n", -+ prScanInfo->eCurrentPSCNState, eNextPSCNState); -+ if (prScanInfo->eCurrentPSCNState != eNextPSCNState) -+ fgTransitionState = TRUE; -+ -+ prScanInfo->eCurrentPSCNState = eNextPSCNState; -+ } while (fgTransitionState); -+ -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c -new file mode 100644 -index 0000000000000..29eb8d4e7d92f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c -@@ -0,0 +1,1112 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/sec_fsm.c#1 -+*/ -+ -+/*! \file "sec_fsm.c" -+ \brief This is the file implement security check state machine. -+ -+ In security module, do the port control check after success join to an AP, -+ and the path to NORMAL TR, the state machine handle these state transition. -+*/ -+ -+/* -+** Log: sec_fsm.c -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 03 29 2011 wh.su -+ * [WCXRP00000248] [MT6620 Wi-Fi][FW]Fixed the Klockwork error -+ * fixed the kclocwork error. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix Compile Error when DBG is disabled. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. -+ * -+ * 09 24 2010 wh.su -+ * NULL -+ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 20 2010 wh.su -+ * NULL -+ * adding the eapol callback setting. -+ * -+ * 08 19 2010 wh.su -+ * NULL -+ * adding the tx pkt call back handle for countermeasure. -+ * -+ * 07 19 2010 wh.su -+ * -+ * fixed the compilng error at debug mode. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 05 28 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * fixed the ad-hoc wpa-none send non-encrypted frame issue. -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 13 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the Klocwork error and refine the class error message. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, -+ * and modify the security related callback function prototype. -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Refine the variable and parameter for security. -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 13 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * fixed the compiling warning -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * refine some code -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * refine the code -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * code refine -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function name -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the state machine, to meet the firmware security design v1.1 -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_RSN_MIGRATION -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugSecState[SEC_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("SEC_STATE_INIT"), -+ (PUINT_8) DISP_STRING("SEC_STATE_INITIATOR_PORT_BLOCKED"), -+ (PUINT_8) DISP_STRING("SEC_STATE_RESPONDER_PORT_BLOCKED"), -+ (PUINT_8) DISP_STRING("SEC_STATE_CHECK_OK"), -+ (PUINT_8) DISP_STRING("SEC_STATE_SEND_EAPOL"), -+ (PUINT_8) DISP_STRING("SEC_STATE_SEND_DEAUTH"), -+ (PUINT_8) DISP_STRING("SEC_STATE_COUNTERMEASURE"), -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do initialization of Security FSM and all variables in -+* SEC_INFO_T. -+* -+* \param[in] prSta Pointer to the STA record -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ -+#if 1 /* MT6620 */ -+ /* At MT5921, is ok, but at MT6620, firmware base ASIC, the firmware */ -+ /* will lost these data, thus, driver have to keep the wep material and */ -+ /* setting to firmware while awake from D3. */ -+#endif -+ -+ prSecInfo->eCurrentState = SEC_STATE_INIT; -+ -+ prSecInfo->fg2nd1xSend = FALSE; -+ prSecInfo->fgKeyStored = FALSE; -+ -+ if (IS_STA_IN_AIS(prSta)) { -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ prAisSpecBssInfo->u4RsnaLastMICFailTime = 0; -+ prAisSpecBssInfo->fgCheckEAPoLTxDone = FALSE; -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) secFsmEventEapolTxTimeout, (ULONG) prSta); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) secFsmEventEndOfCounterMeasure, (ULONG) prSta); -+ -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do uninitialization of Security FSM and all variables in -+* SEC_INFO_T. -+* -+* \param[in] prSta Pointer to the STA record -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID /* whsu:Todo: */ -+secFsmUnInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ -+ prSecInfo->fg2nd1xSend = FALSE; -+ prSecInfo->fgKeyStored = FALSE; -+ -+ /* nicPrivacyRemoveWlanTable(prSta->ucWTEntry); */ -+ -+ if (IS_STA_IN_AIS(prSta)) { -+ cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer); -+ cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* STANDBY to CHECK_OK. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_INIT_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ secSetPortBlocked(prAdapter, prSta, FALSE); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* INIT to INITIATOR_PORT_BLOCKED. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_INIT_to_INITIATOR_PORT_BLOCKED(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* INIT to RESPONDER_PORT_BLOCKED. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_INIT_to_RESPONDER_PORT_BLOCKED(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* INITIATOR_PORT_BLOCKED to CHECK_OK. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_INITIATOR_PORT_BLOCKED_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ secSetPortBlocked(prAdapter, prSta, FALSE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* RESPONDER_PORT_BLOCKED to CHECK_OK. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_RESPONDER_PORT_BLOCKED_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ secSetPortBlocked(prAdapter, prSta, FALSE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* CHECK_OK to SEND_EAPOL -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_CHECK_OK_to_SEND_EAPOL(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ -+ P_AIS_SPECIFIC_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ ASSERT(prSta); -+ -+ prAisBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ ASSERT(prAisBssInfo); -+ -+ if (!IS_STA_IN_AIS(prSta)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ prAisBssInfo->fgCheckEAPoLTxDone = TRUE; -+ -+ /* cnmTimerStartTimer(prAdapter, */ -+ /* &prAisBssInfo->rRsnaEAPoLReportTimeoutTimer, */ -+ /* SEC_TO_MSEC(EAPOL_REPORT_SEND_TIMEOUT_INTERVAL_SEC)); */ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* SEND_EAPOL to SEND_DEAUTH. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_SEND_EAPOL_to_SEND_DEAUTH(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ -+ if (!IS_STA_IN_AIS(prSta)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ /* Compose deauth frame to AP, a call back function for tx done */ -+ if (authSendDeauthFrame(prAdapter, -+ prSta, -+ (P_SW_RFB_T) NULL, -+ REASON_CODE_MIC_FAILURE, -+ (PFN_TX_DONE_HANDLER) secFsmEventDeauthTxDone) != WLAN_STATUS_SUCCESS) { -+ ASSERT(FALSE); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* SEND_DEAUTH to COUNTERMEASURE. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_SEND_DEAUTH_to_COUNTERMEASURE(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prSta); -+ -+ if (!IS_STA_IN_AIS(prSta)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ /* Start the 60 sec timer */ -+ cnmTimerStartTimer(prAdapter, -+ &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer, -+ SEC_TO_MSEC(COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC)); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* SEND_DEAUTH to COUNTERMEASURE. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_COUNTERMEASURE_to_INIT(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ -+ /* Clear the counter measure flag */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The Core FSM engine of security module. -+* -+* \param[in] prSta Pointer to the Sta record -+* \param[in] eNextState Enum value of next sec STATE -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmSteps(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN ENUM_SEC_STATE_T eNextState) -+{ -+ P_SEC_INFO_T prSecInfo; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ ASSERT(prSecInfo); -+ -+ DEBUGFUNC("secFsmSteps"); -+ do { -+ /* Do entering Next State */ -+ prSecInfo->ePreviousState = prSecInfo->eCurrentState; -+ -+ /* Do entering Next State */ -+#if DBG -+ DBGLOG(RSN, STATE, "\n %pM TRANSITION: [%s] -> [%s]\n\n", -+ prSta->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState], apucDebugSecState[eNextState]); -+#else -+ DBGLOG(RSN, STATE, "\n %pM [%d] TRANSITION: [%d] -> [%d]\n\n", -+ prSta->aucMacAddr, DBG_RSN_IDX, prSecInfo->eCurrentState, eNextState); -+#endif -+ prSecInfo->eCurrentState = eNextState; -+ -+ fgIsTransition = (BOOLEAN) FALSE; -+#if 0 -+ /* Do tasks of the State that we just entered */ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_INIT: -+ break; -+ case SEC_STATE_INITIATOR_PORT_BLOCKED: -+ break; -+ case SEC_STATE_RESPONDER_PORT_BLOCKED: -+ break; -+ case SEC_STATE_CHECK_OK: -+ break; -+ case SEC_STATE_SEND_EAPOL: -+ break; -+ case SEC_STATE_SEND_DEAUTH: -+ break; -+ case SEC_STATE_COUNTERMEASURE: -+ break; -+ default: -+ ASSERT(0); /* Make sure we have handle all STATEs */ -+ break; -+ } -+#endif -+ } while (fgIsTransition); -+ -+ return; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do initialization of Security FSM and all variables in -+* SEC_INFO_T. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEventStart(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ ENUM_SEC_STATE_T eNextState; -+ -+ DBGLOG(RSN, TRACE, "secFsmRunEventStart\n"); -+ -+ ASSERT(prSta); -+ -+ if (!prSta) -+ return; -+ -+ if (!IS_STA_IN_AIS(prSta)) -+ return; -+ -+ DBGLOG(RSN, TRACE, "secFsmRunEventStart for sta %pM network %d\n", -+ prSta->aucMacAddr, prSta->ucNetTypeIndex); -+ -+ prSecInfo = (P_SEC_INFO_T) &prSta->rSecInfo; -+ -+ eNextState = prSecInfo->eCurrentState; -+ -+ secSetPortBlocked(prAdapter, prSta, TRUE); -+ -+ /* prSta->fgTransmitKeyExist = FALSE; */ -+ /* whsu:: nicPrivacySetStaDefaultWTIdx(prSta); */ -+ -+#if 1 /* Since the 1x and key can set to firmware in order, always enter the check ok state */ -+ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, CHECK_OK); -+#else -+ if (IS_STA_IN_AIS(prSta->eStaType)) { -+ if (secRsnKeyHandshakeEnabled(prAdapter) == TRUE -+#if CFG_SUPPORT_WAPI -+ || (prAdapter->rWifiVar.rConnSettings.fgWapiMode) -+#endif -+ ) { -+ prSta->fgTransmitKeyExist = FALSE; -+ /* nicPrivacyInitialize(prSta->ucNetTypeIndex); */ -+ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, INITIATOR_PORT_BLOCKED); -+ } else { -+ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, CHECK_OK); -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT || CFG_ENABLE_BT_OVER_WIFI -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_BT_OVER_WIFI -+ else if ((prSta->eStaType == STA_TYPE_BOW_CLIENT) || (prSta->eStaType == STA_TYPE_P2P_GC)) { -+#elif CFG_ENABLE_WIFI_DIRECT -+ else if (prSta->eStaType == STA_TYPE_P2P_GC) { -+#elif CFG_ENABLE_BT_OVER_WIFI -+ else if (prSta->eStaType == STA_TYPE_BOW_CLIENT) { -+#endif -+ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, RESPONDER_PORT_BLOCKED); -+ } -+#endif -+ else -+ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, INITIATOR_PORT_BLOCKED); -+#endif -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+} /* secFsmRunEventStart */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function called by reset procedure to force the sec fsm enter -+* idle state -+* -+* \param[in] ucNetTypeIdx The Specific Network type index -+* \param[in] prSta Pointer to the Sta record -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEventAbort(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ -+ DBGLOG(RSN, TRACE, "secFsmEventAbort for sta %pM network %d\n", -+ prSta->aucMacAddr, prSta->ucNetTypeIndex); -+ -+ ASSERT(prSta); -+ -+ if (!prSta) -+ return; -+ -+ if (!IS_STA_IN_AIS(prSta)) -+ return; -+ -+ prSecInfo = (P_SEC_INFO_T) &prSta->rSecInfo; -+ -+ prSta->fgTransmitKeyExist = FALSE; -+ -+ secSetPortBlocked(prAdapter, prSta, TRUE); -+ -+ if (prSecInfo == NULL) -+ return; -+ -+ if (IS_STA_IN_AIS(prSta)) { -+ -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE; -+ -+ if (prSecInfo->eCurrentState == SEC_STATE_SEND_EAPOL) { -+ if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgCheckEAPoLTxDone == FALSE) { -+ DBGLOG(RSN, TRACE, "EAPOL STATE not match the flag\n"); -+ /* cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar. -+ * rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer); */ -+ } -+ } -+ } -+ prSecInfo->eCurrentState = SEC_STATE_INIT; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "2nd EAPoL Tx is sending" to Sec FSM. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEvent2ndEapolTx(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ /* BOOLEAN fgIsTransition = (BOOLEAN)FALSE; */ -+ -+ DEBUGFUNC("secFsmRunEvent2ndEapolTx"); -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ eNextState = prSecInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_INITIATOR_PORT_BLOCKED: -+ case SEC_STATE_CHECK_OK: -+ prSecInfo->fg2nd1xSend = TRUE; -+ break; -+ default: -+#if DBG -+ DBGLOG(RSN, WARN, "Rcv 2nd EAPoL at %s\n", apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, WARN, "Rcv 2nd EAPoL at [%d]\n", prSecInfo->eCurrentState); -+#endif -+ break; -+ } -+ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+ return; -+ -+} /* secFsmRunEvent2ndEapolTx */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "4th EAPoL Tx is Tx done" to Sec FSM. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEvent4ndEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ P_CMD_802_11_KEY prStoredKey; -+ -+ DEBUGFUNC("secFsmRunEvent4ndEapolTx"); -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ eNextState = prSecInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_INITIATOR_PORT_BLOCKED: -+ case SEC_STATE_CHECK_OK: -+ prSecInfo->fg2nd1xSend = FALSE; -+ if (prSecInfo->fgKeyStored) { -+ prStoredKey = (P_CMD_802_11_KEY) prSecInfo->aucStoredKey; -+ -+ /* prSta = rxmLookupStaRecIndexFromTA(prStoredKey->aucPeerAddr); */ -+ /* if (nicPrivacySetKeyEntry(prStoredKey, prSta->ucWTEntry) == FALSE) */ -+ /* DBGLOG(RSN, WARN, ("nicPrivacySetKeyEntry() fail,..\n")); */ -+ -+ /* key update */ -+ prSecInfo->fgKeyStored = FALSE; -+ prSta->fgTransmitKeyExist = TRUE; -+ } -+ if (prSecInfo->eCurrentState == SEC_STATE_INITIATOR_PORT_BLOCKED) -+ SEC_STATE_TRANSITION(prAdapter, prSta, INITIATOR_PORT_BLOCKED, CHECK_OK); -+ break; -+ default: -+ -+#if DBG -+ DBGLOG(RSN, WARN, "Rcv thh EAPoL Tx done at %s\n", apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, WARN, "Rcv thh EAPoL Tx done at [%d]\n", prSecInfo->eCurrentState); -+#endif -+ break; -+ } -+ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+ return; -+ -+} /* secFsmRunEvent4ndEapolTx */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "Pairwise key installed" to SEC FSM. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \retval TRUE The key can be installed to HW -+* \retval FALSE The kay conflict with the current key, abort it -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secFsmEventPTKInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgStatus = TRUE; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ if (prSecInfo == NULL) -+ return TRUE; /* Not PTK */ -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAdd), -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ eNextState = prSecInfo->eCurrentState; -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_INIT: -+ /* Legacy wep, wpa-none */ -+ break; -+ -+ case SEC_STATE_INITIATOR_PORT_BLOCKED: -+ if (prSecInfo->fg2nd1xSend) -+ ; -+ else -+ SEC_STATE_TRANSITION(prAdapter, prSta, INITIATOR_PORT_BLOCKED, CHECK_OK); -+ break; -+ -+ case SEC_STATE_RESPONDER_PORT_BLOCKED: -+ SEC_STATE_TRANSITION(prAdapter, prSta, RESPONDER_PORT_BLOCKED, CHECK_OK); -+ break; -+ -+ case SEC_STATE_CHECK_OK: -+ break; -+ -+ default: -+ fgStatus = FALSE; -+ break; -+ } -+ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+ return fgStatus; -+ -+} /* end of secFsmRunEventPTKInstalled() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "Counter Measure" to SEC FSM. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEventStartCounterMeasure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ DEBUGFUNC("secFsmRunEventStartCounterMeasure"); -+ -+ ASSERT(prSta); -+ -+ if (!IS_STA_IN_AIS(prSta)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ prSecInfo = &prSta->rSecInfo; -+ -+ eNextState = prSecInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ prAdapter->rWifiVar.rAisSpecificBssInfo.u4RsnaLastMICFailTime = 0; -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_CHECK_OK: -+ { -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure = TRUE; -+ -+ /* dls port control */ -+ SEC_STATE_TRANSITION(prAdapter, prSta, CHECK_OK, SEND_EAPOL); -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ /* Call arbFsmSteps() when we are going to change ARB STATE */ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+ return; -+ -+} /* secFsmRunEventStartCounterMeasure */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "802.1x EAPoL Tx Done" to Sec FSM. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+secFsmEventEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisBssInfo; -+ -+ DEBUGFUNC("secFsmRunEventEapolTxDone"); -+ -+ ASSERT(prStaRec); -+ -+ if (rTxDoneStatus != TX_RESULT_SUCCESS) { -+ DBGLOG(RSN, INFO, "Error EAPoL fram fail to send!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ if (!IS_STA_IN_AIS(prStaRec)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ prAisBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ ASSERT(prAisBssInfo); -+ -+ prSecInfo = &prStaRec->rSecInfo; -+ eNextState = prSecInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prStaRec->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prStaRec->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_SEND_EAPOL: -+ if (prAisBssInfo->fgCheckEAPoLTxDone == FALSE) -+ ASSERT(0); -+ -+ prAisBssInfo->fgCheckEAPoLTxDone = FALSE; -+ /* cnmTimerStopTimer(prAdapter, &prAisBssInfo->rRsnaEAPoLReportTimeoutTimer); */ -+ -+ SEC_STATE_TRANSITION(prAdapter, prStaRec, SEND_EAPOL, SEND_DEAUTH); -+ break; -+ default: -+ break; -+ } -+ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prStaRec, eNextState); -+ -+ return; -+ -+} /* secFsmRunEventEapolTxDone */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "Deauth frame Tx Done" to Sec FSM. -+* -+* \param[in] pMsduInfo Pointer to the Msdu Info -+* \param[in] rStatus The Tx done status -+* -+* \return - -+* -+* \note after receive deauth frame, callback function call this -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+secFsmEventDeauthTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ DEBUGFUNC("secFsmRunEventDeauthTxDone"); -+ -+ ASSERT(prMsduInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return; -+ -+ if (!IS_STA_IN_AIS(prStaRec)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ prSecInfo = (P_SEC_INFO_T) &prStaRec->rSecInfo; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prStaRec->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prStaRec->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_SEND_DEAUTH: -+ -+ DBGLOG(RSN, TRACE, "Set timer %d\n", COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC); -+ -+ SEC_STATE_TRANSITION(prAdapter, prStaRec, SEND_DEAUTH, COUNTERMEASURE); -+ -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+ -+} /* secFsmRunEventDeauthTxDone */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will check the eapol error frame fail to send issue. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEventEapolTxTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParm) -+{ -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("secFsmRunEventEapolTxTimeout"); -+ -+ prStaRec = (P_STA_RECORD_T) ulParm; -+ -+ ASSERT(prStaRec); -+ -+ /* Todo:: How to handle the Eapol Error fail to send case? */ -+ ASSERT(0); -+ -+ return; -+ -+} /* secFsmEventEapolTxTimeout */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will stop the counterMeasure duration. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEventEndOfCounterMeasure(IN P_ADAPTER_T prAdapter, ULONG ulParm) -+{ -+ P_STA_RECORD_T prSta; -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ DEBUGFUNC("secFsmRunEventEndOfCounterMeasure"); -+ -+ prSta = (P_STA_RECORD_T) ulParm; -+ -+ ASSERT(prSta); -+ -+ if (!IS_STA_IN_AIS(prSta)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ prSecInfo = &prSta->rSecInfo; -+ eNextState = prSecInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_SEND_DEAUTH: -+ { -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure = FALSE; -+ -+ SEC_STATE_TRANSITION(prAdapter, prSta, COUNTERMEASURE, INIT); -+ } -+ break; -+ -+ default: -+ ASSERT(0); -+ } -+ -+ /* Call arbFsmSteps() when we are going to change ARB STATE */ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+} /* end of secFsmRunEventEndOfCounterMeasure */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c -new file mode 100644 -index 0000000000000..ab3fcc028375b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c -@@ -0,0 +1,1342 @@ -+/* -+** Id: stats.c#1 -+*/ -+ -+/*! \file stats.c -+ \brief This file includes statistics support. -+*/ -+ -+/* -+** Log: stats.c -+ * -+ * 07 17 2014 samp.lin -+ * NULL -+ * Initial version. -+ */ -+ -+/******************************************************************************* -+ * C O M P I L E R F L A G S -+ ******************************************************************************** -+ */ -+ -+/******************************************************************************* -+ * E X T E R N A L R E F E R E N C E S -+ ******************************************************************************** -+ */ -+#include "precomp.h" -+ -+enum EVENT_TYPE { -+ EVENT_RX, -+ EVENT_TX, -+ EVENT_TX_DONE -+}; -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); -+ -+static WLAN_STATUS -+statsInfoEnvRequest(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+UINT_64 u8DrvOwnStart, u8DrvOwnEnd; -+UINT32 u4DrvOwnMax = 0; -+#define CFG_USER_LOAD 0 -+static UINT_16 su2TxDoneCfg = CFG_DHCP | CFG_ICMP | CFG_EAPOL; -+/******************************************************************************* -+* P R I V A T E F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display all environment log. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ P_ADAPTER_T prAdapter; -+ STA_RECORD_T *prStaRec; -+ UINT32 u4NumOfInfo, u4InfoId; -+ UINT32 u4RxErrBitmap; -+ STATS_INFO_ENV_T *prInfo; -+ UINT32 u4Total, u4RateId; -+ -+/* -+[wlan] statsInfoEnvRequest: (INIT INFO) statsInfoEnvRequest cmd ok. -+[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event -+[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event: 0 -+[wlan] statsInfoEnvDisplay: (INIT INFO) Display stats for [00:0c:43:31:35:97]: -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) TPAM(0x0) RTS(0 0) BA(0x1 0) OK(9 9 xxx) ERR(0 0 0 0 0 0 0) -+ TPAM (bit0: enable 40M, bit1: enable 20 short GI, bit2: enable 40 short GI, -+ bit3: use 40M TX, bit4: use short GI TX, bit5: use no ack) -+ RTS (1st: current use RTS/CTS, 2nd: ever use RTS/CTS) -+ BA (1st: TX session BA bitmap for TID0 ~ TID7, 2nd: peer receive maximum agg number) -+ OK (1st: total number of tx packet from host, 2nd: total number of tx ok, system time last TX OK) -+ ERR (1st: total number of tx err, 2nd ~ 7st: total number of -+ WLAN_STATUS_BUFFER_RETAINED, WLAN_STATUS_PACKET_FLUSHED, WLAN_STATUS_PACKET_AGING_TIMEOUT, -+ WLAN_STATUS_PACKET_MPDU_ERROR, WLAN_STATUS_PACKET_RTS_ERROR, WLAN_STATUS_PACKET_LIFETIME_ERROR) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) TRATE (6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (0 0 0 0 0 0 0 3) -+ TX rate count (1M 2 5.5 11 NA NA NA NA 48 24 12 6 54 36 18 9) (MCS0 ~ MCS7) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) RX(148 1 0) BA(0x1 64) OK(2 2) ERR(0) -+ RX (1st: latest RCPI, 2nd: chan num) -+ BA (1st: RX session BA bitmap for TID0 ~ TID7, 2nd: our receive maximum agg number) -+ OK (number of rx packets without error, number of rx packets to OS) -+ ERR (number of rx packets with error) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) RCCK (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) -+ CCK MODE (1 2 5.5 11M) -+[wlan] statsInfoEnvDisplay: (INIT INFO) ROFDM (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) -+ OFDM MODE (NA NA NA NA 6 9 12 18 24 36 48 54M) -+[wlan] statsInfoEnvDisplay: (INIT INFO) RHT (0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0) -+ MIXED MODE (number of rx packets with MCS0 ~ MCS15) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntH2M us (29 29 32) (0 0 0) (0 0 0) -+ delay from HIF to MAC own bit=1 (min, avg, max for 500B) (min, avg, max for 1000B) (min, avg, max for others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) AirTime us (608 864 4480) (0 0 0) (0 0 0) -+ delay from MAC start TX to MAC TX done -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayInt us (795 1052 4644_4504) (0 0 0_0) (0 0 0_0) -+ delay from HIF to MAC TX done (min, avg, max_system time for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntD2T us (795 1052 4644) (0 0 0) (0 0 0) -+ delay from driver to MAC TX done (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_M2H us (37 40 58) (0 0 0) (0 0 0) -+ delay from MAC to HIF (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_H2D us (0 0 0) (0 0 0) (0 0 0) -+ delay from HIF to Driver OS (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCntD2H unit:10ms (10 0 0 0) -+ delay count from Driver to HIF (count in 0~10ms, 10~20ms, 20~30ms, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt unit:1ms (6 3 0 1) -+ delay count from HIF to TX DONE (count in 0~1ms, 1~5ms, 5~10ms, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt (0~1161:7) (1161~2322:2) (2322~3483:0) (3483~4644:0) (4644~:1) -+ delay count from HIF to TX DONE (count in 0~1161 ticks, 1161~2322, 2322~3483, 3483~4644, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) OTHER (61877) (0) (38) (0) (0) (0ms) -+ Channel idle time, scan count, channel change count, empty tx quota count, -+ power save change count from active to PS, maximum delay from PS to active -+*/ -+ -+ /* init */ -+ prAdapter = prGlueInfo->prAdapter; -+ /*prInfo = &rStatsInfoEnv;*/ -+ prInfo = kalMemAlloc(sizeof(STATS_INFO_ENV_T), VIR_MEM_TYPE); -+ if (prInfo == NULL) { -+ DBGLOG(RX, INFO, "prInfo alloc fail"); -+ return; -+ } -+ -+ kalMemZero(prInfo, sizeof(STATS_INFO_ENV_T)); -+ -+ if (u4InBufLen > sizeof(STATS_INFO_ENV_T)) -+ u4InBufLen = sizeof(STATS_INFO_ENV_T); -+ -+ /* parse */ -+ u4NumOfInfo = *(UINT32 *) prInBuf; -+ u4RxErrBitmap = *(UINT32 *) (prInBuf + 4); -+ -+ /* print */ -+ for (u4InfoId = 0; u4InfoId < u4NumOfInfo; u4InfoId++) { -+ /* -+ use u4InBufLen, not sizeof(rStatsInfoEnv) -+ because the firmware version maybe not equal to driver version -+ */ -+ kalMemCopy(prInfo, prInBuf + 8, u4InBufLen); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prInfo->ucStaRecIdx); -+ if (prStaRec == NULL) -+ continue; -+ -+ DBGLOG(RX, INFO, " Display stats for [%pM]: %uB\n", -+ prStaRec->aucMacAddr, (UINT32) sizeof(STATS_INFO_ENV_T)); -+ -+ if (prStaRec->ucStatsGenDisplayCnt++ > 10) { -+ /* display general statistics information every 10 * (5 or 10s) */ -+ DBGLOG(RX, INFO, " TBA(0x%x %u) RBA(0x%x %u)\n", -+ prInfo->ucTxAggBitmap, prInfo->ucTxPeerAggMaxSize, -+ prInfo->ucRxAggBitmap, prInfo->ucRxAggMaxSize); -+ prStaRec->ucStatsGenDisplayCnt = 0; -+ } -+ -+ if (prInfo->u4TxDataCntErr == 0) { -+ DBGLOG(RX, INFO, " TOS(%u) OK(%u %u)\n", -+ (UINT32) prGlueInfo->rNetDevStats.tx_packets, -+ prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK); -+ } else { -+ DBGLOG(RX, INFO, " TOS(%u) OK(%u %u) ERR(%u)\n", -+ (UINT32) prGlueInfo->rNetDevStats.tx_packets, -+ prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK, prInfo->u4TxDataCntErr); -+ DBGLOG(RX, INFO, " ERR type(%u %u %u %u %u %u)\n", -+ prInfo->u4TxDataCntErrType[0], prInfo->u4TxDataCntErrType[1], -+ prInfo->u4TxDataCntErrType[2], prInfo->u4TxDataCntErrType[3], -+ prInfo->u4TxDataCntErrType[4], prInfo->u4TxDataCntErrType[5]); -+ } -+ -+ for (u4RateId = 1, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4TxRateCntNonHT[u4RateId]; -+ if (u4Total > 0) { -+ DBGLOG(RX, INFO, " non-HT TRATE (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", -+ prInfo->u4TxRateCntNonHT[0], prInfo->u4TxRateCntNonHT[1], -+ prInfo->u4TxRateCntNonHT[2], prInfo->u4TxRateCntNonHT[3], -+ prInfo->u4TxRateCntNonHT[4], prInfo->u4TxRateCntNonHT[5], -+ prInfo->u4TxRateCntNonHT[6], prInfo->u4TxRateCntNonHT[7], -+ prInfo->u4TxRateCntNonHT[8], prInfo->u4TxRateCntNonHT[9], -+ prInfo->u4TxRateCntNonHT[10], prInfo->u4TxRateCntNonHT[11], -+ prInfo->u4TxRateCntNonHT[12], prInfo->u4TxRateCntNonHT[13], -+ prInfo->u4TxRateCntNonHT[14], prInfo->u4TxRateCntNonHT[15]); -+ } -+ if (prInfo->u4TxRateCntNonHT[0] > 0) { -+ DBGLOG(RX, INFO, " HT TRATE (1M %u) (%u %u %u %u %u %u %u %u)\n", -+ prInfo->u4TxRateCntNonHT[0], -+ prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1], -+ prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3], -+ prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5], -+ prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7]); -+ } else { -+ DBGLOG(RX, INFO, " HT TRATE (%u %u %u %u %u %u %u %u)\n", -+ prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1], -+ prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3], -+ prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5], -+ prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7]); -+ } -+ -+ if ((prStaRec->u4RxReorderFallAheadCnt != 0) || -+ (prStaRec->u4RxReorderFallBehindCnt != 0) || (prStaRec->u4RxReorderHoleCnt != 0)) { -+ DBGLOG(RX, INFO, " TREORDER (%u %u %u)\n", -+ prStaRec->u4RxReorderFallAheadCnt, -+ prStaRec->u4RxReorderFallBehindCnt, prStaRec->u4RxReorderHoleCnt); -+ } -+ -+ if (prInfo->u4RxDataCntErr == 0) { -+ DBGLOG(RX, INFO, " ROK(%u %u)\n", -+ prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt); -+ } else { -+ DBGLOG(RX, INFO, " ROK(%u %u) ERR(%u)\n", -+ prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt, -+ prInfo->u4RxDataCntErr); -+ } -+ -+ for (u4RateId = 1, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateCnt[0][u4RateId] + prInfo->u4RxRateRetryCnt[0][u4RateId]; -+ if (u4Total > 0) { -+ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateRetryCnt[0][u4RateId]; -+ if (u4Total > 0) { -+ DBGLOG(RX, INFO, -+ " RCCK (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" -+ "(%u %u)(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0], -+ prInfo->u4RxRateCnt[0][1], prInfo->u4RxRateRetryCnt[0][1], -+ prInfo->u4RxRateCnt[0][2], prInfo->u4RxRateRetryCnt[0][2], -+ prInfo->u4RxRateCnt[0][3], prInfo->u4RxRateRetryCnt[0][3], -+ prInfo->u4RxRateCnt[0][4], prInfo->u4RxRateRetryCnt[0][4], -+ prInfo->u4RxRateCnt[0][5], prInfo->u4RxRateRetryCnt[0][5], -+ prInfo->u4RxRateCnt[0][6], prInfo->u4RxRateRetryCnt[0][6], -+ prInfo->u4RxRateCnt[0][7], prInfo->u4RxRateRetryCnt[0][7], -+ prInfo->u4RxRateCnt[0][8], prInfo->u4RxRateRetryCnt[0][8], -+ prInfo->u4RxRateCnt[0][9], prInfo->u4RxRateRetryCnt[0][9], -+ prInfo->u4RxRateCnt[0][10], prInfo->u4RxRateRetryCnt[0][10], -+ prInfo->u4RxRateCnt[0][11], prInfo->u4RxRateRetryCnt[0][11], -+ prInfo->u4RxRateCnt[0][12], prInfo->u4RxRateRetryCnt[0][12], -+ prInfo->u4RxRateCnt[0][13], prInfo->u4RxRateRetryCnt[0][13], -+ prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateRetryCnt[0][14], -+ prInfo->u4RxRateCnt[0][15], prInfo->u4RxRateRetryCnt[0][15]); -+ } else { -+ DBGLOG(RX, INFO, " RCCK (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", -+ prInfo->u4RxRateCnt[0][0], -+ prInfo->u4RxRateCnt[0][1], -+ prInfo->u4RxRateCnt[0][2], -+ prInfo->u4RxRateCnt[0][3], -+ prInfo->u4RxRateCnt[0][4], -+ prInfo->u4RxRateCnt[0][5], -+ prInfo->u4RxRateCnt[0][6], -+ prInfo->u4RxRateCnt[0][7], -+ prInfo->u4RxRateCnt[0][8], -+ prInfo->u4RxRateCnt[0][9], -+ prInfo->u4RxRateCnt[0][10], -+ prInfo->u4RxRateCnt[0][11], -+ prInfo->u4RxRateCnt[0][12], -+ prInfo->u4RxRateCnt[0][13], -+ prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateCnt[0][15]); -+ } -+ } else { -+ if ((prInfo->u4RxRateCnt[0][0] + prInfo->u4RxRateRetryCnt[0][0]) > 0) { -+ DBGLOG(RX, INFO, " RCCK (%u %u)\n", -+ prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0]); -+ } -+ } -+ -+ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateCnt[1][u4RateId] + prInfo->u4RxRateRetryCnt[1][u4RateId]; -+ if (u4Total > 0) { -+ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateRetryCnt[1][u4RateId]; -+ if (u4Total > 0) { -+ DBGLOG(RX, INFO, -+ " ROFDM (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" -+ "(%u %u)(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[1][0], prInfo->u4RxRateRetryCnt[1][0], -+ prInfo->u4RxRateCnt[1][1], prInfo->u4RxRateRetryCnt[1][1], -+ prInfo->u4RxRateCnt[1][2], prInfo->u4RxRateRetryCnt[1][2], -+ prInfo->u4RxRateCnt[1][3], prInfo->u4RxRateRetryCnt[1][3], -+ prInfo->u4RxRateCnt[1][4], prInfo->u4RxRateRetryCnt[1][4], -+ prInfo->u4RxRateCnt[1][5], prInfo->u4RxRateRetryCnt[1][5], -+ prInfo->u4RxRateCnt[1][6], prInfo->u4RxRateRetryCnt[1][6], -+ prInfo->u4RxRateCnt[1][7], prInfo->u4RxRateRetryCnt[1][7], -+ prInfo->u4RxRateCnt[1][8], prInfo->u4RxRateRetryCnt[1][8], -+ prInfo->u4RxRateCnt[1][9], prInfo->u4RxRateRetryCnt[1][9], -+ prInfo->u4RxRateCnt[1][10], prInfo->u4RxRateRetryCnt[1][10], -+ prInfo->u4RxRateCnt[1][11], prInfo->u4RxRateRetryCnt[1][11], -+ prInfo->u4RxRateCnt[1][12], prInfo->u4RxRateRetryCnt[1][12], -+ prInfo->u4RxRateCnt[1][13], prInfo->u4RxRateRetryCnt[1][13], -+ prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateRetryCnt[1][14], -+ prInfo->u4RxRateCnt[1][15], prInfo->u4RxRateRetryCnt[1][15]); -+ } else { -+ DBGLOG(RX, INFO, " ROFDM (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", -+ prInfo->u4RxRateCnt[1][0], -+ prInfo->u4RxRateCnt[1][1], -+ prInfo->u4RxRateCnt[1][2], -+ prInfo->u4RxRateCnt[1][3], -+ prInfo->u4RxRateCnt[1][4], -+ prInfo->u4RxRateCnt[1][5], -+ prInfo->u4RxRateCnt[1][6], -+ prInfo->u4RxRateCnt[1][7], -+ prInfo->u4RxRateCnt[1][8], -+ prInfo->u4RxRateCnt[1][9], -+ prInfo->u4RxRateCnt[1][10], -+ prInfo->u4RxRateCnt[1][11], -+ prInfo->u4RxRateCnt[1][12], -+ prInfo->u4RxRateCnt[1][13], -+ prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateCnt[1][15]); -+ } -+ } -+ -+ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateCnt[2][u4RateId] + prInfo->u4RxRateRetryCnt[2][u4RateId]; -+ if (u4Total > 0) { -+ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateRetryCnt[2][u4RateId]; -+ if (u4Total > 0) { -+ DBGLOG(RX, INFO, " RHT\n" -+ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[2][0], prInfo->u4RxRateRetryCnt[2][0], -+ prInfo->u4RxRateCnt[2][1], prInfo->u4RxRateRetryCnt[2][1], -+ prInfo->u4RxRateCnt[2][2], prInfo->u4RxRateRetryCnt[2][2], -+ prInfo->u4RxRateCnt[2][3], prInfo->u4RxRateRetryCnt[2][3], -+ prInfo->u4RxRateCnt[2][4], prInfo->u4RxRateRetryCnt[2][4], -+ prInfo->u4RxRateCnt[2][5], prInfo->u4RxRateRetryCnt[2][5], -+ prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateRetryCnt[2][6], -+ prInfo->u4RxRateCnt[2][7], prInfo->u4RxRateRetryCnt[2][7]); -+ } else { -+ DBGLOG(RX, INFO, " RHT (%u %u %u %u %u %u %u %u)\n", -+ prInfo->u4RxRateCnt[2][0], -+ prInfo->u4RxRateCnt[2][1], -+ prInfo->u4RxRateCnt[2][2], -+ prInfo->u4RxRateCnt[2][3], -+ prInfo->u4RxRateCnt[2][4], -+ prInfo->u4RxRateCnt[2][5], -+ prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateCnt[2][7]); -+ } -+ } -+ -+ /* RX drop counts */ -+ for (u4RateId = 0, u4Total = 0; u4RateId < 20; u4RateId++) -+ u4Total += prInfo->u4NumOfRxDrop[u4RateId]; -+ if (u4Total > 0) { -+ DBGLOG(RX, INFO, " RX Drop Count: (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n" -+ " (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n", -+ prInfo->u4NumOfRxDrop[0], prInfo->u4NumOfRxDrop[1], -+ prInfo->u4NumOfRxDrop[2], prInfo->u4NumOfRxDrop[3], -+ prInfo->u4NumOfRxDrop[4], prInfo->u4NumOfRxDrop[5], -+ prInfo->u4NumOfRxDrop[6], prInfo->u4NumOfRxDrop[7], -+ prInfo->u4NumOfRxDrop[8], prInfo->u4NumOfRxDrop[9], -+ prInfo->u4NumOfRxDrop[10], prInfo->u4NumOfRxDrop[11], -+ prInfo->u4NumOfRxDrop[12], prInfo->u4NumOfRxDrop[13], -+ prInfo->u4NumOfRxDrop[14], prInfo->u4NumOfRxDrop[15], -+ prInfo->u4NumOfRxDrop[16], prInfo->u4NumOfRxDrop[17], -+ prInfo->u4NumOfRxDrop[18], prInfo->u4NumOfRxDrop[19]); -+ } -+ -+ /* delay from HIF RX to HIF RX Done */ -+ if (((prInfo->u4StayIntMinHR2HRD[1] + prInfo->u4StayIntAvgHR2HRD[1] + -+ prInfo->u4StayIntMaxHR2HRD[1]) > 0) || -+ ((prInfo->u4StayIntMinHR2HRD[2] + prInfo->u4StayIntAvgHR2HRD[2] + -+ prInfo->u4StayIntMaxHR2HRD[2]) > 0)) { -+ DBGLOG(RX, INFO, " StayIntR_HR2HRD us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prInfo->u4StayIntMinHR2HRD[0], prInfo->u4StayIntAvgHR2HRD[0], -+ prInfo->u4StayIntMaxHR2HRD[0], -+ prInfo->u4StayIntMinHR2HRD[1], prInfo->u4StayIntAvgHR2HRD[1], -+ prInfo->u4StayIntMaxHR2HRD[1], -+ prInfo->u4StayIntMinHR2HRD[2], prInfo->u4StayIntAvgHR2HRD[2], -+ prInfo->u4StayIntMaxHR2HRD[2]); -+ } else { -+ DBGLOG(RX, INFO, " StayIntR_HR2HRD us (%u %u %u)\n", -+ prInfo->u4StayIntMinHR2HRD[0], prInfo->u4StayIntAvgHR2HRD[0], -+ prInfo->u4StayIntMaxHR2HRD[0]); -+ } -+ -+ /* others */ -+ DBGLOG(RX, INFO, " OTHER (%u) (%u) (%u) (%x)\n", -+ prInfo->u4RxFifoFullCnt, prAdapter->ucScanTime, -+ prInfo->u4NumOfChanChange, prInfo->u4CurrChnlInfo); -+#if CFG_SUPPORT_THERMO_THROTTLING -+ prAdapter->u4AirDelayTotal = (prInfo->u4AirDelayTotal << 5) / 400000; -+#endif -+ /* reset */ -+ kalMemZero(prStaRec->u4StayIntMinRx, sizeof(prStaRec->u4StayIntMinRx)); -+ kalMemZero(prStaRec->u4StayIntAvgRx, sizeof(prStaRec->u4StayIntAvgRx)); -+ kalMemZero(prStaRec->u4StayIntMaxRx, sizeof(prStaRec->u4StayIntMaxRx)); -+ prStaRec->u4StatsRxPassToOsCnt = 0; -+ prStaRec->u4RxReorderFallAheadCnt = 0; -+ prStaRec->u4RxReorderFallBehindCnt = 0; -+ prStaRec->u4RxReorderHoleCnt = 0; -+ } -+ -+ STATS_DRIVER_OWN_RESET(); -+ kalMemFree(prInfo, VIR_MEM_TYPE, sizeof(STATS_INFO_ENV_T)); -+} -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display all environment log. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ P_ADAPTER_T prAdapter; -+ STA_RECORD_T *prStaRec; -+ UINT32 u4NumOfInfo, u4InfoId; -+ UINT32 u4RxErrBitmap; -+ STATS_INFO_ENV_T rStatsInfoEnv, *prInfo; -+ -+/* -+[wlan] statsInfoEnvRequest: (INIT INFO) statsInfoEnvRequest cmd ok. -+[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event -+[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event: 0 -+[wlan] statsInfoEnvDisplay: (INIT INFO) Display stats for [00:0c:43:31:35:97]: -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) TPAM(0x0) RTS(0 0) BA(0x1 0) OK(9 9 xxx) ERR(0 0 0 0 0 0 0) -+ TPAM (bit0: enable 40M, bit1: enable 20 short GI, bit2: enable 40 short GI, -+ bit3: use 40M TX, bit4: use short GI TX, bit5: use no ack) -+ RTS (1st: current use RTS/CTS, 2nd: ever use RTS/CTS) -+ BA (1st: TX session BA bitmap for TID0 ~ TID7, 2nd: peer receive maximum agg number) -+ OK (1st: total number of tx packet from host, 2nd: total number of tx ok, system time last TX OK) -+ ERR (1st: total number of tx err, 2nd ~ 7st: total number of -+ WLAN_STATUS_BUFFER_RETAINED, WLAN_STATUS_PACKET_FLUSHED, WLAN_STATUS_PACKET_AGING_TIMEOUT, -+ WLAN_STATUS_PACKET_MPDU_ERROR, WLAN_STATUS_PACKET_RTS_ERROR, WLAN_STATUS_PACKET_LIFETIME_ERROR) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) TRATE (6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (0 0 0 0 0 0 0 3) -+ TX rate count (1M 2 5.5 11 NA NA NA NA 48 24 12 6 54 36 18 9) (MCS0 ~ MCS7) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) RX(148 1 0) BA(0x1 64) OK(2 2) ERR(0) -+ RX (1st: latest RCPI, 2nd: chan num) -+ BA (1st: RX session BA bitmap for TID0 ~ TID7, 2nd: our receive maximum agg number) -+ OK (number of rx packets without error, number of rx packets to OS) -+ ERR (number of rx packets with error) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) RCCK (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) -+ CCK MODE (1 2 5.5 11M) -+[wlan] statsInfoEnvDisplay: (INIT INFO) ROFDM (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) -+ OFDM MODE (NA NA NA NA 6 9 12 18 24 36 48 54M) -+[wlan] statsInfoEnvDisplay: (INIT INFO) RHT (0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0) -+ MIXED MODE (number of rx packets with MCS0 ~ MCS15) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntH2M us (29 29 32) (0 0 0) (0 0 0) -+ delay from HIF to MAC own bit=1 (min, avg, max for 500B) (min, avg, max for 1000B) (min, avg, max for others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) AirTime us (608 864 4480) (0 0 0) (0 0 0) -+ delay from MAC start TX to MAC TX done -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayInt us (795 1052 4644_4504) (0 0 0_0) (0 0 0_0) -+ delay from HIF to MAC TX done (min, avg, max_system time for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntD2T us (795 1052 4644) (0 0 0) (0 0 0) -+ delay from driver to MAC TX done (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_M2H us (37 40 58) (0 0 0) (0 0 0) -+ delay from MAC to HIF (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_H2D us (0 0 0) (0 0 0) (0 0 0) -+ delay from HIF to Driver OS (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCntD2H unit:10ms (10 0 0 0) -+ delay count from Driver to HIF (count in 0~10ms, 10~20ms, 20~30ms, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt unit:1ms (6 3 0 1) -+ delay count from HIF to TX DONE (count in 0~1ms, 1~5ms, 5~10ms, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt (0~1161:7) (1161~2322:2) (2322~3483:0) (3483~4644:0) (4644~:1) -+ delay count from HIF to TX DONE (count in 0~1161 ticks, 1161~2322, 2322~3483, 3483~4644, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) OTHER (61877) (0) (38) (0) (0) (0ms) -+ Channel idle time, scan count, channel change count, empty tx quota count, -+ power save change count from active to PS, maximum delay from PS to active -+*/ -+ -+ /* init */ -+ prAdapter = prGlueInfo->prAdapter; -+ prInfo = &rStatsInfoEnv; -+ kalMemZero(&rStatsInfoEnv, sizeof(rStatsInfoEnv)); -+ -+ if (u4InBufLen > sizeof(rStatsInfoEnv)) -+ u4InBufLen = sizeof(rStatsInfoEnv); -+ -+ /* parse */ -+ u4NumOfInfo = *(UINT32 *) prInBuf; -+ u4RxErrBitmap = *(UINT32 *) (prInBuf + 4); -+ -+ /* print */ -+ for (u4InfoId = 0; u4InfoId < u4NumOfInfo; u4InfoId++) { -+ /* -+ use u4InBufLen, not sizeof(rStatsInfoEnv) -+ because the firmware version maybe not equal to driver version -+ */ -+ kalMemCopy(&rStatsInfoEnv, prInBuf + 8, u4InBufLen); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, rStatsInfoEnv.ucStaRecIdx); -+ if (prStaRec == NULL) -+ continue; -+ -+ DBGLOG(RX, INFO, " Display stats V%d.%d for [%pM]: %uB %ums\n", -+ prInfo->ucFwVer[0], prInfo->ucFwVer[1], -+ (prStaRec->aucMacAddr), (UINT32) sizeof(STATS_INFO_ENV_T), -+ prInfo->u4ReportSysTime); -+ DBGLOG(RX, INFO, "TPAM(0x%x)RTS(%u %u)BA(0x%x %u)OS(%u)OK(%u %u)ERR(%u %u %u %u %u %u %u)\n", -+ prInfo->ucTxParam, -+ prInfo->fgTxIsRtsUsed, prInfo->fgTxIsRtsEverUsed, -+ prInfo->ucTxAggBitmap, prInfo->ucTxPeerAggMaxSize, -+ (UINT32) prGlueInfo->rNetDevStats.tx_packets, -+ prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK, -+ prInfo->u4TxDataCntErr, prInfo->u4TxDataCntErrType[0], -+ prInfo->u4TxDataCntErrType[1], prInfo->u4TxDataCntErrType[2], -+ prInfo->u4TxDataCntErrType[3], prInfo->u4TxDataCntErrType[4], -+ prInfo->u4TxDataCntErrType[5])); -+ -+ DBGLOG(RX, INFO, "TRATE(%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", -+ prInfo->u4TxRateCntNonHT[0], prInfo->u4TxRateCntNonHT[1], -+ prInfo->u4TxRateCntNonHT[2], prInfo->u4TxRateCntNonHT[3], -+ prInfo->u4TxRateCntNonHT[4], prInfo->u4TxRateCntNonHT[5], -+ prInfo->u4TxRateCntNonHT[6], prInfo->u4TxRateCntNonHT[7], -+ prInfo->u4TxRateCntNonHT[8], prInfo->u4TxRateCntNonHT[9], -+ prInfo->u4TxRateCntNonHT[10], prInfo->u4TxRateCntNonHT[11], -+ prInfo->u4TxRateCntNonHT[12], prInfo->u4TxRateCntNonHT[13], -+ prInfo->u4TxRateCntNonHT[14], prInfo->u4TxRateCntNonHT[15], -+ prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1], -+ prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3], -+ prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5], -+ prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7])); -+ -+ DBGLOG(RX, INFO, " TREORDER (%u %u %u)\n", -+ prStaRec->u4RxReorderFallAheadCnt, -+ prStaRec->u4RxReorderFallBehindCnt, prStaRec->u4RxReorderHoleCnt); -+ -+ DBGLOG(RX, INFO, " RX(%u %u %u) BA(0x%x %u) OK(%u %u) ERR(%u)\n", -+ prInfo->ucRcvRcpi, prInfo->ucHwChanNum, prInfo->fgRxIsShortGI, -+ prInfo->ucRxAggBitmap, prInfo->ucRxAggMaxSize, -+ prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt, prInfo->u4RxDataCntErr); -+ -+ DBGLOG(RX, INFO, " RX Free MAC DESC(%u %u %u %u %u %u) Free HIF DESC(%u %u %u %u %u %u)\n", -+ prInfo->u4RxMacFreeDescCnt[0], prInfo->u4RxMacFreeDescCnt[1], -+ prInfo->u4RxMacFreeDescCnt[2], prInfo->u4RxMacFreeDescCnt[3], -+ prInfo->u4RxMacFreeDescCnt[4], prInfo->u4RxMacFreeDescCnt[5], -+ prInfo->u4RxHifFreeDescCnt[0], prInfo->u4RxHifFreeDescCnt[1], -+ prInfo->u4RxHifFreeDescCnt[2], prInfo->u4RxHifFreeDescCnt[3], -+ prInfo->u4RxHifFreeDescCnt[4], prInfo->u4RxHifFreeDescCnt[5])); -+ -+ DBGLOG(RX, INFO, " RCCK (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" -+ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0], -+ prInfo->u4RxRateCnt[0][1], prInfo->u4RxRateRetryCnt[0][1], -+ prInfo->u4RxRateCnt[0][2], prInfo->u4RxRateRetryCnt[0][2], -+ prInfo->u4RxRateCnt[0][3], prInfo->u4RxRateRetryCnt[0][3], -+ prInfo->u4RxRateCnt[0][4], prInfo->u4RxRateRetryCnt[0][4], -+ prInfo->u4RxRateCnt[0][5], prInfo->u4RxRateRetryCnt[0][5], -+ prInfo->u4RxRateCnt[0][6], prInfo->u4RxRateRetryCnt[0][6], -+ prInfo->u4RxRateCnt[0][7], prInfo->u4RxRateRetryCnt[0][7], -+ prInfo->u4RxRateCnt[0][8], prInfo->u4RxRateRetryCnt[0][8], -+ prInfo->u4RxRateCnt[0][9], prInfo->u4RxRateRetryCnt[0][9], -+ prInfo->u4RxRateCnt[0][10], prInfo->u4RxRateRetryCnt[0][10], -+ prInfo->u4RxRateCnt[0][11], prInfo->u4RxRateRetryCnt[0][11], -+ prInfo->u4RxRateCnt[0][12], prInfo->u4RxRateRetryCnt[0][12], -+ prInfo->u4RxRateCnt[0][13], prInfo->u4RxRateRetryCnt[0][13], -+ prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateRetryCnt[0][14], -+ prInfo->u4RxRateCnt[0][15], prInfo->u4RxRateRetryCnt[0][15])); -+ DBGLOG(RX, INFO, " ROFDM (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" -+ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[1][0], prInfo->u4RxRateRetryCnt[1][0], -+ prInfo->u4RxRateCnt[1][1], prInfo->u4RxRateRetryCnt[1][1], -+ prInfo->u4RxRateCnt[1][2], prInfo->u4RxRateRetryCnt[1][2], -+ prInfo->u4RxRateCnt[1][3], prInfo->u4RxRateRetryCnt[1][3], -+ prInfo->u4RxRateCnt[1][4], prInfo->u4RxRateRetryCnt[1][4], -+ prInfo->u4RxRateCnt[1][5], prInfo->u4RxRateRetryCnt[1][5], -+ prInfo->u4RxRateCnt[1][6], prInfo->u4RxRateRetryCnt[1][6], -+ prInfo->u4RxRateCnt[1][7], prInfo->u4RxRateRetryCnt[1][7], -+ prInfo->u4RxRateCnt[1][8], prInfo->u4RxRateRetryCnt[1][8], -+ prInfo->u4RxRateCnt[1][9], prInfo->u4RxRateRetryCnt[1][9], -+ prInfo->u4RxRateCnt[1][10], prInfo->u4RxRateRetryCnt[1][10], -+ prInfo->u4RxRateCnt[1][11], prInfo->u4RxRateRetryCnt[1][11], -+ prInfo->u4RxRateCnt[1][12], prInfo->u4RxRateRetryCnt[1][12], -+ prInfo->u4RxRateCnt[1][13], prInfo->u4RxRateRetryCnt[1][13], -+ prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateRetryCnt[1][14], -+ prInfo->u4RxRateCnt[1][15], prInfo->u4RxRateRetryCnt[1][15])); -+ DBGLOG(RX, INFO, " RHT (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" -+ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[2][0], prInfo->u4RxRateRetryCnt[2][0], -+ prInfo->u4RxRateCnt[2][1], prInfo->u4RxRateRetryCnt[2][1], -+ prInfo->u4RxRateCnt[2][2], prInfo->u4RxRateRetryCnt[2][2], -+ prInfo->u4RxRateCnt[2][3], prInfo->u4RxRateRetryCnt[2][3], -+ prInfo->u4RxRateCnt[2][4], prInfo->u4RxRateRetryCnt[2][4], -+ prInfo->u4RxRateCnt[2][5], prInfo->u4RxRateRetryCnt[2][5], -+ prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateRetryCnt[2][6], -+ prInfo->u4RxRateCnt[2][7], prInfo->u4RxRateRetryCnt[2][7], -+ prInfo->u4RxRateCnt[2][8], prInfo->u4RxRateRetryCnt[2][8], -+ prInfo->u4RxRateCnt[2][9], prInfo->u4RxRateRetryCnt[2][9], -+ prInfo->u4RxRateCnt[2][10], prInfo->u4RxRateRetryCnt[2][10], -+ prInfo->u4RxRateCnt[2][11], prInfo->u4RxRateRetryCnt[2][11], -+ prInfo->u4RxRateCnt[2][12], prInfo->u4RxRateRetryCnt[2][12], -+ prInfo->u4RxRateCnt[2][13], prInfo->u4RxRateRetryCnt[2][13], -+ prInfo->u4RxRateCnt[2][14], prInfo->u4RxRateRetryCnt[2][14], -+ prInfo->u4RxRateCnt[2][15], prInfo->u4RxRateRetryCnt[2][15])); -+ -+ /* delay from HIF to MAC */ -+ DBGLOG(RX, INFO, " StayIntH2M us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prInfo->u4StayIntMinH2M[0], prInfo->u4StayIntAvgH2M[0], -+ prInfo->u4StayIntMaxH2M[0], -+ prInfo->u4StayIntMinH2M[1], prInfo->u4StayIntAvgH2M[1], -+ prInfo->u4StayIntMaxH2M[1], -+ prInfo->u4StayIntMinH2M[2], prInfo->u4StayIntAvgH2M[2], -+ prInfo->u4StayIntMaxH2M[2])); -+ /* delay from MAC to TXDONE */ -+ DBGLOG(RX, INFO, " AirTime us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prInfo->u4AirDelayMin[0] << 5, prInfo->u4AirDelayAvg[0] << 5, -+ prInfo->u4AirDelayMax[0] << 5, -+ prInfo->u4AirDelayMin[1] << 5, prInfo->u4AirDelayAvg[1] << 5, -+ prInfo->u4AirDelayMax[1] << 5, -+ prInfo->u4TxDataCntAll, (prInfo->u4AirDelayAvg[2] << 5) / (prInfo->u4TxDataCntAll), -+ (prInfo->u4AirDelayAvg[2] << 5) / 400000)); -+ prAdapter->u4AirDelayTotal = (prInfo->u4AirDelayTotal << 5) / 400000; -+ /* delay from HIF to TXDONE */ -+ DBGLOG(RX, INFO, " StayInt us (%u %u %u_%u) (%u %u %u_%u) (%u %u %u_%u)\n", -+ prInfo->u4StayIntMin[0], prInfo->u4StayIntAvg[0], -+ prInfo->u4StayIntMax[0], prInfo->u4StayIntMaxSysTime[0], -+ prInfo->u4StayIntMin[1], prInfo->u4StayIntAvg[1], -+ prInfo->u4StayIntMax[1], prInfo->u4StayIntMaxSysTime[1], -+ prInfo->u4StayIntMin[2], prInfo->u4StayIntAvg[2], -+ prInfo->u4StayIntMax[2], prInfo->u4StayIntMaxSysTime[2])); -+ /* delay from Driver to TXDONE */ -+ DBGLOG(RX, INFO, " StayIntD2T us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prInfo->u4StayIntMinD2T[0], prInfo->u4StayIntAvgD2T[0], -+ prInfo->u4StayIntMaxD2T[0], -+ prInfo->u4StayIntMinD2T[1], prInfo->u4StayIntAvgD2T[1], -+ prInfo->u4StayIntMaxD2T[1], -+ prInfo->u4StayIntMinD2T[2], prInfo->u4StayIntAvgD2T[2], -+ prInfo->u4StayIntMaxD2T[2])); -+ -+ /* delay from RXDONE to HIF */ -+ DBGLOG(RX, INFO, " StayIntR_M2H us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prInfo->u4StayIntMinRx[0], prInfo->u4StayIntAvgRx[0], -+ prInfo->u4StayIntMaxRx[0], -+ prInfo->u4StayIntMinRx[1], prInfo->u4StayIntAvgRx[1], -+ prInfo->u4StayIntMaxRx[1], -+ prInfo->u4StayIntMinRx[2], prInfo->u4StayIntAvgRx[2], prInfo->u4StayIntMaxRx[2])); -+ /* delay from HIF to OS */ -+ DBGLOG(RX, INFO, " StayIntR_H2D us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prStaRec->u4StayIntMinRx[0], prStaRec->u4StayIntAvgRx[0], -+ prStaRec->u4StayIntMaxRx[0], -+ prStaRec->u4StayIntMinRx[1], prStaRec->u4StayIntAvgRx[1], -+ prStaRec->u4StayIntMaxRx[1], -+ prStaRec->u4StayIntMinRx[2], prStaRec->u4StayIntAvgRx[2], -+ prStaRec->u4StayIntMaxRx[2])); -+ -+ /* count based on delay from OS to HIF */ -+ DBGLOG(RX, INFO, " StayCntD2H unit:%dms (%d %d %d %d)\n", -+ STATS_STAY_INT_D2H_CONST, -+ prInfo->u4StayIntD2HByConst[0], prInfo->u4StayIntD2HByConst[1], -+ prInfo->u4StayIntD2HByConst[2], prInfo->u4StayIntD2HByConst[3]); -+ -+ /* count based on different delay from HIF to TX DONE */ -+ DBGLOG(RX, INFO, " StayCnt unit:%dms (%d %d %d %d)\n", -+ STATS_STAY_INT_CONST, -+ prInfo->u4StayIntByConst[0], prInfo->u4StayIntByConst[1], -+ prInfo->u4StayIntByConst[2], prInfo->u4StayIntByConst[3]); -+ DBGLOG(RX, INFO, " StayCnt (%d~%d:%d) (%d~%d:%d) (%d~%d:%d) (%d~%d:%d) (%d~:%d)\n", -+ 0, prInfo->u4StayIntMaxPast / 4, prInfo->u4StayIntCnt[0], -+ prInfo->u4StayIntMaxPast / 4, prInfo->u4StayIntMaxPast / 2, prInfo->u4StayIntCnt[1], -+ prInfo->u4StayIntMaxPast / 2, prInfo->u4StayIntMaxPast * 3 / 4, -+ prInfo->u4StayIntCnt[2], prInfo->u4StayIntMaxPast * 3 / 4, prInfo->u4StayIntMaxPast, -+ prInfo->u4StayIntCnt[3], prInfo->u4StayIntMaxPast, prInfo->u4StayIntCnt[4])); -+ -+ /* channel idle time */ -+ DBGLOG(RX, INFO, " Idle Time (slot): (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n", -+ prInfo->au4ChanIdleCnt[0], prInfo->au4ChanIdleCnt[1], -+ prInfo->au4ChanIdleCnt[2], prInfo->au4ChanIdleCnt[3], -+ prInfo->au4ChanIdleCnt[4], prInfo->au4ChanIdleCnt[5], -+ prInfo->au4ChanIdleCnt[6], prInfo->au4ChanIdleCnt[7], -+ prInfo->au4ChanIdleCnt[8], prInfo->au4ChanIdleCnt[9])); -+ -+ /* BT coex */ -+ DBGLOG(RX, INFO, " BT coex (0x%x)\n", prInfo->u4BtContUseTime); -+ -+ /* others */ -+ DBGLOG(RX, INFO, " OTHER (%u) (%u) (%u) (%u) (%u) (%ums) (%uus)\n", -+ prInfo->u4RxFifoFullCnt, prAdapter->ucScanTime, -+ prInfo->u4NumOfChanChange, prStaRec->u4NumOfNoTxQuota, -+ prInfo->ucNumOfPsChange, prInfo->u4PsIntMax, u4DrvOwnMax / 1000); -+ -+ /* reset */ -+ kalMemZero(prStaRec->u4StayIntMinRx, sizeof(prStaRec->u4StayIntMinRx)); -+ kalMemZero(prStaRec->u4StayIntAvgRx, sizeof(prStaRec->u4StayIntAvgRx)); -+ kalMemZero(prStaRec->u4StayIntMaxRx, sizeof(prStaRec->u4StayIntMaxRx)); -+ prStaRec->u4StatsRxPassToOsCnt = 0; -+ prStaRec->u4RxReorderFallAheadCnt = 0; -+ prStaRec->u4RxReorderFallBehindCnt = 0; -+ prStaRec->u4RxReorderHoleCnt = 0; -+ } -+ -+ STATS_DRIVER_OWN_RESET(); -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to request firmware to feedback statistics. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static WLAN_STATUS -+statsInfoEnvRequest(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ STATS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* sanity check */ -+ if (fgIsUnderSuspend == true) -+ return WLAN_STATUS_SUCCESS; /* do not request stats after early suspend */ -+ -+ /* init command buffer */ -+ prCmdContent = (STATS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = STATS_CORE_CMD_ENV_REQUEST; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_STATS, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(STATS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(RX, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return WLAN_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(RX, INFO, "%s cmd ok.\n", __func__); -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/******************************************************************************* -+* P U B L I C F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to handle any statistics event. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID statsEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ UINT32 u4EventId; -+ -+ /* sanity check */ -+/* DBGLOG(RX, INFO, */ -+/* (" %s: Rcv a event\n", __FUNCTION__)); */ -+ -+ if ((prGlueInfo == NULL) || (prInBuf == NULL)) -+ return; /* shall not be here */ -+ -+ /* handle */ -+ u4EventId = *(UINT32 *) prInBuf; -+ u4InBufLen -= 4; -+ -+/* DBGLOG(RX, INFO, */ -+/* (" %s: Rcv a event: %d\n", __FUNCTION__, u4EventId)); */ -+ -+ switch (u4EventId) { -+ case STATS_HOST_EVENT_ENV_REPORT: -+ statsInfoEnvDisplay(prGlueInfo, prInBuf + 4, u4InBufLen); -+ break; -+ -+ default: -+ break; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to detect if we can request firmware to feedback statistics. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] ucStaRecIndex The station index -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID statsEnvReportDetect(ADAPTER_T *prAdapter, UINT8 ucStaRecIndex) -+{ -+ STA_RECORD_T *prStaRec; -+ OS_SYSTIME rCurTime; -+ STATS_CMD_CORE_T rCmd; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); -+ if (prStaRec == NULL) -+ return; -+ -+ prStaRec->u4StatsEnvTxCnt++; -+ GET_CURRENT_SYSTIME(&rCurTime); -+ -+ if (prStaRec->rStatsEnvTxPeriodLastTime == 0) { -+ prStaRec->rStatsEnvTxLastTime = rCurTime; -+ prStaRec->rStatsEnvTxPeriodLastTime = rCurTime; -+ return; -+ } -+ -+ if (prStaRec->u4StatsEnvTxCnt > STATS_ENV_TX_CNT_REPORT_TRIGGER) { -+ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rStatsEnvTxLastTime, -+ SEC_TO_SYSTIME(STATS_ENV_TX_CNT_REPORT_TRIGGER_SEC))) { -+ rCmd.ucStaRecIdx = ucStaRecIndex; -+ statsInfoEnvRequest(prAdapter, &rCmd, 0, NULL); -+ -+ prStaRec->rStatsEnvTxLastTime = rCurTime; -+ prStaRec->rStatsEnvTxPeriodLastTime = rCurTime; -+ prStaRec->u4StatsEnvTxCnt = 0; -+ return; -+ } -+ } -+ -+ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rStatsEnvTxPeriodLastTime, SEC_TO_SYSTIME(STATS_ENV_TIMEOUT_SEC))) { -+ rCmd.ucStaRecIdx = ucStaRecIndex; -+ statsInfoEnvRequest(prAdapter, &rCmd, 0, NULL); -+ -+ prStaRec->rStatsEnvTxPeriodLastTime = rCurTime; -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to handle rx done. -+* -+* \param[in] prStaRec Pointer to the STA_RECORD_T structure -+* \param[in] prSwRfb Pointer to the received packet -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID StatsEnvRxDone(STA_RECORD_T *prStaRec, SW_RFB_T *prSwRfb) -+{ -+ UINT32 u4LenId; -+ UINT32 u4CurTime, u4DifTime; -+ -+ /* sanity check */ -+ if (prStaRec == NULL) -+ return; -+ -+ /* stats: rx done count */ -+ prStaRec->u4StatsRxPassToOsCnt++; -+ -+ /* get length partition ID */ -+ u4LenId = 0; -+ if (prSwRfb->u2PacketLen < STATS_STAY_INT_BYTE_THRESHOLD) { -+ u4LenId = 0; -+ } else { -+ if ((STATS_STAY_INT_BYTE_THRESHOLD <= prSwRfb->u2PacketLen) && -+ (prSwRfb->u2PacketLen < (STATS_STAY_INT_BYTE_THRESHOLD << 1))) { -+ u4LenId = 1; -+ } else -+ u4LenId = 2; -+ } -+ -+ /* stats: rx delay */ -+ u4CurTime = kalGetTimeTick(); -+ -+ if ((u4CurTime > prSwRfb->rRxTime) && (prSwRfb->rRxTime != 0)) { -+ u4DifTime = u4CurTime - prSwRfb->rRxTime; -+ -+ if (prStaRec->u4StayIntMinRx[u4LenId] == 0) /* impossible */ -+ prStaRec->u4StayIntMinRx[u4LenId] = 0xffffffff; -+ -+ if (u4DifTime > prStaRec->u4StayIntMaxRx[u4LenId]) -+ prStaRec->u4StayIntMaxRx[u4LenId] = u4DifTime; -+ else if (u4DifTime < prStaRec->u4StayIntMinRx[u4LenId]) -+ prStaRec->u4StayIntMinRx[u4LenId] = u4DifTime; -+ -+ prStaRec->u4StayIntAvgRx[u4LenId] += u4DifTime; -+ if (prStaRec->u4StayIntAvgRx[u4LenId] != u4DifTime) -+ prStaRec->u4StayIntAvgRx[u4LenId] >>= 1; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to handle rx done. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_64 StatsEnvTimeGet(VOID) -+{ -+ /* TODO: use better API to get time to save time, jiffies unit is 10ms, too large */ -+ -+/* struct timeval tv; */ -+ -+/* do_gettimeofday(&tv); */ -+/* return tv.tv_usec + tv.tv_sec * (UINT_64)1000000; */ -+ -+ UINT_64 u8Clk; -+/* UINT32 *pClk = &u8Clk; */ -+ -+ u8Clk = sched_clock(); /* unit: naro seconds */ -+/* printk(" sched_clock() = %x %x %u\n", pClk[0], pClk[1], sizeof(jiffies)); */ -+ -+ return (UINT_64) u8Clk; /* sched_clock *//* jiffies size = 4B */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to handle rx done. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID StatsEnvTxTime2Hif(MSDU_INFO_T *prMsduInfo, HIF_TX_HEADER_T *prHwTxHeader) -+{ -+ UINT_64 u8SysTime, u8SysTimeIn; -+ UINT32 u4TimeDiff; -+ -+ u8SysTime = StatsEnvTimeGet(); -+ u8SysTimeIn = GLUE_GET_PKT_XTIME(prMsduInfo->prPacket); -+ -+/* printk(" hif: 0x%x %u %u %u\n", */ -+/* prMsduInfo->prPacket, StatsEnvTimeGet(), u8SysTime, GLUE_GET_PKT_XTIME(prMsduInfo->prPacket)); */ -+ -+ if ((u8SysTimeIn > 0) && (u8SysTime > u8SysTimeIn)) { -+ u8SysTime = u8SysTime - u8SysTimeIn; -+ u4TimeDiff = (UINT32) u8SysTime; -+ u4TimeDiff = u4TimeDiff / 1000; /* ns to us */ -+ -+ /* pass the delay between OS to us and we to HIF */ -+ if (u4TimeDiff > 0xFFFF) -+ *(UINT16 *) prHwTxHeader->aucReserved = (UINT16) 0xFFFF; /* 65535 us */ -+ else -+ *(UINT16 *) prHwTxHeader->aucReserved = (UINT16) u4TimeDiff; -+ -+/* printk(" u4TimeDiff: %u\n", u4TimeDiff); */ -+ } else { -+ prHwTxHeader->aucReserved[0] = 0; -+ prHwTxHeader->aucReserved[1] = 0; -+ } -+} -+ -+static VOID statsParsePktInfo(PUINT_8 pucPkt, UINT_8 status, UINT_8 eventType, P_MSDU_INFO_T prMsduInfo) -+{ -+ /* get ethernet protocol */ -+ UINT_16 u2EtherType = (pucPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pucPkt[ETH_TYPE_LEN_OFFSET + 1]); -+ PUINT_8 pucEthBody = &pucPkt[ETH_HLEN]; -+ -+ switch (u2EtherType) { -+ case ETH_P_ARP: -+ { -+ UINT_16 u2OpCode = (pucEthBody[6] << 8) | pucEthBody[7]; -+ if (eventType == EVENT_TX) -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ if ((su2TxDoneCfg & CFG_ARP) == 0) -+ break; -+ -+ switch (eventType) { -+ case EVENT_RX: -+ if (u2OpCode == ARP_PRO_REQ) -+ DBGLOG(RX, INFO, " Arp Req From IP: %d.%d.%d.%d\n", -+ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); -+ else if (u2OpCode == ARP_PRO_RSP) -+ DBGLOG(RX, INFO, " Arp Rsp from IP: %d.%d.%d.%d\n", -+ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); -+ break; -+ case EVENT_TX: -+ if (u2OpCode == ARP_PRO_REQ) -+ DBGLOG(TX, INFO, " Arp Req to IP: %d.%d.%d.%d\n", -+ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); -+ else if (u2OpCode == ARP_PRO_RSP) -+ DBGLOG(TX, INFO, " Arp Rsp to IP: %d.%d.%d.%d\n", -+ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ break; -+ case EVENT_TX_DONE: -+ if (u2OpCode == ARP_PRO_REQ) -+ DBGLOG(TX, INFO, " Arp Req to IP: %d.%d.%d.%d\n", status, -+ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); -+ else if (u2OpCode == ARP_PRO_RSP) -+ DBGLOG(TX, INFO, " Arp Rsp to IP: %d.%d.%d.%d\n", status, -+ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); -+ break; -+ } -+ break; -+ } -+ case ETH_P_IP: -+ { -+ UINT_8 ucIpProto = pucEthBody[9]; /* IP header without options */ -+ UINT_8 ucIpVersion = (pucEthBody[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; -+ UINT_16 u2IpId = pucEthBody[4]<<8 | pucEthBody[5]; -+ -+ if (ucIpVersion != IPVERSION) -+ break; -+ -+ switch (ucIpProto) { -+ case IP_PRO_ICMP: -+ { -+ /* the number of ICMP packets is seldom so we print log here */ -+ UINT_8 ucIcmpType; -+ UINT_16 u2IcmpId, u2IcmpSeq; -+ PUINT_8 pucIcmp = &pucEthBody[20]; -+ -+ ucIcmpType = pucIcmp[0]; -+ /* don't log network unreachable packet */ -+ if (((su2TxDoneCfg & CFG_ICMP) == 0) || ucIcmpType == 3) -+ break; -+ u2IcmpId = *(UINT_16 *) &pucIcmp[4]; -+ u2IcmpSeq = *(UINT_16 *) &pucIcmp[6]; -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " ICMP: Type %d, Id BE 0x%04x, Seq BE 0x%04x\n", -+ ucIcmpType, u2IcmpId, u2IcmpSeq); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " ICMP: Type %d, Id 0x04%x, Seq BE 0x%04x\n", -+ ucIcmpType, u2IcmpId, u2IcmpSeq); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " Type %d, Id 0x%04x, Seq 0x%04x\n", -+ status, ucIcmpType, u2IcmpId, u2IcmpSeq); -+ break; -+ } -+ break; -+ } -+ case IP_PRO_UDP: -+ { -+ /* the number of DHCP packets is seldom so we print log here */ -+ PUINT_8 pucUdp = &pucEthBody[20]; -+ PUINT_8 pucUdpPayload = &pucUdp[8]; -+ UINT_16 u2UdpDstPort; -+ UINT_16 u2UdpSrcPort; -+ -+ u2UdpDstPort = (pucUdp[2] << 8) | pucUdp[3]; -+ u2UdpSrcPort = (pucUdp[0] << 8) | pucUdp[1]; -+ /* dhcp */ -+ if ((u2UdpDstPort == UDP_PORT_DHCPS) || (u2UdpDstPort == UDP_PORT_DHCPC)) { -+ UINT_32 u4TransID = pucUdpPayload[4]<<24 | pucUdpPayload[5]<<16 | -+ pucUdpPayload[6]<<8 | pucUdpPayload[7]; -+ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n", -+ u2IpId, pucUdpPayload[0], u4TransID); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n", -+ u2IpId, pucUdpPayload[0], u4TransID); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, -+ " DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n", -+ status, u2IpId, pucUdpPayload[0], u4TransID); -+ break; -+ } -+ } else if (u2UdpDstPort == UDP_PORT_DNS) { /* tx dns */ -+ UINT_16 u2TransId = (pucUdpPayload[0] << 8) | pucUdpPayload[1]; -+ if (eventType == EVENT_TX) -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ if ((su2TxDoneCfg & CFG_DNS) == 0) -+ break; -+ if (eventType == EVENT_TX) { -+ DBGLOG(TX, INFO, " DNS: IPID 0x%02x, TransID 0x%04x\n", u2IpId, u2TransId); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ } else if (eventType == EVENT_TX_DONE) -+ DBGLOG(TX, INFO, " DNS: IPID 0x%02x, TransID 0x%04x\n", -+ status, u2IpId, u2TransId); -+ } else if (u2UdpSrcPort == UDP_PORT_DNS && eventType == EVENT_RX) { /* rx dns */ -+ UINT_16 u2TransId = (pucUdpPayload[0] << 8) | pucUdpPayload[1]; -+ -+ if ((su2TxDoneCfg & CFG_DNS) == 0) -+ break; -+ DBGLOG(RX, INFO, " DNS: IPID 0x%02x, TransID 0x%04x\n", u2IpId, u2TransId); -+ } else if ((su2TxDoneCfg & CFG_UDP) != 0) { -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " UDP: IPID 0x%04x\n", u2IpId); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " UDP: IPID 0x%04x\n", u2IpId); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " UDP: IPID 0x%04x\n", status, u2IpId); -+ break; -+ } -+ } -+ break; -+ } -+ case IP_PRO_TCP: -+ if ((su2TxDoneCfg & CFG_TCP) == 0) -+ break; -+ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " TCP: IPID 0x%04x\n", u2IpId); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " TCP: IPID 0x%04x\n", u2IpId); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " TCP: IPID 0x%04x\n", status, u2IpId); -+ break; -+ } -+ break; -+ } -+ break; -+ } -+ case ETH_P_PRE_1X: -+ DBGLOG(RX, INFO, "pre-1x\n"); -+ case ETH_P_1X: -+ { -+ PUINT_8 pucEapol = pucEthBody; -+ UINT_8 ucEapolType = pucEapol[1]; -+ -+ switch (ucEapolType) { -+ case 0: /* eap packet */ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " EAP Packet: code %d, id %d, type %d\n", -+ pucEapol[4], pucEapol[5], pucEapol[7]); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d\n", -+ pucEapol[4], pucEapol[5], pucEapol[7]); -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d\n", -+ status, pucEapol[4], pucEapol[5], pucEapol[7]); -+ break; -+ } -+ break; -+ case 1: /* eapol start */ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " EAPOL: start\n"); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " EAPOL: start\n"); -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " EAPOL: start\n", status); -+ break; -+ } -+ break; -+ case 3: /* key */ -+ { -+ UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6]; -+ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, -+ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n", -+ u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], -+ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, -+ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n", -+ u2KeyInfo, -+ pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], -+ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]); -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, -+ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n", -+ status, u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], -+ pucEapol[20], pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]); -+ break; -+ } -+ -+ break; -+ } -+ } -+ break; -+ } -+ case ETH_WPI_1X: -+ { -+ UINT_8 ucSubType = pucEthBody[3]; /* sub type filed*/ -+ UINT_16 u2Length = *(PUINT_16)&pucEthBody[6]; -+ UINT_16 u2Seq = *(PUINT_16)&pucEthBody[8]; -+ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", -+ ucSubType, u2Length, u2Seq); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", -+ ucSubType, u2Length, u2Seq); -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", -+ status, ucSubType, u2Length, u2Seq); -+ break; -+ } -+ break; -+ } -+ } -+} -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display rx packet information. -+* -+* \param[in] pPkt Pointer to the packet -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID StatsRxPktInfoDisplay(UINT_8 *pPkt) -+{ -+ statsParsePktInfo(pPkt, 0, EVENT_RX, NULL); -+#if 0 /* carefully! too many ARP */ -+ if (pucIpHdr[0] == 0x00) { /* ARP */ -+ UINT_8 *pucDstIp = (UINT_8 *) pucIpHdr; -+ -+ if (pucDstIp[7] == ARP_PRO_REQ) { -+ DBGLOG(RX, TRACE, " OS rx a arp req from %d.%d.%d.%d\n", -+ pucDstIp[14], pucDstIp[15], pucDstIp[16], pucDstIp[17]); -+ } else if (pucDstIp[7] == ARP_PRO_RSP) { -+ DBGLOG(RX, TRACE, " OS rx a arp rsp from %d.%d.%d.%d\n", -+ pucDstIp[24], pucDstIp[25], pucDstIp[26], pucDstIp[27]); -+ } -+ } -+#endif -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display tx packet information. -+* -+* \param[in] pPkt Pointer to the packet -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID StatsTxPktCallBack(UINT_8 *pPkt, P_MSDU_INFO_T prMsduInfo) -+{ -+ UINT_16 u2EtherTypeLen; -+ -+ u2EtherTypeLen = (pPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pPkt[ETH_TYPE_LEN_OFFSET + 1]); -+ statsParsePktInfo(pPkt, 0, EVENT_TX, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to handle display tx packet tx done information. -+* -+* \param[in] pPkt Pointer to the packet -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID StatsTxPktDoneInfoDisplay(ADAPTER_T *prAdapter, UINT_8 *pucEvtBuf) -+{ -+ EVENT_TX_DONE_STATUS_T *prTxDone; -+ -+ prTxDone = (EVENT_TX_DONE_STATUS_T *) pucEvtBuf; -+ /* -+ * Why 65 Bytes: -+ * 8B + wlanheader(40B) + hif_tx_header(16B) + 6B + 6B(LLC) - 12B -+ */ -+ statsParsePktInfo(&prTxDone->aucPktBuf[64], prTxDone->ucStatus, EVENT_TX_DONE, NULL); -+} -+ -+VOID StatsSetCfgTxDone(UINT_16 u2Cfg, BOOLEAN fgSet) -+{ -+ if (fgSet) -+ su2TxDoneCfg |= u2Cfg; -+ else -+ su2TxDoneCfg &= ~u2Cfg; -+} -+ -+UINT_16 StatsGetCfgTxDone(VOID) -+{ -+ return su2TxDoneCfg; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c -new file mode 100644 -index 0000000000000..67eccbda9fa8f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c -@@ -0,0 +1,1170 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/swcr.c#1 -+*/ -+ -+/*! \file "swcr.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: swcr.c -+ * -+ * 06 04 2012 tsaiyuan.hsu -+ * [WCXRP00001249] [ALPS.ICS] Daily build warning on "wlan/mgmt/swcr.c#1" -+ * resolve build waring for "WNM_UNIT_TEST not defined". -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 11 22 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * keep debug counter setting after wake up. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Fix compiling warning -+ * -+ * 11 11 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * fix debug counters of rx in driver. -+ * -+ * 11 11 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters of bb and ar for xlog. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Modify the QM xlog level and remove LOG_FUNC. -+ * -+ * 11 08 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters, eCurPsProf, for PS. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG -+ * -+ * 08 31 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * remove obsolete code. -+ * -+ * 08 15 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * add swcr in driver reg, 0x9fxx0000, to disable roaming . -+ * -+ * 05 11 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Fix dest type when GO packet copying. -+ * -+ * 05 09 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Check free number before copying broadcast packet. -+ * -+ * 04 14 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Check the SW RFB free. Fix the compile warning.. -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 03 28 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Fix Klockwork warning. -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 01 11 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * Add swcr for test. -+ * -+* -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_SUPPORT_SWCR -+ -+#ifdef __GNUC__ -+#pragma GCC diagnostic ignored "-Wformat" -+#endif -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if 0 -+SWCR_MOD_MAP_ENTRY_T g_arSwCrAllMaps[] = { -+ {SWCR_MAP_NUM(g_arRlmArSwCrMap), g_arRlmArSwCrMap}, /* 0x00nn */ -+ {0, NULL} -+}; -+#endif -+ -+UINT_32 g_au4SwCr[SWCR_CR_NUM]; /*: 0: command other: data */ -+ -+/* JB mDNS Filter*/ -+UINT_32 g_u4mDNSRXFilter = 0; /* [31] 0: stop 1: start, [3] IPv6 [2] IPv4 */ -+ -+static TIMER_T g_rSwcrDebugTimer; -+static BOOLEAN g_fgSwcrDebugTimer = FALSE; -+static UINT_32 g_u4SwcrDebugCheckTimeout; -+static ENUM_SWCR_DBG_TYPE_T g_ucSwcrDebugCheckType; -+static UINT_32 g_u4SwcrDebugFrameDumpType; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#define TEST_PS 1 -+ -+static const PFN_CMD_RW_T g_arSwCtrlCmd[] = { -+ swCtrlCmdCategory0, -+ swCtrlCmdCategory1 -+#if TEST_PS -+ , testPsCmdCategory0, testPsCmdCategory1 -+#endif -+#if CFG_SUPPORT_802_11V -+#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (WNM_UNIT_TEST == 1) -+ , testWNMCmdCategory0 -+#endif -+#endif -+}; -+ -+const PFN_SWCR_RW_T g_arSwCrModHandle[] = { -+ swCtrlSwCr, -+ NULL -+}; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+enum { -+ SWCTRL_MAGIC, -+ SWCTRL_DEBUG, -+ SWCTRL_WIFI_VAR, -+ SWCTRL_ENABLE_INT, -+ SWCTRL_DISABLE_INT, -+ SWCTRL_TXM_INFO, -+ SWCTRL_RXM_INFO, -+ SWCTRL_DUMP_BSS, -+ SWCTRL_QM_INFO, -+ SWCTRL_DUMP_ALL_QUEUE_LEN, -+ SWCTRL_DUMP_MEM, -+ SWCTRL_TX_CTRL_INFO, -+ SWCTRL_DUMP_QUEUE, -+ SWCTRL_DUMP_QM_DBG_CNT, -+ SWCTRL_QM_DBG_CNT, -+ SWCTRL_RX_PKTS_DUMP, -+ SWCTRL_RX_MDNS_FILTER, -+ SWCTRL_CATA0_INDEX_NUM -+}; -+ -+enum { -+ SWCTRL_STA_INFO, -+ SWCTRL_DUMP_STA, -+ SWCTRL_STA_QUE_INFO, -+ SWCTRL_CATA1_INDEX_NUM -+}; -+ -+/* JB mDNS Filter*/ -+#define RX_MDNS_FILTER_START (1<<31) -+#define RX_MDNS_FILTER_IPV4 (1<<2) -+#define RX_MDNS_FILTER_IPV6 (1<<3) -+typedef enum _ENUM_SWCR_RX_MDNS_FILTER_CMD_T { -+ SWCR_RX_MDNS_FILTER_CMD_STOP = 0, -+ SWCR_RX_MDNS_FILTER_CMD_START, -+ SWCR_RX_MDNS_FILTER_CMD_ADD, -+ SWCR_RX_MDNS_FILTER_CMD_REMOVE, -+ SWCR_RX_MDNS_FILTER_NUM -+} ENUM_SWCR_RX_MDNS_FILTER_CMD_T; -+ -+#if TEST_PS -+enum { -+ TEST_PS_MAGIC, -+ TEST_PS_SETUP_BSS, -+ TEST_PS_ENABLE_BEACON, -+ TEST_PS_TRIGGER_BMC, -+ TEST_PS_SEND_NULL, -+ TEST_PS_BUFFER_BMC, -+ TEST_PS_UPDATE_BEACON, -+ TEST_PS_CATA0_INDEX_NUM -+}; -+ -+enum { -+ TEST_PS_STA_PS, -+ TEST_PS_STA_ENTER_PS, -+ TEST_PS_STA_EXIT_PS, -+ TEST_PS_STA_TRIGGER_PSPOLL, -+ TEST_PS_STA_TRIGGER_FRAME, -+ TEST_PS_CATA1_INDEX_NUM -+}; -+#endif -+ -+#if CFG_SUPPORT_802_11V -+#if WNM_UNIT_TEST -+enum { -+ TEST_WNM_TIMING_MEAS, -+ TEST_WNM_CATA0_INDEX_NUM -+}; -+#endif -+#endif -+ -+#define _SWCTRL_MAGIC 0x66201642 -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+void dumpQueue(P_ADAPTER_T prAdapter) -+{ -+ -+ P_TX_CTRL_T prTxCtrl; -+ P_QUE_MGT_T prQM; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 i; -+ UINT_32 j; -+ -+ DEBUGFUNC("dumpQueue"); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prQM = &prAdapter->rQM; -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ for (i = TC0_INDEX; i <= TC5_INDEX; i++) { -+ DBGLOG(SW4, INFO, "TC %u\n", i); -+ DBGLOG(SW4, INFO, "Max %u Free %u\n", -+ prTxCtrl->rTc.aucMaxNumOfBuffer[i], prTxCtrl->rTc.aucFreeBufferCount[i]); -+ -+ DBGLOG(SW4, INFO, "Average %u minReserved %u CurrentTcResource %u GuaranteedTcResource %u\n", -+ QM_GET_TX_QUEUE_LEN(prAdapter, i), -+ prQM->au4MinReservedTcResource[i], -+ prQM->au4CurrentTcResource[i], prQM->au4GuaranteedTcResource[i]); -+ -+ } -+ -+ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) { -+ DBGLOG(SW4, INFO, -+ "TC %u HeadStaIdx %u ForwardCount %u\n", i, prQM->au4HeadStaRecIndex[i], -+ prQM->au4ForwardCount[i]); -+ } -+ -+ DBGLOG(SW4, INFO, "BMC or unknown TxQueue Len %u\n", prQM->arTxQueue[0].u4NumElem); -+ DBGLOG(SW4, INFO, "Pending %d\n", prGlueInfo->i4TxPendingFrameNum); -+ DBGLOG(SW4, INFO, "Pending Security %d\n", prGlueInfo->i4TxPendingSecurityFrameNum); -+#if defined(LINUX) -+ for (i = 0; i < 4; i++) { -+ for (j = 0; j < CFG_MAX_TXQ_NUM; j++) { -+ DBGLOG(SW4, INFO, -+ "Pending Q[%u][%u] %d\n", i, j, prGlueInfo->ai4TxPendingFrameNumPerQueue[i][j]); -+ } -+ } -+#endif -+ -+ DBGLOG(SW4, INFO, " rFreeSwRfbList %u\n", prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); -+ DBGLOG(SW4, INFO, " rReceivedRfbList %u\n", prAdapter->rRxCtrl.rReceivedRfbList.u4NumElem); -+ DBGLOG(SW4, INFO, " rIndicatedRfbList %u\n", prAdapter->rRxCtrl.rIndicatedRfbList.u4NumElem); -+ DBGLOG(SW4, INFO, " ucNumIndPacket %u\n", prAdapter->rRxCtrl.ucNumIndPacket); -+ DBGLOG(SW4, INFO, " ucNumRetainedPacket %u\n", prAdapter->rRxCtrl.ucNumRetainedPacket); -+ -+} -+ -+void dumpSTA(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec) -+{ -+ UINT_8 ucWTEntry; -+ UINT_32 i; -+ P_BSS_INFO_T prBssInfo; -+ -+ DEBUGFUNC("dumpSTA"); -+ -+ ASSERT(prStaRec); -+ ucWTEntry = prStaRec->ucWTEntry; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ ASSERT(prBssInfo); -+ -+ DBGLOG(SW4, INFO, "Mac address: %pM Rcpi %u" "\n", prStaRec->aucMacAddr, prStaRec->ucRCPI); -+ -+ DBGLOG(SW4, INFO, "Idx %u Wtbl %u Used %u State %u Bss Phy 0x%x Sta DesiredPhy 0x%x\n", -+ prStaRec->ucIndex, ucWTEntry, -+ prStaRec->fgIsInUse, prStaRec->ucStaState, -+ prBssInfo->ucPhyTypeSet, prStaRec->ucDesiredPhyTypeSet); -+ -+ DBGLOG(SW4, INFO, "Sta Operation 0x%x DesiredNontHtRateSet 0x%x Mcs 0x%x u2HtCapInfo 0x%x\n", -+ prStaRec->u2OperationalRateSet, prStaRec->u2DesiredNonHTRateSet, prStaRec->ucMcsSet, -+ prStaRec->u2HtCapInfo); -+ -+ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) -+ DBGLOG(SW4, INFO, "TC %u Queue Len %u\n", i, prStaRec->arTxQueue[i].u4NumElem); -+ -+ DBGLOG(SW4, INFO, "BmpDeliveryAC %x\n", prStaRec->ucBmpDeliveryAC); -+ DBGLOG(SW4, INFO, "BmpTriggerAC %x\n", prStaRec->ucBmpTriggerAC); -+ DBGLOG(SW4, INFO, "UapsdSpSupproted %u\n", prStaRec->fgIsUapsdSupported); -+ DBGLOG(SW4, INFO, "IsQoS %u\n", prStaRec->fgIsQoS); -+ DBGLOG(SW4, INFO, "AssocId %u\n", prStaRec->u2AssocId); -+ -+ DBGLOG(SW4, INFO, "fgIsInPS %u\n", prStaRec->fgIsInPS); -+ DBGLOG(SW4, INFO, "ucFreeQuota %u\n", prStaRec->ucFreeQuota); -+ DBGLOG(SW4, INFO, "ucFreeQuotaForDelivery %u\n", prStaRec->ucFreeQuotaForDelivery); -+ DBGLOG(SW4, INFO, "ucFreeQuotaForNonDelivery %u\n", prStaRec->ucFreeQuotaForNonDelivery); -+ -+#if 0 -+ DBGLOG(SW4, INFO, "IsQmmSup %u\n", prStaRec->fgIsWmmSupported); -+ DBGLOG(SW4, INFO, "IsUapsdSup %u\n", prStaRec->fgIsUapsdSupported); -+ DBGLOG(SW4, INFO, "AvailabaleDeliverPkts %u\n", prStaRec->ucAvailableDeliverPkts); -+ DBGLOG(SW4, INFO, "BmpDeliverPktsAC %u\n", prStaRec->u4BmpDeliverPktsAC); -+ DBGLOG(SW4, INFO, "BmpBufferAC %u\n", prStaRec->u4BmpBufferAC); -+ DBGLOG(SW4, INFO, "BmpNonDeliverPktsAC %u\n", prStaRec->u4BmpNonDeliverPktsAC); -+#endif -+ -+ for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) { -+ if (prStaRec->aprRxReorderParamRefTbl[i]) { -+ DBGLOG(SW4, INFO, -+ "RxReorder fgIsValid: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->fgIsValid); -+ DBGLOG(SW4, INFO, "RxReorder Tid: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->ucTid); -+ DBGLOG(SW4, INFO, -+ "RxReorder rReOrderQue Len: %u\n", -+ prStaRec->aprRxReorderParamRefTbl[i]->rReOrderQue.u4NumElem); -+ DBGLOG(SW4, INFO, -+ "RxReorder WinStart: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinStart); -+ DBGLOG(SW4, INFO, "RxReorder WinEnd: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinEnd); -+ DBGLOG(SW4, INFO, "RxReorder WinSize: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinSize); -+ } -+ } -+ -+} -+ -+VOID dumpBss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ -+ DBGLOG(SW4, INFO, "SSID %s\n", prBssInfo->aucSSID); -+ DBGLOG(SW4, INFO, "OWN %pM\n", prBssInfo->aucOwnMacAddr); -+ DBGLOG(SW4, INFO, "BSSID %pM\n", prBssInfo->aucBSSID); -+ DBGLOG(SW4, INFO, "ucNetTypeIndex %u\n", prBssInfo->ucNetTypeIndex); -+ DBGLOG(SW4, INFO, "eConnectionState %u\n", prBssInfo->eConnectionState); -+ DBGLOG(SW4, INFO, "eCurrentOPMode %u\n", prBssInfo->eCurrentOPMode); -+ DBGLOG(SW4, INFO, "fgIsQBSS %u\n", prBssInfo->fgIsQBSS); -+ DBGLOG(SW4, INFO, "fgIsShortPreambleAllowed %u\n", prBssInfo->fgIsShortPreambleAllowed); -+ DBGLOG(SW4, INFO, "fgUseShortPreamble %u\n", prBssInfo->fgUseShortPreamble); -+ DBGLOG(SW4, INFO, "fgUseShortSlotTime %u\n", prBssInfo->fgUseShortSlotTime); -+ DBGLOG(SW4, INFO, "ucNonHTBasicPhyType %x\n", prBssInfo->ucNonHTBasicPhyType); -+ DBGLOG(SW4, INFO, "u2OperationalRateSet %x\n", prBssInfo->u2OperationalRateSet); -+ DBGLOG(SW4, INFO, "u2BSSBasicRateSet %x\n", prBssInfo->u2BSSBasicRateSet); -+ DBGLOG(SW4, INFO, "ucPhyTypeSet %x\n", prBssInfo->ucPhyTypeSet); -+ DBGLOG(SW4, INFO, "rStaRecOfClientList %d\n", prBssInfo->rStaRecOfClientList.u4NumElem); -+ DBGLOG(SW4, INFO, "u2CapInfo %x\n", prBssInfo->u2CapInfo); -+ DBGLOG(SW4, INFO, "u2ATIMWindow %x\n", prBssInfo->u2ATIMWindow); -+ DBGLOG(SW4, INFO, "u2AssocId %x\n", prBssInfo->u2AssocId); -+ DBGLOG(SW4, INFO, "ucDTIMPeriod %x\n", prBssInfo->ucDTIMPeriod); -+ DBGLOG(SW4, INFO, "ucDTIMCount %x\n", prBssInfo->ucDTIMCount); -+ DBGLOG(SW4, INFO, "fgIsNetAbsent %x\n", prBssInfo->fgIsNetAbsent); -+ DBGLOG(SW4, INFO, "eBand %d\n", prBssInfo->eBand); -+ DBGLOG(SW4, INFO, "ucPrimaryChannel %d\n", prBssInfo->ucPrimaryChannel); -+ DBGLOG(SW4, INFO, "ucHtOpInfo1 %d\n", prBssInfo->ucHtOpInfo1); -+ DBGLOG(SW4, INFO, "ucHtOpInfo2 %d\n", prBssInfo->u2HtOpInfo2); -+ DBGLOG(SW4, INFO, "ucHtOpInfo3 %d\n", prBssInfo->u2HtOpInfo3); -+ DBGLOG(SW4, INFO, "fgErpProtectMode %d\n", prBssInfo->fgErpProtectMode); -+ DBGLOG(SW4, INFO, "eHtProtectMode %d\n", prBssInfo->eHtProtectMode); -+ DBGLOG(SW4, INFO, "eGfOperationMode %d\n", prBssInfo->eGfOperationMode); -+ DBGLOG(SW4, INFO, "eRifsOperationMode %d\n", prBssInfo->eRifsOperationMode); -+ DBGLOG(SW4, INFO, "fgObssErpProtectMode %d\n", prBssInfo->fgObssErpProtectMode); -+ DBGLOG(SW4, INFO, "eObssHtProtectMode %d\n", prBssInfo->eObssHtProtectMode); -+ DBGLOG(SW4, INFO, "eObssGfProtectMode %d\n", prBssInfo->eObssGfOperationMode); -+ DBGLOG(SW4, INFO, "fgObssRifsOperationMode %d\n", prBssInfo->fgObssRifsOperationMode); -+ DBGLOG(SW4, INFO, "fgAssoc40mBwAllowed %d\n", prBssInfo->fgAssoc40mBwAllowed); -+ DBGLOG(SW4, INFO, "fg40mBwAllowed %d\n", prBssInfo->fg40mBwAllowed); -+ DBGLOG(SW4, INFO, "eBssSCO %d\n", prBssInfo->eBssSCO); -+ -+} -+ -+VOID swCtrlCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) -+{ -+ UINT_8 ucIndex, ucRead; -+ UINT_32 i; -+ -+ DEBUGFUNC("swCtrlCmdCategory0"); -+ -+ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); -+ -+ i = 0; -+ -+ if (ucIndex >= SWCTRL_CATA0_INDEX_NUM) -+ return; -+ -+ if (ucRead == SWCR_WRITE) { -+ switch (ucIndex) { -+ case SWCTRL_DEBUG: -+#if DBG -+ aucDebugModule[ucOpt0] = (UINT_8) g_au4SwCr[1]; -+#endif -+ break; -+ case SWCTRL_WIFI_VAR: -+ break; -+ -+#if QM_DEBUG_COUNTER -+ case SWCTRL_DUMP_QM_DBG_CNT: -+ for (i = 0; i < QM_DBG_CNT_NUM; i++) -+ prAdapter->rQM.au4QmDebugCounters[i] = 0; -+ break; -+ case SWCTRL_QM_DBG_CNT: -+ prAdapter->rQM.au4QmDebugCounters[ucOpt0] = g_au4SwCr[1]; -+ -+ break; -+#endif -+#if CFG_RX_PKTS_DUMP -+ case SWCTRL_RX_PKTS_DUMP: -+ /* DBGLOG(SW4, INFO,("SWCTRL_RX_PKTS_DUMP: mask %x\n", g_au4SwCr[1])); */ -+ prAdapter->rRxCtrl.u4RxPktsDumpTypeMask = g_au4SwCr[1]; -+ break; -+#endif -+ case SWCTRL_RX_MDNS_FILTER: -+ { -+ UINT_32 u4rxfilter; -+ BOOLEAN fgUpdate = FALSE; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_STOP) { -+ g_u4mDNSRXFilter &= ~(RX_MDNS_FILTER_START); -+ -+ u4rxfilter = prAdapter->u4OsPacketFilter; -+ fgUpdate = TRUE; -+ } else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_START) { -+ g_u4mDNSRXFilter |= (RX_MDNS_FILTER_START); -+ -+ u4rxfilter = prAdapter->u4OsPacketFilter; -+ if ((g_u4mDNSRXFilter & RX_MDNS_FILTER_IPV4) || -+ (g_u4mDNSRXFilter & RX_MDNS_FILTER_IPV6)) { -+ u4rxfilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; -+ } -+ fgUpdate = TRUE; -+ } else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_ADD) { -+ if (ucOpt1 < 31) -+ g_u4mDNSRXFilter |= (1 << ucOpt1); -+ } else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_REMOVE) { -+ if (ucOpt1 < 31) -+ g_u4mDNSRXFilter &= ~(1 << ucOpt1); -+ } -+ -+ if (fgUpdate == TRUE) { -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_RX_FILTER, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(UINT_32), /* u4SetQueryInfoLen */ -+ (PUINT_8)&u4rxfilter, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* un4SetQueryBufferLen */ -+ ); -+ } -+/* DBGLOG(SW4, INFO,("SWCTRL_RX_MDNS_FILTER: g_u4mDNSRXFilter %x ucOpt0 %x ucOpt1 %x fgUpdate %x u4rxfilter %x, */ -+/* rStatus %x\n", g_u4mDNSRXFilter, ucOpt0, ucOpt1, fgUpdate, u4rxfilter, rStatus)); */ -+ } -+ break; -+ default: -+ break; -+ } -+ } else { -+ switch (ucIndex) { -+ case SWCTRL_DEBUG: -+#if DBG -+ g_au4SwCr[1] = aucDebugModule[ucOpt0]; -+#endif -+ break; -+ case SWCTRL_MAGIC: -+ g_au4SwCr[1] = _SWCTRL_MAGIC; -+ /* DBGLOG(SW4, INFO, "BUILD TIME: %s %s\n", __DATE__, __TIME__); */ -+ break; -+ case SWCTRL_QM_INFO: -+ { -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ switch (ucOpt0) { -+ case 0: -+ g_au4SwCr[1] = (QM_GET_TX_QUEUE_LEN(prAdapter, ucOpt1)); -+ g_au4SwCr[2] = prQM->au4MinReservedTcResource[ucOpt1]; -+ g_au4SwCr[3] = prQM->au4CurrentTcResource[ucOpt1]; -+ g_au4SwCr[4] = prQM->au4GuaranteedTcResource[ucOpt1]; -+ break; -+ -+ case 1: -+ g_au4SwCr[1] = prQM->au4ForwardCount[ucOpt1]; -+ g_au4SwCr[2] = prQM->au4HeadStaRecIndex[ucOpt1]; -+ break; -+ -+ case 2: -+ g_au4SwCr[1] = prQM->arTxQueue[ucOpt1].u4NumElem; /* only one */ -+ -+ break; -+ } -+ -+ } -+ break; -+ case SWCTRL_TX_CTRL_INFO: -+ { -+ P_TX_CTRL_T prTxCtrl; -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ switch (ucOpt0) { -+ case 0: -+ g_au4SwCr[1] = prAdapter->rTxCtrl.rTc.aucFreeBufferCount[ucOpt1]; -+ g_au4SwCr[2] = prAdapter->rTxCtrl.rTc.aucMaxNumOfBuffer[ucOpt1]; -+ break; -+ } -+ -+ } -+ break; -+ case SWCTRL_DUMP_QUEUE: -+ dumpQueue(prAdapter); -+ -+ break; -+#if QM_DEBUG_COUNTER -+ case SWCTRL_DUMP_QM_DBG_CNT: -+ for (i = 0; i < QM_DBG_CNT_NUM; i++) -+ DBGLOG(SW4, INFO, "QM:DBG %u %u\n", i, prAdapter->rQM.au4QmDebugCounters[i]); -+ break; -+ -+ case SWCTRL_QM_DBG_CNT: -+ g_au4SwCr[1] = prAdapter->rQM.au4QmDebugCounters[ucOpt0]; -+ break; -+#endif -+ case SWCTRL_DUMP_BSS: -+ { -+ dumpBss(prAdapter, &(prAdapter->rWifiVar.arBssInfo[ucOpt0])); -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ } -+} -+ -+VOID swCtrlCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) -+{ -+ UINT_8 ucIndex, ucRead; -+ UINT_8 ucWTEntry; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("swCtrlCmdCategory1"); -+ -+ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); -+ -+ if (ucOpt0 >= CFG_STA_REC_NUM) -+ return; -+ -+ /* prStaRec = cnmGetStaRecByIndex (prAdapter, ucOpt0); */ -+ prStaRec = &prAdapter->arStaRec[ucOpt0]; -+ ucWTEntry = prStaRec->ucWTEntry; -+ if (ucRead == SWCR_WRITE) { -+ /* Do nothing */ -+ } else { -+ /* Read */ -+ switch (ucIndex) { -+ case SWCTRL_STA_QUE_INFO: -+ { -+ g_au4SwCr[1] = prStaRec->arTxQueue[ucOpt1].u4NumElem; -+ } -+ break; -+ case SWCTRL_STA_INFO: -+ switch (ucOpt1) { -+ case 0: -+ g_au4SwCr[1] = prStaRec->fgIsInPS; -+ break; -+ } -+ -+ break; -+ -+ case SWCTRL_DUMP_STA: -+ { -+ dumpSTA(prAdapter, prStaRec); -+ } -+ break; -+ -+ default: -+ -+ break; -+ } -+ } -+ -+} -+ -+#if TEST_PS -+ -+VOID -+testPsSendQoSNullFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN UINT_8 ucUP, -+ IN UINT_8 ucNetTypeIndex, -+ IN BOOLEAN fgBMC, -+ IN BOOLEAN fgIsBurstEnd, IN BOOLEAN ucPacketType, IN BOOLEAN ucPsSessionID, IN BOOLEAN fgSetEOSP) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2EstimatedFrameLen; -+ P_WLAN_MAC_HEADER_QOS_T prQoSNullFrame; -+ -+ DEBUGFUNC("testPsSendQoSNullFrame"); -+ DBGLOG(SW4, LOUD, "\n"); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ -+ /* Init with MGMT Header Length */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SW4, WARN, "No PKT_INFO_T for sending Null Frame.\n"); -+ return; -+ } -+ /* 4 <2> Compose Null frame in MSDU_INfO_T. */ -+ bssComposeQoSNullFrame(prAdapter, -+ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prStaRec, ucUP, fgSetEOSP); -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ /* prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_DATA; */ -+ prMsduInfo->ucPacketType = ucPacketType; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_QOS_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_QOS_LEN; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ prMsduInfo->fgIsBurstEnd = fgIsBurstEnd; -+ prMsduInfo->ucUserPriority = ucUP; -+ prMsduInfo->ucPsSessionID = ucPsSessionID /* 0~7 Test 7 means NOACK */; -+ -+ prQoSNullFrame = (P_WLAN_MAC_HEADER_QOS_T) (((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD)); -+ -+ if (fgBMC) -+ prQoSNullFrame->aucAddr1[0] = 0xfd; -+ else -+ prQoSNullFrame->aucAddr1[5] = 0xdd; -+ -+ /* 4 <4> Inform TXM to send this Null frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+} -+ -+VOID testPsSetupBss(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetworkTypeIndex) -+{ -+ P_BSS_INFO_T prBssInfo; -+ UINT_8 _aucZeroMacAddr[] = NULL_MAC_ADDR; -+ -+ DEBUGFUNC("testPsSetupBss()"); -+ DBGLOG(SW4, INFO, "index %d\n", ucNetworkTypeIndex); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetworkTypeIndex]); -+ -+ /* 4 <1.2> Initiate PWR STATE */ -+ /* SET_NET_PWR_STATE_IDLE(prAdapter, ucNetworkTypeIndex); */ -+ -+ /* 4 <2> Initiate BSS_INFO_T - common part */ -+ BSS_INFO_INIT(prAdapter, ucNetworkTypeIndex); -+ -+ prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; -+ prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; -+ prBssInfo->eCurrentOPMode = OP_MODE_ACCESS_POINT; -+ prBssInfo->fgIsNetActive = TRUE; -+ prBssInfo->ucNetTypeIndex = (ucNetworkTypeIndex); -+ prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; -+ -+ prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; /* Depend on eBand */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->u2BSSBasicRateSet = RATE_SET_ERP; -+ prBssInfo->u2OperationalRateSet = RATE_SET_OFDM; -+ prBssInfo->fgErpProtectMode = FALSE; -+ prBssInfo->fgIsQBSS = TRUE; -+ -+ /* 4 <1.5> Setup MIB for current BSS */ -+ prBssInfo->u2BeaconInterval = 100; -+ prBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; -+ prBssInfo->u2ATIMWindow = 0; -+ -+ prBssInfo->ucBeaconTimeoutCount = 0; -+ -+ bssInitForAP(prAdapter, prBssInfo, TRUE); -+ -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, _aucZeroMacAddr); -+ LINK_INITIALIZE(&prBssInfo->rStaRecOfClientList); -+ prBssInfo->fgIsBeaconActivated = TRUE; -+ prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; -+ -+ COPY_MAC_ADDR(prBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucMacAddress); -+ -+ /* 4 <3> Initiate BSS_INFO_T - private part */ -+ /* TODO */ -+ prBssInfo->eBand = BAND_2G4; -+ prBssInfo->ucPrimaryChannel = 1; -+ prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ -+ /* prBssInfo->fgErpProtectMode = eErpProectMode; */ -+ /* prBssInfo->eHtProtectMode = eHtProtectMode; */ -+ /* prBssInfo->eGfOperationMode = eGfOperationMode; */ -+ -+ /* 4 <4> Allocate MSDU_INFO_T for Beacon */ -+ prBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH); -+ -+ if (prBssInfo->prBeacon) { -+ prBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; -+ prBssInfo->prBeacon->ucNetworkType = ucNetworkTypeIndex; -+ } else { -+ DBGLOG(SW4, INFO, "prBeacon allocation fail\n"); -+ } -+ -+#if 0 -+ prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; -+ prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; -+ prBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; -+#else -+ prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = (UINT_8) prAdapter->u4UapsdAcBmp; -+ prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = (UINT_8) prAdapter->u4UapsdAcBmp; -+ prBssInfo->rPmProfSetupInfo.ucUapsdSp = (UINT_8) prAdapter->u4MaxSpLen; -+#endif -+ -+#if 0 -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ prBssInfo->arACQueParms[eAci].fgIsACMSet = FALSE; -+ prBssInfo->arACQueParms[eAci].u2Aifsn = (UINT_16) eAci; -+ prBssInfo->arACQueParms[eAci].u2CWmin = 7; -+ prBssInfo->arACQueParms[eAci].u2CWmax = 31; -+ prBssInfo->arACQueParms[eAci].u2TxopLimit = eAci + 1; -+ DBGLOG(SW4, INFO, "MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", -+ eAci, prBssInfo->arACQueParms[eAci].fgIsACMSet, -+ prBssInfo->arACQueParms[eAci].u2Aifsn, -+ prBssInfo->arACQueParms[eAci].u2CWmin, -+ prBssInfo->arACQueParms[eAci].u2CWmax, prBssInfo->arACQueParms[eAci].u2TxopLimit)); -+ -+ } -+#endif -+ -+ DBGLOG(SW4, INFO, "[2] ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x, ucUapsdSp:0x%x", -+ prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC, -+ prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC, prBssInfo->rPmProfSetupInfo.ucUapsdSp); -+ -+} -+ -+VOID testPsCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) -+{ -+ UINT_8 ucIndex, ucRead; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("testPsCmdCategory0"); -+ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); -+ -+ DBGLOG(SW4, LOUD, "Read %u Index %u\n", ucRead, ucIndex); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, 0); -+ -+ if (ucIndex >= TEST_PS_CATA0_INDEX_NUM) -+ return; -+ -+ if (ucRead == SWCR_WRITE) { -+ switch (ucIndex) { -+ case TEST_PS_SETUP_BSS: -+ testPsSetupBss(prAdapter, ucOpt0); -+ break; -+ -+ case TEST_PS_ENABLE_BEACON: -+ break; -+ -+ case TEST_PS_TRIGGER_BMC: -+ /* txmForwardQueuedBmcPkts (ucOpt0); */ -+ break; -+ case TEST_PS_SEND_NULL: -+ { -+ -+ testPsSendQoSNullFrame(prAdapter, prStaRec, (UINT_8) (g_au4SwCr[1] & 0xFF), /* UP */ -+ ucOpt0, (BOOLEAN) ((g_au4SwCr[1] >> 8) & 0xFF), /* BMC */ -+ (BOOLEAN) ((g_au4SwCr[1] >> 16) & 0xFF), /* BurstEnd */ -+ (BOOLEAN) ((g_au4SwCr[1] >> 24) & 0xFF), /* Packet type */ -+ (UINT_8) ((g_au4SwCr[2]) & 0xFF), /* PS sesson ID 7: NOACK */ -+ FALSE /* EOSP */ -+ ); -+ } -+ break; -+ case TEST_PS_BUFFER_BMC: -+ /* g_aprBssInfo[ucOpt0]->fgApToBufferBMC = (g_au4SwCr[1] & 0xFF); */ -+ break; -+ case TEST_PS_UPDATE_BEACON: -+ bssUpdateBeaconContent(prAdapter, ucOpt0 /*networktype */); -+ break; -+ -+ default: -+ break; -+ } -+ } else { -+ switch (ucIndex) { -+ -+ case TEST_PS_MAGIC: -+ g_au4SwCr[1] = 0x88660011; -+ break; -+ -+ } -+ } -+} -+ -+#endif /* TEST_PS */ -+ -+#if TEST_PS -+ -+VOID testPsCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) -+{ -+ UINT_8 ucIndex, ucRead; -+ UINT_8 ucWTEntry; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("testPsCmdCategory1"); -+ -+ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); -+ -+ if (ucOpt0 >= CFG_STA_REC_NUM) -+ return; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, ucOpt0); -+ if (!prStaRec) -+ return; -+ ucWTEntry = prStaRec->ucWTEntry; -+ if (ucRead == SWCR_WRITE) { -+ -+ switch (ucIndex) { -+ case TEST_PS_STA_PS: -+ prStaRec->fgIsInPS = (BOOLEAN) (g_au4SwCr[1] & 0x1); -+ prStaRec->fgIsQoS = (BOOLEAN) (g_au4SwCr[1] >> 8 & 0xFF); -+ prStaRec->fgIsUapsdSupported = (BOOLEAN) (g_au4SwCr[1] >> 16 & 0xFF); -+ prStaRec->ucBmpDeliveryAC = (BOOLEAN) (g_au4SwCr[1] >> 24 & 0xFF); -+ break; -+ -+ } -+ -+ } else { -+ /* Read */ -+ switch (ucIndex) { -+ default: -+ break; -+ } -+ } -+ -+} -+ -+#endif /* TEST_PS */ -+ -+#if CFG_SUPPORT_802_11V -+#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (WNM_UNIT_TEST == 1) -+VOID testWNMCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) -+{ -+ UINT_8 ucIndex, ucRead; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("testWNMCmdCategory0"); -+ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); -+ -+ DBGLOG(SW4, INFO, "Read %u Index %u\n", ucRead, ucIndex); -+ -+ if (ucIndex >= TEST_WNM_CATA0_INDEX_NUM) -+ return; -+ -+ if (ucRead == SWCR_WRITE) { -+ switch (ucIndex) { -+ case TEST_WNM_TIMING_MEAS: -+ wnmTimingMeasUnitTest1(prAdapter, ucOpt0); -+ break; -+ -+ default: -+ break; -+ } -+ } -+} -+#endif /* TEST_WNM */ -+#endif /* CFG_SUPPORT_802_11V */ -+ -+VOID swCtrlSwCr(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data) -+{ -+ /* According other register STAIDX */ -+ UINT_8 ucOffset; -+ -+ ucOffset = (u2Addr >> 2) & 0x3F; -+ -+ if (ucOffset >= SWCR_CR_NUM) -+ return; -+ -+ if (ucRead == SWCR_WRITE) { -+ g_au4SwCr[ucOffset] = *pu4Data; -+ if (ucOffset == 0x0) { -+ /* Commmand [31:24]: Category */ -+ /* Commmand [23:23]: 1(W) 0(R) */ -+ /* Commmand [22:16]: Index */ -+ /* Commmand [15:08]: Option0 */ -+ /* Commmand [07:00]: Option1 */ -+ UINT_8 ucCate; -+ UINT_32 u4Cmd; -+ -+ u4Cmd = g_au4SwCr[0]; -+ ucCate = (UINT_8) (u4Cmd >> 24); -+ if (ucCate < sizeof(g_arSwCtrlCmd) / sizeof(g_arSwCtrlCmd[0])) { -+ if (g_arSwCtrlCmd[ucCate] != NULL) { -+ g_arSwCtrlCmd[ucCate] (prAdapter, ucCate, (UINT_8) (u4Cmd >> 16 & 0xFF), -+ (UINT_8) ((u4Cmd >> 8) & 0xFF), (UINT_8) (u4Cmd & 0xFF)); -+ } -+ } -+ } -+ } else { -+ *pu4Data = g_au4SwCr[ucOffset]; -+ } -+} -+ -+VOID swCrReadWriteCmd(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data) -+{ -+ UINT_8 ucMod; -+ -+ ucMod = u2Addr >> 8; -+ /* Address [15:8] MOD ID */ -+ /* Address [7:0] OFFSET */ -+ -+ DEBUGFUNC("swCrReadWriteCmd"); -+ DBGLOG(SW4, TRACE, "%u addr 0x%x data 0x%x\n", ucRead, u2Addr, *pu4Data); -+ -+ if (ucMod < (sizeof(g_arSwCrModHandle) / sizeof(g_arSwCrModHandle[0]))) { -+ -+ if (g_arSwCrModHandle[ucMod] != NULL) -+ g_arSwCrModHandle[ucMod] (prAdapter, ucRead, u2Addr, pu4Data); -+ } /* ucMod */ -+} -+ -+/* Debug Support */ -+VOID swCrFrameCheckEnable(P_ADAPTER_T prAdapter, UINT_32 u4DumpType) -+{ -+ g_u4SwcrDebugFrameDumpType = u4DumpType; -+ prAdapter->rRxCtrl.u4RxPktsDumpTypeMask = u4DumpType; -+} -+ -+VOID swCrDebugInit(P_ADAPTER_T prAdapter) -+{ -+ /* frame dump */ -+ if (g_u4SwcrDebugFrameDumpType) -+ swCrFrameCheckEnable(prAdapter, g_u4SwcrDebugFrameDumpType); -+ /* debug counter */ -+ g_fgSwcrDebugTimer = FALSE; -+ -+ cnmTimerInitTimer(prAdapter, &g_rSwcrDebugTimer, (PFN_MGMT_TIMEOUT_FUNC) swCrDebugCheckTimeout, (ULONG) NULL); -+ -+ if (g_u4SwcrDebugCheckTimeout) -+ swCrDebugCheckEnable(prAdapter, TRUE, g_ucSwcrDebugCheckType, g_u4SwcrDebugCheckTimeout); -+} -+ -+VOID swCrDebugUninit(P_ADAPTER_T prAdapter) -+{ -+ cnmTimerStopTimer(prAdapter, &g_rSwcrDebugTimer); -+ -+ g_fgSwcrDebugTimer = FALSE; -+} -+ -+VOID swCrDebugCheckEnable(P_ADAPTER_T prAdapter, BOOLEAN fgIsEnable, UINT_8 ucType, UINT_32 u4Timeout) -+{ -+ if (fgIsEnable) { -+ g_ucSwcrDebugCheckType = ucType; -+ g_u4SwcrDebugCheckTimeout = u4Timeout; -+ if (g_fgSwcrDebugTimer == FALSE) -+ swCrDebugCheckTimeout(prAdapter, 0); -+ } else { -+ cnmTimerStopTimer(prAdapter, &g_rSwcrDebugTimer); -+ g_u4SwcrDebugCheckTimeout = 0; -+ } -+ -+ g_fgSwcrDebugTimer = fgIsEnable; -+} -+ -+VOID swCrDebugCheck(P_ADAPTER_T prAdapter, P_CMD_SW_DBG_CTRL_T prCmdSwCtrl) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_TX_CTRL_T prTxCtrl; -+ -+ ASSERT(prAdapter); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ /* dump counters */ -+ if (prCmdSwCtrl) { -+ if (prCmdSwCtrl->u4Data == SWCR_DBG_TYPE_ALL) { -+ -+ /* TX Counter from fw */ -+ DBGLOG(SW4, INFO, "TX0\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n", -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_BCN_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_FAILED_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_RETRY_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_AGING_TIMEOUT_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_PS_OVERFLOW_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_MGNT_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_ERROR_CNT]); -+#if 1 -+ /* TX Counter from drv */ -+ DBGLOG(SW4, INFO, "TX1\n" -+ "%08x %08x %08x %08x\n", -+ (UINT_32) TX_GET_CNT(prTxCtrl, TX_INACTIVE_BSS_DROP), -+ (UINT_32) TX_GET_CNT(prTxCtrl, TX_INACTIVE_STA_DROP), -+ (UINT_32) TX_GET_CNT(prTxCtrl, TX_FORWARD_OVERFLOW_DROP), -+ (UINT_32) TX_GET_CNT(prTxCtrl, TX_AP_BORADCAST_DROP)); -+#endif -+ -+ /* RX Counter */ -+ DBGLOG(SW4, INFO, "RX0\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n", -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_DUP_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_TYPE_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_CLASS_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_AMPDU_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_STATUS_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FORMAT_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_ICV_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_KEY_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_TKIP_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_MIC_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_BIP_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FCSERR_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FIFOFULL_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_PFDROP_CNT]); -+ -+ DBGLOG(SW4, INFO, "RX1\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n", -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_INDICATION_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_RETURNED_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_RETAINED_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_TYPE_ERR_DROP_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_CLASS_ERR_DROP_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DST_NULL_DROP_COUNT)); -+ -+ DBGLOG(SW4, INFO, "PWR\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n", -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PS_POLL_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_TRIGGER_NULL_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_BCN_IND_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_BCN_TIMEOUT_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PM_STATE0], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PM_STATE1], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_CUR_PS_PROF0], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_CUR_PS_PROF1]); -+ -+ DBGLOG(SW4, INFO, "ARM\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x\n", -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_RATE], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_BWGI], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_RX_RATE_RCPI], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_ENABLE], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_ROAM_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_INT_CNT]); -+ -+ DBGLOG(SW4, INFO, "BB\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n", -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_RX_MDRDY_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_RX_FCSERR_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_PD_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_PD_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_SFDERR_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_SIGERR_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_TAGERR_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_SIGERR_CNT]); -+ -+ } -+ } -+ /* start the next check */ -+ if (g_u4SwcrDebugCheckTimeout) -+ cnmTimerStartTimer(prAdapter, &g_rSwcrDebugTimer, g_u4SwcrDebugCheckTimeout * MSEC_PER_SEC); -+} -+ -+VOID swCrDebugCheckTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ CMD_SW_DBG_CTRL_T rCmdSwCtrl; -+ WLAN_STATUS rStatus; -+ -+ rCmdSwCtrl.u4Id = (0xb000 << 16) + g_ucSwcrDebugCheckType; -+ rCmdSwCtrl.u4Data = 0; -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SW_DBG_CTRL, /* ucCID */ -+ FALSE, /* fgSetQuery */ -+ TRUE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ swCrDebugQuery, /* pfCmdDoneHandler */ -+ swCrDebugQueryTimeout, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_SW_DBG_CTRL_T), /* u4SetQueryInfoLen */ -+ (PUINT_8)&rCmdSwCtrl, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+} -+ -+VOID swCrDebugQuery(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ ASSERT(prAdapter); -+ -+ swCrDebugCheck(prAdapter, (P_CMD_SW_DBG_CTRL_T) (pucEventBuf)); -+} -+ -+VOID swCrDebugQueryTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ ASSERT(prAdapter); -+ -+ swCrDebugCheck(prAdapter, NULL); -+} -+ -+#endif /* CFG_SUPPORT_SWCR */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c -new file mode 100644 -index 0000000000000..96293c57e2b03 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c -@@ -0,0 +1,5199 @@ -+/* -+** Id: tdls.c#1 -+*/ -+ -+/*! \file tdls.c -+ \brief This file includes IEEE802.11z TDLS support. -+*/ -+ -+/* -+** Log: tdls.c -+ * -+ * 11 13 2013 vend_samp.lin -+ * NULL -+ * Initial version. -+ */ -+ -+/******************************************************************************* -+ * C O M P I L E R F L A G S -+ ******************************************************************************** -+ */ -+ -+/******************************************************************************* -+ * E X T E R N A L R E F E R E N C E S -+ ******************************************************************************** -+ */ -+#include "precomp.h" -+ -+#if (CFG_SUPPORT_TDLS == 1) -+#include "gl_wext.h" -+#include "tdls.h" -+#include "gl_cfg80211.h" -+#include -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static VOID TdlsCmdTestRxIndicatePkts(GLUE_INFO_T *prGlueInfo, struct sk_buff *prSkb); -+ -+#if TDLS_CFG_CMD_TEST -+static void TdlsCmdTestAddPeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestChSwProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestChSwReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestChSwRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestChSwTimeoutSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestDataContSend(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestDataRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestDataSend(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestDelay(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestDiscoveryReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestKeepAliveSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestPtiReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestPtiRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestPtiTxDoneFail(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestRvFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestSetupConfirmRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestSetupReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestSetupRspRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestScanCtrl(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestTearDownRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestTxFailSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestTxTdlsFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestTxFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static TDLS_STATUS -+TdlsCmdTestTxFmeSetupReqBufTranslate(UINT_8 *pCmdBuf, UINT_32 u4BufLen, PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd); -+ -+static void TdlsCmdTestUpdatePeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestNullRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static VOID TdlsTimerTestDataContSend(ADAPTER_T *prAdapter, UINT_32 u4Param); -+ -+static TDLS_STATUS -+TdlsTestChStReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestChStRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestNullRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestPtiReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestPtiRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestTearDownRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestDataRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestPtiTxFail(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestTdlsFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestTxFailSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestKeepAliveSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestChSwTimeoutSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestScanSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsChSwConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static void TdlsCmdChSwConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdKeyInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdMibParamUpdate(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdSetupConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdUapsdConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static TDLS_STATUS -+TdlsInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsKeyInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static VOID -+TdlsLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, -+ BOOLEAN fgIsTearDown, -+ UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode, VOID *prOthers); -+ -+static VOID -+TdlsLinkHistoryRecordUpdate(GLUE_INFO_T *prGlueInfo, -+ UINT8 *pucPeerMac, TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus, VOID *pInfo); -+ -+static TDLS_STATUS -+TdlsMibParamUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsSetupConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsUapsdConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static void TdlsEventStatistics(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); -+ -+static void TdlsEventTearDown(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); -+ -+#endif /* TDLS_CFG_CMD_TEST */ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static BOOLEAN fgIsPtiTimeoutSkip = FALSE; -+ -+/******************************************************************************* -+* P R I V A T E F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to indicate packets to upper layer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prSkb A pointer to the received packet -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID TdlsCmdTestRxIndicatePkts(GLUE_INFO_T *prGlueInfo, struct sk_buff *prSkb) -+{ -+ struct net_device *prNetDev; -+ -+ /* init */ -+ prNetDev = prGlueInfo->prDevHandler; -+ prGlueInfo->rNetDevStats.rx_bytes += prSkb->len; -+ prGlueInfo->rNetDevStats.rx_packets++; -+ -+ /* pass to upper layer */ -+ //prNetDev->last_rx = jiffies; -+ prSkb->protocol = eth_type_trans(prSkb, prNetDev); -+ prSkb->dev = prNetDev; -+ -+ if (!in_interrupt()) -+ netif_rx_ni(prSkb); /* only in non-interrupt context */ -+ else -+ netif_rx(prSkb); -+} -+ -+#if TDLS_CFG_CMD_TEST -+ -+#define LR_TDLS_FME_FIELD_FILL(__Len) \ -+do { \ -+ pPkt += __Len; \ -+ u4PktLen += __Len; \ -+} while (0) -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to add a TDLS peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_2_[Responder MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_2_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestAddPeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; -+ struct wireless_dev *prWdev; -+ -+ /* reset */ -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr); -+ -+ /* init */ -+ rCmd.rPeerInfo.supported_rates = NULL; -+ rCmd.rPeerInfo.ht_capa = &rCmd.rHtCapa; -+ rCmd.rPeerInfo.vht_capa = &rCmd.rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */ -+ rCmd.rPeerInfo.sta_flags_set = BIT(NL80211_STA_FLAG_TDLS_PEER); -+ -+ /* send command to wifi task to handle */ -+ prWdev = prGlueInfo->prDevHandler->ieee80211_ptr; -+ mtk_cfg80211_add_station(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, &rCmd.rPeerInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to simulate to set the TDLS Prohibited bit. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_16_[Enable/Disable]_[Set/Clear] -+ -+ iwpriv wlan0 set_str_cmd 0_16_1_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestChSwProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ TDLS_CMD_CORE_T rCmd; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdProhibit.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdProhibit.fgIsSet = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdProhibit.fgIsEnable); -+ -+ /* command to do this */ -+ flgTdlsTestExtCapElm = rCmd.Content.rCmdProhibit.fgIsEnable; -+ -+ aucTdlsTestExtCapElm[0] = ELEM_ID_EXTENDED_CAP; -+ aucTdlsTestExtCapElm[1] = 5; -+ aucTdlsTestExtCapElm[2] = 0; -+ aucTdlsTestExtCapElm[3] = 0; -+ aucTdlsTestExtCapElm[4] = 0; -+ aucTdlsTestExtCapElm[5] = 0; -+ aucTdlsTestExtCapElm[6] = (rCmd.Content.rCmdProhibit.fgIsSet << 7); /* bit39 */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a channel switch request from the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_5_[TDLS Peer MAC]_[Chan]_[RegulatoryClass]_ -+ [SecondaryChannelOffset]_[SwitchTime]_[SwitchTimeout] -+ -+ iwpriv wlan0 set_str_cmd 0_1_5_00:11:22:33:44:01_1_255_0_15000_30000 -+ -+ RegulatoryClass: TODO (reference to Annex I of 802.11n spec.) -+ Secondary Channel Offset: 0 (SCN - no secondary channel) -+ 1 (SCA - secondary channel above) -+ 2 (SCB - secondary channel below) -+ SwitchTime: units of microseconds -+ -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestChSwReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ -+ rCmd.Content.rCmdChStReqRcv.u4Chan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStReqRcv.u4RegClass = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStReqRcv.u4SecChanOff = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStReqRcv.u4SwitchTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStReqRcv.u4SwitchTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s:[%pM]u4Chan=%u u4RegClass=%u u4SecChanOff=%u u4SwitchTime=%u u4SwitchTimeout=%u\n", -+ __func__, rCmd.aucPeerMac, -+ (UINT32) rCmd.Content.rCmdChStReqRcv.u4Chan, -+ (UINT32) rCmd.Content.rCmdChStReqRcv.u4RegClass, -+ (UINT32) rCmd.Content.rCmdChStReqRcv.u4SecChanOff, -+ (UINT32) rCmd.Content.rCmdChStReqRcv.u4SwitchTime, -+ (UINT32) rCmd.Content.rCmdChStReqRcv.u4SwitchTimeout); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestChStReqRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a channel switch response from the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_6_[TDLS Peer MAC]_[Chan]_ -+ [SwitchTime]_[SwitchTimeout]_[StatusCode] -+ -+ iwpriv wlan0 set_str_cmd 0_1_6_00:11:22:33:44:01_11_15000_30000_0 -+ -+ RegulatoryClass: TODO (reference to Annex I of 802.11n spec.) -+ Secondary Channel Offset: 0 (SCN - no secondary channel) -+ 1 (SCA - secondary channel above) -+ 2 (SCB - secondary channel below) -+ SwitchTime: units of microseconds -+ -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestChSwRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ -+ rCmd.Content.rCmdChStRspRcv.u4Chan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStRspRcv.u4SwitchTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStRspRcv.u4SwitchTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStRspRcv.u4StatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: [ %pM ] u4Chan=%u u4SwitchTime=%u u4SwitchTimeout=%u u4StatusCode=%u\n", -+ __func__, rCmd.aucPeerMac, -+ (UINT32) rCmd.Content.rCmdChStRspRcv.u4Chan, -+ (UINT32) rCmd.Content.rCmdChStRspRcv.u4SwitchTime, -+ (UINT32) rCmd.Content.rCmdChStRspRcv.u4SwitchTimeout, -+ (UINT32) rCmd.Content.rCmdChStRspRcv.u4StatusCode); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestChStRspRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to inform firmware to skip channel switch timeout function. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_11_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_11_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestChSwTimeoutSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdKeepAliveSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdKeepAliveSkip.fgIsEnable); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsTestChSwTimeoutSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a data frame to the peer periodically. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TIMER_T rTdlsTimerTestDataSend; -+static UINT_8 aucTdlsTestDataSPeerMac[6]; -+static UINT_16 u2TdlsTestDataSInterval; -+ -+static void TdlsCmdTestDataContSend(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ BOOLEAN fgIsEnabled; -+ -+ /* init */ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucTdlsTestDataSPeerMac); -+ u2TdlsTestDataSInterval = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ fgIsEnabled = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ cnmTimerStopTimer(prAdapter, &rTdlsTimerTestDataSend); -+ -+ if (fgIsEnabled == FALSE) { -+ /* stop test timer */ -+ return; -+ } -+ -+ /* re-init test timer */ -+ cnmTimerInitTimer(prAdapter, -+ &rTdlsTimerTestDataSend, (PFN_MGMT_TIMEOUT_FUNC) TdlsTimerTestDataContSend, (ULONG) NULL); -+ -+ cnmTimerStartTimer(prAdapter, &rTdlsTimerTestDataSend, u2TdlsTestDataSInterval); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a data frame from the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_0_x80_[TDLS Peer MAC]_[PM]_[UP]_[EOSP]_[IsNull] -+ -+ iwpriv wlan0 set_str_cmd 0_1_x80_00:11:22:33:44:01_0_0_0_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestDataRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ rCmd.Content.rCmdDatRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdDatRcv.u4UP = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdDatRcv.u4EOSP = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdDatRcv.u4IsNull = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: [%pM] PM(%u) UP(%u) EOSP(%u) NULL(%u)\n", -+ __func__, rCmd.aucPeerMac, -+ (UINT32) rCmd.Content.rCmdDatRcv.u4PM, -+ (UINT32) rCmd.Content.rCmdDatRcv.u4UP, -+ (UINT32) rCmd.Content.rCmdDatRcv.u4EOSP, (UINT32) rCmd.Content.rCmdDatRcv.u4IsNull); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestDataRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a data frame to the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_4_[Responder MAC]_[tx status] -+ -+ iwpriv wlan0 set_str_cmd 0_4_00:11:22:33:44:01_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestDataSend(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ P_ADAPTER_T prAdapter; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *prPkt; -+ UINT_8 MAC[6]; -+ UINT_8 ucTxStatus; -+ -+ /* init */ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, MAC); -+ ucTxStatus = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ /* allocate a data frame */ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1000, &prPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s allocate pkt fail!\n", __func__); -+ return; -+ } -+ -+ /* init dev */ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s prMsduInfo->dev == NULL!\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* init packet */ -+ prMsduInfo->len = 1000; -+ kalMemZero(prMsduInfo->data, 100); /* for QoS field */ -+ kalMemCopy(prMsduInfo->data, MAC, 6); -+ kalMemCopy(prMsduInfo->data + 6, prAdapter->rMyMacAddr, 6); -+ *(UINT_16 *) (prMsduInfo->data + 12) = 0x0800; -+ -+ /* simulate OS to send the packet */ -+ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to simulate to set the TDLS Prohibited bit. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_16_[mili seconds] -+ -+ iwpriv wlan0 set_str_cmd 0_19_1000 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestDelay(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ UINT32 u4Delay; -+ -+ u4Delay = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(TDLS, INFO, "%s: Delay = %d\n", __func__, u4Delay); -+ -+ kalMdelay(u4Delay); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test discovery request frame command. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_10_[DialogToken]_[Peer MAC]_[BSSID] -+ -+ iwpriv wlan0 set_str_cmd 0_1_10_1_00:11:22:33:44:01 -+ iwpriv wlan0 set_str_cmd 0_1_10_1_00:11:22:33:44:01_00:22:33:44:11:22 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestDiscoveryReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ P_BSS_INFO_T prBssInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ UINT_8 ucDialogToken, aucPeerMac[6], aucBSSID[6], aucZeroMac[6]; -+ -+ /* parse arguments */ -+ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); -+ -+ kalMemZero(aucZeroMac, sizeof(aucZeroMac)); -+ kalMemZero(aucBSSID, sizeof(aucBSSID)); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucBSSID); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: DialogToken=%d from %pM\n", __func__, ucDialogToken, aucPeerMac); -+ -+ /* allocate/init packet */ -+ prAdapter = prGlueInfo->prAdapter; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = TDLS_FRM_ACTION_DISCOVERY_REQ; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Dialog token */ -+ *pPkt = ucDialogToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18; -+ -+ if (kalMemCmp(aucBSSID, aucZeroMac, 6) == 0) -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ else -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, aucBSSID, 6); -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* pass to OS */ -+ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to inform firmware to skip keep alive function. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_10_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_10_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestKeepAliveSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdKeepAliveSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdKeepAliveSkip.fgIsEnable); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsTestKeepAliveSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to simulate to set the TDLS Prohibited bit. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_11_[Enable/Disable]_[Set/Clear] -+ -+ iwpriv wlan0 set_str_cmd 0_13_1_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ TDLS_CMD_CORE_T rCmd; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdProhibit.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdProhibit.fgIsSet = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdProhibit.fgIsEnable); -+ -+ /* command to do this */ -+ flgTdlsTestExtCapElm = rCmd.Content.rCmdProhibit.fgIsEnable; -+ -+ aucTdlsTestExtCapElm[0] = ELEM_ID_EXTENDED_CAP; -+ aucTdlsTestExtCapElm[1] = 5; -+ aucTdlsTestExtCapElm[2] = 0; -+ aucTdlsTestExtCapElm[3] = 0; -+ aucTdlsTestExtCapElm[4] = 0; -+ aucTdlsTestExtCapElm[5] = 0; -+ aucTdlsTestExtCapElm[6] = (rCmd.Content.rCmdProhibit.fgIsSet << 6); /* bit38 */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a PTI request from the AP. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_4_[TDLS Peer MAC]_[Dialog Token] -+ -+ iwpriv wlan0 set_str_cmd 0_1_4_00:11:22:33:44:01_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestPtiReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ -+ rCmd.Content.rCmdPtiRspRcv.u4DialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: [ %pM ] u4DialogToken = %u\n", -+ __func__, rCmd.aucPeerMac, (UINT32) rCmd.Content.rCmdPtiRspRcv.u4DialogToken); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestPtiReqRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a PTI response from the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_9_[TDLS Peer MAC]_[Dialog Token]_[PM] -+ -+ iwpriv wlan0 set_str_cmd 0_1_9_00:11:22:33:44:01_0_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestPtiRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ -+ rCmd.Content.rCmdPtiRspRcv.u4DialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdPtiRspRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: [%pM] u4DialogToken = %u %u\n", -+ __func__, rCmd.aucPeerMac, -+ (UINT32) rCmd.Content.rCmdPtiRspRcv.u4DialogToken, -+ (UINT32) rCmd.Content.rCmdPtiRspRcv.u4PM); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestPtiRspRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to inform firmware to simulate PTI tx done fail case. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_21_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_21_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestPtiTxDoneFail(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdPtiTxFail.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdPtiTxFail.fgIsEnable); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestPtiTxFail, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test frame. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestRvFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+/* PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; */ -+/* TDLS_STATUS u4Status; */ -+ UINT_32 u4Subcmd; -+/* UINT_32 u4BufLen; */ -+ -+ /* parse sub-command */ -+ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(TDLS, INFO, " test rv frame sub command = %u\n", (UINT32) u4Subcmd); -+ -+ /* parse command arguments */ -+ switch (u4Subcmd) { -+ case TDLS_FRM_ACTION_SETUP_REQ: -+ /* simulate to receive a setup request frame */ -+ TdlsCmdTestSetupReqRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_SETUP_RSP: -+ /* simulate to receive a setup response frame */ -+ TdlsCmdTestSetupRspRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_CONFIRM: -+ /* simulate to receive a setup confirm frame */ -+ TdlsCmdTestSetupConfirmRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_TEARDOWN: -+ /* simulate to receive a tear down frame */ -+ TdlsCmdTestTearDownRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_PTI: -+ /* simulate to receive a PTI request frame */ -+ TdlsCmdTestPtiReqRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_PTI_RSP: -+ /* simulate to receive a PTI response frame */ -+ TdlsCmdTestPtiRspRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_DATA_TEST_DATA: -+ /* simulate to receive a DATA frame */ -+ TdlsCmdTestDataRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_CHAN_SWITCH_REQ: -+ /* simulate to receive a channel switch request frame */ -+ TdlsCmdTestChSwReqRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_CHAN_SWITCH_RSP: -+ /* simulate to receive a channel switch response frame */ -+ TdlsCmdTestChSwRspRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_DISCOVERY_REQ: -+ /* simulate to receive a discovery request frame */ -+ TdlsCmdTestDiscoveryReqRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ default: -+ DBGLOG(TDLS, ERROR, " wrong test rv frame sub command\n"); -+ return; -+ } -+ -+/* if (u4Status != TDLS_STATUS_SUCCESS) */ -+ { -+/* DBGLOG(TDLS, ERROR, (" command parse fail\n")); */ -+/* return; */ -+ } -+ -+ /* send command to wifi task to handle */ -+#if 0 -+ kalIoctl(prGlueInfo, -+ TdlsTestFrameSend, -+ (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test setup confirm frame command. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_2_[DialogToken]_[StatusCode]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_1_2_1_0_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestSetupConfirmRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ P_BSS_INFO_T prBssInfo; -+ PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ UINT_8 ucDialogToken, ucStatusCode, aucPeerMac[6]; -+ -+ /* parse arguments */ -+ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ ucStatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: DialogToken=%d StatusCode=%d from %pM\n", -+ __func__, ucDialogToken, ucStatusCode, aucPeerMac); -+ -+ /* allocate/init packet */ -+ prAdapter = prGlueInfo->prAdapter; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = TDLS_FRM_ACTION_CONFIRM; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Status Code */ -+ *pPkt = ucStatusCode; -+ *(pPkt + 1) = 0x00; -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 3. Frame Formation - (4) Dialog token */ -+ *pPkt = ucDialogToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (17) WMM Information element */ -+ if (prAdapter->rWifiVar.fgSupportQoS) { -+ u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, prBssInfo, pPkt, OP_MODE_INFRASTRUCTURE); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ } -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* pass to OS */ -+ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test setup request frame command. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_0_[DialogToken]_[Peer MAC]_[BSSID] -+ -+ iwpriv wlan0 set_str_cmd 0_1_0_1_00:11:22:33:44:01 -+ iwpriv wlan0 set_str_cmd 0_1_0_1_00:11:22:33:44:01_00:22:33:44:11:22 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestSetupReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ P_BSS_INFO_T prBssInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ UINT_8 ucDialogToken, aucPeerMac[6], aucBSSID[6], aucZeroMac[6]; -+ UINT_16 u2CapInfo; -+ -+ /* parse arguments */ -+ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); -+ -+ kalMemZero(aucZeroMac, sizeof(aucZeroMac)); -+ kalMemZero(aucBSSID, sizeof(aucBSSID)); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucBSSID); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: DialogToken=%d from %pM\n", __func__, ucDialogToken, aucPeerMac); -+ -+ /* allocate/init packet */ -+ prAdapter = prGlueInfo->prAdapter; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = TDLS_FRM_ACTION_SETUP_REQ; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Dialog token */ -+ *pPkt = ucDialogToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (4) Capability */ -+ u2CapInfo = assocBuildCapabilityInfo(prAdapter, NULL); -+ WLAN_SET_FIELD_16(pPkt, u2CapInfo); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 4. Append general IEs */ -+ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (10) Extended capabilities element */ -+ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; -+ EXT_CAP_IE(pPkt)->ucLength = 5; -+ -+ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ -+ -+ /* TDLS_EX_CAP_PEER_UAPSD */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); -+ /* TDLS_EX_CAP_CHAN_SWITCH */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); -+ /* TDLS_EX_CAP_TDLS */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18; -+ -+ if (kalMemCmp(aucBSSID, aucZeroMac, 6) == 0) -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ else -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, aucBSSID, 6); -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* pass to OS */ -+ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test setup response frame command. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_1_[DialogToken]_[StatusCode]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_1_1_1_0_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestSetupRspRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ P_BSS_INFO_T prBssInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ UINT_8 ucDialogToken, ucStatusCode, aucPeerMac[6]; -+ UINT_16 u2CapInfo; -+ -+ /* parse arguments */ -+ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ ucStatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: DialogToken=%d StatusCode=%d from %pM\n", -+ __func__, ucDialogToken, ucStatusCode, aucPeerMac); -+ -+ /* allocate/init packet */ -+ prAdapter = prGlueInfo->prAdapter; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = TDLS_FRM_ACTION_SETUP_RSP; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Status Code */ -+ *pPkt = ucStatusCode; -+ *(pPkt + 1) = 0x00; -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 3. Frame Formation - (4) Dialog token */ -+ *pPkt = ucDialogToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (5) Capability */ -+ u2CapInfo = assocBuildCapabilityInfo(prAdapter, NULL); -+ WLAN_SET_FIELD_16(pPkt, u2CapInfo); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 4. Append general IEs */ -+ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (10) Extended capabilities element */ -+ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; -+ EXT_CAP_IE(pPkt)->ucLength = 5; -+ -+ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ -+ -+ /* TDLS_EX_CAP_PEER_UAPSD */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); -+ /* TDLS_EX_CAP_CHAN_SWITCH */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); -+ /* TDLS_EX_CAP_TDLS */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, aucPeerMac, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* pass to OS */ -+ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to inform firmware to skip channel switch timeout function. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_14_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_14_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestScanCtrl(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdScanSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdScanSkip.fgIsEnable); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestScanSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test tear down frame command. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_3_[IsInitiator]_[ReasonCode]_[Peer MAC]_[Where] -+ -+ Where 0 (From driver) or 1 (From FW) -+ -+ iwpriv wlan0 set_str_cmd 0_1_3_1_26_00:11:22:33:44:01_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestTearDownRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ P_BSS_INFO_T prBssInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ BOOLEAN fgIsInitiator; -+ UINT_8 ucReasonCode, aucPeerMac[6]; -+ BOOLEAN fgIsFromWhich; -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ fgIsInitiator = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ ucReasonCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); -+ fgIsFromWhich = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: ReasonCode=%d from %pM %d\n", -+ __func__, ucReasonCode, aucPeerMac, fgIsFromWhich); -+ -+ if (fgIsFromWhich == 0) { -+ /* allocate/init packet */ -+ prAdapter = prGlueInfo->prAdapter; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = TDLS_FRM_ACTION_TEARDOWN; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Reason Code */ -+ *pPkt = ucReasonCode; -+ *(pPkt + 1) = 0x00; -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ if (fgIsInitiator == 1) { -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); -+ } else { -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, aucPeerMac, 6); -+ } -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* pass to OS */ -+ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); -+ } else { -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ kalMemCopy(rCmd.aucPeerMac, aucPeerMac, 6); -+ rCmd.Content.rCmdTearDownRcv.u4ReasonCode = (UINT32) ucReasonCode; -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsTestTearDownRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to inform firmware to skip tx fail case. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_7_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_7_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestTxFailSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdTxFailSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdTxFailSkip.fgIsEnable); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestTxFailSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a test frame command to wifi task. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_12_0_[FrameType]_[DialogToken]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_12_0_0_1_00:11:22:33:44:01 -+* -+* EX: iwpriv wlan0 set_str_cmd 0_12_2_[FrameType]_[DialogToken]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_12_2_0_1_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestTxTdlsFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; -+ UINT32 u4Subcmd; -+ UINT_32 u4BufLen; -+ -+ /* parse sub-command */ -+ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(TDLS, INFO, " test tx tdls frame sub command = %u\n", u4Subcmd); -+ -+ /* parse command arguments */ -+ rCmd.ucFmeType = CmdStringDecParse(prInBuf, &prInBuf, &u4BufLen); -+ -+ switch (u4Subcmd) { -+ case TDLS_FRM_ACTION_SETUP_REQ: -+ case TDLS_FRM_ACTION_SETUP_RSP: -+ case TDLS_FRM_ACTION_CONFIRM: -+ rCmd.ucToken = CmdStringDecParse(prInBuf, &prInBuf, &u4BufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr); -+ -+ DBGLOG(TDLS, INFO, " setup FmeType=%d Token=%d to [%pM]\n", -+ rCmd.ucFmeType, rCmd.ucToken, rCmd.arRspAddr); -+ break; -+ -+ default: -+ DBGLOG(TDLS, ERROR, " wrong test tx frame sub command\n"); -+ return; -+ } -+ -+ /* send command to wifi task to handle */ -+ kalIoctl(prGlueInfo, -+ TdlsTestTdlsFrameSend, -+ (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a test frame command to wifi task. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_0_0_[FrameType]_[DialogToken]_[Cap]_[ExCap]_ -+ [SupRate0]_[SupRate1]_[SupRate2]_[SupRate3]_ -+ [SupChan0]_[SupChan1]_[SupChan2]_[SupChan3]_ -+ [Timeout]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_0_0_0_1_1_7_0_0_0_0_0_0_0_0_300_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestTxFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; -+ TDLS_STATUS u4Status; -+ UINT_32 u4Subcmd; -+ UINT_32 u4BufLen; -+ -+ /* parse sub-command */ -+ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(TDLS, INFO, " test tx frame sub command = %u\n", (UINT32) u4Subcmd); -+ -+ /* parse command arguments */ -+ switch (u4Subcmd) { -+ case TDLS_FRM_ACTION_SETUP_REQ: -+ u4Status = TdlsCmdTestTxFmeSetupReqBufTranslate(prInBuf, u4InBufLen, &rCmd); -+ break; -+ -+ default: -+ DBGLOG(TDLS, ERROR, " wrong test tx frame sub command\n"); -+ return; -+ } -+ -+ if (u4Status != TDLS_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, " command parse fail\n"); -+ return; -+ } -+ -+ /* send command to wifi task to handle */ -+ kalIoctl(prGlueInfo, -+ TdlsTestFrameSend, -+ (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Parse the TDLS test frame command, setup request -+* -+* @param CmdBuf Pointer to the buffer. -+* @param BufLen Record buffer length. -+* @param CmdTspec Pointer to the structure. -+* -+* @retval WLAN_STATUS_SUCCESS: Translate OK. -+* @retval WLAN_STATUS_FAILURE: Translate fail. -+* @usage iwpriv wlan0 set_str_cmd [tdls]_[command] -+* -+* EX: iwpriv wlan0 set_str_cmd 0_0_0_[FrameType]_[DialogToken]_[Cap]_[ExCap]_ -+ [SupRate0]_[SupRate1]_[SupRate2]_[SupRate3]_ -+ [SupChan0]_[SupChan1]_[SupChan2]_[SupChan3]_ -+ [Timeout]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_0_0_0_1_1_7_0_0_0_0_0_0_0_0_300_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsCmdTestTxFmeSetupReqBufTranslate(UINT_8 *pCmdBuf, UINT_32 u4BufLen, PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd) -+{ -+/* dumpMemory8(ANDROID_LOG_INFO, pCmdBuf, u4BufLen); */ -+ -+ prCmd->ucFmeType = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->ucToken = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->u2Cap = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->ucExCap = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupRate[0] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupRate[1] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupRate[2] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupRate[3] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupChan[0] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupChan[1] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupChan[2] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupChan[3] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->u4Timeout = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ CmdStringMacParse(pCmdBuf, &pCmdBuf, &u4BufLen, prCmd->arRspAddr); -+ -+ DBGLOG(TDLS, INFO, " command content =\n"); -+ DBGLOG(TDLS, INFO, "\tPeer MAC = %pM\n", (prCmd->arRspAddr)); -+ DBGLOG(TDLS, INFO, "\tToken = %u, Cap = 0x%x, ExCap = 0x%x, Timeout = %us FrameType = %u\n", -+ (UINT32) prCmd->ucToken, prCmd->u2Cap, prCmd->ucExCap, -+ (UINT32) prCmd->u4Timeout, (UINT32) prCmd->ucFmeType); -+ DBGLOG(TDLS, INFO, "\tSupRate = 0x%x %x %x %x\n", -+ prCmd->arSupRate[0], prCmd->arSupRate[1], prCmd->arSupRate[2], prCmd->arSupRate[3]); -+ DBGLOG(TDLS, INFO, "\tSupChan = %d %d %d %d\n", -+ prCmd->arSupChan[0], prCmd->arSupChan[1], prCmd->arSupChan[2], prCmd->arSupChan[3]); -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update a TDLS peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_3_[Responder MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_3_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestUpdatePeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; -+ struct wireless_dev *prWdev; -+ -+ /* reset */ -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr); -+ -+ /* init */ -+ rCmd.rPeerInfo.supported_rates = rCmd.arSupRate; -+ rCmd.rPeerInfo.ht_capa = &rCmd.rHtCapa; -+ rCmd.rPeerInfo.vht_capa = &rCmd.rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */ -+ rCmd.rPeerInfo.sta_flags_set = BIT(NL80211_STA_FLAG_TDLS_PEER); -+ rCmd.rPeerInfo.uapsd_queues = 0xf; /* all AC */ -+ rCmd.rPeerInfo.max_sp = 0; /* delivery all packets */ -+ -+ /* send command to wifi task to handle */ -+ prWdev = prGlueInfo->prDevHandler->ieee80211_ptr; -+ mtk_cfg80211_add_station(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, &rCmd.rPeerInfo); -+ -+ /* update */ -+ TdlsexCfg80211TdlsOper(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, NL80211_TDLS_ENABLE_LINK); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a Null frame from the peer. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+* EX: iwpriv wlan0 set_str_cmd 0_5_[Responder MAC]_[PM bit] -+ -+ iwpriv wlan0 set_str_cmd 0_5_00:11:22:33:44:01_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestNullRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ rCmd.Content.rCmdNullRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: [%pM] u4PM = %u\n", -+ __func__, (rCmd.aucPeerMac), (UINT32) rCmd.Content.rCmdNullRcv.u4PM); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestNullRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a data frame to the peer periodically. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] u4Param no use -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_15_[Responder MAC]_[Interval: ms]_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_15_00:11:22:33:44:01_5000_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID TdlsTimerTestDataContSend(ADAPTER_T *prAdapter, UINT_32 u4Param) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *prPkt; -+ -+ /* init */ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* allocate a data frame */ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1000, &prPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s allocate pkt fail!\n", __func__); -+ return; -+ } -+ -+ /* init dev */ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s prMsduInfo->dev == NULL!\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* init packet */ -+ prMsduInfo->len = 1000; -+ kalMemCopy(prMsduInfo->data, aucTdlsTestDataSPeerMac, 6); -+ kalMemCopy(prMsduInfo->data + 6, prAdapter->rMyMacAddr, 6); -+ *(UINT_16 *) (prMsduInfo->data + 12) = 0x0800; -+ -+ DBGLOG(TDLS, INFO, " %s try to send a data frame to %pM\n", -+ __func__, aucTdlsTestDataSPeerMac); -+ -+ /* simulate OS to send the packet */ -+ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); -+ -+ /* restart test timer */ -+ cnmTimerStartTimer(prAdapter, &rTdlsTimerTestDataSend, u2TdlsTestDataSInterval); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a Channel Switch Request frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestChStReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_REQ; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a Channel Switch Response frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestChStRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_RSP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to send a test frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd; -+ P_BSS_INFO_T prBssInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ -+ /* sanity check */ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ DBGLOG(TDLS, INFO, " %s\n", __func__); -+ -+ if (u4SetBufferLen == 0) -+ return TDLS_STATUS_INVALID_LENGTH; -+ -+ /* allocate/init packet */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ prCmd = (PARAM_CUSTOM_TDLS_CMD_STRUCT_T *) pvSetBuffer; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ *pu4SetInfoLen = u4SetBufferLen; -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prCmd->arRspAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = prCmd->ucFmeType; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Dialog token */ -+ *pPkt = prCmd->ucToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (4) Capability */ -+ WLAN_SET_FIELD_16(pPkt, prCmd->u2Cap); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 4. Append general IEs */ -+ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (10) Extended capabilities element */ -+ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; -+ EXT_CAP_IE(pPkt)->ucLength = 5; -+ -+ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ -+ -+ if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD) -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); -+ if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH) -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); -+ if (prCmd->ucExCap & TDLS_EX_CAP_TDLS) -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (12) Timeout interval element (TPK Key Lifetime) */ -+ TIMEOUT_INTERVAL_IE(pPkt)->ucId = ELEM_ID_TIMEOUT_INTERVAL; -+ TIMEOUT_INTERVAL_IE(pPkt)->ucLength = 5; -+ -+ TIMEOUT_INTERVAL_IE(pPkt)->ucType = IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME; -+ TIMEOUT_INTERVAL_IE(pPkt)->u4Value = htonl(prCmd->u4Timeout); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prCmd->arRspAddr, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* 5. send the data frame */ -+ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a NULL frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestNullRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_NULL_RCV; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a PTI frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestPtiReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_REQ; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a PTI response frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestPtiRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_RSP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a Tear Down frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestTearDownRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_TEAR_DOWN; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a data frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestDataRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_DATA_RCV; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to skip PTI tx fail status. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestPtiTxFail(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_TX_FAIL; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to send a TDLS action frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+* EX: iwpriv wlan0 set_str_cmd 0_12_0_[FrameType]_[DialogToken]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_12_0_0_1_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestTdlsFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd; -+ struct wireless_dev *prWdev; -+ -+ /* sanity check */ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ DBGLOG(TDLS, INFO, " %s\n", __func__); -+ -+ if (u4SetBufferLen == 0) -+ return TDLS_STATUS_INVALID_LENGTH; -+ -+ /* allocate/init packet */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ prCmd = (PARAM_CUSTOM_TDLS_CMD_STRUCT_T *) pvSetBuffer; -+ prWdev = (struct wireless_dev *)prGlueInfo->prDevHandler->ieee80211_ptr; -+ -+ TdlsexCfg80211TdlsMgmt(prWdev->wiphy, NULL, -+ prCmd->arRspAddr, prCmd->ucFmeType, 1, -+ 0, 0, /* open/none */ -+ FALSE, NULL, 0); -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to skip tx fail status. So always success in tx done in firmware. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestTxFailSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_TX_FAIL_SKIP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to skip to do keep alive function in firmware. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestKeepAliveSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_KEEP_ALIVE_SKIP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to skip channel switch timeout. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestChSwTimeoutSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_TIMEOUT_SKIP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to skip scan request. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestScanSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_SCAN_SKIP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+#endif /* TDLS_CFG_CMD_TEST */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to configure channel switch parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsChSwConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_CHSW_CONF; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update channel switch parameters. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_9_[TDLS Peer MAC]_ -+ [NetworkTypeIndex]_[1 (Enable) or (0) Disable]_[1 (Start) or 0 (Stop)]_ -+ [RegClass]_[Chan]_[SecChanOff]_[1 (Reqular) or (0) One Shot] -+ -+ RegulatoryClass: TODO (reference to Annex I of 802.11n spec.) -+ Secondary Channel Offset: 0 (SCN - no secondary channel) -+ 1 (SCA - secondary channel above) -+ 2 (SCB - secondary channel below) -+ SwitchTime: units of microseconds -+ -+ iwpriv wlan0 set_str_cmd 0_9_00:11:22:33:44:01_0_1_0_0_1_0_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdChSwConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ -+ rCmd.Content.rCmdChSwConf.ucNetTypeIndex = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.fgIsChSwEnabled = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.fgIsChSwStarted = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.ucRegClass = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.ucTargetChan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.ucSecChanOff = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.fgIsChSwRegular = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: %pM ucNetTypeIndex=%d, fgIsChSwEnabled=%d, fgIsChSwStarted=%d", -+ __func__, (rCmd.aucPeerMac), -+ rCmd.Content.rCmdChSwConf.ucNetTypeIndex, -+ rCmd.Content.rCmdChSwConf.fgIsChSwEnabled, -+ rCmd.Content.rCmdChSwConf.fgIsChSwStarted); -+ DBGLOG(TDLS, INFO, " RegClass=%d, TargetChan=%d, SecChanOff=%d, Regular=%d\n", -+ rCmd.Content.rCmdChSwConf.ucRegClass, -+ rCmd.Content.rCmdChSwConf.ucTargetChan, -+ rCmd.Content.rCmdChSwConf.ucSecChanOff, rCmd.Content.rCmdChSwConf.fgIsChSwRegular); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsChSwConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display TDLS related information. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_18_[Peer MAC]_[Network Interface ID]_[IsClear] -+ -+ Network Interface ID: reference to ENUM_NETWORK_TYPE_INDEX_T -+ -+ typedef enum _ENUM_NETWORK_TYPE_INDEX_T { -+ NETWORK_TYPE_AIS_INDEX = 0, -+ NETWORK_TYPE_P2P_INDEX, -+ NETWORK_TYPE_BOW_INDEX, -+ NETWORK_TYPE_INDEX_NUM -+ } ENUM_NETWORK_TYPE_INDEX_T; -+ -+ iwpriv wlan0 set_str_cmd 0_18_00:00:00:00:00:00_0_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ rCmd.ucNetTypeIndex = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdInfoDisplay.fgIsToClearAllHistory = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, " %s: Command PeerMac=%pM in BSS%u\n", -+ __func__, (rCmd.aucPeerMac), rCmd.ucNetTypeIndex); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsInfoDisplay, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display key related information. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_20 -+ -+ iwpriv wlan0 set_str_cmd 0_20 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdKeyInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ -+ DBGLOG(TDLS, INFO, " %s\n", __func__); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsKeyInfoDisplay, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update MIB parameters. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_6_[TdlsEn]_[UapsdEn]_[PsmEn]_[PtiWin]_[CWCap]_ -+ [AckMisRetry]_[RspTimeout]_[CWPbDelay]_[DRWin]_[LowestAcInt] -+ -+ iwpriv wlan0 set_str_cmd 0_6_1_1_0_1_1_3_5_1000_2_1 -+ -+ reference to TDLS_CMD_CORE_MIB_PARAM_UPDATE_T -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdMibParamUpdate(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* reset */ -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ -+ /* parse arguments */ -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TunneledDirectLinkSetupImplemented = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDBufferSTAActivated = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerPSMActivated = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDIndicationWindow = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSChannelSwitchingActivated = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerSTAMissingAckRetryLimit = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSResponseTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSProbeDelay = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSDiscoveryRequestWindow = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSACDeterminationInterval = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, " MIB param = %d %d %d %d %d %d %d %d %d %d\n", -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TunneledDirectLinkSetupImplemented, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDBufferSTAActivated, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerPSMActivated, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDIndicationWindow, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSChannelSwitchingActivated, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerSTAMissingAckRetryLimit, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSResponseTimeout, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSProbeDelay, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSDiscoveryRequestWindow, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSACDeterminationInterval); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsMibParamUpdate, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update setup parameters. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_17_[20/40 Support] -+ -+ iwpriv wlan0 set_str_cmd 0_17_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdSetupConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ -+ rCmd.Content.rCmdSetupConf.fgIs2040Supported = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: rCmdSetupConf=%d\n", __func__, rCmd.Content.rCmdSetupConf.fgIs2040Supported); -+ -+ /* command to do this */ -+ prGlueInfo->rTdlsLink.fgIs2040Sup = rCmd.Content.rCmdSetupConf.fgIs2040Supported; -+ -+ rStatus = kalIoctl(prGlueInfo, TdlsSetupConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update UAPSD parameters. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_8_[SP timeout skip]_[PTI timeout skip] -+ -+ iwpriv wlan0 set_str_cmd 0_8_1_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdUapsdConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ -+ /* UAPSD Service Period */ -+ rCmd.Content.rCmdUapsdConf.fgIsSpTimeoutSkip = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdUapsdConf.fgIsPtiTimeoutSkip = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ /* PTI Service Period */ -+ fgIsPtiTimeoutSkip = rCmd.Content.rCmdUapsdConf.fgIsPtiTimeoutSkip; -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsSpTimeoutSkip=%d, fgIsPtiTimeoutSkip=%d\n", -+ __func__, rCmd.Content.rCmdUapsdConf.fgIsSpTimeoutSkip, fgIsPtiTimeoutSkip); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsUapsdConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display TDLS all information. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+* iwpriv wlan0 set_str_cmd 0_18_00:00:00:00:00:00_0_0 -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ TDLS_CMD_CORE_T *prCmdContent; -+ STA_RECORD_T *prStaRec; -+ TDLS_INFO_LINK_T *prLink; -+ UINT32 u4StartIdx; -+ UINT32 u4PeerNum; -+ BOOLEAN fgIsListAll; -+ UINT8 ucMacZero[6]; -+ UINT32 u4HisIdx; -+ UINT8 ucNetTypeIndex; -+ -+ /* init */ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ u4StartIdx = 0; -+ u4PeerNum = 1; -+ fgIsListAll = TRUE; -+ kalMemZero(ucMacZero, sizeof(ucMacZero)); -+ ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ -+ /* display common information */ -+ DBGLOG(TDLS, TRACE, "TDLS common:\n"); -+ DBGLOG(TDLS, TRACE, "\t\trFreeSwRfbList=%u\n", (UINT32) prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); -+ DBGLOG(TDLS, TRACE, "\t\tjiffies=%u %ums (HZ=%d)\n", (UINT32) jiffies, (UINT32) kalGetTimeTick(), HZ); -+ -+ /* display disconnection history information */ -+ DBGLOG(TDLS, TRACE, "TDLS link history: %d\n", prGlueInfo->rTdlsLink.u4LinkIdx); -+ -+ for (u4HisIdx = prGlueInfo->rTdlsLink.u4LinkIdx + 1; u4HisIdx < TDLS_LINK_HISTORY_MAX; u4HisIdx++) { -+ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4HisIdx]; -+ -+ if (kalMemCmp(prLink->aucPeerMac, ucMacZero, 6) == 0) -+ continue; /* skip all zero */ -+ -+ DBGLOG(TDLS, TRACE, -+ "\t\t%d. %pM jiffies start(%lu %ums)end(%lu %ums)Reason(%u)fromUs(%u)Dup(%u)HT(%u)\n", -+ u4HisIdx, prLink->aucPeerMac, -+ prLink->jiffies_start, jiffies_to_msecs(prLink->jiffies_start), -+ prLink->jiffies_end, jiffies_to_msecs(prLink->jiffies_end), -+ prLink->ucReasonCode, -+ prLink->fgIsFromUs, prLink->ucDupCount, (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP)); -+ -+ if (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP) { -+ DBGLOG(TDLS, TRACE, -+ "\t\t\tBA (0x%x %x %x %x %x %x %x %x)\n", -+ prLink->ucHtBa[0], prLink->ucHtBa[1], -+ prLink->ucHtBa[2], prLink->ucHtBa[3], -+ prLink->ucHtBa[4], prLink->ucHtBa[5], prLink->ucHtBa[6], prLink->ucHtBa[7]); -+ } -+ } -+ for (u4HisIdx = 0; u4HisIdx <= prGlueInfo->rTdlsLink.u4LinkIdx; u4HisIdx++) { -+ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4HisIdx]; -+ -+ if (kalMemCmp(prLink->aucPeerMac, ucMacZero, 6) == 0) -+ continue; /* skip all zero, use continue, not break */ -+ -+ DBGLOG(TDLS, TRACE, -+ "\t\t%d. %pM jiffies start(%lu %ums)end(%lu %ums)Reason(%u)fromUs(%u)Dup(%u)HT(%u)\n", -+ u4HisIdx, (prLink->aucPeerMac), -+ prLink->jiffies_start, jiffies_to_msecs(prLink->jiffies_start), -+ prLink->jiffies_end, jiffies_to_msecs(prLink->jiffies_end), -+ prLink->ucReasonCode, -+ prLink->fgIsFromUs, prLink->ucDupCount, (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP)); -+ -+ if (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP) { -+ DBGLOG(TDLS, TRACE, -+ "\t\t\tBA (0x%x %x %x %x %x %x %x %x)\n", -+ prLink->ucHtBa[0], prLink->ucHtBa[1], -+ prLink->ucHtBa[2], prLink->ucHtBa[3], -+ prLink->ucHtBa[4], prLink->ucHtBa[5], prLink->ucHtBa[6], prLink->ucHtBa[7]); -+ } -+ } -+ DBGLOG(TDLS, TRACE, "\n"); -+ -+ /* display link information */ -+ if (prCmdContent != NULL) { -+ if (kalMemCmp(prCmdContent->aucPeerMac, ucMacZero, 6) != 0) { -+ prStaRec = cnmGetStaRecByAddress(prAdapter, -+ prCmdContent->ucNetTypeIndex, prCmdContent->aucPeerMac); -+ if (prStaRec == NULL) -+ fgIsListAll = TRUE; -+ } -+ -+ ucNetTypeIndex = prCmdContent->ucNetTypeIndex; -+ } -+ -+ while (1) { -+ if (fgIsListAll == TRUE) { -+ /* list all TDLS peers */ -+ prStaRec = cnmStaTheTypeGet(prAdapter, ucNetTypeIndex, STA_TYPE_TDLS_PEER, &u4StartIdx); -+ if (prStaRec == NULL) -+ break; -+ } -+ -+ DBGLOG(TDLS, TRACE, "-------- TDLS %d: 0x %pM\n", u4PeerNum, (prStaRec->aucMacAddr)); -+ DBGLOG(TDLS, TRACE, "\t\t\t State %d, PM %d, Cap 0x%x\n", -+ prStaRec->ucStaState, prStaRec->fgIsInPS, prStaRec->u2CapInfo); -+ DBGLOG(TDLS, TRACE, "\t\t\t SetupDisable %d, ChSwDisable %d\n", -+ prStaRec->fgTdlsIsProhibited, prStaRec->fgTdlsIsChSwProhibited); -+ -+ if (fgIsListAll == FALSE) -+ break; /* only list one */ -+ } -+ -+ /* check if we need to clear all histories */ -+ if ((prCmdContent != NULL) && (prCmdContent->Content.rCmdInfoDisplay.fgIsToClearAllHistory == TRUE)) { -+ kalMemZero(&prGlueInfo->rTdlsLink, sizeof(prGlueInfo->rTdlsLink)); -+ prGlueInfo->rTdlsLink.u4LinkIdx = TDLS_LINK_HISTORY_MAX - 1; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display key information. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsKeyInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_KEY_INFO; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to record a disconnection event. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure -+* \param[in] fgIsTearDown TRUE: the link is torn down -+* \param[in] pucPeerMac Pointer to the MAC of the TDLS peer -+* \param[in] fgIsFromUs TRUE: tear down is from us -+* \param[in] u2ReasonCode Disconnection reason (TDLS_REASON_CODE) -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID -+TdlsLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, -+ BOOLEAN fgIsTearDown, -+ UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode, VOID *prOthers) -+{ -+ TDLS_INFO_LINK_T *prLink; -+ -+ DBGLOG(TDLS, INFO, -+ " %s: record history for %pM %d %d %d %d\n", -+ __func__, pucPeerMac, prGlueInfo->rTdlsLink.u4LinkIdx, -+ fgIsTearDown, fgIsFromUs, u2ReasonCode); -+ -+ /* check duplicate one */ -+ if (prGlueInfo->rTdlsLink.u4LinkIdx >= TDLS_LINK_HISTORY_MAX) { -+ DBGLOG(TDLS, ERROR, " %s: u4LinkIdx >= TDLS_LINK_HISTORY_MAX\n", __func__); -+ -+ /* reset to 0 */ -+ prGlueInfo->rTdlsLink.u4LinkIdx = 0; -+ } -+ -+ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[prGlueInfo->rTdlsLink.u4LinkIdx]; -+ -+ if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) == 0) { -+ if ((prLink->ucReasonCode == u2ReasonCode) && (prLink->fgIsFromUs == fgIsFromUs)) { -+ /* same Peer MAC, Reason Code, Trigger source */ -+ if (fgIsTearDown == TRUE) { -+ if (prLink->jiffies_end != 0) { -+ /* already torn down */ -+ prLink->ucDupCount++; -+ return; -+ } -+ } else { -+ /* already built */ -+ prLink->ucDupCount++; -+ return; -+ } -+ } -+ } -+ -+ /* search old entry */ -+ if (fgIsTearDown == TRUE) { -+ /* TODO: need to search all entries to find it if we support multiple TDLS link design */ -+ if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) != 0) { -+ /* error! can not find the link entry */ -+ DBGLOG(TDLS, INFO, " %s: cannot find the same entry!!!\n", __func__); -+ return; -+ } -+ -+ prLink->jiffies_end = jiffies; -+ prLink->ucReasonCode = (UINT8) u2ReasonCode; -+ prLink->fgIsFromUs = fgIsFromUs; -+ } else { -+ /* record new one */ -+ prGlueInfo->rTdlsLink.u4LinkIdx++; -+ if (prGlueInfo->rTdlsLink.u4LinkIdx >= TDLS_LINK_HISTORY_MAX) -+ prGlueInfo->rTdlsLink.u4LinkIdx = 0; -+ -+ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[prGlueInfo->rTdlsLink.u4LinkIdx]; -+ -+ prLink->jiffies_start = jiffies; -+ prLink->jiffies_end = 0; -+ kalMemCopy(&prLink->aucPeerMac, pucPeerMac, 6); -+ prLink->ucReasonCode = 0; -+ prLink->fgIsFromUs = (UINT8) fgIsFromUs; -+ prLink->ucDupCount = 0; -+ -+ if (prOthers != NULL) { -+ /* record other parameters */ -+ TDLS_LINK_HIS_OTHERS_T *prHisOthers; -+ -+ prHisOthers = (TDLS_LINK_HIS_OTHERS_T *) prOthers; -+ if (prHisOthers->fgIsHt == TRUE) -+ prLink->ucHtCap |= TDLS_INFO_LINK_HT_CAP_SUP; -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update a disconnection event. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure -+* \param[in] pucPeerMac Pointer to the MAC of the TDLS peer -+* \param[in] eFmeStatus TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME -+* \param[in] pInfo other information -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID -+TdlsLinkHistoryRecordUpdate(GLUE_INFO_T *prGlueInfo, -+ UINT8 *pucPeerMac, TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus, VOID *pInfo) -+{ -+ TDLS_INFO_LINK_T *prLink; -+ UINT32 u4LinkIdx; -+ UINT32 u4Tid; -+ -+ /* sanity check */ -+ if ((eFmeStatus < TDLS_HOST_EVENT_SF_BA) || (eFmeStatus > TDLS_HOST_EVENT_SF_BA_RSP_DECLINE)) { -+ /* do not care these frames */ -+ return; -+ } -+ -+ DBGLOG(TDLS, INFO, -+ " %s: update history for %pM %d %d\n", -+ __func__, (pucPeerMac), prGlueInfo->rTdlsLink.u4LinkIdx, eFmeStatus); -+ -+ /* init */ -+ u4LinkIdx = prGlueInfo->rTdlsLink.u4LinkIdx; -+ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4LinkIdx]; -+ -+ /* TODO: need to search all entries to find it if we support multiple TDLS link design */ -+ if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) != 0) { -+ /* error! can not find the link entry */ -+ DBGLOG(TDLS, INFO, " %s: cannot find the same entry!!!\n", __func__); -+ return; -+ } -+ -+ /* update */ -+ u4Tid = *(UINT32 *) pInfo; -+ switch (eFmeStatus) { -+ case TDLS_HOST_EVENT_SF_BA: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP; -+ break; -+ -+ case TDLS_HOST_EVENT_SF_BA_OK: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP_OK; -+ break; -+ -+ case TDLS_HOST_EVENT_SF_BA_DECLINE: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP_DECLINE; -+ break; -+ -+ case TDLS_HOST_EVENT_SF_BA_PEER: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_PEER; -+ break; -+ -+ case TDLS_HOST_EVENT_SF_BA_RSP_OK: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_RSP_OK; -+ break; -+ -+ case TDLS_HOST_EVENT_SF_BA_RSP_DECLINE: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_RSP_DECLINE; -+ break; -+ } -+ -+ /* display TDLS link history */ -+ TdlsInfoDisplay(prGlueInfo->prAdapter, NULL, 0, NULL); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to configure TDLS MIB parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsMibParamUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_MIB_UPDATE; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to configure TDLS SETUP parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsSetupConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_SETUP_CONF; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to configure UAPSD parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsUapsdConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_UAPSD_CONF; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update frame status. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsEventFmeStatus(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus; -+ STA_RECORD_T *prStaRec; -+ UINT32 u4Tid; -+ -+ /* init */ -+ u4Tid = *(UINT32 *) prInBuf; -+ prInBuf += 4; /* skip u4EventSubId */ -+ -+ /* sanity check */ -+ prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *prInBuf); -+ if ((prStaRec == NULL) || (!IS_TDLS_STA(prStaRec))) -+ return; -+ prInBuf++; -+ -+ /* update status */ -+ eFmeStatus = *prInBuf; -+ TdlsLinkHistoryRecordUpdate(prGlueInfo, prStaRec->aucMacAddr, eFmeStatus, &u4Tid); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to collect TDLS statistics from firmware. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsEventStatistics(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ STA_RECORD_T *prStaRec; -+ STAT_CNT_INFO_FW_T *prStat; -+ UINT32 u4RateId; -+ -+ /* init */ -+ prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *prInBuf); -+ if ((prStaRec == NULL) || (!IS_TDLS_STA(prStaRec))) -+ return; -+ -+ prInBuf += 4; /* skip prStaRec->ucIndex */ -+ -+ /* update statistics */ -+ kalMemCopy(&prStaRec->rTdlsStatistics.rFw, prInBuf, sizeof(prStaRec->rTdlsStatistics.rFw)); -+ -+ /* display statistics */ -+ prStat = &prStaRec->rTdlsStatistics.rFw; -+ -+ DBGLOG(TDLS, TRACE, " peer [%pM] statistics:\n", (prStaRec->aucMacAddr)); -+ DBGLOG(TDLS, TRACE, "\t\tT%d %d %d (P%d %d) (%dus) - E%d 0x%x - R%d (P%d)\n", -+ prStat->u4NumOfTx, prStat->u4NumOfTxOK, prStat->u4NumOfTxRetry, -+ prStat->u4NumOfPtiRspTxOk, prStat->u4NumOfPtiRspTxErr, -+ prStat->u4TxDoneAirTimeMax, -+ prStat->u4NumOfTxErr, prStat->u4TxErrBitmap, prStat->u4NumOfRx, prStat->u4NumOfPtiRspRx); -+ -+ DBGLOG(TDLS, TRACE, "\t\t"); -+ -+ for (u4RateId = prStat->u4TxRateOkHisId; u4RateId < STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM; u4RateId++) -+ DBGLOG(TDLS, TRACE, -+ "%d(%d) ", prStat->aucTxRateOkHis[u4RateId][0], prStat->aucTxRateOkHis[u4RateId][1]); -+ for (u4RateId = 0; u4RateId < prStat->u4TxRateOkHisId; u4RateId++) -+ DBGLOG(TDLS, TRACE, -+ "%d(%d) ", prStat->aucTxRateOkHis[u4RateId][0], prStat->aucTxRateOkHis[u4RateId][1]); -+ -+ DBGLOG(TDLS, TRACE, "\n\n"); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to do tear down. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsEventTearDown(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ STA_RECORD_T *prStaRec; -+ UINT16 u2ReasonCode; -+ UINT32 u4TearDownSubId; -+ UINT8 *pMac, aucZeroMac[6]; -+ -+ /* init */ -+ u4TearDownSubId = *(UINT32 *) prInBuf; -+ kalMemZero(aucZeroMac, sizeof(aucZeroMac)); -+ pMac = aucZeroMac; -+ -+ prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *(prInBuf + 4)); -+ if (prStaRec != NULL) -+ pMac = prStaRec->aucMacAddr; -+ -+ /* handle */ -+ if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) { -+ DBGLOG(TDLS, WARN, " %s: peer [%pM] Reason=PTI timeout\n", -+ __func__, pMac); -+ } else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_AGE_TIMEOUT) { -+ DBGLOG(TDLS, WARN, " %s: peer [%pM] Reason=AGE timeout\n", -+ __func__, pMac); -+ } else { -+ DBGLOG(TDLS, WARN, " %s: peer [%pM] Reason=%d\n", -+ __func__, pMac, u4TearDownSubId); -+ } -+ -+ /* sanity check */ -+ if (prStaRec == NULL) -+ return; -+ -+ if (fgIsPtiTimeoutSkip == TRUE) { -+ /* skip PTI timeout event */ -+ if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) { -+ DBGLOG(TDLS, WARN, " %s: skip PTI timeout\n", __func__); -+ return; -+ } -+ } -+ -+ /* record history */ -+ if (u4TearDownSubId == TDLS_HOST_EVENT_TD_AGE_TIMEOUT) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_SEND_FAIL) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_FAIL; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_SEND_MAX_FAIL) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_MAX_FAIL; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_WRONG_NETWORK_IDX) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WRONG_NETWORK_IDX; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_NON_STATE3) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_NON_STATE3; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_LOST_TEAR_DOWN) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_LOST_TEAR_DOWN; -+ else { -+ /* shall not be here */ -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_UNKNOWN; -+ } -+ -+ TdlsLinkHistoryRecord(prGlueInfo, TRUE, prStaRec->aucMacAddr, TRUE, u2ReasonCode, NULL); -+ -+ /* correct correct reason code for PTI or AGE timeout to supplicant */ -+ if ((u2ReasonCode == TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT) || -+ (u2ReasonCode == TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT)) { -+ u2ReasonCode = TDLS_REASON_CODE_UNREACHABLE; -+ } -+ -+ /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */ -+ cfg80211_tdls_oper_request(prGlueInfo->prDevHandler, -+ prStaRec->aucMacAddr, NL80211_TDLS_TEARDOWN, u2ReasonCode, GFP_ATOMIC); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to do tx down. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsEventTxDone(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ /* UINT32 u4FmeIdx; */ -+ UINT8 *pucFmeHdr; -+ UINT8 ucErrStatus; -+ -+ ucErrStatus = *(UINT32 *) prInBuf; -+ -+ pucFmeHdr = prInBuf + 4; /* skip ucErrStatus */ -+ -+ if (ucErrStatus == 0) -+ DBGLOG(TDLS, TRACE, " %s: OK to tx a TDLS action:", __func__); -+ else -+ DBGLOG(TDLS, TRACE, " %s: fail to tx a TDLS action (err=0x%x):", __func__, ucErrStatus); -+ #if 0 -+ /* dump TX packet content from wlan header */ -+ for (u4FmeIdx = 0; u4FmeIdx < (u4InBufLen - 4); u4FmeIdx++) { -+ if ((u4FmeIdx % 16) == 0) -+ DBGLOG(TDLS, TRACE, "\n"); -+ -+ DBGLOG(TDLS, TRACE, "%02x ", *pucFmeHdr++); -+ } -+ DBGLOG(TDLS, TRACE, "\n\n"); -+ #endif -+} -+ -+/******************************************************************************* -+* P U B L I C F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to parse TDLS Extended Capabilities element. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexBssExtCapParse(STA_RECORD_T *prStaRec, UINT_8 *pucIE) -+{ -+ UINT_8 *pucIeExtCap; -+ -+ /* sanity check */ -+ if ((prStaRec == NULL) || (pucIE == NULL)) -+ return; -+ -+ if (IE_ID(pucIE) != ELEM_ID_EXTENDED_CAP) -+ return; -+ -+ /* -+ from bit0 ~ -+ -+ bit 38: TDLS Prohibited -+ The TDLS Prohibited subfield indicates whether the use of TDLS is prohibited. The -+ field is set to 1 to indicate that TDLS is prohibited and to 0 to indicate that TDLS is -+ allowed. -+ */ -+ if (IE_LEN(pucIE) < 5) -+ return; /* we need 39/8 = 5 bytes */ -+ -+ /* init */ -+ prStaRec->fgTdlsIsProhibited = FALSE; -+ prStaRec->fgTdlsIsChSwProhibited = FALSE; -+ -+ /* parse */ -+ pucIeExtCap = pucIE + 2; -+ pucIeExtCap += 4; /* shift to the byte we care about */ -+ -+ if ((*pucIeExtCap) & BIT(38 - 32)) -+ prStaRec->fgTdlsIsProhibited = TRUE; -+ if ((*pucIeExtCap) & BIT(39 - 32)) -+ prStaRec->fgTdlsIsChSwProhibited = TRUE; -+ -+ DBGLOG(TDLS, TRACE, -+ " %s: AP [%pM] tdls prohibit bit=%d %d\n", -+ __func__, -+ prStaRec->aucMacAddr, prStaRec->fgTdlsIsProhibited, prStaRec->fgTdlsIsChSwProhibited); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to transmit a TDLS data frame from nl80211. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] -+* \param[in] -+* \param[in] buf includes RSN IE + FT IE + Lifetimeout IE -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+TdlsexCfg80211TdlsMgmt(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, u8 action_code, u8 dialog_token, -+ u16 status_code, u32 peer_capability, -+ bool initiator, const u8 *buf, size_t len) -+{ -+ ADAPTER_T *prAdapter; -+ GLUE_INFO_T *prGlueInfo; -+ BSS_INFO_T *prAisBssInfo; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ TDLS_MGMT_TX_INFO *prMgmtTxInfo; -+ -+ /* -+ Have correct behavior for STAUT receiving TDLS Setup Request after sending TDLS -+ Set Request and before receiving TDLS Setup Response: -+ -- Source Address of received Request is higher than own MAC address -+ -- Source Address of received Request is lower than own MAC address -+ -+ ==> STA with larger MAC address will send the response frame. -+ -+ Supplicant will do this in wpa_tdls_process_tpk_m1(). -+ */ -+ -+ /* sanity check */ -+ if ((wiphy == NULL) || (peer == NULL)) { -+ DBGLOG(TDLS, ERROR, " %s: wrong 0x%p 0x%p!\n", __func__, wiphy, peer); -+ return -EINVAL; -+ } -+ -+ DBGLOG(TDLS, INFO, " %s: [%pM] %d %d %d 0x%p %u\n", -+ __func__, peer, action_code, dialog_token, status_code, buf, (UINT32) len); -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) wiphy_priv(wiphy); -+ if (prGlueInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: wrong prGlueInfo 0x%p!\n", __func__, prGlueInfo); -+ return -EINVAL; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ if (prAdapter->fgTdlsIsSup == FALSE) { -+ DBGLOG(TDLS, ERROR, " %s: firmware TDLS is not supported!\n", __func__); -+ return -EBUSY; -+ } -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ if (prAisBssInfo->fgTdlsIsProhibited == TRUE) { -+ /* do not send anything if TDLS is prohibited in the BSS */ -+ return 0; -+ } -+ -+ prMgmtTxInfo = kalMemAlloc(sizeof(TDLS_MGMT_TX_INFO), VIR_MEM_TYPE); -+ if (prMgmtTxInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate fail!\n", __func__); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO)); -+ -+ if (peer != NULL) -+ kalMemCopy(prMgmtTxInfo->aucPeer, peer, 6); -+ prMgmtTxInfo->ucActionCode = action_code; -+ prMgmtTxInfo->ucDialogToken = dialog_token; -+ prMgmtTxInfo->u2StatusCode = status_code; -+ -+ if (buf != NULL) { -+ if (len > sizeof(prMgmtTxInfo->aucSecBuf)) { -+ kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO)); -+ return -EINVAL; -+ } -+ prMgmtTxInfo->u4SecBufLen = len; -+ kalMemCopy(prMgmtTxInfo->aucSecBuf, buf, len); -+ } -+ -+ /* send the TDLS action data frame */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsexMgmtCtrl, -+ prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ /* -+ clear all content to avoid any bug if we dont yet execute TdlsexMgmtCtrl() -+ then kalIoctl finishes -+ */ -+ kalMemZero(prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO)); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s enable or disable link fail:%x\n", __func__, rStatus); -+ kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO)); -+ return -EINVAL; -+ } -+ -+ kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO)); -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to enable or disable TDLS link from upper layer. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] -+* \param[in] -+* \param[in] buf includes RSN IE + FT IE + Lifetimeout IE -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+int TdlsexCfg80211TdlsOper(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, enum nl80211_tdls_operation oper) -+{ -+ ADAPTER_T *prAdapter; -+ GLUE_INFO_T *prGlueInfo; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ TDLS_CMD_LINK_T rCmdLink; -+ -+ /* sanity check */ -+ if (peer == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: peer == NULL!\n", __func__); -+ return -EINVAL; -+ } -+ -+ DBGLOG(TDLS, INFO, " %s: [%pM] %d %d\n", -+ __func__, peer, oper, (wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)); -+ -+ if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) -+ return -ENOTSUPP; -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) wiphy_priv(wiphy); -+ if (prGlueInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: wrong prGlueInfo 0x%p!\n", __func__, prGlueInfo); -+ return -EINVAL; -+ } -+ prAdapter = prGlueInfo->prAdapter; -+ kalMemCopy(rCmdLink.aucPeerMac, peer, sizeof(rCmdLink.aucPeerMac)); -+ rCmdLink.fgIsEnabled = FALSE; -+ -+ /* -+ enum nl80211_tdls_operation { -+ NL80211_TDLS_DISCOVERY_REQ, -+ NL80211_TDLS_SETUP, -+ NL80211_TDLS_TEARDOWN, -+ NL80211_TDLS_ENABLE_LINK, -+ NL80211_TDLS_DISABLE_LINK, -+ }; -+ */ -+ -+ switch (oper) { -+ case NL80211_TDLS_ENABLE_LINK: -+ rCmdLink.fgIsEnabled = TRUE; -+ break; -+ -+ case NL80211_TDLS_DISABLE_LINK: -+ rCmdLink.fgIsEnabled = FALSE; -+ break; -+ -+ case NL80211_TDLS_TEARDOWN: -+ case NL80211_TDLS_SETUP: -+ case NL80211_TDLS_DISCOVERY_REQ: -+ /* we do not support setup/teardown/discovery from driver */ -+ return -ENOTSUPP; -+ -+ default: -+ return -ENOTSUPP; -+ } -+ -+ /* enable or disable TDLS link */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsexLinkCtrl, &rCmdLink, sizeof(TDLS_CMD_LINK_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s enable or disable link fail:%x\n", __func__, rStatus); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a command to TDLS module. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ UINT_32 u4Subcmd; -+ static void (*TdlsCmdTestFunc)(P_GLUE_INFO_T, UINT_8 *, UINT_32); -+ -+ /* parse TDLS sub-command */ -+ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(TDLS, INFO, " sub command = %u\n", (UINT32) u4Subcmd); -+ TdlsCmdTestFunc = NULL; -+ -+ /* handle different sub-command */ -+ switch (u4Subcmd) { -+#if TDLS_CFG_CMD_TEST /* only for unit test */ -+ case TDLS_CMD_TEST_TX_FRAME: -+ /* simulate to send a TDLS frame */ -+ /* TdlsCmdTestTxFrame(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestTxFrame; -+ break; -+ -+ case TDLS_CMD_TEST_TX_TDLS_FRAME: -+ /* simulate to send a TDLS frame from supplicant */ -+ /* TdlsCmdTestTxTdlsFrame(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestTxTdlsFrame; -+ break; -+ -+ case TDLS_CMD_TEST_RCV_FRAME: -+ /* simulate to receive a TDLS frame */ -+ /* TdlsCmdTestRvFrame(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestRvFrame; -+ break; -+ -+ case TDLS_CMD_TEST_PEER_ADD: -+ /* simulate to add a TDLS peer */ -+ /* TdlsCmdTestAddPeer(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestAddPeer; -+ break; -+ -+ case TDLS_CMD_TEST_PEER_UPDATE: -+ /* simulate to update a TDLS peer */ -+ /* TdlsCmdTestUpdatePeer(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestUpdatePeer; -+ break; -+ -+ case TDLS_CMD_TEST_DATA_FRAME: -+ /* simulate to send a data frame to the peer */ -+ /* TdlsCmdTestDataSend(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestDataSend; -+ break; -+ -+ case TDLS_CMD_TEST_RCV_NULL: -+ /* simulate to receive a QoS null frame from the peer */ -+ /* TdlsCmdTestNullRecv(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestNullRecv; -+ break; -+ -+ case TDLS_CMD_TEST_SKIP_TX_FAIL: -+ /* command firmware to skip tx fail case */ -+ /* TdlsCmdTestTxFailSkip(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestTxFailSkip; -+ break; -+ -+ case TDLS_CMD_TEST_SKIP_KEEP_ALIVE: -+ /* command firmware to skip keep alive function */ -+ /* TdlsCmdTestKeepAliveSkip(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestKeepAliveSkip; -+ break; -+ -+ case TDLS_CMD_TEST_SKIP_CHSW_TIMEOUT: -+ /* command firmware to skip channel switch timeout function */ -+ /* TdlsCmdTestChSwTimeoutSkip(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestChSwTimeoutSkip; -+ break; -+ -+ case TDLS_CMD_TEST_PROHIBIT_SET_IN_AP: -+ /* simulate to set Prohibited Bit in AP */ -+ /* TdlsCmdTestProhibitedBitSet(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestProhibitedBitSet; -+ break; -+ -+ case TDLS_CMD_TEST_SCAN_DISABLE: -+ /* command to disable scan request to do channel switch */ -+ /* TdlsCmdTestScanCtrl(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestScanCtrl; -+ break; -+ -+ case TDLS_CMD_TEST_DATA_FRAME_CONT: -+ /* simulate to send a data frame to the peer periodically */ -+ /* TdlsCmdTestDataContSend(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestDataContSend; -+ break; -+ -+ case TDLS_CMD_TEST_CH_SW_PROHIBIT_SET_IN_AP: -+ /* simulate to set channel switch Prohibited Bit in AP */ -+ /* TdlsCmdTestChSwProhibitedBitSet(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestChSwProhibitedBitSet; -+ break; -+ -+ case TDLS_CMD_TEST_DELAY: -+ /* delay a where */ -+ /* TdlsCmdTestDelay(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestDelay; -+ break; -+ -+ case TDLS_CMD_TEST_PTI_TX_FAIL: -+ /* simulate the tx done fail for PTI */ -+ /* TdlsCmdTestPtiTxDoneFail(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestPtiTxDoneFail; -+ break; -+#endif /* TDLS_CFG_CMD_TEST */ -+ -+ case TDLS_CMD_MIB_UPDATE: -+ /* update MIB parameters */ -+ /* TdlsCmdMibParamUpdate(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdMibParamUpdate; -+ break; -+ -+ case TDLS_CMD_UAPSD_CONF: -+ /* config UAPSD parameters */ -+ /* TdlsCmdUapsdConf(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdUapsdConf; -+ break; -+ -+ case TDLS_CMD_CH_SW_CONF: -+ /* enable or disable or start or stop channel switch function */ -+ /* TdlsCmdChSwConf(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdChSwConf; -+ break; -+ -+ case TDLS_CMD_SETUP_CONF: -+ /* config setup parameters */ -+ /* TdlsCmdSetupConf(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdSetupConf; -+ break; -+ -+ case TDLS_CMD_INFO: -+ /* display all TDLS information */ -+ /* TdlsCmdInfoDisplay(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdInfoDisplay; -+ break; -+ -+ case TDLS_CMD_KEY_INFO: -+ /* display key information */ -+ /* TdlsCmdKeyInfoDisplay(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdKeyInfoDisplay; -+ break; -+ -+ default: -+ break; -+ } -+ -+ if (TdlsCmdTestFunc != NULL) -+ TdlsCmdTestFunc(prGlueInfo, prInBuf, u4InBufLen); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to record a disconnection event. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure -+* \param[in] fgIsTearDown TRUE: tear down -+* \param[in] pucPeerMac Pointer to the MAC of the TDLS peer -+* \param[in] fgIsFromUs TRUE: tear down is from us -+* \param[in] u2ReasonCode Disconnection reason (TDLS_REASON_CODE) -+* -+* \retval none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+TdlsexLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, -+ BOOLEAN fgIsTearDown, UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode) -+{ -+ /* sanity check */ -+ if ((prGlueInfo == NULL) || (pucPeerMac == NULL)) -+ return; -+ -+ DBGLOG(TDLS, INFO, -+ " %s: Rcv a inform from %pM %d %d\n", -+ __func__, pucPeerMac, fgIsFromUs, u2ReasonCode); -+ -+ /* record */ -+ TdlsLinkHistoryRecord(prGlueInfo, fgIsTearDown, pucPeerMac, fgIsFromUs, u2ReasonCode, NULL); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a command to TDLS module. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ UINT32 u4EventId; -+ -+ /* sanity check */ -+ if ((prGlueInfo == NULL) || (prInBuf == NULL)) -+ return; /* shall not be here */ -+ -+ /* handle */ -+ u4EventId = *(UINT32 *) prInBuf; -+ u4InBufLen -= 4; -+ -+ DBGLOG(TDLS, INFO, " %s: Rcv a event: %d\n", __func__, u4EventId); -+ -+ switch (u4EventId) { -+ case TDLS_HOST_EVENT_TEAR_DOWN: -+ TdlsEventTearDown(prGlueInfo, prInBuf + 4, u4InBufLen); -+ break; -+ -+ case TDLS_HOST_EVENT_TX_DONE: -+ TdlsEventTxDone(prGlueInfo, prInBuf + 4, u4InBufLen); -+ break; -+ -+ case TDLS_HOST_EVENT_FME_STATUS: -+ TdlsEventFmeStatus(prGlueInfo, prInBuf + 4, u4InBufLen); -+ break; -+ -+ case TDLS_HOST_EVENT_STATISTICS: -+ TdlsEventStatistics(prGlueInfo, prInBuf + 4, u4InBufLen); -+ break; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to initialize variables in TDLS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* @return TDLS_STATUS_SUCCESS: do not set key and key infor. is queued -+ TDLS_STATUS_FAILURE: set key -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexKeyHandle(ADAPTER_T *prAdapter, PARAM_KEY_T *prNewKey) -+{ -+ STA_RECORD_T *prStaRec; -+ -+ /* sanity check */ -+ if ((prAdapter == NULL) || (prNewKey == NULL)) -+ return TDLS_STATUS_FAILURE; -+ -+ /* -+ supplicant will set key before updating station & enabling the link so we need to -+ backup the key information and set key when link is enabled -+ */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prNewKey->arBSSID); -+ if ((prStaRec != NULL) && IS_TDLS_STA(prStaRec)) { -+ DBGLOG(TDLS, TRACE, " %s: [%pM] queue key (len=%d) until link is enabled\n", -+ __func__, prNewKey->arBSSID, (UINT32) prNewKey->u4KeyLength); -+ -+ if (prStaRec->ucStaState == STA_STATE_3) { -+ DBGLOG(TDLS, TRACE, " %s: [%pM] tear down the link due to STA_STATE_3\n", -+ __func__, prNewKey->arBSSID); -+ -+ /* re-key */ -+ TdlsLinkHistoryRecord(prAdapter->prGlueInfo, TRUE, -+ prStaRec->aucMacAddr, TRUE, -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY, NULL); -+ -+ /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */ -+ cfg80211_tdls_oper_request(prAdapter->prGlueInfo->prDevHandler, -+ prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN, -+ TDLS_REASON_CODE_UNSPECIFIED, GFP_ATOMIC); -+ return TDLS_STATUS_SUCCESS; -+ } -+ -+ /* backup the key */ -+ kalMemCopy(&prStaRec->rTdlsKeyTemp, prNewKey, sizeof(prStaRec->rTdlsKeyTemp)); -+ return TDLS_STATUS_SUCCESS; -+ } -+ -+ return TDLS_STATUS_FAILURE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to initialize variables in TDLS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexInit(ADAPTER_T *prAdapter) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ -+ /* reset */ -+ kalMemZero(&prGlueInfo->rTdlsLink, sizeof(prGlueInfo->rTdlsLink)); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get any peer is in power save. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* \retval TRUE (at least one peer is in power save) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN TdlsexIsAnyPeerInPowerSave(ADAPTER_T *prAdapter) -+{ -+ STA_RECORD_T *prStaRec; -+ UINT32 u4StaId, u4StartIdx; -+ -+ for (u4StaId = 0, u4StartIdx = 0; u4StaId < CFG_STA_REC_NUM; u4StaId++) { -+ /* list all TDLS peers */ -+ prStaRec = cnmStaTheTypeGet(prAdapter, NETWORK_TYPE_AIS_INDEX, STA_TYPE_TDLS_PEER, &u4StartIdx); -+ if (prStaRec == NULL) -+ break; -+ -+ if (prStaRec->fgIsInPS == TRUE) { -+ DBGLOG(TDLS, TRACE, " yes, at least one peer is in ps\n"); -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to enable or disable a TDLS link. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexLinkCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ TDLS_CMD_LINK_T *prCmd; -+ BSS_INFO_T *prBssInfo; -+ STA_RECORD_T *prStaRec; -+ TDLS_LINK_HIS_OTHERS_T rHisOthers; -+ -+ /* sanity check */ -+ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { -+ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ *pu4SetInfoLen = sizeof(TDLS_CMD_LINK_T); -+ prCmd = (TDLS_CMD_LINK_T *) pvSetBuffer; -+ -+ /* search old entry */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac); -+ if (prStaRec == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: cannot find the peer! %pM\n", -+ __func__, prCmd->aucPeerMac); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ if (prCmd->fgIsEnabled == TRUE) { -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ DBGLOG(TDLS, TRACE, " %s: NL80211_TDLS_ENABLE_LINK\n", __func__); -+ -+ /* update key information after cnmStaRecChangeState(STA_STATE_3) */ -+ prStaRec->fgTdlsInSecurityMode = FALSE; -+ -+ if (prStaRec->rTdlsKeyTemp.u4Length > 0) { -+ UINT_32 u4BufLen; /* no use */ -+ -+ DBGLOG(TDLS, INFO, " %s: key len=%d\n", -+ __func__, (UINT32) prStaRec->rTdlsKeyTemp.u4Length); -+ -+ /* -+ reminder the function that we are CIPHER_SUITE_CCMP, -+ do not change cipher type to CIPHER_SUITE_WEP128 -+ */ -+ _wlanoidSetAddKey(prAdapter, &prStaRec->rTdlsKeyTemp, -+ prStaRec->rTdlsKeyTemp.u4Length, FALSE, CIPHER_SUITE_CCMP, &u4BufLen); -+ -+ /* clear the temp key */ -+ prStaRec->fgTdlsInSecurityMode = TRUE; -+ kalMemZero(&prStaRec->rTdlsKeyTemp, sizeof(prStaRec->rTdlsKeyTemp)); -+ } -+ -+ /* check if we need to disable channel switch function */ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ if (prBssInfo->fgTdlsIsChSwProhibited == TRUE) { -+ TDLS_CMD_CORE_T rCmd; -+ -+ kalMemZero(&rCmd, sizeof(TDLS_CMD_CORE_T)); -+ rCmd.Content.rCmdChSwConf.ucNetTypeIndex = prStaRec->ucNetTypeIndex; -+ rCmd.Content.rCmdChSwConf.fgIsChSwEnabled = FALSE; -+ kalMemCopy(rCmd.aucPeerMac, prStaRec->aucMacAddr, 6); -+ TdlsChSwConf(prAdapter, &rCmd, 0, 0); -+ -+ DBGLOG(TDLS, INFO, " %s: disable channel switch\n", __func__); -+ } -+ -+ TDLS_LINK_INCREASE(prGlueInfo); -+ -+ /* record link */ -+ if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11N) -+ rHisOthers.fgIsHt = TRUE; -+ else -+ rHisOthers.fgIsHt = FALSE; -+ -+ TdlsLinkHistoryRecord(prAdapter->prGlueInfo, FALSE, -+ prStaRec->aucMacAddr, !prStaRec->flgTdlsIsInitiator, 0, &rHisOthers); -+ } else { -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ cnmStaRecFree(prAdapter, prStaRec, TRUE); /* release to other TDLS peers */ -+ DBGLOG(TDLS, TRACE, " %s: NL80211_TDLS_DISABLE_LINK\n", __func__); -+ -+ TDLS_LINK_DECREASE(prGlueInfo); -+/* while(1); //sample debug */ -+ } -+ -+ /* work-around link count */ -+ if ((TDLS_LINK_COUNT(prGlueInfo) < 0) || (TDLS_LINK_COUNT(prGlueInfo) > 1)) { -+ /* ERROR case: work-around to recount by searching all station records */ -+ UINT32 u4Idx; -+ -+ TDLS_LINK_COUNT_RESET(prGlueInfo); -+ -+ for (u4Idx = 0; u4Idx < CFG_STA_REC_NUM; u4Idx++) { -+ prStaRec = &prAdapter->arStaRec[u4Idx]; -+ -+ if (prStaRec->fgIsInUse && IS_TDLS_STA(prStaRec)) -+ TDLS_LINK_INCREASE(prGlueInfo); -+ } -+ -+ if (TDLS_LINK_COUNT(prGlueInfo) > 1) { -+ /* number of links is still > 1 */ -+ DBGLOG(TDLS, INFO, " %s: cTdlsLinkCnt %d > 1?\n", -+ __func__, TDLS_LINK_COUNT(prGlueInfo)); -+ -+ TDLS_LINK_COUNT_RESET(prGlueInfo); -+ -+ /* free all TDLS links */ -+ for (u4Idx = 0; u4Idx < CFG_STA_REC_NUM; u4Idx++) { -+ prStaRec = &prAdapter->arStaRec[u4Idx]; -+ -+ if (prStaRec->fgIsInUse && IS_TDLS_STA(prStaRec)) -+ cnmStaRecFree(prAdapter, prStaRec, TRUE); -+ } -+ -+ /* maybe inform supplicant ? */ -+ } -+ } -+ -+ /* display TDLS link history */ -+ TdlsInfoDisplay(prAdapter, NULL, 0, NULL); -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to send a TDLS action data frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexMgmtCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ TDLS_MGMT_TX_INFO *prMgmtTxInfo; -+ STA_RECORD_T *prStaRec; -+ -+ /* sanity check */ -+ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { -+ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ *pu4SetInfoLen = sizeof(TDLS_MGMT_TX_INFO); -+ prMgmtTxInfo = (TDLS_MGMT_TX_INFO *) pvSetBuffer; -+ -+ switch (prMgmtTxInfo->ucActionCode) { -+ case TDLS_FRM_ACTION_DISCOVERY_RESPONSE: -+ prStaRec = NULL; -+ break; -+ -+ case TDLS_FRM_ACTION_SETUP_REQ: -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMgmtTxInfo->aucPeer); -+ if ((prStaRec != NULL) && (prStaRec->ucStaState == STA_STATE_3)) { -+ /* rekey? we reject re-setup link currently */ -+ /* TODO: Still can setup link during rekey */ -+ -+ /* -+ return success to avoid supplicant clear TDLS entry; -+ Or we cannot send out any TDLS tear down frame to the peer -+ */ -+ DBGLOG(TDLS, TRACE, " %s: skip new setup on the exist link!\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+ } -+ -+ prStaRec = NULL; -+ break; -+ -+ case TDLS_FRM_ACTION_SETUP_RSP: -+ case TDLS_FRM_ACTION_CONFIRM: -+ case TDLS_FRM_ACTION_TEARDOWN: -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMgmtTxInfo->aucPeer); -+#if 0 /* in some cases, the prStaRec is still NULL */ -+ /* -+ EX: if a peer sends us a TDLS setup request with wrong BSSID, -+ supplicant will not call TdlsexPeerAdd() to create prStaRec and -+ supplicant will send a TDLS setup response with status code 7. -+ -+ So in the case, prStaRec will be NULL. -+ */ -+ if (prStaRec == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: cannot find the peer!\n", __func__); -+ return -EINVAL; -+ } -+#endif -+ break; -+ -+ /* -+ TODO: Discovery response frame -+ Note that the TDLS Discovery Response frame is not a TDLS frame but a 11 -+ Public Action frame. -+ In WiFi TDLS Tech Minutes June 8 2010.doc, -+ a public action frame (i.e. it is no longer an encapsulated data frame) -+ */ -+ -+ default: -+ DBGLOG(TDLS, ERROR, -+ " %s: wrong action_code %d!\n", __func__, prMgmtTxInfo->ucActionCode); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* send the TDLS data frame */ -+ if (prStaRec != NULL) { -+ DBGLOG(TDLS, INFO, " %s: [%pM] ps=%d status=%d\n", -+ __func__, prStaRec->aucMacAddr, -+ prStaRec->fgIsInPS, prMgmtTxInfo->u2StatusCode); -+ -+ if (prMgmtTxInfo->ucActionCode == TDLS_FRM_ACTION_TEARDOWN) { -+ /* record disconnect history */ -+ TdlsLinkHistoryRecord(prGlueInfo, TRUE, prMgmtTxInfo->aucPeer, -+ TRUE, prMgmtTxInfo->u2StatusCode, NULL); -+ } -+ } -+ -+ return TdlsDataFrameSend(prAdapter, -+ prStaRec, -+ prMgmtTxInfo->aucPeer, -+ prMgmtTxInfo->ucActionCode, -+ prMgmtTxInfo->ucDialogToken, -+ prMgmtTxInfo->u2StatusCode, -+ (UINT_8 *) prMgmtTxInfo->aucSecBuf, prMgmtTxInfo->u4SecBufLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to add a peer record. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexPeerAdd(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ TDLS_CMD_PEER_ADD_T *prCmd; -+ BSS_INFO_T *prAisBssInfo; -+ STA_RECORD_T *prStaRec; -+ UINT_8 ucNonHTPhyTypeSet; -+ UINT32 u4StartIdx; -+ OS_SYSTIME rCurTime; -+ -+ /* sanity check */ -+ DBGLOG(TDLS, INFO, " %s\n", __func__); -+ -+ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { -+ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ *pu4SetInfoLen = sizeof(TDLS_CMD_PEER_ADD_T); -+ prCmd = (TDLS_CMD_PEER_ADD_T *) pvSetBuffer; -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ u4StartIdx = 0; -+ -+ /* search old entry */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac); -+ -+ /* check if any TDLS link exists because we only support one TDLS link currently */ -+ if (prStaRec == NULL) { -+ /* the MAC is new peer */ -+ prStaRec = cnmStaTheTypeGet(prAdapter, NETWORK_TYPE_AIS_INDEX, STA_TYPE_TDLS_PEER, &u4StartIdx); -+ -+ if (prStaRec != NULL) { -+ /* a building TDLS link exists */ -+ DBGLOG(TDLS, ERROR, -+ " %s: one TDLS link setup [%pM] is going...\n", -+ __func__, prStaRec->aucMacAddr); -+ -+ if (prStaRec->ucStaState != STA_STATE_3) { -+ /* check timeout */ -+ GET_CURRENT_SYSTIME(&rCurTime); -+ -+ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rTdlsSetupStartTime, -+ SEC_TO_SYSTIME(TDLS_SETUP_TIMEOUT_SEC))) { -+ /* free the StaRec */ -+ cnmStaRecFree(prAdapter, prStaRec, TRUE); -+ -+ DBGLOG(TDLS, ERROR, -+ " %s: free going TDLS link setup [%pM]\n", -+ __func__, (prStaRec->aucMacAddr)); -+ -+ /* handle new setup */ -+ prStaRec = NULL; -+ } else -+ return TDLS_STATUS_FAILURE; -+ } else { -+ /* the TDLS is built and works fine, reject new one */ -+ return TDLS_STATUS_FAILURE; -+ } -+ } -+ } else { -+ if (prStaRec->ucStaState == STA_STATE_3) { -+ /* the peer exists, maybe TPK lifetime expired, supplicant wants to renew key */ -+ TdlsLinkHistoryRecord(prAdapter->prGlueInfo, TRUE, -+ prStaRec->aucMacAddr, TRUE, -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY, NULL); -+ -+ /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */ -+ cfg80211_tdls_oper_request(prAdapter->prGlueInfo->prDevHandler, -+ prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN, -+ TDLS_REASON_CODE_UNSPECIFIED, GFP_ATOMIC); -+ -+ DBGLOG(TDLS, TRACE, -+ " %s: re-setup link for [%pM] maybe re-key?\n", -+ __func__, (prStaRec->aucMacAddr)); -+ return TDLS_STATUS_FAILURE; -+ } -+ } -+ -+ /* -+ create new entry if not exist -+ -+ 1. we are initiator -+ (1) send TDLS setup request -+ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); -+ create a station record with STA_STATE_1. -+ (2) got TDLS setup response and send TDLS setup confirm -+ wpa_tdls_enable_link() -+ update a station record with STA_STATE_3. -+ -+ 2. we are responder -+ (1) got TDLS setup request -+ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); -+ create a station record with STA_STATE_1. -+ (2) send TDLS setup response -+ (3) got TDLS setup confirm -+ wpa_tdls_enable_link() -+ update a station record with STA_STATE_3. -+ */ -+ if (prStaRec == NULL) { -+ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX); -+ -+ if (prStaRec == NULL) { -+ /* shall not be here */ -+ DBGLOG(TDLS, ERROR, " %s: alloc prStaRec fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ /* init the prStaRec */ -+ /* prStaRec will be zero first in cnmStaRecAlloc() */ -+ COPY_MAC_ADDR(prStaRec->aucMacAddr, prCmd->aucPeerMac); -+ -+/* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); */ -+ } else { -+#if 0 -+ if ((prStaRec->ucStaState > STA_STATE_1) && (IS_TDLS_STA(prStaRec))) { -+ /* -+ test plan: The STAUT should locally tear down existing TDLS direct link and -+ respond with Set up Response frame. -+ */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ } -+#endif -+ } -+ -+ /* reference to bssCreateStaRecFromBssDesc() and use our best capability */ -+ /* reference to assocBuildReAssocReqFrameCommonIEs() to fill elements */ -+ -+ /* prStaRec->u2CapInfo */ -+ /* TODO: Need to parse elements from setup request frame */ -+ prStaRec->u2OperationalRateSet = prAisBssInfo->u2OperationalRateSet; -+ prStaRec->u2BSSBasicRateSet = prAisBssInfo->u2BSSBasicRateSet; -+ prStaRec->u2DesiredNonHTRateSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet; -+ prStaRec->ucPhyTypeSet = prAisBssInfo->ucPhyTypeSet; -+ prStaRec->eStaType = STA_TYPE_TDLS_PEER; -+ -+ prStaRec->ucDesiredPhyTypeSet = /*prStaRec->ucPhyTypeSet & */ -+ prAdapter->rWifiVar.ucAvailablePhyTypeSet; -+ ucNonHTPhyTypeSet = prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11ABG; -+ -+ /* check for Target BSS's non HT Phy Types */ -+ if (ucNonHTPhyTypeSet) { -+ if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_ERP) { -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; -+ } else if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_OFDM) { -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; -+ } else { /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ -+ -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; -+ } -+ -+ prStaRec->fgHasBasicPhyType = TRUE; -+ } else { -+ /* use mandatory for 11N only BSS */ -+/* ASSERT(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N); */ -+ -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; -+ prStaRec->fgHasBasicPhyType = FALSE; -+ } -+ -+ /* update non HT Desired Rate Set */ -+ { -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prStaRec->u2DesiredNonHTRateSet = -+ (prStaRec->u2OperationalRateSet & prConnSettings->u2DesiredNonHTRateSet); -+ } -+ -+#if 0 /* TdlsexPeerAdd() will be called before we receive setup rsp in TdlsexRxFrameHandle() */ -+ /* check if the add is from the same peer in the 1st unhandled setup request frame */ -+ DBGLOG(TDLS, INFO, " %s: [%pM] [%pM]\n", -+ __func__, prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac); -+ -+ if (kalMemCmp(prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac, 6) == 0) { -+ /* copy the HT capability from its setup request */ -+ kalMemCopy(&prStaRec->rTdlsHtCap, &prGlueInfo->rTdlsHtCap, sizeof(IE_HT_CAP_T)); -+ -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; -+ prStaRec->u2DesiredNonHTRateSet |= BIT(RATE_HT_PHY_INDEX); -+ -+ /* reset backup */ -+ kalMemZero(&prGlueInfo->rTdlsHtCap, sizeof(prStaRec->rTdlsHtCap)); -+ kalMemZero(prGlueInfo->aucTdlsHtPeerMac, sizeof(prGlueInfo->aucTdlsHtPeerMac)); -+ -+ DBGLOG(TDLS, INFO, " %s: peer is a HT device\n", __func__); -+ } -+#endif -+ -+ /* update WMM: must support due to UAPSD in TDLS link */ -+ prStaRec->fgIsWmmSupported = TRUE; -+ prStaRec->fgIsUapsdSupported = TRUE; -+ -+ /* update station record to firmware */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ /* update time */ -+ GET_CURRENT_SYSTIME(&prStaRec->rTdlsSetupStartTime); -+ -+ DBGLOG(TDLS, INFO, " %s: create a peer [%pM]\n", -+ __func__, (prStaRec->aucMacAddr)); -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to update a peer record. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexPeerUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ TDLS_CMD_PEER_UPDATE_T *prCmd; -+ BSS_INFO_T *prAisBssInfo; -+ STA_RECORD_T *prStaRec; -+ IE_HT_CAP_T *prHtCap; -+ -+ /* sanity check */ -+ DBGLOG(TDLS, INFO, " %s\n", __func__); -+ -+ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { -+ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ *pu4SetInfoLen = sizeof(TDLS_CMD_PEER_ADD_T); -+ prCmd = (TDLS_CMD_PEER_UPDATE_T *) pvSetBuffer; -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* search old entry */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac); -+ -+ /* -+ create new entry if not exist -+ -+ 1. we are initiator -+ (1) send TDLS setup request -+ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); -+ create a station record with STA_STATE_1. -+ (2) got TDLS setup response and send TDLS setup confirm -+ wpa_tdls_enable_link() -+ update a station record with STA_STATE_3. -+ -+ 2. we are responder -+ (1) got TDLS setup request -+ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); -+ create a station record with STA_STATE_1. -+ (2) send TDLS setup response -+ (3) got TDLS setup confirm -+ wpa_tdls_enable_link() -+ update a station record with STA_STATE_3. -+ */ -+ if ((prStaRec == NULL) || (prStaRec->fgIsInUse == 0)) { -+ DBGLOG(TDLS, ERROR, " %s: cannot find the peer!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ DBGLOG(TDLS, INFO, " %s: update a peer [%pM] %d -> %d, 0x%x\n", -+ __func__, (prStaRec->aucMacAddr), -+ prStaRec->ucStaState, STA_STATE_3, prStaRec->eStaType); -+ -+ if (!IS_TDLS_STA(prStaRec)) { -+ DBGLOG(TDLS, ERROR, " %s: peer is not TDLS one!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* check if the add is from the same peer in the 1st unhandled setup request frame */ -+ DBGLOG(TDLS, INFO, " %s: [%pM] [%pM]\n", -+ __func__, (prGlueInfo->aucTdlsHtPeerMac), (prCmd->aucPeerMac)); -+ -+ if (kalMemCmp(prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac, 6) == 0) { -+ /* copy the HT capability from its setup request */ -+ kalMemCopy(&prStaRec->rTdlsHtCap, &prGlueInfo->rTdlsHtCap, sizeof(IE_HT_CAP_T)); -+ -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; -+ prStaRec->u2DesiredNonHTRateSet |= BIT(RATE_HT_PHY_INDEX); -+ -+ /* reset backup */ -+ kalMemZero(&prGlueInfo->rTdlsHtCap, sizeof(prStaRec->rTdlsHtCap)); -+ kalMemZero(prGlueInfo->aucTdlsHtPeerMac, sizeof(prGlueInfo->aucTdlsHtPeerMac)); -+ -+ DBGLOG(TDLS, INFO, " %s: peer is a HT device\n", __func__); -+ } -+ -+ /* update the record join time. */ -+ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); -+ -+ /* update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = prCmd->u2StatusCode; -+ -+ /* prStaRec->ucStaState shall be STA_STATE_1 */ -+ -+ prStaRec->u2CapInfo = prCmd->u2Capability; -+/* prStaRec->u2OperationalRateSet */ -+ prStaRec->u2AssocId = 0; /* no use */ -+ prStaRec->u2ListenInterval = 0; /* unknown */ -+/* prStaRec->ucDesiredPhyTypeSet */ -+/* prStaRec->u2DesiredNonHTRateSet */ -+/* prStaRec->u2BSSBasicRateSet */ -+/* prStaRec->ucMcsSet */ -+/* prStaRec->fgSupMcs32 */ -+/* prStaRec->u2HtCapInfo */ -+ prStaRec->fgIsQoS = TRUE; -+ prStaRec->fgIsUapsdSupported = (prCmd->UapsdBitmap == 0) ? FALSE : TRUE; -+/* prStaRec->ucAmpduParam */ -+/* prStaRec->u2HtExtendedCap */ -+ prStaRec->u4TxBeamformingCap = 0; /* no use */ -+ prStaRec->ucAselCap = 0; /* no use */ -+ prStaRec->ucRCPI = 0; -+ prStaRec->ucBmpTriggerAC = prCmd->UapsdBitmap; -+ prStaRec->ucBmpDeliveryAC = prCmd->UapsdBitmap; -+ prStaRec->ucUapsdSp = prCmd->UapsdMaxSp; -+ -+ /* update HT */ -+#if (TDLS_CFG_HT_SUP == 1) -+ if (prCmd->fgIsSupHt == FALSE) { -+ /* no HT IE is from supplicant so we use the backup */ -+ prHtCap = (IE_HT_CAP_T *) &prStaRec->rTdlsHtCap; -+ -+ DBGLOG(TDLS, INFO, " %s: [%pM] update ht ie 0x%x\n", -+ __func__, (prStaRec->aucMacAddr), prHtCap->ucId); -+ -+ if (prHtCap->ucId == ELEM_ID_HT_CAP) { -+ prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; -+ prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE; -+ -+ prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; -+ prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; -+ prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; -+ prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap; -+ prStaRec->ucAselCap = prHtCap->ucAselCap; -+ prStaRec->ucDesiredPhyTypeSet |= PHY_TYPE_SET_802_11N; -+ } -+ } else { -+ /* TODO: use the HT IE from supplicant */ -+ } -+#endif /* TDLS_CFG_HT_SUP */ -+ -+ DBGLOG(TDLS, INFO, " %s: UAPSD 0x%x %d MCS=0x%x\n", -+ __func__, prCmd->UapsdBitmap, prCmd->UapsdMaxSp, prStaRec->ucMcsSet); -+ -+/* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */ -+ -+ DBGLOG(TDLS, INFO, " %s: update a peer [%pM]\n", -+ __func__, (prStaRec->aucMacAddr)); -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to check if we need to drop a TDLS action frame. -+* -+* \param[in] *pPkt Pointer to the struct sk_buff->data. -+* \param[in] -+* \param[in] -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN TdlsexRxFrameDrop(GLUE_INFO_T *prGlueInfo, UINT_8 *pPkt) -+{ -+ ADAPTER_T *prAdapter; -+ UINT8 ucActionId; -+ -+ /* sanity check */ -+ if ((pPkt == NULL) || (*(pPkt + 12) != 0x89) || (*(pPkt + 13) != 0x0d)) -+ return FALSE; /* not TDLS data frame htons(0x890d) */ -+ -+#if 0 /* supplicant handles this check */ -+ if (prStaRec == NULL) -+ return FALSE; /* shall not be here */ -+ -+ DBGLOG(TDLS, INFO, -+ " %s: Rcv a TDLS action frame (id=%d) %d %d\n", -+ __func__, *(pPkt + 13 + 4), prStaRec->fgTdlsIsProhibited, fgIsPtiTimeoutSkip); -+ -+ /* check if TDLS Prohibited bit is set in AP's beacon */ -+ if (prStaRec->fgTdlsIsProhibited == TRUE) -+ return TRUE; -+#endif -+ -+ ucActionId = *(pPkt + 12 + 2 + 2); /* skip dst, src MAC, type, payload type, category */ -+ -+ if (fgIsPtiTimeoutSkip == TRUE) { -+ /* also skip any tear down frame from the peer */ -+ if (ucActionId == TDLS_FRM_ACTION_TEARDOWN) -+ return TRUE; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ DBGLOG(TDLS, INFO, -+ " %s: Rcv a TDLS action frame %d (%u)\n", -+ __func__, ucActionId, (UINT32) prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); -+ -+ if (ucActionId == TDLS_FRM_ACTION_TEARDOWN) { -+ DBGLOG(TDLS, WARN, " %s: Rcv a TDLS tear down frame %d, will DISABLE link\n", -+ __func__, *(pPkt + 13 + 4)); /* reason code */ -+ -+ /* record disconnect history */ -+ TdlsLinkHistoryRecord(prGlueInfo, TRUE, pPkt + 6, FALSE, *(pPkt + 13 + 4), NULL); -+ -+ /* inform tear down to supplicant only in OPEN/NONE mode */ -+ /* -+ we need to tear down the link manually; or supplicant will display -+ "No FTIE in TDLS Teardown" and it will not tear down the link -+ */ -+ cfg80211_tdls_oper_request(prGlueInfo->prDevHandler, -+ pPkt + 6, TDLS_FRM_ACTION_TEARDOWN, *(pPkt + 13 + 4), GFP_ATOMIC); -+ } -+#if 0 /* pass all to supplicant except same thing is handled in supplicant */ -+ if (((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_PTI) || -+ ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_CHAN_SWITCH_REQ) || -+ ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_CHAN_SWITCH_RSP) || -+ ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_PTI_RSP)) { -+ return TRUE; -+ } -+#endif -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to parse some IEs in the setup frame from the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] pPkt Pointer to the ethernet packet -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexRxFrameHandle(GLUE_INFO_T *prGlueInfo, UINT8 *pPkt, UINT16 u2PktLen) -+{ -+ ADAPTER_T *prAdapter; -+ STA_RECORD_T *prStaRec; -+ UINT8 ucActionId; -+ UINT8 *pucPeerMac, ucElmId, ucElmLen; -+ INT16 s2FmeLen; -+ -+ /* sanity check */ -+ if ((prGlueInfo == NULL) || (pPkt == NULL) || (*(pPkt + 12) != 0x89) || (*(pPkt + 13) != 0x0d)) -+ return; -+ -+ ucActionId = *(pPkt + 12 + 2 + 2); /* skip dst, src MAC, type, payload type, category */ -+ -+ if ((ucActionId != TDLS_FRM_ACTION_SETUP_REQ) && (ucActionId != TDLS_FRM_ACTION_SETUP_RSP)) -+ return; -+ -+ /* init */ -+ prAdapter = prGlueInfo->prAdapter; -+ pucPeerMac = pPkt + 6; -+ s2FmeLen = (INT16) u2PktLen; -+ -+ DBGLOG(TDLS, TRACE, -+ " %s: get a setup frame %d from %pM\n", -+ __func__, ucActionId, (pucPeerMac)); -+ -+ if (ucActionId == TDLS_FRM_ACTION_SETUP_REQ) -+ pPkt += 12 + 2 + 2 + 1 + 1 + 2; /* skip action, dialog token, capability */ -+ else -+ pPkt += 12 + 2 + 2 + 1 + 2 + 1 + 2; /* skip action, status code, dialog token, capability */ -+ -+ /* check station record */ -+ prStaRec = cnmGetStaRecByAddress(prGlueInfo->prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, pucPeerMac); -+ -+ if (prStaRec == NULL) { -+ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX); -+ -+ if (prStaRec == NULL) { -+ /* TODO: only one TDLS entry, need to free old one if timeout */ -+ DBGLOG(TDLS, ERROR, " %s: alloc prStaRec fail!\n", __func__); -+ return; -+ } -+ -+ /* init the prStaRec */ -+ /* prStaRec will be zero first in cnmStaRecAlloc() */ -+ COPY_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMac); -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ } -+ -+ /* backup HT IE to station record */ -+ /* TODO: Maybe our TDLS only supports non-11n */ -+ while (s2FmeLen > 0) { -+ ucElmId = *pPkt++; -+ ucElmLen = *pPkt++; -+ -+ switch (ucElmId) { -+ case ELEM_ID_HT_CAP: /* 0x2d */ -+ /* backup the HT IE of 1st unhandled setup request frame */ -+ if (prGlueInfo->rTdlsHtCap.ucId == 0x00) { -+ kalMemCopy(prGlueInfo->aucTdlsHtPeerMac, pucPeerMac, 6); -+ kalMemCopy(&prGlueInfo->rTdlsHtCap, pPkt - 2, ucElmLen + 2); -+ -+ /* -+ cannot backup in prStaRec; or -+ -+ 1. we build a TDLS link -+ 2. peer re-sends setup req -+ 3. we backup HT cap element -+ 4. supplicant disables the link -+ 5. we clear the prStaRec -+ */ -+ -+ DBGLOG(TDLS, TRACE, -+ " %s: %pM: find a HT IE\n", -+ __func__, (pucPeerMac)); -+ } -+ return; -+ -+ case ELEM_ID_EXTENDED_CAP: -+ /* TODO: backup the extended capability IE */ -+ break; -+ } -+ -+ pPkt += ucElmLen; -+ s2FmeLen -= (2 + ucElmLen); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to get the TDLS station record. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval TDLS_STATUS_SUCCESS: this is TDLS packet -+* TDLS_STATUS_FAILURE: this is not TDLS packet -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexStaRecIdxGet(ADAPTER_T *prAdapter, MSDU_INFO_T *prMsduInfo) -+{ -+ BSS_INFO_T *prBssInfo; -+ STA_RECORD_T *prStaRec; -+ TDLS_STATUS Status; -+ -+ /* sanity check */ -+ if ((prAdapter == NULL) || (prMsduInfo == NULL)) -+ return TDLS_STATUS_FAILURE; -+ -+ if (prAdapter->prGlueInfo == NULL) -+ return TDLS_STATUS_FAILURE; -+ if (TDLS_IS_NO_LINK_GOING(prAdapter->prGlueInfo)) -+ return TDLS_STATUS_FAILURE; -+ -+ /* init */ -+ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; -+ Status = TDLS_STATUS_SUCCESS; -+ -+ /* get record by ether dest */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMsduInfo->aucEthDestAddr); -+ -+ /* -+ TDLS Setup Request frames, TDLS Setup Response frames and TDLS Setup Confirm -+ frames shall be transmitted through the AP and shall not be transmitted to a group -+ address. -+ -+ 1. In first time, prStaRec == NULL or prStaRec->ucStaState != STA_STATE_3, -+ we will send them to AP; -+ 2. When link is still on, if you command to send TDLS setup from supplicant, -+ supplicant will DISABLE LINK first, prStaRec will be NULL then send TDLS -+ setup frame to the peer. -+ */ -+ -+ do { -+ if ((prStaRec != NULL) && (prStaRec->ucStaState == STA_STATE_3) && (IS_TDLS_STA(prStaRec))) { -+ /* -+ TDLS Test Case 5.3 Tear Down -+ Automatically sends TDLS Teardown frame to STA 2 via AP -+ -+ 11.21.5 TDLS Direct Link Teardown -+ The TDLS Teardown frame shall be sent over the direct path and the reason -+ code shall be set to "TDLS 40 direct link teardown for unspecified reason", -+ except when the TDLS peer STA is unreachable via the TDLS direct link, -+ in which case, the TDLS Teardown frame shall be sent through the AP and -+ the reason code shall be set to "TDLS direct link teardown due to TDLS peer -+ STA unreachable via the TDLS direct link". -+ */ -+ /* if (prStaRec->fgIsInPS == TRUE) */ -+ /* -+ check if the packet is tear down: -+ we do not want to use PTI to indicate the tear down and -+ we want to send the tear down to AP then AP help us to send it -+ */ -+ struct sk_buff *prSkb; -+ UINT8 *pEth; -+ UINT_16 u2EtherTypeLen; -+ -+ prSkb = (struct sk_buff *)prMsduInfo->prPacket; -+ if (prSkb != NULL) { -+ UINT8 ucActionCode, ucReasonCode; -+ -+ /* init */ -+ pEth = prSkb->data; -+ u2EtherTypeLen = (pEth[ETH_TYPE_LEN_OFFSET] << 8) | -+ (pEth[ETH_TYPE_LEN_OFFSET + 1]); -+ ucActionCode = pEth[ETH_TYPE_LEN_OFFSET + 1 + 3]; -+ ucReasonCode = pEth[ETH_TYPE_LEN_OFFSET + 1 + 4] | -+ (pEth[ETH_TYPE_LEN_OFFSET + 1 + 5] << 8); -+ -+ /* TDLS_REASON_CODE_UNREACHABLE: keep alive fail or PTI timeout */ -+ if ((u2EtherTypeLen == TDLS_FRM_PROT_TYPE) && -+ (ucActionCode == TDLS_FRM_ACTION_TEARDOWN) && -+ (ucReasonCode == TDLS_REASON_CODE_UNREACHABLE)) { -+ /* -+ when we cannot reach the peer, -+ we need AP's help to send the tear down frame -+ */ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prStaRec = prBssInfo->prStaRecOfAP; -+ if (prStaRec == NULL) { -+ Status = TDLS_STATUS_FAILURE; -+ break; -+ } -+#if 0 -+ /* change status code */ -+ pEth[ETH_TYPE_LEN_OFFSET + 1 + 4] = TDLS_REASON_CODE_UNREACHABLE; -+#endif -+ } -+ } -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ } -+ } while (FALSE); -+ -+ DBGLOG(TDLS, INFO, " %s: (Status=%x) [%pM] ucStaRecIndex = %d!\n", -+ __func__, (INT32) Status, (prMsduInfo->aucEthDestAddr), -+ prMsduInfo->ucStaRecIndex); -+ return Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to check if we suffer timeout for TX quota empty case. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexTxQuotaCheck(GLUE_INFO_T *prGlueInfo, STA_RECORD_T *prStaRec, UINT8 FreeQuota) -+{ -+ OS_SYSTIME rCurTime; -+ -+ /* sanity check */ -+ if (!IS_TDLS_STA(prStaRec)) -+ return; -+ -+ if (FreeQuota != 0) { -+ /* reset timeout */ -+ prStaRec->rTdlsTxQuotaEmptyTime = 0; -+ return; -+ } -+ -+ /* work-around: check if the no free quota case is too long */ -+ GET_CURRENT_SYSTIME(&rCurTime); -+ -+ if (prStaRec->rTdlsTxQuotaEmptyTime == 0) { -+ prStaRec->rTdlsTxQuotaEmptyTime = rCurTime; -+ } else { -+ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rTdlsTxQuotaEmptyTime, -+ SEC_TO_SYSTIME(TDLS_TX_QUOTA_EMPTY_TIMEOUT))) { -+ /* tear down the link */ -+ DBGLOG(TDLS, WARN, -+ " %s: [%pM] TX quota empty timeout!\n", -+ __func__, (prStaRec->aucMacAddr)); -+ -+ /* record disconnect history */ -+ TdlsLinkHistoryRecord(prGlueInfo, TRUE, prStaRec->aucMacAddr, -+ TRUE, TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_TX_QUOTA_EMPTY, NULL); -+ -+ /* inform tear down to supplicant only in OPEN/NONE mode */ -+ /* -+ we need to tear down the link manually; or supplicant will display -+ "No FTIE in TDLS Teardown" and it will not tear down the link -+ */ -+ cfg80211_tdls_oper_request(prGlueInfo->prDevHandler, -+ prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN, -+ TDLS_REASON_CODE_UNREACHABLE, GFP_ATOMIC); -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to un-initialize variables in TDLS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexUninit(ADAPTER_T *prAdapter) -+{ -+#if TDLS_CFG_CMD_TEST -+ cnmTimerStopTimer(prAdapter, &rTdlsTimerTestDataSend); -+#endif /* TDLS_CFG_CMD_TEST */ -+} -+ -+#endif /* CFG_SUPPORT_TDLS */ -+ -+/* End of tdls.c */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c -new file mode 100644 -index 0000000000000..5450cbb651837 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c -@@ -0,0 +1,741 @@ -+/* -+** Id: tdls_com.c#1 -+*/ -+ -+/*! \file tdls_com.c -+ \brief This file includes IEEE802.11z TDLS main support. -+*/ -+ -+/* -+** Log: tdls_com.c -+ * -+ * 11 13 2013 vend_samp.lin -+ * NULL -+ * Initial version. -+ */ -+ -+/******************************************************************************* -+ * C O M P I L E R F L A G S -+ ******************************************************************************** -+ */ -+ -+/******************************************************************************* -+ * E X T E R N A L R E F E R E N C E S -+ ******************************************************************************** -+ */ -+ -+#include "precomp.h" -+ -+#if (CFG_SUPPORT_TDLS == 1) -+#include "tdls.h" -+ -+ /******************************************************************************* -+ * C O N S T A N T S -+ ******************************************************************************** -+ */ -+ -+ /******************************************************************************* -+ * F U N C T I O N D E C L A R A T I O N S -+ ******************************************************************************** -+ */ -+ -+ /******************************************************************************* -+ * P R I V A T E D A T A -+ ******************************************************************************** -+ */ -+ -+ /******************************************************************************* -+ * P R I V A T E F U N C T I O N S -+ ******************************************************************************** -+ */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to append general IEs. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] prStaRec Pointer to the STA_RECORD_T structure. -+* \param[in] u2StatusCode Status code. -+* \param[in] pPkt Pointer to the frame body -+* -+* \retval append length -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 TdlsFrameGeneralIeAppend(ADAPTER_T *prAdapter, STA_RECORD_T *prStaRec, UINT_16 u2StatusCode, UINT_8 *pPkt) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ BSS_INFO_T *prBssInfo; -+ PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo; -+ UINT_32 u4NonHTPhyType; -+ UINT_16 u2SupportedRateSet; -+ UINT_8 aucAllSupportedRates[RATE_NUM] = { 0 }; -+ UINT_8 ucAllSupportedRatesLen; -+ UINT_8 ucSupRatesLen; -+ UINT_8 ucExtSupRatesLen; -+ UINT_32 u4PktLen, u4IeLen; -+ BOOLEAN fg40mAllowed; -+ -+ /* reference to assocBuildReAssocReqFrameCommonIEs() */ -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ u4PktLen = 0; -+ -+ /* 3. Frame Formation - (5) Supported Rates element */ -+ /* use all sup rate we can support */ -+ if (prStaRec != NULL) -+ u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; -+ else -+ u4NonHTPhyType = PHY_TYPE_ERP_INDEX; /* default */ -+ -+ u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet; -+ -+ if (prStaRec != NULL) { -+ u2SupportedRateSet &= prStaRec->u2OperationalRateSet; -+ -+ if (u2SupportedRateSet == 0) -+ u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet; -+ } -+ -+ rateGetDataRatesFromRateSet(u2SupportedRateSet, -+ prBssInfo->u2BSSBasicRateSet, aucAllSupportedRates, &ucAllSupportedRatesLen); -+ -+ ucSupRatesLen = ((ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ? -+ ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen); -+ -+ ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen; -+ -+ if (ucSupRatesLen) { -+ SUP_RATES_IE(pPkt)->ucId = ELEM_ID_SUP_RATES; -+ SUP_RATES_IE(pPkt)->ucLength = ucSupRatesLen; -+ kalMemCopy(SUP_RATES_IE(pPkt)->aucSupportedRates, aucAllSupportedRates, ucSupRatesLen); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ pPkt += u4IeLen; -+ u4PktLen += u4IeLen; -+ } -+ -+ /* 3. Frame Formation - (7) Extended sup rates element */ -+ if (ucExtSupRatesLen) { -+ -+ EXT_SUP_RATES_IE(pPkt)->ucId = ELEM_ID_EXTENDED_SUP_RATES; -+ EXT_SUP_RATES_IE(pPkt)->ucLength = ucExtSupRatesLen; -+ -+ kalMemCopy(EXT_SUP_RATES_IE(pPkt)->aucExtSupportedRates, -+ &aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ pPkt += u4IeLen; -+ u4PktLen += u4IeLen; -+ } -+ -+ /* 3. Frame Formation - (8) Supported channels element */ -+ /* -+ The Supported channels element is included in Request frame and also in Response -+ frame if Status Code 0 (successful). -+ */ -+ if (u2StatusCode == 0) { -+ SUPPORTED_CHANNELS_IE(pPkt)->ucId = ELEM_ID_SUP_CHS; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 2; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[0] = 1; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[1] = 11; -+ -+#if CFG_SUPPORT_DFS -+ if (prAdapter->fgEnable5GBand == TRUE) { -+ /* 5G support */ -+ SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 10; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[2] = 36; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[3] = 4; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[4] = 52; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[5] = 4; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[6] = 149; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[7] = 4; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[8] = 165; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[9] = 4; -+ } -+#endif /* CFG_SUPPORT_DFS */ -+ -+ u4IeLen = IE_SIZE(pPkt); -+ pPkt += u4IeLen; -+ u4PktLen += u4IeLen; -+ } -+ -+ /* 3. Frame Formation - (14) HT capabilities element */ -+ -+ /* no need to check AP capability */ -+/* if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && */ -+ -+ /* -+ after we set ucPhyTypeSet to PHY_TYPE_SET_802_11N in TdlsexRxFrameHandle(), -+ supplicant will disable link if exists and we will clear prStaRec. -+ -+ finally, prStaRec->ucPhyTypeSet will also be 0 -+ -+ so we have a fix in TdlsexPeerAdd(). -+ */ -+ if (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { -+ /* TODO: prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode */ -+#if 0 /* always support */ -+ if (prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode == CONFIG_BW_20M) -+ fg40mAllowed = FALSE; -+ else -+#endif -+ fg40mAllowed = TRUE; -+ -+ u4IeLen = rlmFillHtCapIEByParams(fg40mAllowed, -+ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled, -+ prAdapter->rWifiVar.u8SupportRxSgi20, -+ prAdapter->rWifiVar.u8SupportRxSgi40, -+ prAdapter->rWifiVar.u8SupportRxGf, -+ prAdapter->rWifiVar.u8SupportRxSTBC, prBssInfo->eCurrentOPMode, pPkt); -+ -+ pPkt += u4IeLen; -+ u4PktLen += u4IeLen; -+ } -+ -+ /* 3. Frame Formation - (17) WMM Information element */ -+ -+ /* always support */ -+/* if (prAdapter->rWifiVar.fgSupportQoS) */ -+ -+ { -+ /* force to support all UAPSD in TDLS link */ -+ u4IeLen = mqmGenerateWmmInfoIEByParam(TRUE /*prAdapter->rWifiVar.fgSupportUAPSD */ , -+ 0xf /*prPmProfSetupInfo->ucBmpDeliveryAC */ , -+ 0xf /*prPmProfSetupInfo->ucBmpTriggerAC */ , -+ WMM_MAX_SP_LENGTH_ALL /*prPmProfSetupInfo->ucUapsdSp */ , -+ pPkt); -+ -+ pPkt += u4IeLen; -+ u4PktLen += u4IeLen; -+ } -+ -+ return u4PktLen; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to transmit a TDLS data frame (setup req/rsp/confirm and tear down). -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] prStaRec Pointer to the STA_RECORD_T structure. -+* \param[in] pPeerMac Pointer to the MAC of the TDLS peer -+* \param[in] ucActionCode TDLS Action -+* \param[in] ucDialogToken Dialog token -+* \param[in] u2StatusCode Status code -+* \param[in] pAppendIe Others IEs (here are security IEs from supplicant) -+* \param[in] AppendIeLen IE length of others IEs -+* -+* \retval TDLS_STATUS_xx -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS -+TdlsDataFrameSend(ADAPTER_T *prAdapter, -+ STA_RECORD_T *prStaRec, -+ UINT_8 *pPeerMac, -+ UINT_8 ucActionCode, -+ UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen) -+{ -+#define LR_TDLS_FME_FIELD_FILL(__Len) \ -+do { \ -+ pPkt += __Len; \ -+ u4PktLen += __Len; \ -+} while (0) -+ -+ GLUE_INFO_T *prGlueInfo; -+ BSS_INFO_T *prBssInfo; -+ PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo; -+ struct sk_buff *prMsduInfo; -+ MSDU_INFO_T *prMsduInfoMgmt; -+ UINT8 *pPkt, *pucInitiator, *pucResponder; -+ UINT32 u4PktLen, u4IeLen; -+ UINT16 u2CapInfo; -+/* UINT8 *pPktTemp; */ -+ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ -+ DBGLOG(TDLS, INFO, " %s: 2040=%d\n", __func__, prGlueInfo->rTdlsLink.fgIs2040Sup); -+ -+ /* sanity check */ -+ if (prStaRec != NULL) { -+ if (prStaRec->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) { -+ DBGLOG(TDLS, ERROR, -+ " %s: net index %d fail\n", __func__, prStaRec->ucNetTypeIndex); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ } else { -+ /* prStaRec maybe NULL in setup request */ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ } -+ -+ /* allocate/init packet */ -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ u4PktLen = 0; -+ prMsduInfo = NULL; -+ prMsduInfoMgmt = NULL; -+ -+ /* make up frame content */ -+ if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RESPONSE) { -+ /* -+ The STAUT will not respond to a TDLS Discovery Request Frame with different BSSID. -+ Supplicant will check this in wpa_tdls_process_discovery_request(). -+ */ -+ -+ /* TODO: reduce 1600 to correct size */ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* 1. 802.3 header */ -+/* pPktTemp = pPkt; */ -+ kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ } else { -+ /* discovery response */ -+ WLAN_MAC_HEADER_T *prHdr; -+ -+ prMsduInfoMgmt = (MSDU_INFO_T *) -+ cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN); -+ if (prMsduInfoMgmt == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate mgmt pkt fail\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ pPkt = (UINT8 *) prMsduInfoMgmt->prPacket; -+ prHdr = (WLAN_MAC_HEADER_T *) pPkt; -+ -+ /* 1. 802.11 header */ -+ prHdr->u2FrameCtrl = MAC_FRAME_ACTION; -+ prHdr->u2DurationID = 0; -+ kalMemCopy(prHdr->aucAddr1, pPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(prHdr->aucAddr2, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(prHdr->aucAddr3, prBssInfo->aucBSSID, TDLS_FME_MAC_ADDR_LEN); -+ prHdr->u2SeqCtrl = 0; -+ LR_TDLS_FME_FIELD_FILL(sizeof(WLAN_MAC_HEADER_T)); -+ -+ /* Frame Formation - (1) Category */ -+ *pPkt = CATEGORY_PUBLIC_ACTION; -+ LR_TDLS_FME_FIELD_FILL(1); -+ } -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = ucActionCode; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - Status Code */ -+ switch (ucActionCode) { -+ case TDLS_FRM_ACTION_SETUP_RSP: -+ case TDLS_FRM_ACTION_CONFIRM: -+ case TDLS_FRM_ACTION_TEARDOWN: -+ WLAN_SET_FIELD_16(pPkt, u2StatusCode); -+ LR_TDLS_FME_FIELD_FILL(2); -+ break; -+ } -+ -+ /* 3. Frame Formation - (3) Dialog token */ -+ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { -+ *pPkt = ucDialogToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ } -+ -+ /* Fill elements */ -+ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { -+ /* -+ Capability -+ -+ Support Rates -+ Extended Support Rates -+ Supported Channels -+ HT Capabilities -+ WMM Information Element -+ -+ Extended Capabilities -+ Link Identifier -+ -+ RSNIE -+ FTIE -+ Timeout Interval -+ */ -+ if (ucActionCode != TDLS_FRM_ACTION_CONFIRM) { -+ /* 3. Frame Formation - (4) Capability: 0x31 0x04, privacy bit will be set */ -+ u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec); -+ WLAN_SET_FIELD_16(pPkt, u2CapInfo); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 4. Append general IEs */ -+ /* -+ TODO check HT: prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode -+ must be CONFIG_BW_20_40M. -+ -+ TODO check HT: HT_CAP_INFO_40M_INTOLERANT must be clear if -+ Tdls 20/40 is enabled. -+ */ -+ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, u2StatusCode, pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 5. Frame Formation - Extended capabilities element */ -+ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; -+ EXT_CAP_IE(pPkt)->ucLength = 5; -+ -+ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ -+ -+ /* if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD) */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); -+ /* if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH) */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); -+ /* if (prCmd->ucExCap & TDLS_EX_CAP_TDLS) */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ } else { -+ /* 5. Frame Formation - WMM Parameter element */ -+ if (prAdapter->rWifiVar.fgSupportQoS) { -+ u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, -+ prBssInfo, pPkt, OP_MODE_INFRASTRUCTURE); -+ -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ } -+ } -+ } -+ -+ /* 6. Frame Formation - 20/40 BSS Coexistence */ -+ /* -+ Follow WiFi test plan, add 20/40 element to request/response/confirm. -+ */ -+/* if (prGlueInfo->rTdlsLink.fgIs2040Sup == TRUE) */ /* force to enable */ -+ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { -+ /* -+ bit0 = 1: The Information Request field is used to indicate that a -+ transmitting STA is requesting the recipient to transmit a 20/40 BSS -+ Coexistence Management frame with the transmitting STA as the -+ recipient. -+ -+ bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP -+ that receives this information or reports of this information from -+ operating a 20/40 MHz BSS. -+ -+ bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit -+ a receiving AP from operating its BSS as a 20/40 MHz BSS. -+ */ -+ BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE; -+ BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1; -+ BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01; -+ LR_TDLS_FME_FIELD_FILL(3); -+ } -+ -+ /* 6. Frame Formation - HT Operation element */ -+/* u4IeLen = rlmFillHtOpIeBody(prBssInfo, pPkt); */ -+/* LR_TDLS_FME_FIELD_FILL(u4IeLen); */ -+ -+ /* 7. Frame Formation - Link identifier element */ -+ /* Note1: Link ID sequence must be correct; Or the calculated MIC will be error */ -+ /* -+ Note2: When we receive a setup request with link ID, Marvell will send setup response -+ to the peer in link ID, not the SA in the WLAN header. -+ */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ -+ switch (ucActionCode) { -+ case TDLS_FRM_ACTION_SETUP_REQ: -+ case TDLS_FRM_ACTION_CONFIRM: -+ default: -+ /* we are initiator */ -+ pucInitiator = prBssInfo->aucOwnMacAddr; -+ pucResponder = pPeerMac; -+ -+ if (prStaRec != NULL) -+ prStaRec->flgTdlsIsInitiator = TRUE; -+ break; -+ -+ case TDLS_FRM_ACTION_SETUP_RSP: -+ case TDLS_FRM_ACTION_DISCOVERY_RESPONSE: -+ /* peer is initiator */ -+ pucInitiator = pPeerMac; -+ pucResponder = prBssInfo->aucOwnMacAddr; -+ -+ if (prStaRec != NULL) -+ prStaRec->flgTdlsIsInitiator = FALSE; -+ break; -+ -+ case TDLS_FRM_ACTION_TEARDOWN: -+ if (prStaRec != NULL) { -+ if (prStaRec->flgTdlsIsInitiator == TRUE) { -+ /* we are initiator */ -+ pucInitiator = prBssInfo->aucOwnMacAddr; -+ pucResponder = pPeerMac; -+ } else { -+ /* peer is initiator */ -+ pucInitiator = pPeerMac; -+ pucResponder = prBssInfo->aucOwnMacAddr; -+ } -+ } else { -+ /* peer is initiator */ -+ pucInitiator = pPeerMac; -+ pucResponder = prBssInfo->aucOwnMacAddr; -+ } -+ break; -+ } -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, pucInitiator, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, pucResponder, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 8. Append security IEs */ -+ /* -+ 11.21.5 TDLS Direct Link Teardown -+ If the STA has security enabled on the link 37 with the AP, then the FTIE shall be -+ included in the TDLS Teardown frame. -+ -+ For ralink station, it can accept our tear down without FTIE but marvell station. -+ */ -+/* if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) && (pAppendIe != NULL)) */ -+ if (pAppendIe != NULL) { -+ if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) || -+ ((ucActionCode == TDLS_FRM_ACTION_TEARDOWN) && -+ (prStaRec != NULL) && (prStaRec->fgTdlsInSecurityMode == TRUE))) { -+ kalMemCopy(pPkt, pAppendIe, AppendIeLen); -+ LR_TDLS_FME_FIELD_FILL(AppendIeLen); -+ } -+ } -+ -+ /* 7. Append Supported Operating Classes IE */ -+ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { -+ /* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */ -+ u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ } -+ -+ /* 11. send the data or management frame */ -+ if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RESPONSE) { -+#if 0 -+ /* -+ Note1: remember to modify our MAC & AP MAC & peer MAC in LINK ID -+ Note2: dialog token in rsp & confirm must be same as sender. -+ */ -+ -+#if 1 -+ /* example for Ralink's and Broadcom's TDLS setup request frame in open/none */ -+ if (ucActionCode == TDLS_FRM_ACTION_SETUP_REQ) { -+#if 0 -+ /* mediatek */ -+ char buffer[] = { 0x31, 0x04, -+ 0x01, 0x08, 0x02, 0x04, 0x0b, 0x16, 0xc, 0x12, 0x18, 0x24, -+ 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c, -+ 0x24, 0x0a, 0x01, 0x0b, 0x24, 0x04, 0x34, 0x04, 0x95, 0x04, 0xa5, 0x01, -+ 0x2d, 0x1a, 0x72, 0x11, 0x03, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f, -+ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0x20, -+ 0x48, 0x01, 0x01, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x31, 0x35, 0x97, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, -+ 0x1b, 0x1c, 0x1e, 0x20, 0x21, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e -+ }; -+#endif -+ -+#if 1 -+ /* ralink *//* from capability */ -+ char buffer[] = { 0x21, 0x04, -+ 0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0xdd, 0x20, 0x00, -+ 0x32, 0x04, 0x0c, 0x18, 0x30, 0x60, -+ 0x24, 0x06, 0x01, 0x0b, 0x24, 0x08, 0x95, 0x04, -+ 0x7f, 0x05, 0x01, 0x00, 0x00, 0x50, 0x20, -+ 0x3b, 0x10, 0x20, 0x01, 0x02, 0x03, 0x04, 0x0c, 0x16, 0x17, 0x18, 0x19, -+ 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, -+ 0x2d, 0x1a, 0x6e, 0x00, 0x17, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x48, 0x01, 0x01, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f -+ }; -+#endif -+#if 0 -+ /* 6630 */ -+ char buffer[] = { 0x01, 0x01, -+ 0x01, 0x04, 0x02, 0x04, 0x0b, 0x16, -+ 0x24, 0x02, 0x01, 0x0d, -+ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0xff, -+ 0x2d, 0x1a, 0x61, 0x01, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x38, 0x05, 0x02, 0xc0, 0xa8, 0x00, 0x00, -+ 0x48, 0x01, 0x01, -+ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, -+ 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x80, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, -+ 0x00, 0x00, 0x00, -+ 0xbf, 0x0c, 0x30, 0x01, 0x80, 0x03, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, -+ 0x00, 0x00 -+ }; -+#endif -+ -+ pPktTemp += 18; -+ memcpy(pPktTemp, buffer, sizeof(buffer)); -+ u4PktLen = 18 + sizeof(buffer); -+ } -+#endif -+ -+#if 1 -+ if (ucActionCode == TDLS_FRM_ACTION_CONFIRM) { -+ /* Note: dialog token must be same as request */ -+#if 1 -+ /* ralink */ -+ char buffer[] = { 0x00, -+ 0x01, 0x2d, 0x1a, 0x6e, 0x00, 0x17, 0xff, 0x00, 0x00, 0x00, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x0f, 0x00, 0x03, -+ 0xa4, 0x00, 0x00, 0x27, 0xa4, 0x00, 0x00, 0x42, 0x43, 0x5e, 0x00, -+ 0x62, 0x32, 0x2f, 0x00 -+ }; -+#endif -+ -+#if 0 -+ /* 6630 */ -+ char buffer[] = { 0x00, -+ 0x01, -+ 0x38, 0x05, 0x02, 0xc0, 0xa8, 0x00, 0x00, -+ 0x48, 0x01, 0x01, -+ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, -+ 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00, -+ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x80, 0x3f, 0x00, 0x00, -+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, -+ 0x00, 0x00, 0x00 -+ }; -+#endif -+ -+#if 0 -+ /* A/D die */ -+ char buffer[] = { 0x00, -+ 0x01, -+ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x0f, 0x6b, 0x00, 0x00, -+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, -+ 0x00, 0x00, 0x00 0x65, 0x12, 0x00, 0x0c, 0x43, 0x31, 0x35, 0x97, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0x38, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, 0x1b, -+ 0x1c, 0x1e, 0x20, 0x21, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e -+ }; -+#endif -+ -+ pPktTemp += 18; -+ memcpy(pPktTemp, buffer, sizeof(buffer)); -+ u4PktLen = 18 + sizeof(buffer); -+ } -+#endif -+ -+#else -+ -+#if 0 -+ /* for test in open/none */ -+ if (ucActionCode == TDLS_FRM_ACTION_SETUP_REQ) { -+ char buffer[] = { 0x01, 0x04, -+ 0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0xdd, 0x20, 0x00, -+ 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c, -+ 0x24, 0x0a, 0x01, 0x0b, 0x24, 0x04, 0x34, 0x04, 0x95, 0x04, 0xa5, 0x01, -+ 0x2d, 0x1a, 0x72, 0x11, 0x03, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f, -+ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0x20, -+ 0x48, 0x01, 0x01, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, -+ 0x1b, 0x1c, 0x1e, 0x20, 0x21 -+ }; -+ -+ pPktTemp += 18; -+ memcpy(pPktTemp, buffer, sizeof(buffer)); -+ u4PktLen = 18 + sizeof(buffer); -+ } -+#endif -+#endif /* 0 */ -+ -+ /* 9. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); -+ } else { -+ /* -+ A TDLS capable STA that receives a TDLS Discovery Request frame is required to -+ send the response "to the requesting STA, via the direct path." -+ However, prior to establishment of the direct link, the responding STA may not -+ know the rate capabilities of the requesting STA. In this case, the responding -+ STA shall send the TDLS Discovery Response frame using a rate from the -+ BSSBasicRateSet of the BSS to which the STA is currently associated. -+ */ -+ prMsduInfoMgmt->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfoMgmt->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; -+ prMsduInfoMgmt->ucNetworkType = prBssInfo->ucNetTypeIndex; -+ prMsduInfoMgmt->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfoMgmt->fgIs802_1x = FALSE; -+ prMsduInfoMgmt->fgIs802_11 = TRUE; -+ prMsduInfoMgmt->u2FrameLength = u4PktLen; -+ prMsduInfoMgmt->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfoMgmt->pfTxDoneHandler = NULL; -+ prMsduInfoMgmt->fgIsBasicRate = TRUE; /* use basic rate */ -+ -+ /* Send them to HW queue */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfoMgmt); -+ } -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ /* End of tdls_com.c */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c -new file mode 100644 -index 0000000000000..af66ef95d17cf ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c -@@ -0,0 +1,491 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/wapi.c#1 -+*/ -+ -+/*! \file "wapi.c" -+ \brief This file including the WAPI related function. -+ -+ This file provided the macros and functions library support the wapi ie parsing, -+ cipher and AKM check to help the AP seleced deciding. -+*/ -+ -+/* -+** Log: wapi.c -+** -+** 10 24 2012 wh.su -+** [ALPS00376392] [klocwork 9.1] in wapi.c, line 344 -+** Use MAX_NUM_SUPPORTED_WAPI_AKM_SUITESfor avoid Klocwork warning. -+** -+** 10 24 2012 wh.su -+** [ALPS00376391] [klocwork 9.1] in wapi.c, line 311 -+** Use the MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES for avoid Klccwork waring. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function -+ * fixed the network type -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 07 20 2010 wh.su -+ * -+ * . -+ * -+ * 04 06 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the firmware return the broadcast frame at wrong tc. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the function to check and update the default wapi tx -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the generate wapi ie function, and replace the tabe by space -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+#if CFG_SUPPORT_WAPI -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to generate WPA IE for -+* associate request frame. -+* -+* \param[in] prCurrentBss The Selected BSS description -+* -+* \retval The append WPA IE length -+* -+* \note -+* Called by: AIS module, Associate request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wapiGenerateWAPIIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ PUINT_8 pucBuffer; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX) -+ return; -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + prMsduInfo->u2FrameLength); -+ -+ /* ASSOC INFO IE ID: 68 :0x44 */ -+ if (/* prWlanInfo->fgWapiMode && */ prAdapter->prGlueInfo->u2WapiAssocInfoIESz) { -+ kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWapiAssocInfoIEs, -+ prAdapter->prGlueInfo->u2WapiAssocInfoIESz); -+ prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WapiAssocInfoIESz; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to parse WAPI IE. -+* -+* \param[in] prInfoElem Pointer to the RSN IE -+* \param[out] prRsnInfo Pointer to the BSSDescription structure to store the -+** WAPI information from the given WAPI IE -+* -+* \retval TRUE - Succeeded -+* \retval FALSE - Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wapiParseWapiIE(IN P_WAPI_INFO_ELEM_T prInfoElem, OUT P_WAPI_INFO_T prWapiInfo) -+{ -+ UINT_32 i; -+ INT_32 u4RemainWapiIeLen; -+ UINT_16 u2Version; -+ UINT_16 u2Cap = 0; -+ UINT_32 u4GroupSuite = WAPI_CIPHER_SUITE_WPI; -+ UINT_16 u2PairSuiteCount = 0; -+ UINT_16 u2AuthSuiteCount = 0; -+ PUCHAR pucPairSuite = NULL; -+ PUCHAR pucAuthSuite = NULL; -+ PUCHAR cp; -+ -+ DEBUGFUNC("wapiParseWapiIE"); -+ -+ ASSERT(prInfoElem); -+ ASSERT(prWapiInfo); -+ -+ /* Verify the length of the WAPI IE. */ -+ if (prInfoElem->ucLength < 6) { -+ DBGLOG(SEC, TRACE, "WAPI IE length too short (length=%d)\n", prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ /* Check WAPI version: currently, we only support version 1. */ -+ WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); -+ if (u2Version != 1) { -+ DBGLOG(SEC, TRACE, "Unsupported WAPI IE version: %d\n", u2Version); -+ return FALSE; -+ } -+ -+ cp = (PUCHAR) &prInfoElem->u2AuthKeyMgtSuiteCount; -+ u4RemainWapiIeLen = (INT_32) prInfoElem->ucLength - 2; -+ -+ do { -+ if (u4RemainWapiIeLen == 0) -+ break; -+ -+ /* -+ AuthCount : 2 -+ AuthSuite : 4 * authSuiteCount -+ PairwiseCount: 2 -+ PairwiseSuite: 4 * pairSuiteCount -+ GroupSuite : 4 -+ Cap : 2 */ -+ -+ /* Parse the Authentication and Key Management Cipher Suite Count -+ field. */ -+ if (u4RemainWapiIeLen < 2) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in auth & key mgt suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); -+ cp += 2; -+ u4RemainWapiIeLen -= 2; -+ -+ /* Parse the Authentication and Key Management Cipher Suite List -+ field. */ -+ i = (UINT_32) u2AuthSuiteCount * 4; -+ if (u4RemainWapiIeLen < (INT_32) i) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in auth & key mgt suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucAuthSuite = cp; -+ -+ cp += i; -+ u4RemainWapiIeLen -= (INT_32) i; -+ -+ if (u4RemainWapiIeLen == 0) -+ break; -+ -+ /* Parse the Pairwise Key Cipher Suite Count field. */ -+ if (u4RemainWapiIeLen < 2) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in pairwise cipher suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); -+ cp += 2; -+ u4RemainWapiIeLen -= 2; -+ -+ /* Parse the Pairwise Key Cipher Suite List field. */ -+ i = (UINT_32) u2PairSuiteCount * 4; -+ if (u4RemainWapiIeLen < (INT_32) i) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in pairwise cipher suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucPairSuite = cp; -+ -+ cp += i; -+ u4RemainWapiIeLen -= (INT_32) i; -+ -+ /* Parse the Group Key Cipher Suite field. */ -+ if (u4RemainWapiIeLen < 4) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in group cipher suite (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_32(cp, &u4GroupSuite); -+ cp += 4; -+ u4RemainWapiIeLen -= 4; -+ -+ /* Parse the WAPI u2Capabilities field. */ -+ if (u4RemainWapiIeLen < 2) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in WAPI capabilities (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2Cap); -+ u4RemainWapiIeLen -= 2; -+ -+ /* Todo:: BKID support */ -+ } while (FALSE); -+ -+ /* Save the WAPI information for the BSS. */ -+ -+ prWapiInfo->ucElemId = ELEM_ID_WAPI; -+ -+ prWapiInfo->u2Version = u2Version; -+ -+ prWapiInfo->u4GroupKeyCipherSuite = u4GroupSuite; -+ -+ DBGLOG(SEC, LOUD, "WAPI: version %d, group key cipher suite %02x-%02x-%02x-%02x\n", -+ u2Version, (UCHAR) (u4GroupSuite & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); -+ -+ if (pucPairSuite) { -+ /* The information about the pairwise key cipher suites is present. */ -+ if (u2PairSuiteCount > MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES) -+ u2PairSuiteCount = MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES; -+ -+ prWapiInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucPairSuite, &prWapiInfo->au4PairwiseKeyCipherSuite[i]); -+ pucPairSuite += 4; -+ -+ DBGLOG(SEC, LOUD, "WAPI: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prWapiInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the pairwise key cipher suites is not present. -+ Use the default chipher suite for WAPI: WPI. */ -+ prWapiInfo->u4PairwiseKeyCipherSuiteCount = 1; -+ prWapiInfo->au4PairwiseKeyCipherSuite[0] = WAPI_CIPHER_SUITE_WPI; -+ -+ DBGLOG(SEC, LOUD, "WAPI: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prWapiInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ if (pucAuthSuite) { -+ /* The information about the authentication and key management suites -+ is present. */ -+ if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_WAPI_AKM_SUITES) -+ u2AuthSuiteCount = MAX_NUM_SUPPORTED_WAPI_AKM_SUITES; -+ -+ prWapiInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucAuthSuite, &prWapiInfo->au4AuthKeyMgtSuite[i]); -+ pucAuthSuite += 4; -+ -+ DBGLOG(SEC, LOUD, "WAPI: AKM suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prWapiInfo->au4AuthKeyMgtSuite[i] & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the authentication and key management suites -+ is not present. Use the default AKM suite for WAPI. */ -+ prWapiInfo->u4AuthKeyMgtSuiteCount = 1; -+ prWapiInfo->au4AuthKeyMgtSuite[0] = WAPI_AKM_SUITE_802_1X; -+ -+ DBGLOG(SEC, LOUD, "WAPI: AKM suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prWapiInfo->au4AuthKeyMgtSuite[0] & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ prWapiInfo->u2WapiCap = u2Cap; -+ DBGLOG(SEC, LOUD, "WAPI: cap: 0x%04x\n", prWapiInfo->u2WapiCap); -+ -+ return TRUE; -+} /* wapiParseWapiIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to perform WAPI policy selection for a given BSS. -+* -+* \param[in] prAdapter Pointer to the adapter object data area. -+* \param[in] prBss Pointer to the BSS description -+* -+* \retval TRUE - The WAPI policy selection for the given BSS is -+* successful. The selected pairwise and group cipher suites -+* are returned in the BSS description. -+* \retval FALSE - The WAPI policy selection for the given BSS is failed. -+* The driver shall not attempt to join the given BSS. -+* -+* \note The Encrypt status matched score will save to bss for final ap select. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wapiPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss) -+{ -+ UINT_32 i; -+ UINT_32 u4PairwiseCipher = 0; -+ UINT_32 u4GroupCipher = 0; -+ UINT_32 u4AkmSuite = 0; -+ P_WAPI_INFO_T prBssWapiInfo; -+ P_WLAN_INFO_T prWlanInfo; -+ -+ DEBUGFUNC("wapiPerformPolicySelection"); -+ -+ ASSERT(prBss); -+ -+ /* Notice!!!! WAPI AP not set the privacy bit for WAI and WAI-PSK at WZC configuration mode */ -+ prWlanInfo = &prAdapter->rWlanInfo; -+ -+ if (prBss->fgIEWAPI) { -+ prBssWapiInfo = &prBss->rIEWAPI; -+ } else { -+ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode == FALSE) { -+ DBGLOG(SEC, TRACE, "-- No Protected BSS\n"); -+ return TRUE; -+ } -+ DBGLOG(SEC, TRACE, "WAPI Information Element does not exist.\n"); -+ return FALSE; -+ } -+ -+ /* Select pairwise/group ciphers */ -+ for (i = 0; i < prBssWapiInfo->u4PairwiseKeyCipherSuiteCount; i++) { -+ if (prBssWapiInfo->au4PairwiseKeyCipherSuite[i] == -+ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedPairwiseCipher) { -+ u4PairwiseCipher = prBssWapiInfo->au4PairwiseKeyCipherSuite[i]; -+ } -+ } -+ if (prBssWapiInfo->u4GroupKeyCipherSuite == prAdapter->rWifiVar.rConnSettings.u4WapiSelectedGroupCipher) -+ u4GroupCipher = prBssWapiInfo->u4GroupKeyCipherSuite; -+ -+ /* Exception handler */ -+ /* If we cannot find proper pairwise and group cipher suites to join the -+ BSS, do not check the supported AKM suites. */ -+ if (u4PairwiseCipher == 0 || u4GroupCipher == 0) { -+ DBGLOG(SEC, TRACE, "Failed to select pairwise/group cipher (0x%08x/0x%08x)\n", -+ u4PairwiseCipher, u4GroupCipher); -+ return FALSE; -+ } -+ -+ /* Select AKM */ -+ /* If the driver cannot support any authentication suites advertised in -+ the given BSS, we fail to perform RSNA policy selection. */ -+ /* Attempt to find any overlapping supported AKM suite. */ -+ for (i = 0; i < prBssWapiInfo->u4AuthKeyMgtSuiteCount; i++) { -+ if (prBssWapiInfo->au4AuthKeyMgtSuite[i] == prAdapter->rWifiVar.rConnSettings.u4WapiSelectedAKMSuite) { -+ u4AkmSuite = prBssWapiInfo->au4AuthKeyMgtSuite[i]; -+ break; -+ } -+ } -+ -+ if (u4AkmSuite == 0) { -+ DBGLOG(SEC, TRACE, "Cannot support any AKM suites\n"); -+ return FALSE; -+ } -+ -+ DBGLOG(SEC, TRACE, "Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n", -+ (UINT_8) (u4PairwiseCipher & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF), -+ (UINT_8) (u4GroupCipher & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF)); -+ -+ DBGLOG(SEC, TRACE, "Selected AKM suite: %02x-%02x-%02x-%02x\n", -+ (UINT_8) (u4AkmSuite & 0x000000FF), -+ (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF), -+ (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF), (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF)); -+ -+ return TRUE; -+} /* wapiPerformPolicySelection */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is use for wapi mode, to update the current wpi tx idx ? 0 :1 . -+* -+* \param[in] prStaRec Pointer to the Sta record -+* \param[out] ucWlanIdx The Rx status->wlanidx field -+* -+* \retval TRUE - Succeeded -+* \retval FALSE - Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wapiUpdateTxKeyIdx(IN P_STA_RECORD_T prStaRec, IN UINT_8 ucWlanIdx) -+{ -+ UINT_8 ucKeyId; -+ -+ if ((ucWlanIdx & BITS(0, 3)) == CIPHER_SUITE_WPI) { -+ -+ ucKeyId = ((ucWlanIdx & BITS(4, 5)) >> 4); -+ -+ if (ucKeyId != g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey) { -+ DBGLOG(RSN, STATE, -+ "Change wapi key index from %d->%d\n", -+ g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey, ucKeyId); -+ g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey = ucKeyId; -+ -+ prStaRec->ucWTEntry = -+ (ucKeyId == -+ WTBL_AIS_BSSID_WAPI_IDX_0) ? WTBL_AIS_BSSID_WAPI_IDX_0 : WTBL_AIS_BSSID_WAPI_IDX_1; -+ } -+ } -+} -+#endif -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c -new file mode 100644 -index 0000000000000..f54d229411485 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c -@@ -0,0 +1,301 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/mgmt/wnm.c#1 -+*/ -+ -+/*! \file "wnm.c" -+ \brief This file includes the 802.11v default vale and functions. -+*/ -+ -+/* -+** Log: wnm.c -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_SUPPORT_802_11V -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define WNM_MAX_TOD_ERROR 0 -+#define WNM_MAX_TOA_ERROR 0 -+#define MICRO_TO_10NANO(x) ((x)*100) -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+static UINT_8 ucTimingMeasToken; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to process the 802.11v wnm category action frame. -+* -+* -+* \note -+* Called by: Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wnmWNMAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_ACTION_FRAME prRxFrame; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxFrame = (P_WLAN_ACTION_FRAME) prSwRfb->pvHeader; -+ -+#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT -+ if (prRxFrame->ucAction == ACTION_WNM_TIMING_MEASUREMENT_REQUEST) { -+ wnmTimingMeasRequest(prAdapter, prSwRfb); -+ return; -+ } -+#endif -+ -+ DBGLOG(WNM, TRACE, "Unsupport WNM action frame: %d\n", prRxFrame->ucAction); -+} -+ -+#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to report timing measurement data. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wnmReportTimingMeas(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIndex, IN UINT_32 u4ToD, IN UINT_32 u4ToA) -+{ -+ P_STA_RECORD_T prStaRec; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); -+ -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) -+ return; -+ -+ DBGLOG(WNM, TRACE, "wnmReportTimingMeas: u4ToD %x u4ToA %x", u4ToD, u4ToA); -+ -+ if (!prStaRec->rWNMTimingMsmt.ucTrigger) -+ return; -+ -+ prStaRec->rWNMTimingMsmt.u4ToD = MICRO_TO_10NANO(u4ToD); -+ prStaRec->rWNMTimingMsmt.u4ToA = MICRO_TO_10NANO(u4ToA); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle TxDone(TimingMeasurement) Event. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prMsduInfo Pointer to the MSDU_INFO_T. -+* @param[in] rTxDoneStatus Return TX status of the Timing Measurement frame. -+* -+* @retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wnmRunEventTimgingMeasTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ DBGLOG(WNM, LOUD, "EVENT-TX DONE: Current Time = %u\n", kalGetTimeTick()); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) -+ return WLAN_STATUS_SUCCESS; /* For the case of replying ERROR STATUS CODE */ -+ -+ DBGLOG(WNM, TRACE, "wnmRunEventTimgingMeasTxDone: ucDialog %d ucFollowUp %d u4ToD %x u4ToA %x", -+ prStaRec->rWNMTimingMsmt.ucDialogToken, -+ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken, -+ prStaRec->rWNMTimingMsmt.u4ToD, prStaRec->rWNMTimingMsmt.u4ToA); -+ -+ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken; -+ prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; -+ -+ wnmComposeTimingMeasFrame(prAdapter, prStaRec, NULL); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of wnmRunEventTimgingMeasTxDone() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the Timing Measurement frame. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+wnmComposeTimingMeasFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME prTxFrame; -+ UINT_16 u2PayloadLen; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ ASSERT(prBssInfo); -+ -+ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); -+ -+ if (!prMsduInfo) -+ return; -+ -+ prTxFrame = (P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME) -+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; -+ -+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); -+ -+ prTxFrame->ucCategory = CATEGORY_UNPROTECTED_WNM_ACTION; -+ prTxFrame->ucAction = ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT; -+ -+ /* 3 Compose the frame body's frame. */ -+ prTxFrame->ucDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken; -+ prTxFrame->ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken; -+ prTxFrame->u4ToD = prStaRec->rWNMTimingMsmt.u4ToD; -+ prTxFrame->u4ToA = prStaRec->rWNMTimingMsmt.u4ToA; -+ prTxFrame->ucMaxToDErr = WNM_MAX_TOD_ERROR; -+ prTxFrame->ucMaxToAErr = WNM_MAX_TOA_ERROR; -+ -+ u2PayloadLen = 2 + ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN; -+ -+ /* 4 Update information of MSDU_INFO_T */ -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ DBGLOG(WNM, TRACE, "wnmComposeTimingMeasFrame: ucDialogToken %d ucFollowUpDialogToken %d u4ToD %x u4ToA %x\n", -+ prTxFrame->ucDialogToken, prTxFrame->ucFollowUpDialogToken, -+ prTxFrame->u4ToD, prTxFrame->u4ToA); -+ -+ /* 4 Enqueue the frame to send this action frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return; -+ -+} /* end of wnmComposeTimingMeasFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to process the 802.11v timing measurement request. -+* -+* -+* \note -+* Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wnmTimingMeasRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_ACTION_WNM_TIMING_MEAS_REQ_FRAME prRxFrame = NULL; -+ P_STA_RECORD_T prStaRec; -+ -+ prRxFrame = (P_ACTION_WNM_TIMING_MEAS_REQ_FRAME) prSwRfb->pvHeader; -+ if (!prRxFrame) -+ return; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) -+ return; -+ -+ DBGLOG(WNM, TRACE, "IEEE 802.11: Received Timing Measuremen Request from %pM\n" -+ prStaRec->aucMacAdd); -+ -+ /* reset timing msmt */ -+ prStaRec->rWNMTimingMsmt.fgInitiator = TRUE; -+ prStaRec->rWNMTimingMsmt.ucTrigger = prRxFrame->ucTrigger; -+ if (!prRxFrame->ucTrigger) -+ return; -+ -+ prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; -+ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0; -+ -+ wnmComposeTimingMeasFrame(prAdapter, prStaRec, wnmRunEventTimgingMeasTxDone); -+} -+ -+#if WNM_UNIT_TEST -+VOID wnmTimingMeasUnitTest1(P_ADAPTER_T prAdapter, UINT_8 ucStaRecIndex) -+{ -+ P_STA_RECORD_T prStaRec; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) -+ return; -+ -+ DBGLOG(WNM, INFO, "IEEE 802.11v: Test Timing Measuremen Request from %pM\n", -+ prStaRec->aucMacAddr); -+ -+ prStaRec->rWNMTimingMsmt.fgInitiator = TRUE; -+ prStaRec->rWNMTimingMsmt.ucTrigger = 1; -+ -+ prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; -+ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0; -+ -+ wnmComposeTimingMeasFrame(prAdapter, prStaRec, wnmRunEventTimgingMeasTxDone); -+} -+#endif -+ -+#endif /* CFG_SUPPORT_802_11V_TIMING_MEASUREMENT */ -+ -+#endif /* CFG_SUPPORT_802_11V */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c -new file mode 100644 -index 0000000000000..6f1bb6fd771ec ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c -@@ -0,0 +1,254 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/cmd_buf.c#1 -+*/ -+ -+/*! \file "cmd_buf.c" -+ \brief This file contain the management function of internal Command Buffer -+ for CMD_INFO_T. -+ -+ We'll convert the OID into Command Packet and then send to FW. Thus we need -+ to copy the OID information to Command Buffer for following reasons. -+ 1. The data structure of OID information may not equal to the data structure of -+ Command, we cannot use the OID buffer directly. -+ 2. If the Command was not generated by driver we also need a place to store the -+ information. -+ 3. Because the CMD is NOT FIFO when doing memory allocation (CMD will be generated -+ from OID or interrupt handler), thus we'll use the Block style of Memory Allocation -+ here. -+*/ -+ -+/* -+** Log: cmd_buf.c -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 02 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. clear prPendingCmdInfo properly -+ * * 2. while allocating memory for cmdinfo, no need to add extra 4 bytes. -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-10-13 21:59:08 GMT mtk01084 -+** remove un-neceasary spaces -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-05-20 12:24:26 GMT mtk01461 -+** Increase CMD Buffer - HIF_RX_HW_APPENDED_LEN when doing CMD_INFO_T allocation -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 09:41:08 GMT mtk01461 -+** Add init of Driver Domain MCR flag and fix lint MTK WARN -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-17 19:51:45 GMT mtk01461 -+** allocation function of CMD_INFO_T -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static BOOLEAN fgCmdDumpIsDone = FALSE; -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to initial the MGMT memory pool for CMD Packet. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cmdBufInitialize(IN P_ADAPTER_T prAdapter) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ QUEUE_INITIALIZE(&prAdapter->rFreeCmdList); -+ -+ for (i = 0; i < CFG_TX_MAX_CMD_PKT_NUM; i++) { -+ prCmdInfo = &prAdapter->arHifCmdDesc[i]; -+ QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry); -+ } -+ fgCmdDumpIsDone = FALSE; -+} /* end of cmdBufInitialize() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief dump CMD queue and print to trace, for debug use only -+* @param[in] prQueue Pointer to the command Queue to be dumped -+* @param[in] quename Name of the queue -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cmdBufDumpCmdQueue(P_QUE_T prQueue, CHAR *queName) -+{ -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)QUEUE_GET_HEAD(prQueue); -+ -+ DBGLOG(NIC, INFO, "Dump CMD info for %s, Elem number:%u\n", queName, prQueue->u4NumElem); -+ while (prCmdInfo) { -+ P_CMD_INFO_T prCmdInfo1, prCmdInfo2, prCmdInfo3; -+ -+ prCmdInfo1 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo); -+ if (!prCmdInfo1) { -+ DBGLOG(NIC, INFO, "CID:%d SEQ:%d\n", prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum); -+ break; -+ } -+ prCmdInfo2 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo1); -+ if (!prCmdInfo2) { -+ DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", prCmdInfo->ucCID, -+ prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, prCmdInfo1->ucCmdSeqNum); -+ break; -+ } -+ prCmdInfo3 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo2); -+ if (!prCmdInfo3) { -+ DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", prCmdInfo->ucCID, -+ prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, prCmdInfo1->ucCmdSeqNum, -+ prCmdInfo2->ucCID, prCmdInfo2->ucCmdSeqNum); -+ break; -+ } -+ DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", -+ prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, -+ prCmdInfo1->ucCmdSeqNum, prCmdInfo2->ucCID, prCmdInfo2->ucCmdSeqNum, -+ prCmdInfo3->ucCID, prCmdInfo3->ucCmdSeqNum); -+ prCmdInfo = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo3); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Allocate CMD_INFO_T from a free list and MGMT memory pool. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] u4Length Length of the frame buffer to allocate. -+* -+* @retval NULL Pointer to the valid CMD Packet handler -+* @retval !NULL Fail to allocat CMD Packet -+*/ -+/*----------------------------------------------------------------------------*/ -+P_CMD_INFO_T cmdBufAllocateCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("cmdBufAllocateCmdInfo"); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ -+ if (prCmdInfo) { -+ /* Setup initial value in CMD_INFO_T */ -+ /* Start address of allocated memory */ -+ prCmdInfo->pucInfoBuffer = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length); -+ -+ if (prCmdInfo->pucInfoBuffer == NULL) { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ -+ prCmdInfo = NULL; -+ -+ DBGLOG(NIC, ERROR, "Allocate prCmdInfo->pucInfoBuffer fail!\n"); -+ } else { -+ prCmdInfo->u2InfoBufLen = 0; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ } -+ fgCmdDumpIsDone = FALSE; -+ } else if (!fgCmdDumpIsDone) { -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ P_QUE_T prCmdQue = &prGlueInfo->rCmdQueue; -+ P_QUE_T prPendingCmdQue = &prAdapter->rPendingCmdQueue; -+ P_TX_TCQ_STATUS_T prTc = &prAdapter->rTxCtrl.rTc; -+ -+ fgCmdDumpIsDone = TRUE; -+ cmdBufDumpCmdQueue(prCmdQue, "waiting Tx CMD queue"); -+ cmdBufDumpCmdQueue(prPendingCmdQue, "waiting response CMD queue"); -+ DBGLOG(NIC, INFO, "Tc4 number:%d\n", prTc->aucFreeBufferCount[TC4_INDEX]); -+ if (prTc->aucFreeBufferCount[TC4_INDEX] != 0) -+ glDoChipReset(); -+ } -+ -+ return prCmdInfo; -+ -+} /* end of cmdBufAllocateCmdInfo() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to free the CMD Packet to the MGMT memory pool. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo CMD Packet handler -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cmdBufFreeCmdInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("cmdBufFreeCmdInfo"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ if (prCmdInfo) { -+ if (prCmdInfo->pucInfoBuffer) { -+ cnmMemFree(prAdapter, prCmdInfo->pucInfoBuffer); -+ prCmdInfo->pucInfoBuffer = NULL; -+ } -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ } -+ -+ return; -+ -+} /* end of cmdBufFreeCmdPacket() */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c -new file mode 100644 -index 0000000000000..dfaaedd118bfb ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c -@@ -0,0 +1,4062 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic.c#2 -+*/ -+ -+/*! \file nic.c -+ \brief Functions that provide operation in NIC's (Network Interface Card) point of view. -+ -+ This file includes functions which unite multiple hal(Hardware) operations -+ and also take the responsibility of Software Resource Management in order -+ to keep the synchronization with Hardware Manipulation. -+*/ -+ -+/* -+** Log: nic.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 05 02 2012 terry.wu -+ * NULL -+ * Set the default value of AP StaRec index to "STA_REC_INDEX_NOT_FOUND" in update firmware bss command. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 11 28 2011 cp.wu -+ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment when -+ * returining to ROM code -+ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware -+ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not -+ * -+ * 11 22 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * keep debug counter setting after wake up. -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Update RSSI for P2P. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 11 04 2011 cp.wu -+ * [WCXRP00001079] [MT5931][Driver] Release pending MMPDU only when BSS is being deactivated -+ * pre-check for NULL before calling MMPDU free function -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG -+ * -+ * 11 01 2011 chinglan.wang -+ * NULL -+ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP. -+ * If disconnect the AP and flush all the data frame in the TX queue, WPS cannot do the 4-way handshake to connect to -+ * the AP.. -+ * -+ * 10 11 2011 terry.wu -+ * NULL -+ * Rewrite Assert Dump Function for Portability. -+ * -+ * 09 20 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * New CMD definition about RLM parameters -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * reuse firmware download logic of MT6620 for MT6628. -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting device -+ * issue. -+ * Fix GO send deauth frame issue. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 07 11 2011 wh.su -+ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define for make sure the value is initialize, for -+ * customer not enable WAPI -+ * For make sure wapi initial value is set. -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky -+ * AP which use space character as hidden SSID -+ * 1. correct logic -+ * 2. replace only BSS-DESC which doesn't have a valid SSID. -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky -+ * AP which use space character as hidden SSID -+ * allow to have a single BSSID with multiple SSID to be presented in scanning result -+ * -+ * 05 12 2011 puff.wen -+ * NULL -+ * FW Assert information dump to driver -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 15 2011 cp.wu -+ * [WCXRP00000651] [MT6620 Wi-Fi][Driver] Refine RSSI buffering mechanism -+ * ROLLBACK due to the special design is to workaround incorrect initial RCPI value coming from firmware domain. -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 14 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected -+ * 2. add dummy function for both Win32 and Linux part. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for -+ * dedicated network type -+ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected -+ * -+ * 04 12 2011 wh.su -+ * NULL -+ * enable the p2p check the cipher to set the bssInfo auth mode. -+ * -+ * 04 12 2011 wh.su -+ * NULL -+ * prepare the code for sync the auth mode and encryption status for P2P and BOW. -+ * -+ * 04 11 2011 yuche.tsai -+ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue. -+ * Fix kernel panic issue when MMPDU of P2P is pending in driver. -+ * -+ * 04 10 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * Fix compiler issue. -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 04 07 2011 cp.wu -+ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure happend inside -+ * wlanAdapterStart -+ * . -+ * -+ * 04 07 2011 cp.wu -+ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure happend inside -+ * wlanAdapterStart -+ * implementation of internal error handling of nicAllocateAdapterMemory. -+ * -+ * 03 31 2011 chinglan.wang -+ * [WCXRP00000613] [MT6620 Wi-Fi] [FW] [Driver] BssInfo can get the security mode which is WPA/WPA2/WAPI or not. -+ * . -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * use pre-allocated buffer for storing enhanced interrupt response as well -+ * -+ * 03 16 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * 1. pre-allocate physical continuous buffer while module is being loaded -+ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer -+ * -+ * The windows part remained the same as before, but added similar APIs to hide the difference. -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 10 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after -+ * connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 08 2011 terry.wu -+ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log -+ * Use kalPrint to print firmware assert info. -+ * -+ * 02 01 2011 terry.wu -+ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log -+ * . -+ * -+ * 02 01 2011 cm.chang -+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode -+ * . -+ * -+ * 01 31 2011 terry.wu -+ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log -+ * Print firmware ASSERT info at Android kernel log, driver side -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * Allocate system RAM if fixed message or mgmt buffer is not available -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 19 2011 cp.wu -+ * [WCXRP00000372] [MT6620 Wi-Fi][Driver] Check bus access failure inside nicProcessIST() -+ * check bus error and/or card removal when retrieving interrupt status from HAL -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * 1) correct typo in scan.c -+ * 2) TX descriptors, RX descriptos and management buffer should use virtually continuous buffer instead of -+ * physically contineous one -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 30 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * host driver not to set FW-own when there is still pending interrupts -+ * -+ * 12 17 2010 cp.wu -+ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged -+ * before BSS disconnection is indicated to firmware, all correlated peer should be cleared and freed -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 02 2010 eddie.chen -+ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry -+ * Add more control value but dont use it now. -+ * -+ * 11 30 2010 eddie.chen -+ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry -+ * Add auto rate check window in registry -+ * -+ * 11 10 2010 eddie.chen -+ * [WCXRP00000156] [MT6620][FW] Change Auto rate window to 64 and add throughput swcr -+ * Use autorate parameter 1 as phy rate mask. -+ * -+ * 11 08 2010 cp.wu -+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period -+ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time -+ * -+ * 10 26 2010 eddie.chen -+ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB -+ * Add auto rate parameter in registry. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to -+ * BSOD when entering RF test with AIS associated -+ * 1. remove redundant variables in STA_REC structure -+ * 2. add STA-REC uninitialization routine for clearing pending events -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000103] [MT6620 Wi-Fi][Driver] Driver crashed when using WZC to connect to AP#B with connection with AP#A -+ * reset ptrs when IEs are going to be dropped -+ * -+ * 10 12 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * add HT (802.11n) fixed rate support. -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by -+ * ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test -+ * with AIS associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * Androi/Linux: return current operating channel information -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * HIFSYS Clock Source Workaround -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Fix someones coding error while enable WIFI_DIRECT. -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update BOW for the 1st time. -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Add state change indication. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add support for P2P BSS update info. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [removing debugging] not to dump beacon content. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 11 2010 cp.wu -+ * NULL -+ * 1) do not use in-stack variable for beacon updating. (for MAUI porting) -+ * 2) extending scanning result to 64 instead of 48 -+ * -+ * 08 04 2010 yarco.yang -+ * NULL -+ * Add TX_AMPDU and ADDBA_REJECT command -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * Centralize mgmt/system service procedures into independent calls. -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * sync. CMD_BSS_INFO structure change to CMD-EVENT v0.15. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 23 2010 cp.wu -+ * -+ * FIX: structure of CMD_SET_BSS_INFO has been changed but no follow-ups are done. -+ * -+ * 07 22 2010 george.huang -+ * -+ * . -+ * -+ * 07 22 2010 george.huang -+ * -+ * Update fgIsQoS information in BSS INFO by CMD -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * update prStaRecOfAP with BSS-INFO. -+ * -+ * 07 06 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Update arguments for nicUpdateBeaconIETemplate() -+ * -+ * 07 06 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * STA-REC is maintained by CNM only. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) ignore RSN checking when RSN is not turned on. -+ * 2) set STA-REC deactivation callback as NULL -+ * 3) add variable initialization API based on PHY configuration -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support sync command of STA_REC -+ * -+ * 06 30 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync. with CMD/EVENT document ver0.07. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * correct variable naming for 8-bit variable used in CMD_BEACON_TEMPLATE_UPDATE. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 25 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Create beacon update path, with expose bssUpdateBeaconContent() -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * fill fgIsUapsdConnection when indicating BSS-CREATE with AIS-STA mode. -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implement TX_DONE callback path. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * TX descriptors are now allocated once for reducing allocation overhead -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) surpress compiler warning -+ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add channel frequency <-> number conversion -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver -+ * correct nicProcessIST_impl() for interrupt status brought up by RX enhanced response -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+ * 03 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always process TX interrupt first then RX interrupt. -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add checksum offloading support. -+** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-12-16 18:03:43 GMT mtk02752 -+** handling enhanced response which fields are fetched at different moments -+** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-12-15 17:00:29 GMT mtk02752 -+** if RX enhanced response is used, D2H interrupt status should be coming from buffered result as well -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-12-15 12:01:55 GMT mtk02752 -+** if TX_DONE bit is not set but WTSR0/WTSR1 is non-zero, then set TX_DONE -+** bit due to time latency of interrupt status enhanced response -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:52:52 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-24 20:51:01 GMT mtk02752 -+** integrate with SD1 by invoking qmHandleMailboxRxMessage() -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-16 17:32:33 GMT mtk02752 -+** prepare code for invoking rxHandleMailboxRxMessage() -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-11 10:36:08 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-09 22:56:41 GMT mtk01084 -+** modify HW access routines -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-30 18:17:20 GMT mtk01084 -+** prevent warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-29 19:54:57 GMT mtk01084 -+** init HIF -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-10-23 16:08:30 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-10-13 21:59:12 GMT mtk01084 -+** update for new HW design -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-09-09 17:26:15 GMT mtk01084 -+** modify for CFG_TEST_WITH_MT5921 -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-05-19 10:55:22 GMT mtk01461 -+** Unmask the unused HISR -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-05-18 15:59:13 GMT mtk01084 -+** remove debug purpose code -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-05-18 14:05:02 GMT mtk01084 -+** update for WIFI ownback part on initial -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-04 21:32:57 GMT mtk01084 -+** add temporarily code to set driver own on adapter initialization -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-28 10:35:41 GMT mtk01461 -+** Add init of TX aggregation and fix RX STATUS is DW align for SDIO_STATUS_ENHANCE mode -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-24 21:12:10 GMT mtk01104 -+** Add function nicRestoreSpiDefMode() -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-21 09:43:31 GMT mtk01461 -+** Revise for MTK coding style - nicInitializeAdapter() -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-17 19:52:47 GMT mtk01461 -+** Update allocate Adapter Memory for MGMT Memory pool -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:57:08 GMT mtk01461 -+** Refine the order of release memory from pucRxCoalescingBufCached -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-19 18:32:57 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 21:00:14 GMT mtk01426 -+** Add CFG_SDIO_RX_ENHANCE support -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:10:27 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:25:59 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+const UINT_8 aucPhyCfg2PhyTypeSet[PHY_CONFIG_NUM] = { -+ PHY_TYPE_SET_802_11ABG, /* PHY_CONFIG_802_11ABG */ -+ PHY_TYPE_SET_802_11BG, /* PHY_CONFIG_802_11BG */ -+ PHY_TYPE_SET_802_11G, /* PHY_CONFIG_802_11G */ -+ PHY_TYPE_SET_802_11A, /* PHY_CONFIG_802_11A */ -+ PHY_TYPE_SET_802_11B, /* PHY_CONFIG_802_11B */ -+ PHY_TYPE_SET_802_11ABGN, /* PHY_CONFIG_802_11ABGN */ -+ PHY_TYPE_SET_802_11BGN, /* PHY_CONFIG_802_11BGN */ -+ PHY_TYPE_SET_802_11AN, /* PHY_CONFIG_802_11AN */ -+ PHY_TYPE_SET_802_11GN /* PHY_CONFIG_802_11GN */ -+}; -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+#define REQ_GATING_ENABLE_H2D_INT BIT(31) -+#define REQ_GATING_DISABLE_H2D_INT BIT(30) -+#define ACK_GATING_ENABLE_D2H_INT BIT(31) -+#define ACK_GATING_DISABLE_D2H_INT BIT(30) -+ -+#define GATING_CONTROL_POLL_LIMIT 64 -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+static INT_EVENT_MAP_T arIntEventMapTable[] = { -+ {WHISR_ABNORMAL_INT, INT_EVENT_ABNORMAL}, -+ {WHISR_D2H_SW_INT, INT_EVENT_SW_INT}, -+ {WHISR_TX_DONE_INT, INT_EVENT_TX}, -+ {(WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT), INT_EVENT_RX} -+}; -+ -+static const UINT_8 ucIntEventMapSize = (sizeof(arIntEventMapTable) / sizeof(INT_EVENT_MAP_T)); -+ -+static IST_EVENT_FUNCTION apfnEventFuncTable[] = { -+ nicProcessAbnormalInterrupt, /*!< INT_EVENT_ABNORMAL */ -+ nicProcessSoftwareInterrupt, /*!< INT_EVENT_SW_INT */ -+ nicProcessTxInterrupt, /*!< INT_EVENT_TX */ -+ nicProcessRxInterrupt, /*!< INT_EVENT_RX */ -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/*! This macro is used to reduce coding errors inside nicAllocateAdapterMemory() -+ * and also enhance the readability. -+ */ -+#define LOCAL_NIC_ALLOCATE_MEMORY(pucMem, u4Size, eMemType, pucComment) \ -+ { \ -+ DBGLOG(NIC, INFO, "Allocating %u bytes for %s.\n", u4Size, pucComment); \ -+ pucMem = (PUINT_8)kalMemAlloc(u4Size, eMemType); \ -+ if (pucMem == (PUINT_8)NULL) { \ -+ DBGLOG(NIC, ERROR, "Could not allocate %u bytes for %s.\n", u4Size, pucComment); \ -+ break; \ -+ } \ -+ ASSERT(((ULONG)pucMem % 4) == 0); \ -+ DBGLOG(NIC, TRACE, "Virtual Address = %p for %s.\n", pucMem, pucComment); \ -+ } -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+VOID HifDumpEnhanceModeData(P_ADAPTER_T prAdapter) -+{ -+ dumpMemory32((PUINT_32)prAdapter->prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+} -+ -+VOID HifRegDump(P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i; -+ UINT_32 RegVal = 0; -+ -+ for (i = 0; i <= 0x58; i += 4) { -+ if ((i != MCR_WTDR0) && (i != MCR_WTDR1) && (i != MCR_WRDR0) && -+ (i != MCR_WRDR1) && (i != MCR_WSDIOCSR) && (i != MCR_WRPLR)) { -+ HAL_MCR_RD(prAdapter, i, &RegVal); -+ DBGLOG(NIC, WARN, "HIF Reg 0x%x = 0x%x\n", i, RegVal); -+ } -+ } -+ DBGLOG(NIC, WARN, "\n\n"); -+} -+ -+BOOLEAN HifIsFwOwn(P_ADAPTER_T prAdapter) -+{ -+ return prAdapter->fgIsFwOwn; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is responsible for the allocation of the data structures -+* inside the Adapter structure, include: -+* 1. SW_RFB_Ts -+* 2. Common coalescing buffer for TX PATH. -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @retval WLAN_STATUS_SUCCESS - Has enough memory. -+* @retval WLAN_STATUS_RESOURCES - Memory is not enough. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicAllocateAdapterMemory(IN P_ADAPTER_T prAdapter) -+{ -+ WLAN_STATUS status = WLAN_STATUS_RESOURCES; -+ P_RX_CTRL_T prRxCtrl; -+ P_TX_CTRL_T prTxCtrl; -+ -+ DEBUGFUNC("nicAllocateAdapterMemory"); -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ do { -+ /* 4 <0> Reset all Memory Handler */ -+#if CFG_DBG_MGT_BUF -+ prAdapter->u4MemFreeDynamicCount = 0; -+ prAdapter->u4MemAllocDynamicCount = 0; -+#endif -+ prAdapter->pucMgtBufCached = (PUINT_8) NULL; -+ prRxCtrl->pucRxCached = (PUINT_8) NULL; -+ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) NULL; -+ -+ /* 4 <1> Memory for Management Memory Pool and CMD_INFO_T */ -+ /* Allocate memory for the CMD_INFO_T and its MGMT memory pool. */ -+ prAdapter->u4MgtBufCachedSize = MGT_BUFFER_SIZE; -+ -+ LOCAL_NIC_ALLOCATE_MEMORY(prAdapter->pucMgtBufCached, -+ prAdapter->u4MgtBufCachedSize, VIR_MEM_TYPE, "COMMON MGMT MEMORY POOL"); -+ -+ /* 4 <2> Memory for RX Descriptor */ -+ /* Initialize the number of rx buffers we will have in our queue. */ -+ /* We may setup ucRxPacketDescriptors by GLUE Layer, and using -+ * this variable directly. -+ */ -+ /* Allocate memory for the SW receive structures. */ -+ prRxCtrl->u4RxCachedSize = CFG_RX_MAX_PKT_NUM * ALIGN_4(sizeof(SW_RFB_T)); -+ -+ LOCAL_NIC_ALLOCATE_MEMORY(prRxCtrl->pucRxCached, prRxCtrl->u4RxCachedSize, VIR_MEM_TYPE, "SW_RFB_T"); -+ -+ /* 4 <3> Memory for TX DEscriptor */ -+ prTxCtrl->u4TxCachedSize = CFG_TX_MAX_PKT_NUM * ALIGN_4(sizeof(MSDU_INFO_T)); -+ -+ LOCAL_NIC_ALLOCATE_MEMORY(prTxCtrl->pucTxCached, prTxCtrl->u4TxCachedSize, VIR_MEM_TYPE, "MSDU_INFO_T"); -+ -+ /* 4 <4> Memory for Common Coalescing Buffer */ -+#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG -+ prAdapter->pucCoalescingBufCached = (PUINT_8) NULL; -+ -+ /* Allocate memory for the common coalescing buffer. */ -+ prAdapter->u4CoalescingBufCachedSize = CFG_COALESCING_BUFFER_SIZE > CFG_RX_COALESCING_BUFFER_SIZE ? -+ CFG_COALESCING_BUFFER_SIZE : CFG_RX_COALESCING_BUFFER_SIZE; -+ -+ prAdapter->pucCoalescingBufCached = kalAllocateIOBuffer(prAdapter->u4CoalescingBufCachedSize); -+ -+ if (prAdapter->pucCoalescingBufCached == NULL) { -+ DBGLOG(NIC, ERROR, -+ "Could not allocate %u bytes for coalescing buffer.\n", -+ prAdapter->u4CoalescingBufCachedSize); -+ break; -+ } -+#endif /* CFG_COALESCING_BUFFER_SIZE */ -+ -+ /* 4 <5> Memory for enhanced interrupt response */ -+ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) -+ kalAllocateIOBuffer(sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ -+ if (prAdapter->prSDIOCtrl == NULL) { -+ DBGLOG(NIC, ERROR, -+ "Could not allocate %zu bytes for interrupt response.\n", -+ sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ break; -+ } -+ -+ status = WLAN_STATUS_SUCCESS; -+ -+ } while (FALSE); -+ -+ if (status != WLAN_STATUS_SUCCESS) -+ nicReleaseAdapterMemory(prAdapter); -+ -+ return status; -+ -+} /* end of nicAllocateAdapterMemory() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is responsible for releasing the allocated memory by -+* nicAllocatedAdapterMemory(). -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicReleaseAdapterMemory(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_RX_CTRL_T prRxCtrl; -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ /* 4 <5> Memory for enhanced interrupt response */ -+ if (prAdapter->prSDIOCtrl) { -+ kalReleaseIOBuffer((PVOID) prAdapter->prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) NULL; -+ } -+ /* 4 <4> Memory for Common Coalescing Buffer */ -+#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG -+ if (prAdapter->pucCoalescingBufCached) { -+ kalReleaseIOBuffer((PVOID) prAdapter->pucCoalescingBufCached, prAdapter->u4CoalescingBufCachedSize); -+ prAdapter->pucCoalescingBufCached = (PUINT_8) NULL; -+ } -+#endif /* CFG_COALESCING_BUFFER_SIZE */ -+ -+ /* 4 <3> Memory for TX Descriptor */ -+ if (prTxCtrl->pucTxCached) { -+ kalMemFree((PVOID) prTxCtrl->pucTxCached, VIR_MEM_TYPE, prTxCtrl->u4TxCachedSize); -+ prTxCtrl->pucTxCached = (PUINT_8) NULL; -+ } -+ /* 4 <2> Memory for RX Descriptor */ -+ if (prRxCtrl->pucRxCached) { -+ kalMemFree((PVOID) prRxCtrl->pucRxCached, VIR_MEM_TYPE, prRxCtrl->u4RxCachedSize); -+ prRxCtrl->pucRxCached = (PUINT_8) NULL; -+ } -+ /* 4 <1> Memory for Management Memory Pool */ -+ if (prAdapter->pucMgtBufCached) { -+ kalMemFree((PVOID) prAdapter->pucMgtBufCached, VIR_MEM_TYPE, prAdapter->u4MgtBufCachedSize); -+ prAdapter->pucMgtBufCached = (PUINT_8) NULL; -+ } -+#if CFG_DBG_MGT_BUF -+ /* Check if all allocated memories are free */ -+ ASSERT(prAdapter->u4MemFreeDynamicCount == prAdapter->u4MemAllocDynamicCount); -+#endif -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief disable global interrupt -+* -+* @param prAdapter pointer to the Adapter handler -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicDisableInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_CLR); -+ -+ prAdapter->fgIsIntEnable = FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief enable global interrupt -+* -+* @param prAdapter pointer to the Adapter handler -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicEnableInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ BOOLEAN fgIsIntEnableCache; -+ -+ ASSERT(prAdapter); -+ fgIsIntEnableCache = prAdapter->fgIsIntEnable; -+ -+ prAdapter->fgIsIntEnable = TRUE; /* NOTE(Kevin): It must be placed before MCR GINT write. */ -+ -+ /* If need enable INT and also set LPOwn at the same time. */ -+ if (prAdapter->fgIsIntEnableWithLPOwnSet) { -+ prAdapter->fgIsIntEnableWithLPOwnSet = FALSE; /* NOTE(Kevin): It's better to place it -+ * before MCR GINT write. -+ */ -+ /* If INT was enabled, only set LPOwn */ -+ if (fgIsIntEnableCache) { -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); -+ prAdapter->fgIsFwOwn = TRUE; -+ } -+ /* If INT was not enabled, enable it and also set LPOwn now */ -+ else { -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET | WHLPCR_INT_EN_SET); -+ prAdapter->fgIsFwOwn = TRUE; -+ } -+ } -+ /* If INT was not enabled, enable it now */ -+ else if (!fgIsIntEnableCache) -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_SET); -+ -+} /* end of nicEnableInterrupt() */ -+ -+#if CFG_SDIO_INTR_ENHANCE -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief For SDIO enhance mode, set the max rx len and tx status -+* -+* @param prAdapter a pointer to adapter private data structure. -+* -+* @return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicSDIOInit(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4Value = 0; -+ -+ ASSERT(prAdapter); -+ -+ /* 4 <1> Check STATUS Buffer is DW alignment. */ -+ ASSERT(IS_ALIGN_4((ULONG)&prAdapter->prSDIOCtrl->u4WHISR)); -+ -+ /* 4 <2> Setup STATUS count. */ -+ { -+ HAL_MCR_RD(prAdapter, MCR_WHCR, &u4Value); -+ -+ /* 4 <2.1> Setup the number of maximum RX length to be report */ -+ u4Value &= ~(WHCR_MAX_HIF_RX_LEN_NUM); -+ u4Value |= ((SDIO_MAXIMUM_RX_LEN_NUM << WHCR_OFFSET_MAX_HIF_RX_LEN_NUM)); -+ -+ /* 4 <2.2> Setup RX enhancement mode */ -+#if CFG_SDIO_RX_ENHANCE -+ u4Value |= WHCR_RX_ENHANCE_MODE_EN; -+#else -+ u4Value &= ~WHCR_RX_ENHANCE_MODE_EN; -+#endif /* CFG_SDIO_RX_AGG */ -+ -+ HAL_MCR_WR(prAdapter, MCR_WHCR, u4Value); -+ } -+ -+ return; -+ -+} /* end of nicSDIOInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read interrupt status from hardware -+* -+* @param prAdapter pointer to the Adapter handler -+* @param the interrupts -+* -+* @return N/A -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicSDIOReadIntStatus(IN P_ADAPTER_T prAdapter, OUT PUINT_32 pu4IntStatus) -+{ -+ P_SDIO_CTRL_T prSDIOCtrl; -+ -+ DEBUGFUNC("nicSDIOReadIntStatus"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4IntStatus); -+ -+ /* -+ prSDIOCtrl is from IO buffer. -+ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) -+ kalAllocateIOBuffer(sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ */ -+ prSDIOCtrl = prAdapter->prSDIOCtrl; -+ ASSERT(prSDIOCtrl); -+ -+ HAL_PORT_RD(prAdapter, -+ MCR_WHISR, -+ sizeof(ENHANCE_MODE_DATA_STRUCT_T), (PUINT_8) prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ *pu4IntStatus = 0; -+ return; -+ } -+ -+ /* workaround */ -+ if ((prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT) == 0 && -+ (prSDIOCtrl->rTxInfo.au4WTSR[0] | prSDIOCtrl->rTxInfo.au4WTSR[1])) { -+ prSDIOCtrl->u4WHISR |= WHISR_TX_DONE_INT; -+ } -+ -+ if ((prSDIOCtrl->u4WHISR & BIT(31)) == 0 && -+ HAL_GET_MAILBOX_READ_CLEAR(prAdapter) == TRUE && -+ (prSDIOCtrl->u4RcvMailbox0 != 0 || prSDIOCtrl->u4RcvMailbox1 != 0)) { -+ prSDIOCtrl->u4WHISR |= BIT(31); -+ } -+ -+ *pu4IntStatus = prSDIOCtrl->u4WHISR; -+ -+} /* end of nicSDIOReadIntStatus() */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The function used to read interrupt status and then invoking -+* dispatching procedure for the appropriate functions -+* corresponding to specific interrupt bits -+* -+* @param prAdapter pointer to the Adapter handler -+* -+* @retval WLAN_STATUS_SUCCESS -+* @retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicProcessIST(IN P_ADAPTER_T prAdapter) -+{ -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ UINT_32 u4IntStatus = 0; -+ UINT_32 i; -+ -+ DEBUGFUNC("nicProcessIST"); -+ /* DBGLOG(NIC, LOUD, ("\n")); */ -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(REQ, WARN, "Fail in set nicProcessIST! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == TRUE) -+ nicDisableClockGating(prAdapter); -+#endif -+ -+ for (i = 0; i < CFG_IST_LOOP_COUNT; i++) { /* CFG_IST_LOOP_COUNT = 1 */ -+ -+#if CFG_SDIO_INTR_ENHANCE -+ nicSDIOReadIntStatus(prAdapter, &u4IntStatus); -+#else -+ HAL_MCR_RD(prAdapter, MCR_WHISR, &u4IntStatus); -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+/* DBGLOG(NIC, TRACE, ("u4IntStatus: 0x%x\n", u4IntStatus)); */ -+ -+ if (u4IntStatus & ~(WHIER_DEFAULT | WHIER_FW_OWN_BACK_INT_EN)) { -+ DBGLOG(INTR, WARN, "Un-handled HISR %#x, HISR = %#x (HIER:0x%x)\n", -+ (UINT_32) (u4IntStatus & ~WHIER_DEFAULT), u4IntStatus, -+ (UINT_32) WHIER_DEFAULT); -+ u4IntStatus &= WHIER_DEFAULT; -+ } -+ -+ nicProcessIST_impl(prAdapter, u4IntStatus); -+ -+ if (u4IntStatus == 0) { -+ if (i == 0) -+ u4Status = WLAN_STATUS_NOT_INDICATING; -+ break; -+ } -+ } -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == FALSE) -+ nicEnableClockGating(prAdapter); -+#endif -+ -+ return u4Status; -+} /* end of nicProcessIST() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The function used to dispatch the appropriate functions for specific -+* interrupt bits -+* -+* @param prAdapter pointer to the Adapter handler -+* u4IntStatus interrupt status bits -+* -+* @retval WLAN_STATUS_SUCCESS -+* @retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicProcessIST_impl(IN P_ADAPTER_T prAdapter, IN UINT_32 u4IntStatus) -+{ -+ UINT_32 u4IntCount = 0; -+ P_INT_EVENT_MAP_T prIntEventMap = NULL; -+ -+ ASSERT(prAdapter); -+ -+ prAdapter->u4IntStatus = u4IntStatus; -+ -+ /* Process each of the interrupt status consequently */ -+ prIntEventMap = &arIntEventMapTable[0]; -+ for (u4IntCount = 0; u4IntCount < ucIntEventMapSize; prIntEventMap++, u4IntCount++) { -+ if (prIntEventMap->u4Int & prAdapter->u4IntStatus) { -+ if (prIntEventMap->u4Event == INT_EVENT_RX && prAdapter->fgIsEnterD3ReqIssued == TRUE) { -+ /* ignore */ -+ } else if (apfnEventFuncTable[prIntEventMap->u4Event] != NULL) { -+ apfnEventFuncTable[prIntEventMap->u4Event] (prAdapter); -+ } else { -+ DBGLOG(INTR, WARN, -+ "Empty INTR handler! ISAR bit#: %u, event:%u, func: %p\n", -+ prIntEventMap->u4Int, prIntEventMap->u4Event, -+ apfnEventFuncTable[prIntEventMap->u4Event]); -+ -+ ASSERT(0); /* to trap any NULL interrupt handler */ -+ } -+ prAdapter->u4IntStatus &= ~prIntEventMap->u4Int; -+ } -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of nicProcessIST_impl() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Verify the CHIP ID -+* -+* @param prAdapter a pointer to adapter private data structure. -+* -+* -+* @retval TRUE CHIP ID is the same as the setting compiled -+* @retval FALSE CHIP ID is different from the setting compiled -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN nicVerifyChipID(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4CIR = 0; -+ -+ ASSERT(prAdapter); -+ -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4CIR); -+ -+ DBGLOG(NIC, TRACE, "Chip ID: 0x%x\n", (UINT_32) (u4CIR & WCIR_CHIP_ID)); -+ DBGLOG(NIC, TRACE, "Revision ID: 0x%x\n", (UINT_32) ((u4CIR & WCIR_REVISION_ID) >> 16)); -+ -+#if 0 -+ if (((u4CIR & WCIR_CHIP_ID) != MTK_CHIP_REV_72) && ((u4CIR & WCIR_CHIP_ID) != MTK_CHIP_REV_82)) -+ return FALSE; -+#endif -+ -+ prAdapter->ucRevID = (UINT_8) (((u4CIR & WCIR_REVISION_ID) >> 16) & 0xF); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialize the MCR to the appropriate init value, and verify the init -+* value -+* -+* @param prAdapter a pointer to adapter private data structure. -+* -+* @return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicMCRInit(IN P_ADAPTER_T prAdapter) -+{ -+ -+ ASSERT(prAdapter); -+ -+ /* 4 <0> Initial value */ -+} -+ -+VOID nicHifInit(IN P_ADAPTER_T prAdapter) -+{ -+ -+ ASSERT(prAdapter); -+#if 0 -+ /* reset event */ -+ nicPutMailbox(prAdapter, 0, 0x52455345); /* RESE */ -+ nicPutMailbox(prAdapter, 1, 0x545F5746); /* T_WF */ -+ nicSetSwIntr(prAdapter, BIT(16)); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialize the Adapter soft variable -+* -+* @param prAdapter pointer to the Adapter handler -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicInitializeAdapter(IN P_ADAPTER_T prAdapter) -+{ -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ -+ prAdapter->fgIsIntEnableWithLPOwnSet = FALSE; -+ -+ do { -+ if (!nicVerifyChipID(prAdapter)) { -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ /* 4 <1> MCR init */ -+ nicMCRInit(prAdapter); -+ -+#if CFG_SDIO_INTR_ENHANCE -+ nicSDIOInit(prAdapter); -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+ HAL_MCR_WR(prAdapter, MCR_WHIER, WHIER_DEFAULT); -+ -+ /* 4 <2> init FW HIF */ -+ nicHifInit(prAdapter); -+ } while (FALSE); -+ -+ return u4Status; -+} -+ -+#if defined(_HIF_SPI) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Restore the SPI Mode Select to default mode, -+* this is important while driver is unload, and this must be last mcr -+* since the operation will let the hif use 8bit mode access -+* -+* \param[in] prAdapter a pointer to adapter private data structure. -+* \param[in] eGPIO2_Mode GPIO2 operation mode -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+void nicRestoreSpiDefMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ HAL_MCR_WR(prAdapter, MCR_WCSR, SPICSR_8BIT_MODE_DATA); -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process rx interrupt. When the rx -+* Interrupt is asserted, it means there are frames in queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicProcessAbnormalInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4Value = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prGlueInfo->IsrAbnormalCnt++; -+ HAL_MCR_RD(prAdapter, MCR_WASR, &u4Value); -+ DBGLOG(REQ, WARN, "MCR_WASR: 0x%x\n", u4Value); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief . -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicProcessFwOwnBackInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ -+} /* end of nicProcessFwOwnBackInterrupt() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief . -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicProcessSoftwareInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4IntrBits; -+ -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ u4IntrBits = prAdapter->u4IntStatus & BITS(8, 31); -+ -+ prGlueInfo->IsrSoftWareCnt++; -+ -+ if ((u4IntrBits & WHISR_D2H_SW_ASSERT_INFO_INT) != 0) { -+ nicPrintFirmwareAssertInfo(prAdapter); -+#if CFG_CHIP_RESET_SUPPORT -+ glSendResetRequest(); -+#endif -+ } -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ ASSERT((u4IntrBits & (ACK_GATING_ENABLE_D2H_INT | ACK_GATING_DISABLE_D2H_INT)) -+ != (ACK_GATING_ENABLE_D2H_INT | ACK_GATING_DISABLE_D2H_INT)); -+ -+ if (u4IntrBits & ACK_GATING_ENABLE_D2H_INT) -+ prAdapter->fgIsClockGatingEnabled = TRUE; -+ -+ if (u4IntrBits & ACK_GATING_DISABLE_D2H_INT) { -+ prAdapter->fgIsClockGatingEnabled = FALSE; -+ -+ /* Indicate Service Thread for TX */ -+ if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0) -+ kalSetEvent(prAdapter->prGlueInfo); -+ } -+#endif -+ -+ DBGLOG(REQ, WARN, "u4IntrBits: 0x%x\n", u4IntrBits); -+} /* end of nicProcessSoftwareInterrupt() */ -+ -+VOID nicPutMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, IN UINT_32 u4Data) -+{ -+ if (u4MailboxNum == 0) { -+ /* HAL_MCR_WR */ -+ HAL_MCR_WR(prAdapter, MCR_H2DSM0R, u4Data); -+ } else if (u4MailboxNum == 1) { -+ /* HAL_MCR_WR */ -+ HAL_MCR_WR(prAdapter, MCR_H2DSM1R, u4Data); -+ } else { -+ ASSERT(0); -+ } -+} -+ -+VOID nicGetMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, OUT PUINT_32 pu4Data) -+{ -+ if (u4MailboxNum == 0) { -+ /* HAL_MCR_RD */ -+ HAL_MCR_RD(prAdapter, MCR_D2HRM0R, pu4Data); -+ } else if (u4MailboxNum == 1) { -+ /* HAL_MCR_RD */ -+ HAL_MCR_RD(prAdapter, MCR_D2HRM1R, pu4Data); -+ } else { -+ ASSERT(0); -+ } -+} -+ -+VOID nicSetSwIntr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4SwIntrBitmap) -+{ -+ /* NOTE: -+ * SW interrupt in HW bit 16 is mapping to SW bit 0 (shift 16bit in HW transparancy) -+ * SW interrupt valid from b0~b15 -+ */ -+ ASSERT((u4SwIntrBitmap & BITS(0, 15)) == 0); -+/* DBGLOG(NIC, TRACE, ("u4SwIntrBitmap: 0x%08x\n", u4SwIntrBitmap)); */ -+ -+ HAL_MCR_WR(prAdapter, MCR_WSICR, u4SwIntrBitmap); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This procedure is used to dequeue from prAdapter->rPendingCmdQueue -+* with specified sequential number -+* -+* @param prAdapter Pointer of ADAPTER_T -+* ucSeqNum Sequential Number -+* -+* @retval - P_CMD_INFO_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_CMD_INFO_T nicGetPendingCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ prCmdQue = &prAdapter->rPendingCmdQueue; -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->ucCmdSeqNum == ucSeqNum) -+ break; -+ -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ -+ prCmdInfo = NULL; -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ return prCmdInfo; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This procedure is used to dequeue from prAdapter->rTxCtrl.rTxMgmtTxingQueue -+* with specified sequential number -+* -+* @param prAdapter Pointer of ADAPTER_T -+* ucSeqNum Sequential Number -+* -+* @retval - P_MSDU_INFO_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T nicGetPendingTxMsduInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum) -+{ -+ P_QUE_T prTxingQue; -+ QUE_T rTempQue; -+ P_QUE_T prTempQue = &rTempQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); -+ QUEUE_MOVE_ALL(prTempQue, prTxingQue); -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; -+ -+ if (prMsduInfo->ucTxSeqNum == ucSeqNum) -+ break; -+ -+ QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); -+ -+ prMsduInfo = NULL; -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ QUEUE_CONCATENATE_QUEUES(prTxingQue, prTempQue); -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ return prMsduInfo; -+} -+ -+P_MSDU_INFO_T nicGetPendingStaMMPDU(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx) -+{ -+ P_MSDU_INFO_T prMsduInfoListHead = (P_MSDU_INFO_T) NULL; -+ P_QUE_T prTxingQue = (P_QUE_T) NULL; -+ QUE_T rTempQue; -+ P_QUE_T prTempQue = &rTempQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ if (prAdapter == NULL) { -+ ASSERT(FALSE); -+ return NULL; -+ } -+ -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ do { -+ -+ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); -+ QUEUE_MOVE_ALL(prTempQue, prTxingQue); -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; -+ -+ if ((prMsduInfo->ucStaRecIndex == ucStaRecIdx) && (prMsduInfo->pfTxDoneHandler != NULL)) { -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfo, prMsduInfoListHead); -+ prMsduInfoListHead = prMsduInfo; -+ } else { -+ QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); -+ -+ prMsduInfo = NULL; -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ } while (FALSE); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ return prMsduInfoListHead; -+} /* nicGetPendingStaMMPDU */ -+ -+VOID nicFreePendingTxMsduInfoByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType) -+{ -+ P_QUE_T prTxingQue; -+ QUE_T rTempQue; -+ P_QUE_T prTempQue = &rTempQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_MSDU_INFO_T prMsduInfoListHead = (P_MSDU_INFO_T) NULL; -+ P_MSDU_INFO_T prMsduInfoListTail = (P_MSDU_INFO_T) NULL; -+ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); -+ QUEUE_MOVE_ALL(prTempQue, prTxingQue); -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; -+ -+ if ((ENUM_NETWORK_TYPE_INDEX_T) (prMsduInfo->ucNetworkType) == eNetworkType) { -+ if (prMsduInfoListHead == NULL) { -+ prMsduInfoListHead = prMsduInfoListTail = prMsduInfo; -+ } else { -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, prMsduInfo); -+ prMsduInfoListTail = prMsduInfo; -+ } -+ } else { -+ QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); -+ -+ prMsduInfo = NULL; -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ QUEUE_CONCATENATE_QUEUES(prTxingQue, prTempQue); -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ /* free */ -+ if (prMsduInfoListHead) -+ nicTxFreeMsduInfoPacket(prAdapter, prMsduInfoListHead); -+ -+ return; -+ -+} /* end of nicFreePendingTxMsduInfoByNetwork() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This procedure is used to retrieve a CMD sequence number atomically -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval - UINT_8 -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 nicIncreaseCmdSeqNum(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucRetval; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_SEQ_NUM); -+ -+ prAdapter->ucCmdSeqNum++; -+ ucRetval = prAdapter->ucCmdSeqNum; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_SEQ_NUM); -+ -+ return ucRetval; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This procedure is used to retrieve a TX sequence number atomically -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval - UINT_8 -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 nicIncreaseTxSeqNum(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucRetval; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_SEQ_NUM); -+ -+ prAdapter->ucTxSeqNum++; -+ ucRetval = prAdapter->ucTxSeqNum; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_SEQ_NUM); -+ -+ return ucRetval; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to handle -+* media state change event -+* -+* @param -+* -+* @retval -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicMediaStateChange(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ ASSERT(prAdapter); -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ switch (eNetworkType) { -+ case NETWORK_TYPE_AIS_INDEX: -+ if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_DISCONNECTED) { /* disconnected */ -+ if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { -+ -+ DBGLOG(NIC, TRACE, "DisByMC\n"); -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ -+ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); -+ } -+ -+ /* reset buffered link quality information */ -+ prAdapter->fgIsLinkQualityValid = FALSE; -+ prAdapter->fgIsLinkRateValid = FALSE; -+ } else if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_CONNECTED) { /* connected */ -+ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); -+ -+ /* fill information for association result */ -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen = prConnectionStatus->ucSsidLen; -+ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, -+ prConnectionStatus->aucSsid, prConnectionStatus->ucSsidLen); -+ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, -+ prConnectionStatus->aucBssid, MAC_ADDR_LEN); -+ prAdapter->rWlanInfo.rCurrBssId.u4Privacy -+ = prConnectionStatus->ucEncryptStatus; /* @FIXME */ -+ prAdapter->rWlanInfo.rCurrBssId.rRssi = 0; /* @FIXME */ -+ prAdapter->rWlanInfo.rCurrBssId.eNetworkTypeInUse -+ = PARAM_NETWORK_TYPE_AUTOMODE; /* @FIXME */ -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod -+ = prConnectionStatus->u2BeaconPeriod; -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4ATIMWindow = prConnectionStatus->u2ATIMWindow; -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4DSConfig = prConnectionStatus->u4FreqInKHz; -+ prAdapter->rWlanInfo.ucNetworkType = prConnectionStatus->ucNetworkType; -+ prAdapter->rWlanInfo.rCurrBssId.eOpMode -+ = (ENUM_PARAM_OP_MODE_T) prConnectionStatus->ucInfraMode; -+ -+ /* always indicate to OS according to MSDN (re-association/roaming) */ -+ if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, NULL, 0); -+ } else { -+ /* connected -> connected : roaming ? */ -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_ROAM_OUT_FIND_BEST, NULL, 0); -+ } -+ } -+ break; -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ case NETWORK_TYPE_BOW_INDEX: -+ break; -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ case NETWORK_TYPE_P2P_INDEX: -+ break; -+#endif -+ default: -+ ASSERT(0); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* nicMediaStateChange */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to convert between -+* frequency and channel number -+* -+* @param u4ChannelNum -+* -+* @retval - Frequency in unit of KHz, 0 for invalid channel number -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 nicChannelNum2Freq(UINT_32 u4ChannelNum) -+{ -+ UINT_32 u4ChannelInMHz; -+ -+ if (u4ChannelNum >= 1 && u4ChannelNum <= 13) -+ u4ChannelInMHz = 2412 + (u4ChannelNum - 1) * 5; -+ else if (u4ChannelNum == 14) -+ u4ChannelInMHz = 2484; -+ else if (u4ChannelNum == 133) -+ u4ChannelInMHz = 3665; /* 802.11y */ -+ else if (u4ChannelNum == 137) -+ u4ChannelInMHz = 3685; /* 802.11y */ -+ else if (u4ChannelNum >= 34 && u4ChannelNum <= 165) -+ u4ChannelInMHz = 5000 + u4ChannelNum * 5; -+ else if (u4ChannelNum >= 183 && u4ChannelNum <= 196) -+ u4ChannelInMHz = 4000 + u4ChannelNum * 5; -+ else -+ u4ChannelInMHz = 0; -+ -+ return 1000 * u4ChannelInMHz; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to convert between -+* frequency and channel number -+* -+* @param u4FreqInKHz -+* -+* @retval - Frequency Number, 0 for invalid freqency -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 nicFreq2ChannelNum(UINT_32 u4FreqInKHz) -+{ -+ switch (u4FreqInKHz) { -+ case 2412000: -+ return 1; -+ case 2417000: -+ return 2; -+ case 2422000: -+ return 3; -+ case 2427000: -+ return 4; -+ case 2432000: -+ return 5; -+ case 2437000: -+ return 6; -+ case 2442000: -+ return 7; -+ case 2447000: -+ return 8; -+ case 2452000: -+ return 9; -+ case 2457000: -+ return 10; -+ case 2462000: -+ return 11; -+ case 2467000: -+ return 12; -+ case 2472000: -+ return 13; -+ case 2484000: -+ return 14; -+ case 3665000: -+ return 133; /* 802.11y */ -+ case 3685000: -+ return 137; /* 802.11y */ -+ case 4915000: -+ return 183; -+ case 4920000: -+ return 184; -+ case 4925000: -+ return 185; -+ case 4930000: -+ return 186; -+ case 4935000: -+ return 187; -+ case 4940000: -+ return 188; -+ case 4945000: -+ return 189; -+ case 4960000: -+ return 192; -+ case 4980000: -+ return 196; -+ case 5170000: -+ return 34; -+ case 5180000: -+ return 36; -+ case 5190000: -+ return 38; -+ case 5200000: -+ return 40; -+ case 5210000: -+ return 42; -+ case 5220000: -+ return 44; -+ case 5230000: -+ return 46; -+ case 5240000: -+ return 48; -+ case 5250000: -+ return 50; -+ case 5260000: -+ return 52; -+ case 5270000: -+ return 54; -+ case 5280000: -+ return 56; -+ case 5290000: -+ return 58; -+ case 5300000: -+ return 60; -+ case 5320000: -+ return 64; -+ case 5500000: -+ return 100; -+ case 5520000: -+ return 104; -+ case 5540000: -+ return 108; -+ case 5560000: -+ return 112; -+ case 5580000: -+ return 116; -+ case 5600000: -+ return 120; -+ case 5620000: -+ return 124; -+ case 5640000: -+ return 128; -+ case 5660000: -+ return 132; -+ case 5680000: -+ return 136; -+ case 5700000: -+ return 140; -+ case 5745000: -+ return 149; -+ case 5765000: -+ return 153; -+ case 5785000: -+ return 157; -+ case 5805000: -+ return 161; -+ case 5825000: -+ return 165; -+ case 5845000: -+ return 169; -+ case 5865000: -+ return 173; -+ default: -+ return 0; -+ } -+} -+ -+/* firmware command wrapper */ -+/* NETWORK (WIFISYS) */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to activate WIFISYS for specified network -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of network type -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicActivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ CMD_BSS_ACTIVATE_CTRL rCmdActivateCtrl; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ rCmdActivateCtrl.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ rCmdActivateCtrl.ucActive = 1; -+ -+ if (((UINT_8) eNetworkTypeIdx) < NETWORK_TYPE_INDEX_NUM) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]; -+ prBssInfo->fg40mBwAllowed = FALSE; -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ } -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_BSS_ACTIVATE_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_BSS_ACTIVATE_CTRL), (PUINT_8)&rCmdActivateCtrl, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to deactivate WIFISYS for specified network -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of network type -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicDeactivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ WLAN_STATUS u4Status; -+ CMD_BSS_ACTIVATE_CTRL rCmdActivateCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ rCmdActivateCtrl.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ rCmdActivateCtrl.ucActive = 0; -+ -+ u4Status = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_BSS_ACTIVATE_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, sizeof(CMD_BSS_ACTIVATE_CTRL), (PUINT_8)&rCmdActivateCtrl, NULL, 0); -+ -+ /* free all correlated station records */ -+ cnmStaFreeAllStaByNetType(prAdapter, eNetworkTypeIdx, FALSE); -+ qmFreeAllByNetType(prAdapter, eNetworkTypeIdx); -+ nicFreePendingTxMsduInfoByNetwork(prAdapter, eNetworkTypeIdx); -+ kalClearSecurityFramesByNetType(prAdapter->prGlueInfo, eNetworkTypeIdx); -+ -+ return u4Status; -+} -+ -+/* BSS-INFO */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to sync bss info with firmware -+* when a new BSS has been connected or disconnected -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of BSS-INFO type -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicUpdateBss(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ WLAN_STATUS u4Status; -+ P_BSS_INFO_T prBssInfo; -+ CMD_SET_BSS_INFO rCmdSetBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); -+ -+ kalMemZero(&rCmdSetBssInfo, sizeof(CMD_SET_BSS_INFO)); -+ -+ rCmdSetBssInfo.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ rCmdSetBssInfo.ucConnectionState = (UINT_8) prBssInfo->eConnectionState; -+ rCmdSetBssInfo.ucCurrentOPMode = (UINT_8) prBssInfo->eCurrentOPMode; -+ rCmdSetBssInfo.ucSSIDLen = (UINT_8) prBssInfo->ucSSIDLen; -+ kalMemCopy(rCmdSetBssInfo.aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); -+ COPY_MAC_ADDR(rCmdSetBssInfo.aucBSSID, prBssInfo->aucBSSID); -+ rCmdSetBssInfo.ucIsQBSS = (UINT_8) prBssInfo->fgIsQBSS; -+ rCmdSetBssInfo.ucNonHTBasicPhyType = prBssInfo->ucNonHTBasicPhyType; -+ rCmdSetBssInfo.u2OperationalRateSet = prBssInfo->u2OperationalRateSet; -+ rCmdSetBssInfo.u2BSSBasicRateSet = prBssInfo->u2BSSBasicRateSet; -+ rCmdSetBssInfo.ucPhyTypeSet = prBssInfo->ucPhyTypeSet; -+ rCmdSetBssInfo.fgHiddenSsidMode = prBssInfo->eHiddenSsidType; -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ COPY_MAC_ADDR(rCmdSetBssInfo.aucOwnMac, prBssInfo->aucOwnMacAddr); -+#endif -+ -+ rlmFillSyncCmdParam(&rCmdSetBssInfo.rBssRlmParam, prBssInfo); -+ -+ rCmdSetBssInfo.fgWapiMode = (UINT_8) FALSE; -+ -+ if (rCmdSetBssInfo.ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+ P_CONNECTION_SETTINGS_T prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ rCmdSetBssInfo.ucAuthMode = (UINT_8) prConnSettings->eAuthMode; -+ rCmdSetBssInfo.ucEncStatus = (UINT_8) prConnSettings->eEncStatus; -+ rCmdSetBssInfo.fgWapiMode = (UINT_8) prConnSettings->fgWapiMode; -+ } -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (rCmdSetBssInfo.ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) { -+ /* P_CONNECTION_SETTINGS_T prConnSettings = &(prAdapter->rWifiVar.rConnSettings); */ -+ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK; -+ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT; -+ } -+#endif -+ else { -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) { -+ if (kalP2PGetCipher(prAdapter->prGlueInfo)) { -+ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK; -+ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT; -+ } else { -+ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_OPEN; -+ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION_DISABLED; -+ } -+ /* Need the probe response to detect the PBC overlap */ -+ rCmdSetBssInfo.fgIsApMode = p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo); -+ } -+#else -+ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK; -+ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT; -+#endif -+ } -+ -+ if (eNetworkTypeIdx == NETWORK_TYPE_AIS_INDEX && -+ prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && prBssInfo->prStaRecOfAP != NULL) { -+ rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex; -+ -+ cnmAisInfraConnectNotify(prAdapter); -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && -+ (eNetworkTypeIdx == NETWORK_TYPE_P2P_INDEX) && -+ (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && (prBssInfo->prStaRecOfAP != NULL)) { -+ rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex; -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (eNetworkTypeIdx == NETWORK_TYPE_BOW_INDEX && -+ prBssInfo->eCurrentOPMode == OP_MODE_BOW && prBssInfo->prStaRecOfAP != NULL) { -+ rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex; -+ } -+#endif -+ else -+ rCmdSetBssInfo.ucStaRecIdxOfAP = STA_REC_INDEX_NOT_FOUND; -+ -+ u4Status = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_BSS_INFO, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_SET_BSS_INFO), (PUINT_8)&rCmdSetBssInfo, NULL, 0); -+ -+ /* if BSS-INFO is going to be disconnected state, free all correlated station records */ -+ if (prBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ /* clear client list */ -+ bssClearClientList(prAdapter, prBssInfo); -+ -+ /* free all correlated station records */ -+ cnmStaFreeAllStaByNetType(prAdapter, eNetworkTypeIdx, FALSE); -+ qmFreeAllByNetType(prAdapter, eNetworkTypeIdx); -+ kalClearSecurityFramesByNetType(prAdapter->prGlueInfo, eNetworkTypeIdx); -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ if (prBssInfo->prIpV4NetAddrList) -+ FREE_IPV4_NETWORK_ADDR_LIST(prBssInfo->prIpV4NetAddrList); -+#endif -+ } -+ -+ return u4Status; -+} -+ -+/* BSS-INFO Indication (PM) */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to indicate PM that -+* a BSS has been created. (for AdHoc / P2P-GO) -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of BSS-INFO -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicPmIndicateBssCreated(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ P_BSS_INFO_T prBssInfo; -+ CMD_INDICATE_PM_BSS_CREATED rCmdIndicatePmBssCreated; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); -+ -+ rCmdIndicatePmBssCreated.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ rCmdIndicatePmBssCreated.ucDtimPeriod = prBssInfo->ucDTIMPeriod; -+ rCmdIndicatePmBssCreated.u2BeaconInterval = prBssInfo->u2BeaconInterval; -+ rCmdIndicatePmBssCreated.u2AtimWindow = prBssInfo->u2ATIMWindow; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_INDICATE_PM_BSS_CREATED, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_INDICATE_PM_BSS_CREATED), (PUINT_8)&rCmdIndicatePmBssCreated, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to indicate PM that -+* a BSS has been connected -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of BSS-INFO -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicPmIndicateBssConnected(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ P_BSS_INFO_T prBssInfo; -+ CMD_INDICATE_PM_BSS_CONNECTED rCmdIndicatePmBssConnected; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); -+ -+ rCmdIndicatePmBssConnected.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ rCmdIndicatePmBssConnected.ucDtimPeriod = prBssInfo->ucDTIMPeriod; -+ rCmdIndicatePmBssConnected.u2AssocId = prBssInfo->u2AssocId; -+ rCmdIndicatePmBssConnected.u2BeaconInterval = prBssInfo->u2BeaconInterval; -+ rCmdIndicatePmBssConnected.u2AtimWindow = prBssInfo->u2ATIMWindow; -+ -+ rCmdIndicatePmBssConnected.ucBmpDeliveryAC = prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC; -+ rCmdIndicatePmBssConnected.ucBmpTriggerAC = prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC; -+ -+ /* DBGPRINTF("nicPmIndicateBssConnected: ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x", */ -+ /* rCmdIndicatePmBssConnected.ucBmpDeliveryAC, */ -+ /* rCmdIndicatePmBssConnected.ucBmpTriggerAC); */ -+ -+ if ((eNetworkTypeIdx == NETWORK_TYPE_AIS_INDEX) -+#if CFG_ENABLE_WIFI_DIRECT -+ || ((eNetworkTypeIdx == NETWORK_TYPE_P2P_INDEX) && (prAdapter->fgIsP2PRegistered)) -+#endif -+ ) { -+ if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { -+ rCmdIndicatePmBssConnected.fgIsUapsdConnection = -+ (UINT_8) prBssInfo->prStaRecOfAP->fgIsUapsdSupported; -+ } else { -+ rCmdIndicatePmBssConnected.fgIsUapsdConnection = 0; /* @FIXME */ -+ } -+ } else { -+ rCmdIndicatePmBssConnected.fgIsUapsdConnection = 0; -+ } -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_INDICATE_PM_BSS_CONNECTED, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_INDICATE_PM_BSS_CONNECTED), -+ (PUINT_8)&rCmdIndicatePmBssConnected, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to indicate PM that -+* a BSS has been disconnected -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of BSS-INFO -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicPmIndicateBssAbort(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ CMD_INDICATE_PM_BSS_ABORT rCmdIndicatePmBssAbort; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ rCmdIndicatePmBssAbort.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_INDICATE_PM_BSS_ABORT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_INDICATE_PM_BSS_ABORT), (PUINT_8)&rCmdIndicatePmBssAbort, NULL, 0); -+} -+ -+WLAN_STATUS -+nicConfigPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, PARAM_POWER_MODE ePwrMode, BOOLEAN fgEnCmdEvent) -+{ -+ DEBUGFUNC("nicConfigPowerSaveProfile"); -+ DBGLOG(NIC, TRACE, "eNetTypeIndex:%d, ePwrMode:%d, fgEnCmdEvent:%d\n", -+ eNetTypeIndex, ePwrMode, fgEnCmdEvent); -+ -+ ASSERT(prAdapter); -+ -+ if (eNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) { -+ ASSERT(0); -+ return WLAN_STATUS_NOT_SUPPORTED; -+ } -+/* prAdapter->rWlanInfo.ePowerSaveMode.ucNetTypeIndex = eNetTypeIndex; */ -+/* prAdapter->rWlanInfo.ePowerSaveMode.ucPsProfile = (UINT_8)ePwrMode; */ -+ prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex].ucNetTypeIndex = eNetTypeIndex; -+ prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex].ucPsProfile = (UINT_8) ePwrMode; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_POWER_SAVE_MODE, -+ TRUE, -+ FALSE, -+ (fgEnCmdEvent ? TRUE : FALSE), -+ (fgEnCmdEvent ? nicCmdEventSetCommon : NULL), -+ (fgEnCmdEvent ? nicOidCmdTimeoutCommon : NULL), -+ sizeof(CMD_PS_PROFILE_T), -+ (PUINT_8)&(prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex]), -+ NULL, sizeof(PARAM_POWER_MODE) -+ ); -+ -+} /* end of wlanoidSetAcpiDevicePowerStateMode() */ -+ -+WLAN_STATUS nicEnterCtiaMode(IN P_ADAPTER_T prAdapter, BOOLEAN fgEnterCtia, BOOLEAN fgEnCmdEvent) -+{ -+ CMD_SW_DBG_CTRL_T rCmdSwCtrl; -+ CMD_ACCESS_REG rCmdAccessReg; -+ WLAN_STATUS rWlanStatus; -+ -+ DEBUGFUNC("nicEnterCtiaMode"); -+ DBGLOG(NIC, TRACE, "nicEnterCtiaMode: %d\n", fgEnterCtia); -+ -+ ASSERT(prAdapter); -+ -+ rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ if (fgEnterCtia) { -+ /* 1. Disable On-Lin Scan */ -+ prAdapter->fgEnOnlineScan = FALSE; -+ -+ /* 3. Disable FIFO FULL no ack */ -+ rCmdAccessReg.u4Address = 0x60140028; -+ rCmdAccessReg.u4Data = 0x904; -+ wlanSendSetQueryCmd(prAdapter, CMD_ID_ACCESS_REG, TRUE, /* FALSE, */ -+ FALSE, /* TRUE, */ -+ FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8)&rCmdAccessReg, NULL, 0); -+ -+ /* 4. Disable Roaming */ -+ rCmdSwCtrl.u4Id = 0x90000204; -+ rCmdSwCtrl.u4Data = 0x0; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ rCmdSwCtrl.u4Id = 0x90000200; -+ rCmdSwCtrl.u4Data = 0x820000; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ /* Disalbe auto tx power */ -+ rCmdSwCtrl.u4Id = 0xa0100003; -+ rCmdSwCtrl.u4Data = 0x0; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ /* 2. Keep at CAM mode */ -+ { -+ PARAM_POWER_MODE ePowerMode; -+ -+ prAdapter->u4CtiaPowerMode = 0; -+ prAdapter->fgEnCtiaPowerMode = TRUE; -+ -+ ePowerMode = Param_PowerModeCAM; -+ rWlanStatus = nicConfigPowerSaveProfile(prAdapter, -+ NETWORK_TYPE_AIS_INDEX, ePowerMode, fgEnCmdEvent); -+ } -+ -+ /* 5. Disable Beacon Timeout Detection */ -+ prAdapter->fgDisBcnLostDetection = TRUE; -+ } else { -+ /* 1. Enaable On-Lin Scan */ -+ prAdapter->fgEnOnlineScan = TRUE; -+ -+ /* 3. Enable FIFO FULL no ack */ -+ rCmdAccessReg.u4Address = 0x60140028; -+ rCmdAccessReg.u4Data = 0x905; -+ wlanSendSetQueryCmd(prAdapter, CMD_ID_ACCESS_REG, TRUE, /* FALSE, */ -+ FALSE, /* TRUE, */ -+ FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8)&rCmdAccessReg, NULL, 0); -+ -+ /* 4. Enable Roaming */ -+ rCmdSwCtrl.u4Id = 0x90000204; -+ rCmdSwCtrl.u4Data = 0x1; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ rCmdSwCtrl.u4Id = 0x90000200; -+ rCmdSwCtrl.u4Data = 0x820000; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ /* Enable auto tx power */ -+ /* */ -+ -+ rCmdSwCtrl.u4Id = 0xa0100003; -+ rCmdSwCtrl.u4Data = 0x1; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ /* 2. Keep at Fast PS */ -+ { -+ PARAM_POWER_MODE ePowerMode; -+ -+ prAdapter->u4CtiaPowerMode = 2; -+ prAdapter->fgEnCtiaPowerMode = TRUE; -+ -+ ePowerMode = Param_PowerModeFast_PSP; -+ rWlanStatus = nicConfigPowerSaveProfile(prAdapter, -+ NETWORK_TYPE_AIS_INDEX, ePowerMode, fgEnCmdEvent); -+ } -+ -+ /* 5. Enable Beacon Timeout Detection */ -+ prAdapter->fgDisBcnLostDetection = FALSE; -+ -+ } -+ -+ return rWlanStatus; -+} /* end of nicEnterCtiaMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to indicate firmware domain -+* for beacon generation parameters -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eIeUpdMethod, Update Method -+* eNetTypeIndex Index of Network -+* u2Capability Capability -+* aucIe Pointer to buffer of IEs -+* u2IELen Length of IEs -+* -+* @retval - WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+* WLAN_STATUS_PENDING -+* WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicUpdateBeaconIETemplate(IN P_ADAPTER_T prAdapter, -+ IN ENUM_IE_UPD_METHOD_T eIeUpdMethod, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN UINT_16 u2Capability, IN PUINT_8 aucIe, IN UINT_16 u2IELen) -+{ -+ P_CMD_BEACON_TEMPLATE_UPDATE prCmdBcnUpdate; -+ UINT_16 u2CmdBufLen = 0; -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_8 ucCmdSeqNum; -+ -+ DEBUGFUNC("wlanUpdateBeaconIETemplate"); -+ -+ DBGLOG(NIC, LOUD, "\nnicUpdateBeaconIETemplate\n"); -+ -+ ASSERT(prAdapter); -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (u2IELen > MAX_IE_LENGTH) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ if (eIeUpdMethod == IE_UPD_METHOD_UPDATE_RANDOM || eIeUpdMethod == IE_UPD_METHOD_UPDATE_ALL) { -+ u2CmdBufLen = OFFSET_OF(CMD_BEACON_TEMPLATE_UPDATE, aucIE) + u2IELen; -+ } else if (eIeUpdMethod == IE_UPD_METHOD_DELETE_ALL) { -+ u2CmdBufLen = OFFSET_OF(CMD_BEACON_TEMPLATE_UPDATE, u2IELen); -+ } else { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* prepare command info */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u2CmdBufLen)); -+ if (!prCmdInfo) { -+ DBGLOG(NIC, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = eNetTypeIndex; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u2CmdBufLen); -+ prCmdInfo->pfCmdDoneHandler = NULL; /* @FIXME */ -+ prCmdInfo->pfCmdTimeoutHandler = NULL; /* @FIXME */ -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_UPDATE_BEACON_CONTENT; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u2CmdBufLen; -+ prCmdInfo->pvInformationBuffer = NULL; -+ prCmdInfo->u4InformationBufferLength = 0; -+ -+ /* Setup WIFI_CMD_T (no payload) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ prCmdBcnUpdate = (P_CMD_BEACON_TEMPLATE_UPDATE) (prWifiCmd->aucBuffer); -+ -+ /* fill beacon updating command */ -+ prCmdBcnUpdate->ucUpdateMethod = (UINT_8) eIeUpdMethod; -+ prCmdBcnUpdate->ucNetTypeIndex = (UINT_8) eNetTypeIndex; -+ prCmdBcnUpdate->u2Capability = u2Capability; -+ prCmdBcnUpdate->u2IELen = u2IELen; -+ if (u2IELen > 0) -+ kalMemCopy(prCmdBcnUpdate->aucIE, aucIe, u2IELen); -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ return WLAN_STATUS_PENDING; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to initialization PHY related -+* varaibles -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicSetAvailablePhyTypeSet(IN P_ADAPTER_T prAdapter) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ ASSERT(prAdapter); -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ if (prConnSettings->eDesiredPhyConfig >= PHY_CONFIG_NUM) { -+ ASSERT(0); -+ return; -+ } -+ -+ prAdapter->rWifiVar.ucAvailablePhyTypeSet = aucPhyCfg2PhyTypeSet[prConnSettings->eDesiredPhyConfig]; -+ -+ if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_BIT_ERP) -+ prAdapter->rWifiVar.eNonHTBasicPhyType2G4 = PHY_TYPE_ERP_INDEX; -+ /* NOTE(Kevin): Because we don't have N only mode, TBD */ -+ else { /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ -+ -+ prAdapter->rWifiVar.eNonHTBasicPhyType2G4 = PHY_TYPE_HR_DSSS_INDEX; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update WMM Parms -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of BSS-INFO -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicQmUpdateWmmParms(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ P_BSS_INFO_T prBssInfo; -+ CMD_UPDATE_WMM_PARMS_T rCmdUpdateWmmParms; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ DBGLOG(QM, EVENT, "sizeof(AC_QUE_PARMS_T): %zu\n", sizeof(AC_QUE_PARMS_T)); -+ DBGLOG(QM, EVENT, "sizeof(CMD_UPDATE_WMM_PARMS): %zu\n", sizeof(CMD_UPDATE_WMM_PARMS_T)); -+ DBGLOG(QM, EVENT, "sizeof(WIFI_CMD_T): %zu\n", sizeof(WIFI_CMD_T)); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); -+ rCmdUpdateWmmParms.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ kalMemCopy(&rCmdUpdateWmmParms.arACQueParms[0], &prBssInfo->arACQueParms[0], (sizeof(AC_QUE_PARMS_T) * AC_NUM)); -+ -+ rCmdUpdateWmmParms.fgIsQBSS = prBssInfo->fgIsQBSS; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_UPDATE_WMM_PARMS, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_UPDATE_WMM_PARMS_T), (PUINT_8)&rCmdUpdateWmmParms, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update TX power gain corresponding to -+* each band/modulation combination -+* -+* @param prAdapter Pointer of ADAPTER_T -+* prTxPwrParam Pointer of TX power parameters -+* -+* @retval WLAN_STATUS_PENDING -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicUpdateTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam) -+{ -+ DEBUGFUNC("nicUpdateTxPower"); -+ -+ ASSERT(prAdapter); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_TX_PWR, -+ TRUE, -+ FALSE, FALSE, NULL, NULL, sizeof(CMD_TX_PWR_T), (PUINT_8) prTxPwrParam, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to set auto tx power parameter -+* -+* @param prAdapter Pointer of ADAPTER_T -+* prTxPwrParam Pointer of Auto TX power parameters -+* -+* @retval WLAN_STATUS_PENDING -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicSetAutoTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_AUTO_POWER_PARAM_T prAutoPwrParam) -+{ -+ DEBUGFUNC("nicSetAutoTxPower"); -+ -+ ASSERT(prAdapter); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_AUTOPWR_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_AUTO_POWER_PARAM_T), (PUINT_8) prAutoPwrParam, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update TX power gain corresponding to -+* each band/modulation combination -+* -+* @param prAdapter Pointer of ADAPTER_T -+* prTxPwrParam Pointer of TX power parameters -+* -+* @retval WLAN_STATUS_PENDING -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicSetAutoTxPowerControl(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam) -+{ -+ DEBUGFUNC("nicUpdateTxPower"); -+ -+ ASSERT(prAdapter); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_TX_PWR, -+ TRUE, -+ FALSE, FALSE, NULL, NULL, sizeof(CMD_TX_PWR_T), (PUINT_8) prTxPwrParam, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update power offset around 5GHz band -+* -+* @param prAdapter Pointer of ADAPTER_T -+* pr5GPwrOffset Pointer of 5GHz power offset parameter -+* -+* @retval WLAN_STATUS_PENDING -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicUpdate5GOffset(IN P_ADAPTER_T prAdapter, IN P_CMD_5G_PWR_OFFSET_T pr5GPwrOffset) -+{ -+ DEBUGFUNC("nicUpdate5GOffset"); -+ -+ ASSERT(prAdapter); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_5G_PWR_OFFSET, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_5G_PWR_OFFSET_T), (PUINT_8) pr5GPwrOffset, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update DPD calibration result -+* -+* @param prAdapter Pointer of ADAPTER_T -+* pr5GPwrOffset Pointer of parameter for DPD calibration result -+* -+* @retval WLAN_STATUS_PENDING -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicUpdateDPD(IN P_ADAPTER_T prAdapter, IN P_CMD_PWR_PARAM_T prDpdCalResult) -+{ -+ DEBUGFUNC("nicUpdateDPD"); -+ -+ ASSERT(prAdapter); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PWR_PARAM, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_PWR_PARAM_T), (PUINT_8) prDpdCalResult, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function starts system service such as timer and -+* memory pools -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicInitSystemService(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* <1> Initialize MGMT Memory pool and STA_REC */ -+ cnmMemInit(prAdapter); -+ cnmStaRecInit(prAdapter); -+ cmdBufInitialize(prAdapter); -+ -+ /* <2> Mailbox Initialization */ -+ mboxInitialize(prAdapter); -+ -+ /* <3> Timer Initialization */ -+ cnmTimerInitialize(prAdapter); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function reset some specific system service, -+* such as STA-REC -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicResetSystemService(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update WMM Parms -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicUninitSystemService(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* Timer Destruction */ -+ cnmTimerDestroy(prAdapter); -+ -+ /* Mailbox Destruction */ -+ mboxDestroy(prAdapter); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update WMM Parms -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicInitMGMT(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo) -+{ -+ ASSERT(prAdapter); -+ -+ /* CNM Module - initialization */ -+ cnmInit(prAdapter); -+ -+ /* RLM Module - initialization */ -+ rlmFsmEventInit(prAdapter); -+ -+ /* SCN Module - initialization */ -+ scnInit(prAdapter); -+ -+ /* AIS Module - intiailization */ -+ aisInitializeConnectionSettings(prAdapter, prRegInfo); -+ aisFsmInit(prAdapter); -+ -+#if CFG_SUPPORT_ROAMING -+ /* Roaming Module - intiailization */ -+ roamingFsmInit(prAdapter); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+#if CFG_SUPPORT_SWCR -+ swCrDebugInit(prAdapter); -+#endif /* CFG_SUPPORT_SWCR */ -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ TdlsexInit(prAdapter); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update WMM Parms -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicUninitMGMT(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+#if CFG_SUPPORT_SWCR -+ swCrDebugUninit(prAdapter); -+#endif /* CFG_SUPPORT_SWCR */ -+ -+#if CFG_SUPPORT_ROAMING -+ /* Roaming Module - unintiailization */ -+ roamingFsmUninit(prAdapter); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ /* AIS Module - unintiailization */ -+ aisFsmUninit(prAdapter); -+ -+ /* SCN Module - unintiailization */ -+ scnUninit(prAdapter); -+ -+ /* RLM Module - uninitialization */ -+ rlmFsmEventUninit(prAdapter); -+ -+ /* CNM Module - uninitialization */ -+ cnmUninit(prAdapter); -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ TdlsexUninit(prAdapter); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+} -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is to inform firmware to enable MCU clock gating -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicEnableClockGating(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i, u4WHISR = 0; -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->fgIsClockGatingEnabled == TRUE) -+ return WLAN_STATUS_SUCCESS; -+ -+ nicSetSwIntr(prAdapter, REQ_GATING_ENABLE_H2D_INT); -+ -+ i = 0; -+ while (i < GATING_CONTROL_POLL_LIMIT) { -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) -+ return WLAN_STATUS_FAILURE; -+ -+ HAL_READ_INTR_STATUS(prAdapter, sizeof(UINT_32), (PUINT_8)&u4WHISR); -+ -+ if (u4WHISR & ACK_GATING_ENABLE_D2H_INT) { -+ prAdapter->fgIsClockGatingEnabled = TRUE; -+ return WLAN_STATUS_SUCCESS; -+ } -+ } -+ -+ ASSERT(0); -+ return WLAN_STATUS_PENDING; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is to inform firmware to disable MCU clock gating -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicDisableClockGating(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i, u4WHISR = 0; -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->fgIsClockGatingEnabled == FALSE) -+ return WLAN_STATUS_SUCCESS; -+ -+ nicSetSwIntr(prAdapter, REQ_GATING_DISABLE_H2D_INT); -+ -+ i = 0; -+ while (i < GATING_CONTROL_POLL_LIMIT) { -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) -+ return WLAN_STATUS_FAILURE; -+ -+ HAL_READ_INTR_STATUS(prAdapter, sizeof(UINT_32), (PUINT_8)&u4WHISR); -+ -+ if (u4WHISR & ACK_GATING_DISABLE_D2H_INT) { -+ prAdapter->fgIsClockGatingEnabled = FALSE; -+ return WLAN_STATUS_SUCCESS; -+ } -+ } -+ -+ ASSERT(0); -+ return WLAN_STATUS_PENDING; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is invoked to buffer scan result -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param rMacAddr BSSID -+* @param prSsid Pointer to SSID -+* @param u4Privacy Privacy settings (0: Open / 1: WEP/WPA/WPA2 enabled) -+* @param rRssi Received Strength (-10 ~ -200 dBm) -+* @param eNetworkType Network Type (a/b/g) -+* @param prConfiguration Network Parameter -+* @param eOpMode Infra/Ad-Hoc -+* @param rSupportedRates Supported basic rates -+* @param u2IELength IE Length -+* @param pucIEBuf Pointer to Information Elements(IEs) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicAddScanResult(IN P_ADAPTER_T prAdapter, -+ IN PARAM_MAC_ADDRESS rMacAddr, -+ IN P_PARAM_SSID_T prSsid, -+ IN UINT_32 u4Privacy, -+ IN PARAM_RSSI rRssi, -+ IN ENUM_PARAM_NETWORK_TYPE_T eNetworkType, -+ IN P_PARAM_802_11_CONFIG_T prConfiguration, -+ IN ENUM_PARAM_OP_MODE_T eOpMode, -+ IN PARAM_RATES_EX rSupportedRates, IN UINT_16 u2IELength, IN PUINT_8 pucIEBuf) -+{ -+ BOOLEAN bReplace; -+ UINT_32 i; -+ UINT_32 u4IdxWeakest = 0; -+ PARAM_RSSI rWeakestRssi; -+ UINT_32 u4BufferSize; -+ -+ ASSERT(prAdapter); -+ -+ rWeakestRssi = (PARAM_RSSI) INT_MAX; -+ u4BufferSize = sizeof(prAdapter->rWlanInfo.aucScanIEBuf) / sizeof(prAdapter->rWlanInfo.aucScanIEBuf[0]); -+ -+ bReplace = FALSE; -+ -+ /* decide to replace or add */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ /* find weakest entry && not connected one */ -+ if (UNEQUAL_MAC_ADDR -+ (prAdapter->rWlanInfo.arScanResult[i].arMacAddress, prAdapter->rWlanInfo.rCurrBssId.arMacAddress) -+ && prAdapter->rWlanInfo.arScanResult[i].rRssi < rWeakestRssi) { -+ u4IdxWeakest = i; -+ rWeakestRssi = prAdapter->rWlanInfo.arScanResult[i].rRssi; -+ } -+ -+ if (prAdapter->rWlanInfo.arScanResult[i].eOpMode == eOpMode && -+ EQUAL_MAC_ADDR(&(prAdapter->rWlanInfo.arScanResult[i].arMacAddress), rMacAddr) && -+ (EQUAL_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, -+ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, -+ prSsid->aucSsid, prSsid->u4SsidLen) -+ || prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen == 0)) { -+ /* replace entry */ -+ bReplace = TRUE; -+ -+ /* free IE buffer then zero */ -+ nicFreeScanResultIE(prAdapter, i); -+ kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ -+ /* then fill buffer */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length = -+ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength; -+ COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr); -+ COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, -+ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, -+ prSsid->aucSsid, prSsid->u4SsidLen); -+ prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy; -+ prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; -+ prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType; -+ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration), -+ prConfiguration, sizeof(PARAM_802_11_CONFIG_T)); -+ prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; -+ kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates), -+ rSupportedRates, sizeof(PARAM_RATES_EX)); -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength; -+ -+ /* IE - allocate buffer and update pointer */ -+ if (u2IELength > 0) { -+ if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) { -+ kalMemCopy(& -+ (prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]), -+ pucIEBuf, u2IELength); -+ -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = -+ &(prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]); -+ -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength); -+ } else { -+ /* buffer is not enough */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength; -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0; -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ } else { -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ -+ break; -+ } -+ } -+ -+ if (bReplace == FALSE) { -+ if (prAdapter->rWlanInfo.u4ScanResultNum < (CFG_MAX_NUM_BSS_LIST - 1)) { -+ i = prAdapter->rWlanInfo.u4ScanResultNum; -+ -+ /* zero */ -+ kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ -+ /* then fill buffer */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length = -+ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength; -+ COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr); -+ COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, -+ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, -+ prSsid->aucSsid, prSsid->u4SsidLen); -+ prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy; -+ prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; -+ prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType; -+ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration), -+ prConfiguration, sizeof(PARAM_802_11_CONFIG_T)); -+ prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; -+ kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates), -+ rSupportedRates, sizeof(PARAM_RATES_EX)); -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength; -+ -+ /* IE - allocate buffer and update pointer */ -+ if (u2IELength > 0) { -+ if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) { -+ kalMemCopy(& -+ (prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]), -+ pucIEBuf, u2IELength); -+ -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = -+ &(prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]); -+ -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength); -+ } else { -+ /* buffer is not enough */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength; -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0; -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ } else { -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ -+ prAdapter->rWlanInfo.u4ScanResultNum++; -+ } else if (rWeakestRssi != (PARAM_RSSI) INT_MAX) { -+ /* replace weakest one */ -+ i = u4IdxWeakest; -+ -+ /* free IE buffer then zero */ -+ nicFreeScanResultIE(prAdapter, i); -+ kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ -+ /* then fill buffer */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length = -+ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength; -+ COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr); -+ COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, -+ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, -+ prSsid->aucSsid, prSsid->u4SsidLen); -+ prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy; -+ prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; -+ prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType; -+ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration), -+ prConfiguration, sizeof(PARAM_802_11_CONFIG_T)); -+ prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; -+ kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates), -+ rSupportedRates, sizeof(PARAM_RATES_EX)); -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength; -+ -+ if (u2IELength > 0) { -+ /* IE - allocate buffer and update pointer */ -+ if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) { -+ kalMemCopy(& -+ (prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]), -+ pucIEBuf, u2IELength); -+ -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = -+ &(prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]); -+ -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength); -+ } else { -+ /* buffer is not enough */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength; -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0; -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ } else { -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is invoked to free IE buffer for dedicated scan result -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param u4Idx Index of Scan Result -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicFreeScanResultIE(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Idx) -+{ -+ UINT_32 i; -+ PUINT_8 pucPivot, pucMovePivot; -+ UINT_32 u4MoveSize, u4FreeSize, u4ReserveSize; -+ -+ ASSERT(prAdapter); -+ ASSERT(u4Idx < CFG_MAX_NUM_BSS_LIST); -+ -+ if (prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength == 0 -+ || prAdapter->rWlanInfo.apucScanResultIEs[u4Idx] == NULL) { -+ return; -+ } -+ -+ u4FreeSize = ALIGN_4(prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength); -+ -+ pucPivot = prAdapter->rWlanInfo.apucScanResultIEs[u4Idx]; -+ pucMovePivot = (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[u4Idx]) + u4FreeSize); -+ -+ u4ReserveSize = ((ULONG) pucPivot) - (ULONG) (&(prAdapter->rWlanInfo.aucScanIEBuf[0])); -+ u4MoveSize = prAdapter->rWlanInfo.u4ScanIEBufferUsage - u4ReserveSize - u4FreeSize; -+ -+ /* 1. rest of buffer to move forward */ -+ kalMemCopy(pucPivot, pucMovePivot, u4MoveSize); -+ -+ /* 1.1 modify pointers */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ if (i != u4Idx) { -+ if (prAdapter->rWlanInfo.apucScanResultIEs[i] >= pucMovePivot) { -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = -+ (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[i]) - u4FreeSize); -+ } -+ } -+ } -+ -+ /* 1.2 reset the freed one */ -+ prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength = 0; -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ -+ /* 2. reduce IE buffer usage */ -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage -= u4FreeSize; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to hack parameters for WLAN TABLE for -+* fixed rate settings -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param eRateSetting -+* @param pu2DesiredNonHTRateSet, -+* @param pu2BSSBasicRateSet, -+* @param pucMcsSet -+* @param pucSupMcs32 -+* @param pu2HtCapInfo -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicUpdateRateParams(IN P_ADAPTER_T prAdapter, -+ IN ENUM_REGISTRY_FIXED_RATE_T eRateSetting, -+ IN PUINT_8 pucDesiredPhyTypeSet, -+ IN PUINT_16 pu2DesiredNonHTRateSet, -+ IN PUINT_16 pu2BSSBasicRateSet, -+ IN PUINT_8 pucMcsSet, IN PUINT_8 pucSupMcs32, IN PUINT_16 pu2HtCapInfo) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eRateSetting > FIXED_RATE_NONE && eRateSetting < FIXED_RATE_NUM); -+ -+ switch (prAdapter->rWifiVar.eRateSetting) { -+ case FIXED_RATE_1M: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_1M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_1M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_2M: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_2M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_2M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_5_5M: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_5_5M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_5_5M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_11M: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_11M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_11M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_6M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_6M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_6M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_9M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_9M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_9M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_12M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_12M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_12M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_18M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_18M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_18M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_24M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_24M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_24M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_36M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_36M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_36M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_48M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_48M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_48M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_54M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_54M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_54M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_MCS0_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS0_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS1_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS1_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS2_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS2_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS3_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS3_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS4_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS4_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS5_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS5_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS6_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS6_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS7_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS7_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS0_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS0_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS1_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS1_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS2_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS2_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS3_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS3_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS4_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS4_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS5_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS5_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS6_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS6_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS7_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS7_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS0_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS0_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS1_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS1_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS2_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS2_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS3_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS3_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS4_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS4_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS5_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS5_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS6_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS6_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS7_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS7_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS32_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS32_INDEX; -+ *pucSupMcs32 = 1; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS0_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS0_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS1_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS1_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS2_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS2_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS3_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS3_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS4_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS4_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS5_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS5_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS6_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS6_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS7_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS7_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS32_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS32_INDEX; -+ *pucSupMcs32 = 1; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ default: -+ ASSERT(0); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to write the register -+* -+* @param u4Address Register address -+* u4Value the value to be written -+* -+* @retval WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS nicWriteMcr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Address, IN UINT_32 u4Value) -+{ -+ CMD_ACCESS_REG rCmdAccessReg; -+ -+ rCmdAccessReg.u4Address = u4Address; -+ rCmdAccessReg.u4Data = u4Value; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8) &rCmdAccessReg, NULL, 0); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to modify the auto rate parameters -+* -+* @param u4ArSysParam0 see description below -+* u4ArSysParam1 -+* u4ArSysParam2 -+* u4ArSysParam3 -+* -+* -+* @retval WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+* -+* @note -+* ArSysParam0[0:3] -> auto rate version (0:disable 1:version1 2:version2) -+* ArSysParam0[4:5]-> auto bw version (0:disable 1:version1 2:version2) -+* ArSysParam0[6:7]-> auto gi version (0:disable 1:version1 2:version2) -+* ArSysParam0[8:15]-> HT rate clear mask -+* ArSysParam0[16:31]-> Legacy rate clear mask -+* ArSysParam1[0:7]-> Auto Rate check weighting window -+* ArSysParam1[8:15]-> Auto Rate v1 Force Rate down -+* ArSysParam1[16:23]-> Auto Rate v1 PerH -+* ArSysParam1[24:31]-> Auto Rate v1 PerL -+* -+* Examples -+* ArSysParam0 = 1, -+* Enable auto rate version 1 -+* -+* ArSysParam0 = 983041, -+* Enable auto rate version 1 -+* Remove CCK 1M, 2M, 5.5M, 11M -+* -+* ArSysParam0 = 786433 -+* Enable auto rate version 1 -+* Remove CCK 5.5M 11M -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS -+nicRlmArUpdateParms(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4ArSysParam0, -+ IN UINT_32 u4ArSysParam1, IN UINT_32 u4ArSysParam2, IN UINT_32 u4ArSysParam3) -+{ -+ UINT_8 ucArVer, ucAbwVer, ucAgiVer; -+ UINT_16 u2HtClrMask; -+ UINT_16 u2LegacyClrMask; -+ UINT_8 ucArCheckWindow; -+ UINT_8 ucArPerL; -+ UINT_8 ucArPerH; -+ UINT_8 ucArPerForceRateDownPer; -+ -+ ucArVer = (UINT_8) (u4ArSysParam0 & BITS(0, 3)); -+ ucAbwVer = (UINT_8) ((u4ArSysParam0 & BITS(4, 5)) >> 4); -+ ucAgiVer = (UINT_8) ((u4ArSysParam0 & BITS(6, 7)) >> 6); -+ u2HtClrMask = (UINT_16) ((u4ArSysParam0 & BITS(8, 15)) >> 8); -+ u2LegacyClrMask = (UINT_16) ((u4ArSysParam0 & BITS(16, 31)) >> 16); -+ -+#if 0 -+ ucArCheckWindow = (UINT_8) (u4ArSysParam1 & BITS(0, 7)); -+ ucArPerForceRateDownPer = (UINT_8) ((u4ArSysParam1 & BITS(8, 15) >> 8)); -+ ucArPerH = (UINT_8) ((u4ArSysParam1 & BITS(16, 23)) >> 16); -+ ucArPerL = (UINT_8) ((u4ArSysParam1 & BITS(24, 31)) >> 24); -+#endif -+ -+ ucArCheckWindow = (UINT_8) (u4ArSysParam1 & BITS(0, 7)); -+ ucArPerForceRateDownPer = (UINT_8) (((u4ArSysParam1 >> 8) & BITS(0, 7))); -+ ucArPerH = (UINT_8) (((u4ArSysParam1 >> 16) & BITS(0, 7))); -+ ucArPerL = (UINT_8) (((u4ArSysParam1 >> 24) & BITS(0, 7))); -+ -+ DBGLOG(NIC, INFO, "ArParam %u %u %u %u\n", u4ArSysParam0, u4ArSysParam1, u4ArSysParam2, u4ArSysParam3); -+ DBGLOG(NIC, INFO, "ArVer %u AbwVer %u AgiVer %u\n", ucArVer, ucAbwVer, ucAgiVer); -+ DBGLOG(NIC, INFO, "HtMask %x LegacyMask %x\n", u2HtClrMask, u2LegacyClrMask); -+ DBGLOG(NIC, INFO, -+ "CheckWin %u RateDownPer %u PerH %u PerL %u\n", ucArCheckWindow, ucArPerForceRateDownPer, ucArPerH, -+ ucArPerL); -+ -+#define SWCR_DATA_ADDR(MOD, ADDR) (0x90000000+(MOD<<8)+(ADDR)) -+#define SWCR_DATA_CMD(CATE, WRITE, INDEX, OPT0, OPT1) ((CATE<<24) | (WRITE<<23) | (INDEX<<16) | (OPT0 << 8) | OPT1) -+#define SWCR_DATA0 0x0 -+#define SWCR_DATA1 0x4 -+#define SWCR_DATA2 0x8 -+#define SWCR_DATA3 0xC -+#define SWCR_DATA4 0x10 -+#define SWCR_WRITE 1 -+#define SWCR_READ 0 -+ -+ if (ucArVer > 0) { -+ /* dummy = WiFi.WriteMCR(&h90000104, &h00000001) */ -+ /* dummy = WiFi.WriteMCR(&h90000100, &h00850000) */ -+ -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), 1); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 5, 0, 0)); -+ } else { -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), 0); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 5, 0, 0)); -+ } -+ -+ /* ucArVer 0: none 1:PER 2:Rcpi */ -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArVer); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 7, 0, 0)); -+ -+ /* Candidate rate Ht mask */ -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), u2HtClrMask); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1c, 0, 0)); -+ -+ /* Candidate rate legacy mask */ -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), u2LegacyClrMask); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1d, 0, 0)); -+ -+#if 0 -+ if (ucArCheckWindow != 0) { -+ /* TX DONE MCS INDEX CHECK STA RATE DOWN TH */ -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArCheckWindow); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x14, 0, 0)); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArCheckWindow); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0xc, 0, 0)); -+ } -+ -+ if (ucArPerForceRateDownPer != 0) { -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerForceRateDownPer); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x18, 0, 0)); -+ } -+ if (ucArPerH != 0) { -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerH); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1, 0, 0)); -+ } -+ if (ucArPerL != 0) { -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerL); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x2, 0, 0)); -+ } -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to enable roaming -+* -+* @param u4EnableRoaming -+* -+* -+* @retval WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+* -+* @note -+* u4EnableRoaming -> Enable Romaing -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRoamingUpdateParams(IN P_ADAPTER_T prAdapter, IN UINT_32 u4EnableRoaming) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prConnSettings->fgIsEnableRoaming = ((u4EnableRoaming > 0) ? (TRUE) : (FALSE)); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief dump firmware Assert message -+* -+* \param[in] -+* prAdapter -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicPrintFirmwareAssertInfo(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4MailBox0, u4MailBox1; -+ UINT_32 line = 0; -+ UINT_8 aucAssertFile[7]; -+ UINT_32 u4ChipId; -+ -+#if CFG_SDIO_INTR_ENHANCE -+ u4MailBox0 = prAdapter->prSDIOCtrl->u4RcvMailbox0; -+ u4MailBox1 = prAdapter->prSDIOCtrl->u4RcvMailbox1; -+#else -+ nicGetMailbox(prAdapter, 0, &u4MailBox0); -+ nicGetMailbox(prAdapter, 1, &u4MailBox1); -+#endif -+ -+ line = u4MailBox0 & 0x0000FFFF; -+ -+ u4MailBox0 = ((u4MailBox0 >> 16) & 0x0000FFFF); -+ -+ kalMemCopy(&aucAssertFile[0], &u4MailBox0, 2); -+ kalMemCopy(&aucAssertFile[2], &u4MailBox1, 4); -+ -+ aucAssertFile[6] = '\0'; -+ -+#if defined(MT6620) -+ u4ChipId = 6620; -+#elif defined(MT6628) -+ u4ChipId = 6582; -+#endif -+ -+ kalPrint("\n[MT%u][wifi][Firmware] Assert at \"%s\" #%u\n\n", u4ChipId, aucAssertFile, line); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to update Link Quality information -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* eNetTypeIdx -+* prEventLinkQuality -+* cRssi -+* cLinkQuality -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicUpdateLinkQuality(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN P_EVENT_LINK_QUALITY prEventLinkQuality) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ ASSERT(prEventLinkQuality); -+ -+ switch (eNetTypeIdx) { -+ case NETWORK_TYPE_AIS_INDEX: -+ if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* check is to prevent RSSI to be updated by incorrect initial RSSI from hardware */ -+ /* buffer statistics for further query */ -+ if (prAdapter->fgIsLinkQualityValid == FALSE -+ || (kalGetTimeTick() - prAdapter->rLinkQualityUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) { -+ nicUpdateRSSI(prAdapter, eNetTypeIdx, prEventLinkQuality->cRssi, -+ prEventLinkQuality->cLinkQuality); -+ } -+ -+ if (prAdapter->fgIsLinkRateValid == FALSE -+ || (kalGetTimeTick() - prAdapter->rLinkRateUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) { -+ nicUpdateLinkSpeed(prAdapter, eNetTypeIdx, prEventLinkQuality->u2LinkSpeed); -+ } -+ } -+ break; -+#if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY -+ case NETWORK_TYPE_P2P_INDEX: -+ if (prAdapter->fgIsP2pLinkQualityValid == FALSE -+ || (kalGetTimeTick() - prAdapter->rP2pLinkQualityUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) { -+ P_EVENT_LINK_QUALITY_EX prEventLQEx = (P_EVENT_LINK_QUALITY_EX) prEventLinkQuality; -+ -+ nicUpdateRSSI(prAdapter, NETWORK_TYPE_P2P_INDEX, prEventLQEx->cRssiP2P, -+ prEventLQEx->cLinkQualityP2P); -+ } -+ break; -+#endif -+ default: -+ break; -+ -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to update RSSI and Link Quality information -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* eNetTypeIdx -+* cRssi -+* cLinkQuality -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicUpdateRSSI(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ switch (eNetTypeIdx) { -+ case NETWORK_TYPE_AIS_INDEX: -+ if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ prAdapter->fgIsLinkQualityValid = TRUE; -+ prAdapter->rLinkQualityUpdateTime = kalGetTimeTick(); -+ -+ prAdapter->rLinkQuality.cRssi = cRssi; -+ prAdapter->rLinkQuality.cLinkQuality = cLinkQuality; -+ -+ /* indicate to glue layer */ -+ kalUpdateRSSI(prAdapter->prGlueInfo, -+ KAL_NETWORK_TYPE_AIS_INDEX, -+ prAdapter->rLinkQuality.cRssi, prAdapter->rLinkQuality.cLinkQuality); -+ } -+ -+ break; -+#if CFG_ENABLE_WIFI_DIRECT -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ case NETWORK_TYPE_P2P_INDEX: -+ prAdapter->fgIsP2pLinkQualityValid = TRUE; -+ prAdapter->rP2pLinkQualityUpdateTime = kalGetTimeTick(); -+ -+ prAdapter->rP2pLinkQuality.cRssi = cRssi; -+ prAdapter->rP2pLinkQuality.cLinkQuality = cLinkQuality; -+ -+ kalUpdateRSSI(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_P2P_INDEX, cRssi, cLinkQuality); -+ break; -+#endif -+#endif -+ default: -+ break; -+ -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to update Link Quality information -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* eNetTypeIdx -+* prEventLinkQuality -+* cRssi -+* cLinkQuality -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicUpdateLinkSpeed(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN UINT_16 u2LinkSpeed) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ switch (eNetTypeIdx) { -+ case NETWORK_TYPE_AIS_INDEX: -+ if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* buffer statistics for further query */ -+ prAdapter->fgIsLinkRateValid = TRUE; -+ prAdapter->rLinkRateUpdateTime = kalGetTimeTick(); -+ -+ prAdapter->rLinkQuality.u2LinkSpeed = u2LinkSpeed; -+ } -+ break; -+ -+ default: -+ break; -+ -+ } -+ -+} -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+WLAN_STATUS nicUpdateRddTestMode(IN P_ADAPTER_T prAdapter, IN P_CMD_RDD_CH_T prRddChParam) -+{ -+ DEBUGFUNC("nicUpdateRddTestMode.\n"); -+ -+ ASSERT(prAdapter); -+ -+/* aisFsmScanRequest(prAdapter, NULL); */ -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_RDD_CH, -+ TRUE, -+ FALSE, FALSE, NULL, NULL, sizeof(CMD_RDD_CH_T), (PUINT_8) prRddChParam, NULL, 0); -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c -new file mode 100644 -index 0000000000000..3c9c24f9542bc ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c -@@ -0,0 +1,1636 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_cmd_event.c#1 -+*/ -+ -+/*! \file nic_cmd_event.c -+ \brief Callback functions for Command packets. -+ -+ Various Event packet handlers which will be setup in the callback function of -+ a command packet. -+*/ -+ -+/* -+** Log: nic_cmd_event.c -+ * -+ * 04 10 2012 yuche.tsai -+ * NULL -+ * Update address for wifi direct connection issue. -+ * -+ * 06 15 2011 cm.chang -+ * [WCXRP00000785] [MT6620 Wi-Fi][Driver][FW] P2P/BOW MAC address is XOR with AIS MAC address -+ * P2P/BOW mac address XOR with local bit instead of OR -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add security check code. -+ * -+ * 02 24 2011 cp.wu -+ * [WCXRP00000493] [MT6620 Wi-Fi][Driver] Do not indicate redundant disconnection to host when entering into RF -+ * test mode -+ * only indicate DISCONNECTION to host when entering RF test if necessary (connected -> disconnected cases) -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to -+ * system scheduling -+ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being -+ * loaded -+ * -+ * 12 01 2010 cp.wu -+ * [WCXRP00000223] MT6620 Wi-Fi][Driver][FW] Adopt NVRAM parameters when enter/exit RF test mode -+ * reload NVRAM settings before entering RF test mode and leaving from RF test mode. -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 20 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * use OID_CUSTOM_TEST_MODE as indication for driver reset -+ * by dropping pending TX packets -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ * associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 15 2010 yuche.tsai -+ * NULL -+ * Start to test AT GO only when P2P state is not IDLE. -+ * -+ * 09 09 2010 yuche.tsai -+ * NULL -+ * Add AT GO Test mode after MAC address available. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add support for P2P Device Address query from FW. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * Centralize mgmt/system service procedures into independent calls. -+ * -+ * 08 02 2010 cp.wu -+ * NULL -+ * reset FSMs before entering RF test mode. -+ * -+ * 07 22 2010 cp.wu -+ * -+ * 1) refine AIS-FSM indent. -+ * 2) when entering RF Test mode, flush 802.1X frames as well -+ * 3) when entering D3 state, flush 802.1X frames as well -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) change fake BSS_DESC from channel 6 to channel 1 due to channel switching is not done yet. -+ * 2) after MAC address is queried from firmware, all related variables in driver domain should be updated as well -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 29 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change upon request: indicate as disconnected in driver domain when leaving from RF test mode -+ * -+ * 05 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * do not clear scanning list array after disassociation -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) disable NETWORK_LAYER_ADDRESSES handling temporally. -+ * 2) finish statistics OIDs -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change OID behavior to meet WHQL requirement. -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct OID_802_11_DISASSOCIATE handling. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 04 16 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * treat BUS access failure as kind of card removal. -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * accessing to firmware load/start address, and access to OID handling information -+ * are now handled in glue layer -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * are done in adapter layer. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add KAL API: kalFlushPendingTxPackets(), and take use of the API -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glude code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * sync statistics data structure definition with firmware implementation -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * statistics information OIDs are now handled by querying from firmware domain -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * indicate media stream mode after set is done -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement custom OID: EEPROM read/write access -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_3_MULTICAST_LIST oid handling -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * limit RSSI return value to micxxsoft defined range. -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 29 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * block until firmware finished RF test enter/leave then indicate completion to upper layer -+ * -+ * 01 29 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * when entering RF test mode and leaving from RF test mode, wait for W_FUNC_RDY bit to be asserted forever until it -+ * is set or card is removed. -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * * * * * 4. correct some HAL implementation -+ * -+ * 01 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Under WinXP with SDIO, use prGlueInfo->rHifInfo.pvInformationBuffer instead of prGlueInfo->pvInformationBuffer -+ * -+ * 01 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement following 802.11 OIDs: -+ * * * * * OID_802_11_RSSI, -+ * * * * * OID_802_11_RSSI_TRIGGER, -+ * * * * * OID_802_11_STATISTICS, -+ * * * * * OID_802_11_DISASSOCIATE, -+ * * * * * OID_802_11_POWER_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_MEDIA_STREAM_MODE -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * * * * and result is retrieved by get ATInfo instead -+ * * * * * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:47:47 GMT mtk02752 -+** only handle MCR read when accessing FW domain register -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-08 17:37:28 GMT mtk02752 -+** * refine nicCmdEventQueryMcrRead -+** + add TxStatus/RxStatus for RF test QueryInformation OIDs -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-12-02 22:05:45 GMT mtk02752 -+** kalOidComplete() will decrease i4OidPendingCount -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-12-01 23:02:57 GMT mtk02752 -+** remove unnecessary spin locks -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-12-01 22:51:18 GMT mtk02752 -+** maintein i4OidPendingCount -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-30 10:55:03 GMT mtk02752 -+** modify for compatibility -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-23 14:46:32 GMT mtk02752 -+** add another version of command-done handler upon new event structure -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-29 15:42:33 GMT mtk01461 -+** Add comment -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 19:32:42 GMT mtk01461 -+** Add nicCmdEventSetCommon() for general set OID -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-21 01:40:35 GMT mtk01461 -+** Command Done Handler -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+VOID nicCmdEventQueryMcrRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrRdInfo; -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_ACCESS_REG prCmdAccessReg; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdAccessReg = (P_CMD_ACCESS_REG) (pucEventBuf); -+ -+ u4QueryInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T); -+ -+ prMcrRdInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) prCmdInfo->pvInformationBuffer; -+ prMcrRdInfo->u4McrOffset = prCmdAccessReg->u4Address; -+ prMcrRdInfo->u4McrData = prCmdAccessReg->u4Data; -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+ return; -+ -+} -+ -+VOID nicCmdEventQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo; -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_SW_DBG_CTRL_T prCmdSwCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdSwCtrl = (P_CMD_SW_DBG_CTRL_T) (pucEventBuf); -+ -+ u4QueryInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T); -+ -+ prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) prCmdInfo->pvInformationBuffer; -+ prSwCtrlInfo->u4Id = prCmdSwCtrl->u4Id; -+ prSwCtrlInfo->u4Data = prCmdSwCtrl->u4Data; -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+ return; -+ -+} -+ -+VOID nicCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, prCmdInfo->u4InformationBufferLength, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+ -+VOID nicCmdEventSetDisassociate(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ } -+ -+ DBGLOG(NIC, TRACE, "DisByCmdE\n"); -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ -+#if !defined(LINUX) -+ prAdapter->fgIsRadioOff = TRUE; -+#endif -+ -+} -+ -+VOID nicCmdEventSetIpAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4Count; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ u4Count = (prCmdInfo->u4SetInfoLen - OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress)) -+ / sizeof(IPV4_NETWORK_ADDRESS); -+ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, -+ OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress) + u4Count * -+ (OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP)), -+ WLAN_STATUS_SUCCESS); -+ } -+ -+} -+ -+VOID nicCmdEventQueryRfTestATInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_TEST_STATUS prTestStatus, prQueryBuffer; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prTestStatus = (P_EVENT_TEST_STATUS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prQueryBuffer = (P_EVENT_TEST_STATUS) prCmdInfo->pvInformationBuffer; -+ -+ kalMemCopy(prQueryBuffer, prTestStatus, sizeof(EVENT_TEST_STATUS)); -+ -+ u4QueryInfoLen = sizeof(EVENT_TEST_STATUS); -+ -+ /* Update Query Information Length */ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+ -+VOID nicCmdEventQueryLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ PARAM_RSSI rRssi, *prRssi; -+ P_EVENT_LINK_QUALITY prLinkQuality; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; -+ -+ rRssi = (PARAM_RSSI) prLinkQuality->cRssi; /* ranged from (-128 ~ 30) in unit of dBm */ -+ DBGLOG(NIC, INFO, " %s: rRssi = %d\n", __func__, rRssi); -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) -+ rRssi = PARAM_WHQL_RSSI_MAX_DBM; -+ else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) -+ rRssi = PARAM_WHQL_RSSI_MIN_DBM; -+ } else { -+ rRssi = PARAM_WHQL_RSSI_MIN_DBM; -+ } -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prRssi = (PARAM_RSSI *) prCmdInfo->pvInformationBuffer; -+ -+ kalMemCopy(prRssi, &rRssi, sizeof(PARAM_RSSI)); -+ u4QueryInfoLen = sizeof(PARAM_RSSI); -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is in response of OID_GEN_LINK_SPEED query request -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the pending command info -+* @param pucEventBuf -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventQueryLinkSpeed(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_LINK_QUALITY prLinkQuality; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4LinkSpeed; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ pu4LinkSpeed = (PUINT_32) (prCmdInfo->pvInformationBuffer); -+ -+ *pu4LinkSpeed = prLinkQuality->u2LinkSpeed * 5000; -+ -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics; -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ u4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) prCmdInfo->pvInformationBuffer; -+ -+ prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics->rTransmittedFragmentCount = prEventStatistics->rTransmittedFragmentCount; -+ prStatistics->rMulticastTransmittedFrameCount = prEventStatistics->rMulticastTransmittedFrameCount; -+ prStatistics->rFailedCount = prEventStatistics->rFailedCount; -+ prStatistics->rRetryCount = prEventStatistics->rRetryCount; -+ prStatistics->rMultipleRetryCount = prEventStatistics->rMultipleRetryCount; -+ prStatistics->rRTSSuccessCount = prEventStatistics->rRTSSuccessCount; -+ prStatistics->rRTSFailureCount = prEventStatistics->rRTSFailureCount; -+ prStatistics->rACKFailureCount = prEventStatistics->rACKFailureCount; -+ prStatistics->rFrameDuplicateCount = prEventStatistics->rFrameDuplicateCount; -+ prStatistics->rReceivedFragmentCount = prEventStatistics->rReceivedFragmentCount; -+ prStatistics->rMulticastReceivedFrameCount = prEventStatistics->rMulticastReceivedFrameCount; -+ prStatistics->rFCSErrorCount = prEventStatistics->rFCSErrorCount; -+ prStatistics->rTKIPLocalMICFailures.QuadPart = 0; -+ prStatistics->rTKIPICVErrors.QuadPart = 0; -+ prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; -+ prStatistics->rTKIPReplays.QuadPart = 0; -+ prStatistics->rCCMPFormatErrors.QuadPart = 0; -+ prStatistics->rCCMPReplays.QuadPart = 0; -+ prStatistics->rCCMPDecryptErrors.QuadPart = 0; -+ prStatistics->rFourWayHandshakeFailures.QuadPart = 0; -+ prStatistics->rWEPUndecryptableCount.QuadPart = 0; -+ prStatistics->rWEPICVErrorCount.QuadPart = 0; -+ prStatistics->rDecryptSuccessCount.QuadPart = 0; -+ prStatistics->rDecryptFailureCount.QuadPart = 0; -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventEnterRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+#define WAIT_FW_READY_RETRY_CNT 200 -+ -+ UINT_32 u4WHISR = 0, u4Value = 0; -+ UINT_8 aucTxCount[8]; -+ UINT_16 u2RetryCnt = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ /* [driver-land] */ -+ prAdapter->fgTestMode = TRUE; -+ -+ /* 0. always indicate disconnection */ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ /* 1. Remove pending TX */ -+ nicTxRelease(prAdapter); -+ -+ /* 1.1 clear pending Security / Management Frames */ -+ kalClearSecurityFrames(prAdapter->prGlueInfo); -+ kalClearMgmtFrames(prAdapter->prGlueInfo); -+ -+ /* 1.2 clear pending TX packet queued in glue layer */ -+ kalFlushPendingTxPackets(prAdapter->prGlueInfo); -+ -+ /* 2. Reset driver-domain FSMs */ -+ nicUninitMGMT(prAdapter); -+ -+ nicResetSystemService(prAdapter); -+ nicInitMGMT(prAdapter, NULL); -+ -+ /* 3. Disable Interrupt */ -+ HAL_INTR_DISABLE(prAdapter); -+ -+ /* 4. Block til firmware completed entering into RF test mode */ -+ kalMsleep(500); -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); -+ -+ if (u4Value & WCIR_WLAN_READY) { -+ break; -+ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE || -+ kalIsResetting() || u2RetryCnt >= WAIT_FW_READY_RETRY_CNT) { -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, -+ prCmdInfo->u4SetInfoLen, WLAN_STATUS_NOT_SUPPORTED); -+ -+ } -+ return; -+ } -+ kalMsleep(10); -+ u2RetryCnt++; -+ } -+ -+ /* 5. Clear Interrupt Status */ -+ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR); -+ if (HAL_IS_TX_DONE_INTR(u4WHISR)) -+ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); -+ /* 6. Reset TX Counter */ -+ nicTxResetResource(prAdapter); -+ -+ /* 7. Re-enable Interrupt */ -+ HAL_INTR_ENABLE(prAdapter); -+ -+ /* 8. completion indication */ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); -+ } -+#if CFG_SUPPORT_NVRAM -+ /* 9. load manufacture data */ -+ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); -+#endif -+ -+} -+ -+VOID nicCmdEventLeaveRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+#define WAIT_FW_READY_RETRY_CNT 200 -+ -+ UINT_32 u4WHISR = 0, u4Value = 0; -+ UINT_8 aucTxCount[8]; -+ UINT_16 u2RetryCnt = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ /* 1. Disable Interrupt */ -+ HAL_INTR_DISABLE(prAdapter); -+ -+ /* 2. Block til firmware completed leaving from RF test mode */ -+ kalMsleep(500); -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); -+ -+ if (u4Value & WCIR_WLAN_READY) { -+ break; -+ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE || -+ kalIsResetting() || u2RetryCnt >= WAIT_FW_READY_RETRY_CNT) { -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, -+ prCmdInfo->u4SetInfoLen, WLAN_STATUS_NOT_SUPPORTED); -+ -+ } -+ return; -+ } -+ kalMsleep(10); -+ u2RetryCnt++; -+ } -+ -+ /* 3. Clear Interrupt Status */ -+ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR); -+ if (HAL_IS_TX_DONE_INTR(u4WHISR)) -+ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); -+ /* 4. Reset TX Counter */ -+ nicTxResetResource(prAdapter); -+ -+ /* 5. Re-enable Interrupt */ -+ HAL_INTR_ENABLE(prAdapter); -+ -+ /* 6. set driver-land variable */ -+ prAdapter->fgTestMode = FALSE; -+ -+ /* 7. completion indication */ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+ /* 8. Indicate as disconnected */ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ -+ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); -+ } -+#if CFG_SUPPORT_NVRAM -+ /* 9. load manufacture data */ -+ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); -+#endif -+ -+ /* 10. Override network address */ -+ wlanUpdateNetworkAddress(prAdapter); -+ -+} -+ -+VOID nicCmdEventQueryAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_GLUE_INFO_T prGlueInfo; -+ P_EVENT_BASIC_CONFIG prEventBasicConfig; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ prEventBasicConfig = (P_EVENT_BASIC_CONFIG) (pucEventBuf); -+ -+ /* copy to adapter */ -+ kalMemCopy(&(prAdapter->rMyMacAddr), &(prEventBasicConfig->rMyMacAddr), MAC_ADDR_LEN); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ kalMemCopy(prCmdInfo->pvInformationBuffer, &(prEventBasicConfig->rMyMacAddr), MAC_ADDR_LEN); -+ u4QueryInfoLen = MAC_ADDR_LEN; -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ /* 4 <3> Update new MAC address and all 3 networks */ -+ COPY_MAC_ADDR(prAdapter->rWifiVar.aucMacAddress, prAdapter->rMyMacAddr); -+ COPY_MAC_ADDR(prAdapter->rWifiVar.aucDeviceAddress, prAdapter->rMyMacAddr); -+ prAdapter->rWifiVar.aucDeviceAddress[0] ^= MAC_ADDR_LOCAL_ADMIN; -+ -+ COPY_MAC_ADDR(prAdapter->rWifiVar.aucInterfaceAddress, prAdapter->rMyMacAddr); -+ prAdapter->rWifiVar.aucInterfaceAddress[0] ^= MAC_ADDR_LOCAL_ADMIN; -+ -+ COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].aucOwnMacAddr, prAdapter->rMyMacAddr); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) { -+ COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].aucOwnMacAddr, -+ prAdapter->rWifiVar.aucDeviceAddress); -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX].aucOwnMacAddr, -+ prAdapter->rWifiVar.aucDeviceAddress); -+#endif -+ -+#if CFG_TEST_WIFI_DIRECT_GO -+ if (prAdapter->rWifiVar.prP2pFsmInfo->eCurrentState == P2P_STATE_IDLE) { -+ wlanEnableP2pFunction(prAdapter); -+ -+ wlanEnableATGO(prAdapter); -+ } -+#endif -+ -+ kalUpdateMACAddress(prAdapter->prGlueInfo, prAdapter->rWifiVar.aucMacAddress); -+ -+} -+ -+VOID nicCmdEventQueryMcastAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_GLUE_INFO_T prGlueInfo; -+ P_EVENT_MAC_MCAST_ADDR prEventMacMcastAddr; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEventMacMcastAddr = (P_EVENT_MAC_MCAST_ADDR) (pucEventBuf); -+ -+ u4QueryInfoLen = prEventMacMcastAddr->u4NumOfGroupAddr * MAC_ADDR_LEN; -+ -+ /* buffer length check */ -+ if (prCmdInfo->u4InformationBufferLength < u4QueryInfoLen) { -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_BUFFER_TOO_SHORT); -+ } else { -+ kalMemCopy(prCmdInfo->pvInformationBuffer, -+ prEventMacMcastAddr->arAddress, -+ prEventMacMcastAddr->u4NumOfGroupAddr * MAC_ADDR_LEN); -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ } -+} -+ -+VOID nicCmdEventQueryEepromRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRdInfo; -+ P_GLUE_INFO_T prGlueInfo; -+ P_EVENT_ACCESS_EEPROM prEventAccessEeprom; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEventAccessEeprom = (P_EVENT_ACCESS_EEPROM) (pucEventBuf); -+ -+ u4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); -+ -+ prEepromRdInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) prCmdInfo->pvInformationBuffer; -+ prEepromRdInfo->ucEepromIndex = (UINT_8) (prEventAccessEeprom->u2Offset); -+ prEepromRdInfo->u2EepromData = prEventAccessEeprom->u2Data; -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+ return; -+ -+} -+ -+VOID nicCmdEventSetMediaStreamMode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ PARAM_MEDIA_STREAMING_INDICATION rParamMediaStreamIndication; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+ rParamMediaStreamIndication.rStatus.eStatusType = ENUM_STATUS_TYPE_MEDIA_STREAM_MODE; -+ rParamMediaStreamIndication.eMediaStreamMode = -+ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode == 0 ? ENUM_MEDIA_STREAM_OFF : ENUM_MEDIA_STREAM_ON; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID)&rParamMediaStreamIndication, sizeof(PARAM_MEDIA_STREAMING_INDICATION)); -+} -+ -+/* Statistics responder */ -+VOID nicCmdEventQueryXmitOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rTransmittedFragmentCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = prEventStatistics->rTransmittedFragmentCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryRecvOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rReceivedFragmentCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = prEventStatistics->rReceivedFragmentCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryXmitError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rFailedCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = (UINT_64) prEventStatistics->rFailedCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryRecvError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rFCSErrorCount.QuadPart; -+ /* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */ -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = prEventStatistics->rFCSErrorCount.QuadPart; -+ /* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */ -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryRecvNoBuffer(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = 0; /* @FIXME? */ -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = 0; /* @FIXME? */ -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryRecvCrcError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rFCSErrorCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = prEventStatistics->rFCSErrorCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryRecvErrorAlignment(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) 0; /* @FIXME */ -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = 0; /* @FIXME */ -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = -+ (UINT_32) (prEventStatistics->rMultipleRetryCount.QuadPart - -+ prEventStatistics->rRetryCount.QuadPart); -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = -+ (UINT_64) (prEventStatistics->rMultipleRetryCount.QuadPart - -+ prEventStatistics->rRetryCount.QuadPart); -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rMultipleRetryCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = (UINT_64) prEventStatistics->rMultipleRetryCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rFailedCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = (UINT_64) prEventStatistics->rFailedCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when command by OID/ioctl has been timeout -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicOidCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ ASSERT(prAdapter); -+ -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is a generic command timeout handler -+* -+* @param pfnOidHandler Pointer to the OID handler -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ ASSERT(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when command for entering RF test has -+* failed sending due to timeout (highly possibly by firmware crash) -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicOidCmdEnterRFTestTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ ASSERT(prAdapter); -+ -+ /* 1. Remove pending TX frames */ -+ nicTxRelease(prAdapter); -+ -+ /* 1.1 clear pending Security / Management Frames */ -+ kalClearSecurityFrames(prAdapter->prGlueInfo); -+ kalClearMgmtFrames(prAdapter->prGlueInfo); -+ -+ /* 1.2 clear pending TX packet queued in glue layer */ -+ kalFlushPendingTxPackets(prAdapter->prGlueInfo); -+ -+ /* 2. indicate for OID failure */ -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when command for memory dump has -+* replied a event. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventQueryMemDump(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo; -+ P_GLUE_INFO_T prGlueInfo; -+ P_EVENT_DUMP_MEM_T prEventDumpMem; -+ static UINT_8 aucPath[256]; -+ static UINT_32 u4CurTimeTick; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEventDumpMem = (P_EVENT_DUMP_MEM_T) (pucEventBuf); -+ -+ u4QueryInfoLen = sizeof(P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T); -+ -+ prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) prCmdInfo->pvInformationBuffer; -+ prMemDumpInfo->u4Address = prEventDumpMem->u4Address; -+ prMemDumpInfo->u4Length = prEventDumpMem->u4Length; -+ prMemDumpInfo->u4RemainLength = prEventDumpMem->u4RemainLength; -+ prMemDumpInfo->ucFragNum = prEventDumpMem->ucFragNum; -+ -+#if 0 -+ do { -+ UINT_32 i = 0; -+ -+ DBGLOG(REQ, TRACE, "Rx dump address 0x%X, Length %d, FragNum %d, remain %d\n", -+ prEventDumpMem->u4Address, -+ prEventDumpMem->u4Length, prEventDumpMem->ucFragNum, prEventDumpMem->u4RemainLength); -+#if 0 -+ for (i = 0; i < prEventDumpMem->u4Length; i++) { -+ DBGLOG(REQ, TRACE, "%02X ", prEventDumpMem->aucBuffer[i]); -+ if (i % 32 == 31) -+ DBGLOG(REQ, TRACE, "\n"); -+ } -+#endif -+ } while (FALSE); -+#endif -+ -+ if (prEventDumpMem->ucFragNum == 1) { -+ /* Store memory dump into sdcard, -+ * path /sdcard/dump___.hex -+ */ -+ u4CurTimeTick = kalGetTimeTick(); -+ sprintf(aucPath, "/sdcard/dump_%d_0x%08X_%d.hex", -+ u4CurTimeTick, -+ prEventDumpMem->u4Address, prEventDumpMem->u4Length + prEventDumpMem->u4RemainLength); -+ kalWriteToFile(aucPath, FALSE, &prEventDumpMem->aucBuffer[0], prEventDumpMem->u4Length); -+ } else { -+ /* Append current memory dump to the hex file */ -+ kalWriteToFile(aucPath, TRUE, &prEventDumpMem->aucBuffer[0], prEventDumpMem->u4Length); -+ } -+ -+ if (prEventDumpMem->u4RemainLength == 0 || prEventDumpMem->u4Address == 0xFFFFFFFF) { -+ /* The request is finished or firmware response a error */ -+ /* Reply time tick to iwpriv */ -+ *((PUINT_32) prCmdInfo->pvInformationBuffer) = u4CurTimeTick; -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } else { -+ /* The memory dump request is not finished, Send next command */ -+ wlanSendMemDumpCmd(prAdapter, -+ prCmdInfo->pvInformationBuffer, prCmdInfo->u4InformationBufferLength); -+ } -+ } -+ -+ return; -+ -+} -+ -+#if CFG_SUPPORT_BATCH_SCAN -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when event for SUPPORT_BATCH_SCAN -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to the event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventBatchScanResult(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_BATCH_RESULT_T prEventBatchResult; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ DBGLOG(SCN, TRACE, "nicCmdEventBatchScanResult"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEventBatchResult = (P_EVENT_BATCH_RESULT_T) pucEventBuf; -+ -+ u4QueryInfoLen = sizeof(EVENT_BATCH_RESULT_T); -+ kalMemCopy(prCmdInfo->pvInformationBuffer, prEventBatchResult, sizeof(EVENT_BATCH_RESULT_T)); -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+#endif -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when event for build date code information -+* has been retrieved -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to the event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventBuildDateCode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_BUILD_DATE_CODE prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEvent = (P_EVENT_BUILD_DATE_CODE) pucEventBuf; -+ -+ u4QueryInfoLen = sizeof(UINT_8) * 16; -+ kalMemCopy(prCmdInfo->pvInformationBuffer, prEvent->aucDateCode, sizeof(UINT_8) * 16); -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when event for query STA link status -+* has been retrieved -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to the event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventQueryStaStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_STA_STATISTICS_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ P_PARAM_GET_STA_STATISTICS prStaStatistics; -+ -+ if ((prAdapter == NULL) -+ || (prCmdInfo == NULL) -+ || (pucEventBuf == NULL) -+ || (prCmdInfo->pvInformationBuffer == NULL)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEvent = (P_EVENT_STA_STATISTICS_T) pucEventBuf; -+ prStaStatistics = (P_PARAM_GET_STA_STATISTICS) prCmdInfo->pvInformationBuffer; -+ -+ u4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS); -+ -+ /* Statistics from FW is valid */ -+ if (prEvent->u4Flags & BIT(0)) { -+ prStaStatistics->ucPer = prEvent->ucPer; -+ prStaStatistics->ucRcpi = prEvent->ucRcpi; -+ prStaStatistics->u4PhyMode = prEvent->u4PhyMode; -+ prStaStatistics->u2LinkSpeed = prEvent->u2LinkSpeed; -+ -+ prStaStatistics->u4TxFailCount = prEvent->u4TxFailCount; -+ prStaStatistics->u4TxLifeTimeoutCount = prEvent->u4TxLifeTimeoutCount; -+ -+ if (prEvent->u4TxCount) { -+ UINT_32 u4TxDoneAirTimeMs = USEC_TO_MSEC(prEvent->u4TxDoneAirTime * 32); -+ -+ prStaStatistics->u4TxAverageAirTime = (u4TxDoneAirTimeMs / prEvent->u4TxCount); -+ } else { -+ prStaStatistics->u4TxAverageAirTime = 0; -+ } -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ -+/* 4 Auto Channel Selection */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when event for query STA link status -+* has been retrieved -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to the event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventQueryChannelLoad(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_CHN_LOAD_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ P_PARAM_GET_CHN_LOAD prChnLoad; -+ -+ if ((prAdapter == NULL) -+ || (prCmdInfo == NULL) -+ || (pucEventBuf == NULL) -+ || (prCmdInfo->pvInformationBuffer == NULL)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEvent = (P_EVENT_CHN_LOAD_T) pucEventBuf; /* 4 The firmware responsed data */ -+ /* 4 Fill the firmware data in and send it back to host */ -+ prChnLoad = (P_PARAM_GET_CHN_LOAD) prCmdInfo->pvInformationBuffer; -+ -+ u4QueryInfoLen = sizeof(PARAM_GET_CHN_LOAD); -+ -+ /* Statistics from FW is valid */ -+ if (prEvent->u4Flags & BIT(0)) { -+ prChnLoad->rEachChnLoad[0].ucChannel = prEvent->ucChannel; -+ prChnLoad->rEachChnLoad[0].u2ChannelLoad = prEvent->u2ChannelLoad; -+ DBGLOG(P2P, INFO, "CHN[%d]=%d\n", prEvent->ucChannel, prEvent->u2ChannelLoad); -+ -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+ -+VOID nicCmdEventQueryLTESafeChn(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_8 ucIdx = 0; -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_LTE_MODE_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ P_PARAM_GET_CHN_LOAD prLteSafeChnInfo; -+ -+ if ((prAdapter == NULL) -+ || (prCmdInfo == NULL) -+ || (pucEventBuf == NULL) -+ || (prCmdInfo->pvInformationBuffer == NULL)) { -+ ASSERT(FALSE); -+ return; -+ } -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEvent = (P_EVENT_LTE_MODE_T) pucEventBuf; /* 4 The firmware responsed data */ -+ -+ prLteSafeChnInfo = (P_PARAM_GET_CHN_LOAD) prCmdInfo->pvInformationBuffer; -+ -+ u4QueryInfoLen = sizeof(PARAM_GET_CHN_LOAD); -+ -+ /* Statistics from FW is valid */ -+ if (prEvent->u4Flags & BIT(0)) { -+ for (ucIdx = 0; ucIdx < (NL80211_TESTMODE_AVAILABLE_CHAN_NUM - 1); ucIdx++) { -+ prLteSafeChnInfo->rLteSafeChnList.au4SafeChannelBitmask[ucIdx] = -+ prEvent->rLteSafeChn.au4SafeChannelBitmask[ucIdx]; -+ -+ DBGLOG(P2P, INFO, -+ "[Auto Channel]LTE safe channels [%d]=[%x]\n", ucIdx, -+ (UINT32) prLteSafeChnInfo->rLteSafeChnList.au4SafeChannelBitmask[ucIdx]); -+ } -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when event for query FW bss info -+* has been retrieved -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to the event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID nicCmdEventGetBSSInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_AIS_BSS_INFO_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEvent = (P_EVENT_AIS_BSS_INFO_T) pucEventBuf; -+ -+ u4QueryInfoLen = sizeof(EVENT_AIS_BSS_INFO_T); -+ kalMemCopy(prCmdInfo->pvInformationBuffer, prEvent, sizeof(EVENT_AIS_BSS_INFO_T)); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ if (prEvent->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { -+ if (prEvent->eConnectionState != prAisBssInfo->eConnectionState) { -+ DBGLOG(NIC, ERROR, "driver[%d] & FW[%d] status didn't sync !!!\n", -+ prAisBssInfo->eConnectionState, prEvent->eCurrentOPMode); -+ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_RADIO_LOST, FALSE); -+ } -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c -new file mode 100644 -index 0000000000000..cf80fd999a240 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c -@@ -0,0 +1,669 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_pwr_mgt.c#1 -+*/ -+ -+/*! \file "nic_pwr_mgt.c" -+ \brief In this file we define the STATE and EVENT for Power Management FSM. -+ -+ The SCAN FSM is responsible for performing SCAN behavior when the Arbiter enter -+ ARB_STATE_SCAN. The STATE and EVENT for SCAN FSM are defined here with detail -+ description. -+*/ -+ -+/* -+** Log: nic_pwr_mgt.c -+ * -+ * 11 28 2011 cp.wu -+ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment when -+ * returining to ROM code -+ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware -+ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware download path in divided scatters. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * reuse firmware download logic of MT6620 for MT6628. -+ * -+ * 05 11 2011 cp.wu -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. -+ * -+ * 04 29 2011 cp.wu -+ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) -+ * fix for compilation error when applied with FW_DOWNLOAD = 0 -+ * -+ * 04 18 2011 cp.wu -+ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) -+ * 1) add API for glue layer to query ACPI state -+ * 2) Windows glue should not access to hardware after switched into D3 state -+ * -+ * 04 13 2011 cp.wu -+ * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete -+ * refine for MT5931/MT6620 logic separation. -+ * -+ * 04 13 2011 cp.wu -+ * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete -+ * bugfix: firmware download procedure for ACPI state transition is not complete. -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system -+ * scheduling -+ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being -+ * loaded -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * check success or failure for setting fw-own -+ * -+ * 12 30 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * host driver not to set FW-own when there is still pending interrupts -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ * associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * reset ACPI power state before waking up MT6620 Wi-Fi firmware. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * Centralize mgmt/system service procedures into independent calls. -+ * -+ * 07 22 2010 cp.wu -+ * -+ * 1) refine AIS-FSM indent. -+ * 2) when entering RF Test mode, flush 802.1X frames as well -+ * 3) when entering D3 state, flush 802.1X frames as well -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change MAC address updating logic. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) when acquiring LP-own, write for clr-own with lower frequency compared to read poll -+ * 2) correct address list parsing -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * sleepy notify is only used for sleepy state, -+ * while wake-up state is automatically set when host needs to access device -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct hibernation problem. -+ * -+ * 04 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) surpress compiler warning -+ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * when acquiring driver-own, wait for up to 8 seconds. -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove redundant firmware image unloading -+ * * 2) use compile-time macros to separate logic related to accquiring own -+ * -+ * 04 16 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * treat BUS access failure as kind of card removal. -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * accessing to firmware load/start address, and access to OID handling information -+ * * are now handled in glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * ePowerCtrl is not necessary as a glue variable. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add KAL API: kalFlushPendingTxPackets(), and take use of the API -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always send CMD_NIC_POWER_CTRL packet when nic is being halted -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct typo. -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX -+ * response -+ * -+ * 03 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. -+ * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-10-13 21:59:15 GMT mtk01084 -+** update for new HW design -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-09-09 17:26:36 GMT mtk01084 -+** remove CMD52 access -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-05-18 14:50:29 GMT mtk01084 -+** modify lines in nicpmSetDriverOwn() -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-23 16:55:37 GMT mtk01084 -+** modify nicpmSetDriverOwn() -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-19 18:33:00 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-03-19 15:05:32 GMT mtk01084 -+** Initial version -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to process the POWER ON procedure. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicpmSetFWOwn(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableGlobalInt) -+{ -+ UINT_32 u4RegValue = 0; -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->fgIsFwOwn == TRUE) -+ return; -+ -+ if (nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { -+ /* pending interrupts */ -+ return; -+ } -+ -+ if (fgEnableGlobalInt) { -+ prAdapter->fgIsIntEnableWithLPOwnSet = TRUE; -+ } else { -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); -+ -+ HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); -+ if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { -+ /* if set firmware own not successful (possibly pending interrupts), */ -+ /* indicate an own clear event */ -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); -+ -+ return; -+ } -+ -+ prAdapter->fgIsFwOwn = TRUE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to process the POWER OFF procedure. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 u4OriRegValue = 0; -+BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter) -+{ -+#define LP_OWN_BACK_TOTAL_DELAY_MS 2000 /* exponential of 2 */ -+#define LP_OWN_BACK_LOOP_DELAY_MS 1 /* exponential of 2 */ -+#define LP_OWN_BACK_CLR_OWN_ITERATION 256 /* exponential of 2 */ -+ -+ BOOLEAN fgStatus = TRUE; -+ UINT_32 i, u4CurrTick; -+ UINT_32 u4RegValue = 0; -+ GL_HIF_INFO_T *HifInfo; -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->fgIsFwOwn == FALSE) -+ return fgStatus; -+ -+ HifInfo = &prAdapter->prGlueInfo->rHifInfo; -+ -+ u4CurrTick = kalGetTimeTick(); -+ STATS_DRIVER_OWN_START_RECORD(); -+ i = 0; -+ -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); -+ -+ if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { -+ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4OriRegValue); -+ prAdapter->fgIsFwOwn = FALSE; -+ break; -+ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE -+ || fgIsBusAccessFailed == TRUE -+ || (kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS || fgIsResetting == TRUE) { -+ /* ERRORLOG(("LP cannot be own back (for %ld ms)", kalGetTimeTick() - u4CurrTick)); */ -+ fgStatus = FALSE; -+ if (fgIsResetting != TRUE) { -+ UINT_32 u4FwCnt; -+ static unsigned int u4OwnCnt; -+ /* MCR_D2HRM2R: low 4 bit means interrupt times, -+ * high 4 bit means firmware response times. -+ * ORI_MCR_D2HRM2R: the last successful value. -+ * for example: -+ * MCR_D2HRM2R = 0x44, ORI_MCR_D2HRM2R = 0x44 -+ * means firmware no receive interrupt form hardware. -+ * MCR_D2HRM2R = 0x45, ORI_MCR_D2HRM2R = 0x44 -+ * means firmware no send response. -+ * MCR_D2HRM2R = 0x55, ORI_MCR_D2HRM2R = 0x44 -+ * means firmware send response, but driver no receive. */ -+ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4RegValue); -+ DBGLOG(NIC, WARN, " [1]MCR_D2HRM2R = 0x%x, ORI_MCR_D2HRM2R = 0x%x\n", -+ u4RegValue, u4OriRegValue); -+ -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); -+ HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); -+ if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { -+ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4OriRegValue); -+ prAdapter->fgIsFwOwn = FALSE; -+ break; -+ } -+ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4RegValue); -+ DBGLOG(NIC, WARN, " [2]MCR_D2HRM2R = 0x%x, ORI_MCR_D2HRM2R = 0x%x\n", -+ u4RegValue, u4OriRegValue); -+ DBGLOG(NIC, WARN, -+ " Fatal error! Driver own fail!!!!!!!!!!!! %d, fgIsBusAccessFailed: %d\n", -+ u4OwnCnt++, fgIsBusAccessFailed); -+ -+ DBGLOG(NIC, WARN, "CONNSYS FW CPUINFO:\n"); -+ for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++) -+ DBGLOG(NIC, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR)); -+ /* CONSYS_REG_READ(CONSYS_CPUPCR_REG) */ -+ kalSendAeeWarning("[Fatal error! Driver own fail!]", __func__); -+ glDoChipReset(); -+ } -+ break; -+ } -+ if ((i & (LP_OWN_BACK_CLR_OWN_ITERATION - 1)) == 0) { -+ /* Software get LP ownership - per 256 iterations */ -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); -+ } -+ -+ /* Delay for LP engine to complete its operation. */ -+ kalMsleep(LP_OWN_BACK_LOOP_DELAY_MS); -+ i++; -+ } -+ -+ STATS_DRIVER_OWN_END_RECORD(); -+ STATS_DRIVER_OWN_STOP(); -+ -+ return fgStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set ACPI power mode to D0. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN nicpmSetAcpiPowerD0(IN P_ADAPTER_T prAdapter) -+{ -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ UINT_32 u4Value = 0, u4WHISR = 0; -+ UINT_8 aucTxCount[8]; -+ UINT_32 i; -+#if CFG_ENABLE_FW_DOWNLOAD -+ UINT_32 u4FwImgLength, u4FwLoadAddr, u4ImgSecSize; -+ PVOID prFwMappingHandle; -+ PVOID pvFwImageMapFile = NULL; -+#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD -+ UINT_32 j; -+ P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead; -+ BOOLEAN fgValidHead; -+ const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries); -+#endif -+#endif -+ -+ DEBUGFUNC("nicpmSetAcpiPowerD0"); -+ ASSERT(prAdapter); -+ -+ do { -+ /* 0. Reset variables in ADAPTER_T */ -+ prAdapter->fgIsFwOwn = TRUE; -+ prAdapter->fgWiFiInSleepyState = FALSE; -+ prAdapter->rAcpiState = ACPI_STATE_D0; -+ prAdapter->fgIsEnterD3ReqIssued = FALSE; -+ -+ /* 1. Request Ownership to enter F/W download state */ -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+#if !CFG_ENABLE_FULL_PM -+ nicpmSetDriverOwn(prAdapter); -+#endif -+ -+ /* 2. Initialize the Adapter */ -+ u4Status = nicInitializeAdapter(prAdapter); -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ DBGLOG(NIC, ERROR, "nicInitializeAdapter failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+ prFwMappingHandle = kalFirmwareImageMapping(prAdapter->prGlueInfo, &pvFwImageMapFile, &u4FwImgLength); -+ if (!prFwMappingHandle) { -+ DBGLOG(NIC, ERROR, "Fail to load FW image from file!\n"); -+ pvFwImageMapFile = NULL; -+ } -+ -+ if (pvFwImageMapFile == NULL) { -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ -+ /* 3.1 disable interrupt, download is done by polling mode only */ -+ nicDisableInterrupt(prAdapter); -+ -+ /* 3.2 Initialize Tx Resource to fw download state */ -+ nicTxInitResetResource(prAdapter); -+ -+ /* 3.3 FW download here */ -+ u4FwLoadAddr = kalGetFwLoadAddress(prAdapter->prGlueInfo); -+ -+#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD -+ /* 3a. parse file header for decision of divided firmware download or not */ -+ prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T) pvFwImageMapFile; -+ -+ if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE && -+ prFwHead->u4CRC == wlanCRC32((PUINT_8) pvFwImageMapFile + u4CRCOffset, -+ u4FwImgLength - u4CRCOffset)) { -+ fgValidHead = TRUE; -+ } else { -+ fgValidHead = FALSE; -+ } -+ -+ /* 3b. engage divided firmware downloading */ -+ if (fgValidHead == TRUE) { -+ for (i = 0; i < prFwHead->u4NumOfEntries; i++) { -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+ if (wlanImageSectionDownloadAggregated(prAdapter, -+ prFwHead->arSection[i].u4DestAddr, -+ prFwHead->arSection[i].u4Length, -+ (PUINT_8) pvFwImageMapFile + -+ prFwHead->arSection[i].u4Offset) != -+ WLAN_STATUS_SUCCESS) { -+ DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } -+#else -+ for (j = 0; j < prFwHead->arSection[i].u4Length; j += CMD_PKT_SIZE_FOR_IMAGE) { -+ if (j + CMD_PKT_SIZE_FOR_IMAGE < prFwHead->arSection[i].u4Length) -+ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; -+ else -+ u4ImgSecSize = prFwHead->arSection[i].u4Length - j; -+ -+ if (wlanImageSectionDownload(prAdapter, -+ prFwHead->arSection[i].u4DestAddr + j, -+ u4ImgSecSize, -+ (PUINT_8) pvFwImageMapFile + -+ prFwHead->arSection[i].u4Offset + j) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ } -+#endif -+ /* escape from loop if any pending error occurs */ -+ if (u4Status == WLAN_STATUS_FAILURE) -+ break; -+ } -+ } else -+#endif -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+ if (wlanImageSectionDownloadAggregated(prAdapter, -+ u4FwLoadAddr, -+ u4FwImgLength, -+ (PUINT_8) pvFwImageMapFile) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } -+#else -+ for (i = 0; i < u4FwImgLength; i += CMD_PKT_SIZE_FOR_IMAGE) { -+ if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImgLength) -+ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; -+ else -+ u4ImgSecSize = u4FwImgLength - i; -+ -+ if (wlanImageSectionDownload(prAdapter, -+ u4FwLoadAddr + i, -+ u4ImgSecSize, -+ (PUINT_8) pvFwImageMapFile + i) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(NIC, ERROR, "wlanImageSectionDownload failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ } -+#endif -+ -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); -+ break; -+ } -+#if !CFG_ENABLE_FW_DOWNLOAD_ACK -+ /* Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response */ -+ if (wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) { -+ kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+#endif -+ kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); -+ -+ /* 4. send Wi-Fi Start command */ -+#if CFG_OVERRIDE_FW_START_ADDRESS -+ wlanConfigWifiFunc(prAdapter, TRUE, kalGetFwStartAddress(prAdapter->prGlueInfo)); -+#else -+ wlanConfigWifiFunc(prAdapter, FALSE, 0); -+#endif -+#endif /* if CFG_ENABLE_FW_DOWNLOAD */ -+ -+ /* 5. check Wi-Fi FW asserts ready bit */ -+ DBGLOG(NIC, TRACE, "wlanAdapterStart(): Waiting for Ready bit..\n"); -+ i = 0; -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); -+ -+ if (u4Value & WCIR_WLAN_READY) { -+ DBGLOG(NIC, TRACE, "Ready bit asserted\n"); -+ break; -+ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) { -+ DBGLOG(NIC, ERROR, "Waiting for Ready bit: Timeout\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ i++; -+ kalMsleep(10); -+ } -+ -+ if (u4Status == WLAN_STATUS_SUCCESS) { -+ /* 6.1 reset interrupt status */ -+ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)(&u4WHISR)); -+ if (HAL_IS_TX_DONE_INTR(u4WHISR)) -+ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); -+ -+ /* 6.2 reset TX Resource for normal operation */ -+ nicTxResetResource(prAdapter); -+ -+ /* 6.3 Enable interrupt */ -+ nicEnableInterrupt(prAdapter); -+ -+ /* 6.4 Override network address */ -+ wlanUpdateNetworkAddress(prAdapter); -+ -+ /* 6.5 indicate disconnection as default status */ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ } -+ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ -+ /* MGMT Initialization */ -+ nicInitMGMT(prAdapter, NULL); -+ -+ } while (FALSE); -+ -+ if (u4Status != WLAN_STATUS_SUCCESS) -+ return FALSE; -+ else -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is used to set ACPI power mode to D3. -+* -+* @param prAdapter pointer to the Adapter handler -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN nicpmSetAcpiPowerD3(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ /* 1. MGMT - unitialization */ -+ nicUninitMGMT(prAdapter); -+ -+ /* 2. Disable Interrupt */ -+ nicDisableInterrupt(prAdapter); -+ -+ /* 3. emit CMD_NIC_POWER_CTRL command packet */ -+ wlanSendNicPowerCtrlCmd(prAdapter, 1); -+ -+ /* 4. Clear Interrupt Status */ -+ i = 0; -+ while (i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { -+ i++; -+ }; -+ -+ /* 5. Remove pending TX */ -+ nicTxRelease(prAdapter); -+ -+ /* 5.1 clear pending Security / Management Frames */ -+ kalClearSecurityFrames(prAdapter->prGlueInfo); -+ kalClearMgmtFrames(prAdapter->prGlueInfo); -+ -+ /* 5.2 clear pending TX packet queued in glue layer */ -+ kalFlushPendingTxPackets(prAdapter->prGlueInfo); -+ -+ /* 6. Set Onwership to F/W */ -+ nicpmSetFWOwn(prAdapter, FALSE); -+ -+ /* 7. Set variables */ -+ prAdapter->rAcpiState = ACPI_STATE_D3; -+ -+ return TRUE; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c -new file mode 100644 -index 0000000000000..ba4840414da85 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c -@@ -0,0 +1,3782 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_rx.c#3 -+*/ -+ -+/*! \file nic_rx.c -+ \brief Functions that provide many rx-related functions -+ -+ This file includes the functions used to process RFB and dispatch RFBs to -+ the appropriate related rx functions for protocols. -+*/ -+ -+/* -+** Log: nic_rx.c -+** -+** 08 31 2012 yuche.tsai -+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected to AP previously, -+** one device reboots automatically with KE -+** Fix possible KE when concurrent & disconnect. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 02 14 2012 cp.wu -+ * NULL -+ * remove another assertion by error message dump -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Update RSSI for P2P. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 17 2011 tsaiyuan.hsu -+ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. -+ * avoid deactivating staRec when changing state from 3 to 3. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Modify the QM xlog level and remove LOG_FUNC. -+ * -+ * 11 09 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog for beacon timeout and sta aging timeout. -+ * -+ * 11 08 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog function. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 10 21 2011 eddie.chen -+ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout -+ * Add switch to ignore the STA aging timeout. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 08 26 2011 cp.wu -+ * [WCXRP00000958] [MT6620 Wi-Fi][Driver] Extend polling timeout from 25ms to 1sec due to RF calibration might took -+ * up to 600ms -+ * extend polling RX response timeout period from 25ms to 1000ms. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 27 2011 cp.wu -+ * [WCXRP00000876] [MT5931][Drver] Decide to retain according to currently available RX counter and QUE_MGT used count -+ * correct comment. -+ * -+ * 07 27 2011 cp.wu -+ * [WCXRP00000876] [MT5931][Drver] Decide to retain according to currently available RX counter and QUE_MGT used count -+ * take use of QUE_MGT exported function to estimate currently RX buffer usage count. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 06 09 2011 tsaiyuan.hsu -+ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size -+ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. -+ * -+ * 05 11 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Fix dest type when GO packet copying. -+ * -+ * 05 09 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Check free number before copying broadcast packet. -+ * -+ * 05 05 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * add delay after whole-chip resetting for MT5931 E1 ASIC. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discoverability support for GO. -+ * -+ * 04 01 2011 tsaiyuan.hsu -+ * [WCXRP00000615] [MT 6620 Wi-Fi][Driver] Fix klocwork issues -+ * fix the klocwork issues, 57500, 57501, 57502 and 57503. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Add beacon timeout support for WiFi Direct Network. -+ * -+ * 03 18 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * enable the Anti_piracy check at driver . -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * use pre-allocated buffer for storing enhanced interrupt response as well -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add security check code. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after -+ * connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect to target station for AAA -+ * module. -+ * Remove Station Record after Aging timeout. -+ * -+ * 02 10 2011 cp.wu -+ * [WCXRP00000434] [MT6620 Wi-Fi][Driver] Obsolete unused event packet handlers -+ * EVENT_ID_CONNECTION_STATUS has been obsoleted and no need to handle. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add MLME deauthentication support for Hot-Spot mode. -+ * -+ * 02 09 2011 eddie.chen -+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode -+ * Adjust variable order. -+ * -+ * 02 08 2011 eddie.chen -+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode -+ * Add event STA agint timeout -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 24 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Remove comments. -+ * -+ * 01 24 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Add destination decision in AP mode. -+ * -+ * 01 24 2011 cm.chang -+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode and stop ampdu timer when sta_rec -+ * is freed -+ * Process received 20/40 coexistence action frame for AP mode -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 15 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * update beacon for NoA -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 27 2010 george.huang -+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB -+ * Support registry option for disable beacon lost detection. -+ * -+ * 10 20 2010 wh.su -+ * NULL -+ * add a cmd to reset the p2p key -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * fixed compilier error. -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ * associated -+ * release RX packet to packet pool when in RF test mode -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ @ associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Add a common buffer, store the IE of a P2P device in this common buffer. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * When enable WiFi Direct function, check each packet to tell which interface to indicate. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Add P2P Device Discovery Function. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 03 2010 george.huang -+ * NULL -+ * handle event for updating NOA parameters indicated from FW -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * Add support API for RX public action frame. -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Update Device Capability Bitmap & Group Capability Bitmap from 16 bits to 8 bits. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 23 2010 cp.wu -+ * -+ * add AIS-FSM handling for beacon timeout event. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 15 2010 cp.wu -+ * -+ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * fill ucStaRecIdx into SW_RFB_T. -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) for event packet, no need to fill RFB. -+ * 2) when wlanAdapterStart() failed, no need to initialize state machines -+ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 29 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * replace g_rQM with Adpater->rQM -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * refine TX-DONE callback. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implement TX_DONE callback path. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Add TX Done Event handle entry -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * . -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * . -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * saa_fsm.c is migrated. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync with MT6620 driver for scan result replacement policy -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 04 29 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * fixing the PMKID candicate indicate code. -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * basic implementation for EVENT_BT_OVER_WIFI -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * -+ * 1) modify rx path code for supporting Wi-Fi direct -+ * 2) modify config.h since Linux dont need to consider retaining packet -+ * -+ * 04 16 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * treat BUS access failure as kind of card removal. -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * nicRxProcessEvent packet doesn't access spin-lock directly from now on. -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * do not need to release the spin lock due to it is done inside nicGetPendingCmdInfo() -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add channel frequency <-> number conversion -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) add spinlock -+ * 2) add KAPI for handling association info -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * are done in adapter layer. -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 04 01 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve Linux supplicant compliance -+ * -+ * 03 31 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix ioctl which may cause cmdinfo memory leak -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * remove driver-land statistics. -+ * -+ * 03 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 03 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * rWlanInfo is modified before data is indicated to OS -+ * -+ * 03 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * rWlanInfo is modified before data is indicated to OS -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add a temporary flag for integration with CMD/EVENT v0.9. -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. -+ * * * the frequency is used for adhoc connection only -+ * * * 2) update with SD1 v0.9 CMD/EVENT documentation -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * . -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK -+ * * * * -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX -+ * response -+ * -+ * 03 15 2010 kevin.huang -+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test -+ * Add event for activate STA_RECORD_T -+ * -+ * 03 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct fgSetQuery/fgNeedResp check -+ * -+ * 03 11 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING -+ * -+ * 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 03 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. -+ * * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock -+ * * * * 2) ensure wlanReleasePendingOid will clear all command queues -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add mutex to avoid multiple access to qmTxQueue simultaneously. -+ * -+ * 02 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move EVENT_ID_ASSOC_INFO from nic_rx.c to gl_kal_ndis_51.c -+ * * 'cause it involves OS dependent data structure handling -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Updated API interfaces for qmHandleEventRxAddBa() and qmHandleEventRxDelBa() -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement host-side firmware download logic -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * * * * * 2) firmware image length is now retrieved via NdisFileOpen -+ * * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * * * * * 4) nicRxWaitResponse() revised -+ * * * * * 5) another set of TQ counter default value is added for fw-download state -+ * * * * * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+ * -+ * 01 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement following 802.11 OIDs: -+ * * * * * * OID_802_11_RSSI, -+ * * * * * * OID_802_11_RSSI_TRIGGER, -+ * * * * * * OID_802_11_STATISTICS, -+ * * * * * * OID_802_11_DISASSOCIATE, -+ * * * * * * OID_802_11_POWER_MODE -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * * * * * and result is retrieved by get ATInfo instead -+ * * * * * * * * * 2) add 4 counter for recording aggregation statistics -+ * -+ * 12 23 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add a precheck: if free sw rfb is not enough, do not invoke read transactionu1rwduu`wvpghlqg|fu+rp -+ * -+ * 12 22 2009 cp.wu -+ * [WPD00003809][Bug] Host driver will crash when processing reordered MSDUs -+ * The root cause is pointer accessing by mistake. After dequeued from reordering-buffer, handling logic should access -+ * returned pointer instead of pointer which has been passed in before. -+** \main\maintrunk.MT6620WiFiDriver_Prj\58 2009-12-17 13:40:33 GMT mtk02752 -+** always update prAdapter->rSDIOCtrl when enhanced response is read by RX -+** \main\maintrunk.MT6620WiFiDriver_Prj\57 2009-12-16 18:01:38 GMT mtk02752 -+** if interrupt enhanced response is fetched by RX enhanced response, RX needs to invoke interrupt handlers too -+** \main\maintrunk.MT6620WiFiDriver_Prj\56 2009-12-16 14:16:52 GMT mtk02752 -+** \main\maintrunk.MT6620WiFiDriver_Prj\55 2009-12-15 20:03:12 GMT mtk02752 -+** ASSERT when RX FreeSwRfb is not enough -+** \main\maintrunk.MT6620WiFiDriver_Prj\54 2009-12-15 17:01:29 GMT mtk02752 -+** when CFG_SDIO_RX_ENHANCE is enabled, after enhanced response is read, rx procedure should process -+** 1) TX_DONE_INT 2) D2H INT as well -+** \main\maintrunk.MT6620WiFiDriver_Prj\53 2009-12-14 20:45:28 GMT mtk02752 -+** when CFG_SDIO_RX_ENHANCE is set, TC counter must be updated each time RX enhance response is read -+** -+** \main\maintrunk.MT6620WiFiDriver_Prj\52 2009-12-14 11:34:16 GMT mtk02752 -+** correct a trivial logic issue -+** \main\maintrunk.MT6620WiFiDriver_Prj\51 2009-12-14 10:28:25 GMT mtk02752 -+** add a protection to avoid out-of-boundary access -+** \main\maintrunk.MT6620WiFiDriver_Prj\50 2009-12-10 16:55:18 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\49 2009-12-09 14:06:47 GMT MTK02468 -+** Added parsing event packets with EVENT_ID_RX_ADDBA or EVENT_ID_RX_DELBA -+** \main\maintrunk.MT6620WiFiDriver_Prj\48 2009-12-08 17:37:51 GMT mtk02752 -+** handle EVENT_ID_TEST_STATUS as well -+** \main\maintrunk.MT6620WiFiDriver_Prj\47 2009-12-04 17:59:11 GMT mtk02752 -+** to pass free-build compilation check -+** \main\maintrunk.MT6620WiFiDriver_Prj\46 2009-12-04 12:09:52 GMT mtk02752 -+** correct trivial mistake -+** \main\maintrunk.MT6620WiFiDriver_Prj\45 2009-12-04 11:53:37 GMT mtk02752 -+** all API should be compilable under SD1_SD3_DATAPATH_INTEGRATION == 0 -+** \main\maintrunk.MT6620WiFiDriver_Prj\44 2009-12-03 16:19:48 GMT mtk01461 -+** Fix the Connected Event -+** \main\maintrunk.MT6620WiFiDriver_Prj\43 2009-11-30 10:56:18 GMT mtk02752 -+** 1st DW of WIFI_EVENT_T is shared with HIF_RX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\42 2009-11-30 10:11:27 GMT mtk02752 -+** implement replacement for bss scan result -+** \main\maintrunk.MT6620WiFiDriver_Prj\41 2009-11-27 11:08:05 GMT mtk02752 -+** add flush for reset -+** \main\maintrunk.MT6620WiFiDriver_Prj\40 2009-11-26 09:38:59 GMT mtk02752 -+** \main\maintrunk.MT6620WiFiDriver_Prj\39 2009-11-26 09:29:40 GMT mtk02752 -+** enable packet forwarding path (for AP mode) -+** \main\maintrunk.MT6620WiFiDriver_Prj\38 2009-11-25 21:37:00 GMT mtk02752 -+** sync. with EVENT_SCAN_RESULT_T change, and add an assert for checking event size -+** \main\maintrunk.MT6620WiFiDriver_Prj\37 2009-11-25 20:17:41 GMT mtk02752 -+** fill HIF_TX_HEADER_T.u2SeqNo -+** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-11-25 18:18:57 GMT mtk02752 -+** buffer scan result to prGlueInfo->rWlanInfo.arScanResult directly. -+** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-11-24 22:42:45 GMT mtk02752 -+** add nicRxAddScanResult() to prepare to handle SCAN_RESULT event (not implemented yet) -+** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-11-24 20:51:41 GMT mtk02752 -+** integrate with SD1's data path API -+** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-11-24 19:56:17 GMT mtk02752 -+** adopt P_HIF_RX_HEADER_T in new path -+** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-11-23 20:31:21 GMT mtk02752 -+** payload to send into pfCmdDoneHandler() will not include WIFI_EVENT_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-11-23 17:51:34 GMT mtk02752 -+** when event packet corresponding to some pendingOID is received, pendingOID should be cleared -+** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-11-23 14:46:54 GMT mtk02752 -+** implement nicRxProcessEventPacket() -+** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-17 22:40:54 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-16 21:48:22 GMT mtk02752 -+** add SD1_SD3_DATAPATH_INTEGRATION data path handling -+** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-16 15:41:18 GMT mtk01084 -+** modify the length to be read in emu mode -+** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-13 17:00:12 GMT mtk02752 -+** add blank function for event packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-13 13:54:24 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-11 14:41:51 GMT mtk02752 -+** fix typo -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-11 14:33:46 GMT mtk02752 -+** add protection when there is no packet avilable -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-11 12:33:36 GMT mtk02752 -+** add RX1 read path for aggregated/enhanced/normal packet read procedures -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-11 10:36:18 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-04 14:11:08 GMT mtk01084 -+** modify lines in RX aggregation -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-30 18:17:23 GMT mtk01084 -+** modify RX aggregation handling -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-29 19:56:12 GMT mtk01084 -+** modify HAL part -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-10-23 16:08:34 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-10-13 21:59:20 GMT mtk01084 -+** update for new HW design -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-10-02 13:59:08 GMT mtk01725 -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-05-21 23:39:05 GMT mtk01461 -+** Fix the paste error of RX STATUS in OOB of HIF Loopback CTRL -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-05-20 12:25:32 GMT mtk01461 -+** Fix process of Read Done, and add u4MaxEventBufferLen to nicRxWaitResponse() -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-05-18 21:13:18 GMT mtk01426 -+** Fixed compiler error -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-18 21:05:29 GMT mtk01426 -+** Fixed nicRxSDIOAggReceiveRFBs() ASSERT issue -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-28 10:38:43 GMT mtk01461 -+** Fix RX STATUS is DW align for SDIO_STATUS_ENHANCE mode and refine nicRxSDIOAggeceiveRFBs() for RX Aggregation -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-22 09:12:17 GMT mtk01461 -+** Fix nicRxProcessHIFLoopbackPacket(), the size of HIF CTRL LENGTH field is 1 byte -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-14 15:51:26 GMT mtk01426 -+** Update RX OOB Setting -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-03 14:58:58 GMT mtk01426 -+** Fixed logical error -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:58:31 GMT mtk01461 -+** Rename the HIF_PKT_TYPE_DATA -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 21:51:18 GMT mtk01461 -+** Fix u4HeaderOffset in nicRxProcessHIFLoopbackPacket() -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 21:02:58 GMT mtk01426 -+** Add CFG_SDIO_RX_ENHANCE and CFG_HIF_LOOPBACK support -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:20:59 GMT mtk01426 -+** Add nicRxWaitResponse function -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:26:01 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#ifndef LINUX -+#include -+#else -+#include -+#endif -+ -+#include "gl_os.h" -+#include "debug.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include -+#include -+#include -+#include "gl_cfg80211.h" -+#include "gl_vendor.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define RX_RESPONSE_TIMEOUT (1000) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+#if CFG_MGMT_FRAME_HANDLING -+static PROCESS_RX_MGT_FUNCTION apfnProcessRxMgtFrame[MAX_NUM_OF_FC_SUBTYPES] = { -+#if CFG_SUPPORT_AAA -+ aaaFsmRunEventRxAssoc, /* subtype 0000: Association request */ -+#else -+ NULL, /* subtype 0000: Association request */ -+#endif /* CFG_SUPPORT_AAA */ -+ saaFsmRunEventRxAssoc, /* subtype 0001: Association response */ -+#if CFG_SUPPORT_AAA -+ aaaFsmRunEventRxAssoc, /* subtype 0010: Reassociation request */ -+#else -+ NULL, /* subtype 0010: Reassociation request */ -+#endif /* CFG_SUPPORT_AAA */ -+ saaFsmRunEventRxAssoc, /* subtype 0011: Reassociation response */ -+#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) -+ bssProcessProbeRequest, /* subtype 0100: Probe request */ -+#else -+ NULL, /* subtype 0100: Probe request */ -+#endif /* CFG_SUPPORT_ADHOC */ -+ scanProcessBeaconAndProbeResp, /* subtype 0101: Probe response */ -+ NULL, /* subtype 0110: reserved */ -+ NULL, /* subtype 0111: reserved */ -+ scanProcessBeaconAndProbeResp, /* subtype 1000: Beacon */ -+ NULL, /* subtype 1001: ATIM */ -+ saaFsmRunEventRxDisassoc, /* subtype 1010: Disassociation */ -+ authCheckRxAuthFrameTransSeq, /* subtype 1011: Authentication */ -+ saaFsmRunEventRxDeauth, /* subtype 1100: Deauthentication */ -+ nicRxProcessActionFrame, /* subtype 1101: Action */ -+ NULL, /* subtype 1110: reserved */ -+ NULL /* subtype 1111: reserved */ -+}; -+#endif -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialize the RFBs -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxInitialize(IN P_ADAPTER_T prAdapter) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ PUINT_8 pucMemHandle; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ UINT_32 i; -+ -+ DEBUGFUNC("nicRxInitialize"); -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ /* 4 <0> Clear allocated memory. */ -+ kalMemZero((PVOID) prRxCtrl->pucRxCached, prRxCtrl->u4RxCachedSize); -+ -+ /* 4 <1> Initialize the RFB lists */ -+ QUEUE_INITIALIZE(&prRxCtrl->rFreeSwRfbList); -+ QUEUE_INITIALIZE(&prRxCtrl->rReceivedRfbList); -+ QUEUE_INITIALIZE(&prRxCtrl->rIndicatedRfbList); -+ -+ pucMemHandle = prRxCtrl->pucRxCached; -+ for (i = CFG_RX_MAX_PKT_NUM; i != 0; i--) { -+ prSwRfb = (P_SW_RFB_T) pucMemHandle; -+ -+ nicRxSetupRFB(prAdapter, prSwRfb); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ -+ pucMemHandle += ALIGN_4(sizeof(SW_RFB_T)); -+ } -+ -+ ASSERT(prRxCtrl->rFreeSwRfbList.u4NumElem == CFG_RX_MAX_PKT_NUM); -+ /* Check if the memory allocation consist with this initialization function */ -+ ASSERT((ULONG) (pucMemHandle - prRxCtrl->pucRxCached) == prRxCtrl->u4RxCachedSize); -+ -+ /* 4 <2> Clear all RX counters */ -+ RX_RESET_ALL_CNTS(prRxCtrl); -+ -+#if CFG_SDIO_RX_AGG -+ prRxCtrl->pucRxCoalescingBufPtr = prAdapter->pucCoalescingBufCached; -+ HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, CFG_SDIO_MAX_RX_AGG_NUM); -+#else -+ HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, 1); -+#endif -+ -+#if CFG_HIF_STATISTICS -+ prRxCtrl->u4TotalRxAccessNum = 0; -+ prRxCtrl->u4TotalRxPacketNum = 0; -+#endif -+ -+#if CFG_HIF_RX_STARVATION_WARNING -+ prRxCtrl->u4QueuedCnt = 0; -+ prRxCtrl->u4DequeuedCnt = 0; -+#endif -+ -+} /* end of nicRxInitialize() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Uninitialize the RFBs -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxUninitialize(IN P_ADAPTER_T prAdapter) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ nicRxFlush(prAdapter); -+ -+ do { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rReceivedRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ if (prSwRfb) { -+ if (prSwRfb->pvPacket) -+ kalPacketFree(prAdapter->prGlueInfo, prSwRfb->pvPacket); -+ prSwRfb->pvPacket = NULL; -+ } else { -+ break; -+ } -+ } while (TRUE); -+ -+ do { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ if (prSwRfb) { -+ if (prSwRfb->pvPacket) -+ kalPacketFree(prAdapter->prGlueInfo, prSwRfb->pvPacket); -+ prSwRfb->pvPacket = NULL; -+ } else { -+ break; -+ } -+ } while (TRUE); -+ -+} /* end of nicRxUninitialize() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Fill RFB -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb specify the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxFillRFB(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ -+ UINT_32 u4PktLen = 0; -+ UINT_32 u4MacHeaderLen; -+ UINT_32 u4HeaderOffset; -+ -+ DEBUGFUNC("nicRxFillRFB"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ ASSERT(prHifRxHdr); -+ -+ u4PktLen = prHifRxHdr->u2PacketLen; -+ -+ u4HeaderOffset = (UINT_32) (prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK); -+ u4MacHeaderLen = (UINT_32) (prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_LEN) -+ >> HIF_RX_HDR_HEADER_LEN_OFFSET; -+ -+ /* DBGLOG(RX, TRACE, ("u4HeaderOffset = %d, u4MacHeaderLen = %d\n", */ -+ /* u4HeaderOffset, u4MacHeaderLen)); */ -+ -+ prSwRfb->u2HeaderLen = (UINT_16) u4MacHeaderLen; -+ prSwRfb->pvHeader = (PUINT_8) prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset; -+ prSwRfb->u2PacketLen = (UINT_16) (u4PktLen - (HIF_RX_HDR_SIZE + u4HeaderOffset)); -+ -+ /* DBGLOG(RX, TRACE, ("Dump Rx packet, u2PacketLen = %d\n", prSwRfb->u2PacketLen)); */ -+ /* DBGLOG_MEM8(RX, TRACE, prSwRfb->pvHeader, prSwRfb->u2PacketLen); */ -+ -+#if 0 -+ if (prHifRxHdr->ucReorder & HIF_RX_HDR_80211_HEADER_FORMAT) { -+ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_802_11_FORMAT; -+ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_802_11_FORMAT\n"); -+ } -+ -+ if (prHifRxHdr->ucReorder & HIF_RX_HDR_DO_REORDER) { -+ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_DO_REORDERING; -+ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_DO_REORDERING\n"); -+ -+ /* Get Seq. No and TID, Wlan Index info */ -+ if (prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_BAR_FRAME) { -+ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_BAR_FRAME; -+ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_BAR_FRAME\n"); -+ } -+ -+ prSwRfb->u2SSN = prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_SEQ_NO_MASK; -+ prSwRfb->ucTid = (UINT_8) ((prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_TID_MASK) -+ >> HIF_RX_HDR_TID_OFFSET); -+ DBGLOG(RX, TRACE, "u2SSN = %d, ucTid = %d\n", prSwRfb->u2SSN, prSwRfb->ucTid); -+ } -+ -+ if (prHifRxHdr->ucReorder & HIF_RX_HDR_WDS) { -+ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_AMP_WDS; -+ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_AMP_WDS\n"); -+ } -+#endif -+} -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Fill checksum status in RFB -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* @param u4TcpUdpIpCksStatus specify the Checksum status -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxFillChksumStatus(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb, IN UINT_32 u4TcpUdpIpCksStatus) -+{ -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ if (prAdapter->u4CSUMFlags != CSUM_NOT_SUPPORTED) { -+ if (u4TcpUdpIpCksStatus & RX_CS_TYPE_IPv4) { /* IPv4 packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_NONE; -+ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_IP) { /* IP packet csum failed */ -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_FAILED; -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_SUCCESS; -+ } -+ -+ if (u4TcpUdpIpCksStatus & RX_CS_TYPE_TCP) { /* TCP packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; -+ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_TCP) { /* TCP packet csum failed */ -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_FAILED; -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_SUCCESS; -+ } -+ } else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_UDP) { /* UDP packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; -+ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_UDP) { /* UDP packet csum failed */ -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_FAILED; -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_SUCCESS; -+ } -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; -+ } -+ } else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_IPv6) { /* IPv6 packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_NONE; -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_SUCCESS; -+ -+ if (u4TcpUdpIpCksStatus & RX_CS_TYPE_TCP) { /* TCP packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; -+ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_TCP) { /* TCP packet csum failed */ -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_FAILED; -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_SUCCESS; -+ } -+ } else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_UDP) { /* UDP packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; -+ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_UDP) { /* UDP packet csum failed */ -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_FAILED; -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_SUCCESS; -+ } -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; -+ } -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_NONE; -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_NONE; -+ } -+ } -+ -+} -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process packet doesn't need to do buffer reordering -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessPktWithoutReorder(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_TX_CTRL_T prTxCtrl; -+ BOOLEAN fgIsRetained = FALSE; -+ UINT_32 u4CurrentRxBufferCount; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ DEBUGFUNC("nicRxProcessPktWithoutReorder"); -+ /* DBGLOG(RX, TRACE, ("\n")); */ -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ ASSERT(prTxCtrl); -+ -+ u4CurrentRxBufferCount = prRxCtrl->rFreeSwRfbList.u4NumElem; -+ /* QM USED = $A, AVAILABLE COUNT = $B, INDICATED TO OS = $C -+ * TOTAL = $A + $B + $C -+ * -+ * Case #1 (Retain) -+ * ------------------------------------------------------- -+ * $A + $B < THRESHOLD := $A + $B + $C < THRESHOLD + $C := $TOTAL - THRESHOLD < $C -+ * => $C used too much, retain -+ * -+ * Case #2 (Non-Retain) -+ * ------------------------------------------------------- -+ * $A + $B > THRESHOLD := $A + $B + $C > THRESHOLD + $C := $TOTAL - THRESHOLD > $C -+ * => still available for $C to use -+ * -+ */ -+ fgIsRetained = (((u4CurrentRxBufferCount + -+ qmGetRxReorderQueuedBufferCount(prAdapter) + -+ prTxCtrl->i4PendingFwdFrameCount) < CFG_RX_RETAINED_PKT_THRESHOLD) ? TRUE : FALSE); -+ -+ /* DBGLOG(RX, INFO, ("fgIsRetained = %d\n", fgIsRetained)); */ -+ -+ if (kalProcessRxPacket(prAdapter->prGlueInfo, -+ prSwRfb->pvPacket, -+ prSwRfb->pvHeader, -+ (UINT_32) prSwRfb->u2PacketLen, fgIsRetained, prSwRfb->aeCSUM) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(RX, ERROR, "kalProcessRxPacket return value != WLAN_STATUS_SUCCESS\n"); -+ ASSERT(0); -+ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ return; -+ } -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prStaRec) { -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX && prAdapter->fgIsP2PRegistered == TRUE) -+ GLUE_SET_PKT_FLAG_P2P(prSwRfb->pvPacket); -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) -+ GLUE_SET_PKT_FLAG_PAL(prSwRfb->pvPacket); -+#endif -+ -+ /* record the count to pass to os */ -+ STATS_RX_PASS2OS_INC(prStaRec, prSwRfb); -+ } -+ prRxCtrl->apvIndPacket[prRxCtrl->ucNumIndPacket] = prSwRfb->pvPacket; -+ prRxCtrl->ucNumIndPacket++; -+ -+ if (fgIsRetained) { -+ prRxCtrl->apvRetainedPacket[prRxCtrl->ucNumRetainedPacket] = prSwRfb->pvPacket; -+ prRxCtrl->ucNumRetainedPacket++; -+ /* TODO : error handling of nicRxSetupRFB */ -+ nicRxSetupRFB(prAdapter, prSwRfb); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ } else { -+ prSwRfb->pvPacket = NULL; -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process forwarding data packet -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessForwardPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_MSDU_INFO_T prMsduInfo, prRetMsduInfoList; -+ P_TX_CTRL_T prTxCtrl; -+ P_RX_CTRL_T prRxCtrl; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxProcessForwardPkt"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_REMOVE_HEAD(&prTxCtrl->rFreeMsduInfoList, prMsduInfo, P_MSDU_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ -+ if (prMsduInfo && kalProcessRxPacket(prAdapter->prGlueInfo, -+ prSwRfb->pvPacket, -+ prSwRfb->pvHeader, -+ (UINT_32) prSwRfb->u2PacketLen, -+ prRxCtrl->rFreeSwRfbList.u4NumElem < -+ CFG_RX_RETAINED_PKT_THRESHOLD ? TRUE : FALSE, -+ prSwRfb->aeCSUM) == WLAN_STATUS_SUCCESS) { -+ -+ prMsduInfo->eSrc = TX_PACKET_FORWARDING; -+ /* pack into MSDU_INFO_T */ -+ nicTxFillMsduInfo(prAdapter, prMsduInfo, (P_NATIVE_PACKET) (prSwRfb->pvPacket)); -+ /* Overwrite the ucNetworkType */ -+ prMsduInfo->ucNetworkType = HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr); -+ -+ /* release RX buffer (to rIndicatedRfbList) */ -+ prSwRfb->pvPacket = NULL; -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ -+ /* increase forward frame counter */ -+ GLUE_INC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); -+ -+ /* send into TX queue */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ prRetMsduInfoList = qmEnqueueTxPackets(prAdapter, prMsduInfo); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ -+ if (prRetMsduInfoList != NULL) { /* TX queue refuses queuing the packet */ -+ nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfoList); -+ nicTxReturnMsduInfo(prAdapter, prRetMsduInfoList); -+ } -+ /* indicate service thread for sending */ -+ if (prTxCtrl->i4PendingFwdFrameCount > 0) -+ kalSetEvent(prAdapter->prGlueInfo); -+ } else /* no TX resource */ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process broadcast data packet for both host and forwarding -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessGOBroadcastPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_SW_RFB_T prSwRfbDuplicated; -+ P_TX_CTRL_T prTxCtrl; -+ P_RX_CTRL_T prRxCtrl; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxProcessGOBroadcastPkt"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ ASSERT(prHifRxHdr); -+ -+ ASSERT(CFG_NUM_OF_QM_RX_PKT_NUM >= 16); -+ -+ if (prRxCtrl->rFreeSwRfbList.u4NumElem -+ >= (CFG_RX_MAX_PKT_NUM - (CFG_NUM_OF_QM_RX_PKT_NUM - 16 /* Reserved for others */))) { -+ -+ /* 1. Duplicate SW_RFB_T */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfbDuplicated, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (prSwRfbDuplicated) { -+ kalMemCopy(prSwRfbDuplicated->pucRecvBuff, -+ prSwRfb->pucRecvBuff, ALIGN_4(prHifRxHdr->u2PacketLen + HIF_RX_HW_APPENDED_LEN)); -+ -+ prSwRfbDuplicated->ucPacketType = HIF_RX_PKT_TYPE_DATA; -+ prSwRfbDuplicated->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); -+ nicRxFillRFB(prAdapter, prSwRfbDuplicated); -+ -+ /* 2. Modify eDst */ -+ prSwRfbDuplicated->eDst = RX_PKT_DESTINATION_FORWARD; -+ -+ /* 4. Forward */ -+ nicRxProcessForwardPkt(prAdapter, prSwRfbDuplicated); -+ } -+ } else { -+ DBGLOG(RX, WARN, "Stop to forward BMC packet due to less free Sw Rfb %u\n", -+ prRxCtrl->rFreeSwRfbList.u4NumElem); -+ } -+ -+ /* 3. Indicate to host */ -+ prSwRfb->eDst = RX_PKT_DESTINATION_HOST; -+ nicRxProcessPktWithoutReorder(prAdapter, prSwRfb); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process HIF data packet -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessDataPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prRetSwRfb, prNextSwRfb; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_STA_RECORD_T prStaRec; -+ BOOLEAN fIsDummy = FALSE; -+ -+ DEBUGFUNC("nicRxProcessDataPacket"); -+ /* DBGLOG(RX, TRACE, ("\n")); */ -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ fIsDummy = (prHifRxHdr->u2PacketLen >= 12) ? FALSE : TRUE; -+ -+ nicRxFillRFB(prAdapter, prSwRfb); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 -+ { -+ UINT_32 u4TcpUdpIpCksStatus; -+ -+ u4TcpUdpIpCksStatus = *((PUINT_32) ((ULONG) prHifRxHdr + (UINT_32) (ALIGN_4(prHifRxHdr->u2PacketLen)))); -+ nicRxFillChksumStatus(prAdapter, prSwRfb, u4TcpUdpIpCksStatus); -+ -+ } -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prHifRxHdr->ucStaRecIdx); -+ if (secCheckClassError(prAdapter, prSwRfb, prStaRec) == TRUE && prAdapter->fgTestMode == FALSE) { -+#if CFG_HIF_RX_STARVATION_WARNING -+ prRxCtrl->u4QueuedCnt++; -+#endif -+ prRetSwRfb = qmHandleRxPackets(prAdapter, prSwRfb); -+ if (prRetSwRfb != NULL) { -+ do { -+ /* save next first */ -+ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prRetSwRfb); -+ if (fIsDummy == TRUE) { -+ nicRxReturnRFB(prAdapter, prRetSwRfb); -+ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); -+ DBGLOG(RX, WARN, "Drop Dummy Packets"); -+ -+ } else { -+ switch (prRetSwRfb->eDst) { -+ case RX_PKT_DESTINATION_HOST: -+#if ARP_MONITER_ENABLE -+ if (IS_STA_IN_AIS(prStaRec)) -+ qmHandleRxArpPackets(prAdapter, prRetSwRfb); -+#endif -+ nicRxProcessPktWithoutReorder(prAdapter, prRetSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_FORWARD: -+ nicRxProcessForwardPkt(prAdapter, prRetSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_HOST_WITH_FORWARD: -+ nicRxProcessGOBroadcastPkt(prAdapter, prRetSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_NULL: -+ nicRxReturnRFB(prAdapter, prRetSwRfb); -+ RX_INC_CNT(prRxCtrl, RX_DST_NULL_DROP_COUNT); -+ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); -+ break; -+ -+ default: -+ break; -+ } -+ } -+#if CFG_HIF_RX_STARVATION_WARNING -+ prRxCtrl->u4DequeuedCnt++; -+#endif -+ prRetSwRfb = prNextSwRfb; -+ } while (prRetSwRfb); -+ } -+ } else { -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ RX_INC_CNT(prRxCtrl, RX_CLASS_ERR_DROP_COUNT); -+ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process HIF event packet -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+UINT_8 nicRxProcessGSCNEvent(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_WIFI_EVENT_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ struct sk_buff *skb; -+ struct wiphy *wiphy; -+ -+ UINT_32 real_num = 0; -+ -+ P_EVENT_GSCAN_SCAN_AVAILABLE_T prEventGscnAvailable; -+ P_EVENT_GSCAN_RESULT_T prEventBuffer; -+ P_WIFI_GSCAN_RESULT_T prEventGscnResult; -+ INT_32 i4Status = -EINVAL; -+ struct nlattr *attr; -+ UINT_32 scan_id; -+ UINT_8 scan_flag; -+ P_EVENT_GSCAN_CAPABILITY_T prEventGscnCapbiblity; -+ P_EVENT_GSCAN_SCAN_COMPLETE_T prEventGscnScnDone; -+ P_WIFI_GSCAN_RESULT_T prEventGscnFullResult; -+ P_PARAM_WIFI_GSCAN_RESULT prParamGscnFullResult; -+ P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T prEventGscnSignificantChange; -+ P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T prEventGscnGeofenceFound; -+ -+ P_PARAM_WIFI_GSCAN_RESULT prResults; -+ -+ DEBUGFUNC("nicRxProcessGSCNEvent"); -+ /* DBGLOG(RX, TRACE, ("\n")); */ -+ -+ DBGLOG(SCN, INFO, "nicRxProcessGSCNEvent\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff; -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* Push the data to the skb */ -+ wiphy = priv_to_wiphy(prGlueInfo); -+ -+ /* prGlueInfo-> */ -+ -+ /* Event Handling */ -+ switch (prEvent->ucEID) { -+ case EVENT_ID_GSCAN_SCAN_AVAILABLE: -+ { -+ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_SCAN_AVAILABLE\n"); -+ -+ prEventGscnAvailable = (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer); -+ memcpy(prEventGscnAvailable, (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer), -+ sizeof(EVENT_GSCAN_SCAN_AVAILABLE_T)); -+ -+ mtk_cfg80211_vendor_event_scan_results_available(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, -+ prEventGscnAvailable->u2Num); -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_RESULT: -+ { -+ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_RESULT 2\n"); -+ -+ prEventBuffer = (P_EVENT_GSCAN_RESULT_T) (prEvent->aucBuffer); -+ prEventGscnResult = prEventBuffer->rResult; -+/* -+ the following event struct should moved to kal and use the kal api to avoid future porting effort -+ -+*/ -+ scan_id = prEventBuffer->u2ScanId; -+ scan_flag = prEventBuffer->u2ScanFlags; -+ real_num = prEventBuffer->u2NumOfResults; -+ -+ DBGLOG(SCN, INFO, "scan_id=%d, scan_flag =%d, real_num=%d\r\n", scan_id, scan_flag, real_num); -+ -+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(PARAM_WIFI_GSCAN_RESULT) * real_num); -+ if (!skb) { -+ DBGLOG(RX, TRACE, "%s allocate skb failed:%x\n", __func__, i4Status); -+ return -ENOMEM; -+ } -+ -+ attr = nla_nest_start(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS); -+ /*NLA_PUT_U32(skb, GSCAN_ATTRIBUTE_SCAN_ID, scan_id);*/ -+ { -+ unsigned int __tmp = scan_id; -+ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_ID, sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /*NLA_PUT_U8(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, 1);*/ -+ { -+ unsigned char __tmp = 1; -+ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, sizeof(u8), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /*NLA_PUT_U32(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS, real_num);*/ -+ { -+ unsigned int __tmp = real_num; -+ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ prResults = (P_PARAM_WIFI_GSCAN_RESULT) prEventGscnResult; -+ if (prResults) -+ DBGLOG(SCN, INFO, "ssid=%s, rssi=%d, channel=%d \r\n", -+ prResults->ssid, prResults->rssi, prResults->channel); -+ /*NLA_PUT(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS, sizeof(PARAM_WIFI_GSCAN_RESULT) * real_num, -+ prResults);*/ -+ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS, -+ sizeof(PARAM_WIFI_GSCAN_RESULT)*real_num, prResults) < 0)) -+ goto nla_put_failure; -+ -+ DBGLOG(SCN, INFO, "NLA_PUT scan results over\t"); -+ -+ if (attr) -+ nla_nest_end(skb, attr); -+ /* report_events=1 */ -+ /*NLA_PUT_U8(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, 1);*/ -+ { -+ unsigned char __tmp = 1; -+ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ i4Status = cfg80211_vendor_cmd_reply(skb); -+ skb = NULL; -+ DBGLOG(SCN, INFO, " i4Status %d\n", i4Status); -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_CAPABILITY: -+ { -+ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_CAPABILITY\n"); -+ -+ prEventGscnCapbiblity = (P_EVENT_GSCAN_CAPABILITY_T) (prEvent->aucBuffer); -+ memcpy(prEventGscnCapbiblity, (P_EVENT_GSCAN_CAPABILITY_T) (prEvent->aucBuffer), -+ sizeof(EVENT_GSCAN_CAPABILITY_T)); -+ -+ mtk_cfg80211_vendor_get_gscan_capabilities(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, -+ prEventGscnCapbiblity, sizeof(EVENT_GSCAN_CAPABILITY_T)); -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_SCAN_COMPLETE: -+ { -+ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_SCAN_COMPLETE\n"); -+ prEventGscnScnDone = (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer); -+ memcpy(prEventGscnScnDone, (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer), -+ sizeof(EVENT_GSCAN_SCAN_COMPLETE_T)); -+ -+ mtk_cfg80211_vendor_event_complete_scan(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, -+ prEventGscnScnDone->ucScanState); -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_FULL_RESULT: -+ { -+ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_FULL_RESULT\n"); -+ -+ prEventGscnFullResult = kalMemAlloc(sizeof(WIFI_GSCAN_RESULT_T), VIR_MEM_TYPE); -+ if (prEventGscnFullResult) -+ memcpy(prEventGscnFullResult, (P_WIFI_GSCAN_RESULT_T) (prEvent->aucBuffer), -+ sizeof(WIFI_GSCAN_RESULT_T)); -+ -+ prParamGscnFullResult = kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_RESULT), VIR_MEM_TYPE); -+ if (prEventGscnFullResult && prParamGscnFullResult) { -+ kalMemZero(prParamGscnFullResult, sizeof(PARAM_WIFI_GSCAN_RESULT)); -+ memcpy(prParamGscnFullResult, prEventGscnFullResult, sizeof(WIFI_GSCAN_RESULT_T)); -+ -+ mtk_cfg80211_vendor_event_full_scan_results(wiphy, -+ prGlueInfo->prDevHandler->ieee80211_ptr, -+ prParamGscnFullResult, -+ sizeof(PARAM_WIFI_GSCAN_RESULT)); -+ } -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_SIGNIFICANT_CHANGE: -+ { -+ prEventGscnSignificantChange = (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer); -+ memcpy(prEventGscnSignificantChange, (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer), -+ sizeof(EVENT_GSCAN_SIGNIFICANT_CHANGE_T)); -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_GEOFENCE_FOUND: -+ { -+ prEventGscnGeofenceFound = (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer); -+ memcpy(prEventGscnGeofenceFound, (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer), -+ sizeof(EVENT_GSCAN_SIGNIFICANT_CHANGE_T)); -+ } -+ break; -+ -+ default: -+ DBGLOG(SCN, INFO, "not GSCN event ????\n"); -+ break; -+ } -+ -+ DBGLOG(SCN, INFO, "Done with GSCN event handling\n"); -+ return real_num; /* cfg80211_vendor_cmd_reply(skb); */ -+ -+nla_put_failure: -+ if (skb != NULL) -+ kfree_skb(skb); -+ DBGLOG(SCN, INFO, "nla_put_failure\n"); -+ return 0; /* cfg80211_vendor_cmd_reply(skb); */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process HIF event packet -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ P_WIFI_EVENT_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ DEBUGFUNC("nicRxProcessEventPacket"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff; -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ DBGLOG(RX, EVENT, "prEvent->ucEID = 0x%02x\n", prEvent->ucEID); -+ /* Event Handling */ -+ switch (prEvent->ucEID) { -+ case EVENT_ID_CMD_RESULT: -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ P_EVENT_CMD_RESULT prCmdResult; -+ -+ prCmdResult = (P_EVENT_CMD_RESULT) ((PUINT_8) prEvent + EVENT_HDR_SIZE); -+ -+ /* CMD_RESULT should be only in response to Set commands */ -+ ASSERT(prCmdInfo->fgSetQuery == FALSE || prCmdInfo->fgNeedResp == TRUE); -+ -+ if (prCmdResult->ucStatus == 0) { /* success */ -+ if (prCmdInfo->pfCmdDoneHandler) { -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ } else if (prCmdInfo->fgIsOid == TRUE) { -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, -+ WLAN_STATUS_SUCCESS); -+ } -+ } else if (prCmdResult->ucStatus == 1) { /* reject */ -+ if (prCmdInfo->fgIsOid == TRUE) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, -+ WLAN_STATUS_FAILURE); -+ } else if (prCmdResult->ucStatus == 2) { /* unknown CMD */ -+ if (prCmdInfo->fgIsOid == TRUE) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, -+ WLAN_STATUS_NOT_SUPPORTED); -+ } -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ -+ break; -+ -+#if 0 -+ case EVENT_ID_CONNECTION_STATUS: -+ /* OBSELETE */ -+ { -+ P_EVENT_CONNECTION_STATUS prConnectionStatus; -+ -+ prConnectionStatus = (P_EVENT_CONNECTION_STATUS) (prEvent->aucBuffer); -+ -+ DbgPrint("RX EVENT: EVENT_ID_CONNECTION_STATUS = %d\n", prConnectionStatus->ucMediaStatus); -+ if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_DISCONNECTED) { -+ /* disconnected */ -+ if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { -+ -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ -+ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); -+ } -+ } else if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_CONNECTED) { -+ /* connected */ -+ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); -+ -+ /* fill information for association result */ -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen = prConnectionStatus->ucSsidLen; -+ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, -+ prConnectionStatus->aucSsid, prConnectionStatus->ucSsidLen); -+ -+ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, -+ prConnectionStatus->aucBssid, MAC_ADDR_LEN); -+ -+ /* @FIXME */ -+ prAdapter->rWlanInfo.rCurrBssId.u4Privacy = prConnectionStatus->ucEncryptStatus; -+ prAdapter->rWlanInfo.rCurrBssId.rRssi = 0; /* @FIXME */ -+ /* @FIXME */ -+ prAdapter->rWlanInfo.rCurrBssId.eNetworkTypeInUse = PARAM_NETWORK_TYPE_AUTOMODE; -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod -+ = prConnectionStatus->u2BeaconPeriod; -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4ATIMWindow -+ = prConnectionStatus->u2ATIMWindow; -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4DSConfig -+ = prConnectionStatus->u4FreqInKHz; -+ prAdapter->rWlanInfo.ucNetworkType = prConnectionStatus->ucNetworkType; -+ -+ switch (prConnectionStatus->ucInfraMode) { -+ case 0: -+ prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_IBSS; -+ break; -+ case 1: -+ prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_INFRA; -+ break; -+ case 2: -+ default: -+ prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_AUTO_SWITCH; -+ break; -+ } -+ /* always indicate to OS according to MSDN (re-association/roaming) */ -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, NULL, 0); -+ } -+ } -+ break; -+ -+ case EVENT_ID_SCAN_RESULT: -+ /* OBSELETE */ -+ break; -+#endif -+ -+ case EVENT_ID_RX_ADDBA: -+ /* The FW indicates that an RX BA agreement will be established */ -+ qmHandleEventRxAddBa(prAdapter, prEvent); -+ break; -+ -+ case EVENT_ID_RX_DELBA: -+ /* The FW indicates that an RX BA agreement has been deleted */ -+ qmHandleEventRxDelBa(prAdapter, prEvent); -+ break; -+ -+ case EVENT_ID_LINK_QUALITY: -+#if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY -+ if (prEvent->u2PacketLen == EVENT_HDR_SIZE + sizeof(EVENT_LINK_QUALITY_EX)) { -+ P_EVENT_LINK_QUALITY_EX prLqEx = (P_EVENT_LINK_QUALITY_EX) (prEvent->aucBuffer); -+ -+ if (prLqEx->ucIsLQ0Rdy) -+ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, (P_EVENT_LINK_QUALITY) prLqEx); -+ if (prLqEx->ucIsLQ1Rdy) -+ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_P2P_INDEX, (P_EVENT_LINK_QUALITY) prLqEx); -+ } else { -+ /* For old FW, P2P may invoke link quality query, and make driver flag becone TRUE. */ -+ DBGLOG(P2P, WARN, "Old FW version, not support P2P RSSI query.\n"); -+ -+ /* Must not use NETWORK_TYPE_P2P_INDEX, cause the structure is mismatch. */ -+ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, -+ (P_EVENT_LINK_QUALITY) (prEvent->aucBuffer)); -+ } -+#else -+ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, (P_EVENT_LINK_QUALITY) (prEvent->aucBuffer)); -+#endif -+ -+ /* command response handling */ -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ if (prCmdInfo->pfCmdDoneHandler) -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ else if (prCmdInfo->fgIsOid) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+#ifndef LINUX -+ if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_GREATER && -+ prAdapter->rWlanInfo.rRssiTriggerValue >= (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) { -+ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED; -+ -+ kalIndicateStatusAndComplete(prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID)&(prAdapter->rWlanInfo.rRssiTriggerValue), -+ sizeof(PARAM_RSSI)); -+ } else if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_LESS -+ && prAdapter->rWlanInfo.rRssiTriggerValue <= (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) { -+ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED; -+ -+ kalIndicateStatusAndComplete(prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID)&(prAdapter->rWlanInfo.rRssiTriggerValue), -+ sizeof(PARAM_RSSI)); -+ } -+#endif -+ -+ break; -+ -+ case EVENT_ID_MIC_ERR_INFO: -+ { -+ P_EVENT_MIC_ERR_INFO prMicError; -+ /* P_PARAM_AUTH_EVENT_T prAuthEvent; */ -+ P_STA_RECORD_T prStaRec; -+ -+ DBGLOG(RSN, EVENT, "EVENT_ID_MIC_ERR_INFO\n"); -+ -+ prMicError = (P_EVENT_MIC_ERR_INFO) (prEvent->aucBuffer); -+ prStaRec = cnmGetStaRecByAddress(prAdapter, -+ (UINT_8) NETWORK_TYPE_AIS_INDEX, -+ prAdapter->rWlanInfo.rCurrBssId.arMacAddress); -+ ASSERT(prStaRec); -+ -+ if (prStaRec) -+ rsnTkipHandleMICFailure(prAdapter, prStaRec, (BOOLEAN) prMicError->u4Flags); -+ else -+ DBGLOG(RSN, WARN, "No STA rec!!\n"); -+#if 0 -+ prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer; -+ -+ /* Status type: Authentication Event */ -+ prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION; -+ -+ /* Authentication request */ -+ prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T); -+ kalMemCopy((PVOID) prAuthEvent->arRequest[0].arBssid, -+ (PVOID) prAdapter->rWlanInfo.rCurrBssId.arMacAddress, -+ /* whsu:Todo? */PARAM_MAC_ADDR_LEN); -+ -+ if (prMicError->u4Flags != 0) -+ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR; -+ else -+ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID) prAuthEvent, -+ sizeof(PARAM_STATUS_INDICATION_T) + sizeof(PARAM_AUTH_REQUEST_T)); -+#endif -+ } -+ break; -+ -+ case EVENT_ID_ASSOC_INFO: -+ { -+ P_EVENT_ASSOC_INFO prAssocInfo; -+ -+ prAssocInfo = (P_EVENT_ASSOC_INFO) (prEvent->aucBuffer); -+ -+ kalHandleAssocInfo(prAdapter->prGlueInfo, prAssocInfo); -+ } -+ break; -+ -+ case EVENT_ID_802_11_PMKID: -+ { -+ P_PARAM_AUTH_EVENT_T prAuthEvent; -+ PUINT_8 cp; -+ UINT_32 u4LenOfUsedBuffer; -+ -+ prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer; -+ -+ prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST; -+ -+ u4LenOfUsedBuffer = (UINT_32) (prEvent->u2PacketLen - 8); -+ -+ prAuthEvent->arRequest[0].u4Length = u4LenOfUsedBuffer; -+ -+ cp = (PUINT_8) &prAuthEvent->arRequest[0]; -+ -+ /* Status type: PMKID Candidatelist Event */ -+ kalMemCopy(cp, (P_EVENT_PMKID_CANDIDATE_LIST_T) (prEvent->aucBuffer), prEvent->u2PacketLen - 8); -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID) prAuthEvent, -+ sizeof(PARAM_STATUS_INDICATION_T) + u4LenOfUsedBuffer); -+ } -+ break; -+ -+#if 0 -+ case EVENT_ID_ACTIVATE_STA_REC_T: -+ { -+ P_EVENT_ACTIVATE_STA_REC_T prActivateStaRec; -+ -+ prActivateStaRec = (P_EVENT_ACTIVATE_STA_REC_T) (prEvent->aucBuffer); -+ -+ DbgPrint("RX EVENT: EVENT_ID_ACTIVATE_STA_REC_T Index:%d, MAC:[%pM]\n", -+ prActivateStaRec->ucStaRecIdx, prActivateStaRec->aucMacAddr); -+ -+ qmActivateStaRec(prAdapter, -+ (UINT_32) prActivateStaRec->ucStaRecIdx, -+ ((prActivateStaRec->fgIsQoS) ? TRUE : FALSE), -+ prActivateStaRec->ucNetworkTypeIndex, -+ ((prActivateStaRec->fgIsAP) ? TRUE : FALSE), prActivateStaRec->aucMacAddr); -+ -+ } -+ break; -+ -+ case EVENT_ID_DEACTIVATE_STA_REC_T: -+ { -+ P_EVENT_DEACTIVATE_STA_REC_T prDeactivateStaRec; -+ -+ prDeactivateStaRec = (P_EVENT_DEACTIVATE_STA_REC_T) (prEvent->aucBuffer); -+ -+ DbgPrint("RX EVENT: EVENT_ID_DEACTIVATE_STA_REC_T Index:%d, MAC:[%pM]\n", -+ prDeactivateStaRec->ucStaRecIdx, prActivateStaRec->aucMacAddr); -+ -+ qmDeactivateStaRec(prAdapter, prDeactivateStaRec->ucStaRecIdx); -+ } -+ break; -+#endif -+ -+ case EVENT_ID_SCAN_DONE: -+ scnEventScanDone(prAdapter, (P_EVENT_SCAN_DONE) (prEvent->aucBuffer)); -+ break; -+ -+ case EVENT_ID_TX_DONE_STATUS: -+ STATS_TX_PKT_DONE_INFO_DISPLAY(prAdapter, prEvent->aucBuffer); -+ break; -+ -+ case EVENT_ID_TX_DONE: -+ { -+ P_EVENT_TX_DONE_T prTxDone; -+ -+ prTxDone = (P_EVENT_TX_DONE_T) (prEvent->aucBuffer); -+ if (prTxDone->ucStatus) -+ DBGLOG(RX, INFO, "EVENT_ID_TX_DONE PacketSeq:%u ucStatus: %u SN: %u\n", -+ prTxDone->ucPacketSeq, prTxDone->ucStatus, prTxDone->u2SequenceNumber); -+ -+ /* call related TX Done Handler */ -+ prMsduInfo = nicGetPendingTxMsduInfo(prAdapter, prTxDone->ucPacketSeq); -+ -+#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT -+ DBGLOG(RX, TRACE, "EVENT_ID_TX_DONE u4TimeStamp = %x u2AirDelay = %x\n", -+ prTxDone->au4Reserved1, prTxDone->au4Reserved2); -+ -+ wnmReportTimingMeas(prAdapter, prMsduInfo->ucStaRecIndex, -+ prTxDone->au4Reserved1, prTxDone->au4Reserved1 + prTxDone->au4Reserved2); -+#endif -+ -+ if (prMsduInfo) { -+ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, -+ (ENUM_TX_RESULT_CODE_T) (prTxDone->ucStatus)); -+ -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ } -+ } -+ break; -+ case EVENT_ID_SLEEPY_NOTIFY: -+ { -+ P_EVENT_SLEEPY_NOTIFY prEventSleepyNotify; -+ -+ prEventSleepyNotify = (P_EVENT_SLEEPY_NOTIFY) (prEvent->aucBuffer); -+ -+ /* DBGLOG(RX, INFO, ("ucSleepyState = %d\n", prEventSleepyNotify->ucSleepyState)); */ -+ -+ prAdapter->fgWiFiInSleepyState = (BOOLEAN) (prEventSleepyNotify->ucSleepyState); -+ } -+ break; -+ case EVENT_ID_BT_OVER_WIFI: -+#if CFG_ENABLE_BT_OVER_WIFI -+ { -+ UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)]; -+ P_EVENT_BT_OVER_WIFI prEventBtOverWifi; -+ P_AMPC_EVENT prBowEvent; -+ P_BOW_LINK_CONNECTED prBowLinkConnected; -+ P_BOW_LINK_DISCONNECTED prBowLinkDisconnected; -+ -+ prEventBtOverWifi = (P_EVENT_BT_OVER_WIFI) (prEvent->aucBuffer); -+ -+ /* construct event header */ -+ prBowEvent = (P_AMPC_EVENT) aucTmp; -+ -+ if (prEventBtOverWifi->ucLinkStatus == 0) { -+ /* Connection */ -+ prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED; -+ prBowEvent->rHeader.ucSeqNumber = 0; -+ prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED); -+ -+ /* fill event body */ -+ prBowLinkConnected = (P_BOW_LINK_CONNECTED) (prBowEvent->aucPayload); -+ prBowLinkConnected->rChannel.ucChannelNum = prEventBtOverWifi->ucSelectedChannel; -+ kalMemZero(prBowLinkConnected->aucPeerAddress, MAC_ADDR_LEN); /* @FIXME */ -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent); -+ } else { -+ /* Disconnection */ -+ prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED; -+ prBowEvent->rHeader.ucSeqNumber = 0; -+ prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED); -+ -+ /* fill event body */ -+ prBowLinkDisconnected = (P_BOW_LINK_DISCONNECTED) (prBowEvent->aucPayload); -+ prBowLinkDisconnected->ucReason = 0; /* @FIXME */ -+ kalMemZero(prBowLinkDisconnected->aucPeerAddress, MAC_ADDR_LEN); /* @FIXME */ -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent); -+ } -+ } -+ break; -+#endif -+ case EVENT_ID_STATISTICS: -+ /* buffer statistics for further query */ -+ prAdapter->fgIsStatValid = TRUE; -+ prAdapter->rStatUpdateTime = kalGetTimeTick(); -+ kalMemCopy(&prAdapter->rStatStruct, prEvent->aucBuffer, sizeof(EVENT_STATISTICS)); -+ -+ /* command response handling */ -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ if (prCmdInfo->pfCmdDoneHandler) -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ else if (prCmdInfo->fgIsOid) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ -+ break; -+ -+ case EVENT_ID_CH_PRIVILEGE: -+ cnmChMngrHandleChEvent(prAdapter, prEvent); -+ break; -+ -+ case EVENT_ID_BSS_ABSENCE_PRESENCE: -+ qmHandleEventBssAbsencePresence(prAdapter, prEvent); -+ break; -+ -+ case EVENT_ID_STA_CHANGE_PS_MODE: -+ qmHandleEventStaChangePsMode(prAdapter, prEvent); -+ break; -+#if CFG_ENABLE_WIFI_DIRECT -+ case EVENT_ID_STA_UPDATE_FREE_QUOTA: -+ qmHandleEventStaUpdateFreeQuota(prAdapter, prEvent); -+ break; -+#endif -+ case EVENT_ID_BSS_BEACON_TIMEOUT: -+ if (prAdapter->fgDisBcnLostDetection == FALSE) { -+ P_EVENT_BSS_BEACON_TIMEOUT_T prEventBssBeaconTimeout; -+ -+ prEventBssBeaconTimeout = (P_EVENT_BSS_BEACON_TIMEOUT_T) (prEvent->aucBuffer); -+ -+ DBGLOG(RX, INFO, "Beacon Timeout Reason = %u\n", prEventBssBeaconTimeout->ucReason); -+ -+ if (prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+ /* Request stats report before beacon timeout */ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ if (prBssInfo) { -+ prStaRec = cnmGetStaRecByAddress(prAdapter, -+ NETWORK_TYPE_AIS_INDEX, -+ prBssInfo->aucBSSID); -+ if (prStaRec) -+ STATS_ENV_REPORT_DETECT(prAdapter, prStaRec->ucIndex); -+ } -+ aisBssBeaconTimeout(prAdapter); -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && -+ (prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX)) -+ -+ p2pFsmRunEventBeaconTimeout(prAdapter); -+#endif -+ else { -+ DBGLOG(RX, ERROR, "EVENT_ID_BSS_BEACON_TIMEOUT: (ucNetTypeIdx = %d)\n", -+ prEventBssBeaconTimeout->ucNetTypeIndex); -+ } -+ } -+ -+ break; -+ case EVENT_ID_UPDATE_NOA_PARAMS: -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) { -+ P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam; -+ -+ prEventUpdateNoaParam = (P_EVENT_UPDATE_NOA_PARAMS_T) (prEvent->aucBuffer); -+ -+ if (prEventUpdateNoaParam->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ p2pProcessEvent_UpdateNOAParam(prAdapter, -+ prEventUpdateNoaParam->ucNetTypeIndex, -+ prEventUpdateNoaParam); -+ } else { -+ ASSERT(0); -+ } -+ } -+#else -+ ASSERT(0); -+#endif -+ break; -+ -+ case EVENT_ID_STA_AGING_TIMEOUT: -+#if CFG_ENABLE_WIFI_DIRECT -+ { -+ if (prAdapter->fgDisStaAgingTimeoutDetection == FALSE) { -+ P_EVENT_STA_AGING_TIMEOUT_T prEventStaAgingTimeout; -+ P_STA_RECORD_T prStaRec; -+ P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL; -+ -+ prEventStaAgingTimeout = (P_EVENT_STA_AGING_TIMEOUT_T) (prEvent->aucBuffer); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prEventStaAgingTimeout->ucStaRecIdx); -+ if (prStaRec == NULL) -+ break; -+ -+ DBGLOG(RX, INFO, "EVENT_ID_STA_AGING_TIMEOUT %u %pM\n", -+ prEventStaAgingTimeout->ucStaRecIdx, -+ prStaRec->aucMacAddr); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); -+ -+ /* Call False Auth */ -+ if (prAdapter->fgIsP2PRegistered) -+ p2pFuncDisconnect(prAdapter, prStaRec, TRUE, REASON_CODE_DISASSOC_INACTIVITY); -+ -+ } -+ /* gDisStaAgingTimeoutDetection */ -+ } -+#endif -+ break; -+ -+ case EVENT_ID_AP_OBSS_STATUS: -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ rlmHandleObssStatusEventPkt(prAdapter, (P_EVENT_AP_OBSS_STATUS_T) prEvent->aucBuffer); -+#endif -+ break; -+ -+ case EVENT_ID_ROAMING_STATUS: -+#if CFG_SUPPORT_ROAMING -+ { -+ P_ROAMING_PARAM_T prParam; -+ -+ prParam = (P_ROAMING_PARAM_T) (prEvent->aucBuffer); -+ roamingFsmProcessEvent(prAdapter, prParam); -+ } -+#endif /* CFG_SUPPORT_ROAMING */ -+ break; -+ case EVENT_ID_SEND_DEAUTH: -+ { -+ P_WLAN_MAC_HEADER_T prWlanMacHeader; -+ P_STA_RECORD_T prStaRec; -+ -+ prWlanMacHeader = (P_WLAN_MAC_HEADER_T) &prEvent->aucBuffer[0]; -+ DBGLOG(RSN, INFO, "nicRx: aucAddr1: %pM, nicRx: aucAddr2: %pM\n", -+ prWlanMacHeader->aucAddr1, prWlanMacHeader->aucAddr2); -+ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prWlanMacHeader->aucAddr2); -+ if (prStaRec != NULL && prStaRec->ucStaState == STA_STATE_3) { -+ DBGLOG(RSN, WARN, "Ignore Deauth for Rx Class 3 error!\n"); -+ } else { -+ /* receive packets without StaRec */ -+ prSwRfb->pvHeader = (P_WLAN_MAC_HEADER_T) &prEvent->aucBuffer[0]; -+ if (WLAN_STATUS_SUCCESS == authSendDeauthFrame(prAdapter, -+ NULL, -+ prSwRfb, -+ REASON_CODE_CLASS_3_ERR, -+ (PFN_TX_DONE_HANDLER) NULL)) -+ DBGLOG(RSN, INFO, "Send Deauth for Rx Class3 Error\n"); -+ else -+ DBGLOG(RSN, WARN, "failed to send deauth for Rx class3 error\n"); -+ } -+ } -+ break; -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ case EVENT_ID_UPDATE_RDD_STATUS: -+ { -+ P_EVENT_RDD_STATUS_T prEventRddStatus; -+ -+ prEventRddStatus = (P_EVENT_RDD_STATUS_T) (prEvent->aucBuffer); -+ -+ prAdapter->ucRddStatus = prEventRddStatus->ucRddStatus; -+ } -+ -+ break; -+#endif -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+ case EVENT_ID_UPDATE_BWCS_STATUS: -+ { -+ P_PTA_IPC_T prEventBwcsStatus; -+ -+ prEventBwcsStatus = (P_PTA_IPC_T) (prEvent->aucBuffer); -+ -+#if CFG_SUPPORT_BCM_BWCS_DEBUG -+ DBGLOG(RSN, INFO, -+ "BCM BWCS Event: %02x%02x%02x%02x\n", -+ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], -+ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]); -+ -+ DBGLOG(RSN, INFO, -+ "BCM BWCS Event: BTPParams[0]:%02x, BTPParams[1]:%02x, BTPParams[2]:%02x, BTPParams[3]:%02x\n", -+ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], -+ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]); -+#endif -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_BWCS_UPDATE, -+ (PVOID) prEventBwcsStatus, sizeof(PTA_IPC_T)); -+ } -+ -+ break; -+ -+ case EVENT_ID_UPDATE_BCM_DEBUG: -+ { -+ P_PTA_IPC_T prEventBwcsStatus; -+ -+ prEventBwcsStatus = (P_PTA_IPC_T) (prEvent->aucBuffer); -+ -+#if CFG_SUPPORT_BCM_BWCS_DEBUG -+ DBGLOG(RSN, INFO, -+ "BCM FW status: %02x%02x%02x%02x\n", -+ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], -+ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]); -+ -+ DBGLOG(RSN, INFO, -+ "BCM FW status: BTPParams[0]:%02x, BTPParams[1]:%02x, BTPParams[2]:%02x, BTPParams[3]:%02x\n", -+ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], -+ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]; -+#endif -+ } -+ -+ break; -+#endif -+ -+ case EVENT_ID_DEBUG_CODE: /* only for debug */ -+ { -+ UINT_32 u4CodeId; -+ -+ DBGLOG(RSN, INFO, "[wlan-fw] function sequence: "); -+ for (u4CodeId = 0; u4CodeId < 1000; u4CodeId++) -+ DBGLOG(RSN, INFO, "%d ", prEvent->aucBuffer[u4CodeId]); -+ DBGLOG(RSN, INFO, "\n\n"); -+ } -+ break; -+ -+ case EVENT_ID_RFTEST_READY: -+ -+ /* command response handling */ -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ if (prCmdInfo->pfCmdDoneHandler) -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ else if (prCmdInfo->fgIsOid) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ -+ break; -+ -+ case EVENT_ID_GSCAN_SCAN_AVAILABLE: -+ case EVENT_ID_GSCAN_CAPABILITY: -+ case EVENT_ID_GSCAN_SCAN_COMPLETE: -+ case EVENT_ID_GSCAN_FULL_RESULT: -+ case EVENT_ID_GSCAN_SIGNIFICANT_CHANGE: -+ case EVENT_ID_GSCAN_GEOFENCE_FOUND: -+ nicRxProcessGSCNEvent(prAdapter, prSwRfb); -+ break; -+ -+ case EVENT_ID_GSCAN_RESULT: -+ { -+ -+ UINT_8 realnum = 0; -+ -+ DBGLOG(SCN, TRACE, "nicRxProcessGSCNEvent ----->\n"); -+ realnum = nicRxProcessGSCNEvent(prAdapter, prSwRfb); -+ DBGLOG(SCN, TRACE, "nicRxProcessGSCNEvent <-----\n"); -+ -+#if 0 /* workaround for FW events cnt mis-match with the actual reqirements from wifi_hal */ -+ if (g_GetResultsCmdCnt == 0) { -+ DBGLOG(SCN, INFO, -+ "FW report events more than the wifi_hal asked number, buffer the results\n"); -+ UINT_8 i = 0; -+ -+ for (i = 0; i < MAX_BUFFERED_GSCN_RESULTS; i++) { -+#if 1 -+ if (!g_arGscanResultsIndicateNumber[i]) { -+ DBGLOG(SCN, INFO, -+ "found available index %d to insert results number %d into buffer\r\n", -+ i, realnum); -+ -+ g_arGscnResultsTempBuffer[i] = prSwRfb; -+ g_arGscanResultsIndicateNumber[i] = realnum; -+ g_GetResultsBufferedCnt++; -+ fgKeepprSwRfb = TRUE; -+ DBGLOG(SCN, INFO, "results buffered in index[%d] \r\n", i); -+ break; -+ } -+#endif -+ } -+ if (i == MAX_BUFFERED_GSCN_RESULTS) -+ DBGLOG(SCN, INFO, -+ "Gscn results buffer is full(all valid), no space to buffer result\r\n"); -+ } else if (g_GetResultsCmdCnt > 0) { -+ DBGLOG(SCN, INFO, "FW report events match the wifi_hal asked number\n"); -+ g_GetResultsCmdCnt--; -+ } else -+ DBGLOG(SCN, INFO, "g_GetResultsCmdCnt < 0 ??? unexpected case\n"); -+#endif -+ /* end of workaround */ -+ -+ } -+ break; -+ -+ case EVENT_ID_NLO_DONE: -+ prAdapter->rWifiVar.rScanInfo.fgPscnOnnning = FALSE; -+ -+ DBGLOG(INIT, INFO, "EVENT_ID_NLO_DONE\n"); -+ scnEventNloDone(prAdapter, (P_EVENT_NLO_DONE_T) (prEvent->aucBuffer)); -+ -+ break; -+ -+#if CFG_SUPPORT_BATCH_SCAN -+ case EVENT_ID_BATCH_RESULT: -+ DBGLOG(SCN, TRACE, "Got EVENT_ID_BATCH_RESULT"); -+ -+ /* command response handling */ -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ if (prCmdInfo->pfCmdDoneHandler) -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ else if (prCmdInfo->fgIsOid) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ -+ break; -+#endif /* CFG_SUPPORT_BATCH_SCAN */ -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ case EVENT_ID_TDLS: -+ TdlsexEventHandle(prAdapter->prGlueInfo, -+ (UINT8 *) prEvent->aucBuffer, (UINT32) (prEvent->u2PacketLen - 8)); -+ break; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+#if (CFG_SUPPORT_STATISTICS == 1) -+ case EVENT_ID_STATS_ENV: -+ statsEventHandle(prAdapter->prGlueInfo, -+ (UINT8 *) prEvent->aucBuffer, (UINT32) (prEvent->u2PacketLen - 8)); -+ break; -+#endif /* CFG_SUPPORT_STATISTICS */ -+ -+ case EVENT_ID_FW_LOG_ENV: -+ { -+ P_EVENT_FW_LOG_T prEventLog; -+ -+ prEventLog = (P_EVENT_FW_LOG_T) (prEvent->aucBuffer); -+ DBGLOG(RX, INFO, "[F-L]%s\n", prEventLog->log); -+ } -+ break; -+ -+ default: -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ if (prCmdInfo->pfCmdDoneHandler) -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ else if (prCmdInfo->fgIsOid) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ -+ break; -+ } -+ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief nicRxProcessMgmtPacket is used to dispatch management frames -+* to corresponding modules -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessMgmtPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ UINT_8 ucSubtype; -+#if CFG_SUPPORT_802_11W -+ BOOLEAN fgMfgDrop = FALSE; -+#endif -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ nicRxFillRFB(prAdapter, prSwRfb); -+ -+ ucSubtype = (*(PUINT_8) (prSwRfb->pvHeader) & MASK_FC_SUBTYPE) >> OFFSET_OF_FC_SUBTYPE; -+ -+#if 0 /* CFG_RX_PKTS_DUMP */ -+ { -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_16 u2TxFrameCtrl; -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ u2TxFrameCtrl = (*(PUINT_8) (prSwRfb->pvHeader) & MASK_FRAME_TYPE); -+ /* if (prAdapter->rRxCtrl.u4RxPktsDumpTypeMask & BIT(HIF_RX_PKT_TYPE_MANAGEMENT)) { */ -+ /* if (u2TxFrameCtrl == MAC_FRAME_BEACON || */ -+ /* u2TxFrameCtrl == MAC_FRAME_PROBE_RSP) { */ -+ -+ DBGLOG(RX, INFO, "QM RX MGT: net %u sta idx %u wlan idx %u ssn %u ptype %u subtype %u 11 %u\n", -+ (UINT_32) HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr), prHifRxHdr->ucStaRecIdx, -+ prSwRfb->ucWlanIdx, (UINT_32) HIF_RX_HDR_GET_SN(prHifRxHdr),/* The new SN of the frame */ -+ prSwRfb->ucPacketType, ucSubtype, HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)); -+ -+ /* DBGLOG_MEM8(SW4, TRACE, (PUINT_8)prSwRfb->pvHeader, prSwRfb->u2PacketLen); */ -+ /* } */ -+ /* } */ -+ } -+#endif -+ -+ if ((prAdapter->fgTestMode == FALSE) && (prAdapter->prGlueInfo->fgIsRegistered == TRUE)) { -+#if CFG_MGMT_FRAME_HANDLING -+#if CFG_SUPPORT_802_11W -+ fgMfgDrop = rsnCheckRxMgmt(prAdapter, prSwRfb, ucSubtype); -+ if (fgMfgDrop) { -+#if DBG -+ LOG_FUNC("QM RX MGT: Drop Unprotected Mgmt frame!!!\n"); -+#endif -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); -+ return; -+ } -+#endif -+ if (apfnProcessRxMgtFrame[ucSubtype]) { -+ switch (apfnProcessRxMgtFrame[ucSubtype] (prAdapter, prSwRfb)) { -+ case WLAN_STATUS_PENDING: -+ return; -+ case WLAN_STATUS_SUCCESS: -+ case WLAN_STATUS_FAILURE: -+ break; -+ -+ default: -+ DBGLOG(RX, WARN, -+ "Unexpected MMPDU(0x%02X) returned with abnormal status\n", ucSubtype); -+ break; -+ } -+ } -+#endif -+ } -+ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+} -+ -+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG -+static VOID nicRxCheckWakeupReason(P_SW_RFB_T prSwRfb) -+{ -+ PUINT_8 pvHeader = NULL; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_16 u2PktLen = 0; -+ UINT_32 u4HeaderOffset; -+ -+ if (!prSwRfb) -+ return; -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ if (!prHifRxHdr) -+ return; -+ -+ switch (prSwRfb->ucPacketType) { -+ case HIF_RX_PKT_TYPE_DATA: -+ { -+ UINT_16 u2Temp = 0; -+ -+ if (HIF_RX_HDR_GET_BAR_FLAG(prHifRxHdr)) { -+ DBGLOG(RX, INFO, "BAR frame[SSN:%d, TID:%d] wakeup host\n", -+ (UINT_16)HIF_RX_HDR_GET_SN(prHifRxHdr), (UINT_8)HIF_RX_HDR_GET_TID(prHifRxHdr)); -+ break; -+ } -+ u4HeaderOffset = (UINT_32)(prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK); -+ pvHeader = (PUINT_8)prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset; -+ u2PktLen = (UINT_16)(prHifRxHdr->u2PacketLen - (HIF_RX_HDR_SIZE + u4HeaderOffset)); -+ if (!pvHeader) { -+ DBGLOG(RX, ERROR, "data packet but pvHeader is NULL!\n"); -+ break; -+ } -+ u2Temp = (pvHeader[ETH_TYPE_LEN_OFFSET] << 8) | (pvHeader[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ switch (u2Temp) { -+ case ETH_P_IPV4: -+ u2Temp = *(UINT_16 *) &pvHeader[ETH_HLEN + 4]; -+ DBGLOG(RX, INFO, "IP Packet from:%d.%d.%d.%d, IP ID 0x%04x wakeup host\n", -+ pvHeader[ETH_HLEN + 12], pvHeader[ETH_HLEN + 13], -+ pvHeader[ETH_HLEN + 14], pvHeader[ETH_HLEN + 15], u2Temp); -+ break; -+ case ETH_P_ARP: -+ { -+ PUINT_8 pucEthBody = &pvHeader[ETH_HLEN]; -+ UINT_16 u2OpCode = (pucEthBody[6] << 8) | pucEthBody[7]; -+ -+ if (u2OpCode == ARP_PRO_REQ) -+ DBGLOG(RX, INFO, "Arp Req From IP: %d.%d.%d.%d wakeup host\n", -+ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); -+ else if (u2OpCode == ARP_PRO_RSP) -+ DBGLOG(RX, INFO, "Arp Rsp from IP: %d.%d.%d.%d wakeup host\n", -+ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); -+ break; -+ } -+ case ETH_P_1X: -+ case ETH_P_PRE_1X: -+#if CFG_SUPPORT_WAPI -+ case ETH_WPI_1X: -+#endif -+ case ETH_P_AARP: -+ case ETH_P_IPV6: -+ case ETH_P_IPX: -+ case 0x8100: /* VLAN */ -+ case 0x890d: /* TDLS */ -+ DBGLOG(RX, INFO, "Data Packet, EthType 0x%04x wakeup host\n", u2Temp); -+ break; -+ default: -+ DBGLOG(RX, WARN, "maybe abnormal data packet, EthType 0x%04x wakeup host, dump it\n", -+ u2Temp); -+ DBGLOG_MEM8(RX, INFO, pvHeader, u2PktLen > 50 ? 50:u2PacketLen); -+ break; -+ } -+ break; -+ } -+ case HIF_RX_PKT_TYPE_EVENT: -+ { -+ P_WIFI_EVENT_T prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff; -+ -+ DBGLOG(RX, INFO, "Event 0x%02x wakeup host\n", prEvent->ucEID); -+ break; -+ } -+ case HIF_RX_PKT_TYPE_MANAGEMENT: -+ { -+ UINT_8 ucSubtype; -+ P_WLAN_MAC_MGMT_HEADER_T prWlanMgmtHeader; -+ -+ u4HeaderOffset = (UINT_32)(prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK); -+ pvHeader = (PUINT_8)prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset; -+ if (!pvHeader) { -+ DBGLOG(RX, ERROR, "Mgmt Frame but pvHeader is NULL!\n"); -+ break; -+ } -+ prWlanMgmtHeader = (P_WLAN_MAC_MGMT_HEADER_T)pvHeader; -+ ucSubtype = (prWlanMgmtHeader->u2FrameCtrl & MASK_FC_SUBTYPE) >> -+ OFFSET_OF_FC_SUBTYPE; -+ DBGLOG(RX, INFO, "MGMT frame subtype: %d SeqCtrl %d wakeup host\n", -+ ucSubtype, prWlanMgmtHeader->u2SeqCtrl); -+ break; -+ } -+ default: -+ DBGLOG(RX, WARN, "Unknown Packet %d wakeup host\n", prSwRfb->ucPacketType); -+ break; -+ } -+} -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief nicProcessRFBs is used to process RFBs in the rReceivedRFBList queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessRFBs(IN P_ADAPTER_T prAdapter) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxProcessRFBs"); -+ -+ ASSERT(prAdapter); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ prRxCtrl->ucNumIndPacket = 0; -+ prRxCtrl->ucNumRetainedPacket = 0; -+ -+ do { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rReceivedRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (prSwRfb) { -+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG -+ if (kalIsWakeupByWlan(prAdapter)) -+ nicRxCheckWakeupReason(prSwRfb); -+#endif -+ switch (prSwRfb->ucPacketType) { -+ case HIF_RX_PKT_TYPE_DATA: -+ nicRxProcessDataPacket(prAdapter, prSwRfb); -+ break; -+ -+ case HIF_RX_PKT_TYPE_EVENT: -+ nicRxProcessEventPacket(prAdapter, prSwRfb); -+ break; -+ -+ case HIF_RX_PKT_TYPE_TX_LOOPBACK: -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+ { -+ kalDevLoopbkRxHandle(prAdapter, prSwRfb); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ } -+#else -+ DBGLOG(RX, ERROR, "ucPacketType = %d\n", prSwRfb->ucPacketType); -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ break; -+ -+ case HIF_RX_PKT_TYPE_MANAGEMENT: -+ nicRxProcessMgmtPacket(prAdapter, prSwRfb); -+ break; -+ -+ default: -+ RX_INC_CNT(prRxCtrl, RX_TYPE_ERR_DROP_COUNT); -+ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); -+ DBGLOG(RX, ERROR, "ucPacketType = %d\n", prSwRfb->ucPacketType); -+ nicRxReturnRFB(prAdapter, prSwRfb); /* need to free it */ -+ break; -+ } -+ } else { -+ break; -+ } -+ } while (TRUE); -+ -+ if (prRxCtrl->ucNumIndPacket > 0) { -+ RX_ADD_CNT(prRxCtrl, RX_DATA_INDICATION_COUNT, prRxCtrl->ucNumIndPacket); -+ RX_ADD_CNT(prRxCtrl, RX_DATA_RETAINED_COUNT, prRxCtrl->ucNumRetainedPacket); -+ -+ /* DBGLOG(RX, INFO, ("%d packets indicated, Retained cnt = %d\n", */ -+ /* prRxCtrl->ucNumIndPacket, prRxCtrl->ucNumRetainedPacket)); */ -+#if CFG_NATIVE_802_11 -+ kalRxIndicatePkts(prAdapter->prGlueInfo, (UINT_32) prRxCtrl->ucNumIndPacket, -+ (UINT_32) prRxCtrl->ucNumRetainedPacket); -+#else -+ kalRxIndicatePkts(prAdapter->prGlueInfo, prRxCtrl->apvIndPacket, (UINT_32) prRxCtrl->ucNumIndPacket); -+#endif -+ } -+ -+} /* end of nicRxProcessRFBs() */ -+ -+#if !CFG_SDIO_INTR_ENHANCE -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read the rx data from data port and setup RFB -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @retval WLAN_STATUS_SUCCESS: SUCCESS -+* @retval WLAN_STATUS_FAILURE: FAILURE -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRxReadBuffer(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ PUINT_8 pucBuf; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_32 u4PktLen = 0, u4ReadBytes; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ BOOLEAN fgResult = TRUE; -+ UINT_32 u4RegValue; -+ UINT_32 rxNum; -+ -+ DEBUGFUNC("nicRxReadBuffer"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ pucBuf = prSwRfb->pucRecvBuff; -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ ASSERT(pucBuf); -+ DBGLOG(RX, TRACE, "pucBuf= 0x%x, prHifRxHdr= 0x%x\n", pucBuf, prHifRxHdr); -+ -+ do { -+ /* Read the RFB DW length and packet length */ -+ HAL_MCR_RD(prAdapter, MCR_WRPLR, &u4RegValue); -+ if (!fgResult) { -+ DBGLOG(RX, ERROR, "Read RX Packet Lentgh Error\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* 20091021 move the line to get the HIF RX header (for RX0/1) */ -+ if (u4RegValue == 0) { -+ DBGLOG(RX, ERROR, "No RX packet\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ u4PktLen = u4RegValue & BITS(0, 15); -+ if (u4PktLen != 0) { -+ rxNum = 0; -+ } else { -+ rxNum = 1; -+ u4PktLen = (u4RegValue & BITS(16, 31)) >> 16; -+ } -+ -+ DBGLOG(RX, TRACE, "RX%d: u4PktLen = %d\n", rxNum, u4PktLen); -+ -+ /* 4 <4> Read Entire RFB and packet, include HW appended DW (Checksum Status) */ -+ u4ReadBytes = ALIGN_4(u4PktLen) + 4; -+ HAL_READ_RX_PORT(prAdapter, rxNum, u4ReadBytes, pucBuf, CFG_RX_MAX_PKT_SIZE); -+ -+ /* 20091021 move the line to get the HIF RX header */ -+ /* u4PktLen = (UINT_32)prHifRxHdr->u2PacketLen; */ -+ if (u4PktLen != (UINT_32) prHifRxHdr->u2PacketLen) { -+ DBGLOG(RX, ERROR, "Read u4PktLen = %d, prHifRxHdr->u2PacketLen: %d\n", -+ u4PktLen, prHifRxHdr->u2PacketLen); -+#if DBG -+ dumpMemory8((PUINT_8) prHifRxHdr, -+ (prHifRxHdr->u2PacketLen > 4096) ? 4096 : prHifRxHdr->u2PacketLen); -+#endif -+ ASSERT(0); -+ } -+ /* u4PktLen is byte unit, not inlude HW appended DW */ -+ -+ prSwRfb->ucPacketType = (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK); -+ DBGLOG(RX, TRACE, "ucPacketType = %d\n", prSwRfb->ucPacketType); -+ -+ prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); -+ -+ /* fgResult will be updated in MACRO */ -+ if (!fgResult) -+ return WLAN_STATUS_FAILURE; -+ -+ DBGLOG(RX, TRACE, "Dump RX buffer, length = 0x%x\n", u4ReadBytes); -+ DBGLOG_MEM8(RX, TRACE, pucBuf, u4ReadBytes); -+ } while (FALSE); -+ -+ return u4Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read frames from the data port, fill RFB -+* and put each frame into the rReceivedRFBList queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxReceiveRFBs(IN P_ADAPTER_T prAdapter) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ -+ UINT_32 u4HwAppendDW; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxReceiveRFBs"); -+ -+ ASSERT(prAdapter); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ do { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (!prSwRfb) { -+ DBGLOG(RX, TRACE, "No More RFB\n"); -+ break; -+ } -+ /* need to consider */ -+ if (nicRxReadBuffer(prAdapter, prSwRfb) == WLAN_STATUS_FAILURE) { -+ DBGLOG(RX, TRACE, "halRxFillRFB failed\n"); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ break; -+ } -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); -+ RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ u4HwAppendDW = *((PUINT_32) ((ULONG) prHifRxHdr + (UINT_32) (ALIGN_4(prHifRxHdr->u2PacketLen)))); -+ DBGLOG(RX, TRACE, "u4HwAppendDW = 0x%x\n", u4HwAppendDW); -+ DBGLOG(RX, TRACE, "u2PacketLen = 0x%x\n", prHifRxHdr->u2PacketLen); -+ } while (FALSE); /* while (RX_STATUS_TEST_MORE_FLAG(u4HwAppendDW)); */ -+ -+ return; -+ -+} /* end of nicReceiveRFBs() */ -+ -+#else -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read frames from the data port, fill RFB -+* and put each frame into the rReceivedRFBList queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param u4DataPort Specify which port to read -+* @param u2RxLength Specify to the the rx packet length in Byte. -+* @param prSwRfb the RFB to receive rx data. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS -+nicRxEnhanceReadBuffer(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DataPort, IN UINT_16 u2RxLength, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ PUINT_8 pucBuf; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_32 u4PktLen = 0; -+ WLAN_STATUS u4Status = WLAN_STATUS_FAILURE; -+ BOOLEAN fgResult = TRUE; -+ -+ DEBUGFUNC("nicRxEnhanceReadBuffer"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ pucBuf = prSwRfb->pucRecvBuff; -+ ASSERT(pucBuf); -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ ASSERT(prHifRxHdr); -+ -+ /* DBGLOG(RX, TRACE, ("u2RxLength = %d\n", u2RxLength)); */ -+ -+ do { -+ /* 4 <1> Read RFB frame from MCR_WRDR0, include HW appended DW */ -+ HAL_READ_RX_PORT(prAdapter, -+ u4DataPort, ALIGN_4(u2RxLength + HIF_RX_HW_APPENDED_LEN), pucBuf, CFG_RX_MAX_PKT_SIZE); -+ -+ if (!fgResult) { -+ DBGLOG(RX, ERROR, "Read RX Packet Lentgh Error\n"); -+ break; -+ } -+ -+ u4PktLen = (UINT_32) (prHifRxHdr->u2PacketLen); -+ /* DBGLOG(RX, TRACE, ("u4PktLen = %d\n", u4PktLen)); */ -+ -+ prSwRfb->ucPacketType = (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK); -+ /* DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType)); */ -+ -+ prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); -+ -+ /* 4 <2> if the RFB dw size or packet size is zero */ -+ if (u4PktLen == 0) { -+ DBGLOG(RX, ERROR, "Packet Length = %u\n", u4PktLen); -+ ASSERT(0); -+ break; -+ } -+ /* 4 <3> if the packet is too large or too small */ -+ if (u4PktLen > CFG_RX_MAX_PKT_SIZE) { -+ DBGLOG(RX, TRACE, "Read RX Packet Lentgh Error (%u)\n", u4PktLen); -+ ASSERT(0); -+ break; -+ } -+ -+ u4Status = WLAN_STATUS_SUCCESS; -+ } while (FALSE); -+ -+ DBGLOG_MEM8(RX, TRACE, pucBuf, ALIGN_4(u2RxLength + HIF_RX_HW_APPENDED_LEN)); -+ return u4Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read frames from the data port for SDIO -+* I/F, fill RFB and put each frame into the rReceivedRFBList queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxSDIOReceiveRFBs(IN P_ADAPTER_T prAdapter) -+{ -+ P_SDIO_CTRL_T prSDIOCtrl; -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ UINT_32 i, rxNum; -+ UINT_16 u2RxPktNum, u2RxLength = 0, u2Tmp = 0; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxSDIOReceiveRFBs"); -+ -+ ASSERT(prAdapter); -+ -+ prSDIOCtrl = prAdapter->prSDIOCtrl; -+ ASSERT(prSDIOCtrl); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ for (rxNum = 0; rxNum < 2; rxNum++) { -+ u2RxPktNum = -+ (rxNum == 0 ? prSDIOCtrl->rRxInfo.u.u2NumValidRx0Len : prSDIOCtrl->rRxInfo.u.u2NumValidRx1Len); -+ -+ if (u2RxPktNum == 0) -+ continue; -+ -+ for (i = 0; i < u2RxPktNum; i++) { -+ if (rxNum == 0) { -+ /* HAL_READ_RX_LENGTH */ -+ HAL_READ_RX_LENGTH(prAdapter, &u2RxLength, &u2Tmp); -+ } else if (rxNum == 1) { -+ /* HAL_READ_RX_LENGTH */ -+ HAL_READ_RX_LENGTH(prAdapter, &u2Tmp, &u2RxLength); -+ } -+ -+ if (!u2RxLength) -+ break; -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (!prSwRfb) { -+ DBGLOG(RX, TRACE, "No More RFB\n"); -+ break; -+ } -+ ASSERT(prSwRfb); -+ -+ if (nicRxEnhanceReadBuffer(prAdapter, rxNum, u2RxLength, prSwRfb) == WLAN_STATUS_FAILURE) { -+ DBGLOG(RX, TRACE, "nicRxEnhanceRxReadBuffer failed\n"); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ break; -+ } -+ /* prSDIOCtrl->au4RxLength[i] = 0; */ -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); -+ RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ } -+ } -+ -+ prSDIOCtrl->rRxInfo.u.u2NumValidRx0Len = 0; -+ prSDIOCtrl->rRxInfo.u.u2NumValidRx1Len = 0; -+ -+} /* end of nicRxSDIOReceiveRFBs() */ -+ -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+#if CFG_SDIO_RX_AGG -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read frames from the data port for SDIO with Rx aggregation enabled -+* I/F, fill RFB and put each frame into the rReceivedRFBList queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxSDIOAggReceiveRFBs(IN P_ADAPTER_T prAdapter) -+{ -+ P_ENHANCE_MODE_DATA_STRUCT_T prEnhDataStr; -+ P_RX_CTRL_T prRxCtrl; -+ P_SDIO_CTRL_T prSDIOCtrl; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ UINT_32 u4RxLength; -+ UINT_32 i, rxNum; -+ UINT_32 u4RxAggCount = 0, u4RxAggLength = 0; -+ UINT_32 u4RxAvailAggLen, u4CurrAvailFreeRfbCnt; -+ PUINT_8 pucSrcAddr; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ BOOLEAN fgResult = TRUE; -+ BOOLEAN fgIsRxEnhanceMode; -+ UINT_16 u2RxPktNum; -+#if CFG_SDIO_RX_ENHANCE -+ UINT_32 u4MaxLoopCount = CFG_MAX_RX_ENHANCE_LOOP_COUNT; -+#endif -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxSDIOAggReceiveRFBs"); -+ -+ ASSERT(prAdapter); -+ prEnhDataStr = prAdapter->prSDIOCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ prSDIOCtrl = prAdapter->prSDIOCtrl; -+ -+#if CFG_SDIO_RX_ENHANCE -+ fgIsRxEnhanceMode = TRUE; -+#else -+ fgIsRxEnhanceMode = FALSE; -+#endif -+ -+ do { -+#if CFG_SDIO_RX_ENHANCE -+ /* to limit maximum loop for RX */ -+ u4MaxLoopCount--; -+ if (u4MaxLoopCount == 0) -+ break; -+#endif -+ -+ if (prEnhDataStr->rRxInfo.u.u2NumValidRx0Len == 0 && prEnhDataStr->rRxInfo.u.u2NumValidRx1Len == 0) -+ break; -+ -+ for (rxNum = 0; rxNum < 2; rxNum++) { -+ u2RxPktNum = -+ (rxNum == -+ 0 ? prEnhDataStr->rRxInfo.u.u2NumValidRx0Len : prEnhDataStr->rRxInfo.u.u2NumValidRx1Len); -+ -+ /* if this assertion happened, it is most likely a F/W bug */ -+ ASSERT(u2RxPktNum <= 16); -+ -+ if (u2RxPktNum > 16) -+ continue; -+ -+ if (u2RxPktNum == 0) -+ continue; -+ -+#if CFG_HIF_STATISTICS -+ prRxCtrl->u4TotalRxAccessNum++; -+ prRxCtrl->u4TotalRxPacketNum += u2RxPktNum; -+#endif -+ -+ u4CurrAvailFreeRfbCnt = prRxCtrl->rFreeSwRfbList.u4NumElem; -+ -+ /* if SwRfb is not enough, abort reading this time */ -+ if (u4CurrAvailFreeRfbCnt < u2RxPktNum) { -+#if CFG_HIF_RX_STARVATION_WARNING -+ DbgPrint("FreeRfb is not enough: %d available, need %d\n", u4CurrAvailFreeRfbCnt, -+ u2RxPktNum); -+ DbgPrint("Queued Count: %d / Dequeud Count: %d\n", prRxCtrl->u4QueuedCnt, -+ prRxCtrl->u4DequeuedCnt); -+#endif -+ continue; -+ } -+#if CFG_SDIO_RX_ENHANCE -+ u4RxAvailAggLen = -+ CFG_RX_COALESCING_BUFFER_SIZE - (sizeof(ENHANCE_MODE_DATA_STRUCT_T) + -+ 4 /* extra HW padding */); -+#else -+ u4RxAvailAggLen = CFG_RX_COALESCING_BUFFER_SIZE; -+#endif -+ u4RxAggCount = 0; -+ -+ for (i = 0; i < u2RxPktNum; i++) { -+ u4RxLength = (rxNum == 0 ? -+ (UINT_32) prEnhDataStr->rRxInfo.u.au2Rx0Len[i] : -+ (UINT_32) prEnhDataStr->rRxInfo.u.au2Rx1Len[i]); -+ -+ if (!u4RxLength) { -+ ASSERT(0); -+ break; -+ } -+ -+ if (ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN) < u4RxAvailAggLen) { -+ if (u4RxAggCount < u4CurrAvailFreeRfbCnt) { -+ u4RxAvailAggLen -= ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN); -+ u4RxAggCount++; -+ } else { -+ /* no FreeSwRfb for rx packet */ -+ ASSERT(0); -+ break; -+ } -+ } else { -+ /* CFG_RX_COALESCING_BUFFER_SIZE is not large enough */ -+ ASSERT(0); -+ break; -+ } -+ } -+ -+ u4RxAggLength = (CFG_RX_COALESCING_BUFFER_SIZE - u4RxAvailAggLen); -+ /* DBGLOG(RX, INFO, ("u4RxAggCount = %d, u4RxAggLength = %d\n", */ -+ /* u4RxAggCount, u4RxAggLength)); */ -+ -+ HAL_READ_RX_PORT(prAdapter, -+ rxNum, -+ u4RxAggLength, prRxCtrl->pucRxCoalescingBufPtr, CFG_RX_COALESCING_BUFFER_SIZE); -+ if (!fgResult) { -+ DBGLOG(RX, ERROR, "Read RX Agg Packet Error\n"); -+ continue; -+ } -+ -+ pucSrcAddr = prRxCtrl->pucRxCoalescingBufPtr; -+ for (i = 0; i < u4RxAggCount; i++) { -+ UINT_16 u2PktLength; -+ -+ u2PktLength = (rxNum == 0 ? -+ prEnhDataStr->rRxInfo.u.au2Rx0Len[i] : -+ prEnhDataStr->rRxInfo.u.au2Rx1Len[i]); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ ASSERT(prSwRfb); -+ kalMemCopy(prSwRfb->pucRecvBuff, pucSrcAddr, -+ ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN)); -+ -+ /* record the rx time */ -+ STATS_RX_ARRIVE_TIME_RECORD(prSwRfb); /* ms */ -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ ASSERT(prHifRxHdr); -+ -+ prSwRfb->ucPacketType = -+ (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK); -+ /* DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType)); */ -+ -+ prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); -+ RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ pucSrcAddr += ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN); -+ /* prEnhDataStr->au4RxLength[i] = 0; */ -+ } -+ -+#if CFG_SDIO_RX_ENHANCE -+ kalMemCopy(prAdapter->prSDIOCtrl, (pucSrcAddr + 4), sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ -+ /* do the same thing what nicSDIOReadIntStatus() does */ -+ if ((prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT) == 0 && -+ (prSDIOCtrl->rTxInfo.au4WTSR[0] | prSDIOCtrl->rTxInfo.au4WTSR[1])) { -+ prSDIOCtrl->u4WHISR |= WHISR_TX_DONE_INT; -+ } -+ -+ if ((prSDIOCtrl->u4WHISR & BIT(31)) == 0 && -+ HAL_GET_MAILBOX_READ_CLEAR(prAdapter) == TRUE && -+ (prSDIOCtrl->u4RcvMailbox0 != 0 || prSDIOCtrl->u4RcvMailbox1 != 0)) { -+ prSDIOCtrl->u4WHISR |= BIT(31); -+ } -+ -+ /* dispatch to interrupt handler with RX bits masked */ -+ nicProcessIST_impl(prAdapter, -+ prSDIOCtrl->u4WHISR & (~(WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT))); -+#endif -+ } -+ -+#if !CFG_SDIO_RX_ENHANCE -+ prEnhDataStr->rRxInfo.u.u2NumValidRx0Len = 0; -+ prEnhDataStr->rRxInfo.u.u2NumValidRx1Len = 0; -+#endif -+ } while ((prEnhDataStr->rRxInfo.u.u2NumValidRx0Len || prEnhDataStr->rRxInfo.u.u2NumValidRx1Len) -+ && fgIsRxEnhanceMode); -+ -+} -+#endif /* CFG_SDIO_RX_AGG */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Setup a RFB and allocate the os packet to the RFB -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prSwRfb Pointer to the RFB -+* -+* @retval WLAN_STATUS_SUCCESS -+* @retval WLAN_STATUS_RESOURCES -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRxSetupRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ PVOID pvPacket; -+ PUINT_8 pucRecvBuff; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ if (!prSwRfb->pvPacket) { -+ kalMemZero(prSwRfb, sizeof(SW_RFB_T)); -+ pvPacket = kalPacketAlloc(prAdapter->prGlueInfo, CFG_RX_MAX_PKT_SIZE, &pucRecvBuff); -+ if (pvPacket == NULL) -+ return WLAN_STATUS_RESOURCES; -+ -+ prSwRfb->pvPacket = pvPacket; -+ prSwRfb->pucRecvBuff = (PVOID) pucRecvBuff; -+ } else { -+ kalMemZero(((PUINT_8) prSwRfb + OFFSET_OF(SW_RFB_T, prHifRxHdr)), -+ (sizeof(SW_RFB_T) - OFFSET_OF(SW_RFB_T, prHifRxHdr))); -+ } -+ -+ prSwRfb->prHifRxHdr = (P_HIF_RX_HEADER_T) (prSwRfb->pucRecvBuff); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of nicRxSetupRFB() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is called to put a RFB back onto the "RFB with Buffer" list -+* or "RFB without buffer" list according to pvPacket. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prSwRfb Pointer to the RFB -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxReturnRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_QUE_ENTRY_T prQueEntry; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ prQueEntry = &prSwRfb->rQueEntry; -+ -+ ASSERT(prQueEntry); -+ -+ /* The processing on this RFB is done, so put it back on the tail of -+ our list */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (prSwRfb->pvPacket) { -+ /* QUEUE_INSERT_TAIL */ -+ QUEUE_INSERT_TAIL(&prRxCtrl->rFreeSwRfbList, prQueEntry); -+ } else { -+ /* QUEUE_INSERT_TAIL */ -+ QUEUE_INSERT_TAIL(&prRxCtrl->rIndicatedRfbList, prQueEntry); -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+} /* end of nicRxReturnRFB() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process rx interrupt. When the rx -+* Interrupt is asserted, it means there are frames in queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicProcessRxInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ prGlueInfo->IsrRxCnt++; -+#if CFG_SDIO_INTR_ENHANCE -+#if CFG_SDIO_RX_AGG -+ nicRxSDIOAggReceiveRFBs(prAdapter); -+#else -+ nicRxSDIOReceiveRFBs(prAdapter); -+#endif -+#else -+ nicRxReceiveRFBs(prAdapter); -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+ nicRxProcessRFBs(prAdapter); -+ -+ return; -+ -+} /* end of nicProcessRxInterrupt() */ -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Used to update IP/TCP/UDP checksum statistics of RX Module. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param aeCSUM The array of checksum result. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxUpdateCSUMStatistics(IN P_ADAPTER_T prAdapter, IN const ENUM_CSUM_RESULT_T aeCSUM[]) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(aeCSUM); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS) || -+ (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS)) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_IP_SUCCESS_COUNT); -+ } else if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED) || (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_FAILED)) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_IP_FAILED_COUNT); -+ } else if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE) && (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE)) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_UNKNOWN_L3_PKT_COUNT); -+ } else { -+ ASSERT(0); -+ } -+ -+ if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS) { -+ /* count success num */ -+ RX_INC_CNT(prRxCtrl, RX_CSUM_TCP_SUCCESS_COUNT); -+ } else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_TCP_FAILED_COUNT); -+ } else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_UDP_SUCCESS_COUNT); -+ } else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_UDP_FAILED_COUNT); -+ } else if ((aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_NONE) && (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_NONE)) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_UNKNOWN_L4_PKT_COUNT); -+ } else { -+ ASSERT(0); -+ } -+ -+} /* end of nicRxUpdateCSUMStatistics() */ -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to query current status of RX Module. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param pucBuffer Pointer to the message buffer. -+* @param pu4Count Pointer to the buffer of message length count. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxQueryStatus(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ PUINT_8 pucCurrBuf = pucBuffer; -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ /* if (pucBuffer) {} */ /* For Windows, we'll print directly instead of sprintf() */ -+ ASSERT(pu4Count); -+ -+ SPRINTF(pucCurrBuf, ("\n\nRX CTRL STATUS:")); -+ SPRINTF(pucCurrBuf, ("\n===============")); -+ SPRINTF(pucCurrBuf, ("\nFREE RFB w/i BUF LIST :%9u", prRxCtrl->rFreeSwRfbList.u4NumElem)); -+ SPRINTF(pucCurrBuf, ("\nFREE RFB w/o BUF LIST :%9u", prRxCtrl->rIndicatedRfbList.u4NumElem)); -+ SPRINTF(pucCurrBuf, ("\nRECEIVED RFB LIST :%9u", prRxCtrl->rReceivedRfbList.u4NumElem)); -+ -+ SPRINTF(pucCurrBuf, ("\n\n")); -+ -+ /* *pu4Count = (UINT_32)((UINT_32)pucCurrBuf - (UINT_32)pucBuffer); */ -+ -+} /* end of nicRxQueryStatus() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Clear RX related counters -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return - (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxClearStatistics(IN P_ADAPTER_T prAdapter) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ RX_RESET_ALL_CNTS(prRxCtrl); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to query current statistics of RX Module. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param pucBuffer Pointer to the message buffer. -+* @param pu4Count Pointer to the buffer of message length count. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxQueryStatistics(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ PUINT_8 pucCurrBuf = pucBuffer; -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ /* if (pucBuffer) {} */ /* For Windows, we'll print directly instead of sprintf() */ -+ ASSERT(pu4Count); -+ -+#define SPRINTF_RX_COUNTER(eCounter) \ -+ SPRINTF(pucCurrBuf, ("%-30s : %u\n", #eCounter, (UINT_32)prRxCtrl->au8Statistics[eCounter])) -+ -+ SPRINTF_RX_COUNTER(RX_MPDU_TOTAL_COUNT); -+ SPRINTF_RX_COUNTER(RX_SIZE_ERR_DROP_COUNT); -+ SPRINTF_RX_COUNTER(RX_DATA_INDICATION_COUNT); -+ SPRINTF_RX_COUNTER(RX_DATA_RETURNED_COUNT); -+ SPRINTF_RX_COUNTER(RX_DATA_RETAINED_COUNT); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 -+ SPRINTF_RX_COUNTER(RX_CSUM_TCP_FAILED_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_UDP_FAILED_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_IP_FAILED_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_TCP_SUCCESS_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_UDP_SUCCESS_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_IP_SUCCESS_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_UNKNOWN_L4_PKT_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_UNKNOWN_L3_PKT_COUNT); -+ SPRINTF_RX_COUNTER(RX_IP_V6_PKT_CCOUNT); -+#endif -+ -+ /* *pu4Count = (UINT_32)(pucCurrBuf - pucBuffer); */ -+ -+ nicRxClearStatistics(prAdapter); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read the Response data from data port -+* -+* @param prAdapter pointer to the Adapter handler -+* @param pucRspBuffer pointer to the Response buffer -+* -+* @retval WLAN_STATUS_SUCCESS: Response packet has been read -+* @retval WLAN_STATUS_FAILURE: Read Response packet timeout or error occurred -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicRxWaitResponse(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucPortIdx, OUT PUINT_8 pucRspBuffer, IN UINT_32 u4MaxRespBufferLen, OUT PUINT_32 pu4Length) -+{ -+ UINT_32 u4Value = 0, u4PktLen = 0; -+ UINT_32 i = 0; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ BOOLEAN fgResult = TRUE; -+ UINT_32 u4Time, u4Current; -+ -+ DEBUGFUNC("nicRxWaitResponse"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pucRspBuffer); -+ ASSERT(ucPortIdx < 2); -+ -+ u4Time = kalGetTimeTick(); -+ -+ do { -+ /* Read the packet length */ -+ HAL_MCR_RD(prAdapter, MCR_WRPLR, &u4Value); -+ -+ if (!fgResult) { -+ DBGLOG(RX, ERROR, "Read Response Packet Error\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ if (ucPortIdx == 0) -+ u4PktLen = u4Value & 0xFFFF; -+ else -+ u4PktLen = (u4Value >> 16) & 0xFFFF; -+ -+/* DBGLOG(RX, TRACE, ("i = %d, u4PktLen = %d\n", i, u4PktLen)); */ -+ -+ if (u4PktLen == 0) { -+ /* timeout exceeding check */ -+ u4Current = kalGetTimeTick(); -+ -+ if ((u4Current > u4Time) && ((u4Current - u4Time) > RX_RESPONSE_TIMEOUT)) { -+ DBGLOG(RX, ERROR, "RX_RESPONSE_TIMEOUT1 %u %d %u\n", u4PktLen, i, u4Current); -+ return WLAN_STATUS_FAILURE; -+ } else if (u4Current < u4Time && ((u4Current + (0xFFFFFFFF - u4Time)) > RX_RESPONSE_TIMEOUT)) { -+ DBGLOG(RX, ERROR, "RX_RESPONSE_TIMEOUT2 %u %d %u\n", u4PktLen, i, u4Current); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* Response packet is not ready */ -+ kalUdelay(50); -+ -+ i++; -+ continue; -+ } -+ if (u4PktLen > u4MaxRespBufferLen) { -+ /* -+ TO: buffer is not enough but we still need to read all data from HIF to avoid -+ HIF crazy. -+ */ -+ DBGLOG(RX, ERROR, -+ "Not enough Event Buffer: required length = 0x%x, available buffer length = %d\n", -+ u4PktLen, u4MaxRespBufferLen); -+ DBGLOG(RX, ERROR, "i = %d, u4PktLen = %u\n", i, u4PktLen); -+ return WLAN_STATUS_FAILURE; -+ } -+ HAL_PORT_RD(prAdapter, -+ ucPortIdx == 0 ? MCR_WRDR0 : MCR_WRDR1, u4PktLen, pucRspBuffer, u4MaxRespBufferLen); -+ -+ /* fgResult will be updated in MACRO */ -+ if (!fgResult) { -+ DBGLOG(RX, ERROR, "Read Response Packet Error\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ DBGLOG(RX, TRACE, "Dump Response buffer, length = 0x%x\n", u4PktLen); -+ DBGLOG_MEM8(RX, TRACE, pucRspBuffer, u4PktLen); -+ -+ *pu4Length = u4PktLen; -+ break; -+ } while (TRUE); -+ -+ return u4Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Set filter to enable Promiscuous Mode -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxEnablePromiscuousMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+} /* end of nicRxEnablePromiscuousMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Set filter to disable Promiscuous Mode -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxDisablePromiscuousMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+} /* end of nicRxDisablePromiscuousMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function flushes all packets queued in reordering module -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @retval WLAN_STATUS_SUCCESS Flushed successfully -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRxFlush(IN P_ADAPTER_T prAdapter) -+{ -+ P_SW_RFB_T prSwRfb; -+ -+ ASSERT(prAdapter); -+ -+ prSwRfb = qmFlushRxQueues(prAdapter); -+ if (prSwRfb != NULL) { -+ do { -+ P_SW_RFB_T prNextSwRfb; -+ -+ /* save next first */ -+ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb); -+ -+ /* free */ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ -+ prSwRfb = prNextSwRfb; -+ } while (prSwRfb); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param -+* -+* @retval -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRxProcessActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_ACTION_FRAME prActFrame; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ if (prSwRfb->u2PacketLen < sizeof(WLAN_ACTION_FRAME) - 1) -+ return WLAN_STATUS_INVALID_PACKET; -+ prActFrame = (P_WLAN_ACTION_FRAME) prSwRfb->pvHeader; -+ DBGLOG(RX, INFO, "Category %u\n", prActFrame->ucCategory); -+ -+ switch (prActFrame->ucCategory) { -+ case CATEGORY_PUBLIC_ACTION: -+ if (HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) -+ aisFuncValidateRxActionFrame(prAdapter, prSwRfb); -+#if CFG_ENABLE_WIFI_DIRECT -+ else if (prAdapter->fgIsP2PRegistered) { -+ rlmProcessPublicAction(prAdapter, prSwRfb); -+ -+ p2pFuncValidateRxActionFrame(prAdapter, prSwRfb); -+ -+ } -+#endif -+ break; -+ -+ case CATEGORY_HT_ACTION: -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ rlmProcessHtAction(prAdapter, prSwRfb); -+#endif -+ break; -+ case CATEGORY_VENDOR_SPECIFIC_ACTION: -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ p2pFuncValidateRxActionFrame(prAdapter, prSwRfb); -+#endif -+ break; -+#if CFG_SUPPORT_802_11W -+ case CATEGORY_SA_QUERT_ACTION: -+ { -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ -+ if ((HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) -+ && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection /* Use MFP */) { -+ if (!(prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC)) { -+ /* MFP test plan 5.3.3.4 */ -+ rsnSaQueryAction(prAdapter, prSwRfb); -+ } else { -+ DBGLOG(RSN, TRACE, "Un-Protected SA Query, do nothing\n"); -+ } -+ } -+ } -+ break; -+#endif -+#if CFG_SUPPORT_802_11V -+ case CATEGORY_WNM_ACTION: -+ { -+ wnmWNMAction(prAdapter, prSwRfb); -+ } -+ break; -+#endif -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+ case CATEGORY_SPEC_MGT: -+ { -+ if (prAdapter->fgEnable5GBand == TRUE) -+ rlmProcessSpecMgtAction(prAdapter, prSwRfb); -+ } -+ break; -+#endif -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ case 12: /* shall not be here */ -+ /* -+ A received TDLS Action frame with the Type field set to Management shall -+ be discarded. Note that the TDLS Discovery Response frame is not a TDLS -+ frame but a Public Action frame. -+ */ -+ break; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ default: -+ break; -+ } /* end of switch case */ -+ -+ return WLAN_STATUS_SUCCESS; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c -new file mode 100644 -index 0000000000000..024bd95076037 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c -@@ -0,0 +1,2350 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_tx.c#1 -+*/ -+ -+/*! \file nic_tx.c -+ \brief Functions that provide TX operation in NIC Layer. -+ -+ This file provides TX functions which are responsible for both Hardware and -+ Software Resource Management and keep their Synchronization. -+*/ -+ -+/* -+** Log: nic_tx.c -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 11 18 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add log counter for tx -+ * -+ * 11 09 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog for beacon timeout and sta aging timeout. -+ * -+ * 11 08 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog function. -+ * -+ * 05 17 2011 cp.wu -+ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state when DEAUTH frame is dropped due to bss -+ * disconnection -+ * when TX DONE status is TX_RESULT_DROPPED_IN_DRIVER, no need to switch back to IDLE state. -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing frame -+ * dropping cases for TC4 path -+ * remove unused variables. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing frame -+ * dropping cases for TC4 path -+ * 1. add nicTxGetResource() API for QM to make decisions. -+ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case. -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * use pre-allocated buffer for storing enhanced interrupt response as well -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 02 16 2011 cp.wu -+ * [WCXRP00000449] [MT6620 Wi-Fi][Driver] Refine CMD queue handling by adding an extra API for checking available count -+ * and modify behavior -+ * 1. add new API: nicTxGetFreeCmdCount() -+ * 2. when there is insufficient command descriptor, nicTxEnqueueMsdu() will drop command packets directly -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation -+ * needs such information -+ * fill mac header length information for 802.1x frames. -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system -+ * scheduling -+ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being -+ * loaded -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add GPIO debug function -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion -+ * 2. shorten polling count for shorter response time -+ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. -+ * -+ * 09 27 2010 wh.su -+ * NULL -+ * since the u2TxByteCount_UserPriority will or another setting, keep the overall buffer for avoid error -+ * -+ * 09 24 2010 wh.su -+ * NULL -+ * [WCXRP000000058][MT6620 Wi-Fi][Driver] Fail to handshake with WAPI AP due the 802.1x frame send to fw with extra -+ * bytes padding. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * HIFSYS Clock Source Workaround -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * API added: nicTxPendingPackets(), for simplifying porting layer -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 20 2010 wh.su -+ * NULL -+ * adding the eapol callback setting. -+ * -+ * 08 18 2010 yarco.yang -+ * NULL -+ * 1. Fixed HW checksum offload function not work under Linux issue. -+ * 2. Add debug message. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * . -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * simplify post-handling after TX_DONE interrupt is handled. -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under concurrent network -+ * operation -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 29 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * replace g_rQM with Adpater->rQM -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add checking for TX descriptor poll. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * TX descriptors are now allocated once for reducing allocation overhead -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change zero-padding for TX port access to HAL. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * . -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * . -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * fill extra information for revised HIF_TX_HEADER. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change to enqueue TX frame infinitely. -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add TX_PACKET_MGMT to indicate the frame is coming from management modules -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * fill network type field while doing frame identification. -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Tag the packet for QoS on Tx path -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * remove driver-land statistics. -+ * -+ * 03 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK -+ * * * * * -+ * -+* 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 03 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. -+ * * * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add mutex to avoid multiple access to qmTxQueue simultaneously. -+ * -+ * 02 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * avoid referring to NDIS-specific data structure directly from non-glue layer. -+ * -+ * 02 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add Ethernet destination address information in packet info for TX -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * * * * * * 2) firmware image length is now retrieved via NdisFileOpen -+ * * * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * * * * * * 4) nicRxWaitResponse() revised -+ * * * * * * 5) another set of TQ counter default value is added for fw-download state -+ * * * * * * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * * * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * * * * * * 4. correct some HAL implementation -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the Burst_End Indication mechanism -+ * -+ * 01 13 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * TX: fill ucWlanHeaderLength/ucPktFormtId_Flags according to info provided by prMsduInfo -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * * * * * * and result is retrieved by get ATInfo instead -+ * * * * * * * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\44 2009-12-10 16:52:15 GMT mtk02752 -+** remove unused API -+** \main\maintrunk.MT6620WiFiDriver_Prj\43 2009-12-07 22:44:24 GMT mtk02752 -+** correct assertion criterion -+** \main\maintrunk.MT6620WiFiDriver_Prj\42 2009-12-07 21:15:52 GMT mtk02752 -+** correct trivial mistake -+** \main\maintrunk.MT6620WiFiDriver_Prj\41 2009-12-04 15:47:21 GMT mtk02752 -+** + always append a dword of zero on TX path to avoid TX aggregation to triggered on uninitialized data -+** + add more assertion for packet size check -+** \main\maintrunk.MT6620WiFiDriver_Prj\40 2009-12-04 14:51:55 GMT mtk02752 -+** nicTxMsduInfo(): save ptr for next entry before attaching to qDataPort -+** \main\maintrunk.MT6620WiFiDriver_Prj\39 2009-12-04 11:54:54 GMT mtk02752 -+** add 2 assertion for size check -+** \main\maintrunk.MT6620WiFiDriver_Prj\38 2009-12-03 16:20:35 GMT mtk01461 -+** Add debug message -+** \main\maintrunk.MT6620WiFiDriver_Prj\37 2009-11-30 10:57:10 GMT mtk02752 -+** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-11-30 09:20:43 GMT mtk02752 -+** use TC4 instead of TC5 for command packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-11-27 11:08:11 GMT mtk02752 -+** add flush for reset -+** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-11-26 20:31:22 GMT mtk02752 -+** fill prMsduInfo->ucUserPriority -+** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-11-25 21:04:33 GMT mtk02752 -+** fill u2SeqNo -+** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-11-24 20:52:12 GMT mtk02752 -+** integration with SD1's data path API -+** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-11-24 19:54:25 GMT mtk02752 -+** nicTxRetransmitOfOsSendQue & nicTxData but changed to use nicTxMsduInfoList -+** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-11-23 17:53:18 GMT mtk02752 -+** add nicTxCmd() for SD1_SD3_DATAPATH_INTEGRATION, which will append only HIF_TX_HEADER. seqNum, -+** WIFI_CMD_T will be created inside oid handler -+** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-20 15:10:24 GMT mtk02752 -+** use TxAccquireResource instead of accessing TCQ directly. -+** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-17 22:40:57 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-17 17:35:40 GMT mtk02752 -+** add nicTxMsduInfoList () implementation -+** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-17 11:07:10 GMT mtk02752 -+** add nicTxAdjustTcq() implementation -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-16 22:28:38 GMT mtk02752 -+** move aucFreeBufferCount/aucMaxNumOfBuffer into another structure -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-16 21:45:32 GMT mtk02752 -+** add SD1_SD3_DATAPATH_INTEGRATION data path handling -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-13 13:29:56 GMT mtk01084 -+** modify TX hdr format, fix tx retransmission issue -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-11 10:36:21 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-04 14:11:11 GMT mtk01084 -+** modify TX SW data structure -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-10-29 19:56:17 GMT mtk01084 -+** modify HAL part -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-13 21:59:23 GMT mtk01084 -+** update for new HW design -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-02 14:00:18 GMT mtk01725 -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-05-20 12:26:06 GMT mtk01461 -+** Assign SeqNum to CMD Packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-05-19 10:54:04 GMT mtk01461 -+** Add debug message -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-05-12 09:41:55 GMT mtk01461 -+** Fix Query Command need resp issue -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-04-29 15:44:38 GMT mtk01461 -+** Move OS dependent code to kalQueryTxOOBData() -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-04-28 10:40:03 GMT mtk01461 -+** Add nicTxReleaseResource() for SDIO_STATUS_ENHANCE, and also fix the TX aggregation issue for 1x packet to TX1 port -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-04-21 09:50:47 GMT mtk01461 -+** Update nicTxCmd() for moving wait RESP function call to wlanSendCommand() -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-04-17 19:56:32 GMT mtk01461 -+** Move the CMD_INFO_T related function to cmd_buf.c -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-17 18:14:40 GMT mtk01426 -+** Update OOB query for TX packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-14 15:51:32 GMT mtk01426 -+** Support PKGUIO -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-02 17:26:40 GMT mtk01461 -+** Add virtual OOB for HIF LOOPBACK SW PRETEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-01 10:54:43 GMT mtk01461 -+** Add function for SDIO_TX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 21:53:47 GMT mtk01461 -+** Add code for retransmit of rOsSendQueue, mpSendPacket(), and add code for TX Checksum offload, Loopback Test. -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:33:51 GMT mtk01461 -+** Add code for TX Data & Cmd Packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:25:40 GMT mtk01461 -+** Fix LINT warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:10:30 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:26:04 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will initial all variables in regard to SW TX Queues and -+* all free lists of MSDU_INFO_T and SW_TFCB_T. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicTxInitialize(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ PUINT_8 pucMemHandle; -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_32 i; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicTxInitialize"); -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ /* 4 <1> Initialization of Traffic Class Queue Parameters */ -+ nicTxResetResource(prAdapter); -+ -+#if CFG_SDIO_TX_AGG -+ prTxCtrl->pucTxCoalescingBufPtr = prAdapter->pucCoalescingBufCached; -+#endif /* CFG_SDIO_TX_AGG */ -+ -+ /* allocate MSDU_INFO_T and link it into rFreeMsduInfoList */ -+ QUEUE_INITIALIZE(&prTxCtrl->rFreeMsduInfoList); -+ -+ pucMemHandle = prTxCtrl->pucTxCached; -+ for (i = 0; i < CFG_TX_MAX_PKT_NUM; i++) { -+ prMsduInfo = (P_MSDU_INFO_T) pucMemHandle; -+ kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T)); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ -+ pucMemHandle += ALIGN_4(sizeof(MSDU_INFO_T)); -+ } -+ -+ ASSERT(prTxCtrl->rFreeMsduInfoList.u4NumElem == CFG_TX_MAX_PKT_NUM); -+ /* Check if the memory allocation consist with this initialization function */ -+ ASSERT((UINT_32) (pucMemHandle - prTxCtrl->pucTxCached) == prTxCtrl->u4TxCachedSize); -+ -+ QUEUE_INITIALIZE(&prTxCtrl->rTxMgmtTxingQueue); -+ prTxCtrl->i4TxMgmtPendingNum = 0; -+ -+#if CFG_HIF_STATISTICS -+ prTxCtrl->u4TotalTxAccessNum = 0; -+ prTxCtrl->u4TotalTxPacketNum = 0; -+#endif -+ -+ prTxCtrl->i4PendingFwdFrameCount = 0; -+ -+ qmInit(prAdapter); -+ -+ TX_RESET_ALL_CNTS(prTxCtrl); -+ -+} /* end of nicTxInitialize() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver maintain a variable that is synchronous with the usage of individual -+* TC Buffer Count. This function will check if has enough TC Buffer for incoming -+* packet and then update the value after promise to provide the resources. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] ucTC Specify the resource of TC -+* -+* \retval WLAN_STATUS_SUCCESS Resource is available and been assigned. -+* \retval WLAN_STATUS_RESOURCES Resource is not available. -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 u4CurrTick = 0; -+WLAN_STATUS nicTxAcquireResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC, IN BOOLEAN pfgIsSecOrMgmt) -+{ -+#define TC4_NO_RESOURCE_DELAY_MS 5 /* exponential of 5s */ -+ -+ P_TX_CTRL_T prTxCtrl; -+ WLAN_STATUS u4Status = WLAN_STATUS_RESOURCES; -+ P_QUE_MGT_T prQM; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ prQM = &prAdapter->rQM; -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+/* DbgPrint("nicTxAcquireResource prTxCtrl->rTc.aucFreeBufferCount[%d]=%d\n", -+ ucTC, prTxCtrl->rTc.aucFreeBufferCount[ucTC]); */ -+ do { -+ if (pfgIsSecOrMgmt && (ucTC == TC4_INDEX)) { -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] < 2) { -+ DBGLOG(TX, EVENT, " aucFreeBufferCount = %d\n", -+ prTxCtrl->rTc.aucFreeBufferCount[ucTC]); -+ -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC]) -+ u4CurrTick = 0; -+ -+ break; -+ } -+ } -+ -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC]) { -+ -+ if (ucTC == TC4_INDEX) -+ u4CurrTick = 0; -+ /* get a available TX entry */ -+ prTxCtrl->rTc.aucFreeBufferCount[ucTC]--; -+ -+ prQM->au4ResourceUsedCounter[ucTC]++; -+ -+ DBGLOG(TX, EVENT, "Acquire: TC = %d aucFreeBufferCount = %d\n", -+ ucTC, prTxCtrl->rTc.aucFreeBufferCount[ucTC]); -+ -+ u4Status = WLAN_STATUS_SUCCESS; -+ } -+ } while (FALSE); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+ if (ucTC == TC4_INDEX) { -+ if (u4CurrTick == 0) -+ u4CurrTick = kalGetTimeTick(); -+ if (CHECK_FOR_TIMEOUT(kalGetTimeTick(), u4CurrTick, -+ SEC_TO_SYSTIME(TC4_NO_RESOURCE_DELAY_MS))) { -+ wlanDumpTcResAndTxedCmd(NULL, 0); -+ cmdBufDumpCmdQueue(&prAdapter->rPendingCmdQueue, "waiting response CMD queue"); -+ glDumpConnSysCpuInfo(prAdapter->prGlueInfo); -+ kalSendAeeWarning("[TC4 no resource delay 5s!]", __func__); -+ glDoChipReset(); -+ u4CurrTick = 0; -+ } -+ } -+ return u4Status; -+ -+} /* end of nicTxAcquireResourceAndTFCBs() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Driver maintain a variable that is synchronous with the usage of individual -+* TC Buffer Count. This function will do polling if FW has return the resource. -+* Used when driver start up before enable interrupt. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param ucTC Specify the resource of TC -+* -+* @retval WLAN_STATUS_SUCCESS Resource is available. -+* @retval WLAN_STATUS_FAILURE Resource is not available. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxPollingResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ WLAN_STATUS u4Status = WLAN_STATUS_FAILURE; -+ INT_32 i = NIC_TX_RESOURCE_POLLING_TIMEOUT; -+ UINT_32 au4WTSR[2]; -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ if (ucTC >= TC_NUM) -+ return WLAN_STATUS_FAILURE; -+ -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] > 0) -+ return WLAN_STATUS_SUCCESS; -+ -+ while (i-- > 0) { -+ HAL_READ_TX_RELEASED_COUNT(prAdapter, au4WTSR); -+ -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } else if (nicTxReleaseResource(prAdapter, (PUINT_8) au4WTSR)) { -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] > 0) { -+ u4Status = WLAN_STATUS_SUCCESS; -+ break; -+ } -+ kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC); -+ -+ } else { -+ kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC); -+ } -+ } -+ -+ if (i <= 0 && ucTC == TC4_INDEX) { -+ DBGLOG(TX, ERROR, "polling Tx resource for Tc4 timeout\n"); -+ glDumpConnSysCpuInfo(prAdapter->prGlueInfo); -+ } -+#if DBG -+ { -+ INT_32 i4Times = NIC_TX_RESOURCE_POLLING_TIMEOUT - (i + 1); -+ -+ if (i4Times) { -+ DBGLOG(TX, TRACE, "Polling MCR_WTSR delay %d times, %d msec\n", -+ i4Times, (i4Times * NIC_TX_RESOURCE_POLLING_DELAY_MSEC)); -+ } -+ } -+#endif /* DBG */ -+ -+ return u4Status; -+ -+} /* end of nicTxPollingResource() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver maintain a variable that is synchronous with the usage of individual -+* TC Buffer Count. This function will release TC Buffer count according to -+* the given TX_STATUS COUNTER after TX Done. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] u4TxStatusCnt Value of TX STATUS -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN nicTxReleaseResource(IN P_ADAPTER_T prAdapter, IN unsigned char *aucTxRlsCnt) -+{ -+ PUINT_32 pu4Tmp = (PUINT_32) aucTxRlsCnt; -+ P_TX_CTRL_T prTxCtrl; -+ BOOLEAN bStatus = FALSE; -+ UINT_32 i; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ if (pu4Tmp[0] | pu4Tmp[1]) { -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ for (i = 0; i < TC_NUM; i++) -+ prTxCtrl->rTc.aucFreeBufferCount[i] += aucTxRlsCnt[i]; -+ for (i = 0; i < TC_NUM; i++) -+ prQM->au4QmTcResourceBackCounter[i] += aucTxRlsCnt[i]; -+ if (aucTxRlsCnt[TC4_INDEX] != 0) -+ wlanTraceReleaseTcRes(prAdapter, aucTxRlsCnt, prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX]); -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+#if 0 -+ for (i = 0; i < TC_NUM; i++) { -+ DBGLOG(TX, TRACE, "aucFreeBufferCount[%d]: %d, aucMaxNumOfBuffer[%d]: %d\n", -+ i, prTxCtrl->rTc.aucFreeBufferCount[i], i, -+ prTxCtrl->rTc.aucMaxNumOfBuffer[i]); -+ } -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[0]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[0]); -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[1]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[1]); -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[2]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[2]); -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[3]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[3]); -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[4]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[4]); -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[5]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[5]); -+#endif -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX]); -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX]); -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX]); -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX]); -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX]); -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX]); -+ bStatus = TRUE; -+ } -+ -+ return bStatus; -+} /* end of nicTxReleaseResource() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Reset TC Buffer Count to initialized value -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxResetResource(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicTxResetResource"); -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0; -+ prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1; -+ prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2; -+ prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3; -+ prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4; -+ prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5; -+ prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Driver maintain a variable that is synchronous with the usage of individual -+* TC Buffer Count. This function will return the value for other component -+* which needs this information for making decisions -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param ucTC Specify the resource of TC -+* -+* @retval UINT_8 The number of corresponding TC number -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 nicTxGetResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ ASSERT(prTxCtrl); -+ -+ if (ucTC >= TC_NUM) -+ return 0; -+ else -+ return prTxCtrl->rTc.aucFreeBufferCount[ucTC]; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief In this function, we'll aggregate frame(PACKET_INFO_T) -+* corresponding to HIF TX port -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prMsduInfoListHead a link list of P_MSDU_INFO_T -+* -+* @retval WLAN_STATUS_SUCCESS Bus access ok. -+* @retval WLAN_STATUS_FAILURE Bus access fail. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxMsduInfoList(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ P_MSDU_INFO_T prMsduInfo, prNextMsduInfo; -+ QUE_T qDataPort0, qDataPort1; -+ WLAN_STATUS status; -+ BOOLEAN pfgIsSecOrMgmt = FALSE; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfoListHead); -+ -+ prMsduInfo = prMsduInfoListHead; -+ -+ QUEUE_INITIALIZE(&qDataPort0); -+ QUEUE_INITIALIZE(&qDataPort1); -+ -+ /* Separate MSDU_INFO_T lists into 2 categories: for Port#0 & Port#1 */ -+ while (prMsduInfo) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+#if DBG && 0 -+ LOG_FUNC("nicTxMsduInfoList Acquire TC %d net %u mac len %u len %u Type %u 1x %u 11 %u\n", -+ prMsduInfo->ucTC, -+ prMsduInfo->ucNetworkType, -+ prMsduInfo->ucMacHeaderLength, -+ prMsduInfo->u2FrameLength, -+ prMsduInfo->ucPacketType, prMsduInfo->fgIs802_1x, prMsduInfo->fgIs802_11); -+ -+ LOG_FUNC("Dest Mac: %pM\n", prMsduInfo->aucEthDestAddr); -+#endif -+ -+ /* double-check available TX resouce (need to sync with CONNSYS FW) */ -+ /* caller must guarantee that the TX resource is enough in the func; OR assert here */ -+ switch (prMsduInfo->ucTC) { -+ case TC0_INDEX: -+ case TC1_INDEX: -+ case TC2_INDEX: -+ case TC3_INDEX: -+ case TC5_INDEX: /* Broadcast/multicast data packets */ -+ QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL; -+ QUEUE_INSERT_TAIL(&qDataPort0, (P_QUE_ENTRY_T) prMsduInfo); -+ status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC, FALSE); -+ ASSERT(status == WLAN_STATUS_SUCCESS) -+ -+ break; -+ -+ case TC4_INDEX: /* Command or 802.1x packets */ -+ QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL; -+ QUEUE_INSERT_TAIL(&qDataPort1, (P_QUE_ENTRY_T) prMsduInfo); -+ -+ if ((prMsduInfo->fgIs802_1x == TRUE) || -+ (prMsduInfo->fgIs802_11 == TRUE)) -+ pfgIsSecOrMgmt = TRUE; -+ -+ status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC, pfgIsSecOrMgmt); -+ ASSERT(status == WLAN_STATUS_SUCCESS) -+ -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+ -+ prMsduInfo = prNextMsduInfo; -+ } -+ -+ /* send packets to HIF port0 or port1 here */ -+ if (qDataPort0.u4NumElem > 0) -+ nicTxMsduQueue(prAdapter, 0, &qDataPort0); -+ -+ if (qDataPort1.u4NumElem > 0) -+ nicTxMsduQueue(prAdapter, 1, &qDataPort1); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ -+#if CFG_PRINT_RTP_PROFILE -+PKT_PROFILE_T rPrevRoundLastPkt; -+ -+BOOLEAN -+nicTxLifetimePrintCheckRTP(IN P_MSDU_INFO_T prPrevProfileMsduInfo, -+ IN P_PKT_PROFILE_T prPrevRoundLastPkt, -+ IN P_PKT_PROFILE_T prPktProfile, -+ IN OUT PBOOLEAN pfgGotFirst, IN UINT_32 u4MaxDeltaTime, IN UINT_8 ucSnToBePrinted) -+{ -+ BOOLEAN fgPrintCurPkt = FALSE; -+ -+ if (u4MaxDeltaTime) { -+ /* 4 1. check delta between current round first pkt and prevous round last pkt */ -+ if (!*pfgGotFirst) { -+ *pfgGotFirst = TRUE; -+ -+ if (prPrevRoundLastPkt->fgIsValid) { -+ if (CHK_PROFILES_DELTA(prPktProfile, prPrevRoundLastPkt, u4MaxDeltaTime)) { -+ PRINT_PKT_PROFILE(prPrevRoundLastPkt, "PR"); -+ fgPrintCurPkt = TRUE; -+ } -+ } -+ } -+ /* 4 2. check delta between current pkt and previous pkt */ -+ if (prPrevProfileMsduInfo) { -+ if (CHK_PROFILES_DELTA(prPktProfile, &prPrevProfileMsduInfo->rPktProfile, u4MaxDeltaTime)) { -+ PRINT_PKT_PROFILE(&prPrevProfileMsduInfo->rPktProfile, "P"); -+ fgPrintCurPkt = TRUE; -+ } -+ } -+ /* 4 3. check delta of current pkt lifetime */ -+ if (CHK_PROFILE_DELTA(prPktProfile, u4MaxDeltaTime)) -+ fgPrintCurPkt = TRUE; -+ } -+ /* 4 4. print every X RTP packets */ -+#if CFG_SUPPORT_WFD -+ if ((ucSnToBePrinted != 0) && (prPktProfile->u2RtpSn % ucSnToBePrinted) == 0) -+ fgPrintCurPkt = TRUE; -+#endif -+ -+ return fgPrintCurPkt; -+} -+ -+BOOLEAN -+nicTxLifetimePrintCheckSnOrder(IN P_MSDU_INFO_T prPrevProfileMsduInfo, -+ IN P_PKT_PROFILE_T prPrevRoundLastPkt, -+ IN P_PKT_PROFILE_T prPktProfile, IN OUT PBOOLEAN pfgGotFirst, IN UINT_8 ucLayer) -+{ -+ BOOLEAN fgPrintCurPkt = FALSE; -+ P_PKT_PROFILE_T prTarPktProfile = NULL; -+ UINT_16 u2PredictSn = 0; -+ UINT_16 u2CurrentSn = 0; -+ UINT_8 aucNote[8]; -+ -+ /* 4 1. Get the target packet profile to compare */ -+ -+ /* 4 1.1 check SN between current round first pkt and prevous round last pkt */ -+ if ((!*pfgGotFirst) && (prPrevRoundLastPkt->fgIsValid)) { -+ *pfgGotFirst = TRUE; -+ prTarPktProfile = prPrevRoundLastPkt; -+ kalMemCopy(aucNote, "PR\0", 3); -+ } -+ /* 4 1.2 check SN between current pkt and previous pkt */ -+ else if (prPrevProfileMsduInfo) { -+ prTarPktProfile = &prPrevProfileMsduInfo->rPktProfile; -+ kalMemCopy(aucNote, "P\0", 2); -+ } -+ -+ if (!prTarPktProfile) -+ return FALSE; -+ /* 4 2. Check IP or RTP SN */ -+ switch (ucLayer) { -+ /* Check IP SN */ -+ case 0: -+ u2PredictSn = prTarPktProfile->u2IpSn + 1; -+ u2CurrentSn = prPktProfile->u2IpSn; -+ break; -+ /* Check RTP SN */ -+ case 1: -+ default: -+ u2PredictSn = prTarPktProfile->u2RtpSn + 1; -+ u2CurrentSn = prPktProfile->u2RtpSn; -+ break; -+ -+ } -+ /* 4 */ -+ /* 4 3. Compare SN */ -+ if (u2CurrentSn != u2PredictSn) { -+ PRINT_PKT_PROFILE(prTarPktProfile, aucNote); -+ fgPrintCurPkt = TRUE; -+ } -+ -+ return fgPrintCurPkt; -+} -+#endif -+ -+VOID nicTxReturnMsduInfoProfiling(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo; -+ P_PKT_PROFILE_T prPktProfile; -+ UINT_16 u2MagicCode = 0; -+ -+ UINT_8 ucDebugtMode = 0; -+#if CFG_PRINT_RTP_PROFILE -+ P_MSDU_INFO_T prPrevProfileMsduInfo = NULL; -+ P_PKT_PROFILE_T prPrevRoundLastPkt = &rPrevRoundLastPkt; -+ -+ BOOLEAN fgPrintCurPkt = FALSE; -+ BOOLEAN fgGotFirst = FALSE; -+ UINT_8 ucSnToBePrinted = 0; -+ -+ UINT_32 u4MaxDeltaTime = 50; /* in ms */ -+#endif -+ -+#if CFG_ENABLE_PER_STA_STATISTICS -+ UINT_32 u4PktPrintPeriod = 0; -+#endif -+ -+#if CFG_SUPPORT_WFD -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ if (prAdapter->fgIsP2PRegistered) { -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ u2MagicCode = prWfdCfgSettings->u2WfdMaximumTp; -+ ucDebugtMode = prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.ucWfdDebugMode; -+ /* if(prWfdCfgSettings->ucWfdEnable && (prWfdCfgSettings->u4WfdFlag & BIT(0))) { */ -+ /* u2MagicCode = 0xE040; */ -+ /* } */ -+ } -+#endif -+ -+#if CFG_PRINT_RTP_PROFILE -+ if ((u2MagicCode >= 0xF000)) { -+ ucSnToBePrinted = (UINT_8) (u2MagicCode & BITS(0, 7)); -+ u4MaxDeltaTime = (UINT_8) (((u2MagicCode & BITS(8, 11)) >> 8) * 10); -+ } else { -+ ucSnToBePrinted = 0; -+ u4MaxDeltaTime = 0; -+ } -+ -+#endif -+ -+#if CFG_ENABLE_PER_STA_STATISTICS -+ if ((u2MagicCode >= 0xE000) && (u2MagicCode < 0xF000)) -+ u4PktPrintPeriod = (UINT_32) ((u2MagicCode & BITS(0, 7)) * 32); -+ else -+ u4PktPrintPeriod = 0; -+#endif -+ -+ while (prMsduInfo) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+ prPktProfile = &prMsduInfo->rPktProfile; -+ -+ if (prPktProfile->fgIsValid) { -+ -+ prPktProfile->rHifTxDoneTimestamp = kalGetTimeTick(); -+ if (ucDebugtMode > 1) { -+ -+#if CFG_PRINT_RTP_PROFILE -+#if CFG_PRINT_RTP_SN_SKIP -+ fgPrintCurPkt = nicTxLifetimePrintCheckSnOrder(prPrevProfileMsduInfo, -+ prPrevRoundLastPkt, -+ prPktProfile, &fgGotFirst, 0); -+#else -+ fgPrintCurPkt = nicTxLifetimePrintCheckRTP(prPrevProfileMsduInfo, -+ prPrevRoundLastPkt, -+ prPktProfile, -+ &fgGotFirst, -+ u4MaxDeltaTime, ucSnToBePrinted); -+#endif -+ -+ /* Print current pkt profile */ -+ if (fgPrintCurPkt && ucDebugtMode > 1) -+ PRINT_PKT_PROFILE(prPktProfile, "C"); -+ -+ prPrevProfileMsduInfo = prMsduInfo; -+ fgPrintCurPkt = FALSE; -+#endif -+ } -+#if CFG_ENABLE_PER_STA_STATISTICS -+ { -+ P_STA_RECORD_T prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ UINT_32 u4DeltaTime; -+ UINT_32 u4DeltaHifTime; -+#if 0 -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+#endif -+ UINT_8 ucNetIndex; -+ -+ if (prStaRec) { -+ ucNetIndex = prStaRec->ucNetTypeIndex; -+ u4DeltaTime = (UINT_32) (prPktProfile->rHifTxDoneTimestamp - -+ prPktProfile->rHardXmitArrivalTimestamp); -+ u4DeltaHifTime = (UINT_32) (prPktProfile->rHifTxDoneTimestamp - -+ prPktProfile->rDequeueTimestamp); -+ prStaRec->u4TotalTxPktsNumber++; -+ -+ prStaRec->u4TotalTxPktsTime += u4DeltaTime; -+ prStaRec->u4TotalTxPktsHifTime += u4DeltaHifTime; -+ -+ if (u4DeltaTime > prStaRec->u4MaxTxPktsTime) -+ prStaRec->u4MaxTxPktsTime = u4DeltaTime; -+ -+ if (u4DeltaHifTime > prStaRec->u4MaxTxPktsHifTime) -+ prStaRec->u4MaxTxPktsHifTime = u4DeltaHifTime; -+ -+ -+ if (u4DeltaTime >= NIC_TX_TIME_THRESHOLD) -+ prStaRec->u4ThresholdCounter++; -+#if 0 -+ if (u4PktPrintPeriod && (prStaRec->u4TotalTxPktsNumber >= u4PktPrintPeriod)) { -+ -+ DBGLOG(TX, TRACE, "[%u]N[%4u]A[%5u]M[%4u]T[%4u]E[%4u]\n", -+ prStaRec->ucIndex, -+ prStaRec->u4TotalTxPktsNumber, -+ prStaRec->u4TotalTxPktsTime / prStaRec->u4TotalTxPktsNumber, -+ prStaRec->u4MaxTxPktsTime, -+ prStaRec->u4ThresholdCounter, -+ prQM->au4QmTcResourceEmptyCounter[ucNetIndex][TC2_INDEX]); -+ -+ prStaRec->u4TotalTxPktsNumber = 0; -+ prStaRec->u4TotalTxPktsTime = 0; -+ prStaRec->u4MaxTxPktsTime = 0; -+ prStaRec->u4ThresholdCounter = 0; -+ prQM->au4QmTcResourceEmptyCounter[ucNetIndex][TC2_INDEX] = 0; -+ } -+#endif -+ } -+ -+ } -+#endif -+ } -+ -+ prMsduInfo = prNextMsduInfo; -+ }; -+ -+#if CFG_PRINT_RTP_PROFILE -+ /* 4 4. record the lifetime of current round last pkt */ -+ if (prPrevProfileMsduInfo) { -+ prPktProfile = &prPrevProfileMsduInfo->rPktProfile; -+ prPrevRoundLastPkt->u2IpSn = prPktProfile->u2IpSn; -+ prPrevRoundLastPkt->u2RtpSn = prPktProfile->u2RtpSn; -+ prPrevRoundLastPkt->rHardXmitArrivalTimestamp = prPktProfile->rHardXmitArrivalTimestamp; -+ prPrevRoundLastPkt->rEnqueueTimestamp = prPktProfile->rEnqueueTimestamp; -+ prPrevRoundLastPkt->rDequeueTimestamp = prPktProfile->rDequeueTimestamp; -+ prPrevRoundLastPkt->rHifTxDoneTimestamp = prPktProfile->rHifTxDoneTimestamp; -+ prPrevRoundLastPkt->ucTcxFreeCount = prPktProfile->ucTcxFreeCount; -+ prPrevRoundLastPkt->fgIsPrinted = prPktProfile->fgIsPrinted; -+ prPrevRoundLastPkt->fgIsValid = TRUE; -+ } -+#endif -+ -+ nicTxReturnMsduInfo(prAdapter, prMsduInfoListHead); -+ -+} -+ -+VOID nicTxLifetimeRecordEn(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket) -+{ -+ P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile; -+ -+ /* Enable packet lifetime profiling */ -+ prPktProfile->fgIsValid = TRUE; -+ -+ /* Packet arrival time at kernel Hard Xmit */ -+ prPktProfile->rHardXmitArrivalTimestamp = GLUE_GET_PKT_ARRIVAL_TIME(prPacket); -+ -+ /* Packet enqueue time */ -+ prPktProfile->rEnqueueTimestamp = (OS_SYSTIME) kalGetTimeTick(); -+ -+} -+ -+#if CFG_PRINT_RTP_PROFILE -+/* -+ in: -+ data RTP packet pointer -+ size RTP size -+ return -+ 0:audio 1: video, -1:none -+*/ -+UINT8 checkRtpAV(PUINT_8 data, UINT_32 size) -+{ -+ PUINT_8 buf = data + 12; -+ -+ while (buf + 188 <= data + size) { -+ int pid = ((buf[1] << 8) & 0x1F00) | (buf[2] & 0xFF); -+ -+ if (pid == 0 || pid == 0x100 || pid == 0x1000) -+ buf += 188; -+ else if (pid == 0x1100) -+ return 0; -+ else if (pid == 0x1011) -+ return 1; -+ } -+ return -1; -+} -+ -+VOID -+nicTxLifetimeCheckRTP(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, -+ IN P_NATIVE_PACKET prPacket, IN UINT_32 u4PacketLen, IN UINT_8 ucNetworkType) -+{ -+ struct sk_buff *prSkb = (struct sk_buff *)prPacket; -+ UINT_16 u2EtherTypeLen; -+ PUINT_8 aucLookAheadBuf = NULL; -+ P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile; -+ -+ /* UINT_8 ucRtpHdrOffset = 28; */ -+ UINT_8 ucRtpSnOffset = 30; -+ /* UINT_32 u4RtpSrcPort = 15550; */ -+ P_TX_CTRL_T prTxCtrl; -+#if CFG_SUPPORT_WFD -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_WFD_DBG_CFG_SETTINGS_T prWfdDbgSettings = (P_WFD_DBG_CFG_SETTINGS_T) NULL; -+ -+ BOOLEAN fgEnProfiling = FALSE; -+ -+ if (prAdapter->fgIsP2PRegistered) { -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ prWfdDbgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting; -+#if CFG_PRINT_RTP_SN_SKIP -+ if (ucNetworkType == NETWORK_TYPE_P2P_INDEX) { -+ fgEnProfiling = TRUE; -+ } else -+#endif -+ if (((prWfdCfgSettings->u2WfdMaximumTp >= 0xF000) || -+ (prWfdDbgSettings->ucWfdDebugMode > 0)) && (ucNetworkType == NETWORK_TYPE_P2P_INDEX)) { -+ fgEnProfiling = TRUE; -+ } -+ } -+ -+ if (fgEnProfiling == FALSE) { -+ /* prPktProfile->fgIsValid = FALSE; */ -+ return; -+ } -+#endif -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ /* prPktProfile->fgIsValid = FALSE; */ -+ -+ aucLookAheadBuf = prSkb->data; -+ -+ u2EtherTypeLen = (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET] << 8) | (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ if ((u2EtherTypeLen == ETH_P_IP) && (u4PacketLen >= LOOK_AHEAD_LEN)) { -+ PUINT_8 pucIpHdr = &aucLookAheadBuf[ETH_HLEN]; -+ UINT_16 u2tmpIpSN = 0; -+ UINT_8 ucIpVersion; -+ -+ ucIpVersion = (pucIpHdr[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; -+ if (ucIpVersion == IPVERSION) { -+ if (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP) { -+ -+ /* if(checkRtpAV(&pucIpHdr[ucRtpHdrOffset], -+ (u4PacketLen - ETH_HLEN - ucRtpHdrOffset)) == 0) { */ -+ -+ if (prPktProfile->fgIsValid == FALSE) -+ nicTxLifetimeRecordEn(prAdapter, prMsduInfo, prPacket); -+ -+ prPktProfile->fgIsPrinted = FALSE; -+ -+ prPktProfile->ucTcxFreeCount = prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX]; -+ -+ /* RTP SN */ -+ prPktProfile->u2RtpSn = pucIpHdr[ucRtpSnOffset] << 8 | pucIpHdr[ucRtpSnOffset + 1]; -+ -+ /* IP SN */ -+ prPktProfile->u2IpSn = pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET] << 8 | -+ pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET + 1]; -+ u2tmpIpSN = prPktProfile->u2IpSn; -+ if (prWfdDbgSettings->ucWfdDebugMode == 1) { -+ if ((u2tmpIpSN & (prWfdDbgSettings->u2WfdSNShowPeiroid)) == 0) -+ DBGLOG(TX, TRACE, -+ "RtpSn=%d IPId=%d j=%lu\n", prPktProfile->u2RtpSn, -+ prPktProfile->u2IpSn, jiffies); -+ } -+ /* } */ -+ } -+ } -+ } -+ -+} -+#endif -+#if CFG_ENABLE_PER_STA_STATISTICS -+VOID -+nicTxLifetimeCheckByAC(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket, IN UINT_8 ucPriorityParam) -+{ -+ switch (ucPriorityParam) { -+ /* BK */ -+ /* case 1: */ -+ /* case 2: */ -+ -+ /* BE */ -+ /* case 0: */ -+ /* case 3: */ -+ -+ /* VI */ -+ case 4: -+ case 5: -+ -+ /* VO */ -+ case 6: -+ case 7: -+ nicTxLifetimeRecordEn(prAdapter, prMsduInfo, prPacket); -+ break; -+ default: -+ break; -+ } -+} -+ -+#endif -+ -+VOID -+nicTxLifetimeCheck(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, -+ IN P_NATIVE_PACKET prPacket, -+ IN UINT_8 ucPriorityParam, IN UINT_32 u4PacketLen, IN UINT_8 ucNetworkType) -+{ -+ P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile; -+ -+ /* Reset packet profile */ -+ prPktProfile->fgIsValid = FALSE; -+ -+#if CFG_ENABLE_PER_STA_STATISTICS -+ nicTxLifetimeCheckByAC(prAdapter, prMsduInfo, prPacket, ucPriorityParam); -+#endif -+ -+#if CFG_PRINT_RTP_PROFILE -+ nicTxLifetimeCheckRTP(prAdapter, prMsduInfo, prPacket, u4PacketLen, ucNetworkType); -+#endif -+ -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief In this function, we'll write frame(PACKET_INFO_T) into HIF. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param ucPortIdx Port Number -+* @param prQue a link list of P_MSDU_INFO_T -+* -+* @retval WLAN_STATUS_SUCCESS Bus access ok. -+* @retval WLAN_STATUS_FAILURE Bus access fail. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxMsduQueue(IN P_ADAPTER_T prAdapter, UINT_8 ucPortIdx, P_QUE_T prQue) -+{ -+ P_MSDU_INFO_T prMsduInfo, prNextMsduInfo; -+ HIF_TX_HEADER_T rHwTxHeader; -+ P_NATIVE_PACKET prNativePacket; -+ UINT_16 u2OverallBufferLength; -+ UINT_8 ucEtherTypeOffsetInWord; -+ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ -+ UINT_32 u4TxHdrSize; -+ UINT_32 u4ValidBufSize; -+ UINT_32 u4TotalLength; -+ P_TX_CTRL_T prTxCtrl; -+ QUE_T rFreeQueue; -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ UINT_8 ucChksumFlag; -+#endif -+ -+ ASSERT(prAdapter); -+ ASSERT(ucPortIdx < 2); -+ ASSERT(prQue); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ u4ValidBufSize = prAdapter->u4CoalescingBufCachedSize; -+ -+#if CFG_HIF_STATISTICS -+ prTxCtrl->u4TotalTxAccessNum++; -+ prTxCtrl->u4TotalTxPacketNum += prQue->u4NumElem; -+#endif -+ -+ QUEUE_INITIALIZE(&rFreeQueue); -+ -+ if (prQue->u4NumElem > 0) { -+ prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_HEAD(prQue); -+ pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; -+ u4TotalLength = 0; -+ -+ while (prMsduInfo) { -+ -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ { -+ struct sk_buff *prSkb = (struct sk_buff *)prMsduInfo->prPacket; -+ UINT8 *pkt = prSkb->data; -+ UINT16 u2Identifier; -+ -+ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { -+ /* ip */ -+ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); -+ DBGLOG(TX, TRACE, " %d\n", u2Identifier); -+ } -+ } -+#endif -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ kalMetProfilingFinish(prAdapter, prMsduInfo); -+#endif -+ kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader)); -+ -+ prNativePacket = prMsduInfo->prPacket; -+ -+ ASSERT(prNativePacket); -+ -+ u4TxHdrSize = TX_HDR_SIZE; -+ -+ u2OverallBufferLength = ((prMsduInfo->u2FrameLength + TX_HDR_SIZE) & -+ (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ -+ /* init TX header */ -+ rHwTxHeader.u2TxByteCount_UserPriority = u2OverallBufferLength; -+ rHwTxHeader.u2TxByteCount_UserPriority |= -+ ((UINT_16) prMsduInfo->ucUserPriority << HIF_TX_HDR_USER_PRIORITY_OFFSET); -+ -+ if (prMsduInfo->fgIs802_11) { -+ ucEtherTypeOffsetInWord = -+ (TX_HDR_SIZE + prMsduInfo->ucMacHeaderLength + prMsduInfo->ucLlcLength) >> 1; -+ } else { -+ ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + TX_HDR_SIZE) >> 1; -+ } -+ -+ rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK; -+ -+ rHwTxHeader.ucResource_PktType_CSflags = (prMsduInfo->ucTC) << HIF_TX_HDR_RESOURCE_OFFSET; -+ rHwTxHeader.ucResource_PktType_CSflags |= -+ (UINT_8) (((prMsduInfo->ucPacketType) << HIF_TX_HDR_PACKET_TYPE_OFFSET) & -+ (HIF_TX_HDR_PACKET_TYPE_MASK)); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) { -+ if (prAdapter->u4CSUMFlags & -+ (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP)) { -+ kalQueryTxChksumOffloadParam(prNativePacket, &ucChksumFlag); -+ -+ if (ucChksumFlag & TX_CS_IP_GEN) -+ rHwTxHeader.ucResource_PktType_CSflags |= (UINT_8) HIF_TX_HDR_IP_CSUM; -+ -+ if (ucChksumFlag & TX_CS_TCP_UDP_GEN) -+ rHwTxHeader.ucResource_PktType_CSflags |= (UINT_8) HIF_TX_HDR_TCP_CSUM; -+ } -+ } -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+ rHwTxHeader.u2LLH = prMsduInfo->u2PalLLH; -+ rHwTxHeader.ucStaRecIdx = prMsduInfo->ucStaRecIndex; -+ rHwTxHeader.ucForwardingType_SessionID_Reserved = -+ (prMsduInfo->ucPsForwardingType) | ((prMsduInfo->ucPsSessionID) << -+ HIF_TX_HDR_PS_SESSION_ID_OFFSET) -+ | ((prMsduInfo->fgIsBurstEnd) ? HIF_TX_HDR_BURST_END_MASK : 0); -+ -+ rHwTxHeader.ucWlanHeaderLength = -+ (prMsduInfo->ucMacHeaderLength & HIF_TX_HDR_WLAN_HEADER_LEN_MASK); -+ rHwTxHeader.ucPktFormtId_Flags = (prMsduInfo->ucFormatID & HIF_TX_HDR_FORMAT_ID_MASK) -+ | ((prMsduInfo->ucNetworkType << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & -+ HIF_TX_HDR_NETWORK_TYPE_MASK) -+ | ((prMsduInfo->fgIs802_1x << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & -+ HIF_TX_HDR_FLAG_1X_FRAME_MASK) -+ | ((prMsduInfo->fgIs802_11 << HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET) & -+ HIF_TX_HDR_FLAG_802_11_FORMAT_MASK); -+ -+ rHwTxHeader.u2SeqNo = prMsduInfo->u2AclSN; -+ -+ if (prMsduInfo->pfTxDoneHandler) { -+ rHwTxHeader.ucPacketSeqNo = prMsduInfo->ucTxSeqNum; -+ rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_ACK; -+ } else { -+ rHwTxHeader.ucPacketSeqNo = 0; -+ rHwTxHeader.ucAck_BIP_BasicRate = 0; -+ } -+ -+ if (prMsduInfo->fgNeedTxDoneStatus == TRUE) -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_NEED_TX_DONE_STATUS; -+ -+ if (prMsduInfo->fgIsBIP) -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BIP; -+ -+ if (prMsduInfo->fgIsBasicRate) -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE; -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ if (prMsduInfo->rPktProfile.fgIsValid) -+ prMsduInfo->rPktProfile.rDequeueTimestamp = kalGetTimeTick(); -+#endif -+ -+ /* record the queue time in driver */ -+ STATS_TX_TIME_TO_HIF(prMsduInfo, &rHwTxHeader); -+ -+#if CFG_SDIO_TX_AGG -+ /* attach to coalescing buffer */ -+ kalMemCopy(pucOutputBuf + u4TotalLength, &rHwTxHeader, u4TxHdrSize); -+ u4TotalLength += u4TxHdrSize; -+ -+ if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) -+ kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + u4TotalLength); -+ else if (prMsduInfo->eSrc == TX_PACKET_MGMT) -+ kalMemCopy(pucOutputBuf + u4TotalLength, prNativePacket, prMsduInfo->u2FrameLength); -+ else -+ ASSERT(0); -+ -+ u4TotalLength += ALIGN_4(prMsduInfo->u2FrameLength); -+ -+#else -+ kalMemCopy(pucOutputBuf, &rHwTxHeader, u4TxHdrSize); -+ -+ /* Copy Frame Body */ -+ if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) -+ kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + u4TxHdrSize); -+ else if (prMsduInfo->eSrc == TX_PACKET_MGMT) -+ kalMemCopy(pucOutputBuf + u4TxHdrSize, prNativePacket, prMsduInfo->u2FrameLength); -+ else -+ ASSERT(0); -+ -+ ASSERT(u2OverallBufferLength <= u4ValidBufSize); -+ -+ HAL_WRITE_TX_PORT(prAdapter, -+ ucPortIdx, -+ (UINT_32) u2OverallBufferLength, (PUINT_8) pucOutputBuf, u4ValidBufSize); -+ -+ /* send immediately */ -+#endif -+ prNextMsduInfo = (P_MSDU_INFO_T) -+ QUEUE_GET_NEXT_ENTRY(&prMsduInfo->rQueEntry); -+ -+ if (prMsduInfo->eSrc == TX_PACKET_MGMT) { -+ GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); -+ -+ if (prMsduInfo->pfTxDoneHandler == NULL) { -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ } else { -+ KAL_SPIN_LOCK_DECLARATION(); -+ DBGLOG(TX, TRACE, "Wait TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ } -+ } else { -+ /* only free MSDU when it is not a MGMT frame */ -+ QUEUE_INSERT_TAIL(&rFreeQueue, (P_QUE_ENTRY_T) prMsduInfo); -+ -+ if (prMsduInfo->eSrc == TX_PACKET_OS) -+ kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_SUCCESS); -+ else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) -+ GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); -+ } -+ -+ prMsduInfo = prNextMsduInfo; -+ } -+ -+#if CFG_SDIO_TX_AGG -+ ASSERT(u4TotalLength <= u4ValidBufSize); -+ -+#if CFG_DBG_GPIO_PINS -+ { -+ /* Start port write */ -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_PORT_WRITE, DBG_TIE_LOW); -+ kalUdelay(1); -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_PORT_WRITE, DBG_TIE_HIGH); -+ } -+#endif -+ -+ /* send coalescing buffer */ -+ HAL_WRITE_TX_PORT(prAdapter, ucPortIdx, u4TotalLength, (PUINT_8) pucOutputBuf, u4ValidBufSize); -+#endif -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+#if CFG_SUPPORT_WFD && CFG_PRINT_RTP_PROFILE && !CFG_ENABLE_PER_STA_STATISTICS -+ do { -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ -+ if ((prWfdCfgSettings->u2WfdMaximumTp >= 0xF000)) { -+ /* Enable profiling */ -+ nicTxReturnMsduInfoProfiling(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); -+ } else { -+ /* Skip profiling */ -+ nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); -+ } -+ } while (FALSE); -+#else -+ nicTxReturnMsduInfoProfiling(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); -+#endif -+#else -+ /* return */ -+ nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); -+#endif -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief In this function, we'll write Command(CMD_INFO_T) into HIF. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prPacketInfo Pointer of CMD_INFO_T -+* @param ucTC Specify the resource of TC -+* -+* @retval WLAN_STATUS_SUCCESS Bus access ok. -+* @retval WLAN_STATUS_FAILURE Bus access fail. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC) -+{ -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_16 u2OverallBufferLength; -+ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ -+ UINT_8 ucPortIdx; -+ HIF_TX_HEADER_T rHwTxHeader; -+ P_NATIVE_PACKET prNativePacket; -+ UINT_8 ucEtherTypeOffsetInWord; -+ P_MSDU_INFO_T prMsduInfo; -+ P_TX_CTRL_T prTxCtrl; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; -+ -+ /* <1> Assign Data Port */ -+ if (ucTC != TC4_INDEX) { -+ ucPortIdx = 0; -+ } else { -+ /* Broadcast/multicast data frames, 1x frames, command packets, MMPDU */ -+ ucPortIdx = 1; -+ } -+ wlanTraceTxCmd(prCmdInfo); -+ -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) { -+ /* <2> Compose HIF_TX_HEADER */ -+ kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader)); -+ -+ prNativePacket = prCmdInfo->prPacket; -+ -+ ASSERT(prNativePacket); -+ -+ u2OverallBufferLength = TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen + TX_HDR_SIZE) -+ & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ -+ rHwTxHeader.u2TxByteCount_UserPriority = ((prCmdInfo->u2InfoBufLen + TX_HDR_SIZE) -+ & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + TX_HDR_SIZE) >> 1; -+ -+ rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK; -+ -+ rHwTxHeader.ucResource_PktType_CSflags = (ucTC << HIF_TX_HDR_RESOURCE_OFFSET); -+ -+ rHwTxHeader.ucStaRecIdx = prCmdInfo->ucStaRecIndex; -+ rHwTxHeader.ucForwardingType_SessionID_Reserved = HIF_TX_HDR_BURST_END_MASK; -+ -+ rHwTxHeader.ucWlanHeaderLength = (ETH_HLEN & HIF_TX_HDR_WLAN_HEADER_LEN_MASK); -+ rHwTxHeader.ucPktFormtId_Flags = -+ (((UINT_8) (prCmdInfo->eNetworkType) << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & -+ HIF_TX_HDR_NETWORK_TYPE_MASK) -+ | ((1 << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & HIF_TX_HDR_FLAG_1X_FRAME_MASK); -+ -+ rHwTxHeader.u2SeqNo = 0; -+ rHwTxHeader.ucPacketSeqNo = 0; -+ rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_TX_DONE_STATUS; -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE /* | HIF_TX_HDR_RTS */; -+ -+ /* <2.3> Copy HIF TX HEADER */ -+ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID)&rHwTxHeader, TX_HDR_SIZE); -+ -+ /* <3> Copy Frame Body Copy */ -+ kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + TX_HDR_SIZE); -+ } else if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { -+ prMsduInfo = (P_MSDU_INFO_T) prCmdInfo->prPacket; -+ -+ ASSERT(prMsduInfo->fgIs802_11 == TRUE); -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ /* <2> Compose HIF_TX_HEADER */ -+ kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader)); -+ -+ u2OverallBufferLength = ((prMsduInfo->u2FrameLength + TX_HDR_SIZE) & -+ (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ -+ rHwTxHeader.u2TxByteCount_UserPriority = u2OverallBufferLength; -+ rHwTxHeader.u2TxByteCount_UserPriority |= -+ ((UINT_16) prMsduInfo->ucUserPriority << HIF_TX_HDR_USER_PRIORITY_OFFSET); -+ -+ ucEtherTypeOffsetInWord = (TX_HDR_SIZE + prMsduInfo->ucMacHeaderLength + prMsduInfo->ucLlcLength) >> 1; -+ -+ rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK; -+ -+ rHwTxHeader.ucResource_PktType_CSflags = (prMsduInfo->ucTC) << HIF_TX_HDR_RESOURCE_OFFSET; -+ rHwTxHeader.ucResource_PktType_CSflags |= -+ (UINT_8) (((prMsduInfo->ucPacketType) << HIF_TX_HDR_PACKET_TYPE_OFFSET) & -+ (HIF_TX_HDR_PACKET_TYPE_MASK)); -+ -+ rHwTxHeader.u2LLH = prMsduInfo->u2PalLLH; -+ rHwTxHeader.ucStaRecIdx = prMsduInfo->ucStaRecIndex; -+ rHwTxHeader.ucForwardingType_SessionID_Reserved = -+ (prMsduInfo->ucPsForwardingType) | ((prMsduInfo->ucPsSessionID) << HIF_TX_HDR_PS_SESSION_ID_OFFSET) -+ | ((prMsduInfo->fgIsBurstEnd) ? HIF_TX_HDR_BURST_END_MASK : 0); -+ -+ rHwTxHeader.ucWlanHeaderLength = (prMsduInfo->ucMacHeaderLength & HIF_TX_HDR_WLAN_HEADER_LEN_MASK); -+ rHwTxHeader.ucPktFormtId_Flags = (prMsduInfo->ucFormatID & HIF_TX_HDR_FORMAT_ID_MASK) -+ | ((prMsduInfo->ucNetworkType << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & HIF_TX_HDR_NETWORK_TYPE_MASK) -+ | ((prMsduInfo->fgIs802_1x << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & HIF_TX_HDR_FLAG_1X_FRAME_MASK) -+ | ((prMsduInfo->fgIs802_11 << HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET) & -+ HIF_TX_HDR_FLAG_802_11_FORMAT_MASK); -+ -+ rHwTxHeader.u2SeqNo = prMsduInfo->u2AclSN; -+ -+ if (prMsduInfo->pfTxDoneHandler) { -+ rHwTxHeader.ucPacketSeqNo = prMsduInfo->ucTxSeqNum; -+ rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_ACK; -+ } else { -+ rHwTxHeader.ucPacketSeqNo = 0; -+ rHwTxHeader.ucAck_BIP_BasicRate = 0; -+ } -+ -+ if (prMsduInfo->fgIsBIP) -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BIP; -+ -+ if (prMsduInfo->fgIsBasicRate) -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE; -+ /* <2.3> Copy HIF TX HEADER */ -+ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID)&rHwTxHeader, TX_HDR_SIZE); -+ -+ /* <3> Copy Frame Body */ -+ kalMemCopy(pucOutputBuf + TX_HDR_SIZE, prMsduInfo->prPacket, prMsduInfo->u2FrameLength); -+ -+ /* <4> Management Frame Post-Processing */ -+ GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); -+ -+ if (prMsduInfo->pfTxDoneHandler == NULL) { -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ } else { -+ -+ DBGLOG(TX, TRACE, "Wait Cmd TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ } -+ } else { -+ prWifiCmd = (P_WIFI_CMD_T) prCmdInfo->pucInfoBuffer; -+ -+ /* <2> Compose the Header of Transmit Data Structure for CMD Packet */ -+ u2OverallBufferLength = -+ TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ -+ prWifiCmd->u2TxByteCount_UserPriority = u2OverallBufferLength; -+ prWifiCmd->ucEtherTypeOffset = 0; -+ prWifiCmd->ucResource_PktType_CSflags = (ucTC << HIF_TX_HDR_RESOURCE_OFFSET) -+ | (UINT_8) ((HIF_TX_PKT_TYPE_CMD << HIF_TX_HDR_PACKET_TYPE_OFFSET) & (HIF_TX_HDR_PACKET_TYPE_MASK)); -+ -+ /* <3> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */ -+ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen); -+ -+ ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize); -+ -+ if ((prCmdInfo->ucCID == CMD_ID_SCAN_REQ) || -+ (prCmdInfo->ucCID == CMD_ID_SCAN_CANCEL) || -+ (prCmdInfo->ucCID == CMD_ID_SCAN_REQ_V2)) -+ DBGLOG(TX, INFO, "ucCmdSeqNum =%d, ucCID =%d\n", prCmdInfo->ucCmdSeqNum, prCmdInfo->ucCID); -+ } -+ -+ /* <4> Write frame to data port */ -+ HAL_WRITE_TX_PORT(prAdapter, -+ ucPortIdx, -+ (UINT_32) u2OverallBufferLength, -+ (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of nicTxCmd() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will clean up all the pending frames in internal SW Queues -+* by return the pending TX packet to the system. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicTxRelease(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ nicTxFlush(prAdapter); -+ -+ /* free MSDU_INFO_T from rTxMgmtMsduInfoList */ -+ do { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ QUEUE_REMOVE_HEAD(&prTxCtrl->rTxMgmtTxingQueue, prMsduInfo, P_MSDU_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ if (prMsduInfo) { -+ /* the packet must be mgmt frame with tx done callback */ -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ /* invoke done handler */ -+ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_LIFE_TIMEOUT); -+ -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ } else { -+ break; -+ } -+ } while (TRUE); -+ -+} /* end of nicTxRelease() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process the TX Done interrupt and pull in more pending frames in SW -+* Queues for transmission. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicProcessTxInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+#if CFG_SDIO_INTR_ENHANCE -+ P_SDIO_CTRL_T prSDIOCtrl; -+#else -+ UINT_32 au4TxCount[2]; -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ ASSERT(prTxCtrl); -+ prGlueInfo->IsrTxCnt++; -+ -+ /* Get the TX STATUS */ -+#if CFG_SDIO_INTR_ENHANCE -+ -+ prSDIOCtrl = prAdapter->prSDIOCtrl; -+#if DBG -+ /* dumpMemory8((PUINT_8)prSDIOCtrl, sizeof(SDIO_CTRL_T)); */ -+#endif -+ -+ nicTxReleaseResource(prAdapter, (PUINT_8) &prSDIOCtrl->rTxInfo); -+ kalMemZero(&prSDIOCtrl->rTxInfo, sizeof(prSDIOCtrl->rTxInfo)); -+ -+#else -+ -+ HAL_MCR_RD(prAdapter, MCR_WTSR0, &au4TxCount[0]); -+ HAL_MCR_RD(prAdapter, MCR_WTSR1, &au4TxCount[1]); -+ DBGLOG(EMU, TRACE, "MCR_WTSR0: 0x%x, MCR_WTSR1: 0x%x\n", au4TxCount[0], au4TxCount[1]); -+ -+ nicTxReleaseResource(prAdapter, (PUINT_8) au4TxCount); -+ -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+ nicTxAdjustTcq(prAdapter); -+ -+ /* Indicate Service Thread */ -+ if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0) -+ kalSetEvent(prAdapter->prGlueInfo); -+ -+} /* end of nicProcessTxInterrupt() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function frees packet of P_MSDU_INFO_T linked-list -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prMsduInfoList a link list of P_MSDU_INFO_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicTxFreeMsduInfoPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ P_NATIVE_PACKET prNativePacket; -+ P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead; -+ P_TX_CTRL_T prTxCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfoListHead); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ while (prMsduInfo) { -+ prNativePacket = prMsduInfo->prPacket; -+ -+ if (prMsduInfo->eSrc == TX_PACKET_OS) { -+ kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_FAILURE); -+ } else if (prMsduInfo->eSrc == TX_PACKET_MGMT) { -+ P_MSDU_INFO_T prTempMsduInfo = prMsduInfo; -+ -+ if (prMsduInfo->pfTxDoneHandler) -+ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER); -+ prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+ cnmMgtPktFree(prAdapter, prTempMsduInfo); -+ continue; -+ } else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) { -+ GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); -+ } -+ -+ prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function returns P_MSDU_INFO_T of MsduInfoList to TxCtrl->rfreeMsduInfoList -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prMsduInfoList a link list of P_MSDU_INFO_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicTxReturnMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ ASSERT(prTxCtrl); -+ -+ while (prMsduInfo) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+ -+ switch (prMsduInfo->eSrc) { -+ case TX_PACKET_FORWARDING: -+ wlanReturnPacket(prAdapter, prMsduInfo->prPacket); -+ break; -+ case TX_PACKET_OS: -+ case TX_PACKET_OS_OID: -+ case TX_PACKET_MGMT: -+ default: -+ break; -+ } -+ -+ /* Reset MSDU_INFO fields */ -+ kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T)); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ prMsduInfo = prNextMsduInfo; -+ }; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function fills packet information to P_MSDU_INFO_T -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prMsduInfo P_MSDU_INFO_T -+* @param prPacket P_NATIVE_PACKET -+* -+* @retval TRUE Success to extract information -+* @retval FALSE Fail to extract correct information -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN nicTxFillMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_8 ucPriorityParam; -+ UINT_8 ucMacHeaderLen; -+ UINT_8 aucEthDestAddr[PARAM_MAC_ADDR_LEN]; -+ BOOLEAN fgIs1x = FALSE; -+ BOOLEAN fgIsPAL = FALSE; -+ UINT_32 u4PacketLen; -+ ULONG u4SysTime; -+ UINT_8 ucNetworkType; -+ struct sk_buff *prSkb = (struct sk_buff *)prPacket; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ ASSERT(prGlueInfo); -+ -+ if (kalQoSFrameClassifierAndPacketInfo(prGlueInfo, -+ prPacket, -+ &ucPriorityParam, -+ &u4PacketLen, -+ aucEthDestAddr, -+ &fgIs1x, &fgIsPAL, &ucNetworkType, -+ NULL) == FALSE) { -+ return FALSE; -+ } -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ nicTxLifetimeCheck(prAdapter, prMsduInfo, prPacket, ucPriorityParam, u4PacketLen, ucNetworkType); -+#endif -+ -+ /* Save the value of Priority Parameter */ -+ GLUE_SET_PKT_TID(prPacket, ucPriorityParam); -+ -+ if (fgIs1x) -+ GLUE_SET_PKT_FLAG_1X(prPacket); -+ -+ if (fgIsPAL) -+ GLUE_SET_PKT_FLAG_PAL(prPacket); -+ -+ ucMacHeaderLen = ETH_HLEN; -+ -+ /* Save the value of Header Length */ -+ GLUE_SET_PKT_HEADER_LEN(prPacket, ucMacHeaderLen); -+ -+ /* Save the value of Frame Length */ -+ GLUE_SET_PKT_FRAME_LEN(prPacket, (UINT_16) u4PacketLen); -+ -+ /* Save the value of Arrival Time */ -+ u4SysTime = (OS_SYSTIME) kalGetTimeTick(); -+ GLUE_SET_PKT_ARRIVAL_TIME(prPacket, u4SysTime); -+ -+ prMsduInfo->prPacket = prPacket; -+ prMsduInfo->fgIs802_1x = fgIs1x; -+ prMsduInfo->fgIs802_11 = FALSE; -+ prMsduInfo->ucNetworkType = ucNetworkType; -+ prMsduInfo->ucUserPriority = ucPriorityParam; -+ prMsduInfo->ucMacHeaderLength = ucMacHeaderLen; -+ prMsduInfo->u2FrameLength = (UINT_16) u4PacketLen; -+ COPY_MAC_ADDR(prMsduInfo->aucEthDestAddr, aucEthDestAddr); -+ -+ if (prSkb->len > ETH_HLEN) -+ STATS_TX_PKT_CALLBACK(prSkb->data, prMsduInfo); -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function update TCQ values by passing current status to txAdjustTcQuotas -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @retval WLAN_STATUS_SUCCESS Updated successfully -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxAdjustTcq(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4Num; -+ TX_TCQ_ADJUST_T rTcqAdjust; -+ P_TX_CTRL_T prTxCtrl; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ ASSERT(prTxCtrl); -+ -+ qmAdjustTcQuotas(prAdapter, &rTcqAdjust, &prTxCtrl->rTc); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+ for (u4Num = 0; u4Num < TC_NUM; u4Num++) { -+ prTxCtrl->rTc.aucFreeBufferCount[u4Num] += rTcqAdjust.acVariation[u4Num]; -+ prTxCtrl->rTc.aucMaxNumOfBuffer[u4Num] += rTcqAdjust.acVariation[u4Num]; -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function flushes all packets queued in STA/AC queue -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @retval WLAN_STATUS_SUCCESS Flushed successfully -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS nicTxFlush(IN P_ADAPTER_T prAdapter) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ /* ask Per STA/AC queue to be fllushed and return all queued packets */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ prMsduInfo = qmFlushTxQueues(prAdapter); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ -+ if (prMsduInfo != NULL) { -+ nicTxFreeMsduInfoPacket(prAdapter, prMsduInfo); -+ nicTxReturnMsduInfo(prAdapter, prMsduInfo); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief In this function, we'll write Command(CMD_INFO_T) into HIF. -+* However this function is used for INIT_CMD. -+* -+* In order to avoid further maintenance issues, these 2 functions are separated -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prPacketInfo Pointer of CMD_INFO_T -+* @param ucTC Specify the resource of TC -+* -+* @retval WLAN_STATUS_SUCCESS Bus access ok. -+* @retval WLAN_STATUS_FAILURE Bus access fail. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxInitCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC) -+{ -+ P_INIT_HIF_TX_HEADER_T prInitTxHeader; -+ UINT_16 u2OverallBufferLength; -+ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ -+ UINT_32 ucPortIdx; -+ P_TX_CTRL_T prTxCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(ucTC == TC0_INDEX); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; -+ prInitTxHeader = (P_INIT_HIF_TX_HEADER_T) prCmdInfo->pucInfoBuffer; -+ -+ /* <1> Compose the Header of Transmit Data Structure for CMD Packet */ -+ u2OverallBufferLength = -+ TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ -+ prInitTxHeader->u2TxByteCount = u2OverallBufferLength; -+ prInitTxHeader->ucEtherTypeOffset = 0; -+ prInitTxHeader->ucCSflags = 0; -+ -+ /* <2> Assign Data Port */ -+ if (ucTC != TC4_INDEX) { -+ ucPortIdx = 0; -+ } else { /* Broadcast/multicast data packets */ -+ ucPortIdx = 1; -+ } -+ -+ /* <3> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */ -+ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen); -+ -+ ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize); -+ -+ /* <4> Write frame to data port */ -+ HAL_WRITE_TX_PORT(prAdapter, -+ ucPortIdx, -+ (UINT_32) u2OverallBufferLength, -+ (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief In this function, we'll reset TX resource counter to initial value used -+* in F/W download state -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @retval WLAN_STATUS_SUCCESS Reset is done successfully. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxInitResetResource(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ -+ DEBUGFUNC("nicTxInitResetResource"); -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC0; -+ prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC0; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC1; -+ prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC1; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC2; -+ prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC2; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC3; -+ prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC3; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC4; -+ prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC4; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC5; -+ prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC5; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief this function enqueues MSDU_INFO_T into queue management, -+* or command queue -+* -+* @param prAdapter Pointer to the Adapter structure. -+* prMsduInfo Pointer to MSDU -+* -+* @retval WLAN_STATUS_SUCCESS Reset is done successfully. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxEnqueueMsdu(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prNextMsduInfo, prRetMsduInfo, prMsduInfoHead; -+ QUE_T qDataPort0, qDataPort1; -+ P_CMD_INFO_T prCmdInfo; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ ASSERT(prTxCtrl); -+ -+ QUEUE_INITIALIZE(&qDataPort0); -+ QUEUE_INITIALIZE(&qDataPort1); -+ -+ /* check how many management frame are being queued */ -+ while (prMsduInfo) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+ -+ QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL; -+ -+ if (prMsduInfo->eSrc == TX_PACKET_MGMT) { -+ /* MMPDU: force stick to TC4 */ -+ prMsduInfo->ucTC = TC4_INDEX; -+ -+ QUEUE_INSERT_TAIL(&qDataPort1, (P_QUE_ENTRY_T) prMsduInfo); -+ } else { -+ QUEUE_INSERT_TAIL(&qDataPort0, (P_QUE_ENTRY_T) prMsduInfo); -+ } -+ -+ prMsduInfo = prNextMsduInfo; -+ } -+ -+ if (qDataPort0.u4NumElem) { -+ /* send to QM: queue the packet to different TX queue by policy */ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ prRetMsduInfo = qmEnqueueTxPackets(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&qDataPort0)); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ -+ /* post-process for "dropped" packets */ -+ if (prRetMsduInfo != NULL) { /* unable to enqueue */ -+ nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfo); -+ nicTxReturnMsduInfo(prAdapter, prRetMsduInfo); -+ } -+ } -+ -+ if (qDataPort1.u4NumElem) { -+ prMsduInfoHead = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&qDataPort1); -+ -+ if (qDataPort1.u4NumElem > nicTxGetFreeCmdCount(prAdapter)) { -+ /* not enough descriptors for sending */ -+ u4Status = WLAN_STATUS_FAILURE; -+ -+ /* free all MSDUs */ -+ while (prMsduInfoHead) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry); -+ -+ if (prMsduInfoHead->pfTxDoneHandler != NULL) { -+ prMsduInfoHead->pfTxDoneHandler(prAdapter, prMsduInfoHead, -+ TX_RESULT_DROPPED_IN_DRIVER); -+ } -+ -+ cnmMgtPktFree(prAdapter, prMsduInfoHead); -+ -+ prMsduInfoHead = prNextMsduInfo; -+ } -+ } else { -+ /* send to command queue */ -+ while (prMsduInfoHead) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ -+ if (prCmdInfo) { -+ GLUE_INC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); -+ -+ kalMemZero(prCmdInfo, sizeof(CMD_INFO_T)); -+ -+ prCmdInfo->eCmdType = COMMAND_TYPE_MANAGEMENT_FRAME; -+ prCmdInfo->u2InfoBufLen = prMsduInfoHead->u2FrameLength; -+ prCmdInfo->pucInfoBuffer = NULL; -+ prCmdInfo->prPacket = (P_NATIVE_PACKET) prMsduInfoHead; -+ prCmdInfo->ucStaRecIndex = prMsduInfoHead->ucStaRecIndex; -+ prCmdInfo->eNetworkType = prMsduInfoHead->ucNetworkType; -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->pfCmdTimeoutHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ -+ kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ } else { -+ /* Cmd free count is larger than expected, but allocation fail. */ -+ ASSERT(0); -+ -+ u4Status = WLAN_STATUS_FAILURE; -+ cnmMgtPktFree(prAdapter, prMsduInfoHead); -+ } -+ -+ prMsduInfoHead = prNextMsduInfo; -+ } -+ } -+ } -+ -+ /* indicate service thread for sending */ -+ if (prTxCtrl->i4TxMgmtPendingNum > 0 || kalGetTxPendingFrameCount(prAdapter->prGlueInfo) > 0) -+ kalSetEvent(prAdapter->prGlueInfo); -+ -+ return u4Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief this function returns available count in command queue -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @retval -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 nicTxGetFreeCmdCount(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ return prAdapter->rFreeCmdList.u4NumElem; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c -new file mode 100644 -index 0000000000000..38e4569bc04f9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c -@@ -0,0 +1,192 @@ -+/* -+** Id: @(#) p2p_nic.c@@ -+*/ -+ -+/*! \file p2p_nic.c -+ \brief Wi-Fi Direct Functions that provide operation in NIC's (Network Interface Card) point of view. -+ -+ This file includes functions which unite multiple hal(Hardware) operations -+ and also take the responsibility of Software Resource Management in order -+ to keep the synchronization with Hardware Manipulation. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief When Probe Rsp & Beacon frame is received and decide a P2P device, -+* this function will be invoked to buffer scan result -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prEventScanResult Pointer of EVENT_SCAN_RESULT_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicRxAddP2pDevice(IN P_ADAPTER_T prAdapter, -+ IN P_EVENT_P2P_DEV_DISCOVER_RESULT_T prP2pResult, IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELength) -+{ -+ P_P2P_INFO_T prP2pInfo = (P_P2P_INFO_T) NULL; -+ P_EVENT_P2P_DEV_DISCOVER_RESULT_T prTargetResult = (P_EVENT_P2P_DEV_DISCOVER_RESULT_T) NULL; -+ UINT_32 u4Idx = 0; -+ BOOLEAN bUpdate = FALSE; -+ -+ PUINT_8 pucIeBuf = (PUINT_8) NULL; -+ UINT_16 u2IELength = 0; -+ UINT_8 zeroMac[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; -+ -+ ASSERT(prAdapter); -+ -+ prP2pInfo = prAdapter->prP2pInfo; -+ -+ for (u4Idx = 0; u4Idx < prP2pInfo->u4DeviceNum; u4Idx++) { -+ prTargetResult = &prP2pInfo->arP2pDiscoverResult[u4Idx]; -+ -+ if (EQUAL_MAC_ADDR(prTargetResult->aucDeviceAddr, prP2pResult->aucDeviceAddr)) { -+ bUpdate = TRUE; -+ -+ /* Backup OLD buffer result. */ -+ pucIeBuf = prTargetResult->pucIeBuf; -+ u2IELength = prTargetResult->u2IELength; -+ -+ /* Update Device Info. */ -+ /* zero */ -+ kalMemZero(prTargetResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); -+ -+ /* then buffer */ -+ kalMemCopy(prTargetResult, (PVOID) prP2pResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); -+ -+ /* See if new IE length is longer or not. */ -+ if ((u2RxIELength > u2IELength) && (u2IELength != 0)) { -+ /* Buffer is not enough. */ -+ u2RxIELength = u2IELength; -+ } else if ((u2IELength == 0) && (u2RxIELength != 0)) { -+ /* RX new IE buf. */ -+ ASSERT(pucIeBuf == NULL); -+ pucIeBuf = prP2pInfo->pucCurrIePtr; -+ -+ if (((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength) > -+ (ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]) { -+ /* Common Buffer is no enough. */ -+ u2RxIELength = -+ (UINT_16) ((ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN] - -+ (ULONG) prP2pInfo->pucCurrIePtr); -+ } -+ -+ /* Step to next buffer address. */ -+ prP2pInfo->pucCurrIePtr = -+ (PUINT_8) ((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength); -+ } -+ -+ /* Restore buffer pointer. */ -+ prTargetResult->pucIeBuf = pucIeBuf; -+ -+ if (pucRxIEBuf) { -+ /* If new received IE is available. -+ * Replace the old one & update new IE length. -+ */ -+ kalMemCopy(pucIeBuf, pucRxIEBuf, u2RxIELength); -+ prTargetResult->u2IELength = u2RxIELength; -+ } else { -+ /* There is no new IE information, keep the old one. */ -+ prTargetResult->u2IELength = u2IELength; -+ } -+ } -+ } -+ -+ if (!bUpdate) { -+ /* We would flush the whole scan result after each scan request is issued. -+ * If P2P device is too many, it may over the scan list. -+ */ -+ if ((u4Idx < CFG_MAX_NUM_BSS_LIST) && (UNEQUAL_MAC_ADDR(zeroMac, prP2pResult->aucDeviceAddr))) { -+ /* whsu:XXX */ -+ prTargetResult = &prP2pInfo->arP2pDiscoverResult[u4Idx]; -+ -+ /* zero */ -+ kalMemZero(prTargetResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); -+ -+ /* then buffer */ -+ kalMemCopy(prTargetResult, (PVOID) prP2pResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); -+ -+ /* printk("DVC FND %d %pM, %pM\n", -+ prP2pInfo->u4DeviceNum, -+ prP2pResult->aucDeviceAddr, -+ prTargetResult->aucDeviceAddr); */ -+ -+ if (u2RxIELength) { -+ prTargetResult->pucIeBuf = prP2pInfo->pucCurrIePtr; -+ -+ if (((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength) > -+ (ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]) { -+ /* Common Buffer is no enough. */ -+ u2IELength = -+ (UINT_16) ((ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN] - -+ (ULONG) prP2pInfo->pucCurrIePtr); -+ } else { -+ u2IELength = u2RxIELength; -+ } -+ -+ prP2pInfo->pucCurrIePtr = -+ (PUINT_8) ((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2IELength); -+ -+ kalMemCopy((PVOID) prTargetResult->pucIeBuf, (PVOID) pucRxIEBuf, (UINT_32) u2IELength); -+ prTargetResult->u2IELength = u2IELength; -+ } else { -+ prTargetResult->pucIeBuf = NULL; -+ prTargetResult->u2IELength = 0; -+ } -+ -+ prP2pInfo->u4DeviceNum++; -+ -+ } else { -+ /* TODO: Fixme to replace an old one. (?) */ -+ ASSERT(FALSE); -+ } -+ } -+} /* nicRxAddP2pDevice */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c -new file mode 100644 -index 0000000000000..dd00859d46082 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c -@@ -0,0 +1,5038 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/que_mgt.c#1 -+*/ -+ -+/*! \file "que_mgt.c" -+ \brief TX/RX queues management -+ -+ The main tasks of queue management include TC-based HIF TX flow control, -+ adaptive TC quota adjustment, HIF TX grant scheduling, Power-Save -+ forwarding control, RX packet reordering, and RX BA agreement management. -+*/ -+ -+/* -+** Log: que_mgt.c -+** -+** 04 11 2013 yuche.tsai -+** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop. -+** Drop the probe response packet when absent. -+** -+** 04 09 2013 yuche.tsai -+** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop. -+** Fix CMD buffer short issue. -+** -+** 04 09 2013 yuche.tsai -+** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop. -+** Fix CMD buffer short issue. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 02 23 2012 eddie.chen -+ * [WCXRP00001194] [MT6620][DRV/FW] follow admission control bit to change the enqueue rule -+ * Change the enqueue policy when ACM = 1. -+ * -+ * 11 22 2011 yuche.tsai -+ * NULL -+ * Code refine, remove one #if 0 code. -+ * -+ * 11 19 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog for tx -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 18 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Fix xlog format to hex format -+ * -+ * 11 17 2011 tsaiyuan.hsu -+ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. -+ * avoid deactivating staRec when changing state from 3 to 3. -+ * -+ * 11 11 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug msg for xlog. -+ * -+ * 11 11 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters of bb and ar for xlog. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Use short name for xlog. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Modify the QM xlog level and remove LOG_FUNC. -+ * -+ * 11 10 2011 chinglan.wang -+ * NULL -+ * [WiFi WPS]Can't switch to new AP via WPS PBC when there existing a connection to another AP. -+ * -+ * 11 09 2011 chinglan.wang -+ * NULL -+ * [WiFi direct]Can't make P2P connect via PBC. -+ * -+ * 11 08 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog function. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 11 01 2011 chinglan.wang -+ * NULL -+ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP. -+ * If disconnect the AP and flush all the data frame in the TX queue, WPS cannot do the 4-way handshake to connect to -+ * the AP.. -+ * -+ * 10 25 2011 wh.su -+ * [WCXRP00001059] [MT6620 Wi-Fi][Driver][P2P] Fixed sometimes data (1x) will not indicate to upper layer due ba check -+ * un-expect -+ * let the Rx BA accept even the sta not valid. -+ * -+ * 09 28 2011 tsaiyuan.hsu -+ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX -+ * enlarge window size only by 4. -+ * -+ * 09 01 2011 tsaiyuan.hsu -+ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX -+ * set rx window size as twice buffer size. -+ * -+ * 08 23 2011 yuche.tsai -+ * NULL -+ * Fix multicast address list issue. -+ * -+ * 08 03 2011 tsaiyuan.hsu -+ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX -+ * force window size at least 16. -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting device -+ * issue. -+ * Fix GO send deauth frame issue. -+ * -+ * 07 26 2011 eddie.chen -+ * [WCXRP00000874] [MT5931][DRV] API for query the RX reorder queued packets counter -+ * API for query the RX reorder queued packets counter. -+ * -+ * 07 07 2011 eddie.chen -+ * [WCXRP00000834] [MT6620 Wi-Fi][DRV] Send 1x packet when peer STA is in PS. -+ * Add setEvent when free quota is updated. -+ * -+ * 07 05 2011 eddie.chen -+ * [WCXRP00000834] [MT6620 Wi-Fi][DRV] Send 1x packet when peer STA is in PS. -+ * Send 1x when peer STA is in PS. -+ * -+ * 05 31 2011 eddie.chen -+ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931 -+ * Fix the QM quota in MT5931. -+ * -+ * 05 11 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Fix dest type when GO packet copying. -+ * -+ * 05 09 2011 yuche.tsai -+ * [WCXRP00000712] [Volunteer Patch][MT6620][Driver] Sending deauth issue when Hot spot is disabled. (GO is dissolved) -+ * Deauthentication frame is not bound to network active status. -+ * -+ * 05 09 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Check free number before copying broadcast packet. -+ * -+ * 04 14 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Check the SW RFB free. Fix the compile warning.. -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 04 11 2011 yuche.tsai -+ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue. -+ * Fix kernel panic issue when MMPDU of P2P is pending in driver. -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 03 28 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Fix Klockwork warning. -+ * -+ * 03 28 2011 eddie.chen -+ * [WCXRP00000602] [MT6620 Wi-Fi][DRV] Fix wmm parameters in beacon for BOW -+ * Fix wmm parameters in beacon for BOW. -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 02 23 2011 eddie.chen -+ * [WCXRP00000463] [MT6620 Wi-Fi][FW/Driver][Hotspot] Cannot update WMM PS STA's partital bitmap -+ * Fix parsing WMM INFO and bmp delivery bitmap definition. -+ * -+ * 02 17 2011 eddie.chen -+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel -+ * 1) Change GetFrameAction decision when BSS is absent. -+ * 2) Check channel and resource in processing ProbeRequest -+ * -+ * 02 08 2011 eddie.chen -+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode -+ * Add event STA agint timeout -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 24 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Remove comments. -+ * -+ * 01 24 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Add destination decision in AP mode. -+ * -+ * 01 14 2011 wh.su -+ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out[WCXRP00000326] -+ * [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!! -+ * Allow 802.1x can be send even the net is not active due the drver / fw sync issue. -+ * -+ * 01 13 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ * Fix typo and compile error. -+ * -+ * 01 12 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ * Fix WMM parameter condition for STA -+ * -+ * 01 12 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ * 1) Check Bss if support QoS before adding WMMIE -+ * 2) Check if support prAdapter->rWifiVar QoS and uapsd in flow control -+ * -+ * 01 12 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Update MQM for WMM IE generation method -+ * -+ * 01 11 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * Add per STA flow control when STA is in PS mode -+ * -+ * 01 03 2011 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * update prStaRec->fgIsUapsdSupported flag. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * Add WMM parameter for broadcast. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 23 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * 1. update WMM IE parsing, with ASSOC REQ handling -+ * 2. extend U-APSD parameter passing from driver to FW -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out -+ * use the #14 and modify the add code for check MMPDU. -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out -+ * only MMPDU not check the netActive flag. -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out -+ * not check the netActive flag for mgmt . -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by -+ * ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 08 30 2010 yarco.yang -+ * NULL -+ * Fixed klockwork error message -+ * -+ * 08 18 2010 yarco.yang -+ * NULL -+ * 1. Fixed HW checksum offload function not work under Linux issue. -+ * 2. Add debug message. -+ * -+ * 08 10 2010 yarco.yang -+ * NULL -+ * Code refine -+ * -+ * 08 06 2010 yarco.yang -+ * NULL -+ * Update qmGetFrameAction() to allow P2P MGMT frame w/o STA_Record still can perform TX action -+ * -+ * 07 26 2010 cp.wu -+ * -+ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet -+ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found -+ * -+ * 07 20 2010 yarco.yang -+ * -+ * Add to SetEvent when BSS is from Absent to Present or STA from PS to Awake -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 13 2010 yarco.yang -+ * -+ * [WPD00003849] -+ * [MT6620 and MT5931] SW Migration, add qmGetFrameAction() API for CMD Queue Processing -+ * -+ * 07 09 2010 yarco.yang -+ * -+ * [MT6620 and MT5931] SW Migration: Add ADDBA support -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * . -+ * -+ * 07 06 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Use fgInUse instead of fgIsValid for De-queue judgement -+ * -+ * 07 06 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * For MMPDU, STA_REC will be decided by caller module -+ * -+ * 07 06 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Add MGMT Packet type for HIF_TX_HEADER -+ * -+ * 06 29 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * replace g_rQM with Adpater->rQM -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 31 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Refined the debug msg -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * comment out one assertion which refer to undefined data member. -+ * -+ * 03 30 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled adaptive TC resource control -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+* 03 17 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Changed STA_REC index determination rules (DA=BMCAST always --> STA_REC_INDEX_BMCAST) -+ * -+ * 03 11 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Fixed buffer leak when processing BAR frames -+ * -+ * 03 02 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * For TX packets with STA_REC index = STA_REC_INDEX_NOT_FOUND, use TC5 -+ * -+ * 03 01 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Fixed STA_REC index determination bug (fgIsValid shall be checked) -+ * -+ * 02 25 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Refined function qmDetermineStaRecIndex() for BMCAST packets -+ * -+ * 02 25 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled multi-STA TX path with fairness -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled dynamically activating and deactivating STA_RECs -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Added code for dynamic activating and deactivating STA_RECs. -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the 802.1x path -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the Burst_End Indication mechanism -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-12-14 15:01:37 GMT MTK02468 -+** Fixed casting for qmAddRxBaEntry() -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-12-10 16:51:03 GMT mtk02752 -+** remove SD1_SD3.. flag -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-12-09 14:07:25 GMT MTK02468 -+** Added RX buffer reordering functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-04 13:34:16 GMT MTK02468 -+** Modified Flush Queue function to let queues be reinitialized -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-04 13:18:25 GMT MTK02468 -+** Added flushing per-Type queues code -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-12-02 23:39:49 GMT MTK02468 -+** Added Debug msgs and fixed incorrect assert -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-26 23:50:27 GMT MTK02468 -+** Bug fixing (qmDequeueTxPackets local variable initialization) -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-26 09:39:25 GMT mtk02752 -+** correct and surpress PREfast warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-11-23 22:10:55 GMT mtk02468 -+** Used SD1_SD3_DATAPATH_INTEGRATION -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-11-23 22:02:30 GMT mtk02468 -+** Initial version -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+OS_SYSTIME g_arMissTimeout[CFG_STA_REC_NUM][CFG_RX_MAX_BA_TID_NUM]; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if ARP_MONITER_ENABLE -+static UINT_16 arpMoniter; -+static UINT_8 apIp[4]; -+#endif -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static inline VOID qmDetermineStaRecIndex(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+static inline VOID -+qmDequeueTxPacketsFromPerStaQueues(IN P_ADAPTER_T prAdapter, -+ OUT P_QUE_T prQue, -+ IN UINT_8 ucTC, IN UINT_8 ucCurrentAvailableQuota, IN UINT_8 ucTotalQuota); -+ -+static inline VOID -+qmDequeueTxPacketsFromPerTypeQueues(IN P_ADAPTER_T prAdapter, OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucMaxNum); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Init Queue Management for TX -+* -+* \param[in] (none) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmInit(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4QueArrayIdx; -+ UINT_32 i; -+ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ /* DbgPrint("QM: Enter qmInit()\n"); */ -+#if CFG_SUPPORT_QOS -+ prAdapter->rWifiVar.fgSupportQoS = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportQoS = FALSE; -+#endif -+ -+#if CFG_SUPPORT_AMPDU_RX -+ prAdapter->rWifiVar.fgSupportAmpduRx = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportAmpduRx = FALSE; -+#endif -+ -+#if CFG_SUPPORT_AMPDU_TX -+ prAdapter->rWifiVar.fgSupportAmpduTx = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportAmpduTx = FALSE; -+#endif -+ -+#if CFG_SUPPORT_TSPEC -+ prAdapter->rWifiVar.fgSupportTspec = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportTspec = FALSE; -+#endif -+ -+#if CFG_SUPPORT_UAPSD -+ prAdapter->rWifiVar.fgSupportUAPSD = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportUAPSD = FALSE; -+#endif -+ -+#if CFG_SUPPORT_UL_PSMP -+ prAdapter->rWifiVar.fgSupportULPSMP = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportULPSMP = FALSE; -+#endif -+ -+#if CFG_SUPPORT_RX_SGI -+ prAdapter->rWifiVar.u8SupportRxSgi20 = 0; -+ prAdapter->rWifiVar.u8SupportRxSgi40 = 0; -+#else -+ prAdapter->rWifiVar.u8SupportRxSgi20 = 2; -+ prAdapter->rWifiVar.u8SupportRxSgi40 = 2; -+#endif -+ -+#if CFG_SUPPORT_RX_HT_GF -+ prAdapter->rWifiVar.u8SupportRxGf = 0; -+#else -+ prAdapter->rWifiVar.u8SupportRxGf = 2; -+#endif -+ -+ /* 4 <2> Initialize other TX queues (queues not in STA_RECs) */ -+ for (u4QueArrayIdx = 0; u4QueArrayIdx < NUM_OF_PER_TYPE_TX_QUEUES; u4QueArrayIdx++) -+ QUEUE_INITIALIZE(&(prQM->arTxQueue[u4QueArrayIdx])); -+ -+ /* 4 <3> Initialize the RX BA table and RX queues */ -+ /* Initialize the RX Reordering Parameters and Queues */ -+ for (u4QueArrayIdx = 0; u4QueArrayIdx < CFG_NUM_OF_RX_BA_AGREEMENTS; u4QueArrayIdx++) { -+ prQM->arRxBaTable[u4QueArrayIdx].fgIsValid = FALSE; -+ QUEUE_INITIALIZE(&(prQM->arRxBaTable[u4QueArrayIdx].rReOrderQue)); -+ prQM->arRxBaTable[u4QueArrayIdx].u2WinStart = 0xFFFF; -+ prQM->arRxBaTable[u4QueArrayIdx].u2WinEnd = 0xFFFF; -+ -+ prQM->arRxBaTable[u4QueArrayIdx].fgIsWaitingForPktWithSsn = FALSE; -+ -+ } -+ prQM->ucRxBaCount = 0; -+ -+ kalMemSet(&g_arMissTimeout, 0, sizeof(g_arMissTimeout)); -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ /* 4 <4> Initialize TC resource control variables */ -+ for (i = 0; i < TC_NUM; i++) -+ prQM->au4AverageQueLen[i] = 0; -+ prQM->u4TimeToAdjustTcResource = QM_INIT_TIME_TO_ADJUST_TC_RSC; -+ prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN; -+ prQM->u4TxNumOfVi = 0; -+ prQM->u4TxNumOfVo = 0; -+ -+/* ASSERT(prQM->u4TimeToAdjust && prQM->u4TimeToUpdateQueLen); */ -+ -+ /* 1 20 1 1 4 1 */ -+ prQM->au4CurrentTcResource[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0; -+ prQM->au4CurrentTcResource[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1; -+ prQM->au4CurrentTcResource[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2; -+ prQM->au4CurrentTcResource[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3; -+ prQM->au4CurrentTcResource[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4; /* Not adjustable (TX port 1) */ -+ prQM->au4CurrentTcResource[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5; -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC0 = %d\n", NIC_TX_BUFF_COUNT_TC0); -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC1 = %d\n", NIC_TX_BUFF_COUNT_TC1); -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC2 = %d\n", NIC_TX_BUFF_COUNT_TC2); -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC3 = %d\n", NIC_TX_BUFF_COUNT_TC3); -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC4 = %d\n", NIC_TX_BUFF_COUNT_TC4); -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC5 = %d\n", NIC_TX_BUFF_COUNT_TC5); -+ -+ /* 1 1 1 1 2 1 */ -+ prQM->au4MinReservedTcResource[TC0_INDEX] = QM_MIN_RESERVED_TC0_RESOURCE; -+ prQM->au4MinReservedTcResource[TC1_INDEX] = QM_MIN_RESERVED_TC1_RESOURCE; -+ prQM->au4MinReservedTcResource[TC2_INDEX] = QM_MIN_RESERVED_TC2_RESOURCE; -+ prQM->au4MinReservedTcResource[TC3_INDEX] = QM_MIN_RESERVED_TC3_RESOURCE; -+ prQM->au4MinReservedTcResource[TC4_INDEX] = QM_MIN_RESERVED_TC4_RESOURCE; /* Not adjustable (TX port 1) */ -+ prQM->au4MinReservedTcResource[TC5_INDEX] = QM_MIN_RESERVED_TC5_RESOURCE; -+ -+ /* 4 4 6 6 2 4 */ -+ prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC3_INDEX] = QM_GUARANTEED_TC3_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC4_INDEX] = QM_GUARANTEED_TC4_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC5_INDEX] = QM_GUARANTEED_TC5_RESOURCE; -+ -+ prQM->fgTcResourcePostAnnealing = FALSE; -+ -+ ASSERT(QM_INITIAL_RESIDUAL_TC_RESOURCE < 64); -+#endif -+ -+#if QM_TEST_MODE -+ prQM->u4PktCount = 0; -+ -+#if QM_TEST_FAIR_FORWARDING -+ -+ prQM->u4CurrentStaRecIndexToEnqueue = 0; -+ { -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+ P_STA_RECORD_T prStaRec; -+ -+ /* Irrelevant in case this STA is an AIS AP (see qmDetermineStaRecIndex()) */ -+ aucMacAddr[0] = 0x11; -+ aucMacAddr[1] = 0x22; -+ aucMacAddr[2] = 0xAA; -+ aucMacAddr[3] = 0xBB; -+ aucMacAddr[4] = 0xCC; -+ aucMacAddr[5] = 0xDD; -+ -+ prStaRec = &prAdapter->arStaRec[1]; -+ ASSERT(prStaRec); -+ -+ prStaRec->fgIsValid = TRUE; -+ prStaRec->fgIsQoS = TRUE; -+ prStaRec->fgIsInPS = FALSE; -+ prStaRec->ucPsSessionID = 0xFF; -+ prStaRec->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ prStaRec->fgIsAp = TRUE; -+ COPY_MAC_ADDR((prStaRec)->aucMacAddr, aucMacAddr); -+ -+ } -+ -+#endif -+ -+#endif -+ -+#if QM_FORWARDING_FAIRNESS -+ { -+ UINT_32 i; -+ -+ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) { -+ prQM->au4ForwardCount[i] = 0; -+ prQM->au4HeadStaRecIndex[i] = 0; -+ } -+ } -+#endif -+ -+#if QM_TC_RESOURCE_EMPTY_COUNTER -+ kalMemZero(prQM->au4QmTcResourceEmptyCounter, sizeof(prQM->au4QmTcResourceEmptyCounter)); -+#endif -+ -+} -+ -+#if QM_TEST_MODE -+VOID qmTestCases(IN P_ADAPTER_T prAdapter) -+{ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ DbgPrint("QM: ** TEST MODE **\n"); -+ -+ if (QM_TEST_STA_REC_DETERMINATION) { -+ if (prAdapter->arStaRec[0].fgIsValid) { -+ prAdapter->arStaRec[0].fgIsValid = FALSE; -+ DbgPrint("QM: (Test) Deactivate STA_REC[0]\n"); -+ } else { -+ prAdapter->arStaRec[0].fgIsValid = TRUE; -+ DbgPrint("QM: (Test) Activate STA_REC[0]\n"); -+ } -+ } -+ -+ if (QM_TEST_STA_REC_DEACTIVATION) { -+ /* Note that QM_STA_REC_HARD_CODING shall be set to 1 for this test */ -+ -+ if (prAdapter->arStaRec[0].fgIsValid) { -+ -+ DbgPrint("QM: (Test) Deactivate STA_REC[0]\n"); -+ qmDeactivateStaRec(prAdapter, 0); -+ } else { -+ -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+ -+ /* Irrelevant in case this STA is an AIS AP (see qmDetermineStaRecIndex()) */ -+ aucMacAddr[0] = 0x11; -+ aucMacAddr[1] = 0x22; -+ aucMacAddr[2] = 0xAA; -+ aucMacAddr[3] = 0xBB; -+ aucMacAddr[4] = 0xCC; -+ aucMacAddr[5] = 0xDD; -+ -+ DbgPrint("QM: (Test) Activate STA_REC[0]\n"); -+ qmActivateStaRec(prAdapter, /* Adapter pointer */ -+ 0, /* STA_REC index from FW */ -+ TRUE, /* fgIsQoS */ -+ NETWORK_TYPE_AIS_INDEX, /* Network type */ -+ TRUE, /* fgIsAp */ -+ aucMacAddr /* MAC address */ -+ ); -+ } -+ } -+ -+ if (QM_TEST_FAIR_FORWARDING) { -+ if (prAdapter->arStaRec[1].fgIsValid) { -+ prQM->u4CurrentStaRecIndexToEnqueue++; -+ prQM->u4CurrentStaRecIndexToEnqueue %= 2; -+ DbgPrint("QM: (Test) Switch to STA_REC[%u]\n", prQM->u4CurrentStaRecIndexToEnqueue); -+ } -+ } -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Activate a STA_REC -+* -+* \param[in] prAdapter Pointer to the Adapter instance -+* \param[in] u4StaRecIdx The index of the STA_REC -+* \param[in] fgIsQoS Set to TRUE if this is a QoS STA -+* \param[in] pucMacAddr The MAC address of the STA -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmActivateStaRec(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ -+ /* 4 <1> Deactivate first */ -+ ASSERT(prStaRec); -+ -+ if (prStaRec->fgIsValid) { /* The STA_REC has been activated */ -+ DBGLOG(QM, WARN, "QM: (WARNING) Activating a STA_REC which has been activated\n"); -+ DBGLOG(QM, WARN, "QM: (WARNING) Deactivating a STA_REC before re-activating\n"); -+ /* To flush TX/RX queues and del RX BA agreements */ -+ qmDeactivateStaRec(prAdapter, prStaRec->ucIndex); -+ } -+ /* 4 <2> Activate the STA_REC */ -+ /* Init the STA_REC */ -+ prStaRec->fgIsValid = TRUE; -+ prStaRec->fgIsInPS = FALSE; -+ prStaRec->ucPsSessionID = 0xFF; -+ prStaRec->fgIsAp = (IS_AP_STA(prStaRec)) ? TRUE : FALSE; -+ -+ /* Done in qmInit() or qmDeactivateStaRec() */ -+#if 0 -+ /* At the beginning, no RX BA agreements have been established */ -+ for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) -+ (prStaRec->aprRxReorderParamRefTbl)[i] = NULL; -+#endif -+ -+ DBGLOG(QM, TRACE, "QM: +STA[%u]\n", (UINT_32) prStaRec->ucIndex); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Deactivate a STA_REC -+* -+* \param[in] prAdapter Pointer to the Adapter instance -+* \param[in] u4StaRecIdx The index of the STA_REC -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmDeactivateStaRec(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_32 i; -+ P_MSDU_INFO_T prFlushedTxPacketList = NULL; -+ -+ ASSERT(u4StaRecIdx < CFG_NUM_OF_STA_RECORD); -+ -+ prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; -+ ASSERT(prStaRec); -+ -+ /* 4<1> Flush TX queues */ -+ prFlushedTxPacketList = qmFlushStaTxQueues(prAdapter, u4StaRecIdx); -+ -+ if (prFlushedTxPacketList) -+ wlanProcessQueuedMsduInfo(prAdapter, prFlushedTxPacketList); -+ /* 4 <2> Flush RX queues and delete RX BA agreements */ -+ for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) { -+ /* Delete the RX BA entry with TID = i */ -+ qmDelRxBaEntry(prAdapter, (UINT_8) u4StaRecIdx, (UINT_8) i, FALSE); -+ } -+ -+ /* 4 <3> Deactivate the STA_REC */ -+ prStaRec->fgIsValid = FALSE; -+ prStaRec->fgIsInPS = FALSE; -+ -+ /* To reduce printk for IOT sta to connect all the time, */ -+ /* DBGLOG(QM, INFO, ("QM: -STA[%ld]\n", u4StaRecIdx)); */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Deactivate a STA_REC -+* -+* \param[in] prAdapter Pointer to the Adapter instance -+* \param[in] u4StaRecIdx The index of the network -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID qmFreeAllByNetType(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ -+ P_QUE_MGT_T prQM; -+ P_QUE_T prQue; -+ QUE_T rNeedToFreeQue; -+ QUE_T rTempQue; -+ P_QUE_T prNeedToFreeQue; -+ P_QUE_T prTempQue; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ prQM = &prAdapter->rQM; -+ prQue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; -+ -+ QUEUE_INITIALIZE(&rNeedToFreeQue); -+ QUEUE_INITIALIZE(&rTempQue); -+ -+ prNeedToFreeQue = &rNeedToFreeQue; -+ prTempQue = &rTempQue; -+ -+ QUEUE_MOVE_ALL(prTempQue, prQue); -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prMsduInfo, P_MSDU_INFO_T); -+ while (prMsduInfo) { -+ -+ if (prMsduInfo->ucNetworkType == eNetworkTypeIdx) { -+ /* QUEUE_INSERT_TAIL */ -+ QUEUE_INSERT_TAIL(prNeedToFreeQue, (P_QUE_ENTRY_T) prMsduInfo); -+ } else { -+ /* QUEUE_INSERT_TAIL */ -+ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prMsduInfo); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prMsduInfo, P_MSDU_INFO_T); -+ } -+ if (QUEUE_IS_NOT_EMPTY(prNeedToFreeQue)) -+ wlanProcessQueuedMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(prNeedToFreeQue)); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Flush all TX queues -+* -+* \param[in] (none) -+* -+* \return The flushed packets (in a list of MSDU_INFOs) -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T qmFlushTxQueues(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucStaArrayIdx; -+ UINT_8 ucQueArrayIdx; -+ -+ P_MSDU_INFO_T prMsduInfoListHead; -+ P_MSDU_INFO_T prMsduInfoListTail; -+ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ DBGLOG(QM, TRACE, "QM: Enter qmFlushTxQueues()\n"); -+ -+ prMsduInfoListHead = NULL; -+ prMsduInfoListTail = NULL; -+ -+ /* Concatenate all MSDU_INFOs in per-STA queues */ -+ for (ucStaArrayIdx = 0; ucStaArrayIdx < CFG_NUM_OF_STA_RECORD; ucStaArrayIdx++) { -+ -+ /* Always check each STA_REC when flushing packets no matter it is inactive or active */ -+#if 0 -+ if (!prAdapter->arStaRec[ucStaArrayIdx].fgIsValid) -+ continue; /* Continue to check the next STA_REC */ -+#endif -+ -+ for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_STA_TX_QUEUES; ucQueArrayIdx++) { -+ if (QUEUE_IS_EMPTY(&(prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]))) -+ continue; /* Continue to check the next TX queue of the same STA */ -+ -+ if (!prMsduInfoListHead) { -+ -+ /* The first MSDU_INFO is found */ -+ prMsduInfoListHead = (P_MSDU_INFO_T) -+ QUEUE_GET_HEAD(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); -+ prMsduInfoListTail = (P_MSDU_INFO_T) -+ QUEUE_GET_TAIL(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); -+ } else { -+ /* Concatenate the MSDU_INFO list with the existing list */ -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, -+ QUEUE_GET_HEAD(&prAdapter-> -+ arStaRec[ucStaArrayIdx].arTxQueue -+ [ucQueArrayIdx])); -+ -+ prMsduInfoListTail = (P_MSDU_INFO_T) -+ QUEUE_GET_TAIL(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); -+ } -+ -+ QUEUE_INITIALIZE(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); -+ } -+ } -+ -+ /* Flush per-Type queues */ -+ for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_TYPE_TX_QUEUES; ucQueArrayIdx++) { -+ -+ if (QUEUE_IS_EMPTY(&(prQM->arTxQueue[ucQueArrayIdx]))) -+ continue; /* Continue to check the next TX queue of the same STA */ -+ -+ if (!prMsduInfoListHead) { -+ -+ /* The first MSDU_INFO is found */ -+ prMsduInfoListHead = (P_MSDU_INFO_T) -+ QUEUE_GET_HEAD(&prQM->arTxQueue[ucQueArrayIdx]); -+ prMsduInfoListTail = (P_MSDU_INFO_T) -+ QUEUE_GET_TAIL(&prQM->arTxQueue[ucQueArrayIdx]); -+ } else { -+ /* Concatenate the MSDU_INFO list with the existing list */ -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, QUEUE_GET_HEAD(&prQM->arTxQueue[ucQueArrayIdx])); -+ -+ prMsduInfoListTail = (P_MSDU_INFO_T) -+ QUEUE_GET_TAIL(&prQM->arTxQueue[ucQueArrayIdx]); -+ } -+ -+ QUEUE_INITIALIZE(&prQM->arTxQueue[ucQueArrayIdx]); -+ -+ } -+ -+ if (prMsduInfoListTail) { -+ /* Terminate the MSDU_INFO list with a NULL pointer */ -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, NULL); -+ } -+ -+ return prMsduInfoListHead; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Flush TX packets for a particular STA -+* -+* \param[in] u4StaRecIdx STA_REC index -+* -+* \return The flushed packets (in a list of MSDU_INFOs) -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T qmFlushStaTxQueues(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx) -+{ -+ UINT_8 ucQueArrayIdx; -+ P_MSDU_INFO_T prMsduInfoListHead; -+ P_MSDU_INFO_T prMsduInfoListTail; -+ P_STA_RECORD_T prStaRec; -+ -+ /* To reduce printk for IOT sta to connect all the time, */ -+ /* DBGLOG(QM, TRACE, ("QM: Enter qmFlushStaTxQueues(%ld)\n", u4StaRecIdx)); */ -+ -+ ASSERT(u4StaRecIdx < CFG_NUM_OF_STA_RECORD); -+ -+ prMsduInfoListHead = NULL; -+ prMsduInfoListTail = NULL; -+ -+ prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; -+ ASSERT(prStaRec); -+ -+ /* No matter whether this is an activated STA_REC, do flush */ -+#if 0 -+ if (!prStaRec->fgIsValid) -+ return NULL; -+#endif -+ -+ /* Concatenate all MSDU_INFOs in TX queues of this STA_REC */ -+ for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_STA_TX_QUEUES; ucQueArrayIdx++) { -+ if (QUEUE_IS_EMPTY(&(prStaRec->arTxQueue[ucQueArrayIdx]))) -+ continue; -+ -+ if (!prMsduInfoListHead) { -+ /* The first MSDU_INFO is found */ -+ prMsduInfoListHead = (P_MSDU_INFO_T) -+ QUEUE_GET_HEAD(&prStaRec->arTxQueue[ucQueArrayIdx]); -+ prMsduInfoListTail = (P_MSDU_INFO_T) -+ QUEUE_GET_TAIL(&prStaRec->arTxQueue[ucQueArrayIdx]); -+ } else { -+ /* Concatenate the MSDU_INFO list with the existing list */ -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, -+ QUEUE_GET_HEAD(&prStaRec->arTxQueue[ucQueArrayIdx])); -+ -+ prMsduInfoListTail = (P_MSDU_INFO_T) QUEUE_GET_TAIL(&prStaRec->arTxQueue[ucQueArrayIdx]); -+ } -+ -+ QUEUE_INITIALIZE(&prStaRec->arTxQueue[ucQueArrayIdx]); -+ -+ } -+ -+#if 0 -+ if (prMsduInfoListTail) { -+ /* Terminate the MSDU_INFO list with a NULL pointer */ -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, nicGetPendingStaMMPDU(prAdapter, (UINT_8) u4StaRecIdx)); -+ } else { -+ prMsduInfoListHead = nicGetPendingStaMMPDU(prAdapter, (UINT_8) u4StaRecIdx); -+ } -+#endif -+ -+ return prMsduInfoListHead; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Flush RX packets -+* -+* \param[in] (none) -+* -+* \return The flushed packets (in a list of SW_RFBs) -+*/ -+/*----------------------------------------------------------------------------*/ -+P_SW_RFB_T qmFlushRxQueues(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i; -+ P_SW_RFB_T prSwRfbListHead; -+ P_SW_RFB_T prSwRfbListTail; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ prSwRfbListHead = prSwRfbListTail = NULL; -+ -+ DBGLOG(QM, TRACE, "QM: Enter qmFlushRxQueues()\n"); -+ -+ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { -+ if (QUEUE_IS_NOT_EMPTY(&(prQM->arRxBaTable[i].rReOrderQue))) { -+ if (!prSwRfbListHead) { -+ -+ /* The first MSDU_INFO is found */ -+ prSwRfbListHead = (P_SW_RFB_T) -+ QUEUE_GET_HEAD(&(prQM->arRxBaTable[i].rReOrderQue)); -+ prSwRfbListTail = (P_SW_RFB_T) -+ QUEUE_GET_TAIL(&(prQM->arRxBaTable[i].rReOrderQue)); -+ } else { -+ /* Concatenate the MSDU_INFO list with the existing list */ -+ QM_TX_SET_NEXT_MSDU_INFO(prSwRfbListTail, -+ QUEUE_GET_HEAD(&(prQM->arRxBaTable[i].rReOrderQue))); -+ -+ prSwRfbListTail = (P_SW_RFB_T) -+ QUEUE_GET_TAIL(&(prQM->arRxBaTable[i].rReOrderQue)); -+ } -+ -+ QUEUE_INITIALIZE(&(prQM->arRxBaTable[i].rReOrderQue)); -+ -+ } else { -+ continue; -+ } -+ } -+ -+ if (prSwRfbListTail) { -+ /* Terminate the MSDU_INFO list with a NULL pointer */ -+ QM_TX_SET_NEXT_SW_RFB(prSwRfbListTail, NULL); -+ } -+ return prSwRfbListHead; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Flush RX packets with respect to a particular STA -+* -+* \param[in] u4StaRecIdx STA_REC index -+* \param[in] u4Tid TID -+* -+* \return The flushed packets (in a list of SW_RFBs) -+*/ -+/*----------------------------------------------------------------------------*/ -+P_SW_RFB_T qmFlushStaRxQueue(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx, IN UINT_32 u4Tid) -+{ -+ /* UINT_32 i; */ -+ P_SW_RFB_T prSwRfbListHead; -+ P_SW_RFB_T prSwRfbListTail; -+ P_RX_BA_ENTRY_T prReorderQueParm; -+ P_STA_RECORD_T prStaRec; -+ -+ DBGLOG(QM, TRACE, "QM: Enter qmFlushStaRxQueues(%u)\n", u4StaRecIdx); -+ -+ prSwRfbListHead = prSwRfbListTail = NULL; -+ -+ prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; -+ ASSERT(prStaRec); -+ -+ /* No matter whether this is an activated STA_REC, do flush */ -+#if 0 -+ if (!prStaRec->fgIsValid) -+ return NULL; -+#endif -+ -+ /* Obtain the RX BA Entry pointer */ -+ prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[u4Tid]); -+ -+ /* Note: For each queued packet, prCurrSwRfb->eDst equals RX_PKT_DESTINATION_HOST */ -+ if (prReorderQueParm) { -+ -+ if (QUEUE_IS_NOT_EMPTY(&(prReorderQueParm->rReOrderQue))) { -+ -+ prSwRfbListHead = (P_SW_RFB_T) -+ QUEUE_GET_HEAD(&(prReorderQueParm->rReOrderQue)); -+ prSwRfbListTail = (P_SW_RFB_T) -+ QUEUE_GET_TAIL(&(prReorderQueParm->rReOrderQue)); -+ -+ QUEUE_INITIALIZE(&(prReorderQueParm->rReOrderQue)); -+ -+ } -+ } -+ -+ if (prSwRfbListTail) { -+ /* Terminate the MSDU_INFO list with a NULL pointer */ -+ QM_TX_SET_NEXT_SW_RFB(prSwRfbListTail, NULL); -+ } -+ return prSwRfbListHead; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Enqueue TX packets -+* -+* \param[in] prMsduInfoListHead Pointer to the list of TX packets -+* -+* \return The freed packets, which are not enqueued -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T qmEnqueueTxPackets(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ P_MSDU_INFO_T prMsduInfoReleaseList; -+ P_MSDU_INFO_T prCurrentMsduInfo; -+ P_MSDU_INFO_T prNextMsduInfo; -+ -+ P_STA_RECORD_T prStaRec; -+ QUE_T rNotEnqueuedQue; -+ P_QUE_T prTxQue = &rNotEnqueuedQue; -+ -+ UINT_8 ucPacketType; -+ UINT_8 ucTC; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ UINT_8 aucNextUP[WMM_AC_INDEX_NUM] = { 1 /* BEtoBK */ , 1 /*na */ , 0 /*VItoBE */ , 4 /*VOtoVI */ }; -+ -+ DBGLOG(QM, LOUD, "Enter qmEnqueueTxPackets\n"); -+ -+ ASSERT(prMsduInfoListHead); -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ { -+ /* UINT_32 i; */ -+ /* 4 <0> Update TC resource control related variables */ -+ /* Keep track of the queue length */ -+ if (--prQM->u4TimeToUpdateQueLen == 0) { /* -- only here */ -+ prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN; -+ qmUpdateAverageTxQueLen(prAdapter); -+ } -+ } -+#endif -+ -+ /* Push TX packets into STA_REC (for UNICAST) or prAdapter->rQM (for BMCAST) */ -+ prStaRec = NULL; -+ prMsduInfoReleaseList = NULL; -+ prCurrentMsduInfo = NULL; -+ QUEUE_INITIALIZE(&rNotEnqueuedQue); -+ prNextMsduInfo = prMsduInfoListHead; -+ -+ do { -+ P_BSS_INFO_T prBssInfo; -+ BOOLEAN fgCheckACMAgain; -+ ENUM_WMM_ACI_T eAci = WMM_AC_BE_INDEX; -+ -+ prCurrentMsduInfo = prNextMsduInfo; -+ prNextMsduInfo = QM_TX_GET_NEXT_MSDU_INFO(prCurrentMsduInfo); -+ ucTC = TC1_INDEX; -+ -+ /* 4 <1> Lookup the STA_REC index */ -+ /* The ucStaRecIndex will be set in this function */ -+ qmDetermineStaRecIndex(prAdapter, prCurrentMsduInfo); -+ ucPacketType = HIF_TX_PACKET_TYPE_DATA; -+ -+ STATS_ENV_REPORT_DETECT(prAdapter, prCurrentMsduInfo->ucStaRecIndex); -+ -+ DBGLOG(QM, LOUD, "***** ucStaRecIndex = %d *****\n", prCurrentMsduInfo->ucStaRecIndex); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prCurrentMsduInfo->ucNetworkType]); -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 0) -+ if (IS_NET_ACTIVE(prAdapter, prCurrentMsduInfo->ucNetworkType)) { -+#else -+ /* force to send the loopback test packet */ -+ if (1) { -+ SET_NET_ACTIVE(prAdapter, prCurrentMsduInfo->ucNetworkType); -+ prCurrentMsduInfo->ucStaRecIndex = STA_REC_INDEX_BMCAST; -+ ucPacketType = HIF_TX_PKT_TYPE_HIF_LOOPBACK; -+#endif /* End of CONF_HIF_LOOPBACK_AUTO */ -+ -+ switch (prCurrentMsduInfo->ucStaRecIndex) { -+ case STA_REC_INDEX_BMCAST: -+ prTxQue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; -+ ucTC = TC5_INDEX; -+#if 0 -+ if (prCurrentMsduInfo->ucNetworkType == NETWORK_TYPE_P2P_INDEX -+ && prCurrentMsduInfo->eSrc != TX_PACKET_MGMT) { -+ if (LINK_IS_EMPTY -+ (&prAdapter->rWifiVar. -+ arBssInfo[NETWORK_TYPE_P2P_INDEX].rStaRecOfClientList)) { -+ prTxQue = &rNotEnqueuedQue; -+ TX_INC_CNT(&prAdapter->rTxCtrl, TX_AP_BORADCAST_DROP); -+ } -+ } -+#endif -+ -+ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_23); -+ break; -+ -+ case STA_REC_INDEX_NOT_FOUND: -+ ucTC = TC5_INDEX; -+ -+ if (prCurrentMsduInfo->eSrc == TX_PACKET_FORWARDING) { -+ -+ /* if the packet is the forward type. the packet should be freed */ -+ DBGLOG(QM, TRACE, "Forwarding packet but Sta is STA_REC_INDEX_NOT_FOUND\n"); -+ /* prTxQue = &rNotEnqueuedQue; */ -+ } -+ prTxQue = &prQM->arTxQueue[TX_QUEUE_INDEX_NO_STA_REC]; -+ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_24); -+ -+ break; -+ -+ default: -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prCurrentMsduInfo->ucStaRecIndex); -+ -+ if (!prStaRec) { -+ DBGLOG(QM, ERROR, "prStaRec is NULL\n"); -+ break; -+ } -+ ASSERT(prStaRec->fgIsValid); -+ -+ if (prCurrentMsduInfo->ucUserPriority < 8) { -+ QM_DBG_CNT_INC(prQM, prCurrentMsduInfo->ucUserPriority + 15); -+ /* QM_DBG_CNT_15 *//* QM_DBG_CNT_16 *//* QM_DBG_CNT_17 *//* QM_DBG_CNT_18 */ -+ /* QM_DBG_CNT_19 *//* QM_DBG_CNT_20 *//* QM_DBG_CNT_21 *//* QM_DBG_CNT_22 */ -+ } -+ -+ eAci = WMM_AC_BE_INDEX; -+ do { -+ fgCheckACMAgain = FALSE; -+ if (!prStaRec->fgIsQoS) { -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1]; -+ ucTC = TC1_INDEX; -+ break; -+ } -+ -+ switch (prCurrentMsduInfo->ucUserPriority) { -+ case 1: -+ case 2: -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC0]; -+ ucTC = TC0_INDEX; -+ eAci = WMM_AC_BK_INDEX; -+ break; -+ case 0: -+ case 3: -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1]; -+ ucTC = TC1_INDEX; -+ eAci = WMM_AC_BE_INDEX; -+ break; -+ case 4: -+ case 5: -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC2]; -+ ucTC = TC2_INDEX; -+ eAci = WMM_AC_VI_INDEX; -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ prQM->u4TxNumOfVi++; -+#endif -+ break; -+ case 6: -+ case 7: -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC3]; -+ ucTC = TC3_INDEX; -+ eAci = WMM_AC_VO_INDEX; -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ prQM->u4TxNumOfVo++; -+#endif -+ break; -+ default: -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1]; -+ ucTC = TC1_INDEX; -+ eAci = WMM_AC_BE_INDEX; -+ ASSERT(0); -+ break; -+ } -+ if (prBssInfo->arACQueParms[eAci].fgIsACMSet && eAci -+ != WMM_AC_BK_INDEX) { -+ prCurrentMsduInfo->ucUserPriority = aucNextUP[eAci]; -+ fgCheckACMAgain = TRUE; -+ } -+ } while (fgCheckACMAgain); -+ -+ /* LOG_FUNC ("QoS %u UP %u TC %u", */ -+ /* prStaRec->fgIsQoS,prCurrentMsduInfo->ucUserPriority, ucTC); */ -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ /* -+ In TDLS or AP mode, peer maybe enter "sleep mode". -+ -+ If QM_INIT_TIME_TO_UPDATE_QUE_LEN = 60 when peer is in sleep mode, -+ we need to wait 60 * u4TimeToAdjustTcResource = 180 packets -+ u4TimeToAdjustTcResource = 3, -+ then we will adjust TC resouce for VI or VO. -+ -+ But in TDLS test case, the throughput is very low, only 0.8Mbps in 5.7, -+ we will to wait about 12 seconds to collect 180 packets. -+ but the test time is only 20 seconds. -+ */ -+ if ((prQM->u4TxNumOfVi == 10) || (prQM->u4TxNumOfVo == 10)) { -+ /* force to do TC resouce update */ -+ prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN_MIN; -+ prQM->u4TimeToAdjustTcResource = 1; -+ } -+#endif -+#if ARP_MONITER_ENABLE -+ if (IS_STA_IN_AIS(prStaRec) && prCurrentMsduInfo->eSrc == TX_PACKET_OS) -+ qmDetectArpNoResponse(prAdapter, prCurrentMsduInfo); -+#endif -+ -+ break; /*default */ -+ } /* switch (prCurrentMsduInfo->ucStaRecIndex) */ -+ -+ if (prCurrentMsduInfo->eSrc == TX_PACKET_FORWARDING) { -+ if (prTxQue->u4NumElem > 32) { -+ DBGLOG(QM, WARN, -+ "Drop the Packet for full Tx queue (forwarding) Bss %u\n", -+ prCurrentMsduInfo->ucNetworkType); -+ prTxQue = &rNotEnqueuedQue; -+ TX_INC_CNT(&prAdapter->rTxCtrl, TX_FORWARD_OVERFLOW_DROP); -+ } -+ } -+ -+ } else { -+ -+ DBGLOG(QM, WARN, "Drop the Packet for inactive Bss %u\n", prCurrentMsduInfo->ucNetworkType); -+ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_31); -+ prTxQue = &rNotEnqueuedQue; -+ TX_INC_CNT(&prAdapter->rTxCtrl, TX_INACTIVE_BSS_DROP); -+ } -+ -+ /* 4 <3> Fill the MSDU_INFO for constructing HIF TX header */ -+ -+ /* TODO: Fill MSDU_INFO according to the network type, -+ * EtherType, and STA status (for PS forwarding control). -+ */ -+ -+ /* Note that the Network Type Index and STA_REC index are determined in -+ * qmDetermineStaRecIndex(prCurrentMsduInfo). -+ */ -+ QM_TX_SET_MSDU_INFO_FOR_DATA_PACKET(prCurrentMsduInfo, /* MSDU_INFO ptr */ -+ ucTC, /* TC tag */ -+ ucPacketType, /* Packet Type */ -+ 0, /* Format ID */ -+ prCurrentMsduInfo->fgIs802_1x, /* Flag 802.1x */ -+ prCurrentMsduInfo->fgIs802_11, /* Flag 802.11 */ -+ 0, /* PAL LLH */ -+ 0, /* ACL SN */ -+ PS_FORWARDING_TYPE_NON_PS, /* PS Forwarding Type */ -+ 0 /* PS Session ID */ -+ ); -+ -+ /* 4 <4> Enqueue the packet to different AC queue (max 5 AC queues) */ -+ QUEUE_INSERT_TAIL(prTxQue, (P_QUE_ENTRY_T) prCurrentMsduInfo); -+ -+ if (prTxQue != &rNotEnqueuedQue) { -+ prQM->u4EnqeueuCounter++; -+ prQM->au4ResourceWantedCounter[ucTC]++; -+ } -+ if (prStaRec) -+ prStaRec->u4EnqeueuCounter++; -+ -+#if QM_TC_RESOURCE_EMPTY_COUNTER -+ { -+ P_TX_CTRL_T prTxCtrl = &prAdapter->rTxCtrl; -+ -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] == 0) { -+ prQM->au4QmTcResourceEmptyCounter[prCurrentMsduInfo->ucNetworkType][ucTC]++; -+ /* -+ DBGLOG(QM, TRACE, ("TC%d Q Empty Count: [%d]%ld\n", -+ ucTC, -+ prCurrentMsduInfo->ucNetworkType, -+ prQM->au4QmTcResourceEmptyCounter[prCurrentMsduInfo->ucNetworkType][ucTC])); -+ */ -+ } -+ -+ } -+#endif -+ -+#if QM_TEST_MODE -+ if (++prQM->u4PktCount == QM_TEST_TRIGGER_TX_COUNT) { -+ prQM->u4PktCount = 0; -+ qmTestCases(prAdapter); -+ } -+#endif -+ -+ DBGLOG(QM, LOUD, "Current queue length = %u\n", prTxQue->u4NumElem); -+ } while (prNextMsduInfo); -+ -+ if (QUEUE_IS_NOT_EMPTY(&rNotEnqueuedQue)) { -+ QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(&rNotEnqueuedQue), NULL); -+ prMsduInfoReleaseList = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rNotEnqueuedQue); -+ } -+ -+ return prMsduInfoReleaseList; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Determine the STA_REC index for a packet -+* -+* \param[in] prMsduInfo Pointer to the packet -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID qmDetermineStaRecIndex(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ UINT_32 i; -+ -+ P_STA_RECORD_T prTempStaRec; -+ /* P_QUE_MGT_T prQM = &prAdapter->rQM; */ -+ -+ prTempStaRec = NULL; -+ -+ ASSERT(prMsduInfo); -+ -+ /* 4 <1> DA = BMCAST */ -+ if (IS_BMCAST_MAC_ADDR(prMsduInfo->aucEthDestAddr)) { -+ /* For intrastructure mode and P2P (playing as a GC), BMCAST frames shall be sent to the AP. -+ * FW shall take care of this. The host driver is not able to distinguish these cases. */ -+ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_BMCAST; -+ DBGLOG(QM, LOUD, "TX with DA = BMCAST\n"); -+ return; -+ } -+#if (CFG_SUPPORT_TDLS == 1) -+ /* Check if the peer is TDLS one */ -+ if (TdlsexStaRecIdxGet(prAdapter, prMsduInfo) == TDLS_STATUS_SUCCESS) -+ return; /* find a TDLS record */ -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ /* 4 <2> Check if an AP STA is present */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { -+ prTempStaRec = &(prAdapter->arStaRec[i]); -+ -+ if ((prTempStaRec->ucNetTypeIndex == prMsduInfo->ucNetworkType) -+ && (prTempStaRec->fgIsAp) -+ && (prTempStaRec->fgIsValid)) { -+ prMsduInfo->ucStaRecIndex = prTempStaRec->ucIndex; -+ return; -+ } -+ } -+ -+ /* 4 <3> Not BMCAST, No AP --> Compare DA (i.e., to see whether this is a unicast frame to a client) */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { -+ prTempStaRec = &(prAdapter->arStaRec[i]); -+ if (prTempStaRec->fgIsValid) { -+ if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, prMsduInfo->aucEthDestAddr)) { -+ prMsduInfo->ucStaRecIndex = prTempStaRec->ucIndex; -+ return; -+ } -+ } -+ } -+ -+ /* 4 <4> No STA found, Not BMCAST --> Indicate NOT_FOUND to FW */ -+ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; -+ DBGLOG(QM, LOUD, "QM: TX with STA_REC_INDEX_NOT_FOUND\n"); -+ -+#if (QM_TEST_MODE && QM_TEST_FAIR_FORWARDING) -+ prMsduInfo->ucStaRecIndex = (UINT_8) prQM->u4CurrentStaRecIndexToEnqueue; -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dequeue TX packets from a STA_REC for a particular TC -+* -+* \param[out] prQue The queue to put the dequeued packets -+* \param[in] ucTC The TC index (TC0_INDEX to TC5_INDEX) -+* \param[in] ucMaxNum The maximum amount of dequeued packets -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID -+qmDequeueTxPacketsFromPerStaQueues(IN P_ADAPTER_T prAdapter, -+ OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucCurrentQuota, IN UINT_8 ucTotalQuota) -+{ -+ -+#if QM_FORWARDING_FAIRNESS -+ UINT_32 i; /* Loop for */ -+ -+ PUINT_32 pu4HeadStaRecIndex; /* The Head STA index */ -+ PUINT_32 pu4HeadStaRecForwardCount; /* The total forwarded packets for the head STA */ -+ -+ P_STA_RECORD_T prStaRec; /* The current focused STA */ -+ P_BSS_INFO_T prBssInfo; /* The Bss for current focused STA */ -+ P_QUE_T prCurrQueue; /* The current TX queue to dequeue */ -+ P_MSDU_INFO_T prDequeuedPkt; /* The dequeued packet */ -+ -+ UINT_32 u4ForwardCount; /* To remember the total forwarded packets for a STA */ -+ UINT_32 u4MaxForwardCount; /* The maximum number of packets a STA can forward */ -+ UINT_32 u4Resource; /* The TX resource amount */ -+ -+ BOOLEAN fgChangeHeadSta; /* Whether a new head STA shall be determined at the end of the function */ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ PUINT_8 pucFreeQuota = NULL; -+#if CFG_ENABLE_WIFI_DIRECT -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo; -+ /*NFC Beam + Indication */ -+#endif -+ DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerStaQueues (TC = %u)\n", ucTC); -+ -+ ASSERT(ucTC == TC0_INDEX || ucTC == TC1_INDEX || ucTC == TC2_INDEX || ucTC == TC3_INDEX || ucTC == TC4_INDEX); -+ -+ if (!ucCurrentQuota) { -+ prQM->au4DequeueNoTcResourceCounter[ucTC]++; -+ DBGLOG(TX, LOUD, "@@@@@ TC = %u ucCurrentQuota = %u @@@@@\n", ucTC, ucCurrentQuota); -+ return; -+ } -+ -+ u4Resource = ucCurrentQuota; -+ -+ /* 4 <1> Determine the head STA */ -+ /* The head STA shall be an active STA */ -+ -+ pu4HeadStaRecIndex = &(prQM->au4HeadStaRecIndex[ucTC]); -+ pu4HeadStaRecForwardCount = &(prQM->au4ForwardCount[ucTC]); -+ -+ DBGLOG(QM, LOUD, "(Fairness) TID = %u Init Head STA = %u Resource = %u\n", -+ ucTC, *pu4HeadStaRecIndex, u4Resource); -+ -+ /* From STA[x] to STA[x+1] to STA[x+2] to ... to STA[x] */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD + 1; i++) { -+ prStaRec = &prAdapter->arStaRec[(*pu4HeadStaRecIndex)]; -+ ASSERT(prStaRec); -+ -+ /* Only Data frame (1x was not included) will be queued in */ -+ if (prStaRec->fgIsValid) { -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex); -+ -+ /* Determine how many packets the head STA is allowed to send in a round */ -+ -+ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_25); -+ u4MaxForwardCount = ucTotalQuota; -+#if CFG_ENABLE_WIFI_DIRECT -+ -+ pucFreeQuota = NULL; -+ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { -+ /* TODO: Change the threshold in coorperation with the PS forwarding mechanism */ -+ /* u4MaxForwardCount = ucTotalQuota; */ -+ /* Per STA flow control when STA in PS mode */ -+ /* The PHASE 1: only update from ucFreeQuota (now) */ -+ /* XXX The PHASE 2: Decide by ucFreeQuota and ucBmpDeliveryAC (per queue ) */ -+ /* aucFreeQuotaPerQueue[] */ -+ /* NOTE: other method to set u4Resource */ -+ -+ if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported -+ /* && prAdapter->rWifiVar.fgSupportQoS -+ && prAdapter->rWifiVar.fgSupportUAPSD */) { -+ -+ if (prStaRec->ucBmpTriggerAC & BIT(ucTC)) { -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForDelivery; -+ } else { -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; -+ } -+ -+ } else { -+ ASSERT(prStaRec->ucFreeQuotaForDelivery == 0); -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; -+ } -+ -+ } /* fgIsInPS */ -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ -+ /*NFC Beam + Indication */ -+ -+ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ if ((prChnlReqInfo->NFC_BEAM != 1) && -+ (u4MaxForwardCount > prBssInfo->ucBssFreeQuota)) -+ u4MaxForwardCount = prBssInfo->ucBssFreeQuota; -+ } else { -+ if (u4MaxForwardCount > prBssInfo->ucBssFreeQuota) -+ u4MaxForwardCount = prBssInfo->ucBssFreeQuota; -+ } -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ /* Determine whether the head STA can continue to forward packets in this round */ -+ if ((*pu4HeadStaRecForwardCount) < u4MaxForwardCount) -+ break; -+ -+ } /* prStaRec->fgIsValid */ -+ else { -+ /* The current Head STA has been deactivated, so search for a new head STA */ -+ prStaRec = NULL; -+ prBssInfo = NULL; -+ (*pu4HeadStaRecIndex)++; -+ (*pu4HeadStaRecIndex) %= CFG_NUM_OF_STA_RECORD; -+ -+ /* Reset the forwarding count before searching (since this is for a new selected STA) */ -+ (*pu4HeadStaRecForwardCount) = 0; -+ } -+ } /* i < CFG_NUM_OF_STA_RECORD + 1 */ -+ -+ /* All STA_RECs are inactive, so exit */ -+ if (!prStaRec) { -+ /* Under concurrent, it is possible that there is no candidcated STA. */ -+ /* DBGLOG(TX, EVENT, ("All STA_RECs are inactive\n")); */ -+ return; -+ } -+ -+ DBGLOG(QM, LOUD, "(Fairness) TID = %u Round Head STA = %u\n", ucTC, *pu4HeadStaRecIndex); -+ -+ /* 4 <2> Dequeue packets from the head STA */ -+ -+ prCurrQueue = &prStaRec->arTxQueue[ucTC]; -+ prDequeuedPkt = NULL; -+ fgChangeHeadSta = FALSE; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ if (pucFreeQuota != NULL) -+ TdlsexTxQuotaCheck(prAdapter->prGlueInfo, prStaRec, *pucFreeQuota); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ while (prCurrQueue) { -+ -+#if QM_DEBUG_COUNTER -+ -+ if (ucTC <= TC4_INDEX) { -+ if (QUEUE_IS_EMPTY(prCurrQueue)) { -+ QM_DBG_CNT_INC(prQM, ucTC); -+ /* QM_DBG_CNT_00 *//* QM_DBG_CNT_01 *//* QM_DBG_CNT_02 */ -+ /* QM_DBG_CNT_03 *//* QM_DBG_CNT_04 */ -+ } -+ if (u4Resource == 0) { -+ QM_DBG_CNT_INC(prQM, ucTC + 5); -+ /* QM_DBG_CNT_05 *//* QM_DBG_CNT_06 *//* QM_DBG_CNT_07 */ -+ /* QM_DBG_CNT_08 *//* QM_DBG_CNT_09 */ -+ } -+ if (((*pu4HeadStaRecForwardCount) >= u4MaxForwardCount)) { -+ QM_DBG_CNT_INC(prQM, ucTC + 10); -+ /* QM_DBG_CNT_10 *//* QM_DBG_CNT_11 *//* QM_DBG_CNT_12 */ -+ /* QM_DBG_CNT_13 *//* QM_DBG_CNT_14 */ -+ } -+ } -+#endif -+ -+ /* Three cases to break: (1) No resource (2) No packets (3) Fairness */ -+ if (QUEUE_IS_EMPTY(prCurrQueue) || ((*pu4HeadStaRecForwardCount) >= u4MaxForwardCount)) { -+ fgChangeHeadSta = TRUE; -+ break; -+ } else if (u4Resource == 0) { -+#if (CFG_SUPPORT_STATISTICS == 1) -+ prStaRec->u4NumOfNoTxQuota++; -+#endif /* CFG_SUPPORT_STATISTICS */ -+ break; -+ } -+ -+ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); -+ prStaRec->u4DeqeueuCounter++; -+ prQM->u4DequeueCounter++; -+ -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ if (prDequeuedPkt != NULL) { -+ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; -+ UINT8 *pkt = prSkb->data; -+ UINT16 u2Identifier; -+ -+ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { -+ /* ip */ -+ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); -+ DBGLOG(QM, LOUD, " %d\n", u2Identifier); -+ } -+ } -+#endif -+#if DBG && 0 -+ LOG_FUNC("Deq0 TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n", -+ prDequeuedPkt->ucTC, -+ prCurrQueue->u4NumElem, -+ prDequeuedPkt->ucNetworkType, -+ prDequeuedPkt->ucMacHeaderLength, -+ prDequeuedPkt->u2FrameLength, -+ prDequeuedPkt->ucPacketType, prDequeuedPkt->fgIs802_1x, prDequeuedPkt->fgIs802_11); -+ -+ LOG_FUNC("Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr); -+ -+#if LINUX -+ { -+ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; -+ -+ dumpMemory8((PUINT_8) prSkb->data, prSkb->len); -+ } -+#endif -+ -+#endif -+ -+ ASSERT(prDequeuedPkt->ucTC == ucTC); -+ -+ if (!QUEUE_IS_EMPTY(prCurrQueue)) { -+ /* XXX: check all queues for STA */ -+ prDequeuedPkt->ucPsForwardingType = PS_FORWARDING_MORE_DATA_ENABLED; -+ } -+ -+ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); -+ u4Resource--; -+ (*pu4HeadStaRecForwardCount)++; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* XXX The PHASE 2: decrease from aucFreeQuotaPerQueue[] */ -+ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { -+ if ((pucFreeQuota) && (*pucFreeQuota > 0)) -+ *pucFreeQuota = *pucFreeQuota - 1; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { -+ if (prBssInfo->ucBssFreeQuota > 0) -+ prBssInfo->ucBssFreeQuota--; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ } -+ -+ if (*pu4HeadStaRecForwardCount) { -+ DBGLOG(QM, LOUD, -+ "TC = %u Round Head STA = %u, u4HeadStaRecForwardCount = %u\n", ucTC, *pu4HeadStaRecIndex, -+ (*pu4HeadStaRecForwardCount)); -+ } -+#if QM_BURST_END_INFO_ENABLED -+ /* Let FW know which packet is the last one dequeued from the STA */ -+ if (prDequeuedPkt) -+ prDequeuedPkt->fgIsBurstEnd = TRUE; -+#endif -+ -+ /* 4 <3> Dequeue from the other STAs if there is residual TX resource */ -+ -+ /* Check all of the STAs to continue forwarding packets (including the head STA) */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { -+ /* Break in case no reasource is available */ -+ if (u4Resource == 0) { -+ prQM->au4DequeueNoTcResourceCounter[ucTC]++; -+ break; -+ } -+ -+ /* The current head STA will be examined when i = CFG_NUM_OF_STA_RECORD-1 */ -+ prStaRec = &prAdapter->arStaRec[((*pu4HeadStaRecIndex) + i + 1) % CFG_NUM_OF_STA_RECORD]; -+ ASSERT(prStaRec); -+ -+ if (prStaRec->fgIsValid) { -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex); -+ -+ DBGLOG(QM, LOUD, "(Fairness) TID = %u Sharing STA = %u Resource = %u\n", -+ ucTC, prStaRec->ucIndex, u4Resource); -+ -+ prCurrQueue = &prStaRec->arTxQueue[ucTC]; -+ u4ForwardCount = 0; -+ u4MaxForwardCount = ucTotalQuota; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ pucFreeQuota = NULL; -+ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { -+ /* TODO: Change the threshold in coorperation with the PS forwarding mechanism */ -+ /* u4MaxForwardCount = ucTotalQuota; */ -+ /* Per STA flow control when STA in PS mode */ -+ /* The PHASE 1: only update from ucFreeQuota (now) */ -+ /* XXX The PHASE 2: Decide by ucFreeQuota and ucBmpDeliveryAC (per queue ) */ -+ /* aucFreeQuotaPerQueue[] */ -+ /* NOTE: other method to set u4Resource */ -+ if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported -+ /* && prAdapter->rWifiVar.fgSupportQoS -+ && prAdapter->rWifiVar.fgSupportUAPSD */) { -+ -+ if (prStaRec->ucBmpTriggerAC & BIT(ucTC)) { -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForDelivery; -+ } else { -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; -+ } -+ -+ } else { -+ ASSERT(prStaRec->ucFreeQuotaForDelivery == 0); -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; -+ } -+ -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { -+ if (u4MaxForwardCount > prBssInfo->ucBssFreeQuota) -+ u4MaxForwardCount = prBssInfo->ucBssFreeQuota; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ } /* prStaRec->fgIsValid */ -+ else { -+ prBssInfo = NULL; -+ /* Invalid STA, so check the next STA */ -+ continue; -+ } -+ -+ while (prCurrQueue) { -+ /* Three cases to break: (1) No resource (2) No packets (3) Fairness */ -+ if ((u4Resource == 0) || QUEUE_IS_EMPTY(prCurrQueue) || (u4ForwardCount >= u4MaxForwardCount)) -+ break; -+ -+ -+ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); -+ -+#if DBG && 0 -+ DBGLOG(QM, LOUD, "Deq0 TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n", -+ prDequeuedPkt->ucTC, -+ prCurrQueue->u4NumElem, -+ prDequeuedPkt->ucNetworkType, -+ prDequeuedPkt->ucMacHeaderLength, -+ prDequeuedPkt->u2FrameLength, -+ prDequeuedPkt->ucPacketType, -+ prDequeuedPkt->fgIs802_1x, prDequeuedPkt->fgIs802_11)); -+ -+ DBGLOG(QM, LOUD, "Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr); -+ -+#if LINUX -+ { -+ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; -+ -+ dumpMemory8((PUINT_8) prSkb->data, prSkb->len); -+ } -+#endif -+ -+#endif -+ -+ ASSERT(prDequeuedPkt->ucTC == ucTC); -+ -+ if (!QUEUE_IS_EMPTY(prCurrQueue)) -+ /* more data field ? */ -+ prDequeuedPkt->ucPsForwardingType = PS_FORWARDING_MORE_DATA_ENABLED; -+ -+ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); -+ if (prStaRec) -+ prStaRec->u4DeqeueuCounter++; -+ prQM->u4DequeueCounter++; -+ u4Resource--; -+ u4ForwardCount++; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* XXX The PHASE 2: decrease from aucFreeQuotaPerQueue[] */ -+ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { -+ ASSERT(pucFreeQuota); -+ ASSERT(*pucFreeQuota > 0); -+ if (*pucFreeQuota > 0) -+ *pucFreeQuota = *pucFreeQuota - 1; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex); -+ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { -+ if (prBssInfo->ucBssFreeQuota > 0) -+ prBssInfo->ucBssFreeQuota--; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ } -+ -+#if QM_BURST_END_INFO_ENABLED -+ /* Let FW know which packet is the last one dequeued from the STA */ -+ if (u4ForwardCount) -+ prDequeuedPkt->fgIsBurstEnd = TRUE; -+#endif -+ } -+ -+ if (fgChangeHeadSta) { -+ (*pu4HeadStaRecIndex)++; -+ (*pu4HeadStaRecIndex) %= CFG_NUM_OF_STA_RECORD; -+ (*pu4HeadStaRecForwardCount) = 0; -+ DBGLOG(QM, LOUD, "(Fairness) TID = %u Scheduled Head STA = %u Left Resource = %u\n", -+ ucTC, (*pu4HeadStaRecIndex), u4Resource); -+ } -+ -+/***************************************************************************************/ -+#else -+ UINT_8 ucStaRecIndex; -+ P_STA_RECORD_T prStaRec; -+ P_QUE_T prCurrQueue; -+ UINT_8 ucPktCount; -+ P_MSDU_INFO_T prDequeuedPkt; -+ -+ DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerStaQueues (TC = %u)\n", ucTC); -+ -+ if (ucCurrentQuota == 0) -+ return; -+ /* 4 <1> Determine the queue index and the head STA */ -+ -+ /* The head STA */ -+ ucStaRecIndex = 0; /* TODO: Get the current head STA */ -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (prStaRec == NULL) -+ return; -+ -+ /* The queue to pull out packets */ -+ ASSERT(ucTC == TC0_INDEX || ucTC == TC1_INDEX || ucTC == TC2_INDEX || ucTC == TC3_INDEX || ucTC == TC4_INDEX); -+ prCurrQueue = &prStaRec->arTxQueue[ucTC]; -+ -+ ucPktCount = ucCurrentQuota; -+ prDequeuedPkt = NULL; -+ -+ /* 4 <2> Dequeue packets for the head STA */ -+ while (TRUE) { -+ if (!(prStaRec->fgIsValid) || ucPktCount == 0 || QUEUE_IS_EMPTY(prCurrQueue)) { -+ break; -+ -+ } else { -+ -+ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); -+ /* DbgPrint("QM: Remove Queue Head, TC= %d\n", prDequeuedPkt->ucTC); */ -+ ASSERT(prDequeuedPkt->ucTC == ucTC); -+ -+ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); -+ ucPktCount--; -+ } -+ } -+ -+ /* DbgPrint("QM: Remaining number of queued packets = %d\n", prCurrQueue->u4NumElem); */ -+ -+#if QM_BURST_END_INFO_ENABLED -+ if (prDequeuedPkt) -+ prDequeuedPkt->fgIsBurstEnd = TRUE; -+#endif -+ -+ /* 4 <3> Update scheduling info */ -+ /* TODO */ -+ -+ /* 4 <4> Utilize the remainaing TX opportunities for non-head STAs */ -+ /* TODO */ -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dequeue TX packets from a per-Type-based Queue for a particular TC -+* -+* \param[out] prQue The queue to put the dequeued packets -+* \param[in] ucTC The TC index (Shall always be TC5_INDEX) -+* \param[in] ucMaxNum The maximum amount of dequeued packets -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID -+qmDequeueTxPacketsFromPerTypeQueues(IN P_ADAPTER_T prAdapter, OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucMaxNum) -+{ -+ /* UINT_8 ucQueIndex; */ -+ /* UINT_8 ucStaRecIndex; */ -+ P_BSS_INFO_T prBssInfo; -+ P_BSS_INFO_T parBssInfo; -+ P_QUE_T prCurrQueue; -+ UINT_8 ucPktCount; -+ P_MSDU_INFO_T prDequeuedPkt; -+ P_MSDU_INFO_T prBurstEndPkt; -+ QUE_T rMergeQue; -+ P_QUE_T prMergeQue; -+ P_QUE_MGT_T prQM; -+ -+ DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerTypeQueues (TC = %d, Max = %d)\n", ucTC, ucMaxNum); -+ -+ /* TC5: Broadcast/Multicast data packets */ -+ ASSERT(ucTC == TC5_INDEX); -+ -+ if (ucMaxNum == 0) -+ return; -+ -+ prQM = &prAdapter->rQM; -+ /* 4 <1> Determine the queue */ -+ -+ prCurrQueue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; -+ ucPktCount = ucMaxNum; -+ prDequeuedPkt = NULL; -+ prBurstEndPkt = NULL; -+ -+ parBssInfo = prAdapter->rWifiVar.arBssInfo; -+ -+ QUEUE_INITIALIZE(&rMergeQue); -+ prMergeQue = &rMergeQue; -+ -+ /* 4 <2> Dequeue packets */ -+ while (TRUE) { -+ if (ucPktCount == 0 || QUEUE_IS_EMPTY(prCurrQueue)) -+ break; -+ -+ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); -+ ASSERT(prDequeuedPkt->ucTC == ucTC); -+ -+ ASSERT(prDequeuedPkt->ucNetworkType < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &parBssInfo[prDequeuedPkt->ucNetworkType]; -+ -+ if (IS_BSS_ACTIVE(prBssInfo)) { -+ if (!prBssInfo->fgIsNetAbsent) { -+ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); -+ prQM->u4DequeueCounter++; -+ prBurstEndPkt = prDequeuedPkt; -+ ucPktCount--; -+ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_26); -+#if DBG && 0 -+ LOG_FUNC -+ ("DeqType TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n", -+ prDequeuedPkt->ucTC, prCurrQueue->u4NumElem, prDequeuedPkt->ucNetworkType, -+ prDequeuedPkt->ucMacHeaderLength, prDequeuedPkt->u2FrameLength, -+ prDequeuedPkt->ucPacketType, prDequeuedPkt->fgIs802_1x, -+ prDequeuedPkt->fgIs802_11); -+ -+ LOG_FUNC("Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr); -+ -+#if LINUX -+ { -+ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; -+ -+ dumpMemory8((PUINT_8) prSkb->data, prSkb->len); -+ } -+#endif -+ -+#endif -+ } else { -+ QUEUE_INSERT_TAIL(prMergeQue, (P_QUE_ENTRY_T) prDequeuedPkt); -+ } -+ } else { -+ QM_TX_SET_NEXT_MSDU_INFO(prDequeuedPkt, NULL); -+ wlanProcessQueuedMsduInfo(prAdapter, prDequeuedPkt); -+ } -+ } -+ -+ if (QUEUE_IS_NOT_EMPTY(prMergeQue)) { -+ QUEUE_CONCATENATE_QUEUES(prMergeQue, prCurrQueue); -+ QUEUE_MOVE_ALL(prCurrQueue, prMergeQue); -+ if (QUEUE_GET_TAIL(prCurrQueue)) -+ QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(prCurrQueue), NULL); -+ } -+#if QM_BURST_END_INFO_ENABLED -+ if (prBurstEndPkt) -+ prBurstEndPkt->fgIsBurstEnd = TRUE; -+#endif -+} /* qmDequeueTxPacketsFromPerTypeQueues */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dequeue TX packets to send to HIF TX -+* -+* \param[in] prTcqStatus Info about the maximum amount of dequeued packets -+* -+* \return The list of dequeued TX packets -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T qmDequeueTxPackets(IN P_ADAPTER_T prAdapter, IN P_TX_TCQ_STATUS_T prTcqStatus) -+{ -+ -+ INT32 i; -+ P_MSDU_INFO_T prReturnedPacketListHead; -+ QUE_T rReturnedQue; -+ -+ DBGLOG(QM, LOUD, "Enter qmDequeueTxPackets\n"); -+ -+ QUEUE_INITIALIZE(&rReturnedQue); -+ -+ prReturnedPacketListHead = NULL; -+ -+ /* dequeue packets from different AC queue based on available aucFreeBufferCount */ -+ /* TC0 to TC4: AC0~AC3, 802.1x (commands packets are not handled by QM) */ -+ for (i = TC4_INDEX; i >= TC0_INDEX; i--) { -+ DBGLOG(QM, LOUD, "Dequeue packets from Per-STA queue[%d]\n", i); -+ -+ /* -+ in the function, we will re-calculate the ucFreeQuota. -+ If any packet with any priority for the station will be sent, ucFreeQuota -- -+ -+ Note1: ucFreeQuota will be decrease only when station is in power save mode. -+ In active mode, we will sent the packet to the air directly. -+ -+ if(prStaRec->fgIsInPS && (ucTC!=TC4_INDEX)) { -+ ASSERT(pucFreeQuota); -+ ASSERT(*pucFreeQuota>0); -+ if ((pucFreeQuota) && (*pucFreeQuota>0)) { -+ *pucFreeQuota = *pucFreeQuota - 1; -+ } -+ } -+ -+ Note2: maximum queued number for a station is 10, TXM_MAX_BUFFER_PER_STA_DEF in fw -+ i.e. default prStaRec->ucFreeQuota = 10 -+ -+ Note3: In qmUpdateFreeQuota(), we will adjust -+ ucFreeQuotaForNonDelivery = ucFreeQuota>>1; -+ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; -+ */ -+ qmDequeueTxPacketsFromPerStaQueues(prAdapter, -+ &rReturnedQue, -+ (UINT_8) i, -+ prTcqStatus->aucFreeBufferCount[i], /* maximum dequeue number */ -+ prTcqStatus->aucMaxNumOfBuffer[i]); -+ -+ /* The aggregate number of dequeued packets */ -+ DBGLOG(QM, LOUD, "DQA)[%u](%u)\n", i, rReturnedQue.u4NumElem); -+ } -+ -+ /* TC5 (BMCAST or STA-NOT-FOUND packets) */ -+ qmDequeueTxPacketsFromPerTypeQueues(prAdapter, -+ &rReturnedQue, TC5_INDEX, prTcqStatus->aucFreeBufferCount[TC5_INDEX] -+ ); -+ -+ DBGLOG(QM, LOUD, "Current total number of dequeued packets = %u\n", rReturnedQue.u4NumElem); -+ -+ if (QUEUE_IS_NOT_EMPTY(&rReturnedQue)) { -+ prReturnedPacketListHead = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rReturnedQue); -+ QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(&rReturnedQue), NULL); -+ } -+ -+ return prReturnedPacketListHead; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Adjust the TC quotas according to traffic demands -+* -+* \param[out] prTcqAdjust The resulting adjustment -+* \param[in] prTcqStatus Info about the current TC quotas and counters -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmAdjustTcQuotas(IN P_ADAPTER_T prAdapter, OUT P_TX_TCQ_ADJUST_T prTcqAdjust, IN P_TX_TCQ_STATUS_T prTcqStatus) -+{ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ UINT_32 i; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ /* Must reset */ -+ for (i = 0; i < TC_NUM; i++) -+ prTcqAdjust->acVariation[i] = 0; -+ -+ /* 4 <1> If TC resource is not just adjusted, exit directly */ -+ if (!prQM->fgTcResourcePostAnnealing) -+ return; -+ /* 4 <2> Adjust TcqStatus according to the updated prQM->au4CurrentTcResource */ -+ else { -+ INT_32 i4TotalExtraQuota = 0; -+ INT_32 ai4ExtraQuota[TC_NUM]; -+ BOOLEAN fgResourceRedistributed = TRUE; -+ -+ /* Obtain the free-to-distribute resource */ -+ for (i = 0; i < TC_NUM; i++) { -+ ai4ExtraQuota[i] = -+ (INT_32) prTcqStatus->aucMaxNumOfBuffer[i] - (INT_32) prQM->au4CurrentTcResource[i]; -+ -+ if (ai4ExtraQuota[i] > 0) { /* The resource shall be reallocated to other TCs */ -+ -+ if (ai4ExtraQuota[i] > prTcqStatus->aucFreeBufferCount[i]) { -+ /* -+ we have residunt TC resources for the TC: -+ EX: aucMaxNumOfBuffer[] = 20, au4CurrentTcResource[] = 5 -+ ai4ExtraQuota[] = 15, aucFreeBufferCount[] = 10 -+ -+ so ai4ExtraQuota[] = aucFreeBufferCount[] = 10 -+ because we available TC resources actually is 10, not 20 -+ */ -+ ai4ExtraQuota[i] = prTcqStatus->aucFreeBufferCount[i]; -+ -+ /* -+ FALSE means we can re-do TC resource adjustment in tx done -+ at next time, maybe more tx done is finished -+ */ -+ fgResourceRedistributed = FALSE; -+ } -+ -+ /* accumulate current all available TC resources */ -+ i4TotalExtraQuota += ai4ExtraQuota[i]; -+ -+ /* deduce unused TC resources for the TC */ -+ prTcqAdjust->acVariation[i] = (INT_8) (-ai4ExtraQuota[i]); -+ } -+ } -+ -+ /* Distribute quotas to TCs which need extra resource according to prQM->au4CurrentTcResource */ -+ for (i = 0; i < TC_NUM; i++) { -+ if (ai4ExtraQuota[i] < 0) { -+ -+ /* The TC needs extra resources */ -+ if ((-ai4ExtraQuota[i]) > i4TotalExtraQuota) { -+ /* the number of needed extra resources is larger than total available */ -+ ai4ExtraQuota[i] = (-i4TotalExtraQuota); -+ -+ /* wait for next tx done to do adjustment */ -+ fgResourceRedistributed = FALSE; -+ } -+ -+ /* decrease the total available */ -+ i4TotalExtraQuota += ai4ExtraQuota[i]; -+ -+ /* mark to increase TC resources for the TC */ -+ prTcqAdjust->acVariation[i] = (INT_8) (-ai4ExtraQuota[i]); -+ } -+ } -+ -+ /* In case some TC is waiting for TX Done, continue to adjust TC quotas upon TX Done */ -+ -+ /* -+ if fgResourceRedistributed == TRUE, it means we will adjust at this time so -+ we need to re-adjust TC resources (fgTcResourcePostAnnealing = FALSE). -+ */ -+ prQM->fgTcResourcePostAnnealing = (!fgResourceRedistributed); -+ -+#if QM_PRINT_TC_RESOURCE_CTRL -+ DBGLOG(QM, LOUD, "QM: Curr Quota [0]=%u [1]=%u [2]=%u [3]=%u [4]=%u [5]=%u\n", -+ prTcqStatus->aucFreeBufferCount[0], -+ prTcqStatus->aucFreeBufferCount[1], -+ prTcqStatus->aucFreeBufferCount[2], -+ prTcqStatus->aucFreeBufferCount[3], -+ prTcqStatus->aucFreeBufferCount[4], prTcqStatus->aucFreeBufferCount[5] -+ )); -+#endif -+ } -+ -+#else -+ UINT_32 i; -+ -+ for (i = 0; i < TC_NUM; i++) -+ prTcqAdjust->acVariation[i] = 0; -+ -+#endif -+} -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Update the average TX queue length for the TC resource control mechanism -+* -+* \param (none) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmUpdateAverageTxQueLen(IN P_ADAPTER_T prAdapter) -+{ -+ INT_32 u4CurrQueLen, i, k; -+ P_STA_RECORD_T prStaRec; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ /* 4 <1> Update the queue lengths for TC0 to TC3 (skip TC4) and TC5 */ -+ /* use moving average algorithm to calculate au4AverageQueLen for every TC queue */ -+ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES - 1; i++) { -+ u4CurrQueLen = 0; -+ -+ for (k = 0; k < CFG_NUM_OF_STA_RECORD; k++) { -+ prStaRec = &prAdapter->arStaRec[k]; -+ ASSERT(prStaRec); -+ -+ /* If the STA is activated, get the queue length */ -+ if (prStaRec->fgIsValid && -+ (!prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex].fgIsNetAbsent) -+ ) { -+ -+ u4CurrQueLen += (prStaRec->arTxQueue[i].u4NumElem); -+ } -+ } -+ -+ if (prQM->au4AverageQueLen[i] == 0) { -+ prQM->au4AverageQueLen[i] = (u4CurrQueLen << QM_QUE_LEN_MOVING_AVE_FACTOR); /* *8 */ -+ } else { -+ /* len => len - len/8 = 7/8 * len + new len */ -+ prQM->au4AverageQueLen[i] -= (prQM->au4AverageQueLen[i] >> QM_QUE_LEN_MOVING_AVE_FACTOR); -+ prQM->au4AverageQueLen[i] += (u4CurrQueLen); -+ } -+ -+ } -+ -+ /* Update the queue length for TC5 (BMCAST) */ -+ u4CurrQueLen = prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST].u4NumElem; -+ -+ if (prQM->au4AverageQueLen[TC_NUM - 1] == 0) { -+ prQM->au4AverageQueLen[TC_NUM - 1] = (u4CurrQueLen << QM_QUE_LEN_MOVING_AVE_FACTOR); -+ } else { -+ prQM->au4AverageQueLen[TC_NUM - 1] -= -+ (prQM->au4AverageQueLen[TC_NUM - 1] >> QM_QUE_LEN_MOVING_AVE_FACTOR); -+ prQM->au4AverageQueLen[TC_NUM - 1] += (u4CurrQueLen); -+ } -+ -+ /* 4 <2> Adjust TC resource assignment every 3 times */ -+ /* Check whether it is time to adjust the TC resource assignment */ -+ if (--prQM->u4TimeToAdjustTcResource == 0) { /* u4TimeToAdjustTcResource = 3 */ -+ -+ /* The last assignment has not been completely applied */ -+ if (prQM->fgTcResourcePostAnnealing) { -+ /* Upon the next qmUpdateAverageTxQueLen function call, do this check again */ -+ -+ /* wait for next time to do qmReassignTcResource */ -+ prQM->u4TimeToAdjustTcResource = 1; -+ } else { /* The last assignment has been applied */ -+ prQM->u4TimeToAdjustTcResource = QM_INIT_TIME_TO_ADJUST_TC_RSC; -+ qmReassignTcResource(prAdapter); -+ } -+ } -+ -+ /* Debug */ -+#if QM_PRINT_TC_RESOURCE_CTRL -+ for (i = 0; i < TC_NUM; i++) { -+ if (QM_GET_TX_QUEUE_LEN(prAdapter, i) >= 100) { -+ DBGLOG(QM, LOUD, "QM: QueLen [%u %u %u %u %u %u]\n", -+ QM_GET_TX_QUEUE_LEN(prAdapter, 0), -+ QM_GET_TX_QUEUE_LEN(prAdapter, 1), -+ QM_GET_TX_QUEUE_LEN(prAdapter, 2), -+ QM_GET_TX_QUEUE_LEN(prAdapter, 3), -+ QM_GET_TX_QUEUE_LEN(prAdapter, 4), QM_GET_TX_QUEUE_LEN(prAdapter, 5) -+ )); -+ break; -+ } -+ } -+#endif -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Assign TX resource for each TC according to TX queue length and current assignment -+* -+* \param (none) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmReassignTcResource(IN P_ADAPTER_T prAdapter) -+{ -+ INT_32 i4TotalResourceDemand = 0; -+ UINT_32 u4ResidualResource = 0; -+ UINT_32 i; -+ INT_32 ai4PerTcResourceDemand[TC_NUM]; -+ UINT_32 u4ShareCount = 0; -+ UINT_32 u4Share = 0; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ /* Note: After the new assignment is obtained, set prQM->fgTcResourcePostAnnealing to TRUE to -+ * start the TC-quota adjusting procedure, which will be invoked upon every TX Done -+ */ -+ /* tx done -> nicProcessTxInterrupt() -> nicTxAdjustTcq() -+ * -> qmAdjustTcQuotas() -> check fgTcResourcePostAnnealing */ -+ -+ /* 4 <1> Determine the demands */ -+ /* Determine the amount of extra resource to fulfill all of the demands */ -+ for (i = 0; i < TC_NUM; i++) { -+ /* Skip TC4, which is not adjustable */ -+ if (i == TC4_INDEX) -+ continue; -+ -+ /* -+ Define: extra_demand = average que_length (includes all station records) + -+ min_reserved_quota - -+ current available TC resources -+ -+ extra_demand means we need extra TC resources to transmit; other TCs can -+ borrow their resources to us? -+ */ -+ ai4PerTcResourceDemand[i] = -+ ((UINT_32) (QM_GET_TX_QUEUE_LEN(prAdapter, i)) + -+ prQM->au4MinReservedTcResource[i] - prQM->au4CurrentTcResource[i]); -+ -+ /* If there are queued packets, allocate extra resource for the TC (for TCP consideration) */ -+ if (QM_GET_TX_QUEUE_LEN(prAdapter, i)) -+ ai4PerTcResourceDemand[i] += QM_EXTRA_RESERVED_RESOURCE_WHEN_BUSY; /* 0 */ -+ -+ /* -+ accumulate all needed extra TC resources -+ maybe someone need + resource, maybe someone need - resource -+ */ -+ i4TotalResourceDemand += ai4PerTcResourceDemand[i]; -+ } -+ -+ /* 4 <2> Case 1: Demand <= Total Resource */ -+ if (i4TotalResourceDemand <= 0) { -+ /* 4 <2.1> Satisfy every TC */ -+ /* total TC resources are enough, no extra TC resources is needed */ -+ -+ /* adjust used TC resources to average TC resources + min reserve TC resources */ -+ for (i = 0; i < TC_NUM; i++) { -+ /* Skip TC4 (not adjustable) */ -+ if (i == TC4_INDEX) -+ continue; -+ -+ /* -+ the number of resources that one TC releases can be used for -+ other TCs -+ -+ EX: TC0 au4CurrentTcResource[0] = 10 ai4PerTcResourceDemand[0] = -5 -+ TC1 au4CurrentTcResource[1] = 5 ai4PerTcResourceDemand[0] = +5 -+ => TC0 au4CurrentTcResource[0] = 10 + (-5) = 5 -+ TC1 au4CurrentTcResource[1] = 5 + (+5) = 10 -+ */ -+ prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; -+ } -+ -+ /* 4 <2.2> Share the residual resource evenly */ -+ u4ShareCount = (TC_NUM - 1); /* 5, excluding TC4 */ -+ -+ /* -+ EX: i4TotalResourceDemand = -10 -+ means we have 10 available resources can be used. -+ */ -+ u4ResidualResource = (UINT_32) (-i4TotalResourceDemand); -+ u4Share = (u4ResidualResource / u4ShareCount); -+ -+ /* share available TC resources to all TCs averagely */ -+ for (i = 0; i < TC_NUM; i++) { -+ /* Skip TC4 (not adjustable) */ -+ if (i == TC4_INDEX) -+ continue; -+ -+ /* allocate residual average resources to the TC */ -+ prQM->au4CurrentTcResource[i] += u4Share; -+ -+ /* Every TC is fully satisfied so no need extra resources */ -+ ai4PerTcResourceDemand[i] = 0; -+ -+ /* decrease the allocated resources */ -+ u4ResidualResource -= u4Share; -+ } -+ -+ /* if still have available resources, we decide to give them to VO (TC3) queue */ -+ /* 4 <2.3> Allocate the left resource to TC3 (VO) */ -+ prQM->au4CurrentTcResource[TC3_INDEX] += (u4ResidualResource); -+ -+ } -+ /* 4 <3> Case 2: Demand > Total Resource --> Guarantee a minimum amount of resource for each TC */ -+ else { -+ /* -+ u4ResidualResource means we at least need to keep -+ QM_INITIAL_RESIDUAL_TC_RESOURCE available TC resources -+ -+ in 6628, u4ResidualResource = 26, max 28 -+ */ -+ u4ResidualResource = QM_INITIAL_RESIDUAL_TC_RESOURCE; -+ -+ /* 4 <3.1> Allocated resource amount = minimum of (guaranteed, total demand) */ -+ for (i = 0; i < TC_NUM; i++) { -+ -+ if (i == TC4_INDEX) -+ continue; /* Skip TC4 (not adjustable) */ -+ -+ /* The demand can be fulfilled with the guaranteed resource amount 4 4 6 6 2 4 */ -+ -+ /* -+ ai4PerTcResourceDemand[i] = -+ ((UINT_32)(QM_GET_TX_QUEUE_LEN(prAdapter, i)) + -+ prQM->au4MinReservedTcResource[i] - -+ prQM->au4CurrentTcResource[i]); -+ -+ so au4CurrentTcResource + ai4PerTcResourceDemand = -+ -+ ((UINT_32)(QM_GET_TX_QUEUE_LEN(prAdapter, i)) + -+ prQM->au4MinReservedTcResource[i] = -+ -+ current average queue len + min TC resources -+ */ -+ if (prQM->au4CurrentTcResource[i] + ai4PerTcResourceDemand[i] < -+ prQM->au4GuaranteedTcResource[i]) { -+ -+ /* avg queue len + min reserve still smaller than guarantee so enough */ -+ prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; -+ -+ /* accumulate available TC resources from the TC */ -+ u4ResidualResource += -+ (prQM->au4GuaranteedTcResource[i] - prQM->au4CurrentTcResource[i]); -+ ai4PerTcResourceDemand[i] = 0; -+ } -+ -+ /* The demand can not be fulfilled with the guaranteed resource amount */ -+ else { -+ -+ /* means even we use all guarantee resources for the TC is still not enough */ -+ -+ /* -+ guarantee number is always for the TC so extra resource number cannot -+ include the guarantee number. -+ -+ EX: au4GuaranteedTcResource = 10, au4CurrentTcResource = 5 -+ ai4PerTcResourceDemand = 6 -+ -+ ai4PerTcResourceDemand -= (10 - 5) ==> 1 -+ only need extra 1 TC resouce is enough. -+ */ -+ ai4PerTcResourceDemand[i] -= -+ (prQM->au4GuaranteedTcResource[i] - prQM->au4CurrentTcResource[i]); -+ -+ /* update current avg TC resource to guarantee number */ -+ prQM->au4CurrentTcResource[i] = prQM->au4GuaranteedTcResource[i]; -+ -+ /* count how many TC queues need to get extra resources */ -+ u4ShareCount++; -+ } -+ } -+ -+ /* 4 <3.2> Allocate the residual resource */ -+ do { -+ /* If there is no resource left, exit directly */ -+ if (u4ResidualResource == 0) -+ break; -+ -+ /* This shall not happen */ -+ if (u4ShareCount == 0) { -+ prQM->au4CurrentTcResource[TC1_INDEX] += u4ResidualResource; -+ DBGLOG(QM, ERROR, "QM: (Error) u4ShareCount = 0\n"); -+ break; -+ } -+ -+ /* Share the residual resource evenly */ -+ u4Share = (u4ResidualResource / u4ShareCount); -+ -+ if (u4Share) { -+ for (i = 0; i < TC_NUM; i++) { -+ /* Skip TC4 (not adjustable) */ -+ if (i == TC4_INDEX) -+ continue; -+ -+ if (ai4PerTcResourceDemand[i] == 0) -+ continue; -+ -+ if (ai4PerTcResourceDemand[i] - u4Share) { -+ /* still not enough but we just can give it u4Share resources */ -+ prQM->au4CurrentTcResource[i] += u4Share; -+ u4ResidualResource -= u4Share; -+ ai4PerTcResourceDemand[i] -= u4Share; -+ } else { -+ /* enough */ -+ prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; -+ u4ResidualResource -= ai4PerTcResourceDemand[i]; -+ ai4PerTcResourceDemand[i] = 0; -+ } -+ } -+ } -+ -+ if (u4ResidualResource == 0) -+ break; -+ /* By priority, allocate the left resource that is not divisible by u4Share */ -+ -+ if (ai4PerTcResourceDemand[TC3_INDEX]) { /* VO */ -+ prQM->au4CurrentTcResource[TC3_INDEX]++; -+ if (--u4ResidualResource == 0) -+ break; -+ } -+ -+ if (ai4PerTcResourceDemand[TC2_INDEX]) { /* VI */ -+ prQM->au4CurrentTcResource[TC2_INDEX]++; -+ if (--u4ResidualResource == 0) -+ break; -+ } -+ -+ if (ai4PerTcResourceDemand[TC5_INDEX]) { /* BMCAST */ -+ prQM->au4CurrentTcResource[TC5_INDEX]++; -+ if (--u4ResidualResource == 0) -+ break; -+ } -+ -+ if (ai4PerTcResourceDemand[TC1_INDEX]) { /* BE */ -+ prQM->au4CurrentTcResource[TC1_INDEX]++; -+ if (--u4ResidualResource == 0) -+ break; -+ } -+ -+ if (ai4PerTcResourceDemand[TC0_INDEX]) { /* BK */ -+ prQM->au4CurrentTcResource[TC0_INDEX]++; -+ if (--u4ResidualResource == 0) -+ break; -+ } -+ -+ /* Allocate the left resource */ -+ prQM->au4CurrentTcResource[TC3_INDEX] += u4ResidualResource; -+ -+ } while (FALSE); -+ } -+ -+ /* mark the flag that we can start to do TC resource adjustment after TX done handle */ -+ prQM->fgTcResourcePostAnnealing = TRUE; -+ -+#if QM_PRINT_TC_RESOURCE_CTRL -+ /* Debug print */ -+ DBGLOG(QM, LOUD, "QM: TC Rsc %u %u %u %u %u %u\n", -+ prQM->au4CurrentTcResource[0], -+ prQM->au4CurrentTcResource[1], -+ prQM->au4CurrentTcResource[2], -+ prQM->au4CurrentTcResource[3], prQM->au4CurrentTcResource[4], prQM->au4CurrentTcResource[5] -+ )); -+#endif -+ -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/* RX-Related Queue Management */ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Init Queue Management for RX -+* -+* \param[in] (none) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmInitRxQueues(IN P_ADAPTER_T prAdapter) -+{ -+ /* DbgPrint("QM: Enter qmInitRxQueues()\n"); */ -+ /* TODO */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle RX packets (buffer reordering) -+* -+* \param[in] prSwRfbListHead The list of RX packets -+* -+* \return The list of packets which are not buffered for reordering -+*/ -+/*----------------------------------------------------------------------------*/ -+P_SW_RFB_T qmHandleRxPackets(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead) -+{ -+ -+#if CFG_RX_REORDERING_ENABLED -+ /* UINT_32 i; */ -+ P_SW_RFB_T prCurrSwRfb; -+ P_SW_RFB_T prNextSwRfb; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ QUE_T rReturnedQue; -+ PUINT_8 pucEthDestAddr; -+ BOOLEAN fgIsBMC; -+ -+ /* DbgPrint("QM: Enter qmHandleRxPackets()\n"); */ -+ -+ DEBUGFUNC("qmHandleRxPackets"); -+ -+ ASSERT(prSwRfbListHead); -+ -+ QUEUE_INITIALIZE(&rReturnedQue); -+ prNextSwRfb = prSwRfbListHead; -+ -+ do { -+ prCurrSwRfb = prNextSwRfb; -+ prNextSwRfb = QM_RX_GET_NEXT_SW_RFB(prCurrSwRfb); -+ -+ prHifRxHdr = prCurrSwRfb->prHifRxHdr; /* TODO: (Tehuang) Use macro to obtain the pointer */ -+ -+ /* TODO: (Tehuang) Check if relaying */ -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST; -+ -+ /* Decide the Destination */ -+#if CFG_RX_PKTS_DUMP -+ if (prAdapter->rRxCtrl.u4RxPktsDumpTypeMask & BIT(HIF_RX_PKT_TYPE_DATA)) { -+ DBGLOG(SW4, INFO, "QM RX DATA: net %u sta idx %u wlan idx %u ssn %u tid %u ptype %u 11 %u\n", -+ (UINT_32) HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr), -+ prHifRxHdr->ucStaRecIdx, prCurrSwRfb->ucWlanIdx, -+ (UINT_32) HIF_RX_HDR_GET_SN(prHifRxHdr), /* The new SN of the frame */ -+ (UINT_32) HIF_RX_HDR_GET_TID(prHifRxHdr), -+ prCurrSwRfb->ucPacketType, -+ (UINT_32) HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)); -+ -+ DBGLOG_MEM8(SW4, TRACE, (PUINT_8) prCurrSwRfb->pvHeader, prCurrSwRfb->u2PacketLen); -+ } -+#endif -+ -+ fgIsBMC = FALSE; -+ if (!HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)) { -+ -+ UINT_8 ucNetTypeIdx; -+ P_BSS_INFO_T prBssInfo; -+ -+ pucEthDestAddr = prCurrSwRfb->pvHeader; -+ ucNetTypeIdx = HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIdx]); -+ /* DBGLOG_MEM8(QM, TRACE,prCurrSwRfb->pvHeader, 16); */ -+ /* */ -+ -+ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr) && (OP_MODE_ACCESS_POINT != prBssInfo->eCurrentOPMode)) -+ fgIsBMC = TRUE; -+ -+ if (prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem > -+ (CFG_RX_MAX_PKT_NUM - CFG_NUM_OF_QM_RX_PKT_NUM)) { -+ -+ if (!IS_BSS_ACTIVE(prBssInfo)) { -+ DBGLOG(QM, WARN, "Mark NULL the Packet for inactive Bss %u\n", ucNetTypeIdx); -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); -+ continue; -+ } -+ -+ if (OP_MODE_ACCESS_POINT == prBssInfo->eCurrentOPMode) { -+ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr)) -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST_WITH_FORWARD; -+ else if (UNEQUAL_MAC_ADDR(prBssInfo->aucOwnMacAddr, pucEthDestAddr) && -+ bssGetClientByAddress(prBssInfo, pucEthDestAddr)) -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_FORWARD; -+ /* TODO : need to check the dst mac is valid */ -+ /* If src mac is invalid, the packet will be freed in fw */ -+ } /* OP_MODE_ACCESS_POINT */ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ else if (hs20IsFrameFilterEnabled(prAdapter, prBssInfo) && -+ hs20IsUnsecuredFrame(prAdapter, prBssInfo, prCurrSwRfb)) { -+ DBGLOG(QM, WARN, -+ "Mark NULL the Packet for Dropped Packet %u\n", ucNetTypeIdx); -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); -+ continue; -+ } -+#endif -+ } else { -+ /* Dont not occupy other SW RFB */ -+ DBGLOG(QM, WARN, "Mark NULL the Packet for less Free Sw Rfb\n"); -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); -+ continue; -+ } -+ -+ } -+#if CFG_SUPPORT_WAPI -+ if (prCurrSwRfb->u2PacketLen > ETHER_HEADER_LEN) { -+ PUINT_8 pc = (PUINT_8) prCurrSwRfb->pvHeader; -+ UINT_16 u2Etype = 0; -+ -+ u2Etype = (pc[ETH_TYPE_LEN_OFFSET] << 8) | (pc[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ /* for wapi integrity test. WPI_1x packet should be always in non-encrypted mode. -+ if we received any WPI(0x88b4) packet that is encrypted, drop here. */ -+ if (u2Etype == ETH_WPI_1X && HIF_RX_HDR_GET_SEC_MODE(prHifRxHdr) != 0) { -+ DBGLOG(QM, INFO, "drop wpi packet with sec mode\n"); -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); -+ continue; -+ } -+ } -+#endif -+ /* BAR frame */ -+ if (HIF_RX_HDR_GET_BAR_FLAG(prHifRxHdr)) { -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ qmProcessBarFrame(prAdapter, prCurrSwRfb, &rReturnedQue); -+ } -+ /* Reordering is not required for this packet, return it without buffering */ -+ else if (!HIF_RX_HDR_GET_REORDER_FLAG(prHifRxHdr) || fgIsBMC) { -+#if 0 -+ if (!HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)) { -+ UINT_8 ucNetTypeIdx; -+ P_BSS_INFO_T prBssInfo; -+ -+ pucEthDestAddr = prCurrSwRfb->pvHeader; -+ ucNetTypeIdx = HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIdx]); -+ -+ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr) -+ && (OP_MODE_ACCESS_POINT == prBssInfo->eCurrentOPMode)) { -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST_WITH_FORWARD; -+ } -+ } -+#endif -+ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); -+ } -+ /* Reordering is required for this packet */ -+ else { -+ /* If this packet should dropped or indicated to the host immediately, -+ * it should be enqueued into the rReturnedQue with specific flags. If -+ * this packet should be buffered for reordering, it should be enqueued -+ * into the reordering queue in the STA_REC rather than into the -+ * rReturnedQue. -+ */ -+ qmProcessPktWithReordering(prAdapter, prCurrSwRfb, &rReturnedQue); -+ -+ } -+ } while (prNextSwRfb); -+ -+ /* RX_PKT_DESTINATION_HOST_WITH_FORWARD or RX_PKT_DESTINATION_FORWARD */ -+ /* The returned list of SW_RFBs must end with a NULL pointer */ -+ if (QUEUE_IS_NOT_EMPTY(&rReturnedQue)) -+ QM_TX_SET_NEXT_MSDU_INFO((P_SW_RFB_T) QUEUE_GET_TAIL(&rReturnedQue), NULL); -+ -+ return (P_SW_RFB_T) QUEUE_GET_HEAD(&rReturnedQue); -+ -+#else -+ -+ /* DbgPrint("QM: Enter qmHandleRxPackets()\n"); */ -+ return prSwRfbListHead; -+ -+#endif -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Reorder the received packet -+* -+* \param[in] prSwRfb The RX packet to process -+* \param[out] prReturnedQue The queue for indicating packets -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmProcessPktWithReordering(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue) -+{ -+ -+ P_STA_RECORD_T prStaRec; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_RX_BA_ENTRY_T prReorderQueParm; -+ -+ UINT_32 u4SeqNo; -+ UINT_32 u4WinStart; -+ UINT_32 u4WinEnd; -+ P_QUE_T prReorderQue; -+ /* P_SW_RFB_T prReorderedSwRfb; */ -+ BOOLEAN fgIsBaTimeout; -+ -+ DEBUGFUNC("qmProcessPktWithReordering"); -+ -+ if ((prSwRfb == NULL) || (prReturnedQue == NULL) || (prSwRfb->prHifRxHdr == NULL)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ prSwRfb->ucStaRecIdx = prHifRxHdr->ucStaRecIdx; -+ prSwRfb->u2SSN = HIF_RX_HDR_GET_SN(prHifRxHdr); /* The new SN of the frame */ -+ prSwRfb->ucTid = (UINT_8) (HIF_RX_HDR_GET_TID(prHifRxHdr)); -+ /* prSwRfb->eDst = RX_PKT_DESTINATION_HOST; */ -+ -+ /* Incorrect STA_REC index */ -+ if (prSwRfb->ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) { -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ DBGLOG(QM, WARN, "Reordering for a NULL STA_REC, ucStaRecIdx = %d\n", prSwRfb->ucStaRecIdx); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ /* Check whether the STA_REC is activated */ -+ prStaRec = &(prAdapter->arStaRec[prSwRfb->ucStaRecIdx]); -+ ASSERT(prStaRec); -+ -+#if 0 -+ if (!(prStaRec->fgIsValid)) { -+ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ DBGLOG(QM, WARN, "Reordering for an invalid STA_REC\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+#endif -+ -+ /* Check whether the BA agreement exists */ -+ prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[prSwRfb->ucTid]); -+ if (!prReorderQueParm) { -+ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ DBGLOG(QM, WARN, "Reordering for a NULL ReorderQueParm\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ /* Start to reorder packets */ -+ u4SeqNo = (UINT_32) (prSwRfb->u2SSN); -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ u4WinStart = (UINT_32) (prReorderQueParm->u2WinStart); -+ u4WinEnd = (UINT_32) (prReorderQueParm->u2WinEnd); -+ -+ /* Debug */ -+ /* DbgPrint("QM:(R)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */ -+ -+ /* Case 1: Fall within */ -+ if /* 0 - start - sn - end - 4095 */ -+ (((u4WinStart <= u4SeqNo) && (u4SeqNo <= u4WinEnd)) -+ /* 0 - end - start - sn - 4095 */ -+ || ((u4WinEnd < u4WinStart) && (u4WinStart <= u4SeqNo)) -+ /* 0 - sn - end - start - 4095 */ -+ || ((u4SeqNo <= u4WinEnd) && (u4WinEnd < u4WinStart))) { -+ -+ qmInsertFallWithinReorderPkt(prSwRfb, prReorderQueParm, prReturnedQue); -+ -+#if QM_RX_WIN_SSN_AUTO_ADVANCING -+ if (prReorderQueParm->fgIsWaitingForPktWithSsn) { -+ /* Let the first received packet pass the reorder check */ -+ DBGLOG(QM, LOUD, "QM:(A)[%d](%u){%u,%u}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); -+ -+ prReorderQueParm->u2WinStart = (UINT_16) u4SeqNo; -+ prReorderQueParm->u2WinEnd = -+ ((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT; -+ prReorderQueParm->fgIsWaitingForPktWithSsn = FALSE; -+ } -+#endif -+ -+ if (qmPopOutDueToFallWithin(prReorderQueParm, prReturnedQue, &fgIsBaTimeout) == FALSE) -+ STATS_RX_REORDER_HOLE_INC(prStaRec); /* record hole count */ -+ STATS_RX_REORDER_HOLE_TIMEOUT_INC(prStaRec, fgIsBaTimeout); -+ } -+ /* Case 2: Fall ahead */ -+ else if -+ /* 0 - start - end - sn - (start+2048) - 4095 */ -+ (((u4WinStart < u4WinEnd) -+ && (u4WinEnd < u4SeqNo) -+ && (u4SeqNo < (u4WinStart + HALF_SEQ_NO_COUNT))) -+ /* 0 - sn - (start+2048) - start - end - 4095 */ -+ || ((u4SeqNo < u4WinStart) -+ && (u4WinStart < u4WinEnd) -+ && ((u4SeqNo + MAX_SEQ_NO_COUNT) < (u4WinStart + HALF_SEQ_NO_COUNT))) -+ /* 0 - end - sn - (start+2048) - start - 4095 */ -+ || ((u4WinEnd < u4SeqNo) -+ && (u4SeqNo < u4WinStart) -+ && ((u4SeqNo + MAX_SEQ_NO_COUNT) < (u4WinStart + HALF_SEQ_NO_COUNT)))) { -+ -+#if QM_RX_WIN_SSN_AUTO_ADVANCING -+ if (prReorderQueParm->fgIsWaitingForPktWithSsn) -+ prReorderQueParm->fgIsWaitingForPktWithSsn = FALSE; -+#endif -+ -+ qmInsertFallAheadReorderPkt(prSwRfb, prReorderQueParm, prReturnedQue); -+ -+ /* Advance the window after inserting a new tail */ -+ prReorderQueParm->u2WinEnd = (UINT_16) u4SeqNo; -+ prReorderQueParm->u2WinStart = -+ (((prReorderQueParm->u2WinEnd) - (prReorderQueParm->u2WinSize) + MAX_SEQ_NO_COUNT + 1) -+ % MAX_SEQ_NO_COUNT); -+ -+ qmPopOutDueToFallAhead(prReorderQueParm, prReturnedQue); -+ -+ STATS_RX_REORDER_FALL_AHEAD_INC(prStaRec); -+ -+ } -+ /* Case 3: Fall behind */ -+ else { -+ -+#if QM_RX_WIN_SSN_AUTO_ADVANCING -+#if QM_RX_INIT_FALL_BEHIND_PASS -+ if (prReorderQueParm->fgIsWaitingForPktWithSsn) { -+ /* ?? prSwRfb->eDst = RX_PKT_DESTINATION_HOST; */ -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ /* DbgPrint("QM:(P)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */ -+ return; -+ } -+#endif -+#endif -+ -+ STATS_RX_REORDER_FALL_BEHIND_INC(prStaRec); -+ /* An erroneous packet */ -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ /* DbgPrint("QM:(D)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */ -+ return; -+ } -+ -+ return; -+ -+} -+ -+VOID qmProcessBarFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue) -+{ -+ -+ P_STA_RECORD_T prStaRec; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_RX_BA_ENTRY_T prReorderQueParm; -+ -+ UINT_32 u4SSN; -+ UINT_32 u4WinStart; -+ UINT_32 u4WinEnd; -+ P_QUE_T prReorderQue; -+ /* P_SW_RFB_T prReorderedSwRfb; */ -+ -+ if ((prSwRfb == NULL) || (prReturnedQue == NULL) || (prSwRfb->prHifRxHdr == NULL)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ prSwRfb->ucStaRecIdx = prHifRxHdr->ucStaRecIdx; -+ prSwRfb->u2SSN = HIF_RX_HDR_GET_SN(prHifRxHdr); /* The new SSN */ -+ prSwRfb->ucTid = (UINT_8) (HIF_RX_HDR_GET_TID(prHifRxHdr)); -+ -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ -+ /* Incorrect STA_REC index */ -+ if (prSwRfb->ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) { -+ DBGLOG(QM, WARN, "QM: (Warning) BAR for a NULL STA_REC, ucStaRecIdx = %d\n", prSwRfb->ucStaRecIdx); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ /* Check whether the STA_REC is activated */ -+ prStaRec = &(prAdapter->arStaRec[prSwRfb->ucStaRecIdx]); -+ ASSERT(prStaRec); -+ -+#if 0 -+ if (!(prStaRec->fgIsValid)) { -+ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ -+ DbgPrint("QM: (Warning) BAR for an invalid STA_REC\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+#endif -+ -+ /* Check whether the BA agreement exists */ -+ prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[prSwRfb->ucTid]); -+ if (!prReorderQueParm) { -+ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ -+ DBGLOG(QM, WARN, "QM: (Warning) BAR for a NULL ReorderQueParm\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ u4SSN = (UINT_32) (prSwRfb->u2SSN); -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ u4WinStart = (UINT_32) (prReorderQueParm->u2WinStart); -+ u4WinEnd = (UINT_32) (prReorderQueParm->u2WinEnd); -+ -+ if (qmCompareSnIsLessThan(u4WinStart, u4SSN)) { -+ prReorderQueParm->u2WinStart = (UINT_16) u4SSN; -+ prReorderQueParm->u2WinEnd = -+ ((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT; -+ DBGLOG(QM, TRACE, -+ "QM:(BAR)[%d](%u){%d,%d}\n", prSwRfb->ucTid, u4SSN, prReorderQueParm->u2WinStart, -+ prReorderQueParm->u2WinEnd); -+ qmPopOutDueToFallAhead(prReorderQueParm, prReturnedQue); -+ } else { -+ DBGLOG(QM, TRACE, "QM:(BAR)(%d)(%u){%u,%u}\n", prSwRfb->ucTid, u4SSN, u4WinStart, u4WinEnd); -+ } -+} -+ -+VOID qmInsertFallWithinReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue) -+{ -+ P_SW_RFB_T prExaminedQueuedSwRfb; -+ P_QUE_T prReorderQue; -+ -+ ASSERT(prSwRfb); -+ ASSERT(prReorderQueParm); -+ ASSERT(prReturnedQue); -+ -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ prExaminedQueuedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue); -+ -+ /* There are no packets queued in the Reorder Queue */ -+ if (prExaminedQueuedSwRfb == NULL) { -+ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = NULL; -+ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; -+ prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb; -+ prReorderQue->prTail = (P_QUE_ENTRY_T) prSwRfb; -+ prReorderQue->u4NumElem++; -+ } -+ -+ /* Determine the insert position */ -+ else { -+ do { -+ /* Case 1: Terminate. A duplicate packet */ -+ if (((prExaminedQueuedSwRfb->u2SSN) == (prSwRfb->u2SSN))) { -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ return; -+ } -+ -+ /* Case 2: Terminate. The insert point is found */ -+ else if (qmCompareSnIsLessThan((prSwRfb->u2SSN), (prExaminedQueuedSwRfb->u2SSN))) -+ break; -+ -+ /* Case 3: Insert point not found. Check the next SW_RFB in the Reorder Queue */ -+ else -+ prExaminedQueuedSwRfb = (P_SW_RFB_T) (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prNext); -+ } while (prExaminedQueuedSwRfb); -+ -+ /* Update the Reorder Queue Parameters according to the found insert position */ -+ if (prExaminedQueuedSwRfb == NULL) { -+ /* The received packet shall be placed at the tail */ -+ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = prReorderQue->prTail; -+ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; -+ (prReorderQue->prTail)->prNext = (P_QUE_ENTRY_T) (prSwRfb); -+ prReorderQue->prTail = (P_QUE_ENTRY_T) (prSwRfb); -+ } else { -+ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = ((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev; -+ ((P_QUE_ENTRY_T) prSwRfb)->prNext = (P_QUE_ENTRY_T) prExaminedQueuedSwRfb; -+ if (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb) == (prReorderQue->prHead)) { -+ /* The received packet will become the head */ -+ prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb; -+ } else { -+ (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev)->prNext = (P_QUE_ENTRY_T) prSwRfb; -+ } -+ ((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev = (P_QUE_ENTRY_T) prSwRfb; -+ } -+ -+ prReorderQue->u4NumElem++; -+ -+ } -+ -+} -+ -+VOID qmInsertFallAheadReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue) -+{ -+ P_QUE_T prReorderQue; -+ -+ ASSERT(prSwRfb); -+ ASSERT(prReorderQueParm); -+ ASSERT(prReturnedQue); -+ -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ -+ /* There are no packets queued in the Reorder Queue */ -+ if (QUEUE_IS_EMPTY(prReorderQue)) { -+ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = NULL; -+ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; -+ prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb; -+ } else { -+ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = prReorderQue->prTail; -+ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; -+ (prReorderQue->prTail)->prNext = (P_QUE_ENTRY_T) (prSwRfb); -+ } -+ prReorderQue->prTail = (P_QUE_ENTRY_T) prSwRfb; -+ prReorderQue->u4NumElem++; -+ -+} -+ -+BOOLEAN -+qmPopOutDueToFallWithin(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue, OUT BOOLEAN *fgIsTimeout) -+{ -+ P_SW_RFB_T prReorderedSwRfb; -+ P_QUE_T prReorderQue; -+ BOOLEAN fgDequeuHead, fgMissing; -+ OS_SYSTIME rCurrentTime, *prMissTimeout; -+ -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ -+ *fgIsTimeout = FALSE; -+ fgMissing = FALSE; -+ rCurrentTime = 0; -+ prMissTimeout = &(g_arMissTimeout[prReorderQueParm->ucStaRecIdx][prReorderQueParm->ucTid]); -+ if ((*prMissTimeout)) { -+ fgMissing = TRUE; -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ } -+ -+ /* Check whether any packet can be indicated to the higher layer */ -+ while (TRUE) { -+ if (QUEUE_IS_EMPTY(prReorderQue)) -+ break; -+ -+ /* Always examine the head packet */ -+ prReorderedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue); -+ fgDequeuHead = FALSE; -+ -+ /* SN == WinStart, so the head packet shall be indicated (advance the window) */ -+ if ((prReorderedSwRfb->u2SSN) == (prReorderQueParm->u2WinStart)) { -+ -+ fgDequeuHead = TRUE; -+ prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT); -+ } -+ /* SN > WinStart, break to update WinEnd */ -+ else { -+ if ((fgMissing == TRUE) && -+ CHECK_FOR_TIMEOUT(rCurrentTime, (*prMissTimeout), -+ MSEC_TO_SYSTIME(QM_RX_BA_ENTRY_MISS_TIMEOUT_MS))) { -+ DBGLOG(QM, TRACE, -+ "QM:RX BA Timout Next Tid %d SSN %d\n", prReorderQueParm->ucTid, -+ prReorderedSwRfb->u2SSN); -+ fgDequeuHead = TRUE; -+ prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT); -+ -+ fgMissing = FALSE; -+ *fgIsTimeout = TRUE; -+ } else -+ break; -+ } -+ -+ /* Dequeue the head packet */ -+ if (fgDequeuHead) { -+ -+ if (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext == NULL) { -+ prReorderQue->prHead = NULL; -+ prReorderQue->prTail = NULL; -+ } else { -+ prReorderQue->prHead = ((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext; -+ (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext)->prPrev = NULL; -+ } -+ prReorderQue->u4NumElem--; -+ /* DbgPrint("QM: [%d] %d (%d)\n", -+ prReorderQueParm->ucTid, -+ prReorderedSwRfb->u2PacketLen, -+ prReorderedSwRfb->u2SSN); */ -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prReorderedSwRfb); -+ } -+ } -+ -+ if (QUEUE_IS_EMPTY(prReorderQue)) -+ *prMissTimeout = 0; -+ else { -+ if (fgMissing == FALSE) -+ GET_CURRENT_SYSTIME(prMissTimeout); -+ } -+ -+ /* After WinStart has been determined, update the WinEnd */ -+ prReorderQueParm->u2WinEnd = -+ (((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT); -+ return QUEUE_IS_EMPTY(prReorderQue); -+} -+ -+VOID qmPopOutDueToFallAhead(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue) -+{ -+ P_SW_RFB_T prReorderedSwRfb; -+ P_QUE_T prReorderQue; -+ BOOLEAN fgDequeuHead; -+ -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ -+ /* Check whether any packet can be indicated to the higher layer */ -+ while (TRUE) { -+ if (QUEUE_IS_EMPTY(prReorderQue)) -+ break; -+ -+ /* Always examine the head packet */ -+ prReorderedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue); -+ fgDequeuHead = FALSE; -+ -+ /* SN == WinStart, so the head packet shall be indicated (advance the window) */ -+ if ((prReorderedSwRfb->u2SSN) == (prReorderQueParm->u2WinStart)) { -+ -+ fgDequeuHead = TRUE; -+ prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT); -+ } -+ -+ /* SN < WinStart, so the head packet shall be indicated (do not advance the window) */ -+ else if (qmCompareSnIsLessThan((UINT_32) (prReorderedSwRfb->u2SSN), -+ (UINT_32) (prReorderQueParm->u2WinStart))) -+ fgDequeuHead = TRUE; -+ -+ /* SN > WinStart, break to update WinEnd */ -+ else -+ break; -+ -+ /* Dequeue the head packet */ -+ if (fgDequeuHead) { -+ -+ if (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext == NULL) { -+ prReorderQue->prHead = NULL; -+ prReorderQue->prTail = NULL; -+ } else { -+ prReorderQue->prHead = ((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext; -+ (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext)->prPrev = NULL; -+ } -+ prReorderQue->u4NumElem--; -+ /* DbgPrint("QM: [%d] %d (%d)\n", */ -+ /* prReorderQueParm->ucTid, prReorderedSwRfb->u2PacketLen, prReorderedSwRfb->u2SSN); */ -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prReorderedSwRfb); -+ } -+ } -+ -+ /* After WinStart has been determined, update the WinEnd */ -+ prReorderQueParm->u2WinEnd = -+ (((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT); -+ -+} -+ -+BOOLEAN qmCompareSnIsLessThan(IN UINT_32 u4SnLess, IN UINT_32 u4SnGreater) -+{ -+ /* 0 <---> SnLess <--(gap>2048)--> SnGreater : SnLess > SnGreater */ -+ if ((u4SnLess + HALF_SEQ_NO_COUNT) <= u4SnGreater) /* Shall be <= */ -+ return FALSE; -+ -+ /* 0 <---> SnGreater <--(gap>2048)--> SnLess : SnLess < SnGreater */ -+ else if ((u4SnGreater + HALF_SEQ_NO_COUNT) < u4SnLess) -+ return TRUE; -+ -+ /* 0 <---> SnGreater <--(gap<2048)--> SnLess : SnLess > SnGreater */ -+ /* 0 <---> SnLess <--(gap<2048)--> SnGreater : SnLess < SnGreater */ -+ else if (u4SnLess < u4SnGreater) -+ return TRUE; -+ else -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle Mailbox RX messages -+* -+* \param[in] prMailboxRxMsg The received Mailbox message from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleMailboxRxMessage(IN MAILBOX_MSG_T prMailboxRxMsg) -+{ -+ /* DbgPrint("QM: Enter qmHandleMailboxRxMessage()\n"); */ -+ /* TODO */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle ADD RX BA Event from the FW -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prEvent The event packet from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleEventRxAddBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_RX_ADDBA_T prEventRxAddBa; -+ P_STA_RECORD_T prStaRec; -+ UINT_32 u4Tid; -+ UINT_32 u4WinSize; -+ -+ DBGLOG(QM, INFO, "QM:Event +RxBa\n"); -+ -+ prEventRxAddBa = (P_EVENT_RX_ADDBA_T) prEvent; -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventRxAddBa->ucStaRecIdx); -+ -+ if (!prStaRec) { -+ /* Invalid STA_REC index, discard the event packet */ -+ /* ASSERT(0); */ -+ DBGLOG(QM, WARN, "QM: (Warning) RX ADDBA Event for a NULL STA_REC\n"); -+ return; -+ } -+#if 0 -+ if (!(prStaRec->fgIsValid)) { -+ /* TODO: (Tehuang) Handle the Host-FW synchronization issue */ -+ DBGLOG(QM, WARN, "QM: (Warning) RX ADDBA Event for an invalid STA_REC\n"); -+ /* ASSERT(0); */ -+ /* return; */ -+ } -+#endif -+ -+ u4Tid = (((prEventRxAddBa->u2BAParameterSet) & BA_PARAM_SET_TID_MASK) -+ >> BA_PARAM_SET_TID_MASK_OFFSET); -+ -+ u4WinSize = (((prEventRxAddBa->u2BAParameterSet) & BA_PARAM_SET_BUFFER_SIZE_MASK) -+ >> BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET); -+ -+ if (!qmAddRxBaEntry(prAdapter, -+ prStaRec->ucIndex, -+ (UINT_8) u4Tid, -+ (prEventRxAddBa->u2BAStartSeqCtrl >> OFFSET_BAR_SSC_SN), (UINT_16) u4WinSize)) { -+ -+ /* FW shall ensure the availabiilty of the free-to-use BA entry */ -+ DBGLOG(QM, ERROR, "QM: (Error) qmAddRxBaEntry() failure\n"); -+ ASSERT(0); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle DEL RX BA Event from the FW -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prEvent The event packet from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleEventRxDelBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_RX_DELBA_T prEventRxDelBa; -+ P_STA_RECORD_T prStaRec; -+ -+ /* DbgPrint("QM:Event -RxBa\n"); */ -+ -+ prEventRxDelBa = (P_EVENT_RX_DELBA_T) prEvent; -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventRxDelBa->ucStaRecIdx); -+ -+ if (!prStaRec) -+ /* Invalid STA_REC index, discard the event packet */ -+ /* ASSERT(0); */ -+ return; -+#if 0 -+ if (!(prStaRec->fgIsValid)) -+ /* TODO: (Tehuang) Handle the Host-FW synchronization issue */ -+ /* ASSERT(0); */ -+ return; -+#endif -+ -+ qmDelRxBaEntry(prAdapter, prStaRec->ucIndex, prEventRxDelBa->ucTid, TRUE); -+ -+} -+ -+P_RX_BA_ENTRY_T qmLookupRxBaEntry(IN P_ADAPTER_T prAdapter, UINT_8 ucStaRecIdx, UINT_8 ucTid) -+{ -+ int i; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ /* DbgPrint("QM: Enter qmLookupRxBaEntry()\n"); */ -+ -+ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { -+ if (prQM->arRxBaTable[i].fgIsValid) { -+ if ((prQM->arRxBaTable[i].ucStaRecIdx == ucStaRecIdx) && (prQM->arRxBaTable[i].ucTid == ucTid)) -+ return &prQM->arRxBaTable[i]; -+ } -+ } -+ return NULL; -+} -+ -+BOOLEAN -+qmAddRxBaEntry(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN UINT_16 u2WinStart, IN UINT_16 u2WinSize) -+{ -+ int i; -+ P_RX_BA_ENTRY_T prRxBaEntry = NULL; -+ P_STA_RECORD_T prStaRec; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ ASSERT(ucStaRecIdx < CFG_NUM_OF_STA_RECORD); -+ -+ if (ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) { -+ /* Invalid STA_REC index, discard the event packet */ -+ DBGLOG(QM, WARN, "QM: (WARNING) RX ADDBA Event for a invalid ucStaRecIdx = %d\n", ucStaRecIdx); -+ return FALSE; -+ } -+ -+ prStaRec = &prAdapter->arStaRec[ucStaRecIdx]; -+ ASSERT(prStaRec); -+ -+ /* if(!(prStaRec->fgIsValid)){ */ -+ /* DbgPrint("QM: (WARNING) Invalid STA when adding an RX BA\n"); */ -+ /* return FALSE; */ -+ /* } */ -+ -+ /* 4 <1> Delete before adding */ -+ /* Remove the BA entry for the same (STA, TID) tuple if it exists */ -+ if (qmLookupRxBaEntry(prAdapter, ucStaRecIdx, ucTid)) -+ qmDelRxBaEntry(prAdapter, ucStaRecIdx, ucTid, TRUE); /* prQM->ucRxBaCount-- */ -+ /* 4 <2> Add a new BA entry */ -+ /* No available entry to store the BA agreement info. Retrun FALSE. */ -+ if (prQM->ucRxBaCount >= CFG_NUM_OF_RX_BA_AGREEMENTS) { -+ DBGLOG(QM, ERROR, "QM: **failure** (limited resource, ucRxBaCount=%d)\n", prQM->ucRxBaCount); -+ return FALSE; -+ } -+ /* Find the free-to-use BA entry */ -+ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { -+ if (!prQM->arRxBaTable[i].fgIsValid) { -+ prRxBaEntry = &(prQM->arRxBaTable[i]); -+ prQM->ucRxBaCount++; -+ DBGLOG(QM, LOUD, "QM: ucRxBaCount=%d\n", prQM->ucRxBaCount); -+ break; -+ } -+ } -+ /* If a free-to-use entry is found, configure it and associate it with the STA_REC */ -+ u2WinSize += CFG_RX_BA_INC_SIZE; -+ if (prRxBaEntry) { -+ prRxBaEntry->ucStaRecIdx = ucStaRecIdx; -+ prRxBaEntry->ucTid = ucTid; -+ prRxBaEntry->u2WinStart = u2WinStart; -+ prRxBaEntry->u2WinSize = u2WinSize; -+ prRxBaEntry->u2WinEnd = ((u2WinStart + u2WinSize - 1) % MAX_SEQ_NO_COUNT); -+ prRxBaEntry->fgIsValid = TRUE; -+ prRxBaEntry->fgIsWaitingForPktWithSsn = TRUE; -+ -+ g_arMissTimeout[ucStaRecIdx][ucTid] = 0; -+ -+ DBGLOG(QM, INFO, "QM: +RxBA(STA=%d TID=%d WinStart=%d WinEnd=%d WinSize=%d)\n", -+ ucStaRecIdx, ucTid, -+ prRxBaEntry->u2WinStart, prRxBaEntry->u2WinEnd, prRxBaEntry->u2WinSize); -+ -+ /* Update the BA entry reference table for per-packet lookup */ -+ prStaRec->aprRxReorderParamRefTbl[ucTid] = prRxBaEntry; -+ } else { -+ /* This shall not happen because FW should keep track of the usage of RX BA entries */ -+ DBGLOG(QM, ERROR, "QM: **AddBA Error** (ucRxBaCount=%d)\n", prQM->ucRxBaCount); -+ return FALSE; -+ } -+ return TRUE; -+} -+ -+VOID qmDelRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN BOOLEAN fgFlushToHost) -+{ -+ P_RX_BA_ENTRY_T prRxBaEntry; -+ P_STA_RECORD_T prStaRec; -+ P_SW_RFB_T prFlushedPacketList = NULL; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ ASSERT(ucStaRecIdx < CFG_NUM_OF_STA_RECORD); -+ -+ prStaRec = &prAdapter->arStaRec[ucStaRecIdx]; -+ ASSERT(prStaRec); -+ -+#if 0 -+ if (!(prStaRec->fgIsValid)) { -+ DbgPrint("QM: (WARNING) Invalid STA when deleting an RX BA\n"); -+ return; -+ } -+#endif -+ -+ /* Remove the BA entry for the same (STA, TID) tuple if it exists */ -+ prRxBaEntry = prStaRec->aprRxReorderParamRefTbl[ucTid]; -+ -+ if (prRxBaEntry) { -+ -+ prFlushedPacketList = qmFlushStaRxQueue(prAdapter, ucStaRecIdx, ucTid); -+ -+ if (prFlushedPacketList) { -+ -+ if (fgFlushToHost) { -+ wlanProcessQueuedSwRfb(prAdapter, prFlushedPacketList); -+ } else { -+ -+ P_SW_RFB_T prSwRfb; -+ P_SW_RFB_T prNextSwRfb; -+ -+ prSwRfb = prFlushedPacketList; -+ -+ do { -+ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ prSwRfb = prNextSwRfb; -+ } while (prSwRfb); -+ -+ } -+ -+ } -+#if ((QM_TEST_MODE == 0) && (QM_TEST_STA_REC_DEACTIVATION == 0)) -+ /* Update RX BA entry state. Note that RX queue flush is not done here */ -+ prRxBaEntry->fgIsValid = FALSE; -+ prQM->ucRxBaCount--; -+ -+ /* Debug */ -+#if 0 -+ DbgPrint("QM: ucRxBaCount=%d\n", prQM->ucRxBaCount); -+#endif -+ -+ /* Update STA RX BA table */ -+ prStaRec->aprRxReorderParamRefTbl[ucTid] = NULL; -+#endif -+ -+ DBGLOG(QM, INFO, "QM: -RxBA(STA=%d,TID=%d)\n", ucStaRecIdx, ucTid); -+ -+ } -+ -+ /* Debug */ -+#if CFG_HIF_RX_STARVATION_WARNING -+ { -+ P_RX_CTRL_T prRxCtrl; -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ DBGLOG(QM, TRACE, -+ "QM: (RX DEBUG) Enqueued: %d / Dequeued: %d\n", prRxCtrl->u4QueuedCnt, -+ prRxCtrl->u4DequeuedCnt); -+ } -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To process WMM related IEs in ASSOC_RSP -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prSwRfb The received frame -+* \param[in] pucIE The pointer to the first IE in the frame -+* \param[in] u2IELength The total length of IEs in the frame -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mqmProcessAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2Offset; -+ PUINT_8 pucIEStart; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ P_IE_WMM_INFO_T prIeWmmInfo; -+ UINT_8 ucQosInfo; -+ UINT_8 ucQosInfoAC; -+ UINT_8 ucBmpAC; -+ -+ DEBUGFUNC("mqmProcessAssocReq"); -+ -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (prStaRec == NULL) -+ return; -+ -+ prStaRec->fgIsQoS = FALSE; -+ prStaRec->fgIsWmmSupported = prStaRec->fgIsUapsdSupported = FALSE; -+ -+ pucIEStart = pucIE; -+ -+ /* If the device does not support QoS or if WMM is not supported by the peer, exit. */ -+ if (!prAdapter->rWifiVar.fgSupportQoS) -+ return; -+ -+ /* Determine whether QoS is enabled with the association */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_WMM: -+ -+ if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && -+ (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { -+ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { -+ case VENDOR_OUI_SUBTYPE_WMM_INFO: -+ if (IE_LEN(pucIE) != 7) -+ break; /* WMM Info IE with a wrong length */ -+ prStaRec->fgIsQoS = TRUE; -+ prStaRec->fgIsWmmSupported = TRUE; -+ -+ prIeWmmInfo = (P_IE_WMM_INFO_T) pucIE; -+ ucQosInfo = prIeWmmInfo->ucQosInfo; -+ ucQosInfoAC = ucQosInfo & BITS(0, 3); -+ -+ prStaRec->fgIsUapsdSupported = ((ucQosInfoAC) ? TRUE : FALSE) & -+ prAdapter->rWifiVar.fgSupportUAPSD; -+ -+ ucBmpAC = 0; -+ -+ if (ucQosInfoAC & WMM_QOS_INFO_VO_UAPSD) -+ ucBmpAC |= BIT(ACI_VO); -+ if (ucQosInfoAC & WMM_QOS_INFO_VI_UAPSD) -+ ucBmpAC |= BIT(ACI_VI); -+ if (ucQosInfoAC & WMM_QOS_INFO_BE_UAPSD) -+ ucBmpAC |= BIT(ACI_BE); -+ if (ucQosInfoAC & WMM_QOS_INFO_BK_UAPSD) -+ ucBmpAC |= BIT(ACI_BK); -+ -+ prStaRec->ucBmpTriggerAC = prStaRec->ucBmpDeliveryAC = ucBmpAC; -+ -+ prStaRec->ucUapsdSp = -+ (ucQosInfo & WMM_QOS_INFO_MAX_SP_LEN_MASK) >> 5; -+ break; -+ default: -+ /* Other WMM QoS IEs. Ignore any */ -+ break; -+ } -+ } -+ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS */ -+ -+ break; -+ -+ case ELEM_ID_HT_CAP: -+ /* Some client won't put the WMM IE if client is 802.11n */ -+ if (IE_LEN(pucIE) == (sizeof(IE_HT_CAP_T) - 2)) -+ prStaRec->fgIsQoS = TRUE; -+ break; -+ default: -+ break; -+ } -+ } -+ -+ DBGLOG(QM, TRACE, "MQM: Assoc_Req Parsing (QoS Enabled=%d)\n", prStaRec->fgIsQoS); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To process WMM related IEs in ASSOC_RSP -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prSwRfb The received frame -+* \param[in] pucIE The pointer to the first IE in the frame -+* \param[in] u2IELength The total length of IEs in the frame -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mqmProcessAssocRsp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2Offset; -+ PUINT_8 pucIEStart; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ -+ DEBUGFUNC("mqmProcessAssocRsp"); -+ -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (prStaRec == NULL) -+ return; -+ -+ prStaRec->fgIsQoS = FALSE; -+ -+ pucIEStart = pucIE; -+ -+ DBGLOG(QM, TRACE, "QM: (fgIsWmmSupported=%d, fgSupportQoS=%d)\n", -+ prStaRec->fgIsWmmSupported, prAdapter->rWifiVar.fgSupportQoS); -+ -+ /* If the device does not support QoS or if WMM is not supported by the peer, exit. */ -+ /* if((!prAdapter->rWifiVar.fgSupportQoS) || (!prStaRec->fgIsWmmSupported)) */ -+ if ((!prAdapter->rWifiVar.fgSupportQoS)) -+ return; -+ -+ /* Determine whether QoS is enabled with the association */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_WMM: -+ if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && -+ (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { -+ -+ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { -+ case VENDOR_OUI_SUBTYPE_WMM_PARAM: -+ if (IE_LEN(pucIE) != 24) -+ break; /* WMM Info IE with a wrong length */ -+ prStaRec->fgIsQoS = TRUE; -+ break; -+ -+ case VENDOR_OUI_SUBTYPE_WMM_INFO: -+ if (IE_LEN(pucIE) != 7) -+ break; /* WMM Info IE with a wrong length */ -+ prStaRec->fgIsQoS = TRUE; -+ break; -+ -+ default: -+ /* Other WMM QoS IEs. Ignore any */ -+ break; -+ } -+ } -+ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS */ -+ break; -+ -+ case ELEM_ID_HT_CAP: -+ /* Some AP won't put the WMM IE if client is 802.11n */ -+ if (IE_LEN(pucIE) == (sizeof(IE_HT_CAP_T) - 2)) -+ prStaRec->fgIsQoS = TRUE; -+ break; -+ default: -+ break; -+ } -+ } -+ -+ /* Parse AC parameters and write to HW CRs */ -+ if ((prStaRec->fgIsQoS) && (prStaRec->eStaType == STA_TYPE_LEGACY_AP)) { -+ mqmParseEdcaParameters(prAdapter, prSwRfb, pucIEStart, u2IELength, TRUE); -+#if ARP_MONITER_ENABLE -+ qmResetArpDetect(); -+#endif -+ } -+ -+ DBGLOG(QM, TRACE, "MQM: Assoc_Rsp Parsing (QoS Enabled=%d)\n", prStaRec->fgIsQoS); -+ if (prStaRec->fgIsWmmSupported) -+ nicQmUpdateWmmParms(prAdapter, prStaRec->ucNetTypeIndex); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To parse WMM Parameter IE (in BCN or Assoc_Rsp) -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prSwRfb The received frame -+* \param[in] pucIE The pointer to the first IE in the frame -+* \param[in] u2IELength The total length of IEs in the frame -+* \param[in] fgForceOverride TRUE: If EDCA parameters are found, always set to HW CRs. -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+mqmParseEdcaParameters(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength, IN BOOLEAN fgForceOverride) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2Offset; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ P_BSS_INFO_T prBssInfo; -+ P_AC_QUE_PARMS_T prAcQueParams; -+ P_IE_WMM_PARAM_T prIeWmmParam; -+ ENUM_WMM_ACI_T eAci; -+ PUINT_8 pucWmmParamSetCount; -+ -+ DEBUGFUNC("mqmParseEdcaParameters"); -+ -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ if (prStaRec == NULL) -+ return; -+ -+ DBGLOG(QM, TRACE, "QM: (fgIsWmmSupported=%d, fgIsQoS=%d)\n", prStaRec->fgIsWmmSupported, prStaRec->fgIsQoS); -+ -+ if ((!prAdapter->rWifiVar.fgSupportQoS) || (!prStaRec->fgIsWmmSupported) || (!prStaRec->fgIsQoS)) -+ return; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ /* Goal: Obtain the EDCA parameters */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_WMM: -+ if ((WMM_IE_OUI_TYPE(pucIE) != VENDOR_OUI_TYPE_WMM) || -+ (kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) -+ break; -+ -+ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { -+ case VENDOR_OUI_SUBTYPE_WMM_PARAM: -+ if (IE_LEN(pucIE) != 24) -+ break; /* WMM Param IE with a wrong length */ -+ -+ pucWmmParamSetCount = &(prBssInfo->ucWmmParamSetCount); -+ prIeWmmParam = (P_IE_WMM_PARAM_T) pucIE; -+ -+ /* Check the Parameter Set Count to determine whether EDCA parameters */ -+ /* have been changed */ -+ if (!fgForceOverride && (*pucWmmParamSetCount -+ == (prIeWmmParam->ucQosInfo & WMM_QOS_INFO_PARAM_SET_CNT))) -+ break; /* Ignore the IE without updating HW CRs */ -+ -+ /* Update Parameter Set Count */ -+ *pucWmmParamSetCount = -+ (prIeWmmParam->ucQosInfo & WMM_QOS_INFO_PARAM_SET_CNT); -+ -+ /* Update EDCA parameters */ -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ prAcQueParams = &prBssInfo->arACQueParms[eAci]; -+ mqmFillAcQueParam(prIeWmmParam, eAci, prAcQueParams); -+ -+ prAcQueParams->fgIsACMSet = -+ (prAcQueParams->u2Aifsn & WMM_ACIAIFSN_ACM) ? TRUE : FALSE; -+ prAcQueParams->u2Aifsn &= WMM_ACIAIFSN_AIFSN; -+ -+ DBGLOG(QM, LOUD, -+ "eAci:%d, ACM:%d, Aifsn:%d, CWmin:%d, CWmax:%d, TxopLmt:%d\n", -+ eAci, prAcQueParams->fgIsACMSet, prAcQueParams->u2Aifsn, -+ prAcQueParams->u2CWmin, prAcQueParams->u2CWmax, -+ prAcQueParams->u2TxopLimit); -+ } -+ break; -+ default: -+ /* Other WMM QoS IEs. Ignore */ -+ break; -+ } -+ -+ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS, ... (not cared) */ -+ break; -+ default: -+ break; -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used for parsing EDCA parameters specified in the WMM Parameter IE -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prIeWmmParam The pointer to the WMM Parameter IE -+* \param[in] u4AcOffset The offset specifying the AC queue for parsing -+* \param[in] prHwAcParams The parameter structure used to configure the HW CRs -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mqmFillAcQueParam(IN P_IE_WMM_PARAM_T prIeWmmParam, IN UINT_32 u4AcOffset, OUT P_AC_QUE_PARMS_T prAcQueParams) -+{ -+ prAcQueParams->u2Aifsn = *((PUINT_8) (&(prIeWmmParam->ucAciAifsn_BE)) + (u4AcOffset * 4)); -+ -+ prAcQueParams->u2CWmax = BIT(((*((PUINT_8) (&(prIeWmmParam->ucEcw_BE)) + (u4AcOffset * 4))) & WMM_ECW_WMAX_MASK) -+ >> WMM_ECW_WMAX_OFFSET) - 1; -+ -+ prAcQueParams->u2CWmin = -+ BIT((*((PUINT_8) (&(prIeWmmParam->ucEcw_BE)) + (u4AcOffset * 4))) & WMM_ECW_WMIN_MASK) - 1; -+ -+ WLAN_GET_FIELD_16(((PUINT_8) (&(prIeWmmParam->aucTxopLimit_BE)) + (u4AcOffset * 4)), -+ &(prAcQueParams->u2TxopLimit)); -+ -+ prAcQueParams->ucGuradTime = TXM_DEFAULT_FLUSH_QUEUE_GUARD_TIME; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To parse WMM/11n related IEs in scan results (only for AP peers) -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prScanResult The scan result which shall be parsed to obtain needed info -+* \param[out] prStaRec The obtained info is stored in the STA_REC -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+#if (CFG_SUPPORT_TDLS == 1) /* for test purpose */ -+BOOLEAN flgTdlsTestExtCapElm = FALSE; -+UINT8 aucTdlsTestExtCapElm[7]; -+#endif /* CFG_SUPPORT_TDLS */ -+VOID mqmProcessScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prScanResult, OUT P_STA_RECORD_T prStaRec) -+{ -+ PUINT_8 pucIE; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ -+ DEBUGFUNC("mqmProcessScanResult"); -+ -+ ASSERT(prScanResult); -+ ASSERT(prStaRec); -+ -+ /* Reset the flag before parsing */ -+ prStaRec->fgIsWmmSupported = prStaRec->fgIsUapsdSupported = FALSE; -+ -+ if (!prAdapter->rWifiVar.fgSupportQoS) -+ return; -+ -+ u2IELength = prScanResult->u2IELength; -+ pucIE = prScanResult->aucIEBuf; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ /* TDLS test purpose */ -+ if (flgTdlsTestExtCapElm == TRUE) -+ TdlsexBssExtCapParse(prStaRec, aucTdlsTestExtCapElm); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ /* Goal: Determine whether the peer supports WMM/QoS and UAPSDU */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_EXTENDED_CAP: -+#if (CFG_SUPPORT_TDLS == 1) -+ TdlsexBssExtCapParse(prStaRec, pucIE); -+#endif /* CFG_SUPPORT_TDLS */ -+ break; -+ -+ case ELEM_ID_WMM: -+ if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && -+ (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { -+ -+ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { -+ case VENDOR_OUI_SUBTYPE_WMM_PARAM: -+ if (IE_LEN(pucIE) != 24) -+ break; /* WMM Param IE with a wrong length */ -+ -+ prStaRec->fgIsWmmSupported = TRUE; -+ prStaRec->fgIsUapsdSupported = -+ (((((P_IE_WMM_PARAM_T) pucIE)->ucQosInfo) & WMM_QOS_INFO_UAPSD) ? -+ TRUE : FALSE); -+ break; -+ -+ case VENDOR_OUI_SUBTYPE_WMM_INFO: -+ if (IE_LEN(pucIE) != 7) -+ break; /* WMM Info IE with a wrong length */ -+ -+ prStaRec->fgIsWmmSupported = TRUE; -+ prStaRec->fgIsUapsdSupported = -+ (((((P_IE_WMM_INFO_T) pucIE)->ucQosInfo) & WMM_QOS_INFO_UAPSD) ? -+ TRUE : FALSE); -+ break; -+ -+ default: -+ /* A WMM QoS IE that doesn't matter. Ignore it. */ -+ break; -+ } -+ } -+ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS, ... (not cared) */ -+ -+ break; -+ -+ default: -+ /* A WMM IE that doesn't matter. Ignore it. */ -+ break; -+ } -+ } -+ DBGLOG(QM, LOUD, "MQM: Scan Result Parsing (WMM=%d, UAPSD=%d)\n", -+ prStaRec->fgIsWmmSupported, prStaRec->fgIsUapsdSupported); -+ -+} -+ -+UINT_8 qmGetStaRecIdx(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucEthDestAddr, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType) -+{ -+ UINT_32 i; -+ P_STA_RECORD_T prTempStaRec; -+ -+ prTempStaRec = NULL; -+ -+ ASSERT(prAdapter); -+ -+ /* 4 <1> DA = BMCAST */ -+ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr)) -+ return STA_REC_INDEX_BMCAST; -+ /* 4 <2> Check if an AP STA is present */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { -+ prTempStaRec = &(prAdapter->arStaRec[i]); -+ if ((prTempStaRec->ucNetTypeIndex == eNetworkType) -+ && (prTempStaRec->fgIsAp) -+ && (prTempStaRec->fgIsValid)) { -+ return prTempStaRec->ucIndex; -+ } -+ } -+ -+ /* 4 <3> Not BMCAST, No AP --> Compare DA (i.e., to see whether this is a unicast frame to a client) */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { -+ prTempStaRec = &(prAdapter->arStaRec[i]); -+ if (prTempStaRec->fgIsValid) { -+ if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, pucEthDestAddr)) -+ return prTempStaRec->ucIndex; -+ } -+ } -+ -+ /* 4 <4> No STA found, Not BMCAST --> Indicate NOT_FOUND to FW */ -+ return STA_REC_INDEX_NOT_FOUND; -+} -+ -+UINT_32 -+mqmGenerateWmmInfoIEByParam(BOOLEAN fgSupportUAPSD, -+ UINT_8 ucBmpDeliveryAC, UINT_8 ucBmpTriggerAC, UINT_8 ucUapsdSp, UINT_8 *pOutBuf) -+{ -+ P_IE_WMM_INFO_T prIeWmmInfo; -+ UINT_32 ucUapsd[] = { -+ WMM_QOS_INFO_BE_UAPSD, -+ WMM_QOS_INFO_BK_UAPSD, -+ WMM_QOS_INFO_VI_UAPSD, -+ WMM_QOS_INFO_VO_UAPSD -+ }; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ -+ ASSERT(pOutBuf); -+ -+ prIeWmmInfo = (P_IE_WMM_INFO_T) pOutBuf; -+ -+ prIeWmmInfo->ucId = ELEM_ID_WMM; -+ prIeWmmInfo->ucLength = ELEM_MAX_LEN_WMM_INFO; -+ -+ /* WMM-2.2.1 WMM Information Element Field Values */ -+ prIeWmmInfo->aucOui[0] = aucWfaOui[0]; -+ prIeWmmInfo->aucOui[1] = aucWfaOui[1]; -+ prIeWmmInfo->aucOui[2] = aucWfaOui[2]; -+ prIeWmmInfo->ucOuiType = VENDOR_OUI_TYPE_WMM; -+ prIeWmmInfo->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_INFO; -+ -+ prIeWmmInfo->ucVersion = VERSION_WMM; -+ prIeWmmInfo->ucQosInfo = 0; -+ -+ /* UAPSD initial queue configurations (delivery and trigger enabled) */ -+ if (fgSupportUAPSD) { -+ -+ UINT_8 ucQosInfo = 0; -+ UINT_8 i; -+ -+ /* Static U-APSD setting */ -+ for (i = ACI_BE; i <= ACI_VO; i++) { -+ if (ucBmpDeliveryAC & ucBmpTriggerAC & BIT(i)) -+ ucQosInfo |= (UINT_8) ucUapsd[i]; -+ } -+ -+ if (ucBmpDeliveryAC & ucBmpTriggerAC) { -+ switch (ucUapsdSp) { -+ case WMM_MAX_SP_LENGTH_ALL: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_ALL; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_2: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_4: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_4; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_6: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_6; -+ break; -+ -+ default: -+ DBGLOG(QM, WARN, "MQM: Incorrect SP length\n"); -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; -+ break; -+ } -+ } -+ prIeWmmInfo->ucQosInfo = ucQosInfo; -+ -+ } -+ -+ /* Increment the total IE length for the Element ID and Length fields. */ -+ return IE_SIZE(prIeWmmInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Generate the WMM Info IE -+* -+* \param[in] prAdapter Adapter pointer -+* @param prMsduInfo The TX MMPDU -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mqmGenerateWmmInfoIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_IE_WMM_INFO_T prIeWmmInfo; -+ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("mqmGenerateWmmInfoIE"); -+ -+ ASSERT(prMsduInfo); -+ -+ /* In case QoS is not turned off, exit directly */ -+ if (!prAdapter->rWifiVar.fgSupportQoS) -+ return; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (prStaRec == NULL) -+ return; -+ -+ if (!prStaRec->fgIsWmmSupported) -+ return; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ -+ prIeWmmInfo = (P_IE_WMM_INFO_T) -+ ((PUINT_8) prMsduInfo->prPacket + prMsduInfo->u2FrameLength); -+ -+#if 0 -+ prIeWmmInfo->ucId = ELEM_ID_WMM; -+ prIeWmmInfo->ucLength = ELEM_MAX_LEN_WMM_INFO; -+ -+ /* WMM-2.2.1 WMM Information Element Field Values */ -+ prIeWmmInfo->aucOui[0] = aucWfaOui[0]; -+ prIeWmmInfo->aucOui[1] = aucWfaOui[1]; -+ prIeWmmInfo->aucOui[2] = aucWfaOui[2]; -+ prIeWmmInfo->ucOuiType = VENDOR_OUI_TYPE_WMM; -+ prIeWmmInfo->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_INFO; -+ -+ prIeWmmInfo->ucVersion = VERSION_WMM; -+ prIeWmmInfo->ucQosInfo = 0; -+ -+ /* UAPSD initial queue configurations (delivery and trigger enabled) */ -+/* if(prAdapter->rWifiVar.fgSupportUAPSD){ */ -+ if (prAdapter->rWifiVar.fgSupportUAPSD && prStaRec->fgIsUapsdSupported) { -+ -+ UINT_8 ucQosInfo = 0; -+ UINT_8 i; -+ -+ /* Static U-APSD setting */ -+ for (i = ACI_BE; i <= ACI_VO; i++) { -+ if (prPmProfSetupInfo->ucBmpDeliveryAC & prPmProfSetupInfo->ucBmpTriggerAC & BIT(i)) -+ ucQosInfo |= (UINT_8) ucUapsd[i]; -+ } -+ -+ if (prPmProfSetupInfo->ucBmpDeliveryAC & prPmProfSetupInfo->ucBmpTriggerAC) { -+ switch (prPmProfSetupInfo->ucUapsdSp) { -+ case WMM_MAX_SP_LENGTH_ALL: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_ALL; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_2: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_4: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_4; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_6: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_6; -+ break; -+ -+ default: -+ DBGLOG(QM, INFO, "MQM: Incorrect SP length\n"); -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; -+ break; -+ } -+ } -+ prIeWmmInfo->ucQosInfo = ucQosInfo; -+ -+ } -+ -+ /* Increment the total IE length for the Element ID and Length fields. */ -+ prMsduInfo->u2FrameLength += IE_SIZE(prIeWmmInfo); -+#else -+ -+ prMsduInfo->u2FrameLength += mqmGenerateWmmInfoIEByParam((prAdapter->rWifiVar.fgSupportUAPSD -+ && prStaRec->fgIsUapsdSupported), -+ prPmProfSetupInfo->ucBmpDeliveryAC, -+ prPmProfSetupInfo->ucBmpTriggerAC, -+ prPmProfSetupInfo->ucUapsdSp, (UINT_8 *) prIeWmmInfo); -+#endif -+} -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief log2 calculation for CW -+* -+* @param[in] val value -+* -+* @return log2(val) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+UINT_32 cwlog2(UINT_32 val) -+{ -+ -+ UINT_32 n; -+ -+ n = 0; -+ -+ while (val >= 512) { -+ n += 9; -+ val = val >> 9; -+ } -+ while (val >= 16) { -+ n += 4; -+ val >>= 4; -+ } -+ while (val >= 2) { -+ n += 1; -+ val >>= 1; -+ } -+ return n; -+} -+#endif -+ -+UINT_32 mqmGenerateWmmParamIEByParam(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, UINT_8 *pOutBuf, ENUM_OP_MODE_T ucOpMode) -+{ -+ P_IE_WMM_PARAM_T prIeWmmParam; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ UINT_8 aucACI[] = { -+ WMM_ACI_AC_BE, -+ WMM_ACI_AC_BK, -+ WMM_ACI_AC_VI, -+ WMM_ACI_AC_VO -+ }; -+ ENUM_WMM_ACI_T eAci; -+ UCHAR *pucAciAifsn, *pucEcw, *pucTxopLimit; -+ -+ ASSERT(pOutBuf); -+ -+ prIeWmmParam = (P_IE_WMM_PARAM_T) pOutBuf; -+ -+ prIeWmmParam->ucId = ELEM_ID_WMM; -+ prIeWmmParam->ucLength = ELEM_MAX_LEN_WMM_PARAM; -+ -+ /* WMM-2.2.1 WMM Information Element Field Values */ -+ prIeWmmParam->aucOui[0] = aucWfaOui[0]; -+ prIeWmmParam->aucOui[1] = aucWfaOui[1]; -+ prIeWmmParam->aucOui[2] = aucWfaOui[2]; -+ prIeWmmParam->ucOuiType = VENDOR_OUI_TYPE_WMM; -+ prIeWmmParam->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_PARAM; -+ -+ prIeWmmParam->ucVersion = VERSION_WMM; -+ prIeWmmParam->ucQosInfo = (prBssInfo->ucWmmParamSetCount & WMM_QOS_INFO_PARAM_SET_CNT); -+ -+ /* UAPSD initial queue configurations (delivery and trigger enabled) */ -+ if (prAdapter->rWifiVar.fgSupportUAPSD) { -+ if (ucOpMode == OP_MODE_INFRASTRUCTURE) -+ prIeWmmParam->ucQosInfo = 0xf; -+ else -+ prIeWmmParam->ucQosInfo |= WMM_QOS_INFO_UAPSD; -+ } -+ -+ /* EDCA parameter */ -+ -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ /* DBGLOG(QM, LOUD, */ -+ /* ("MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", */ -+ /* eAci,prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet , */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmin, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmax, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit)); */ -+ -+#if 0 -+ *(((PUINT_8) (&prIeWmmParam->ucAciAifsn_BE)) + (eAci << 2)) = (UINT_8) (aucACI[eAci] -+ | -+ (prBssInfo->arACQueParmsForBcast -+ [eAci].fgIsACMSet ? -+ WMM_ACIAIFSN_ACM : 0) -+ | -+ (prBssInfo->arACQueParmsForBcast -+ [eAci].u2Aifsn & -+ (WMM_ACIAIFSN_AIFSN))); -+#else -+ /* avoid compile warnings in Klockwork tool */ -+ if (eAci == WMM_AC_BE_INDEX) { -+ pucAciAifsn = &prIeWmmParam->ucAciAifsn_BE; -+ pucEcw = &prIeWmmParam->ucEcw_BE; -+ pucTxopLimit = prIeWmmParam->aucTxopLimit_BE; -+ } else if (eAci == WMM_AC_BK_INDEX) { -+ pucAciAifsn = &prIeWmmParam->ucAciAifsn_BG; -+ pucEcw = &prIeWmmParam->ucEcw_BG; -+ pucTxopLimit = prIeWmmParam->aucTxopLimit_BG; -+ } else if (eAci == WMM_AC_VI_INDEX) { -+ pucAciAifsn = &prIeWmmParam->ucAciAifsn_VI; -+ pucEcw = &prIeWmmParam->ucEcw_VI; -+ pucTxopLimit = prIeWmmParam->aucTxopLimit_VI; -+ } else if (eAci == WMM_AC_VO_INDEX) { -+ pucAciAifsn = &prIeWmmParam->ucAciAifsn_VO; -+ pucEcw = &prIeWmmParam->ucEcw_VO; -+ pucTxopLimit = prIeWmmParam->aucTxopLimit_VO; -+ } -+ -+ *pucAciAifsn = (UINT_8) (aucACI[eAci] -+ | (prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet ? WMM_ACIAIFSN_ACM : 0) -+ | (prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn & (WMM_ACIAIFSN_AIFSN))); -+#endif -+ -+#if 1 -+/* *( ((PUINT_8)(&prIeWmmParam->ucEcw_BE)) + (eAci <<2) ) = (UINT_8) (0 */ -+ *pucEcw = (UINT_8) (0 | (((prBssInfo->aucCWminLog2ForBcast[eAci])) & WMM_ECW_WMIN_MASK) -+ | ((((prBssInfo->aucCWmaxLog2ForBcast[eAci])) << WMM_ECW_WMAX_OFFSET) & -+ WMM_ECW_WMAX_MASK) -+ ); -+#else -+ *(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0 -+ | -+ (cwlog2 -+ ((prBssInfo->arACQueParmsForBcast -+ [eAci].u2CWmin + -+ 1)) & WMM_ECW_WMIN_MASK) -+ | -+ ((cwlog2 -+ ((prBssInfo->arACQueParmsForBcast -+ [eAci].u2CWmax + -+ 1)) << WMM_ECW_WMAX_OFFSET) & -+ WMM_ECW_WMAX_MASK) -+ ); -+#endif -+ -+#if 0 -+ WLAN_SET_FIELD_16(((PUINT_8) (prIeWmmParam->aucTxopLimit_BE)) + (eAci << 2) -+ , prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); -+#else -+ WLAN_SET_FIELD_16(pucTxopLimit, prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); -+#endif -+ } -+ -+ /* Increment the total IE length for the Element ID and Length fields. */ -+ return IE_SIZE(prIeWmmParam); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Generate the WMM Param IE -+* -+* \param[in] prAdapter Adapter pointer -+* @param prMsduInfo The TX MMPDU -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mqmGenerateWmmParamIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_IE_WMM_PARAM_T prIeWmmParam; -+ -+#if 0 -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ -+ UINT_8 aucACI[] = { -+ WMM_ACI_AC_BE, -+ WMM_ACI_AC_BK, -+ WMM_ACI_AC_VI, -+ WMM_ACI_AC_VO -+ }; -+ ENUM_WMM_ACI_T eAci; -+#endif -+ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("mqmGenerateWmmParamIE"); -+ DBGLOG(QM, LOUD, "\n"); -+ -+ ASSERT(prMsduInfo); -+ -+ /* In case QoS is not turned off, exit directly */ -+ if (!prAdapter->rWifiVar.fgSupportQoS) -+ return; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (prStaRec) { -+ if (!prStaRec->fgIsQoS) -+ return; -+ } -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]); -+ -+ if (!prBssInfo->fgIsQBSS) -+ return; -+/* 20120220 frog: update beacon content & change OP mode is a separate event for P2P network. */ -+#if 0 -+ if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT && prBssInfo->eCurrentOPMode != OP_MODE_BOW) -+ return; -+#endif -+ -+ prIeWmmParam = (P_IE_WMM_PARAM_T) -+ ((PUINT_8) prMsduInfo->prPacket + prMsduInfo->u2FrameLength); -+ -+#if 0 -+ prIeWmmParam->ucId = ELEM_ID_WMM; -+ prIeWmmParam->ucLength = ELEM_MAX_LEN_WMM_PARAM; -+ -+ /* WMM-2.2.1 WMM Information Element Field Values */ -+ prIeWmmParam->aucOui[0] = aucWfaOui[0]; -+ prIeWmmParam->aucOui[1] = aucWfaOui[1]; -+ prIeWmmParam->aucOui[2] = aucWfaOui[2]; -+ prIeWmmParam->ucOuiType = VENDOR_OUI_TYPE_WMM; -+ prIeWmmParam->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_PARAM; -+ -+ prIeWmmParam->ucVersion = VERSION_WMM; -+ prIeWmmParam->ucQosInfo = (prBssInfo->ucWmmParamSetCount & WMM_QOS_INFO_PARAM_SET_CNT); -+ -+ /* UAPSD initial queue configurations (delivery and trigger enabled) */ -+ if (prAdapter->rWifiVar.fgSupportUAPSD) -+ prIeWmmParam->ucQosInfo |= WMM_QOS_INFO_UAPSD; -+ -+ /* EDCA parameter */ -+ -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ /* DBGLOG(QM, LOUD, */ -+ /* ("MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", */ -+ /* eAci,prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet , */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmin, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmax, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit)); */ -+ -+ *(((PUINT_8) (&prIeWmmParam->ucAciAifsn_BE)) + (eAci << 2)) = (UINT_8) (aucACI[eAci] -+ | -+ (prBssInfo->arACQueParmsForBcast -+ [eAci].fgIsACMSet ? -+ WMM_ACIAIFSN_ACM : 0) -+ | -+ (prBssInfo->arACQueParmsForBcast -+ [eAci].u2Aifsn & -+ (WMM_ACIAIFSN_AIFSN))); -+#if 1 -+ *(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0 -+ | -+ (((prBssInfo->aucCWminLog2ForBcast -+ [eAci])) & WMM_ECW_WMIN_MASK) -+ | -+ ((((prBssInfo->aucCWmaxLog2ForBcast -+ [eAci])) << WMM_ECW_WMAX_OFFSET) -+ & WMM_ECW_WMAX_MASK) -+ ); -+#else -+ *(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0 -+ | -+ (cwlog2 -+ ((prBssInfo->arACQueParmsForBcast -+ [eAci].u2CWmin + -+ 1)) & WMM_ECW_WMIN_MASK) -+ | -+ ((cwlog2 -+ ((prBssInfo->arACQueParmsForBcast -+ [eAci].u2CWmax + -+ 1)) << WMM_ECW_WMAX_OFFSET) & -+ WMM_ECW_WMAX_MASK) -+ ); -+#endif -+ -+ WLAN_SET_FIELD_16(((PUINT_8) (prIeWmmParam->aucTxopLimit_BE)) + (eAci << 2) -+ , prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); -+ -+ } -+ -+ /* Increment the total IE length for the Element ID and Length fields. */ -+ prMsduInfo->u2FrameLength += IE_SIZE(prIeWmmParam); -+#else -+ -+ prMsduInfo->u2FrameLength += mqmGenerateWmmParamIEByParam(prAdapter, -+ prBssInfo, (UINT_8 *) prIeWmmParam, OP_MODE_ACCESS_POINT); -+#endif -+} -+ -+ENUM_FRAME_ACTION_T -+qmGetFrameAction(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, -+ IN UINT_8 ucStaRecIdx, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_FRAME_TYPE_IN_CMD_Q_T eFrameType) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ P_WLAN_MAC_HEADER_T prWlanFrame; -+ UINT_16 u2TxFrameCtrl; -+ -+ DEBUGFUNC("qmGetFrameAction"); -+ -+#if (NIC_TX_BUFF_COUNT_TC4 > 2) -+#define QM_MGMT_QUUEUD_THRESHOLD 2 -+#else -+#define QM_MGMT_QUUEUD_THRESHOLD 1 -+#endif -+ -+ DATA_STRUCT_INSPECTING_ASSERT(QM_MGMT_QUUEUD_THRESHOLD <= (NIC_TX_BUFF_COUNT_TC4)); -+ DATA_STRUCT_INSPECTING_ASSERT(QM_MGMT_QUUEUD_THRESHOLD > 0); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkType]); -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, ucStaRecIdx); -+ -+ /* XXX Check BOW P2P AIS time ot set active */ -+ if (!IS_BSS_ACTIVE(prBssInfo)) { -+ if (eFrameType == FRAME_TYPE_MMPDU) { -+ prWlanFrame = (P_WLAN_MAC_HEADER_T) prMsduInfo->prPacket; -+ u2TxFrameCtrl = (prWlanFrame->u2FrameCtrl) & MASK_FRAME_TYPE; /* Optimized for ARM */ -+ if (((u2TxFrameCtrl == MAC_FRAME_DEAUTH) -+ && (prMsduInfo->pfTxDoneHandler == NULL)) -+ || (u2TxFrameCtrl == MAC_FRAME_ACTION)) /* whsu */ -+ return FRAME_ACTION_TX_PKT; -+ } -+ -+ DBGLOG(QM, WARN, "Drop packets Action, eFrameType: %d (Bss Index %u).\n", -+ eFrameType, prBssInfo->ucNetTypeIndex); -+ TX_INC_CNT(&prAdapter->rTxCtrl, TX_INACTIVE_BSS_DROP); -+ return FRAME_ACTION_DROP_PKT; -+ } -+ -+ /* TODO Handle disconnect issue */ -+ -+ /* P2P probe Request frame */ -+ do { -+ if (eFrameType == FRAME_TYPE_MMPDU) { -+ prWlanFrame = (P_WLAN_MAC_HEADER_T) prMsduInfo->prPacket; -+ u2TxFrameCtrl = (prWlanFrame->u2FrameCtrl) & MASK_FRAME_TYPE; /* Optimized for ARM */ -+ -+ if (u2TxFrameCtrl == MAC_FRAME_BEACON) { -+ if (prBssInfo->fgIsNetAbsent) -+ return FRAME_ACTION_DROP_PKT; -+ } else if (u2TxFrameCtrl == MAC_FRAME_PROBE_RSP) { -+ if (prBssInfo->fgIsNetAbsent) -+ return FRAME_ACTION_DROP_PKT; -+ } else if (u2TxFrameCtrl == MAC_FRAME_DEAUTH) { -+ if (prBssInfo->fgIsNetAbsent) -+ break; -+ DBGLOG(P2P, LOUD, "Sending DEAUTH Frame\n"); -+ return FRAME_ACTION_TX_PKT; -+ } -+ /* MMPDU with prStaRec && fgIsInUse not check fgIsNetActive */ -+ else if (u2TxFrameCtrl == MAC_FRAME_ASSOC_REQ -+ || u2TxFrameCtrl == MAC_FRAME_AUTH -+ || u2TxFrameCtrl == MAC_FRAME_REASSOC_REQ -+ || u2TxFrameCtrl == MAC_FRAME_PROBE_REQ || u2TxFrameCtrl == MAC_FRAME_ACTION) { -+ -+ if ((prStaRec) && (prStaRec->fgIsInPS)) { -+ if (nicTxGetResource(prAdapter, TC4_INDEX) >= QM_MGMT_QUUEUD_THRESHOLD) -+ return FRAME_ACTION_TX_PKT; -+ else -+ return FRAME_ACTION_QUEUE_PKT; -+ } -+ return FRAME_ACTION_TX_PKT; -+ } -+ -+ if (!prStaRec) -+ return FRAME_ACTION_TX_PKT; -+ -+ if (!prStaRec->fgIsInUse) -+ return FRAME_ACTION_DROP_PKT; -+ -+ } /* FRAME_TYPE_MMPDU */ -+ else if (eFrameType == FRAME_TYPE_802_1X) { -+ -+ if (!prStaRec) -+ return FRAME_ACTION_TX_PKT; -+ -+ if (!prStaRec->fgIsInUse) -+ return FRAME_ACTION_DROP_PKT; -+ if (prStaRec->fgIsInPS) { -+ if (nicTxGetResource(prAdapter, TC4_INDEX) >= QM_MGMT_QUUEUD_THRESHOLD) -+ return FRAME_ACTION_TX_PKT; -+ else -+ return FRAME_ACTION_QUEUE_PKT; -+ } -+ -+ } /* FRAME_TYPE_802_1X */ -+ else if ((!IS_BSS_ACTIVE(prBssInfo)) -+ || (!prStaRec) -+ || (!prStaRec->fgIsInUse)) { -+ return FRAME_ACTION_DROP_PKT; -+ } -+ } while (0); -+ -+ if (prBssInfo->fgIsNetAbsent) { -+ DBGLOG(QM, LOUD, "Queue packets (Absent %u).\n", prBssInfo->ucNetTypeIndex); -+ return FRAME_ACTION_QUEUE_PKT; -+ } -+ -+ if (prStaRec && prStaRec->fgIsInPS) { -+ DBGLOG(QM, LOUD, "Queue packets (PS %u).\n", prStaRec->fgIsInPS); -+ return FRAME_ACTION_QUEUE_PKT; -+ } -+ switch (eFrameType) { -+ case FRAME_TYPE_802_1X: -+ if (!prStaRec->fgIsValid) -+ return FRAME_ACTION_QUEUE_PKT; -+ break; -+ -+ case FRAME_TYPE_MMPDU: -+ break; -+ -+ default: -+ ASSERT(0); -+ } -+ -+ return FRAME_ACTION_TX_PKT; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle BSS change operation Event from the FW -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prEvent The event packet from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleEventBssAbsencePresence(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_BSS_ABSENCE_PRESENCE_T prEventBssStatus; -+ P_BSS_INFO_T prBssInfo; -+ BOOLEAN fgIsNetAbsentOld; -+ -+ prEventBssStatus = (P_EVENT_BSS_ABSENCE_PRESENCE_T) prEvent; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prEventBssStatus->ucNetTypeIdx]); -+ fgIsNetAbsentOld = prBssInfo->fgIsNetAbsent; -+ prBssInfo->fgIsNetAbsent = prEventBssStatus->fgIsAbsent; -+ prBssInfo->ucBssFreeQuota = prEventBssStatus->ucBssFreeQuota; -+ -+ /* DBGLOG(QM, TRACE, ("qmHandleEventBssAbsencePresence (ucNetTypeIdx=%d, fgIsAbsent=%d, FreeQuota=%d)\n", */ -+ /* prEventBssStatus->ucNetTypeIdx, prBssInfo->fgIsNetAbsent, prBssInfo->ucBssFreeQuota)); */ -+ -+ DBGLOG(QM, INFO, "NAF=%d,%d,%d\n", -+ prEventBssStatus->ucNetTypeIdx, prBssInfo->fgIsNetAbsent, prBssInfo->ucBssFreeQuota); -+ -+ if (!prBssInfo->fgIsNetAbsent) { -+ /* QM_DBG_CNT_27 */ -+ QM_DBG_CNT_INC(&(prAdapter->rQM), QM_DBG_CNT_27); -+ } else { -+ /* QM_DBG_CNT_28 */ -+ QM_DBG_CNT_INC(&(prAdapter->rQM), QM_DBG_CNT_28); -+ } -+ /* From Absent to Present */ -+ if ((fgIsNetAbsentOld) && (!prBssInfo->fgIsNetAbsent)) -+ kalSetEvent(prAdapter->prGlueInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle STA change PS mode Event from the FW -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prEvent The event packet from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleEventStaChangePsMode(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_STA_CHANGE_PS_MODE_T prEventStaChangePsMode; -+ P_STA_RECORD_T prStaRec; -+ BOOLEAN fgIsInPSOld; -+ -+ /* DbgPrint("QM:Event -RxBa\n"); */ -+ -+ prEventStaChangePsMode = (P_EVENT_STA_CHANGE_PS_MODE_T) prEvent; -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventStaChangePsMode->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (prStaRec) { -+ -+ fgIsInPSOld = prStaRec->fgIsInPS; -+ prStaRec->fgIsInPS = prEventStaChangePsMode->fgIsInPs; -+ -+ qmUpdateFreeQuota(prAdapter, -+ prStaRec, -+ prEventStaChangePsMode->ucUpdateMode, prEventStaChangePsMode->ucFreeQuota, 0); -+ -+ /* DBGLOG(QM, TRACE, ("qmHandleEventStaChangePsMode (ucStaRecIdx=%d, fgIsInPs=%d)\n", */ -+ /* prEventStaChangePsMode->ucStaRecIdx, prStaRec->fgIsInPS)); */ -+ -+ DBGLOG(QM, TRACE, "PS=%d,%d\n", prEventStaChangePsMode->ucStaRecIdx, prStaRec->fgIsInPS); -+ -+ /* From PS to Awake */ -+ if ((fgIsInPSOld) && (!prStaRec->fgIsInPS)) -+ kalSetEvent(prAdapter->prGlueInfo); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Update STA free quota Event from FW -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prEvent The event packet from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleEventStaUpdateFreeQuota(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_STA_UPDATE_FREE_QUOTA_T prEventStaUpdateFreeQuota; -+ P_STA_RECORD_T prStaRec; -+ -+ prEventStaUpdateFreeQuota = (P_EVENT_STA_UPDATE_FREE_QUOTA_T) prEvent; -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventStaUpdateFreeQuota->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (prStaRec) { -+ if (prStaRec->fgIsInPS) { -+ qmUpdateFreeQuota(prAdapter, -+ prStaRec, -+ prEventStaUpdateFreeQuota->ucUpdateMode, -+ prEventStaUpdateFreeQuota->ucFreeQuota, -+ prEventStaUpdateFreeQuota->aucReserved[0]); -+ -+ kalSetEvent(prAdapter->prGlueInfo); -+ } -+#if 0 -+ DBGLOG(QM, TRACE, -+ "qmHandleEventStaUpdateFreeQuota (ucStaRecIdx=%d, ucUpdateMode=%d, ucFreeQuota=%d)\n", -+ prEventStaUpdateFreeQuota->ucStaRecIdx, prEventStaUpdateFreeQuota->ucUpdateMode, -+ prEventStaUpdateFreeQuota->ucFreeQuota); -+#endif -+ -+ DBGLOG(QM, TRACE, "UFQ=%d,%d,%d\n", -+ prEventStaUpdateFreeQuota->ucStaRecIdx, -+ prEventStaUpdateFreeQuota->ucUpdateMode, prEventStaUpdateFreeQuota->ucFreeQuota); -+ -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Update STA free quota -+* -+* \param[in] prStaRec the STA -+* \param[in] ucUpdateMode the method to update free quota -+* \param[in] ucFreeQuota the value for update -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+qmUpdateFreeQuota(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUpdateMode, IN UINT_8 ucFreeQuota, IN UINT_8 ucNumOfTxDone) -+{ -+ -+ UINT_8 ucFreeQuotaForNonDelivery; -+ UINT_8 ucFreeQuotaForDelivery; -+ BOOLEAN flgIsUpdateForcedToDelivery; -+ -+ ASSERT(prStaRec); -+ DBGLOG(QM, LOUD, "qmUpdateFreeQuota orig ucFreeQuota=%d Mode %u New %u\n", -+ prStaRec->ucFreeQuota, ucUpdateMode, ucFreeQuota); -+ -+ if (!prStaRec->fgIsInPS) -+ return; -+ -+ flgIsUpdateForcedToDelivery = FALSE; -+ -+ if (ucNumOfTxDone > 0) { -+ /* -+ update free quota by -+ num of tx done + resident free quota (delivery + non-delivery) -+ */ -+ UINT_8 ucAvailQuota; -+ -+ ucAvailQuota = ucNumOfTxDone + prStaRec->ucFreeQuotaForDelivery + prStaRec->ucFreeQuotaForNonDelivery; -+ if (ucAvailQuota > ucFreeQuota) /* sanity check */ -+ ucAvailQuota = ucFreeQuota; -+ -+ /* update current free quota */ -+ ucFreeQuota = ucAvailQuota; -+ -+ /* check if the update is from last packet */ -+ if (ucFreeQuota == (prStaRec->ucFreeQuota + 1)) { -+ /* just add the extra quota to delivery queue */ -+ -+ /* -+ EX: -+ 1. TDLS peer enters power save -+ 2. When the last 2 VI packets are tx done, we will receive 2 update events -+ 3. 1st update event: ucFreeQuota = 9 -+ 4. We will correct new quota for delivey and non-delivery to 7:2 -+ 5. 2rd update event: ucFreeQuota = 10 -+ 6. We will re-correct new quota for delivery and non-delivery to 5:5 -+ -+ But non-delivery queue is not busy. -+ So in the case, we will have wrong decision, i.e. higher queue always quota 5 -+ -+ Solution: skip the 2rd update event and just add the extra quota to delivery. -+ */ -+ -+ flgIsUpdateForcedToDelivery = TRUE; -+ } -+ } -+ -+ switch (ucUpdateMode) { -+ case FREE_QUOTA_UPDATE_MODE_INIT: -+ case FREE_QUOTA_UPDATE_MODE_OVERWRITE: -+ prStaRec->ucFreeQuota = ucFreeQuota; -+ break; -+ case FREE_QUOTA_UPDATE_MODE_INCREASE: -+ prStaRec->ucFreeQuota += ucFreeQuota; -+ break; -+ case FREE_QUOTA_UPDATE_MODE_DECREASE: -+ prStaRec->ucFreeQuota -= ucFreeQuota; -+ break; -+ default: -+ ASSERT(0); -+ } -+ -+ DBGLOG(QM, LOUD, "qmUpdateFreeQuota new ucFreeQuota=%d)\n", prStaRec->ucFreeQuota); -+ -+ ucFreeQuota = prStaRec->ucFreeQuota; -+ -+ ucFreeQuotaForNonDelivery = 0; -+ ucFreeQuotaForDelivery = 0; -+ -+ if (ucFreeQuota > 0) { -+ if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported -+ /* && prAdapter->rWifiVar.fgSupportQoS -+ && prAdapter->rWifiVar.fgSupportUAPSD */) { -+ /* XXX We should assign quota to aucFreeQuotaPerQueue[NUM_OF_PER_STA_TX_QUEUES] */ -+ -+ if (flgIsUpdateForcedToDelivery == FALSE) { -+ if (prStaRec->ucFreeQuotaForNonDelivery > 0 && prStaRec->ucFreeQuotaForDelivery > 0) { -+ ucFreeQuotaForNonDelivery = ucFreeQuota >> 1; -+ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; -+ } else if (prStaRec->ucFreeQuotaForNonDelivery == 0 -+ && prStaRec->ucFreeQuotaForDelivery == 0) { -+ ucFreeQuotaForNonDelivery = ucFreeQuota >> 1; -+ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; -+ } else if (prStaRec->ucFreeQuotaForNonDelivery > 0) { -+ /* NonDelivery is not busy */ -+ if (ucFreeQuota >= 3) { -+ ucFreeQuotaForNonDelivery = 2; -+ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; -+ } else { -+ ucFreeQuotaForDelivery = ucFreeQuota; -+ ucFreeQuotaForNonDelivery = 0; -+ } -+ } else if (prStaRec->ucFreeQuotaForDelivery > 0) { -+ /* Delivery is not busy */ -+ if (ucFreeQuota >= 3) { -+ ucFreeQuotaForDelivery = 2; -+ ucFreeQuotaForNonDelivery = ucFreeQuota - ucFreeQuotaForDelivery; -+ } else { -+ ucFreeQuotaForNonDelivery = ucFreeQuota; -+ ucFreeQuotaForDelivery = 0; -+ } -+ } -+ } else { -+ ucFreeQuotaForNonDelivery = 2; -+ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; -+ } -+ } else { -+ /* no use ? */ -+ /* !prStaRec->fgIsUapsdSupported */ -+ ucFreeQuotaForNonDelivery = ucFreeQuota; -+ ucFreeQuotaForDelivery = 0; -+ } -+ } -+ /* ucFreeQuota > 0 */ -+ prStaRec->ucFreeQuotaForDelivery = ucFreeQuotaForDelivery; -+ prStaRec->ucFreeQuotaForNonDelivery = ucFreeQuotaForNonDelivery; -+ -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ if (IS_TDLS_STA(prStaRec)) -+ DBGLOG(QM, LOUD, " quota %d %d %d\n", -+ ucFreeQuota, ucFreeQuotaForDelivery, ucFreeQuotaForNonDelivery); -+#endif -+ -+ DBGLOG(QM, LOUD, "new QuotaForDelivery = %d QuotaForNonDelivery = %d\n", -+ prStaRec->ucFreeQuotaForDelivery, prStaRec->ucFreeQuotaForNonDelivery); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Return the reorder queued RX packets -+* -+* \param[in] (none) -+* -+* \return The number of queued RX packets -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 qmGetRxReorderQueuedBufferCount(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i, u4Total; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ u4Total = 0; -+ /* XXX The summation may impact the performance */ -+ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { -+ u4Total += prQM->arRxBaTable[i].rReOrderQue.u4NumElem; -+#if DBG && 0 -+ if (QUEUE_IS_EMPTY(&(prQM->arRxBaTable[i].rReOrderQue))) -+ ASSERT(prQM->arRxBaTable[i].rReOrderQue == 0); -+#endif -+ } -+ ASSERT(u4Total <= (CFG_NUM_OF_QM_RX_PKT_NUM * 2)); -+ return u4Total; -+} -+ -+#if ARP_MONITER_ENABLE -+VOID qmDetectArpNoResponse(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ struct sk_buff *prSkb = NULL; -+ PUINT_8 pucData = NULL; -+ UINT_16 u2EtherType = 0; -+ int arpOpCode = 0; -+ -+ prSkb = (struct sk_buff *)prMsduInfo->prPacket; -+ -+ if (!prSkb || (prSkb->len <= ETHER_HEADER_LEN)) -+ return; -+ -+ pucData = prSkb->data; -+ if (!pucData) -+ return; -+ u2EtherType = (pucData[ETH_TYPE_LEN_OFFSET] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ if (u2EtherType != ETH_P_ARP || (apIp[0] | apIp[1] | apIp[2] | apIp[3]) == 0) -+ return; -+ -+ if (strncmp(apIp, &pucData[ETH_TYPE_LEN_OFFSET + 26], sizeof(apIp))) /* dest ip address */ -+ return; -+ -+ arpOpCode = (pucData[ETH_TYPE_LEN_OFFSET + 8] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 8 + 1]); -+ if (arpOpCode == ARP_PRO_REQ) { -+ arpMoniter++; -+ if (arpMoniter > 20) { -+ DBGLOG(INIT, WARN, "IOT Critical issue, arp no resp, check AP!\n"); -+ aisBssBeaconTimeout(prAdapter); -+ arpMoniter = 0; -+ kalMemZero(apIp, sizeof(apIp)); -+ } -+ } -+} -+ -+VOID qmHandleRxArpPackets(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) -+{ -+ PUINT_8 pucData = NULL; -+ UINT_16 u2EtherType = 0; -+ int arpOpCode = 0; -+ P_BSS_INFO_T prBssInfo = NULL; -+ -+ if (prSwRfb->u2PacketLen <= ETHER_HEADER_LEN) -+ return; -+ -+ pucData = (PUINT_8)prSwRfb->pvHeader; -+ if (!pucData) -+ return; -+ u2EtherType = (pucData[ETH_TYPE_LEN_OFFSET] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ if (u2EtherType != ETH_P_ARP) -+ return; -+ -+ arpOpCode = (pucData[ETH_TYPE_LEN_OFFSET + 8] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 8 + 1]); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ if (arpOpCode == ARP_PRO_RSP) { -+ arpMoniter = 0; -+ if (prBssInfo && prBssInfo->prStaRecOfAP && prBssInfo->prStaRecOfAP->aucMacAddr) { -+ if (EQUAL_MAC_ADDR(&(pucData[ETH_TYPE_LEN_OFFSET + 10]), /* source hardware address */ -+ prBssInfo->prStaRecOfAP->aucMacAddr)) { -+ strncpy(apIp, &(pucData[ETH_TYPE_LEN_OFFSET + 16]), sizeof(apIp)); /* src ip address */ -+ DBGLOG(INIT, TRACE, "get arp response from AP %d.%d.%d.%d\n", -+ apIp[0], apIp[1], apIp[2], apIp[3]); -+ } -+ } -+ } -+} -+ -+VOID qmResetArpDetect(VOID) -+{ -+ arpMoniter = 0; -+ kalMemZero(apIp, sizeof(apIp)); -+} -+#endif -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c -new file mode 100644 -index 0000000000000..6f5c0bcdd90bb ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c -@@ -0,0 +1,1177 @@ -+/* -+** Id: @(#) gl_bow.c@@ -+*/ -+ -+/*! \file gl_bow.c -+ \brief Main routines of Linux driver interface for 802.11 PAL (BT 3.0 + HS) -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_bow.c -+ * -+ * 02 16 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * [ALPS00235223] [Rose][ICS][Cross Feature][AEE-IPANIC]The device reboot automatically and then the "KE" pops up -+ * after you turn on the "Airplane mode".(once) -+ * -+ * [Root Cause] -+ * PAL operates BOW char dev poll after BOW char dev is registered. -+ * -+ * [Solution] -+ * Rejects PAL char device operation after BOW is unregistered or when wlan GLUE_FLAG_HALT is set. -+ * -+ * This is a workaround for BOW driver robustness, happens only in ICS. -+ * -+ * Root cause should be fixed by CR [ALPS00231570] -+ * -+ * 02 03 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * [ALPS00118114] [Rose][ICS][Free Test][Bluetooth]The "KE" pops up after you turn on the airplane mode.(5/5) -+ * -+ * [Root Cause] -+ * PAL operates BOW char dev poll after BOW char dev is registered. -+ * -+ * [Solution] -+ * Rejects PAL char device operation after BOW is unregistered. -+ * -+ * Happens only in ICS. -+ * -+ * Notified PAL owener to reivew MTKBT/PAL closing BOW char dev procedure. -+ * -+ * [Side Effect] -+ * None. -+ * -+ * 01 16 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support BOW for 5GHz band. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 10 25 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Modify ampc0 char device for major number 151 for all MT6575 projects. -+ * -+ * 07 28 2011 cp.wu -+ * [WCXRP00000884] [MT6620 Wi-Fi][Driver] Deprecate ioctl interface by unlocked ioctl -+ * unlocked_ioctl returns as long instead of int. -+ * -+ * 07 28 2011 cp.wu -+ * [WCXRP00000884] [MT6620 Wi-Fi][Driver] Deprecate ioctl interface by unlocked ioctl -+ * migrate to unlocked ioctl interface -+ * -+ * 04 12 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add WMM IE for BOW initiator data. -+ * -+ * 04 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Change Link disconnection event procedure for hotspot and change skb length check to 1514 bytes. -+ * -+ * 04 09 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Change Link connection event procedure and change skb length check to 1512 bytes. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support multiple physical link. -+ * -+ * 03 06 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Sync BOW Driver to latest person development branch version.. -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * support concurrent network -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * replace alloc_netdev to alloc_netdev_mq for BoW -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * modify net device relative functions to support multiple H/W queues -+ * -+ * 02 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update net register and BOW for concurrent features. -+ * -+ * 02 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix kernel API change issue. -+ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is -+ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); -+ * After ALPS 2.3, kfifo_alloc() is changed to -+ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); -+ * -+ * 02 09 2011 cp.wu -+ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3 -+ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031 -+ * with BOW and P2P enabled as default -+ * -+ * 02 08 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in. -+ * Update BOW get MAC status, remove returning event for AIS network type. -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation -+ * needs such information -+ * fill mac header length information for 802.1x frames. -+ * -+ * 11 11 2010 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix BoW timer assert issue. -+ * -+ * 09 14 2010 chinghwa.yu -+ * NULL -+ * Add bowRunEventAAAComplete. -+ * -+ * 09 14 2010 cp.wu -+ * NULL -+ * correct typo: POLLOUT instead of POLL_OUT -+ * -+ * 09 13 2010 cp.wu -+ * NULL -+ * add waitq for poll() and read(). -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update BOW for the 1st time. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 05 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change variable names for multiple physical link to match with coding convention -+ * -+ * 05 05 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * multiple BoW interfaces need to compare with peer address -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * fix kalIndicateBOWEvent. -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_os.h" -+#include "debug.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include "precomp.h" -+#include -+#include "bss.h" -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* @FIXME if there is command/event with payload length > 28 */ -+#define MAX_BUFFER_SIZE (64) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+#if CFG_BOW_TEST -+UINT_32 g_u4PrevSysTime = 0; -+UINT_32 g_u4CurrentSysTime = 0; -+UINT_32 g_arBowRevPalPacketTime[11]; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* forward declarations */ -+static ssize_t mt6620_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos); -+ -+static ssize_t -+mt6620_ampc_write(IN struct file *filp, OUT const char __user *buf, IN size_t size, IN OUT loff_t *ppos); -+ -+static long mt6620_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg); -+ -+static unsigned int mt6620_ampc_poll(IN struct file *filp, IN poll_table *wait); -+ -+static int mt6620_ampc_open(IN struct inode *inodep, IN struct file *filp); -+ -+static int mt6620_ampc_release(IN struct inode *inodep, IN struct file *filp); -+ -+/* character file operations */ -+static const struct file_operations mt6620_ampc_fops = { -+ /* .owner = THIS_MODULE, */ -+ .read = mt6620_ampc_read, -+ .write = mt6620_ampc_write, -+ .unlocked_ioctl = mt6620_ampc_ioctl, -+ .poll = mt6620_ampc_poll, -+ .open = mt6620_ampc_open, -+ .release = mt6620_ampc_release, -+}; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Register for character device to communicate with 802.11 PAL -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glRegisterAmpc(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ if (prGlueInfo->rBowInfo.fgIsRegistered == TRUE) -+ return FALSE; -+ -+#if 0 -+ /* 1. allocate major number dynamically */ -+ -+ if (alloc_chrdev_region(&(prGlueInfo->rBowInfo.u4DeviceNumber), 0, /* first minor number */ -+ 1, /* number */ -+ GLUE_BOW_DEVICE_NAME) != 0) -+ -+ return FALSE; -+#endif -+ -+#if 1 -+ -+#if defined(CONFIG_AMPC_CDEV_NUM) -+ prGlueInfo->rBowInfo.u4DeviceNumber = MKDEV(CONFIG_AMPC_CDEV_NUM, 0); -+#else -+ prGlueInfo->rBowInfo.u4DeviceNumber = MKDEV(226, 0); -+#endif -+ -+ if (register_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1, /* number */ -+ GLUE_BOW_DEVICE_NAME) != 0) -+ -+ return FALSE; -+#endif -+ -+ /* 2. spin-lock initialization */ -+ /* spin_lock_init(&(prGlueInfo->rBowInfo.rSpinLock)); */ -+ -+ /* 3. initialize kfifo */ -+/* prGlueInfo->rBowInfo.prKfifo = kfifo_alloc(GLUE_BOW_KFIFO_DEPTH, -+ GFP_KERNEL, -+ &(prGlueInfo->rBowInfo.rSpinLock));*/ -+ if ((kfifo_alloc((struct kfifo *)&(prGlueInfo->rBowInfo.rKfifo), GLUE_BOW_KFIFO_DEPTH, GFP_KERNEL))) -+ goto fail_kfifo_alloc; -+ -+/* if(prGlueInfo->rBowInfo.prKfifo == NULL) */ -+ if (&(prGlueInfo->rBowInfo.rKfifo) == NULL) -+ goto fail_kfifo_alloc; -+ -+ /* 4. initialize cdev */ -+ cdev_init(&(prGlueInfo->rBowInfo.cdev), &mt6620_ampc_fops); -+ /* prGlueInfo->rBowInfo.cdev.owner = THIS_MODULE; */ -+ prGlueInfo->rBowInfo.cdev.ops = &mt6620_ampc_fops; -+ -+ /* 5. add character device */ -+ if (cdev_add(&(prGlueInfo->rBowInfo.cdev), prGlueInfo->rBowInfo.u4DeviceNumber, 1)) -+ goto fail_cdev_add; -+ -+ /* 6. in queue initialization */ -+ init_waitqueue_head(&(prGlueInfo->rBowInfo.outq)); -+ -+ /* 7. finish */ -+ prGlueInfo->rBowInfo.fgIsRegistered = TRUE; -+ return TRUE; -+ -+fail_cdev_add: -+ kfifo_free(&(prGlueInfo->rBowInfo.rKfifo)); -+/* kfifo_free(prGlueInfo->rBowInfo.prKfifo); */ -+fail_kfifo_alloc: -+ unregister_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1); -+ return FALSE; -+} /* end of glRegisterAmpc */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Unregister character device for communicating with 802.11 PAL -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glUnregisterAmpc(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ if (prGlueInfo->rBowInfo.fgIsRegistered == FALSE) -+ return FALSE; -+ -+ prGlueInfo->rBowInfo.fgIsRegistered = FALSE; -+ -+ /* 1. free netdev if necessary */ -+#if CFG_BOW_SEPARATE_DATA_PATH -+ kalUninitBowDevice(prGlueInfo); -+#endif -+ -+ /* 2. removal of character device */ -+ cdev_del(&(prGlueInfo->rBowInfo.cdev)); -+ -+ /* 3. free kfifo */ -+/* kfifo_free(prGlueInfo->rBowInfo.prKfifo); */ -+ kfifo_free(&(prGlueInfo->rBowInfo.rKfifo)); -+/* prGlueInfo->rBowInfo.prKfifo = NULL; */ -+/* prGlueInfo->rBowInfo.rKfifo = NULL; */ -+ -+ /* 4. free device number */ -+ unregister_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1); -+ -+ return TRUE; -+} /* end of glUnregisterAmpc */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief read handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static ssize_t mt6620_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos) -+{ -+ UINT_8 aucBuffer[MAX_BUFFER_SIZE]; -+ ssize_t retval; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); -+ -+ ASSERT(prGlueInfo); -+ -+ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) -+ return -EFAULT; -+ /* size check */ -+/* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) >= size) */ -+ if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) >= size) -+ retval = size; -+ else -+ retval = kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)); -+/* retval = kfifo_len(prGlueInfo->rBowInfo.prKfifo); */ -+ -+/* kfifo_get(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */ -+/* kfifo_out(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */ -+ if (!(kfifo_out(&(prGlueInfo->rBowInfo.rKfifo), aucBuffer, retval))) { -+ retval = -EIO; -+ return retval; -+ } -+ -+ if (copy_to_user(buf, aucBuffer, retval)) -+ retval = -EIO; -+ -+ return retval; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief write handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static ssize_t -+mt6620_ampc_write(IN struct file *filp, OUT const char __user *buf, IN size_t size, IN OUT loff_t *ppos) -+{ -+#if CFG_BOW_TEST -+ UINT_8 i; -+#endif -+ -+ UINT_8 aucBuffer[MAX_BUFFER_SIZE]; -+ P_AMPC_COMMAND prCmd; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); -+ ASSERT(prGlueInfo); -+ -+ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) -+ return -EFAULT; -+ -+ if (size > MAX_BUFFER_SIZE) -+ return -EINVAL; -+ else if (copy_from_user(aucBuffer, buf, size)) -+ return -EIO; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "AMP driver CMD buffer size : %d.\n", size); -+ -+ for (i = 0; i < MAX_BUFFER_SIZE; i++) -+ DBGLOG(BOW, EVENT, "AMP write content : 0x%x.\n", aucBuffer[i]); -+ -+ DBGLOG(BOW, EVENT, "BoW CMD write.\n"); -+#endif -+ -+ prCmd = (P_AMPC_COMMAND) aucBuffer; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "AMP write content payload length : %d.\n", prCmd->rHeader.u2PayloadLength); -+ -+ DBGLOG(BOW, EVENT, "AMP write content header length : %d.\n", sizeof(AMPC_COMMAND_HEADER_T)); -+#endif -+ -+ /* size check */ -+ if (prCmd->rHeader.u2PayloadLength + sizeof(AMPC_COMMAND_HEADER_T) != size) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Wrong CMD total length.\n"); -+#endif -+ -+ return -EINVAL; -+ } -+ -+ if (wlanbowHandleCommand(prGlueInfo->prAdapter, prCmd) == WLAN_STATUS_SUCCESS) -+ return size; -+ else -+ return -EINVAL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief ioctl handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static long mt6620_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg) -+{ -+ int err = 0; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); -+ -+ ASSERT(prGlueInfo); -+ -+ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) -+ return -EFAULT; -+ /* permission check */ -+ if (_IOC_DIR(cmd) & _IOC_READ) -+ err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); -+ else if (_IOC_DIR(cmd) & _IOC_WRITE) -+ err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); -+ if (err) -+ return -EFAULT; -+ -+ /* no ioctl is implemented yet */ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief ioctl handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static unsigned int mt6620_ampc_poll(IN struct file *filp, IN poll_table *wait) -+{ -+ unsigned int retval; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); -+ -+ ASSERT(prGlueInfo); -+ -+ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) -+ return -EFAULT; -+ -+ poll_wait(filp, &prGlueInfo->rBowInfo.outq, wait); -+ -+ retval = (POLLOUT | POLLWRNORM); /* always accepts incoming command packets */ -+ -+/* DBGLOG(BOW, EVENT, ("mt6620_ampc_pol, POLLOUT | POLLWRNORM, %x\n", retval)); */ -+ -+/* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) > 0) */ -+ if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) > 0) { -+ retval |= (POLLIN | POLLRDNORM); -+ -+/* DBGLOG(BOW, EVENT, ("mt6620_ampc_pol, POLLIN | POLLRDNORM, %x\n", retval)); */ -+ -+ } -+ -+ return retval; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief open handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int mt6620_ampc_open(IN struct inode *inodep, IN struct file *filp) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_GL_BOW_INFO prBowInfo; -+ -+ prBowInfo = container_of(inodep->i_cdev, GL_BOW_INFO, cdev); -+ ASSERT(prBowInfo); -+ -+ prGlueInfo = container_of(prBowInfo, GLUE_INFO_T, rBowInfo); -+ ASSERT(prGlueInfo); -+ -+ /* set-up private data */ -+ filp->private_data = prGlueInfo; -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief close handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int mt6620_ampc_release(IN struct inode *inodep, IN struct file *filp) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); -+ -+ ASSERT(prGlueInfo); -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to indicate event for Bluetooth over Wi-Fi -+* -+* \param[in] -+* prGlueInfo -+* prEvent -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalIndicateBOWEvent(IN P_GLUE_INFO_T prGlueInfo, IN P_AMPC_EVENT prEvent) -+{ -+ size_t u4AvailSize, u4EventSize; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prEvent); -+ -+ /* check device */ -+ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) -+ return; -+ -+/* u4AvailSize = -+ GLUE_BOW_KFIFO_DEPTH - kfifo_len(prGlueInfo->rBowInfo.prKfifo);*/ -+ -+ u4AvailSize = GLUE_BOW_KFIFO_DEPTH - kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)); -+ -+ u4EventSize = prEvent->rHeader.u2PayloadLength + sizeof(AMPC_EVENT_HEADER_T); -+ -+ /* check kfifo availability */ -+ if (u4AvailSize < u4EventSize) { -+ DBGLOG(BOW, EVENT, "[bow] no space for event: %zu/%zu\n", u4EventSize, u4AvailSize); -+ return; -+ } -+ /* queue into kfifo */ -+/* kfifo_put(prGlueInfo->rBowInfo.prKfifo, (PUINT_8)prEvent, u4EventSize); */ -+/* kfifo_in(prGlueInfo->rBowInfo.prKfifo, (PUINT_8)prEvent, u4EventSize); */ -+ kfifo_in(&(prGlueInfo->rBowInfo.rKfifo), (PUINT_8) prEvent, u4EventSize); -+ wake_up_interruptible(&(prGlueInfo->rBowInfo.outq)); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi state from glue layer -+* -+* \param[in] -+* prGlueInfo -+* rPeerAddr -+* \return -+* ENUM_BOW_DEVICE_STATE -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_BOW_DEVICE_STATE kalGetBowState(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 aucPeerAddress[6]) -+{ -+ UINT_8 i; -+ -+ ASSERT(prGlueInfo); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalGetBowState.\n"); -+#endif -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr, aucPeerAddress) == 0) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalGetBowState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", i, -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], -+ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "kalGetBowState, prGlueInfo->rBowInfo.aeState %x, %x.\n", i, -+ prGlueInfo->rBowInfo.aeState[i]); -+ -+#endif -+ -+ return prGlueInfo->rBowInfo.aeState[i]; -+ } -+ } -+ -+ return BOW_DEVICE_STATE_DISCONNECTED; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set Bluetooth-over-Wi-Fi state in glue layer -+* -+* \param[in] -+* prGlueInfo -+* eBowState -+* rPeerAddr -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalSetBowState(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_BOW_DEVICE_STATE eBowState, IN UINT_8 aucPeerAddress[6]) -+{ -+ UINT_8 i; -+ -+ ASSERT(prGlueInfo); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalSetBowState.\n"); -+ -+ DBGLOG(BOW, EVENT, "kalSetBowState, prGlueInfo->rBowInfo.arPeerAddr, %x:%x:%x:%x:%x:%x.\n", -+ prGlueInfo->rBowInfo.arPeerAddr[0], -+ prGlueInfo->rBowInfo.arPeerAddr[1], -+ prGlueInfo->rBowInfo.arPeerAddr[2], -+ prGlueInfo->rBowInfo.arPeerAddr[3], -+ prGlueInfo->rBowInfo.arPeerAddr[4], prGlueInfo->rBowInfo.arPeerAddr[5])); -+ -+ DBGLOG(BOW, EVENT, "kalSetBowState, aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]); -+#endif -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr, aucPeerAddress) == 0) { -+ prGlueInfo->rBowInfo.aeState[i] = eBowState; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalSetBowState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", i, -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], -+ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "kalSetBowState, prGlueInfo->rBowInfo.aeState %x, %x.\n", i, -+ prGlueInfo->rBowInfo.aeState[i]); -+#endif -+ -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi global state -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* BOW_DEVICE_STATE_DISCONNECTED -+* in case there is no BoW connection or -+* BoW connection under initialization -+* -+* BOW_DEVICE_STATE_STARTING -+* in case there is no BoW connection but -+* some BoW connection under initialization -+* -+* BOW_DEVICE_STATE_CONNECTED -+* in case there is any BoW connection available -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_BOW_DEVICE_STATE kalGetBowGlobalState(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ UINT_32 i; -+ -+ ASSERT(prGlueInfo); -+ -+/* Henry, can reduce this logic to indentify state change */ -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_CONNECTED) -+ return BOW_DEVICE_STATE_CONNECTED; -+ } -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_STARTING) -+ return BOW_DEVICE_STATE_STARTING; -+ } -+ -+ return BOW_DEVICE_STATE_DISCONNECTED; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi operating frequency -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* in unit of KHz -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetBowFreqInKHz(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->rBowInfo.u4FreqInKHz; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi role -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* 0: Responder -+* 1: Initiator -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 kalGetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr) -+{ -+ UINT_32 i; -+ -+ ASSERT(prGlueInfo); -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr[i], rPeerAddr) == 0) -+ return prGlueInfo->rBowInfo.aucRole[i]; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set Bluetooth-over-Wi-Fi role -+* -+* \param[in] -+* prGlueInfo -+* ucRole -+* 0: Responder -+* 1: Initiator -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalSetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRole, IN PARAM_MAC_ADDRESS rPeerAddr) -+{ -+ UINT_32 i; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(ucRole <= 1); -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr[i], rPeerAddr) == 0) -+ prGlueInfo->rBowInfo.aucRole[i] = ucRole; /* Henry, 0 : Responder, 1 : Initiator */ -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to get available Bluetooth-over-Wi-Fi physical link number -+* -+* \param[in] -+* prGlueInfo -+* \return -+* UINT_32 -+* how many physical links are aviailable -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 kalGetBowAvailablePhysicalLinkCount(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ UINT_8 i; -+ UINT_8 ucLinkCount = 0; -+ -+ ASSERT(prGlueInfo); -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_DISCONNECTED) -+ ucLinkCount++; -+ } -+ -+#if 0 /* CFG_BOW_TEST */ -+ DBGLOG(BOW, EVENT, "kalGetBowAvailablePhysicalLinkCount, ucLinkCount, %c.\n", ucLinkCount); -+#endif -+ -+ return ucLinkCount; -+} -+ -+#if CFG_BOW_SEPARATE_DATA_PATH -+ -+/* Net Device Hooks */ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A function for net_device open (ifup) -+ * -+ * \param[in] prDev Pointer to struct net_device. -+ * -+ * \retval 0 The execution succeeds. -+ * \retval < 0 The execution failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+static int bowOpen(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* 2. carrier on & start TX queue */ -+ netif_carrier_on(prDev); -+ netif_tx_start_all_queues(prDev); -+ -+ return 0; /* success */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A function for net_device stop (ifdown) -+ * -+ * \param[in] prDev Pointer to struct net_device. -+ * -+ * \retval 0 The execution succeeds. -+ * \retval < 0 The execution failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+static int bowStop(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* 1. stop TX queue */ -+ netif_tx_stop_all_queues(prDev); -+ -+ /* 2. turn of carrier */ -+ if (netif_carrier_ok(prDev)) -+ netif_carrier_off(prDev); -+ -+ return 0; -+}; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief This function is TX entry point of NET DEVICE. -+ * -+ * \param[in] prSkb Pointer of the sk_buff to be sent -+ * \param[in] prDev Pointer to struct net_device -+ * -+ * \retval NETDEV_TX_OK - on success. -+ * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. -+ */ -+/*----------------------------------------------------------------------------*/ -+static int bowHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ P_QUE_ENTRY_T prQueueEntry = NULL; -+ P_QUE_T prTxQueue = NULL; -+ UINT_16 u2QueueIdx = 0; -+ UINT_8 ucDSAP, ucSSAP, ucControl; -+ UINT_8 aucOUI[3]; -+ PUINT_8 aucLookAheadBuf = NULL; -+ -+#if CFG_BOW_TEST -+ UINT_32 i; -+#endif -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prSkb); -+ ASSERT(prDev); -+ ASSERT(prGlueInfo); -+ -+ aucLookAheadBuf = prSkb->data; -+ -+ ucDSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET]; -+ ucSSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 1]; -+ ucControl = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 2]; -+ aucOUI[0] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET]; -+ aucOUI[1] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1]; -+ aucOUI[2] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2]; -+ prGlueInfo->u8SkbToDriver++; -+ -+ if (!(ucDSAP == ETH_LLC_DSAP_SNAP && -+ ucSSAP == ETH_LLC_SSAP_SNAP && -+ ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION && -+ aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 && -+ aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 && aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) || (prSkb->len > 1514)) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, "Invalid BOW packet, skip tx\n"); -+#endif -+ -+ dev_kfree_skb(prSkb); -+ prGlueInfo->u8SkbFreed++; -+ return NETDEV_TX_OK; -+ } -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ DBGLOG(BOW, TRACE, "GLUE_FLAG_HALT skip tx\n"); -+ dev_kfree_skb(prSkb); -+ prGlueInfo->u8SkbFreed++; -+ return NETDEV_TX_OK; -+ } -+ -+ prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); -+ prTxQueue = &prGlueInfo->rTxQueue; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, "Tx sk_buff->len: %d\n", prSkb->len); -+ DBGLOG(BOW, TRACE, "Tx sk_buff->data_len: %d\n", prSkb->data_len); -+ DBGLOG(BOW, TRACE, "Tx sk_buff->data:\n"); -+ -+ for (i = 0; i < prSkb->len; i++) { -+ DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]); -+ -+ if ((i + 1) % 16 == 0) -+ DBGLOG(BOW, TRACE, "\n"); -+ } -+ -+ DBGLOG(BOW, TRACE, "\n"; -+#endif -+#if CFG_BOW_TEST -+/* g_u4CurrentSysTime = (OS_SYSTIME)kalGetTimeTick(; */ -+ g_u4CurrentSysTime = (OS_SYSTIME) jiffies_to_usecs(jiffies); -+ i = g_u4CurrentSysTime - g_u4PrevSysTime; -+ if ((i >> 10) > 0) -+ i = 10; -+ else -+ i = i >> 7; -+ g_arBowRevPalPacketTime[i]++; -+ g_u4PrevSysTime = g_u4CurrentSysTime; -+#endif -+ if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) { -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); -+ GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx]); -+ if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx] >= -+ CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) -+ DBGLOG(TX, INFO, "netif_stop_subqueue for BOW, Queue len: %d\n", -+ prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx]); -+ -+ netif_stop_subqueue(prDev, u2QueueIdx); -+ } else { -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); -+ } -+ -+ kalSetEvent(prGlueInfo); -+ /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */ -+ return NETDEV_TX_OK; -+} -+ -+/* callbacks for netdevice */ -+static const struct net_device_ops bow_netdev_ops = { -+ .ndo_open = bowOpen, .ndo_stop = bowStop, .ndo_start_xmit = bowHardStartXmit,}; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief initialize net device for Bluetooth-over-Wi-Fi -+* -+* \param[in] -+* prGlueInfo -+* prDevName -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalInitBowDevice(IN P_GLUE_INFO_T prGlueInfo, IN const char *prDevName) -+{ -+ P_ADAPTER_T prAdapter; -+ P_GL_HIF_INFO_T prHif; -+ PARAM_MAC_ADDRESS rMacAddr; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prGlueInfo->rBowInfo.fgIsRegistered == TRUE); -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ prHif = &prGlueInfo->rHifInfo; -+ ASSERT(prHif); -+ if (prGlueInfo->rBowInfo.fgIsNetRegistered == FALSE) { -+ prGlueInfo->rBowInfo.prDevHandler = -+ alloc_netdev_mq(sizeof(P_GLUE_INFO_T), prDevName, NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); -+ if (!prGlueInfo->rBowInfo.prDevHandler) -+ return FALSE; -+ -+ /* 1. setup netdev */ -+ /* 1.1 Point to shared glue structure */ -+ *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->rBowInfo.prDevHandler)) = prGlueInfo; -+ /* 1.2 fill hardware address */ -+ COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); -+ rMacAddr[0] |= 0x2; -+ /* change to local administrated address */ -+ ether_addr_copy(prGlueInfo->rBowInfo.prDevHandler->dev_addr, rMacAddr); -+ ether_addr_copy(prGlueInfo->rBowInfo.prDevHandler->perm_addr, -+ prGlueInfo->rBowInfo.prDevHandler->dev_addr); -+ /* 1.3 register callback functions */ -+ prGlueInfo->rBowInfo.prDevHandler->netdev_ops = &bow_netdev_ops; -+#if (MTK_WCN_HIF_SDIO == 0) -+ SET_NETDEV_DEV(prGlueInfo->rBowInfo.prDevHandler, prHif->Dev); -+#endif -+ register_netdev(prGlueInfo->rBowInfo.prDevHandler); -+ /* 2. net device initialize */ -+ netif_carrier_off(prGlueInfo->rBowInfo.prDevHandler); -+ netif_tx_stop_all_queues(prGlueInfo->rBowInfo.prDevHandler); -+ /* 3. finish */ -+ prGlueInfo->rBowInfo.fgIsNetRegistered = TRUE; -+ } -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief uninitialize net device for Bluetooth-over-Wi-Fi -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalUninitBowDevice(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ /* ASSERT(prGlueInfo->rBowInfo.fgIsRegistered == TRUE); */ -+ if (prGlueInfo->rBowInfo.fgIsNetRegistered == TRUE) { -+ prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE; -+ if (netif_carrier_ok(prGlueInfo->rBowInfo.prDevHandler)) -+ netif_carrier_off(prGlueInfo->rBowInfo.prDevHandler); -+ -+ netif_tx_stop_all_queues(prGlueInfo->rBowInfo.prDevHandler); -+ /* netdevice unregistration & free */ -+ unregister_netdev(prGlueInfo->rBowInfo.prDevHandler); -+ free_netdev(prGlueInfo->rBowInfo.prDevHandler); -+ prGlueInfo->rBowInfo.prDevHandler = NULL; -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+} -+#endif /* CFG_BOW_SEPARATE_DATA_PATH */ -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c -new file mode 100644 -index 0000000000000..1fed65ebc60e6 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c -@@ -0,0 +1,3110 @@ -+/* -+** Id: @(#) gl_cfg80211.c@@ -+*/ -+ -+/*! \file gl_cfg80211.c -+ \brief Main routines for supporintg MT6620 cfg80211 control interface -+ -+ This file contains the support routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_cfg80211.c -+** -+** 09 05 2013 cp.wu -+** correct length to pass to wlanoidSetBssid() -+** -+** 09 04 2013 cp.wu -+** fix typo -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+** -+** 11 23 2012 yuche.tsai -+** [ALPS00398671] [Acer-Tablet] Remove Wi-Fi Direct completely -+** Fix bug of WiFi may reboot under user load, when WiFi Direct is removed.. -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 30 2012 chinglan.wang -+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only -+** . -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_os.h" -+#include "debug.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include "precomp.h" -+#include -+#include -+#include -+#include "gl_cfg80211.h" -+#include "gl_vendor.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/* workaround for some ANR CRs. if suppliant is blocked longer than 10s, wifi hal will tell wifiMonitor -+to teminate. for the case which can block supplicant 10s is to del key more than 5 times. the root cause -+is that there is no resource in TC4, so del key command was not able to set, and then oid -+timeout was happed. if we found the root cause why fw couldn't release TC resouce, we will remove this -+workaround */ -+static UINT_8 gucKeyIndex = 255; -+ -+P_SW_RFB_T g_arGscnResultsTempBuffer[MAX_BUFFERED_GSCN_RESULTS]; -+UINT_8 g_GscanResultsTempBufferIndex = 0; -+UINT_8 g_arGscanResultsIndicateNumber[MAX_BUFFERED_GSCN_RESULTS] = { 0, 0, 0, 0, 0 }; -+ -+UINT_8 g_GetResultsBufferedCnt = 0; -+UINT_8 g_GetResultsCmdCnt = 0; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for change STA type between -+ * 1. Infrastructure Client (Non-AP STA) -+ * 2. Ad-Hoc IBSS -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_cfg80211_change_iface(struct wiphy *wiphy, -+ struct net_device *ndev, enum nl80211_iftype type, /*u32 *flags,*/ struct vif_params *params) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ UINT_32 u4BufLen; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ if (type == NL80211_IFTYPE_STATION) -+ eOpMode = NET_TYPE_INFRA; -+ else if (type == NL80211_IFTYPE_ADHOC) -+ eOpMode = NET_TYPE_IBSS; -+ else -+ return -EINVAL; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetInfrastructureMode, -+ &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, WARN, "set infrastructure mode error:%x\n", rStatus); -+ -+ /* reset wpa info */ -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+#if CFG_SUPPORT_802_11W -+ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; -+#endif -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for adding key -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_cfg80211_add_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) -+{ -+ PARAM_KEY_T rKey; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ INT_32 i4Rslt = -EINVAL; -+ UINT_32 u4BufLen = 0; -+ UINT_8 tmp1[8]; -+ UINT_8 tmp2[8]; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemZero(&rKey, sizeof(PARAM_KEY_T)); -+ -+ rKey.u4KeyIndex = key_index; -+ -+ if (mac_addr) { -+ COPY_MAC_ADDR(rKey.arBSSID, mac_addr); -+ if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) && -+ (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) { -+ rKey.arBSSID[0] = 0xff; -+ rKey.arBSSID[1] = 0xff; -+ rKey.arBSSID[2] = 0xff; -+ rKey.arBSSID[3] = 0xff; -+ rKey.arBSSID[4] = 0xff; -+ rKey.arBSSID[5] = 0xff; -+ } -+ if (rKey.arBSSID[0] != 0xFF) { -+ rKey.u4KeyIndex |= BIT(31); -+ if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) || -+ (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00)) -+ rKey.u4KeyIndex |= BIT(30); -+ } -+ } else { -+ rKey.arBSSID[0] = 0xff; -+ rKey.arBSSID[1] = 0xff; -+ rKey.arBSSID[2] = 0xff; -+ rKey.arBSSID[3] = 0xff; -+ rKey.arBSSID[4] = 0xff; -+ rKey.arBSSID[5] = 0xff; -+ /* rKey.u4KeyIndex |= BIT(31);//Enable BIT 31 will make tx use bc key id,should use pairwise key id 0 */ -+ } -+ -+ if (params->key) { -+ /* rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE); */ -+ kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len); -+ if (params->key_len == 32) { -+ kalMemCopy(tmp1, ¶ms->key[16], 8); -+ kalMemCopy(tmp2, ¶ms->key[24], 8); -+ kalMemCopy(&rKey.aucKeyMaterial[16], tmp2, 8); -+ kalMemCopy(&rKey.aucKeyMaterial[24], tmp1, 8); -+ } -+ } -+ -+ rKey.u4KeyLength = params->key_len; -+ rKey.u4Length = ((ULONG)&(((P_P2P_PARAM_KEY_T) 0)->aucKeyMaterial)) + rKey.u4KeyLength; -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetAddKey, &rKey, rKey.u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus == WLAN_STATUS_SUCCESS) -+ i4Rslt = 0; -+ -+ return i4Rslt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for getting key for specified STA -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_cfg80211_get_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, -+ bool pairwise, -+ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *)) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ /* not implemented */ -+ -+ return -EINVAL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for removing key for specified STA -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ PARAM_REMOVE_KEY_T rRemoveKey; -+ UINT_32 u4BufLen = 0; -+ INT_32 i4Rslt = -EINVAL; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemZero(&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T)); -+ if (mac_addr) -+ COPY_MAC_ADDR(rRemoveKey.arBSSID, mac_addr); -+ else if (key_index <= gucKeyIndex) { /* new operation, reset gucKeyIndex */ -+ gucKeyIndex = 255; -+ } else { /* bypass the next remove key operation */ -+ gucKeyIndex = key_index; -+ return -EBUSY; -+ } -+ rRemoveKey.u4KeyIndex = key_index; -+ rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRemoveKey, &rRemoveKey, rRemoveKey.u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "remove key error:%x\n", rStatus); -+ if (WLAN_STATUS_FAILURE == rStatus && mac_addr) { -+ i4Rslt = -EBUSY; -+ gucKeyIndex = key_index; -+ } -+ } else { -+ gucKeyIndex = 255; -+ i4Rslt = 0; -+ } -+ -+ return i4Rslt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for setting default key on an interface -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool unicast, bool multicast) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ /* not implemented */ -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for setting set_default_mgmt_ke on an interface -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index) -+{ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for getting station information such as RSSI -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac, struct station_info *sinfo) -+{ -+#define LINKSPEED_MAX_RANGE_11BGN 3000 -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ PARAM_MAC_ADDRESS arBssid; -+ UINT_32 u4BufLen; -+ UINT_32 u4Rate = 0; -+ UINT_32 u8diffTxBad, u8diffRetry; -+ INT_32 i4Rssi = 0; -+ PARAM_802_11_STATISTICS_STRUCT_T rStatistics; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemZero(arBssid, MAC_ADDR_LEN); -+ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen); -+ -+ /* 1. check BSSID */ -+ if (UNEQUAL_MAC_ADDR(arBssid, mac)) { -+ /* wrong MAC address */ -+ DBGLOG(REQ, WARN, "incorrect BSSID: [ %pM ] currently connected BSSID[ %pM ]\n", -+ mac, arBssid); -+ return -ENOENT; -+ } -+ -+ /* 2. fill TX rate */ -+ if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) { -+ /* not connected */ -+ DBGLOG(REQ, WARN, "not yet connected\n"); -+ } else { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryLinkSpeed, &u4Rate, sizeof(u4Rate), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); -+ -+ if ((rStatus != WLAN_STATUS_SUCCESS) || (u4Rate == 0)) { -+ /* DBGLOG(REQ, WARN, "unable to retrieve link speed\n")); */ -+ DBGLOG(REQ, WARN, "last link speed\n"); -+ sinfo->txrate.legacy = prGlueInfo->u4LinkSpeedCache; -+ } else { -+ /* sinfo->filled |= STATION_INFO_TX_BITRATE; */ -+ sinfo->txrate.legacy = u4Rate / 1000; /* convert from 100bps to 100kbps */ -+ prGlueInfo->u4LinkSpeedCache = u4Rate / 1000; -+ } -+ } -+ -+ /* 3. fill RSSI */ -+ if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) { -+ /* not connected */ -+ DBGLOG(REQ, WARN, "not yet connected\n"); -+ } else { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryRssi, &i4Rssi, sizeof(i4Rssi), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS || (i4Rssi == PARAM_WHQL_RSSI_MIN_DBM) -+ || (i4Rssi == PARAM_WHQL_RSSI_MAX_DBM)) { -+ /* DBGLOG(REQ, WARN, "unable to retrieve link speed\n"); */ -+ DBGLOG(REQ, WARN, "last rssi\n"); -+ sinfo->signal = prGlueInfo->i4RssiCache; -+ } else { -+ /* in the cfg80211 layer, the signal is a signed char variable. */ -+ sinfo->signal = i4Rssi; /* dBm */ -+ prGlueInfo->i4RssiCache = i4Rssi; -+ } -+ sinfo->rx_packets = prGlueInfo->rNetDevStats.rx_packets; -+ -+ /* 4. Fill Tx OK and Tx Bad */ -+ -+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS); -+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED); -+ { -+ WLAN_STATUS rStatus; -+ -+ kalMemZero(&rStatistics, sizeof(rStatistics)); -+ /* Get Tx OK/Fail cnt from AIS statistic counter */ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStatisticsPL, -+ &rStatistics, sizeof(rStatistics), TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "unable to retrieive statistic\n"); -+ } else { -+ INT_32 i4RssiThreshold = -85; /* set rssi threshold -85dBm */ -+ UINT_32 u4LinkspeedThreshold = 55; /* set link speed threshold 5.5Mbps */ -+ BOOLEAN fgWeighted = 0; -+ -+ /* calculate difference */ -+ u8diffTxBad = rStatistics.rFailedCount.QuadPart - prGlueInfo->u8Statistic[0]; -+ u8diffRetry = rStatistics.rRetryCount.QuadPart - prGlueInfo->u8Statistic[1]; -+ /* restore counters */ -+ prGlueInfo->u8Statistic[0] = rStatistics.rFailedCount.QuadPart; -+ prGlueInfo->u8Statistic[1] = rStatistics.rRetryCount.QuadPart; -+ -+ /* check threshold is valid */ -+ if (prGlueInfo->fgPoorlinkValid) { -+ if (prGlueInfo->i4RssiThreshold) -+ i4RssiThreshold = prGlueInfo->i4RssiThreshold; -+ if (prGlueInfo->u4LinkspeedThreshold) -+ u4LinkspeedThreshold = prGlueInfo->u4LinkspeedThreshold; -+ } -+ /* add weighted to fail counter */ -+ if (sinfo->txrate.legacy < u4LinkspeedThreshold || sinfo->signal < i4RssiThreshold) { -+ prGlueInfo->u8TotalFailCnt += (u8diffTxBad * 16 + u8diffRetry); -+ fgWeighted = 1; -+ } else { -+ prGlueInfo->u8TotalFailCnt += u8diffTxBad; -+ } -+ /* report counters */ -+ prGlueInfo->rNetDevStats.tx_packets = rStatistics.rTransmittedFragmentCount.QuadPart; -+ prGlueInfo->rNetDevStats.tx_errors = prGlueInfo->u8TotalFailCnt; -+ -+ sinfo->tx_packets = prGlueInfo->rNetDevStats.tx_packets; -+ sinfo->tx_failed = prGlueInfo->rNetDevStats.tx_errors; -+ /* Good Fail Bad Difference retry difference Linkspeed Rate Weighted */ -+ DBGLOG(REQ, TRACE, -+ "Poorlink State TxOK(%d) TxFail(%d) Bad(%d) Retry(%d)", -+ sinfo->tx_packets, -+ sinfo->tx_failed, -+ (int)u8diffTxBad, -+ (int)u8diffRetry); -+ DBGLOG(REQ, TRACE, -+ "Rate(%d) Signal(%d) Weight(%d) QuadPart(%d)\n", -+ sinfo->txrate.legacy, -+ sinfo->signal, -+ (int)fgWeighted, -+ (int)rStatistics.rMultipleRetryCount.QuadPart); -+ } -+ } -+ -+ } -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for adding a station information -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_parameters *params) -+{ -+#if (CFG_SUPPORT_TDLS == 1) -+ /* -+ EX: In supplicant, -+ (Supplicant) wpa_tdls_process_tpk_m3() -> -+ (Supplicant) wpa_tdls_enable_link() -> -+ (Supplicant) wpa_sm_tdls_peer_addset() -> -+ (Supplicant) ..tdls_peer_addset() -> -+ (Supplicant) wpa_supplicant_tdls_peer_addset() -> -+ (Supplicant) wpa_drv_sta_add() -> -+ (Supplicant) ..sta_add() -> -+ (Supplicant) wpa_driver_nl80211_sta_add() -> -+ (NL80211) nl80211_set_station() -> -+ (Driver) mtk_cfg80211_change_station() -+ -+ if nl80211_set_station fails, supplicant will tear down the link. -+ */ -+ P_GLUE_INFO_T prGlueInfo; -+ TDLS_CMD_PEER_UPDATE_T rCmdUpdate; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen, u4Temp; -+ -+ /* sanity check */ -+ if ((wiphy == NULL) || (mac == NULL) || (params == NULL)) -+ return -EINVAL; -+ -+ DBGLOG(TDLS, INFO, "%s: 0x%p 0x%x\n", __func__, params->supported_rates, params->sta_flags_set); -+ -+ if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) -+ return -EOPNOTSUPP; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ if (prGlueInfo == NULL) -+ return -EINVAL; -+ -+ /* TODO: check if we are station mode, not AP mode */ -+ -+ /* init */ -+ kalMemZero(&rCmdUpdate, sizeof(rCmdUpdate)); -+ kalMemCopy(rCmdUpdate.aucPeerMac, mac, 6); -+ -+ if (params->supported_rates != NULL) { -+ u4Temp = params->supported_rates_len; -+ if (u4Temp > TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX) { -+ u4Temp = TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX; -+ DBGLOG(TDLS, ERROR, "%s sup rate too long: %d\n", __func__, params->supported_rates_len); -+ } -+ kalMemCopy(rCmdUpdate.aucSupRate, params->supported_rates, u4Temp); -+ rCmdUpdate.u2SupRateLen = u4Temp; -+ } -+ -+ /* -+ In supplicant, only recognize WLAN_EID_QOS 46, not 0xDD WMM -+ So force to support UAPSD here. -+ */ -+ rCmdUpdate.UapsdBitmap = 0x0F; /*params->uapsd_queues; */ -+ rCmdUpdate.UapsdMaxSp = 0; /*params->max_sp; */ -+ -+ DBGLOG(TDLS, INFO, "%s: UapsdBitmap=0x%x UapsdMaxSp=%d\n", -+ __func__, rCmdUpdate.UapsdBitmap, rCmdUpdate.UapsdMaxSp); -+ -+ rCmdUpdate.u2Capability = params->capability; -+ -+ if (params->ext_capab != NULL) { -+ u4Temp = params->ext_capab_len; -+ if (u4Temp > TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN) { -+ u4Temp = TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN; -+ DBGLOG(TDLS, ERROR, "%s ext_capab too long: %d\n", __func__, params->ext_capab_len); -+ } -+ kalMemCopy(rCmdUpdate.aucExtCap, params->ext_capab, u4Temp); -+ rCmdUpdate.u2ExtCapLen = u4Temp; -+ } -+ -+ if (params->ht_capa != NULL) { -+ DBGLOG(TDLS, INFO, "%s: peer is 11n device\n", __func__); -+ -+ rCmdUpdate.rHtCap.u2CapInfo = params->ht_capa->cap_info; -+ rCmdUpdate.rHtCap.ucAmpduParamsInfo = params->ht_capa->ampdu_params_info; -+ rCmdUpdate.rHtCap.u2ExtHtCapInfo = params->ht_capa->extended_ht_cap_info; -+ rCmdUpdate.rHtCap.u4TxBfCapInfo = params->ht_capa->tx_BF_cap_info; -+ rCmdUpdate.rHtCap.ucAntennaSelInfo = params->ht_capa->antenna_selection_info; -+ kalMemCopy(rCmdUpdate.rHtCap.rMCS.arRxMask, -+ params->ht_capa->mcs.rx_mask, sizeof(rCmdUpdate.rHtCap.rMCS.arRxMask)); -+ rCmdUpdate.rHtCap.rMCS.u2RxHighest = params->ht_capa->mcs.rx_highest; -+ rCmdUpdate.rHtCap.rMCS.ucTxParams = params->ht_capa->mcs.tx_params; -+ rCmdUpdate.fgIsSupHt = TRUE; -+ } -+ -+ /* update a TDLS peer record */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsexPeerUpdate, -+ &rCmdUpdate, sizeof(TDLS_CMD_PEER_UPDATE_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s update error:%x\n", __func__, rStatus); -+ return -EINVAL; -+ } -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for adding a station information -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_add_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_parameters *params) -+{ -+#if (CFG_SUPPORT_TDLS == 1) -+ /* from supplicant -- wpa_supplicant_tdls_peer_addset() */ -+ P_GLUE_INFO_T prGlueInfo; -+ TDLS_CMD_PEER_ADD_T rCmdCreate; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ -+ if ((wiphy == NULL) || (mac == NULL) || (params == NULL)) -+ return -EINVAL; -+ -+ /* -+ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, -+ NULL, 0); -+ -+ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add, -+ u16 aid, u16 capability, const u8 *supp_rates, -+ size_t supp_rates_len, -+ const struct ieee80211_ht_capabilities *ht_capab, -+ const struct ieee80211_vht_capabilities *vht_capab, -+ u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len) -+ -+ Only MAC address of the peer is valid. -+ */ -+ -+ DBGLOG(TDLS, INFO, "%s: 0x%p %d\n", __func__, params->supported_rates, params->supported_rates_len); -+ -+ /* sanity check */ -+ if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) -+ return -EOPNOTSUPP; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ if (prGlueInfo == NULL) -+ return -EINVAL; -+ -+ /* TODO: check if we are station mode, not AP mode */ -+ -+ /* init */ -+ kalMemZero(&rCmdCreate, sizeof(rCmdCreate)); -+ kalMemCopy(rCmdCreate.aucPeerMac, mac, 6); -+ -+#if 0 -+ rCmdCreate.eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ -+ rCmdCreate.u2CapInfo = params->capability; -+ -+ DBGLOG(TDLS, INFO, " %s: capability = 0x%x\n", __func__, rCmdCreate.u2CapInfo); -+ -+ if ((params->supported_rates != NULL) && (params->supported_rates_len != 0)) { -+ UINT32 u4Idx; -+ -+ DBGLOG(TDLS, INFO, " %s: sup rate = 0x", __func__); -+ -+ rIeSup.ucId = ELEM_ID_SUP_RATES; -+ rIeSup.ucLength = params->supported_rates_len; -+ for (u4Idx = 0; u4Idx < rIeSup.ucLength; u4Idx++) { -+ rIeSup.aucSupportedRates[u4Idx] = params->supported_rates[u4Idx]; -+ DBGLOG(TDLS, INFO, "%x ", rIeSup.aucSupportedRates[u4Idx]); -+ } -+ DBGLOG(TDLS, INFO, "\n"); -+ -+ rateGetRateSetFromIEs(&rIeSup, -+ NULL, -+ &rCmdCreate.u2OperationalRateSet, -+ &rCmdCreate.u2BSSBasicRateSet, &rCmdCreate.fgIsUnknownBssBasicRate); -+ } -+ -+ /* phy type */ -+#endif -+ -+ /* create a TDLS peer record */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsexPeerAdd, -+ &rCmdCreate, sizeof(TDLS_CMD_PEER_ADD_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s create error:%x\n", __func__, rStatus); -+ return -EINVAL; -+ } -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for deleting a station information -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ * -+ * @other -+ * must implement if you have add_station(). -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, struct station_del_parameters *params) -+//int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac) -+{ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to do a scan -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+static PARAM_SCAN_REQUEST_EXT_T rScanRequest; -+int mtk_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+/* PARAM_SCAN_REQUEST_EXT_T rScanRequest; */ -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "mtk_cfg80211_scan\n"); -+ kalMemZero(&rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T)); -+ -+ /* check if there is any pending scan not yet finished */ -+ if (prGlueInfo->prScanRequest != NULL) { -+ DBGLOG(REQ, ERROR, "prGlueInfo->prScanRequest != NULL\n"); -+ return -EBUSY; -+ } -+ -+ if (request->n_ssids == 0) { -+ rScanRequest.rSsid.u4SsidLen = 0; -+ } else if (request->n_ssids == 1) { -+ COPY_SSID(rScanRequest.rSsid.aucSsid, rScanRequest.rSsid.u4SsidLen, request->ssids[0].ssid, -+ request->ssids[0].ssid_len); -+ } else { -+ DBGLOG(REQ, ERROR, "request->n_ssids:%d\n", request->n_ssids); -+ return -EINVAL; -+ } -+ -+ if (request->ie_len > 0) { -+ rScanRequest.u4IELength = request->ie_len; -+ rScanRequest.pucIE = (PUINT_8) (request->ie); -+ } else { -+ rScanRequest.u4IELength = 0; -+ } -+#if 0 -+ prGlueInfo->prScanRequest = request; -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetBssidListScanExt, -+ &rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "scan error:%x\n", rStatus); -+ prGlueInfo->prScanRequest = NULL; -+ return -EINVAL; -+ } -+ -+ /*prGlueInfo->prScanRequest = request;*/ -+#endif -+ -+ prGlueInfo->prScanRequest = request; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetBssidListScanExt, -+ &rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ prGlueInfo->prScanRequest = NULL; -+ DBGLOG(REQ, ERROR, "scan error:%x\n", rStatus); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static UINT_8 wepBuf[48]; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to connect to -+ * the ESS with the specified parameters -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ UINT_32 cipher; -+ PARAM_CONNECT_T rNewSsid; -+ BOOLEAN fgCarryWPSIE = FALSE; -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "[wlan] mtk_cfg80211_connect %p %zu\n", sme->ie, sme->ie_len); -+ -+ if (prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode > NET_TYPE_AUTO_SWITCH) -+ eOpMode = NET_TYPE_AUTO_SWITCH; -+ else -+ eOpMode = prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetInfrastructureMode, -+ &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetInfrastructureMode fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ /* after set operation mode, key table are cleared */ -+ -+ /* reset wpa info */ -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+#if CFG_SUPPORT_802_11W -+ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; -+#endif -+ -+ if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA; -+ else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA2; -+ else -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ -+ switch (sme->auth_type) { -+ case NL80211_AUTHTYPE_OPEN_SYSTEM: -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+ break; -+ case NL80211_AUTHTYPE_SHARED_KEY: -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY; -+ break; -+ default: -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY; -+ break; -+ } -+ -+ if (sme->crypto.n_ciphers_pairwise) { -+ prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] = -+ sme->crypto.ciphers_pairwise[0]; -+ switch (sme->crypto.ciphers_pairwise[0]) { -+ case WLAN_CIPHER_SUITE_WEP40: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP40; -+ break; -+ case WLAN_CIPHER_SUITE_WEP104: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104; -+ break; -+ case WLAN_CIPHER_SUITE_TKIP: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_TKIP; -+ break; -+ case WLAN_CIPHER_SUITE_CCMP: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP; -+ break; -+ case WLAN_CIPHER_SUITE_AES_CMAC: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP; -+ break; -+ default: -+ DBGLOG(REQ, WARN, "invalid cipher pairwise (%d)\n", sme->crypto.ciphers_pairwise[0]); -+ return -EINVAL; -+ } -+ } -+ -+ if (sme->crypto.cipher_group) { -+ prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite = sme->crypto.cipher_group; -+ switch (sme->crypto.cipher_group) { -+ case WLAN_CIPHER_SUITE_WEP40: -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP40; -+ break; -+ case WLAN_CIPHER_SUITE_WEP104: -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104; -+ break; -+ case WLAN_CIPHER_SUITE_TKIP: -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_TKIP; -+ break; -+ case WLAN_CIPHER_SUITE_CCMP: -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP; -+ break; -+ case WLAN_CIPHER_SUITE_AES_CMAC: -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP; -+ break; -+ default: -+ DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group); -+ return -EINVAL; -+ } -+ } -+ -+ if (sme->crypto.n_akm_suites) { -+ prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] = -+ sme->crypto.akm_suites[0]; -+ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) { -+ switch (sme->crypto.akm_suites[0]) { -+ case WLAN_AKM_SUITE_8021X: -+ eAuthMode = AUTH_MODE_WPA; -+ break; -+ case WLAN_AKM_SUITE_PSK: -+ eAuthMode = AUTH_MODE_WPA_PSK; -+ break; -+ default: -+ DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group); -+ return -EINVAL; -+ } -+ } else if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2) { -+ switch (sme->crypto.akm_suites[0]) { -+ case WLAN_AKM_SUITE_8021X: -+ eAuthMode = AUTH_MODE_WPA2; -+ break; -+ case WLAN_AKM_SUITE_PSK: -+ eAuthMode = AUTH_MODE_WPA2_PSK; -+ break; -+ default: -+ DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group); -+ return -EINVAL; -+ } -+ } -+ } -+ -+ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { -+ eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ? -+ AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH; -+ } -+ -+ prGlueInfo->rWpaInfo.fgPrivacyInvoke = sme->privacy; -+ -+ prGlueInfo->fgWpsActive = FALSE; -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ prGlueInfo->fgConnectHS20AP = FALSE; -+#endif -+ -+ if (sme->ie && sme->ie_len > 0) { -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ PUINT_8 prDesiredIE = NULL; -+ PUINT_8 pucIEStart = (PUINT_8)sme->ie; -+ -+#if CFG_SUPPORT_WAPI -+ if (wextSrchDesiredWAPIIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiAssocInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(SEC, WARN, "[wapi] set wapi assoc info error:%x\n", rStatus); -+ } -+#endif -+ -+ DBGLOG(REQ, TRACE, "[wlan] wlanoidSetWapiAssocInfo: .fgWapiMode = %d\n", -+ prGlueInfo->prAdapter->rWifiVar.rConnSettings.fgWapiMode); -+ -+#if CFG_SUPPORT_WPS2 -+ if (wextSrchDesiredWPSIE(pucIEStart, sme->ie_len, 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ prGlueInfo->fgWpsActive = TRUE; -+ fgCarryWPSIE = TRUE; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWSCAssocInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(SEC, WARN, "WSC] set WSC assoc info error:%x\n", rStatus); -+ } -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ if (wextSrchDesiredHS20IE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetHS20Info, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set HS20 assoc info error:%lx\n", rStatus); */ -+ } -+ } -+ if (wextSrchDesiredInterworkingIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetInterworkingInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set Interworking assoc info error:%lx\n", rStatus); */ -+ } -+ } -+ if (wextSrchDesiredRoamingConsortiumIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRoamingConsortiumIEInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus); */ -+ } -+ } -+#endif -+ } -+ -+ /* clear WSC Assoc IE buffer in case WPS IE is not detected */ -+ if (fgCarryWPSIE == FALSE) { -+ kalMemZero(&prGlueInfo->aucWSCAssocInfoIE, 200); -+ prGlueInfo->u2WSCAssocInfoIELen = 0; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAuthMode, &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, WARN, "set auth mode error:%x\n", rStatus); -+ -+ cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise; -+ -+ if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) { -+ if (cipher & IW_AUTH_CIPHER_CCMP) { -+ eEncStatus = ENUM_ENCRYPTION3_ENABLED; -+ } else if (cipher & IW_AUTH_CIPHER_TKIP) { -+ eEncStatus = ENUM_ENCRYPTION2_ENABLED; -+ } else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) { -+ eEncStatus = ENUM_ENCRYPTION1_ENABLED; -+ } else if (cipher & IW_AUTH_CIPHER_NONE) { -+ if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) -+ eEncStatus = ENUM_ENCRYPTION1_ENABLED; -+ else -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ } else { -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ } -+ } else { -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetEncryptionStatus, -+ &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, WARN, "set encryption mode error:%x\n", rStatus); -+ -+ if (sme->key_len != 0 && prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { -+ P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; -+ -+ prWepKey->u4Length = 12 + sme->key_len; -+ prWepKey->u4KeyLength = (UINT_32) sme->key_len; -+ prWepKey->u4KeyIndex = (UINT_32) sme->key_idx; -+ prWepKey->u4KeyIndex |= BIT(31); -+ if (prWepKey->u4KeyLength > 32) { -+ DBGLOG(REQ, ERROR, "Too long key length (%u)\n", prWepKey->u4KeyLength); -+ return -EINVAL; -+ } -+ kalMemCopy(prWepKey->aucKeyMaterial, sme->key, prWepKey->u4KeyLength); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAddWep, -+ prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ } -+ -+ if (sme->channel) -+ rNewSsid.u4CenterFreq = sme->channel->center_freq; -+ else -+ rNewSsid.u4CenterFreq = 0; -+ rNewSsid.pucBssid = (UINT_8 *)sme->bssid; -+ rNewSsid.pucSsid = (UINT_8 *)sme->ssid; -+ rNewSsid.u4SsidLen = sme->ssid_len; -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetConnect, -+ (PVOID)(&rNewSsid), sizeof(PARAM_CONNECT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "set SSID:%x\n", rStatus); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to disconnect from -+ * currently connected ESS -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "disassociate error:%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to join an IBSS group -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ibss_params *params) -+{ -+ PARAM_SSID_T rNewSsid; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 u4ChnlFreq; /* Store channel or frequency information */ -+ UINT_32 u4BufLen = 0; -+ WLAN_STATUS rStatus; -+ struct ieee80211_channel *channel = NULL; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ /* set channel */ -+ if (params->chandef.chan) -+ channel = params->chandef.chan; -+ if (channel) { -+ u4ChnlFreq = nicChannelNum2Freq(channel->hw_value); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetFrequency, -+ &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ } -+ -+ /* set SSID */ -+ kalMemCopy(rNewSsid.aucSsid, params->ssid, params->ssid_len); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetSsid, -+ (PVOID)(&rNewSsid), sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "set SSID:%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+ -+ return -EINVAL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to leave from IBSS group -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "disassociate error:%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to configure -+ * WLAN power managemenet -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, bool enabled, int timeout) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ PARAM_POWER_MODE ePowerMode; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ if (enabled) { -+ if (timeout == -1) -+ ePowerMode = Param_PowerModeFast_PSP; -+ else -+ ePowerMode = Param_PowerModeMAX_PSP; -+ } else { -+ ePowerMode = Param_PowerModeCAM; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSet802dot11PowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "set_power_mgmt error:%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to cache -+ * a PMKID for a BSSID -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_PARAM_PMKID_T prPmkid; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), VIR_MEM_TYPE); -+ if (!prPmkid) { -+ DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_ADD\n"); -+ return -ENOMEM; -+ } -+ -+ prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T); -+ prPmkid->u4BSSIDInfoCount = 1; -+ kalMemCopy(prPmkid->arBSSIDInfo->arBSSID, pmksa->bssid, 6); -+ kalMemCopy(prPmkid->arBSSIDInfo->arPMKID, pmksa->pmkid, IW_PMKID_LEN); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, WARN, "add pmkid error:%x\n", rStatus); -+ kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T)); -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to remove -+ * a cached PMKID for a BSSID -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa) -+{ -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to flush -+ * all cached PMKID -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_PARAM_PMKID_T prPmkid; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8, VIR_MEM_TYPE); -+ if (!prPmkid) { -+ DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_FLUSH\n"); -+ return -ENOMEM; -+ } -+ -+ prPmkid->u4Length = 8; -+ prPmkid->u4BSSIDInfoCount = 0; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, WARN, "flush pmkid error:%x\n", rStatus); -+ kalMemFree(prPmkid, VIR_MEM_TYPE, 8); -+ -+ return 0; -+} -+ -+void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, -+ IN struct wireless_dev *wdev, -+ IN u16 frame_type, IN bool reg) -+{ -+#if 0 -+ P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL; -+#endif -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ do { -+ -+ DBGLOG(REQ, LOUD, "mtk_cfg80211_mgmt_frame_register\n"); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ switch (frame_type) { -+ case MAC_FRAME_PROBE_REQ: -+ if (reg) { -+ prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(REQ, LOUD, "Open packet filer probe request\n"); -+ } else { -+ prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(REQ, LOUD, "Close packet filer probe request\n"); -+ } -+ break; -+ case MAC_FRAME_ACTION: -+ if (reg) { -+ prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(REQ, LOUD, "Open packet filer action frame.\n"); -+ } else { -+ prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(REQ, LOUD, "Close packet filer action frame.\n"); -+ } -+ break; -+ default: -+ DBGLOG(REQ, TRACE, "Ask frog to add code for mgmt:%x\n", frame_type); -+ break; -+ } -+ -+ if (prGlueInfo->prAdapter != NULL) { -+ /* prGlueInfo->ulFlag |= GLUE_FLAG_FRAME_FILTER_AIS; */ -+ set_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag); -+ -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+ if (in_interrupt()) -+ DBGLOG(REQ, TRACE, "It is in interrupt level\n"); -+ } -+#if 0 -+ -+ prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, -+ sizeof -+ (MSG_P2P_MGMT_FRAME_REGISTER_T)); -+ -+ if (prMgmtFrameRegister == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prMgmtFrameRegister->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_FRAME_REGISTER; -+ -+ prMgmtFrameRegister->u2FrameType = frame_type; -+ prMgmtFrameRegister->fgIsRegister = reg; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMgmtFrameRegister, MSG_SEND_METHOD_BUF); -+ -+#endif -+ -+ } while (FALSE); -+ -+} /* mtk_cfg80211_mgmt_frame_register */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to stay on a -+ * specified channel -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct ieee80211_channel *chan, -+ unsigned int duration, u64 *cookie) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_REMAIN_ON_CHANNEL_T prMsgChnlReq = (P_MSG_REMAIN_ON_CHANNEL_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL) || (chan == NULL) || (cookie == NULL)) -+ break; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+#if 1 -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+#endif -+ -+ *cookie = prGlueInfo->u8Cookie++; -+ -+ prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_REMAIN_ON_CHANNEL_T)); -+ -+ if (prMsgChnlReq == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ kalMemZero(prMsgChnlReq, sizeof(MSG_REMAIN_ON_CHANNEL_T)); -+ -+ prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_AIS_REMAIN_ON_CHANNEL; -+ prMsgChnlReq->u8Cookie = *cookie; -+ prMsgChnlReq->u4DurationMs = duration; -+ -+ prMsgChnlReq->ucChannelNum = nicFreq2ChannelNum(chan->center_freq * 1000); -+ -+ switch (chan->band) { -+ case NL80211_BAND_2GHZ: -+ prMsgChnlReq->eBand = BAND_2G4; -+ break; -+ case NL80211_BAND_5GHZ: -+ prMsgChnlReq->eBand = BAND_5G; -+ break; -+ default: -+ prMsgChnlReq->eBand = BAND_2G4; -+ break; -+ } -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlReq, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to cancel staying -+ * on a specified channel -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ u64 cookie) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_CANCEL_REMAIN_ON_CHANNEL_T prMsgChnlAbort = (P_MSG_CANCEL_REMAIN_ON_CHANNEL_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL)) -+ break; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+#if 1 -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+#endif -+ -+ prMsgChnlAbort = -+ cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_CANCEL_REMAIN_ON_CHANNEL_T)); -+ -+ if (prMsgChnlAbort == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL; -+ prMsgChnlAbort->u8Cookie = cookie; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlAbort, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to send a management frame -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct cfg80211_mgmt_tx_params *params, -+ u64 *cookie) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_MGMT_TX_REQUEST_T prMsgTxReq = (P_MSG_MGMT_TX_REQUEST_T) NULL; -+ P_MSDU_INFO_T prMgmtFrame = (P_MSDU_INFO_T) NULL; -+ PUINT_8 pucFrameBuf = (PUINT_8) NULL; -+ -+ do { -+#if 1 -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+#endif -+ -+ if ((wiphy == NULL) || (wdev == NULL) || (params == 0) || (cookie == NULL)) -+ break; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ *cookie = prGlueInfo->u8Cookie++; -+ -+ /* Channel & Channel Type & Wait time are ignored. */ -+ prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_MGMT_TX_REQUEST_T)); -+ -+ if (prMsgTxReq == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prMsgTxReq->fgNoneCckRate = FALSE; -+ prMsgTxReq->fgIsWaitRsp = TRUE; -+ -+ prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, (UINT_32) (params->len + MAC_TX_RESERVED_FIELD)); -+ prMsgTxReq->prMgmtMsduInfo = prMgmtFrame; -+ if (prMsgTxReq->prMgmtMsduInfo == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prMsgTxReq->u8Cookie = *cookie; -+ prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_AIS_MGMT_TX; -+ -+ pucFrameBuf = (PUINT_8) ((ULONG) prMgmtFrame->prPacket + MAC_TX_RESERVED_FIELD); -+ -+ kalMemCopy(pucFrameBuf, params->buf, params->len); -+ -+ prMgmtFrame->u2FrameLength = params->len; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgTxReq, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ if ((i4Rslt != 0) && (prMsgTxReq != NULL)) { -+ if (prMsgTxReq->prMgmtMsduInfo != NULL) -+ cnmMgtPktFree(prGlueInfo->prAdapter, prMsgTxReq->prMgmtMsduInfo); -+ -+ cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq); -+ } -+ -+ return i4Rslt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to cancel the wait time -+ * from transmitting a management frame on another channel -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ u64 cookie) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ /* not implemented */ -+ -+ return -EINVAL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for handling sched_scan start/stop request -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+ -+int -+mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy, -+ IN struct net_device *ndev, IN struct cfg80211_sched_scan_request *request) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 i, u4BufLen; -+ P_PARAM_SCHED_SCAN_REQUEST prSchedScanRequest; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ ASSERT(prGlueInfo); -+ -+ /* check if there is any pending scan/sched_scan not yet finished */ -+ if (prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL) { -+ DBGLOG(SCN, ERROR, "(prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL)\n"); -+ return -EBUSY; -+ } else if (request == NULL || request->n_match_sets > CFG_SCAN_SSID_MATCH_MAX_NUM) { -+ DBGLOG(SCN, ERROR, "(request == NULL || request->n_match_sets > CFG_SCAN_SSID_MATCH_MAX_NUM)\n"); -+ /* invalid scheduled scan request */ -+ return -EINVAL; -+ } else if (/* !request->n_ssids || */!request->n_match_sets) { -+ /* invalid scheduled scan request */ -+ return -EINVAL; -+ } -+ -+ prSchedScanRequest = (P_PARAM_SCHED_SCAN_REQUEST) kalMemAlloc(sizeof(PARAM_SCHED_SCAN_REQUEST), VIR_MEM_TYPE); -+ if (prSchedScanRequest == NULL) { -+ DBGLOG(SCN, ERROR, "(prSchedScanRequest == NULL) kalMemAlloc fail\n"); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(prSchedScanRequest, sizeof(PARAM_SCHED_SCAN_REQUEST)); -+ -+ prSchedScanRequest->u4SsidNum = request->n_match_sets; -+ for (i = 0; i < request->n_match_sets; i++) { -+ if (request->match_sets == NULL || &(request->match_sets[i]) == NULL) { -+ prSchedScanRequest->arSsid[i].u4SsidLen = 0; -+ } else { -+ COPY_SSID(prSchedScanRequest->arSsid[i].aucSsid, -+ prSchedScanRequest->arSsid[i].u4SsidLen, -+ request->match_sets[i].ssid.ssid, request->match_sets[i].ssid.ssid_len); -+ } -+ } -+ -+ prSchedScanRequest->u4IELength = request->ie_len; -+ if (request->ie_len > 0) -+ prSchedScanRequest->pucIE = (PUINT_8) (request->ie); -+ -+ prSchedScanRequest->u2ScanInterval = (UINT_16) (request->scan_plans[0].interval); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetStartSchedScan, -+ prSchedScanRequest, sizeof(PARAM_SCHED_SCAN_REQUEST), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ kalMemFree(prSchedScanRequest, VIR_MEM_TYPE, sizeof(PARAM_SCHED_SCAN_REQUEST)); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(SCN, ERROR, "scheduled scan error:%x\n", rStatus); -+ return -EINVAL; -+ } -+ -+ prGlueInfo->prSchedScanRequest = request; -+ -+ return 0; -+} -+ -+int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, IN struct net_device *ndev, u64 reqid) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ /* check if there is any pending scan/sched_scan not yet finished */ -+ if (prGlueInfo->prSchedScanRequest == NULL) { -+ DBGLOG(SCN, ERROR, "prGlueInfo->prSchedScanRequest == NULL\n"); -+ return -EBUSY; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetStopSchedScan, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(SCN, ERROR, "scheduled scan error, rStatus: %d\n", rStatus); -+ return -EINVAL; -+ } -+ -+ /* 1. reset first for newly incoming request */ -+ /* GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); */ -+ if (prGlueInfo->prSchedScanRequest != NULL) -+ prGlueInfo->prSchedScanRequest = NULL; -+ /* GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); */ -+ -+ DBGLOG(SCN, TRACE, "start work queue to send event\n"); -+ schedule_delayed_work(&sched_workq, 0); -+ DBGLOG(SCN, TRACE, "tx_thread return from kalSchedScanStoppped\n"); -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for handling association request -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_assoc(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_assoc_request *req) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ PARAM_MAC_ADDRESS arBssid; -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ PUINT_8 prDesiredIE = NULL; -+#endif -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemZero(arBssid, MAC_ADDR_LEN); -+ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen); -+ -+ /* 1. check BSSID */ -+ if (UNEQUAL_MAC_ADDR(arBssid, req->bss->bssid)) { -+ /* wrong MAC address */ -+ DBGLOG(REQ, WARN, "incorrect BSSID: [ %pM ] currently connected BSSID[ %pM ]\n", -+ req->bss->bssid, arBssid); -+ return -ENOENT; -+ } -+ -+ if (req->ie && req->ie_len > 0) { -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ if (wextSrchDesiredHS20IE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetHS20Info, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set HS20 assoc info error:%lx\n", rStatus); */ -+ } -+ } -+ -+ if (wextSrchDesiredInterworkingIE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetInterworkingInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set Interworking assoc info error:%lx\n", rStatus); */ -+ } -+ } -+ -+ if (wextSrchDesiredRoamingConsortiumIE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRoamingConsortiumIEInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus); */ -+ } -+ } -+#endif -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetBssid, -+ (PVOID) req->bss->bssid, MAC_ADDR_LEN, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "set BSSID:%x\n", rStatus); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+#if CONFIG_NL80211_TESTMODE -+/* -+#define NLA_PUT(skb, attrtype, attrlen, data) \ -+do { \ -+ if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \ -+ goto nla_put_failure; \ -+} while (0) -+ -+#define NLA_PUT_TYPE(skb, type, attrtype, value) \ -+do { \ -+ type __tmp = value; \ -+ NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \ -+} while (0) -+ -+#define NLA_PUT_U8(skb, attrtype, value) \ -+ NLA_PUT_TYPE(skb, u8, attrtype, value) -+ -+#define NLA_PUT_U16(skb, attrtype, value) \ -+ NLA_PUT_TYPE(skb, u16, attrtype, value) -+ -+#define NLA_PUT_U32(skb, attrtype, value) \ -+ NLA_PUT_TYPE(skb, u32, attrtype, value) -+ -+#define NLA_PUT_U64(skb, attrtype, value) \ -+ NLA_PUT_TYPE(skb, u64, attrtype, value) -+*/ -+#if CFG_SUPPORT_WAPI -+int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_SET_KEY_EXTS prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) NULL; -+ struct iw_encode_exts *prIWEncExt = (struct iw_encode_exts *)NULL; -+ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; -+ int fgIsValid = 0; -+ UINT_32 u4BufLen = 0; -+ -+ P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf; -+ -+ memset(keyStructBuf, 0, sizeof(keyStructBuf)); -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) data; -+ } else { -+ DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_set_key_ext, data is NULL\n"); -+ return -EINVAL; -+ } -+ -+ if (prParams) -+ prIWEncExt = (struct iw_encode_exts *)&prParams->ext; -+ -+ if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) { -+ /* KeyID */ -+ prWpiKey->ucKeyID = prParams->key_index; -+ prWpiKey->ucKeyID--; -+ if (prWpiKey->ucKeyID > 1) { -+ /* key id is out of range */ -+ /* printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID); */ -+ return -EINVAL; -+ } -+ -+ if (prIWEncExt->key_len != 32) { -+ /* key length not valid */ -+ /* printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len); */ -+ return -EINVAL; -+ } -+ /* printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags); */ -+ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { -+ prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY; -+ prWpiKey->eDirection = ENUM_WPI_RX; -+ } else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { -+ prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY; -+ prWpiKey->eDirection = ENUM_WPI_RX_TX; -+ } -+/* #if CFG_SUPPORT_WAPI */ -+ /* handle_sec_msg_final(prIWEncExt->key, 32, prIWEncExt->key, NULL); */ -+/* #endif */ -+ /* PN */ -+ memcpy(prWpiKey->aucPN, prIWEncExt->tx_seq, IW_ENCODE_SEQ_MAX_SIZE); -+ memcpy(prWpiKey->aucPN + IW_ENCODE_SEQ_MAX_SIZE, prIWEncExt->rx_seq, IW_ENCODE_SEQ_MAX_SIZE); -+ -+ -+ /* BSSID */ -+ memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr, 6); -+ -+ memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16); -+ prWpiKey->u4LenWPIEK = 16; -+ -+ memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16); -+ prWpiKey->u4LenWPICK = 16; -+ -+ rstatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiKey, -+ prWpiKey, sizeof(PARAM_WPI_KEY_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rstatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus); */ -+ fgIsValid = -EFAULT; -+ } -+ -+ } -+ return fgIsValid; -+} -+#endif -+ -+int -+mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ INT_32 i4Status = -EINVAL; -+ UINT_32 u4BufLen; -+ UINT_32 u4LinkScore; -+ UINT_32 u4TotalError; -+ UINT_32 u4TxExceedThresholdCount; -+ UINT_32 u4TxTotalCount; -+ -+ P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL; -+ PARAM_GET_STA_STA_STATISTICS rQueryStaStatistics; -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy); -+ ASSERT(prGlueInfo); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS) data; -+ } else { -+ DBGLOG(QM, ERROR, "mtk_cfg80211_testmode_get_sta_statistics, data is NULL\n"); -+ return -EINVAL; -+ } -+/* -+ if (!prParams->aucMacAddr) { -+ DBGLOG(QM, INFO, "%s MAC Address is NULL\n", __func__); -+ return -EINVAL; -+ } -+*/ -+ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1); -+ -+ if (!skb) { -+ DBGLOG(QM, ERROR, "%s allocate skb failed:%x\n", __func__, rStatus); -+ return -ENOMEM; -+ } -+ -+ DBGLOG(QM, TRACE, "Get [ %pM ] STA statistics\n", prParams->aucMacAddr); -+ -+ kalMemZero(&rQueryStaStatistics, sizeof(rQueryStaStatistics)); -+ COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, prParams->aucMacAddr); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStaStatistics, -+ &rQueryStaStatistics, sizeof(rQueryStaStatistics), TRUE, FALSE, TRUE, TRUE, &u4BufLen); -+ -+ /* Calcute Link Score */ -+ u4TxExceedThresholdCount = rQueryStaStatistics.u4TxExceedThresholdCount; -+ u4TxTotalCount = rQueryStaStatistics.u4TxTotalCount; -+ u4TotalError = rQueryStaStatistics.u4TxFailCount + rQueryStaStatistics.u4TxLifeTimeoutCount; -+ -+ /* u4LinkScore 10~100 , ExceedThreshold ratio 0~90 only */ -+ /* u4LinkScore 0~9 , Drop packet ratio 0~9 and all packets exceed threshold */ -+ if (u4TxTotalCount) { -+ if (u4TxExceedThresholdCount <= u4TxTotalCount) -+ u4LinkScore = (90 - ((u4TxExceedThresholdCount * 90) / u4TxTotalCount)); -+ else -+ u4LinkScore = 0; -+ } else { -+ u4LinkScore = 90; -+ } -+ -+ u4LinkScore += 10; -+ -+ if (u4LinkScore == 10) { -+ -+ if (u4TotalError <= u4TxTotalCount) -+ u4LinkScore = (10 - ((u4TotalError * 10) / u4TxTotalCount)); -+ else -+ u4LinkScore = 0; -+ -+ } -+ -+ if (u4LinkScore > 100) -+ u4LinkScore = 100; -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0);*/ -+ { -+ unsigned char __tmp = 0; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, NL80211_DRIVER_TESTMODE_VERSION);*/ -+ { -+ unsigned char __tmp = NL80211_DRIVER_TESTMODE_VERSION; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /* NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, u4LinkScore); */ -+ { -+ unsigned int __tmp = u4LinkScore; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, prParams->aucMacAddr);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, &prParams->aucMacAddr) < 0)) -+ goto nla_put_failure; -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG, rQueryStaStatistics.u4Flag);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4Flag; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ /* FW part STA link status */ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_PER, rQueryStaStatistics.ucPer);*/ -+ { -+ unsigned char __tmp = rQueryStaStatistics.ucPer; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_PER, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, rQueryStaStatistics.ucRcpi);*/ -+ { -+ unsigned char __tmp = rQueryStaStatistics.ucRcpi; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, rQueryStaStatistics.u4PhyMode);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4PhyMode; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U16(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE, rQueryStaStatistics.u2LinkSpeed);*/ -+ { -+ unsigned short __tmp = rQueryStaStatistics.u2LinkSpeed; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE, -+ sizeof(unsigned short), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, rQueryStaStatistics.u4TxFailCount);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxFailCount; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, rQueryStaStatistics.u4TxLifeTimeoutCount);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxLifeTimeoutCount; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, rQueryStaStatistics.u4TxAverageAirTime);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxAverageAirTime; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /* Driver part link status */ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, rQueryStaStatistics.u4TxTotalCount);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxTotalCount; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, -+ rQueryStaStatistics.u4TxExceedThresholdCount);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxExceedThresholdCount; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, -+ rQueryStaStatistics.u4TxAverageProcessTime);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxAverageProcessTime; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxMaxTime; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAX_PROCESS_TIME, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxAverageHifTime; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_HIF_PROCESS_TIME, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxMaxHifTime; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAX_HIF_PROCESS_TIME, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, rQueryStaStatistics.u4EnqueueCounter); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4EnqueueCounter; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, rQueryStaStatistics.u4DequeueCounter); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4DequeueCounter; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, rQueryStaStatistics.u4EnqueueStaCounter); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4EnqueueStaCounter; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, rQueryStaStatistics.u4DequeueStaCounter); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4DequeueStaCounter; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, rQueryStaStatistics.IsrCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, rQueryStaStatistics.IsrPassCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrPassCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, rQueryStaStatistics.TaskIsrCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.TaskIsrCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, rQueryStaStatistics.IsrAbnormalCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrAbnormalCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, rQueryStaStatistics.IsrSoftWareCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrSoftWareCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, rQueryStaStatistics.IsrTxCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrTxCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ *NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, rQueryStaStatistics.IsrRxCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrRxCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* Network counter */ -+ /*NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceEmptyCount), rQueryStaStatistics.au4TcResourceEmptyCount);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceEmptyCount), &rQueryStaStatistics.au4TcResourceEmptyCount) < 0)) -+ goto nla_put_failure; -+ /* -+ NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, -+ sizeof(rQueryStaStatistics.au4DequeueNoTcResource), rQueryStaStatistics.au4DequeueNoTcResource); -+ */ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, -+ sizeof(rQueryStaStatistics.au4DequeueNoTcResource), &rQueryStaStatistics.au4DequeueNoTcResource) < 0)) -+ goto nla_put_failure; -+ /* -+ NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceBackCount), rQueryStaStatistics.au4TcResourceBackCount); -+ */ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceBackCount), &rQueryStaStatistics.au4TcResourceBackCount) < 0)) -+ goto nla_put_failure; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_USED_BFCT_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceUsedCount), &rQueryStaStatistics.au4TcResourceUsedCount) < 0)) -+ goto nla_put_failure; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_WANTED_BFCT_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceWantedCount), -+ &rQueryStaStatistics.au4TcResourceWantedCount) < 0)) -+ goto nla_put_failure; -+ -+ /* Sta queue length */ -+ /*NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcQueLen), rQueryStaStatistics.au4TcQueLen);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcQueLen), &rQueryStaStatistics.au4TcQueLen) < 0)) -+ goto nla_put_failure; -+ -+ -+ /* Global QM counter */ -+ /*NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcAverageQueLen), rQueryStaStatistics.au4TcAverageQueLen);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcAverageQueLen), &rQueryStaStatistics.au4TcAverageQueLen) < 0)) -+ goto nla_put_failure; -+ -+ /*NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcCurrentQueLen), rQueryStaStatistics.au4TcCurrentQueLen);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcCurrentQueLen), &rQueryStaStatistics.au4TcCurrentQueLen) < 0)) -+ goto nla_put_failure; -+ -+ -+ /* Reserved field */ -+ /*NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, -+ sizeof(rQueryStaStatistics.au4Reserved), rQueryStaStatistics.au4Reserved);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, -+ sizeof(rQueryStaStatistics.au4Reserved), &rQueryStaStatistics.au4Reserved) < 0)) -+ goto nla_put_failure; -+ -+ i4Status = cfg80211_testmode_reply(skb); -+ skb = NULL; -+ -+nla_put_failure: -+ if (skb != NULL) -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+int -+mtk_cfg80211_testmode_get_link_detection(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) -+{ -+ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ INT_32 i4Status = -EINVAL; -+ UINT_32 u4BufLen; -+ -+ PARAM_802_11_STATISTICS_STRUCT_T rStatistics; -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy); -+ ASSERT(prGlueInfo); -+ -+ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1); -+ -+ if (!skb) { -+ DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(&rStatistics, sizeof(rStatistics)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStatistics, -+ &rStatistics, sizeof(rStatistics), TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0);*/ -+ { -+ unsigned char __tmp = 0; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_FAIL_CNT, rStatistics.rFailedCount.QuadPart);*/ -+ { -+ u64 __tmp = rStatistics.rFailedCount.QuadPart; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_FAIL_CNT, -+ sizeof(u64), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_RETRY_CNT, rStatistics.rRetryCount.QuadPart);*/ -+ { -+ u64 __tmp = rStatistics.rFailedCount.QuadPart; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_RETRY_CNT, -+ sizeof(u64), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, rStatistics.rMultipleRetryCount.QuadPart);*/ -+ { -+ u64 __tmp = rStatistics.rMultipleRetryCount.QuadPart; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, -+ sizeof(u64), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_ACK_FAIL_CNT, rStatistics.rACKFailureCount.QuadPart);*/ -+ { -+ u64 __tmp = rStatistics.rACKFailureCount.QuadPart; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_ACK_FAIL_CNT, -+ sizeof(u64), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_FCS_ERR_CNT, rStatistics.rFCSErrorCount.QuadPart);*/ -+ { -+ u64 __tmp = rStatistics.rFCSErrorCount.QuadPart; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_FCS_ERR_CNT, -+ sizeof(u64), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ i4Status = cfg80211_testmode_reply(skb); -+ skb = NULL; -+ -+nla_put_failure: -+ if (skb != NULL) -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_SW_CMD_PARAMS prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) NULL; -+ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; -+ int fgIsValid = 0; -+ UINT_32 u4SetInfoLen = 0; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ if (data && len) -+ prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) data; -+ -+ if (prParams) { -+ if (prParams->set == 1) { -+ rstatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC) wlanoidSetSwCtrlWrite, -+ &prParams->adr, (UINT_32) 8, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ } -+ } -+ -+ if (WLAN_STATUS_SUCCESS != rstatus) -+ fgIsValid = -EFAULT; -+ -+ return fgIsValid; -+} -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct wpa_driver_hs20_data_s *prParams = NULL; -+ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; -+ int fgIsValid = 0; -+ UINT_32 u4SetInfoLen = 0; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ if (data && len) { -+ prParams = (struct wpa_driver_hs20_data_s *)data; -+ -+ DBGLOG(REQ, TRACE, "[%s] Cmd Type (%d)\n", __func__, prParams->CmdType); -+ } -+ -+ if (prParams) { -+ int i; -+ -+ switch (prParams->CmdType) { -+ case HS20_CMD_ID_SET_BSSID_POOL: -+ DBGLOG(REQ, TRACE, "fgBssidPoolIsEnable=%d, ucNumBssidPool=%d\n", -+ prParams->hs20_set_bssid_pool.fgBssidPoolIsEnable, -+ prParams->hs20_set_bssid_pool.ucNumBssidPool); -+ for (i = 0; i < prParams->hs20_set_bssid_pool.ucNumBssidPool; i++) { -+ DBGLOG(REQ, TRACE, "[%d][ %pM ]\n", i, -+ (prParams->hs20_set_bssid_pool.arBssidPool[i])); -+ } -+ rstatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC) wlanoidSetHS20BssidPool, -+ &prParams->hs20_set_bssid_pool, -+ sizeof(struct param_hs20_set_bssid_pool), -+ FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ break; -+ default: -+ DBGLOG(REQ, TRACE, "[%s] Unknown Cmd Type (%d)\n", __func__, prParams->CmdType); -+ rstatus = WLAN_STATUS_FAILURE; -+ -+ } -+ -+ } -+ -+ if (WLAN_STATUS_SUCCESS != rstatus) -+ fgIsValid = -EFAULT; -+ -+ return fgIsValid; -+} -+ -+#endif -+int -+mtk_cfg80211_testmode_set_poorlink_param(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) -+{ -+ int fgIsValid = 0; -+ P_NL80211_DRIVER_POORLINK_PARAMS prParams = NULL; -+ -+ ASSERT(wiphy); -+ ASSERT(prGlueInfo); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_POORLINK_PARAMS) data; -+ } else { -+ DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_set_poorlink_param, data is NULL\n"); -+ return -EINVAL; -+ } -+ if (prParams->ucLinkSpeed) -+ prGlueInfo->u4LinkspeedThreshold = prParams->ucLinkSpeed * 10; -+ if (prParams->cRssi) -+ prGlueInfo->i4RssiThreshold = prParams->cRssi; -+ if (!prGlueInfo->fgPoorlinkValid) -+ prGlueInfo->fgPoorlinkValid = 1; -+#if 0 -+ DBGLOG(REQ, TRACE, "poorlink set param valid(%d)rssi(%d)linkspeed(%d)\n", -+ prGlueInfo->fgPoorlinkValid, prGlueInfo->i4RssiThreshold, prGlueInfo->u4LinkspeedThreshold); -+#endif -+ -+ return fgIsValid; -+ -+} -+ -+int mtk_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_TEST_MODE_PARAMS prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) NULL; -+ INT_32 i4Status = -EINVAL; -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ BOOLEAN fgIsValid = 0; -+#endif -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) data; -+ } else { -+ DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_cmd, data is NULL\n"); -+ return i4Status; -+ } -+ -+ /* Clear the version byte */ -+ prParams->index = prParams->index & ~BITS(24, 31); -+ -+ if (prParams) { -+ switch (prParams->index) { -+ case TESTMODE_CMD_ID_SW_CMD: /* SW cmd */ -+ i4Status = mtk_cfg80211_testmode_sw_cmd(wiphy, data, len); -+ break; -+ case TESTMODE_CMD_ID_WAPI: /* WAPI */ -+#if CFG_SUPPORT_WAPI -+ i4Status = mtk_cfg80211_testmode_set_key_ext(wiphy, data, len); -+#endif -+ break; -+ case TESTMODE_CMD_ID_SUSPEND: -+ { -+ P_NL80211_DRIVER_SUSPEND_PARAMS prParams = (P_NL80211_DRIVER_SUSPEND_PARAMS) data; -+ -+ if (prParams->suspend == 1) { -+ wlanHandleSystemSuspend(); -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ p2pHandleSystemSuspend(); -+ i4Status = 0; -+ } else if (prParams->suspend == 0) { -+ wlanHandleSystemResume(); -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ p2pHandleSystemResume(); -+ i4Status = 0; -+ } -+ break; -+ } -+ case TESTMODE_CMD_ID_STATISTICS: -+ i4Status = mtk_cfg80211_testmode_get_sta_statistics(wiphy, data, len, prGlueInfo); -+ break; -+ case TESTMODE_CMD_ID_LINK_DETECT: -+ i4Status = mtk_cfg80211_testmode_get_link_detection(wiphy, data, len, prGlueInfo); -+ break; -+ case TESTMODE_CMD_ID_POORLINK: -+ i4Status = mtk_cfg80211_testmode_set_poorlink_param(wiphy, data, len, prGlueInfo); -+ break; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ case TESTMODE_CMD_ID_HS20: -+ if (mtk_cfg80211_testmode_hs20_cmd(wiphy, data, len)) -+ fgIsValid = TRUE; -+ break; -+#endif -+ default: -+ i4Status = -EINVAL; -+ break; -+ } -+ } -+ -+ return i4Status; -+} -+ -+int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) -+{ -+#define NL80211_TESTMODE_P2P_SCANDONE_INVALID 0 -+#define NL80211_TESTMODE_P2P_SCANDONE_STATUS 1 -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ INT_32 i4Status = -EINVAL, READY_TO_BEAM = 0; -+ -+/* P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL; */ -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy); -+ ASSERT(prGlueInfo); -+ -+ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(UINT_32)); -+ READY_TO_BEAM = -+ (UINT_32) (prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo. -+ fgIsGOInitialDone) & -+ (!prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest); -+ DBGLOG(QM, TRACE, -+ "NFC:GOInitialDone[%d] and P2PScanning[%d]\n", -+ prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone, -+ prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest); -+ -+ if (!skb) { -+ DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus); -+ return -ENOMEM; -+ } -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, 0);*/ -+ { -+ unsigned char __tmp = 0; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, READY_TO_BEAM);*/ -+ { -+ unsigned int __tmp = READY_TO_BEAM; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ i4Status = cfg80211_testmode_reply(skb); -+ skb = NULL; -+ -+nla_put_failure: -+ if (skb != NULL) -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+int -+mtk_cfg80211_testmode_get_lte_channel(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) -+{ -+#define MAXMUN_2_4G_CHA_NUM 14 -+#define CHN_DIRTY_WEIGHT_UPPERBOUND 4 -+ -+ BOOLEAN fgIsReady = FALSE, fgIsFistRecord = TRUE; -+ BOOLEAN fgIsPureAP, fgIsLteSafeChn = FALSE; -+ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_8 ucIdx = 0, ucMax_24G_Chn_List = 11, ucDefaultIdx = 0, ucArrayIdx = 0; -+ UINT_16 u2APNumScore = 0, u2UpThreshold = 0, u2LowThreshold = 0, ucInnerIdx = 0; -+ INT_32 i4Status = -EINVAL; -+ UINT_32 u4BufLen, u4LteSafeChnBitMask_2_4G = 0; -+ UINT32 AcsChnReport[4]; -+ /*RF_CHANNEL_INFO_T aucChannelList[MAXMUN_2_4G_CHA_NUM];*/ -+ -+ struct sk_buff *skb; -+ -+ /*PARAM_GET_CHN_LOAD rQueryLTEChn;*/ -+ P_PARAM_GET_CHN_LOAD prQueryLTEChn; -+ PARAM_PREFER_CHN_INFO rPreferChannels[2], ar2_4G_ChannelLoadingWeightScore[MAXMUN_2_4G_CHA_NUM]; -+ P_PARAM_CHN_LOAD_INFO prChnLoad; -+ P_PARAM_GET_CHN_LOAD prGetChnLoad; -+ -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ -+/* -+ P_PARAM_GET_CHN_LOAD prParams = NULL; -+*/ -+ ASSERT(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemZero(rPreferChannels, sizeof(rPreferChannels)); -+ fgIsPureAP = prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode; -+#if 0 -+ if (data && len) -+ prParams = (P_NL80211_DRIVER_GET_LTE_PARAMS) data; -+#endif -+ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(AcsChnReport) + sizeof(UINT8) + 1); -+ if (!skb) { -+ DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus); -+ return -ENOMEM; -+ } -+ -+ DBGLOG(P2P, INFO, "[Auto Channel]Get LTE Channels\n"); -+ prQueryLTEChn = kalMemAlloc(sizeof(PARAM_GET_CHN_LOAD), VIR_MEM_TYPE); -+ if (prQueryLTEChn == NULL) { -+ DBGLOG(QM, TRACE, "alloc QueryLTEChn fail\n"); -+ kalMemFree(skb, VIR_MEM_TYPE, sizeof(struct sk_buff)); -+ return -ENOMEM; -+ } -+ kalMemZero(prQueryLTEChn, sizeof(PARAM_GET_CHN_LOAD)); -+ -+ /* Query LTE Safe Channels */ -+ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] -+ = 0xFFFFFFFF; -+ -+ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1] -+ = 0xFFFFFFFF; -+ -+ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1] -+ = 0xFFFFFFFF; -+ -+ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1] = -+ 0xFFFFFFFF; -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidQueryACSChannelList, prQueryLTEChn, sizeof(PARAM_GET_CHN_LOAD), -+ TRUE, FALSE, TRUE, TRUE, &u4BufLen); -+#if 0 -+ if (fgIsPureAP) { -+ -+ AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] = 0x20; /* Channel 6 */ -+ } else -+#endif -+ { -+ fgIsReady = prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit; -+ rPreferChannels[0].u2APNum = 0xFFFF; -+ rPreferChannels[1].u2APNum = 0xFFFF; -+ -+ /* 4 In LTE Mode, Hotspot pick up channels from ch4. */ -+ ucDefaultIdx = 0; -+ /* -+ if (fgIsPureAP) { -+ ucDefaultIdx=3; //SKIP LTE Channels 1~3 -+ } -+ */ -+ -+ /* 4 Get the Maximun channel List in 2.4G Bands */ -+ -+ prDomainInfo = rlmDomainGetDomainInfo(prGlueInfo->prAdapter); -+ ASSERT(prDomainInfo); -+ -+ /* 4 ToDo: Enable Step 2 only if we could get Country Code from framework */ -+ /* 4 2. Get current domain channel list */ -+ -+#if 0 -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, -+ BAND_2G4, MAXMUN_2_4G_CHA_NUM, &ucMax_24G_Chn_List, aucChannelList); -+#endif -+ -+ prGetChnLoad = (P_PARAM_GET_CHN_LOAD) &(prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo); -+ for (ucIdx = 0; ucIdx < ucMax_24G_Chn_List; ucIdx++) { -+ DBGLOG(P2P, INFO, -+ "[Auto Channel] ch[%d]=%d\n", ucIdx, -+ prGetChnLoad->rEachChnLoad[ucIdx + ucInnerIdx].u2APNum); -+ } -+ -+ /*Calculate Each Channel Direty Score */ -+ for (ucIdx = ucDefaultIdx; ucIdx < ucMax_24G_Chn_List; ucIdx++) { -+ -+#if 1 -+ u2APNumScore = prGetChnLoad->rEachChnLoad[ucIdx].u2APNum * CHN_DIRTY_WEIGHT_UPPERBOUND; -+ u2UpThreshold = u2LowThreshold = 3; -+ -+ if (ucIdx < 3) { -+ u2UpThreshold = ucIdx; -+ u2LowThreshold = 3; -+ } else if (ucIdx >= (ucMax_24G_Chn_List - 3)) { -+ u2UpThreshold = 3; -+ u2LowThreshold = ucMax_24G_Chn_List - (ucIdx + 1); -+ -+ } -+ -+ /*Calculate Lower Channel Dirty Score */ -+ for (ucInnerIdx = 0; ucInnerIdx < u2LowThreshold; ucInnerIdx++) { -+ ucArrayIdx = ucIdx + ucInnerIdx + 1; -+ if (ucArrayIdx < MAX_AUTO_CHAL_NUM) { -+ u2APNumScore += -+ (prGetChnLoad->rEachChnLoad[ucArrayIdx].u2APNum * -+ (CHN_DIRTY_WEIGHT_UPPERBOUND - 1 - ucInnerIdx)); -+ } -+ } -+ -+ /*Calculate Upper Channel Dirty Score */ -+ for (ucInnerIdx = 0; ucInnerIdx < u2UpThreshold; ucInnerIdx++) { -+ ucArrayIdx = ucIdx - ucInnerIdx - 1; -+ if (ucArrayIdx < MAX_AUTO_CHAL_NUM) { -+ u2APNumScore += -+ (prGetChnLoad->rEachChnLoad[ucArrayIdx].u2APNum * -+ (CHN_DIRTY_WEIGHT_UPPERBOUND - 1 - ucInnerIdx)); -+ } -+ } -+ -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; -+ -+ DBGLOG(P2P, INFO, "[Auto Channel]chn=%d score=%d\n", ucIdx, u2APNumScore); -+#else -+ if (ucIdx == 0) { -+ /* ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = -+ (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + -+ prGetChnLoad->rEachChnLoad[ucIdx+1].u2APNum*0.75); */ -+ u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ((UINT_16) -+ ((3 * -+ (prGetChnLoad-> -+ rEachChnLoad[ucIdx + -+ 1]. -+ u2APNum + -+ prGetChnLoad-> -+ rEachChnLoad[ucIdx + -+ 2]. -+ u2APNum)) / 4))); -+ -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; -+ DBGLOG(P2P, INFO, -+ "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d\n", ucIdx, -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx + 1].u2APNum)); -+ } -+ if ((ucIdx > 0) && (ucIdx < (MAXMUN_2_4G_CHA_NUM - 1))) { -+ u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ((UINT_16) -+ ((3 * -+ (prGetChnLoad-> -+ rEachChnLoad[ucIdx + -+ 1]. -+ u2APNum + -+ prGetChnLoad-> -+ rEachChnLoad[ucIdx - -+ 1]. -+ u2APNum)) / 4))); -+ -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; -+ DBGLOG(P2P, INFO, -+ "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d+0.75*%d\n", ucIdx, -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx + 1].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum)); -+ } -+ -+ if (ucIdx == (MAXMUN_2_4G_CHA_NUM - 1)) { -+ u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + -+ ((UINT_16) ((3 * prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum) / 4))); -+ -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; -+ DBGLOG(P2P, INFO, -+ "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d\n", ucIdx, -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum)); -+ } -+#endif -+ -+ } -+ -+ u4LteSafeChnBitMask_2_4G = -+ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]; -+ -+ /*Find out the best channel */ -+ for (ucIdx = ucDefaultIdx; ucIdx < ucMax_24G_Chn_List; ucIdx++) { -+ /* 4 Skip LTE Unsafe Channel */ -+ fgIsLteSafeChn = ((u4LteSafeChnBitMask_2_4G & BIT(ucIdx + 1)) >> ucIdx); -+ if (!fgIsLteSafeChn) -+ continue; -+ -+ prChnLoad = -+ (P_PARAM_CHN_LOAD_INFO) &(prGlueInfo->prAdapter->rWifiVar. -+ rChnLoadInfo.rEachChnLoad[ucIdx]); -+ if (rPreferChannels[0].u2APNum >= ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum) { -+ rPreferChannels[1].ucChannel = rPreferChannels[0].ucChannel; -+ rPreferChannels[1].u2APNum = rPreferChannels[0].u2APNum; -+ -+ rPreferChannels[0].ucChannel = ucIdx; -+ rPreferChannels[0].u2APNum = ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum; -+ } else { -+ if (rPreferChannels[1].u2APNum >= ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum -+ || fgIsFistRecord == 1) { -+ fgIsFistRecord = FALSE; -+ rPreferChannels[1].ucChannel = ucIdx; -+ rPreferChannels[1].u2APNum = ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum; -+ } -+ } -+ } -+ /* AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1-1] = -+ BITS((rQueryLTEChn.rLteSafeChnList.ucChannelLow-1),(rQueryLTEChn.rLteSafeChnList.ucChannelHigh-1)); */ -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] = fgIsReady ? BIT(31) : 0; -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] |= BIT(rPreferChannels[0].ucChannel); -+ } -+ -+ /* ToDo: Support 5G Channel Selection */ -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1] = 0x11223344; -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1] = 0x55667788; -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1] = 0x99AABBCC; -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_AVAILABLE_CHAN_INVALID, 0);*/ -+ { -+ unsigned char __tmp = 0; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_INVALID, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]);*/ -+ { -+ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1]);*/ -+ { -+ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1]; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1]);*/ -+ { -+ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1]; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1]);*/ -+ { -+ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1]; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ DBGLOG(P2P, INFO, -+ "[Auto Channel]Relpy AcsChanInfo[%x:%x:%x:%x]\n", AcsChnReport[0], AcsChnReport[1], AcsChnReport[2], -+ AcsChnReport[3]); -+ -+ i4Status = cfg80211_testmode_reply(skb); -+ /*need confirm cfg80211_testmode_reply will free skb*/ -+ skb = NULL; -+ /*kalMemFree(prQueryLTEChn, VIR_MEM_TYPE, sizeof(PARAM_GET_CHN_LOAD));*/ -+ -+nla_put_failure: -+ kalMemFree(prQueryLTEChn, VIR_MEM_TYPE, sizeof(PARAM_GET_CHN_LOAD)); -+ if (skb != NULL) -+ kfree_skb(skb); -+ return i4Status; -+ -+} -+#endif -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief cfg80211 suspend callback, will be invoked in wiphy_suspend -+ * -+ * @param wiphy: pointer to wiphy -+ * wow: pointer to cfg80211_wowlan -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ if (kalHaltTryLock()) -+ return 0; -+ -+ if (kalIsHalted() || !wiphy) -+ goto end; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ set_bit(SUSPEND_FLAG_FOR_WAKEUP_REASON, &prGlueInfo->prAdapter->ulSuspendFlag); -+ set_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prGlueInfo->prAdapter->ulSuspendFlag); -+end: -+ kalHaltUnlock(); -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief cfg80211 resume callback, will be invoked in wiphy_resume. -+ * -+ * @param wiphy: pointer to wiphy -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_resume(struct wiphy *wiphy) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_BSS_DESC_T *pprBssDesc = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ UINT_8 i = 0; -+ -+ if (kalHaltTryLock()) -+ return 0; -+ -+ if (kalIsHalted() || !wiphy) -+ goto end; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ prAdapter = prGlueInfo->prAdapter; -+ clear_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prAdapter->ulSuspendFlag); -+ pprBssDesc = &prAdapter->rWifiVar.rScanInfo.rNloParam.aprPendingBssDescToInd[0]; -+ for (; i < SCN_SSID_MATCH_MAX_NUM; i++) { -+ if (pprBssDesc[i] == NULL) -+ break; -+ if (pprBssDesc[i]->u2RawLength == 0) -+ continue; -+ kalIndicateBssInfo(prGlueInfo, -+ (PUINT_8) pprBssDesc[i]->aucRawBuf, -+ pprBssDesc[i]->u2RawLength, -+ pprBssDesc[i]->ucChannelNum, -+ RCPI_TO_dBm(pprBssDesc[i]->ucRCPI)); -+ } -+ DBGLOG(SCN, INFO, "pending %d sched scan results\n", i); -+ if (i > 0) -+ kalMemZero(&pprBssDesc[0], i * sizeof(P_BSS_DESC_T)); -+end: -+ kalHaltUnlock(); -+ return 0; -+} -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c -new file mode 100644 -index 0000000000000..95ca7546b1bbc ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c -@@ -0,0 +1,3502 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_init.c#7 -+*/ -+ -+/*! \file gl_init.c -+ \brief Main routines of Linux driver -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_init.c -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Fix compile error. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Fix compile error for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 05 25 2012 yuche.tsai -+ * NULL -+ * Fix reset KE issue. -+ * -+ * 05 11 2012 cp.wu -+ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience -+ * show MAC address & source while initiliazation -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * EXPORT_SYMBOL(rsnParseCheckForWFAInfoElem);. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Enable CFG80211 Support. -+ * -+ * 12 22 2011 george.huang -+ * [WCXRP00000905] [MT6628 Wi-Fi][FW] Code refinement for ROM/ RAM module dependency -+ * using global variable instead of stack for setting wlanoidSetNetworkAddress(), due to buffer may be released before -+ * TX thread handling -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 14 2011 yuche.tsai -+ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. -+ * Fix large network type index assert in FW issue. -+ * -+ * 11 14 2011 cm.chang -+ * NULL -+ * Fix compiling warning -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 10 06 2011 eddie.chen -+ * [WCXRP00001027] [MT6628 Wi-Fi][Firmware/Driver] Tx fragmentation -+ * Add rlmDomainGetChnlList symbol. -+ * -+ * 09 22 2011 cm.chang -+ * NULL -+ * Safer writng stype to avoid unitialized regitry structure -+ * -+ * 09 21 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Avoid possible structure alignment problem -+ * -+ * 09 20 2011 chinglan.wang -+ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. -+ * . -+ * -+ * 09 08 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * expose scnQuerySparseChannel() for P2P-FSM. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting -+ * device issue. -+ * Fix GO send deauth frame issue. -+ * -+ * 07 07 2011 wh.su -+ * [WCXRP00000839] [MT6620 Wi-Fi][Driver] Add the dumpMemory8 and dumpMemory32 EXPORT_SYMBOL -+ * Add the dumpMemory8 symbol export for debug mode. -+ * -+ * 07 06 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Improve BoW connection establishment speed. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Export one symbol for enhancement. -+ * -+ * 06 13 2011 eddie.chen -+ * [WCXRP00000779] [MT6620 Wi-Fi][DRV] Add tx rx statistics in linux and use netif_rx_ni -+ * Add tx rx statistics and netif_rx_ni. -+ * -+ * 05 27 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. -+ * -+ * 05 18 2011 cp.wu -+ * [WCXRP00000734] [MT6620 Wi-Fi][Driver] Pass PHY_PARAM in NVRAM to firmware domain -+ * pass PHY_PARAM in NVRAM from driver to firmware. -+ * -+ * 05 09 2011 jeffrey.chang -+ * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change -+ * support ARP filter through kernel notifier -+ * -+ * 05 03 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Use kalMemAlloc to allocate event buffer for kalIndicateBOWEvent. -+ * -+ * 04 27 2011 george.huang -+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter -+ * Support P2P ARP filter setting on early suspend/ late resume -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 04 14 2011 yuche.tsai -+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. -+ * Modify some driver connection flow or behavior to pass Sigma test more easier.. -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 11 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * export wlan functions to p2p -+ * -+ * 04 08 2011 pat.lu -+ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver -+ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver -+ * -+ * 04 08 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * glBusFreeIrq() should use the same pvCookie as glBusSetIrq() or request_irq()/free_irq() won't work as a pair. -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 04 06 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * 1. do not check for pvData inside wlanNetCreate() due to it is NULL for eHPI port -+ * 2. update perm_addr as well for MAC address -+ * 3. not calling check_mem_region() anymore for eHPI -+ * 4. correct MSC_CS macro for 0-based notation -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * fix typo. -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism -+ * -+ * 03 23 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * apply multi-queue operation only for linux kernel > 2.6.26 -+ * -+ * 03 22 2011 pat.lu -+ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build -+ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability for compatible with linux 2.6.12. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * improve portability for awareness of early version of linux kernel and wireless extension. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 03 18 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * remove early suspend functions -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * reverse order to prevent probing racing. -+ * -+ * 03 16 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * 1. pre-allocate physical continuous buffer while module is being loaded -+ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer -+ * -+ * The windows part remained the same as before, but added similar APIs to hide the difference. -+ * -+ * 03 15 2011 jeffrey.chang -+ * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM -+ * refine the queue_select function -+ * -+ * 03 10 2011 cp.wu -+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 -+ * deprecate configuration used by MT6620 E2 -+ * -+ * 03 10 2011 terry.wu -+ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration -+ * Remove unnecessary assert and message. -+ * -+ * 03 08 2011 terry.wu -+ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration -+ * Export nicQmUpdateWmmParms. -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * support concurrent network -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * modify net device relative functions to support multiple H/W queues -+ * -+ * 02 24 2011 george.huang -+ * [WCXRP00000495] [MT6620 Wi-Fi][FW] Support pattern filter for unwanted ARP frames -+ * Support ARP filter during suspended -+ * -+ * 02 21 2011 cp.wu -+ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain -+ * simplify logic for checking NVRAM existence only once. -+ * -+ * 02 17 2011 terry.wu -+ * [WCXRP00000459] [MT6620 Wi-Fi][Driver] Fix deference null pointer problem in wlanRemove -+ * Fix deference a null pointer problem in wlanRemove. -+ * -+ * 02 16 2011 jeffrey.chang -+ * NULL -+ * fix compilig error -+ * -+ * 02 16 2011 jeffrey.chang -+ * NULL -+ * Add query ipv4 and ipv6 address during early suspend and late resume -+ * -+ * 02 15 2011 jeffrey.chang -+ * NULL -+ * to support early suspend in android -+ * -+ * 02 11 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add one more export symbol. -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add RX deauthentication & disassociation process under Hot-Spot mode. -+ * -+ * 02 09 2011 terry.wu -+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules -+ * Halt p2p module init and exit until TxThread finished p2p register and unregister. -+ * -+ * 02 08 2011 george.huang -+ * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler -+ * Support querying power mode OID. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000421] [Volunteer Patch][MT6620][Driver] Fix incorrect SSID length Issue -+ * Export Deactivation Network. -+ * -+ * 02 01 2011 jeffrey.chang -+ * [WCXRP00000414] KAL Timer is not unregistered when driver not loaded -+ * Unregister the KAL timer during driver unloading -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * Allocate system RAM if fixed message or mgmt buffer is not available -+ * -+ * 01 19 2011 cp.wu -+ * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7 -+ * add compile option to check linux version 2.6.35 for different usage of system API to improve portability -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues -+ * due to multiple access -+ * use mutex to protect kalIoctl() for thread safe. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 15 2010 cp.wu -+ * [WCXRP00000265] [MT6620 Wi-Fi][Driver] Remove set_mac_address routine from legacy Wi-Fi Android driver -+ * remove set MAC address. MAC address is always loaded from NVRAM instead. -+ * -+ * 12 10 2010 kevin.huang -+ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check -+ * Add Linux Proc Support -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add GPIO debug function -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] -+ * Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 21 2010 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * . -+ * -+ * 10 19 2010 jeffrey.chang -+ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK -+ * HIF by default -+ * Refine linux kernel module to the license of MTK and enable MTK HIF -+ * -+ * 10 18 2010 jeffrey.chang -+ * [WCXRP00000106] [MT6620 Wi-Fi][Driver] Enable setting multicast callback in Android -+ * . -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item -+ * use firmware reported mac address right after wlanAdapterStart() as permanent address -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 18 2010 yarco.yang -+ * NULL -+ * 1. Fixed HW checksum offload function not work under Linux issue. -+ * 2. Add debug message. -+ * -+ * 08 16 2010 yarco.yang -+ * NULL -+ * Support Linux x86 -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 29 2010 jeffrey.chang -+ * NULL -+ * fix memory leak for module unloading -+ * -+ * 07 28 2010 jeffrey.chang -+ * NULL -+ * 1) remove unused spinlocks -+ * 2) enable encyption ioctls -+ * 3) fix scan ioctl which may cause supplicant to hang -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * bug fix: allocate regInfo when disabling firmware download -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * use glue layer api to decrease or increase counter atomically -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * add new spinlock -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * modify cmd/data path for new design -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) Modify set mac address code -+ * 2) remove power management macro -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement basic wi-fi direct framework -+ * -+ * 05 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * prevent supplicant accessing driver during resume -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic framework for implementating P2P driver hook. -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) fix firmware download bug -+ * 2) remove query statistics for acelerating firmware download -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * follow Linux's firmware framework, and remove unused kal API -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Query statistics from firmware -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * modify tcp/ip checksum offload flags -+ * -+ * 04 16 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix tcp/ip checksum offload bug -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler -+ * * * * * * * * * * * * * * * * * capability -+ * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix spinlock usage -+ * -+ * 04 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Set MAC address from firmware -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * * are done in adapter layer. -+ * -+ * 04 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * (1)improve none-glue code portability -+ * * (2) disable set Multicast address during atomic context -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding debug module -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * emulate NDIS Pending OID facility -+ * -+ * 03 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix f/w download start and load address by using config.h -+ * -+ * 03 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * adding firmware download support -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\52 2009-10-27 22:49:59 GMT mtk01090 -+** Fix compile error for Linux EHPI driver -+** \main\maintrunk.MT5921\51 2009-10-20 17:38:22 GMT mtk01090 -+** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, -+** and then stop hw. -+** \main\maintrunk.MT5921\50 2009-10-08 10:33:11 GMT mtk01090 -+** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input -+** parameters and pointers. -+** \main\maintrunk.MT5921\49 2009-09-28 20:19:05 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\48 2009-09-03 13:58:46 GMT mtk01088 -+** remove non-used code -+** \main\maintrunk.MT5921\47 2009-09-03 11:40:25 GMT mtk01088 -+** adding the module parameter for wapi -+** \main\maintrunk.MT5921\46 2009-08-18 22:56:41 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\45 2009-07-06 20:53:00 GMT mtk01088 -+** adding the code to check the wapi 1x frame -+** \main\maintrunk.MT5921\44 2009-06-23 23:18:55 GMT mtk01090 -+** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support -+** \main\maintrunk.MT5921\43 2009-02-16 23:46:51 GMT mtk01461 -+** Revise the order of increasing u4TxPendingFrameNum because of CFG_TX_RET_TX_CTRL_EARLY -+** \main\maintrunk.MT5921\42 2009-01-22 13:11:59 GMT mtk01088 -+** set the tid and 1x value at same packet reserved field -+** \main\maintrunk.MT5921\41 2008-10-20 22:43:53 GMT mtk01104 -+** Fix wrong variable name "prDev" in wlanStop() -+** \main\maintrunk.MT5921\40 2008-10-16 15:37:10 GMT mtk01461 -+** add handle WLAN_STATUS_SUCCESS in wlanHardStartXmit() for CFG_TX_RET_TX_CTRL_EARLY -+** \main\maintrunk.MT5921\39 2008-09-25 15:56:21 GMT mtk01461 -+** Update driver for Code review -+** \main\maintrunk.MT5921\38 2008-09-05 17:25:07 GMT mtk01461 -+** Update Driver for Code Review -+** \main\maintrunk.MT5921\37 2008-09-02 10:57:06 GMT mtk01461 -+** Update driver for code review -+** \main\maintrunk.MT5921\36 2008-08-05 01:53:28 GMT mtk01461 -+** Add support for linux statistics -+** \main\maintrunk.MT5921\35 2008-08-04 16:52:58 GMT mtk01461 -+** Fix ASSERT if removing module in BG_SSID_SCAN state -+** \main\maintrunk.MT5921\34 2008-06-13 22:52:24 GMT mtk01461 -+** Revise status code handling in wlanHardStartXmit() for WLAN_STATUS_SUCCESS -+** \main\maintrunk.MT5921\33 2008-05-30 18:56:53 GMT mtk01461 -+** Not use wlanoidSetCurrentAddrForLinux() -+** \main\maintrunk.MT5921\32 2008-05-30 14:39:40 GMT mtk01461 -+** Remove WMM Assoc Flag -+** \main\maintrunk.MT5921\31 2008-05-23 10:26:40 GMT mtk01084 -+** modify wlanISR interface -+** \main\maintrunk.MT5921\30 2008-05-03 18:52:36 GMT mtk01461 -+** Fix Unset Broadcast filter when setMulticast -+** \main\maintrunk.MT5921\29 2008-05-03 15:17:26 GMT mtk01461 -+** Move Query Media Status to GLUE -+** \main\maintrunk.MT5921\28 2008-04-24 22:48:21 GMT mtk01461 -+** Revise set multicast function by using windows oid style for LP own back -+** \main\maintrunk.MT5921\27 2008-04-24 12:00:08 GMT mtk01461 -+** Fix multicast setting in Linux and add comment -+** \main\maintrunk.MT5921\26 2008-03-28 10:40:22 GMT mtk01461 -+** Fix set mac address func in Linux -+** \main\maintrunk.MT5921\25 2008-03-26 15:37:26 GMT mtk01461 -+** Add set MAC Address -+** \main\maintrunk.MT5921\24 2008-03-26 14:24:53 GMT mtk01461 -+** For Linux, set net_device has feature with checksum offload by default -+** \main\maintrunk.MT5921\23 2008-03-11 14:50:52 GMT mtk01461 -+** Fix typo -+** \main\maintrunk.MT5921\22 2008-02-29 15:35:20 GMT mtk01088 -+** add 1x decide code for sw port control -+** \main\maintrunk.MT5921\21 2008-02-21 15:01:54 GMT mtk01461 -+** Rearrange the set off place of GLUE spin lock in HardStartXmit -+** \main\maintrunk.MT5921\20 2008-02-12 23:26:50 GMT mtk01461 -+** Add debug option - Packet Order for Linux and add debug level - Event -+** \main\maintrunk.MT5921\19 2007-12-11 00:11:12 GMT mtk01461 -+** Fix SPIN_LOCK protection -+** \main\maintrunk.MT5921\18 2007-11-30 17:02:25 GMT mtk01425 -+** 1. Set Rx multicast packets mode before setting the address list -+** \main\maintrunk.MT5921\17 2007-11-26 19:44:24 GMT mtk01461 -+** Add OS_TIMESTAMP to packet -+** \main\maintrunk.MT5921\16 2007-11-21 15:47:20 GMT mtk01088 -+** fixed the unload module issue -+** \main\maintrunk.MT5921\15 2007-11-07 18:37:38 GMT mtk01461 -+** Fix compile warnning -+** \main\maintrunk.MT5921\14 2007-11-02 01:03:19 GMT mtk01461 -+** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning -+** \main\maintrunk.MT5921\13 2007-10-30 10:42:33 GMT mtk01425 -+** 1. Refine for multicast list -+** \main\maintrunk.MT5921\12 2007-10-25 18:08:13 GMT mtk01461 -+** Add VOIP SCAN Support & Refine Roaming -+** Revision 1.4 2007/07/05 07:25:33 MTK01461 -+** Add Linux initial code, modify doc, add 11BB, RF init code -+** -+** Revision 1.3 2007/06/27 02:18:50 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+** Revision 1.2 2007/06/25 06:16:24 MTK01461 -+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_os.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include "gl_cfg80211.h" -+#include "precomp.h" -+#if CFG_SUPPORT_AGPS_ASSIST -+#include "gl_kal.h" -+#endif -+#if defined(CONFIG_MTK_TC1_FEATURE) -+#include -+#endif -+#include "gl_vendor.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* #define MAX_IOREQ_NUM 10 */ -+ -+BOOLEAN fgIsUnderSuspend = false; -+ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+spinlock_t g_p2p_lock; -+int g_u4P2PEnding = 0; -+int g_u4P2POnOffing = 0; -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Tasklet mechanism is like buttom-half in Linux. We just want to -+ * send a signal to OS for interrupt defer processing. All resources -+ * are NOT allowed reentry, so txPacket, ISR-DPC and ioctl must avoid preempty. -+ */ -+typedef struct _WLANDEV_INFO_T { -+ struct net_device *prDev; -+} WLANDEV_INFO_T, *P_WLANDEV_INFO_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+#define CHAN2G(_channel, _freq, _flags) \ -+{ \ -+ .band = NL80211_BAND_2GHZ, \ -+ .center_freq = (_freq), \ -+ .hw_value = (_channel), \ -+ .flags = (_flags), \ -+ .max_antenna_gain = 0, \ -+ .max_power = 30, \ -+} -+ -+static struct ieee80211_channel mtk_2ghz_channels[] = { -+ CHAN2G(1, 2412, 0), -+ CHAN2G(2, 2417, 0), -+ CHAN2G(3, 2422, 0), -+ CHAN2G(4, 2427, 0), -+ CHAN2G(5, 2432, 0), -+ CHAN2G(6, 2437, 0), -+ CHAN2G(7, 2442, 0), -+ CHAN2G(8, 2447, 0), -+ CHAN2G(9, 2452, 0), -+ CHAN2G(10, 2457, 0), -+ CHAN2G(11, 2462, 0), -+ CHAN2G(12, 2467, 0), -+ CHAN2G(13, 2472, 0), -+ CHAN2G(14, 2484, 0), -+}; -+ -+#define CHAN5G(_channel, _flags) \ -+{ \ -+ .band = NL80211_BAND_5GHZ, \ -+ .center_freq = 5000 + (5 * (_channel)), \ -+ .hw_value = (_channel), \ -+ .flags = (_flags), \ -+ .max_antenna_gain = 0, \ -+ .max_power = 30, \ -+} -+ -+static struct ieee80211_channel mtk_5ghz_channels[] = { -+ CHAN5G(34, 0), CHAN5G(36, 0), -+ CHAN5G(38, 0), CHAN5G(40, 0), -+ CHAN5G(42, 0), CHAN5G(44, 0), -+ CHAN5G(46, 0), CHAN5G(48, 0), -+ CHAN5G(52, 0), CHAN5G(56, 0), -+ CHAN5G(60, 0), CHAN5G(64, 0), -+ CHAN5G(100, 0), CHAN5G(104, 0), -+ CHAN5G(108, 0), CHAN5G(112, 0), -+ CHAN5G(116, 0), CHAN5G(120, 0), -+ CHAN5G(124, 0), CHAN5G(128, 0), -+ CHAN5G(132, 0), CHAN5G(136, 0), -+ CHAN5G(140, 0), CHAN5G(149, 0), -+ CHAN5G(153, 0), CHAN5G(157, 0), -+ CHAN5G(161, 0), CHAN5G(165, 0), -+ CHAN5G(169, 0), CHAN5G(173, 0), -+ CHAN5G(184, 0), CHAN5G(188, 0), -+ CHAN5G(192, 0), CHAN5G(196, 0), -+ CHAN5G(200, 0), CHAN5G(204, 0), -+ CHAN5G(208, 0), CHAN5G(212, 0), -+ CHAN5G(216, 0), -+}; -+ -+#define RATETAB_ENT(_rate, _rateid, _flags) \ -+{ \ -+ .bitrate = (_rate), \ -+ .hw_value = (_rateid), \ -+ .flags = (_flags), \ -+} -+ -+/* for cfg80211 - rate table */ -+static struct ieee80211_rate mtk_rates[] = { -+ RATETAB_ENT(10, 0x1000, 0), -+ RATETAB_ENT(20, 0x1001, 0), -+ RATETAB_ENT(55, 0x1002, 0), -+ RATETAB_ENT(110, 0x1003, 0), /* 802.11b */ -+ RATETAB_ENT(60, 0x2000, 0), -+ RATETAB_ENT(90, 0x2001, 0), -+ RATETAB_ENT(120, 0x2002, 0), -+ RATETAB_ENT(180, 0x2003, 0), -+ RATETAB_ENT(240, 0x2004, 0), -+ RATETAB_ENT(360, 0x2005, 0), -+ RATETAB_ENT(480, 0x2006, 0), -+ RATETAB_ENT(540, 0x2007, 0), /* 802.11a/g */ -+}; -+ -+#define mtk_a_rates (mtk_rates + 4) -+#define mtk_a_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 4) -+#define mtk_g_rates (mtk_rates + 0) -+#define mtk_g_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 0) -+ -+#define WLAN_MCS_INFO \ -+{ \ -+ .rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ -+ .rx_highest = 0, \ -+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ -+} -+ -+#define WLAN_HT_CAP \ -+{ \ -+ .ht_supported = true, \ -+ .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 \ -+ | IEEE80211_HT_CAP_SM_PS \ -+ | IEEE80211_HT_CAP_GRN_FLD \ -+ | IEEE80211_HT_CAP_SGI_20 \ -+ | IEEE80211_HT_CAP_SGI_40, \ -+ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \ -+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE, \ -+ .mcs = WLAN_MCS_INFO, \ -+} -+ -+/********************************************************** -+* Public for both legacy Wi-Fi and P2P to access -+**********************************************************/ -+struct ieee80211_supported_band mtk_band_2ghz = { -+ .band = NL80211_BAND_2GHZ, -+ .channels = mtk_2ghz_channels, -+ .n_channels = ARRAY_SIZE(mtk_2ghz_channels), -+ .bitrates = mtk_g_rates, -+ .n_bitrates = mtk_g_rates_size, -+ .ht_cap = WLAN_HT_CAP, -+}; -+ -+struct ieee80211_supported_band mtk_band_5ghz = { -+ .band = NL80211_BAND_5GHZ, -+ .channels = mtk_5ghz_channels, -+ .n_channels = ARRAY_SIZE(mtk_5ghz_channels), -+ .bitrates = mtk_a_rates, -+ .n_bitrates = mtk_a_rates_size, -+ .ht_cap = WLAN_HT_CAP, -+}; -+ -+const UINT_32 mtk_cipher_suites[5] = { -+ /* keep WEP first, it may be removed below */ -+ WLAN_CIPHER_SUITE_WEP40, -+ WLAN_CIPHER_SUITE_WEP104, -+ WLAN_CIPHER_SUITE_TKIP, -+ WLAN_CIPHER_SUITE_CCMP, -+ -+ /* keep last -- depends on hw flags! */ -+ WLAN_CIPHER_SUITE_AES_CMAC -+}; -+ -+/*********************************************************/ -+ -+#define NIC_INF_NAME "wlan%d" /* interface name */ -+#if CFG_TC1_FEATURE -+#define NIC_INF_NAME_IN_AP_MODE "legacy%d" -+#endif -+ -+/* support to change debug module info dynamically */ -+UINT_8 aucDebugModule[DBG_MODULE_NUM]; -+UINT_32 u4DebugModule = 0; -+ -+/* 4 2007/06/26, mikewu, now we don't use this, we just fix the number of wlan device to 1 */ -+static WLANDEV_INFO_T arWlanDevInfo[CFG_MAX_WLAN_DEVICES] = { {0} }; -+ -+static UINT_32 u4WlanDevNum; /* How many NICs coexist now */ -+ -+/**20150205 added work queue for sched_scan to avoid cfg80211 stop schedule scan dead loack**/ -+struct delayed_work sched_workq; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if CFG_ENABLE_WIFI_DIRECT -+static SUB_MODULE_HANDLER rSubModHandler[SUB_MODULE_NUM] = { {NULL} }; -+#endif -+ -+static struct cfg80211_ops mtk_wlan_ops = { -+ .suspend = mtk_cfg80211_suspend, -+ .resume = mtk_cfg80211_resume, -+ .change_virtual_intf = mtk_cfg80211_change_iface, -+ .add_key = mtk_cfg80211_add_key, -+ .get_key = mtk_cfg80211_get_key, -+ .del_key = mtk_cfg80211_del_key, -+ .set_default_key = mtk_cfg80211_set_default_key, -+ .set_default_mgmt_key = mtk_cfg80211_set_default_mgmt_key, -+ .get_station = mtk_cfg80211_get_station, -+ .change_station = mtk_cfg80211_change_station, -+ .add_station = mtk_cfg80211_add_station, -+ .del_station = mtk_cfg80211_del_station, -+ .scan = mtk_cfg80211_scan, -+ .connect = mtk_cfg80211_connect, -+ .disconnect = mtk_cfg80211_disconnect, -+ .join_ibss = mtk_cfg80211_join_ibss, -+ .leave_ibss = mtk_cfg80211_leave_ibss, -+ .set_power_mgmt = mtk_cfg80211_set_power_mgmt, -+ .set_pmksa = mtk_cfg80211_set_pmksa, -+ .del_pmksa = mtk_cfg80211_del_pmksa, -+ .flush_pmksa = mtk_cfg80211_flush_pmksa, -+ .assoc = mtk_cfg80211_assoc, -+ /* Action Frame TX/RX */ -+ .remain_on_channel = mtk_cfg80211_remain_on_channel, -+ .cancel_remain_on_channel = mtk_cfg80211_cancel_remain_on_channel, -+ .mgmt_tx = mtk_cfg80211_mgmt_tx, -+/* .mgmt_tx_cancel_wait = mtk_cfg80211_mgmt_tx_cancel_wait, */ -+ .mgmt_frame_register = mtk_cfg80211_mgmt_frame_register, -+#ifdef CONFIG_NL80211_TESTMODE -+ .testmode_cmd = mtk_cfg80211_testmode_cmd, -+#endif -+#if (CFG_SUPPORT_TDLS == 1) -+ .tdls_mgmt = TdlsexCfg80211TdlsMgmt, -+ .tdls_oper = TdlsexCfg80211TdlsOper, -+#endif /* CFG_SUPPORT_TDLS */ -+#if 1 /* Remove schedule_scan because we need more verification for NLO */ -+ .sched_scan_start = mtk_cfg80211_sched_scan_start, -+ .sched_scan_stop = mtk_cfg80211_sched_scan_stop, -+#endif -+}; -+ -+static const struct wiphy_vendor_command mtk_wlan_vendor_ops[] = { -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = WIFI_SUBCMD_GET_CHANNEL_LIST -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_get_channel_list -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_set_country_code -+ }, -+ /* GSCAN */ -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_GET_CAPABILITIES -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_get_gscan_capabilities -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_SET_CONFIG -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_set_config -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_SET_SCAN_CONFIG -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV, -+ .doit = mtk_cfg80211_vendor_set_scan_config -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_ENABLE_GSCAN -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_enable_scan -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_enable_full_scan_results -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_GET_SCAN_RESULTS -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_get_scan_results -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_set_significant_change -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_SET_HOTLIST -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_set_hotlist -+ }, -+ /* RTT */ -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = RTT_SUBCMD_GETCAPABILITY -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_get_rtt_capabilities -+ }, -+ /* Link Layer Statistics */ -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = LSTATS_SUBCMD_GET_INFO -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_llstats_get_info -+ }, -+ -+}; -+ -+static const struct nl80211_vendor_cmd_info mtk_wlan_vendor_events[] = { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_HOTLIST_RESULTS_FOUND -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_SCAN_RESULTS_AVAILABLE -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_FULL_SCAN_RESULTS -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = RTT_EVENT_COMPLETE -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_COMPLETE_SCAN -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_HOTLIST_RESULTS_LOST -+ }, -+}; -+ -+/* There isn't a lot of sense in it, but you can transmit anything you like */ -+static const struct ieee80211_txrx_stypes -+ mtk_cfg80211_ais_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { -+ [NL80211_IFTYPE_ADHOC] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_STATION] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) -+ }, -+ [NL80211_IFTYPE_AP] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_AP_VLAN] = { -+ /* copy AP */ -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | -+ BIT(IEEE80211_STYPE_DISASSOC >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4) | -+ BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_P2P_CLIENT] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) -+ }, -+ [NL80211_IFTYPE_P2P_GO] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ } -+}; -+ -+#ifdef CONFIG_PM -+static const struct wiphy_wowlan_support mtk_wlan_wowlan_support = { -+ .flags = WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_ANY, -+}; -+#endif -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Override the implementation of select queue -+* -+* \param[in] dev Pointer to struct net_device -+* \param[in] skb Pointer to struct skb_buff -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+unsigned int _cfg80211_classify8021d(struct sk_buff *skb) -+{ -+ unsigned int dscp = 0; -+ -+ /* skb->priority values from 256->263 are magic values -+ * directly indicate a specific 802.1d priority. This is -+ * to allow 802.1d priority to be passed directly in from -+ * tags -+ */ -+ -+ if (skb->priority >= 256 && skb->priority <= 263) -+ return skb->priority - 256; -+ switch (skb->protocol) { -+ case htons(ETH_P_IP): -+ dscp = ip_hdr(skb)->tos & 0xfc; -+ break; -+ } -+ return dscp >> 5; -+} -+ -+static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; -+ -+static UINT_16 wlanSelectQueue(struct net_device *dev, struct sk_buff *skb, -+ struct net_device *sb_dev, -+ select_queue_fallback_t fallback) -+{ -+ skb->priority = _cfg80211_classify8021d(skb); -+ -+ return au16Wlan1dToQueueIdx[skb->priority]; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Load NVRAM data and translate it into REG_INFO_T -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* \param[out] prRegInfo Pointer to struct REG_INFO_T -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static void glLoadNvram(IN P_GLUE_INFO_T prGlueInfo, OUT P_REG_INFO_T prRegInfo) -+{ -+ UINT_32 i, j; -+ UINT_8 aucTmp[2]; -+ PUINT_8 pucDest; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prRegInfo); -+ -+ if ((!prGlueInfo) || (!prRegInfo)) -+ return; -+ -+ if (kalCfgDataRead16(prGlueInfo, sizeof(WIFI_CFG_PARAM_STRUCT) - sizeof(UINT_16), (PUINT_16) aucTmp) == TRUE) { -+ prGlueInfo->fgNvramAvailable = TRUE; -+ -+ /* load MAC Address */ -+#if !defined(CONFIG_MTK_TC1_FEATURE) -+ for (i = 0; i < PARAM_MAC_ADDR_LEN; i += sizeof(UINT_16)) { -+ kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i, -+ (PUINT_16) (((PUINT_8) prRegInfo->aucMacAddr) + i)); -+ } -+#else -+ TC1_FAC_NAME(FacReadWifiMacAddr) ((unsigned char *)prRegInfo->aucMacAddr); -+#endif -+ -+ /* load country code */ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucCountryCode[0]), (PUINT_16) aucTmp); -+ -+ /* cast to wide characters */ -+ prRegInfo->au2CountryCode[0] = (UINT_16) aucTmp[0]; -+ prRegInfo->au2CountryCode[1] = (UINT_16) aucTmp[1]; -+ -+ /* load default normal TX power */ -+ for (i = 0; i < sizeof(TX_PWR_PARAM_T); i += sizeof(UINT_16)) { -+ kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, rTxPwr) + i, -+ (PUINT_16) (((PUINT_8) &(prRegInfo->rTxPwr)) + i)); -+ } -+ -+ /* load feature flags */ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucTxPwrValid), (PUINT_16) aucTmp); -+ prRegInfo->ucTxPwrValid = aucTmp[0]; -+ prRegInfo->ucSupport5GBand = aucTmp[1]; -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2G4BwFixed20M), (PUINT_16) aucTmp); -+ prRegInfo->uc2G4BwFixed20M = aucTmp[0]; -+ prRegInfo->uc5GBwFixed20M = aucTmp[1]; -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucEnable5GBand), (PUINT_16) aucTmp); -+ prRegInfo->ucEnable5GBand = aucTmp[0]; -+ -+ /* load EFUSE overriding part */ -+ for (i = 0; i < sizeof(prRegInfo->aucEFUSE); i += sizeof(UINT_16)) { -+ kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) + i, -+ (PUINT_16) (((PUINT_8) &(prRegInfo->aucEFUSE)) + i)); -+ } -+ -+ /* load band edge tx power control */ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fg2G4BandEdgePwrUsed), (PUINT_16) aucTmp); -+ prRegInfo->fg2G4BandEdgePwrUsed = (BOOLEAN) aucTmp[0]; -+ if (aucTmp[0]) { -+ prRegInfo->cBandEdgeMaxPwrCCK = (INT_8) aucTmp[1]; -+ -+ kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, cBandEdgeMaxPwrOFDM20), (PUINT_16) aucTmp); -+ prRegInfo->cBandEdgeMaxPwrOFDM20 = (INT_8) aucTmp[0]; -+ prRegInfo->cBandEdgeMaxPwrOFDM40 = (INT_8) aucTmp[1]; -+ } -+ -+ /* load regulation subbands */ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucRegChannelListMap), (PUINT_16) aucTmp); -+ prRegInfo->eRegChannelListMap = (ENUM_REG_CH_MAP_T) aucTmp[0]; -+ prRegInfo->ucRegChannelListIndex = aucTmp[1]; -+ -+ if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) { -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ pucDest = (PUINT_8) &prRegInfo->rDomainInfo.rSubBand[i]; -+ for (j = 0; j < 6; j += sizeof(UINT_16)) { -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo) -+ + (i * 6 + j), (PUINT_16) aucTmp); -+ -+ *pucDest++ = aucTmp[0]; -+ *pucDest++ = aucTmp[1]; -+ } -+ } -+ } -+ /* load RSSI compensation */ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2GRssiCompensation), (PUINT_16) aucTmp); -+ prRegInfo->uc2GRssiCompensation = aucTmp[0]; -+ prRegInfo->uc5GRssiCompensation = aucTmp[1]; -+ -+ kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fgRssiCompensationValidbit), (PUINT_16) aucTmp); -+ prRegInfo->fgRssiCompensationValidbit = aucTmp[0]; -+ prRegInfo->ucRxAntennanumber = aucTmp[1]; -+ } else { -+ prGlueInfo->fgNvramAvailable = FALSE; -+ } -+ -+} -+ -+#if CFG_ENABLE_WIFI_DIRECT -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief called by txthread, run sub module init function -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSubModRunInit(P_GLUE_INFO_T prGlueInfo) -+{ -+ /*now, we only have p2p module */ -+ if (rSubModHandler[P2P_MODULE].fgIsInited == FALSE) { -+ rSubModHandler[P2P_MODULE].subModInit(prGlueInfo); -+ rSubModHandler[P2P_MODULE].fgIsInited = TRUE; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief called by txthread, run sub module exit function -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSubModRunExit(P_GLUE_INFO_T prGlueInfo) -+{ -+ /*now, we only have p2p module */ -+ if (rSubModHandler[P2P_MODULE].fgIsInited == TRUE) { -+ rSubModHandler[P2P_MODULE].subModExit(prGlueInfo); -+ rSubModHandler[P2P_MODULE].fgIsInited = FALSE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief set sub module init flag, force TxThread to run sub modle init -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanSubModInit(P_GLUE_INFO_T prGlueInfo) -+{ -+ /* 4 Mark HALT, notify main thread to finish current job */ -+ prGlueInfo->ulFlag |= GLUE_FLAG_SUB_MOD_INIT; -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ /* wait main thread finish sub module INIT */ -+ wait_for_completion_interruptible(&prGlueInfo->rSubModComp); -+ -+#if 0 -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ p2pNetRegister(prGlueInfo); -+#endif -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief set sub module exit flag, force TxThread to run sub modle exit -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanSubModExit(P_GLUE_INFO_T prGlueInfo) -+{ -+#if 0 -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ p2pNetUnregister(prGlueInfo); -+#endif -+ -+ /* 4 Mark HALT, notify main thread to finish current job */ -+ prGlueInfo->ulFlag |= GLUE_FLAG_SUB_MOD_EXIT; -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ /* wait main thread finish sub module EXIT */ -+ wait_for_completion_interruptible(&prGlueInfo->rSubModComp); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief set by sub module, indicate sub module is already inserted -+* -+* \param[in] rSubModInit, function pointer point to sub module init function -+* \param[in] rSubModExit, function pointer point to sub module exit function -+* \param[in] eSubModIdx, sub module index -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+wlanSubModRegisterInitExit(SUB_MODULE_INIT rSubModInit, SUB_MODULE_EXIT rSubModExit, ENUM_SUB_MODULE_IDX_T eSubModIdx) -+{ -+ rSubModHandler[eSubModIdx].subModInit = rSubModInit; -+ rSubModHandler[eSubModIdx].subModExit = rSubModExit; -+ rSubModHandler[eSubModIdx].fgIsInited = FALSE; -+} -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief check wlan is launched or not -+* -+* \param[in] (none) -+* -+* \return TRUE, wlan is already started -+* FALSE, wlan is not started yet -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanIsLaunched(VOID) -+{ -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ /* 4 <0> Sanity check */ -+ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); -+ if (0 == u4WlanDevNum) -+ return FALSE; -+ -+ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; -+ -+ ASSERT(prDev); -+ if (NULL == prDev) -+ return FALSE; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ if (NULL == prGlueInfo) -+ return FALSE; -+ -+ return prGlueInfo->prAdapter->fgIsWlanLaunched; -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Export wlan GLUE_INFO_T pointer to p2p module -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* -+* \return TRUE: get GlueInfo pointer successfully -+* FALSE: wlan is not started yet -+*/ -+/*---------------------------------------------------------------------------*/ -+BOOLEAN wlanExportGlueInfo(P_GLUE_INFO_T *prGlueInfoExpAddr) -+{ -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ if (0 == u4WlanDevNum) -+ return FALSE; -+ -+ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; -+ if (NULL == prDev) -+ return FALSE; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ if (NULL == prGlueInfo) -+ return FALSE; -+ -+ if (FALSE == prGlueInfo->prAdapter->fgIsWlanLaunched) -+ return FALSE; -+ -+ *prGlueInfoExpAddr = prGlueInfo; -+ return TRUE; -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Release prDev from wlandev_array and free tasklet object related to it. -+* -+* \param[in] prDev Pointer to struct net_device -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static void wlanClearDevIdx(struct net_device *prDev) -+{ -+ int i; -+ -+ ASSERT(prDev); -+ -+ for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) { -+ if (arWlanDevInfo[i].prDev == prDev) { -+ arWlanDevInfo[i].prDev = NULL; -+ u4WlanDevNum--; -+ } -+ } -+ -+} /* end of wlanClearDevIdx() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Allocate an unique interface index, net_device::ifindex member for this -+* wlan device. Store the net_device in wlandev_array, and initialize -+* tasklet object related to it. -+* -+* \param[in] prDev Pointer to struct net_device -+* -+* \retval >= 0 The device number. -+* \retval -1 Fail to get index. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wlanGetDevIdx(struct net_device *prDev) -+{ -+ int i; -+ -+ ASSERT(prDev); -+ -+ for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) { -+ if (arWlanDevInfo[i].prDev == (struct net_device *)NULL) { -+ /* Reserve 2 bytes space to store one digit of -+ * device number and NULL terminator. -+ */ -+ arWlanDevInfo[i].prDev = prDev; -+ u4WlanDevNum++; -+ return i; -+ } -+ } -+ -+ return -1; -+} /* end of wlanGetDevIdx() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A method of struct net_device, a primary SOCKET interface to configure -+* the interface lively. Handle an ioctl call on one of our devices. -+* Everything Linux ioctl specific is done here. Then we pass the contents -+* of the ifr->data to the request message handler. -+* -+* \param[in] prDev Linux kernel netdevice -+* -+* \param[in] prIfReq Our private ioctl request structure, typed for the generic -+* struct ifreq so we can use ptr to function -+* -+* \param[in] cmd Command ID -+* -+* \retval 0 The IOCTL command is executed successfully. -+* \retval <0 The execution of IOCTL command is failed. -+*/ -+/*----------------------------------------------------------------------------*/ -+int wlanDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ int ret = 0; -+ -+ /* Verify input parameters for the following functions */ -+ ASSERT(prDev && prIfReq); -+ if (!prDev || !prIfReq) { -+ DBGLOG(INIT, ERROR, "Invalid input data\n"); -+ return -EINVAL; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ if (!prGlueInfo) { -+ DBGLOG(INIT, ERROR, "prGlueInfo is NULL\n"); -+ return -EFAULT; -+ } -+ -+ if (prGlueInfo->u4ReadyFlag == 0) { -+ DBGLOG(INIT, ERROR, "Adapter is not ready\n"); -+ return -EINVAL; -+ } -+ -+ if ((i4Cmd >= SIOCIWFIRST) && (i4Cmd < SIOCIWFIRSTPRIV)) { -+ /* 0x8B00 ~ 0x8BDF, wireless extension region */ -+ ret = wext_support_ioctl(prDev, prIfReq, i4Cmd); -+ } else if ((i4Cmd >= SIOCIWFIRSTPRIV) && (i4Cmd < SIOCIWLASTPRIV)) { -+ /* 0x8BE0 ~ 0x8BFF, private ioctl region */ -+ ret = priv_support_ioctl(prDev, prIfReq, i4Cmd); -+ } else if (i4Cmd == SIOCDEVPRIVATE + 1) { -+ ret = priv_support_driver_cmd(prDev, prIfReq, i4Cmd); -+ } else { -+ DBGLOG(INIT, WARN, "Unexpected ioctl command: 0x%04x\n", i4Cmd); -+ ret = -EOPNOTSUPP; -+ } -+ -+ return ret; -+} /* end of wlanDoIOCTL() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to set multicast list and set rx mode. -+* -+* \param[in] prDev Pointer to struct net_device -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+static struct delayed_work workq; -+static struct net_device *gPrDev; -+static BOOLEAN fgIsWorkMcStart = FALSE; -+static BOOLEAN fgIsWorkMcEverInit = FALSE; -+static struct wireless_dev *gprWdev; -+ -+static void createWirelessDevice(void) -+{ -+ struct wiphy *prWiphy = NULL; -+ struct wireless_dev *prWdev = NULL; -+#if CFG_SUPPORT_PERSIST_NETDEV -+ struct net_device *prNetDev = NULL; -+#endif -+ -+ /* <1.1> Create wireless_dev */ -+ prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); -+ if (!prWdev) { -+ DBGLOG(INIT, ERROR, "Allocating memory to wireless_dev context failed\n"); -+ return; -+ } -+ -+ -+ /* <1.2> Create wiphy */ -+ prWiphy = wiphy_new(&mtk_wlan_ops, sizeof(GLUE_INFO_T)); -+ if (!prWiphy) { -+ DBGLOG(INIT, ERROR, "Allocating memory to wiphy device failed\n"); -+ goto free_wdev; -+ } -+ -+ /* <1.3> configure wireless_dev & wiphy */ -+ prWdev->iftype = NL80211_IFTYPE_STATION; -+ prWiphy->max_scan_ssids = 1; /* FIXME: for combo scan */ -+ prWiphy->max_scan_ie_len = 512; -+ -+ prWiphy->max_sched_scan_ssids = CFG_SCAN_SSID_MAX_NUM; -+ prWiphy->max_match_sets = CFG_SCAN_SSID_MATCH_MAX_NUM; -+ prWiphy->max_sched_scan_ie_len = CFG_CFG80211_IE_BUF_LEN; -+ prWiphy->max_sched_scan_reqs = 1; -+ -+ prWiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); -+ prWiphy->bands[NL80211_BAND_2GHZ] = &mtk_band_2ghz; -+ /* always assign 5Ghz bands here, if the chip is not support 5Ghz, -+ bands[IEEE80211_BAND_5GHZ] will be assign to NULL */ -+ prWiphy->bands[NL80211_BAND_5GHZ] = &mtk_band_5ghz; -+ prWiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; -+ prWiphy->cipher_suites = mtk_cipher_suites; -+ prWiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites); -+ prWiphy->flags = WIPHY_FLAG_SUPPORTS_FW_ROAM -+ | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; -+ prWiphy->regulatory_flags = REGULATORY_CUSTOM_REG; -+#if CFG_SUPPORT_TDLS -+ TDLSEX_WIPHY_FLAGS_INIT(prWiphy->flags); -+#endif /* CFG_SUPPORT_TDLS */ -+ prWiphy->max_remain_on_channel_duration = 5000; -+ prWiphy->mgmt_stypes = mtk_cfg80211_ais_default_mgmt_stypes; -+ prWiphy->vendor_commands = mtk_wlan_vendor_ops; -+ prWiphy->n_vendor_commands = sizeof(mtk_wlan_vendor_ops) / sizeof(struct wiphy_vendor_command); -+ prWiphy->vendor_events = mtk_wlan_vendor_events; -+ prWiphy->n_vendor_events = ARRAY_SIZE(mtk_wlan_vendor_events); -+ -+ /* <1.4> wowlan support */ -+#ifdef CONFIG_PM -+ prWiphy->wowlan = &mtk_wlan_wowlan_support; -+#endif -+#ifdef CONFIG_CFG80211_WEXT -+ /* <1.5> Use wireless extension to replace IOCTL */ -+ prWiphy->wext = &wext_handler_def; -+#endif -+ -+ if (wiphy_register(prWiphy) < 0) { -+ DBGLOG(INIT, ERROR, "wiphy_register error\n"); -+ goto free_wiphy; -+ } -+ prWdev->wiphy = prWiphy; -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+ /* <2> allocate and register net_device */ -+#if CFG_TC1_FEATURE -+ if (wlan_if_changed) -+ prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME_IN_AP_MODE, NET_NAME_PREDICTABLE, -+ ether_setup, CFG_MAX_TXQ_NUM); -+ else -+#else -+ prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE, -+ ether_setup, CFG_MAX_TXQ_NUM); -+#endif -+ if (!prNetDev) { -+ DBGLOG(INIT, ERROR, "Allocating memory to net_device context failed\n"); -+ goto unregister_wiphy; -+ } -+ -+ *((P_GLUE_INFO_T *) netdev_priv(prNetDev)) = (P_GLUE_INFO_T) wiphy_priv(prWiphy); -+ -+ prNetDev->netdev_ops = &wlan_netdev_ops; -+#ifdef CONFIG_WIRELESS_EXT -+ prNetDev->wireless_handlers = &wext_handler_def; -+#endif -+ netif_carrier_off(prNetDev); -+ netif_tx_stop_all_queues(prNetDev); -+ -+ /* <2.1> co-relate with wireless_dev bi-directionally */ -+ prNetDev->ieee80211_ptr = prWdev; -+ prWdev->netdev = prNetDev; -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ prNetDev->features = NETIF_F_HW_CSUM; -+#endif -+ -+ /* <2.2> co-relate net device & device tree */ -+ SET_NETDEV_DEV(prNetDev, wiphy_dev(prWiphy)); -+ -+ /* <2.3> register net_device */ -+ if (register_netdev(prWdev->netdev) < 0) { -+ DBGLOG(INIT, ERROR, "wlanNetRegister: net_device context is not registered.\n"); -+ goto unregister_wiphy; -+ } -+#endif /* CFG_SUPPORT_PERSIST_NETDEV */ -+ gprWdev = prWdev; -+ DBGLOG(INIT, INFO, "create wireless device success\n"); -+ return; -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+unregister_wiphy: -+ wiphy_unregister(prWiphy); -+#endif -+free_wiphy: -+ wiphy_free(prWiphy); -+free_wdev: -+ kfree(prWdev); -+} -+ -+static void destroyWirelessDevice(void) -+{ -+#if CFG_SUPPORT_PERSIST_NETDEV -+ unregister_netdev(gprWdev->netdev); -+ free_netdev(gprWdev->netdev); -+#endif -+ wiphy_unregister(gprWdev->wiphy); -+ wiphy_free(gprWdev->wiphy); -+ kfree(gprWdev); -+ gprWdev = NULL; -+} -+ -+static void wlanSetMulticastList(struct net_device *prDev) -+{ -+ gPrDev = prDev; -+ schedule_delayed_work(&workq, 0); -+} -+ -+/* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange -+ * another workqueue for sleeping. We don't want to block -+ * tx_thread, so we can't let tx_thread to do this */ -+ -+static void wlanSetMulticastListWorkQueue(struct work_struct *work) -+{ -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 u4PacketFilter = 0; -+ UINT_32 u4SetInfoLen; -+ struct net_device *prDev = gPrDev; -+ -+ fgIsWorkMcStart = TRUE; -+ -+ if (kalHaltLock(KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE)) -+ return; -+ if (kalIsHalted()) { -+ fgIsWorkMcStart = FALSE; -+ kalHaltUnlock(); -+ return; -+ } -+ -+ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; -+ ASSERT(prDev); -+ ASSERT(prGlueInfo); -+ if (!prDev || !prGlueInfo) { -+ DBGLOG(INIT, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo); -+ fgIsWorkMcStart = FALSE; -+ kalHaltUnlock(); -+ return; -+ } -+ -+ if (prDev->flags & IFF_PROMISC) -+ u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS; -+ -+ if (prDev->flags & IFF_BROADCAST) -+ u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST; -+ -+ if (prDev->flags & IFF_MULTICAST) { -+ if ((prDev->flags & IFF_ALLMULTI) || -+ (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) { -+ -+ u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; -+ } else { -+ u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST; -+ } -+ } -+ -+ kalHaltUnlock(); -+ -+ if (kalIoctl(prGlueInfo, -+ wlanoidSetCurrentPacketFilter, -+ &u4PacketFilter, -+ sizeof(u4PacketFilter), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen) != WLAN_STATUS_SUCCESS) { -+ fgIsWorkMcStart = FALSE; -+ DBGLOG(INIT, ERROR, "wlanSetMulticastListWorkQueue kalIoctl u4PacketFilter=%d\n", u4PacketFilter); -+ return; -+ } -+ -+ if (u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) { -+ /* Prepare multicast address list */ -+ struct netdev_hw_addr *ha; -+ PUINT_8 prMCAddrList = NULL; -+ UINT_32 i = 0; -+ -+ if (kalHaltLock(KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE)) -+ return; -+ if (kalIsHalted()) { -+ fgIsWorkMcStart = FALSE; -+ kalHaltUnlock(); -+ /*DBGLOG(INIT, WARN, "wlanSetMulticastListWorkQueue g_u4HaltFlag=%d\n", g_u4HaltFlag);*/ -+ return; -+ } -+ -+ prMCAddrList = kalMemAlloc(MAX_NUM_GROUP_ADDR * ETH_ALEN, VIR_MEM_TYPE); -+ -+ netdev_for_each_mc_addr(ha, prDev) { -+ if (i < MAX_NUM_GROUP_ADDR) { -+ memcpy((prMCAddrList + i * ETH_ALEN), ha->addr, ETH_ALEN); -+ i++; -+ } -+ } -+ -+ kalHaltUnlock(); -+ -+ kalIoctl(prGlueInfo, -+ wlanoidSetMulticastList, -+ prMCAddrList, (i * ETH_ALEN), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ -+ kalMemFree(prMCAddrList, VIR_MEM_TYPE, MAX_NUM_GROUP_ADDR * ETH_ALEN); -+ } -+ -+ fgIsWorkMcStart = FALSE; -+ -+} /* end of wlanSetMulticastList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate scheduled scan has been stopped -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSchedScanStoppedWorkQueue(struct work_struct *work) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct net_device *prDev = gPrDev; -+ -+ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; -+ if (!prGlueInfo) { -+ DBGLOG(SCN, ERROR, "prGlueInfo == NULL unexpected\n"); -+ return; -+ } -+ -+ /* 2. indication to cfg80211 */ -+ /* 20150205 change cfg80211_sched_scan_stopped to work queue due to sched_scan_mtx dead lock issue */ -+ cfg80211_sched_scan_stopped(priv_to_wiphy(prGlueInfo),0); -+ DBGLOG(SCN, INFO, -+ "cfg80211_sched_scan_stopped event send done\n"); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is TX entry point of NET DEVICE. -+* -+* \param[in] prSkb Pointer of the sk_buff to be sent -+* \param[in] prDev Pointer to struct net_device -+* -+* \retval NETDEV_TX_OK - on success. -+* \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. -+*/ -+/*----------------------------------------------------------------------------*/ -+int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ P_QUE_ENTRY_T prQueueEntry = NULL; -+ P_QUE_T prTxQueue = NULL; -+ UINT_16 u2QueueIdx = 0; -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ UINT16 u2Identifier = 0; -+#endif -+ -+#if CFG_BOW_TEST -+ UINT_32 i; -+#endif -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prSkb); -+ ASSERT(prDev); -+ ASSERT(prGlueInfo); -+ prGlueInfo->u8SkbToDriver++; -+ -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ { -+ UINT8 *pkt = prSkb->data; -+ -+ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { -+ /* ip */ -+ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); -+ /* u2TdlsTxSeq[u4TdlsTxSeqId ++] = u2Identifier; */ -+ DBGLOG(INIT, INFO, " %d\n", u2Identifier); -+ } -+ } -+#endif -+ /* check if WiFi is halt */ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ DBGLOG(INIT, INFO, "GLUE_FLAG_HALT skip tx\n"); -+ dev_kfree_skb(prSkb); -+ prGlueInfo->u8SkbFreed++; -+ return NETDEV_TX_OK; -+ } -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ if (prGlueInfo->fgIsDad) { -+ /* kalPrint("[Passpoint R2] Due to ipv4_dad...TX is forbidden\n"); */ -+ dev_kfree_skb(prSkb); -+ prGlueInfo->u8SkbFreed++; -+ return NETDEV_TX_OK; -+ } -+ if (prGlueInfo->fgIs6Dad) { -+ /* kalPrint("[Passpoint R2] Due to ipv6_dad...TX is forbidden\n"); */ -+ dev_kfree_skb(prSkb); -+ prGlueInfo->u8SkbFreed++; -+ return NETDEV_TX_OK; -+ } -+#endif -+ -+ STATS_TX_TIME_ARRIVE(prSkb); -+ prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); -+ prTxQueue = &prGlueInfo->rTxQueue; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, "sk_buff->len: %d\n", prSkb->len); -+ DBGLOG(BOW, TRACE, "sk_buff->data_len: %d\n", prSkb->data_len); -+ DBGLOG(BOW, TRACE, "sk_buff->data:\n"); -+ -+ for (i = 0; i < prSkb->len; i++) { -+ DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]); -+ -+ if ((i + 1) % 16 == 0) -+ DBGLOG(BOW, TRACE, "\n"); -+ } -+ -+ DBGLOG(BOW, TRACE, "\n"); -+#endif -+ -+ if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) { -+ -+ /* non-1x packets */ -+ -+#if CFG_DBG_GPIO_PINS -+ { -+ /* TX request from OS */ -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_LOW); -+ kalUdelay(1); -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_HIGH); -+ } -+#endif -+ -+ u2QueueIdx = skb_get_queue_mapping(prSkb); -+ ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ GLUE_SET_PKT_ARRIVAL_TIME(prSkb, kalGetTimeTick()); -+#endif -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); -+ if (u2QueueIdx < CFG_MAX_TXQ_NUM) -+ GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+/* GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); */ -+/* GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); */ -+ -+ if (u2QueueIdx < CFG_MAX_TXQ_NUM) { -+ if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx] >= -+ CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) { -+ DBGLOG(TX, INFO, "netif_stop_subqueue for wlan0, Queue len: %d\n", -+ prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); -+ -+ netif_stop_subqueue(prDev, u2QueueIdx); -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+ prGlueInfo->rHifInfo.HifLoopbkFlg |= 0x01; -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ } -+ } -+ } else { -+ /* printk("is security frame\n"); */ -+ -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); -+ } -+ -+ DBGLOG(TX, EVENT, "\n+++++ pending frame %d len = %d +++++\n", prGlueInfo->i4TxPendingFrameNum, prSkb->len); -+ prGlueInfo->rNetDevStats.tx_bytes += prSkb->len; -+ prGlueInfo->rNetDevStats.tx_packets++; -+ kalPerMonStart(prGlueInfo); -+ -+ /* set GLUE_FLAG_TXREQ_BIT */ -+ -+ /* pr->u4Flag |= GLUE_FLAG_TXREQ; */ -+ /* wake_up_interruptible(&prGlueInfo->waitq); */ -+ kalSetEvent(prGlueInfo); -+ -+ /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */ -+ return NETDEV_TX_OK; -+} /* end of wlanHardStartXmit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A method of struct net_device, to get the network interface statistical -+* information. -+* -+* Whenever an application needs to get statistics for the interface, this method -+* is called. This happens, for example, when ifconfig or netstat -i is run. -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \return net_device_stats buffer pointer. -+*/ -+/*----------------------------------------------------------------------------*/ -+struct net_device_stats *wlanGetStats(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+#if 0 -+ WLAN_STATUS rStatus; -+ UINT_32 u4XmitError = 0; -+ UINT_32 u4XmitOk = 0; -+ UINT_32 u4RecvError = 0; -+ UINT_32 u4RecvOk = 0; -+ UINT_32 u4BufLen; -+ -+ ASSERT(prDev); -+ -+ /* @FIX ME: need a more clear way to do this */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryXmitError, &u4XmitError, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidQueryXmitOk, &u4XmitOk, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); -+ rStatus = kalIoctl(prGlueInfo, wlanoidQueryRcvOk, &u4RecvOk, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryRcvError, &u4RecvError, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); -+ prGlueInfo->rNetDevStats.rx_packets = u4RecvOk; -+ prGlueInfo->rNetDevStats.tx_packets = u4XmitOk; -+ prGlueInfo->rNetDevStats.tx_errors = u4XmitError; -+ prGlueInfo->rNetDevStats.rx_errors = u4RecvError; -+ /* prGlueInfo->rNetDevStats.rx_bytes = rCustomNetDevStats.u4RxBytes; */ -+ /* prGlueInfo->rNetDevStats.tx_bytes = rCustomNetDevStats.u4TxBytes; */ -+ /* prGlueInfo->rNetDevStats.rx_errors = rCustomNetDevStats.u4RxErrors; */ -+ /* prGlueInfo->rNetDevStats.multicast = rCustomNetDevStats.u4Multicast; */ -+#endif -+ /* prGlueInfo->rNetDevStats.rx_packets = 0; */ -+ /* prGlueInfo->rNetDevStats.tx_packets = 0; */ -+ prGlueInfo->rNetDevStats.tx_errors = 0; -+ prGlueInfo->rNetDevStats.rx_errors = 0; -+ /* prGlueInfo->rNetDevStats.rx_bytes = 0; */ -+ /* prGlueInfo->rNetDevStats.tx_bytes = 0; */ -+ prGlueInfo->rNetDevStats.rx_errors = 0; -+ prGlueInfo->rNetDevStats.multicast = 0; -+ -+ return &prGlueInfo->rNetDevStats; -+ -+} /* end of wlanGetStats() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->init -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \retval 0 The execution of wlanInit succeeds. -+* \retval -ENXIO No such device. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wlanInit(struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ if (fgIsWorkMcEverInit == FALSE) { -+ if (!prDev) -+ return -ENXIO; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ INIT_DELAYED_WORK(&workq, wlanSetMulticastListWorkQueue); -+ -+ /* 20150205 work queue for sched_scan */ -+ INIT_DELAYED_WORK(&sched_workq, wlanSchedScanStoppedWorkQueue); -+ -+ fgIsWorkMcEverInit = TRUE; -+ } -+ -+ return 0; /* success */ -+} /* end of wlanInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->uninit -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static void wlanUninit(struct net_device *prDev) -+{ -+ -+} /* end of wlanUninit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->open -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \retval 0 The execution of wlanOpen succeeds. -+* \retval < 0 The execution of wlanOpen failed. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wlanOpen(struct net_device *prDev) -+{ -+ ASSERT(prDev); -+ -+ netif_tx_start_all_queues(prDev); -+ -+ return 0; /* success */ -+} /* end of wlanOpen() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->stop -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \retval 0 The execution of wlanStop succeeds. -+* \retval < 0 The execution of wlanStop failed. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wlanStop(struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct cfg80211_scan_request *prScanRequest = NULL; -+ -+ struct cfg80211_scan_info info = { -+ .aborted = true, -+ }; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ /* CFG80211 down */ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueInfo->prScanRequest != NULL) { -+ prScanRequest = prGlueInfo->prScanRequest; -+ prGlueInfo->prScanRequest = NULL; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ if (prScanRequest) -+ cfg80211_scan_done(prScanRequest, &info); -+ netif_tx_stop_all_queues(prDev); -+ -+ return 0; /* success */ -+} /* end of wlanStop() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief Update channel table for cfg80211 based on current country domain -+ * -+ * \param[in] prGlueInfo Pointer to glue info -+ * -+ * \return none -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID wlanUpdateChannelTable(P_GLUE_INFO_T prGlueInfo) -+{ -+ UINT_8 i, j; -+ UINT_8 ucNumOfChannel; -+ RF_CHANNEL_INFO_T aucChannelList[ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels)]; -+ -+ /* 1. Disable all channels */ -+ for (i = 0; i < ARRAY_SIZE(mtk_2ghz_channels); i++) { -+ mtk_2ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED; -+ mtk_2ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(mtk_5ghz_channels); i++) { -+ mtk_5ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED; -+ mtk_5ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED; -+ } -+ -+ /* 2. Get current domain channel list */ -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, -+ BAND_NULL, FALSE, -+ ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels), -+ &ucNumOfChannel, aucChannelList); -+ -+ /* 3. Enable specific channel based on domain channel list */ -+ for (i = 0; i < ucNumOfChannel; i++) { -+ switch (aucChannelList[i].eBand) { -+ case BAND_2G4: -+ for (j = 0; j < ARRAY_SIZE(mtk_2ghz_channels); j++) { -+ if (mtk_2ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) { -+ mtk_2ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED; -+ mtk_2ghz_channels[j].orig_flags &= ~IEEE80211_CHAN_DISABLED; -+ break; -+ } -+ } -+ break; -+ -+ case BAND_5G: -+ for (j = 0; j < ARRAY_SIZE(mtk_5ghz_channels); j++) { -+ if (mtk_5ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) { -+ mtk_5ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED; -+ mtk_5ghz_channels[j].orig_flags &= ~IEEE80211_CHAN_DISABLED; -+ break; -+ } -+ } -+ break; -+ -+ default: -+ DBGLOG(INIT, WARN, "Unknown band %d\n", aucChannelList[i].eBand); -+ break; -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Register the device to the kernel and return the index. -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \retval 0 The execution of wlanNetRegister succeeds. -+* \retval < 0 The execution of wlanNetRegister failed. -+*/ -+/*----------------------------------------------------------------------------*/ -+static INT_32 wlanNetRegister(struct wireless_dev *prWdev) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ INT_32 i4DevIdx = -1; -+ -+ ASSERT(prWdev); -+ -+ do { -+ if (!prWdev) -+ break; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); -+ i4DevIdx = wlanGetDevIdx(prWdev->netdev); -+ if (i4DevIdx < 0) { -+ DBGLOG(INIT, ERROR, "wlanNetRegister: net_device number exceeds.\n"); -+ break; -+ } -+ -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ if (register_netdev(prWdev->netdev) < 0) { -+ DBGLOG(INIT, ERROR, "wlanNetRegister: net_device context is not registered.\n"); -+ -+ wiphy_unregister(prWdev->wiphy); -+ wlanClearDevIdx(prWdev->netdev); -+ i4DevIdx = -1; -+ } -+#endif -+ if (i4DevIdx != -1) -+ prGlueInfo->fgIsRegistered = TRUE; -+ -+ } while (FALSE); -+ -+ return i4DevIdx; /* success */ -+} /* end of wlanNetRegister() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Unregister the device from the kernel -+* -+* \param[in] prWdev Pointer to struct net_device. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID wlanNetUnregister(struct wireless_dev *prWdev) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ if (!prWdev) { -+ DBGLOG(INIT, ERROR, "wlanNetUnregister: The device context is NULL\n"); -+ return; -+ } -+ DBGLOG(INIT, TRACE, "unregister net_dev(0x%p)\n", prWdev->netdev); -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); -+ wlanClearDevIdx(prWdev->netdev); -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ unregister_netdev(prWdev->netdev); -+#endif -+ prGlueInfo->fgIsRegistered = FALSE; -+ -+ DBGLOG(INIT, INFO, "unregister wireless_dev(0x%p), ifindex=%d\n", prWdev, prWdev->netdev->ifindex); -+ -+} /* end of wlanNetUnregister() */ -+ -+static const struct net_device_ops wlan_netdev_ops = { -+ .ndo_open = wlanOpen, -+ .ndo_stop = wlanStop, -+ .ndo_set_rx_mode = wlanSetMulticastList, -+ .ndo_get_stats = wlanGetStats, -+ .ndo_do_ioctl = wlanDoIOCTL, -+ .ndo_start_xmit = wlanHardStartXmit, -+ .ndo_init = wlanInit, -+ .ndo_uninit = wlanUninit, -+ .ndo_select_queue = wlanSelectQueue, -+}; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A method for creating Linux NET4 struct net_device object and the -+* private data(prGlueInfo and prAdapter). Setup the IO address to the HIF. -+* Assign the function pointer to the net_device object -+* -+* \param[in] pvData Memory address for the device -+* -+* \retval Not null The wireless_dev object. -+* \retval NULL Fail to create wireless_dev object -+*/ -+/*----------------------------------------------------------------------------*/ -+static struct lock_class_key rSpinKey[SPIN_LOCK_NUM]; -+static struct wireless_dev *wlanNetCreate(PVOID pvData) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct wireless_dev *prWdev = gprWdev; -+ UINT_32 i; -+ struct device *prDev; -+ -+ if (!prWdev) { -+ DBGLOG(INIT, ERROR, "Allocating memory to wireless_dev context failed\n"); -+ return NULL; -+ } -+ /* 4 <1> co-relate wiphy & prDev */ -+#if MTK_WCN_HIF_SDIO -+ mtk_wcn_hif_sdio_get_dev(*((MTK_WCN_HIF_SDIO_CLTCTX *) pvData), &prDev); -+#else -+/* prDev = &((struct sdio_func *) pvData)->dev; //samp */ -+ prDev = pvData; /* samp */ -+#endif -+ if (!prDev) -+ DBGLOG(INIT, WARN, "unable to get struct dev for wlan\n"); -+ /* don't set prDev as parent of wiphy->dev, because we have done device_add -+ in driver init. if we set parent here, parent will be not able to know this child, -+ and may occurs a KE in device_shutdown, to free wiphy->dev, because his parent -+ has been freed. */ -+ /*set_wiphy_dev(prWdev->wiphy, prDev);*/ -+ -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ /* 4 <3> Initial Glue structure */ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); -+ kalMemZero(prGlueInfo, sizeof(GLUE_INFO_T)); -+ /* 4 <3.1> Create net device */ -+#if CFG_TC1_FEATURE -+ if (wlan_if_changed) { -+ prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME_IN_AP_MODE, -+ NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); -+ } else { -+ prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE, -+ ether_setup, CFG_MAX_TXQ_NUM); -+ } -+#else -+ prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE, -+ ether_setup, CFG_MAX_TXQ_NUM); -+#endif -+ if (!prGlueInfo->prDevHandler) { -+ DBGLOG(INIT, ERROR, "Allocating memory to net_device context failed\n"); -+ return NULL; -+ } -+ DBGLOG(INIT, INFO, "net_device prDev(0x%p) allocated ifindex=%d\n", -+ prGlueInfo->prDevHandler, prGlueInfo->prDevHandler->ifindex); -+ -+ /* 4 <3.1.1> initialize net device varaiables */ -+ *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prDevHandler)) = prGlueInfo; -+ -+ prGlueInfo->prDevHandler->netdev_ops = &wlan_netdev_ops; -+#ifdef CONFIG_WIRELESS_EXT -+ prGlueInfo->prDevHandler->wireless_handlers = &wext_handler_def; -+#endif -+ netif_carrier_off(prGlueInfo->prDevHandler); -+ netif_tx_stop_all_queues(prGlueInfo->prDevHandler); -+ -+ /* 4 <3.1.2> co-relate with wiphy bi-directionally */ -+ prGlueInfo->prDevHandler->ieee80211_ptr = prWdev; -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ prGlueInfo->prDevHandler->features = NETIF_F_HW_CSUM; -+#endif -+ prWdev->netdev = prGlueInfo->prDevHandler; -+ -+ /* 4 <3.1.3> co-relate net device & prDev */ -+ /*SET_NETDEV_DEV(prGlueInfo->prDevHandler, wiphy_dev(prWdev->wiphy));*/ -+ SET_NETDEV_DEV(prGlueInfo->prDevHandler, prDev); -+#else /* CFG_SUPPORT_PERSIST_NETDEV */ -+ prGlueInfo->prDevHandler = gprWdev->netdev; -+#endif /* CFG_SUPPORT_PERSIST_NETDEV */ -+ -+ /* 4 <3.2> initiali glue variables */ -+ prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; -+ prGlueInfo->ePowerState = ParamDeviceStateD0; -+ prGlueInfo->fgIsMacAddrOverride = FALSE; -+ prGlueInfo->fgIsRegistered = FALSE; -+ prGlueInfo->prScanRequest = NULL; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ /* Init DAD */ -+ prGlueInfo->fgIsDad = FALSE; -+ prGlueInfo->fgIs6Dad = FALSE; -+ kalMemZero(prGlueInfo->aucDADipv4, 4); -+ kalMemZero(prGlueInfo->aucDADipv6, 16); -+#endif -+ -+ init_completion(&prGlueInfo->rScanComp); -+ init_completion(&prGlueInfo->rHaltComp); -+ init_completion(&prGlueInfo->rPendComp); -+#if CFG_ENABLE_WIFI_DIRECT -+ init_completion(&prGlueInfo->rSubModComp); -+#endif -+ -+ /* initialize timer for OID timeout checker */ -+ kalOsTimerInitialize(prGlueInfo, kalTimeoutHandler); -+ -+ for (i = 0; i < SPIN_LOCK_NUM; i++) { -+ spin_lock_init(&prGlueInfo->rSpinLock[i]); -+ lockdep_set_class(&prGlueInfo->rSpinLock[i], &rSpinKey[i]); -+ } -+ -+ /* initialize semaphore for ioctl */ -+ sema_init(&prGlueInfo->ioctl_sem, 1); -+ -+ glSetHifInfo(prGlueInfo, (ULONG) pvData); -+ -+ /* 4 <8> Init Queues */ -+ init_waitqueue_head(&prGlueInfo->waitq); -+ QUEUE_INITIALIZE(&prGlueInfo->rCmdQueue); -+ QUEUE_INITIALIZE(&prGlueInfo->rTxQueue); -+ -+ /* 4 <4> Create Adapter structure */ -+ prGlueInfo->prAdapter = (P_ADAPTER_T) wlanAdapterCreate(prGlueInfo); -+ -+ if (!prGlueInfo->prAdapter) { -+ DBGLOG(INIT, ERROR, "Allocating memory to adapter failed\n"); -+ return NULL; -+ } -+ KAL_WAKE_LOCK_INIT(prAdapter, &prGlueInfo->rAhbIsrWakeLock, "WLAN AHB ISR"); -+#if CFG_SUPPORT_PERSIST_NETDEV -+ dev_open(prGlueInfo->prDevHandler); -+ netif_carrier_off(prGlueInfo->prDevHandler); -+ netif_tx_stop_all_queues(prGlueInfo->prDevHandler); -+#endif -+ -+ return prWdev; -+} /* end of wlanNetCreate() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Destroying the struct net_device object and the private data. -+* -+* \param[in] prWdev Pointer to struct wireless_dev. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID wlanNetDestroy(struct wireless_dev *prWdev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prWdev); -+ -+ if (!prWdev) { -+ DBGLOG(INIT, ERROR, "wlanNetDestroy: The device context is NULL\n"); -+ return; -+ } -+ -+ /* prGlueInfo is allocated with net_device */ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); -+ ASSERT(prGlueInfo); -+ -+ /* destroy kal OS timer */ -+ kalCancelTimer(prGlueInfo); -+ -+ glClearHifInfo(prGlueInfo); -+ -+ wlanAdapterDestroy(prGlueInfo->prAdapter); -+ prGlueInfo->prAdapter = NULL; -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+ /* take the net_device to down state */ -+ dev_close(prGlueInfo->prDevHandler); -+#else -+ /* Free net_device and private data prGlueInfo, which are allocated by alloc_netdev(). */ -+ free_netdev(prWdev->netdev); -+#endif -+ -+} /* end of wlanNetDestroy() */ -+ -+#ifndef CONFIG_X86 -+UINT_8 g_aucBufIpAddr[32] = { 0 }; -+static void wlanNotifyFwSuspend(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgSuspend) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_32 u4SetInfoLen; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidNotifyFwSuspend, -+ (PVOID)&fgSuspend, -+ sizeof(fgSuspend), -+ FALSE, -+ FALSE, -+ TRUE, -+ FALSE, -+ &u4SetInfoLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(INIT, INFO, "wlanNotifyFwSuspend fail\n"); -+} -+ -+void wlanHandleSystemSuspend(void) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_8 ip[4] = { 0 }; -+ UINT_32 u4NumIPv4 = 0; -+#ifdef CONFIG_IPV6 -+ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ -+ UINT_32 u4NumIPv6 = 0; -+#endif -+ UINT_32 i; -+ P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr; -+ -+ /* <1> Sanity check and acquire the net_device */ -+ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); -+ if (u4WlanDevNum == 0) { -+ DBGLOG(INIT, ERROR, "wlanEarlySuspend u4WlanDevNum==0 invalid!!\n"); -+ return; -+ } -+ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; -+ -+ fgIsUnderSuspend = true; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ kalPerMonDisable(prGlueInfo); -+ -+ if (!prDev || !(prDev->ip_ptr) || -+ !((struct in_device *)(prDev->ip_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { -+ goto notify_suspend; -+ } -+ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); -+ -+ /* todo: traverse between list to find whole sets of IPv4 addresses */ -+ if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0))) -+ u4NumIPv4++; -+#ifdef CONFIG_IPV6 -+ if (!prDev || !(prDev->ip6_ptr) || -+ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { -+ goto notify_suspend; -+ } -+ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); -+ DBGLOG(INIT, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", -+ ip6[0], ip6[1], ip6[2], ip6[3], -+ ip6[4], ip6[5], ip6[6], ip6[7], -+ ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15] -+ ); -+ -+ /* todo: traverse between list to find whole sets of IPv6 addresses */ -+ if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) { -+ /* Do nothing */ -+ /* u4NumIPv6++; */ -+ } -+#endif -+ -+ /* <7> set up the ARP filter */ -+ { -+ UINT_32 u4SetInfoLen = 0; -+ UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress); -+ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; -+ P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress; -+ -+ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); -+ -+ prParamNetAddrList->u4AddressCount = u4NumIPv4; -+#ifdef CONFIG_IPV6 -+ prParamNetAddrList->u4AddressCount += u4NumIPv6; -+#endif -+ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ for (i = 0; i < u4NumIPv4; i++) { -+ prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */ -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress; -+ kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip)); -+ prParamNetAddr = -+ (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS); -+ } -+#ifdef CONFIG_IPV6 -+ for (i = 0; i < u4NumIPv6; i++) { -+ prParamNetAddr->u2AddressLength = 6; -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6)); -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + sizeof(ip6)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); -+ } -+#endif -+ ASSERT(u4Len <= sizeof(g_aucBufIpAddr)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetNetworkAddress, -+ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ } -+ -+notify_suspend: -+ DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ wlanNotifyFwSuspend(prGlueInfo, TRUE); -+} -+ -+void wlanHandleSystemResume(void) -+{ -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_8 ip[4] = { 0 }; -+#ifdef CONFIG_IPV6 -+ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ -+#endif -+ EVENT_AIS_BSS_INFO_T rParam; -+ UINT_32 u4BufLen = 0; -+ -+ /* <1> Sanity check and acquire the net_device */ -+ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); -+ if (u4WlanDevNum == 0) { -+ DBGLOG(INIT, ERROR, "wlanLateResume u4WlanDevNum==0 invalid!!\n"); -+ return; -+ } -+ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; -+ /* ASSERT(prDev); */ -+ -+ fgIsUnderSuspend = false; -+ -+ if (!prDev) { -+ DBGLOG(INIT, INFO, "prDev == NULL!!!\n"); -+ return; -+ } -+ /* <3> acquire the prGlueInfo */ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ kalPerMonEnable(prGlueInfo); -+ -+ /* -+ We will receive the event in rx, we will check if the status is the same in driver -+ and FW, if not the same, trigger disconnetion procedure. -+ */ -+ -+ kalMemZero(&rParam, sizeof(EVENT_AIS_BSS_INFO_T)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryBSSInfo, -+ &rParam, sizeof(EVENT_AIS_BSS_INFO_T), TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Query BSSinfo fail 0x%x!!\n", rStatus); -+ } -+ -+ /* <2> get the IPv4 address */ -+ if (!(prDev->ip_ptr) || -+ !((struct in_device *)(prDev->ip_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { -+ goto notify_resume; -+ } -+ /* <4> copy the IPv4 address */ -+ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); -+ -+#ifdef CONFIG_IPV6 -+ /* <5> get the IPv6 address */ -+ if (!prDev || !(prDev->ip6_ptr) || -+ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { -+ goto notify_resume; -+ } -+ /* <6> copy the IPv6 address */ -+ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); -+ DBGLOG(INIT, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", -+ ip6[0], ip6[1], ip6[2], ip6[3], -+ ip6[4], ip6[5], ip6[6], ip6[7], -+ ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15] -+ ); -+#endif -+ /* <7> clear the ARP filter */ -+ { -+ UINT_32 u4SetInfoLen = 0; -+/* UINT_8 aucBuf[32] = {0}; */ -+ UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST); -+ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; -+ /* aucBuf; */ -+ -+ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); -+ -+ prParamNetAddrList->u4AddressCount = 0; -+ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ -+ ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */)); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetNetworkAddress, -+ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ } -+ -+notify_resume: -+ DBGLOG(INIT, INFO, "Query BSS result: %d %d %d, IP: %d.%d.%d.%d, rStatus: %u\n", -+ rParam.eConnectionState, rParam.eCurrentOPMode, rParam.fgIsNetActive, -+ ip[0], ip[1], ip[2], ip[3], rStatus); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ wlanNotifyFwSuspend(prGlueInfo, FALSE); -+ } -+} -+#endif /* ! CONFIG_X86 */ -+ -+int set_p2p_mode_handler(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode) -+{ -+#if 0 -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(netdev)); -+ PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ rSetP2P.u4Enable = p2pmode.u4Enable; -+ rSetP2P.u4Mode = p2pmode.u4Mode; -+ -+ if (!rSetP2P.u4Enable) -+ p2pNetUnregister(prGlueInfo, TRUE); -+ -+ rWlanStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2pMode, -+ (PVOID) &rSetP2P, -+ sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ DBGLOG(INIT, INFO, "ret = %d\n", rWlanStatus); -+ if (rSetP2P.u4Enable) -+ p2pNetRegister(prGlueInfo, TRUE); -+ -+ return 0; -+ -+#else -+ -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(netdev)); -+ PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ BOOLEAN fgIsP2PEnding; -+ UINT_32 u4BufLen = 0; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ DBGLOG(INIT, INFO, "%u %u\n", (UINT_32) p2pmode.u4Enable, (UINT_32) p2pmode.u4Mode); -+ -+ /* avoid remove & p2p off command simultaneously */ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ fgIsP2PEnding = g_u4P2PEnding; -+ g_u4P2POnOffing = 1; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ -+ if (fgIsP2PEnding == 1) { -+ /* skip the command if we are removing */ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2POnOffing = 0; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ return 0; -+ } -+ -+ rSetP2P.u4Enable = p2pmode.u4Enable; -+ rSetP2P.u4Mode = p2pmode.u4Mode; -+ -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ if ((!rSetP2P.u4Enable) && (fgIsResetting == FALSE)) -+ p2pNetUnregister(prGlueInfo, TRUE); -+#endif -+ /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */ -+ /* -+ Scenario: -+ 1. System enters suspend/resume but not yet enter wlanearlysuspend() -+ or wlanlateresume(); -+ -+ 2. System switches to do PRIV_CMD_P2P_MODE and execute kalIoctl() -+ and get g_halt_sem then do glRegisterEarlySuspend() or -+ glUnregisterEarlySuspend(); -+ -+ But system suspend/resume procedure is not yet finished so we -+ suspend; -+ -+ 3. System switches back to do suspend/resume procedure and execute -+ kalIoctl(). But driver does not yet release g_halt_sem so system -+ suspend in wlanearlysuspend() or wlanlateresume(); -+ -+ ==> deadlock occurs. -+ */ -+ -+ rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, (PVOID) &rSetP2P,/* pu4IntBuf[0]is used as input SubCmd */ -+ sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ /* Need to check fgIsP2PRegistered, in case of whole chip reset. -+ * in this case, kalIOCTL return success always, -+ * and prGlueInfo->prP2pInfo may be NULL */ -+ if ((rSetP2P.u4Enable) && (prGlueInfo->prAdapter->fgIsP2PRegistered) && (fgIsResetting == FALSE)) -+ p2pNetRegister(prGlueInfo, TRUE); -+#endif -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2POnOffing = 0; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ return 0; -+#endif -+} -+ -+static void set_dbg_level_handler(unsigned char dbg_lvl[DBG_MODULE_NUM]) -+{ -+ kalMemCopy(aucDebugModule, dbg_lvl, sizeof(aucDebugModule)); -+ kalPrint("[wlan] change debug level"); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Wlan probe function. This function probes and initializes the device. -+* -+* \param[in] pvData data passed by bus driver init function -+* _HIF_EHPI: NULL -+* _HIF_SDIO: sdio bus driver handle -+* -+* \retval 0 Success -+* \retval negative value Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+static INT_32 wlanProbe(PVOID pvData) -+{ -+ struct wireless_dev *prWdev = NULL; -+ enum probe_fail_reason { -+ BUS_INIT_FAIL, -+ NET_CREATE_FAIL, -+ BUS_SET_IRQ_FAIL, -+ ADAPTER_START_FAIL, -+ NET_REGISTER_FAIL, -+ PROC_INIT_FAIL, -+ FAIL_REASON_NUM -+ } eFailReason; -+ P_WLANDEV_INFO_T prWlandevInfo = NULL; -+ INT_32 i4DevIdx = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ INT_32 i4Status = 0; -+ BOOLEAN bRet = FALSE; -+ -+ eFailReason = FAIL_REASON_NUM; -+ do { -+ /* 4 <1> Initialize the IO port of the interface */ -+ /* GeorgeKuo: pData has different meaning for _HIF_XXX: -+ * _HIF_EHPI: pointer to memory base variable, which will be -+ * initialized by glBusInit(). -+ * _HIF_SDIO: bus driver handle -+ */ -+ -+ bRet = glBusInit(pvData); -+ wlanDebugInit(); -+ /* Cannot get IO address from interface */ -+ if (FALSE == bRet) { -+ DBGLOG(INIT, ERROR, KERN_ALERT "wlanProbe: glBusInit() fail\n"); -+ i4Status = -EIO; -+ eFailReason = BUS_INIT_FAIL; -+ break; -+ } -+ /* 4 <2> Create network device, Adapter, KalInfo, prDevHandler(netdev) */ -+ prWdev = wlanNetCreate(pvData); -+ if (prWdev == NULL) { -+ DBGLOG(INIT, ERROR, "wlanProbe: No memory for dev and its private\n"); -+ i4Status = -ENOMEM; -+ eFailReason = NET_CREATE_FAIL; -+ break; -+ } -+ /* 4 <2.5> Set the ioaddr to HIF Info */ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); -+ gPrDev = prGlueInfo->prDevHandler; -+ -+ /* 4 <4> Setup IRQ */ -+ prWlandevInfo = &arWlanDevInfo[i4DevIdx]; -+ -+ i4Status = glBusSetIrq(prWdev->netdev, NULL, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); -+ -+ if (i4Status != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "wlanProbe: Set IRQ error\n"); -+ eFailReason = BUS_SET_IRQ_FAIL; -+ break; -+ } -+ -+ prGlueInfo->i4DevIdx = i4DevIdx; -+ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ prGlueInfo->u4ReadyFlag = 0; -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ prAdapter->u4CSUMFlags = (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP); -+#endif -+#if CFG_SUPPORT_CFG_FILE -+ { -+ PUINT_8 pucConfigBuf; -+ UINT_32 u4ConfigReadLen; -+ -+ wlanCfgInit(prAdapter, NULL, 0, 0); -+ pucConfigBuf = (PUINT_8) kalMemAlloc(WLAN_CFG_FILE_BUF_SIZE, VIR_MEM_TYPE); -+ u4ConfigReadLen = 0; -+ DBGLOG(INIT, LOUD, "CFG_FILE: Read File...\n"); -+ if (pucConfigBuf) { -+ kalMemZero(pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE); -+ if (kalReadToFile("/data/misc/wifi.cfg", -+ pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) { -+ DBGLOG(INIT, LOUD, "CFG_FILE: Read /data/misc/wifi.cfg\n"); -+ -+ } else if (kalReadToFile("/data/misc/wifi/wifi.cfg", -+ pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) { -+ DBGLOG(INIT, LOUD, "CFG_FILE: Read /data/misc/wifi/wifi.cfg\n"); -+ } else if (kalReadToFile("/lib/firmware/mediatek/wifi.cfg", -+ pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) { -+ DBGLOG(INIT, LOUD, "CFG_FILE: Read /lib/firmware/mediatek/wifi.cfg\n"); -+ } -+ -+ if (pucConfigBuf[0] != '\0' && u4ConfigReadLen > 0) -+ wlanCfgInit(prAdapter, pucConfigBuf, u4ConfigReadLen, 0); -+ kalMemFree(pucConfigBuf, VIR_MEM_TYPE, WLAN_CFG_FILE_BUF_SIZE); -+ } /* pucConfigBuf */ -+ } -+#endif -+ /* 4 <5> Start Device */ -+ /* */ -+#if CFG_ENABLE_FW_DOWNLOAD -+ DBGLOG(INIT, TRACE, "start to download firmware...\n"); -+ -+ /* before start adapter, we need to open and load firmware */ -+ { -+ UINT_32 u4FwSize = 0; -+ PVOID prFwBuffer = NULL; -+ P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo; -+ -+ /* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL); */ -+ kalMemSet(prRegInfo, 0, sizeof(REG_INFO_T)); -+ prRegInfo->u4StartAddress = CFG_FW_START_ADDRESS; -+ prRegInfo->u4LoadAddress = CFG_FW_LOAD_ADDRESS; -+ -+ /* Load NVRAM content to REG_INFO_T */ -+ glLoadNvram(prGlueInfo, prRegInfo); -+#if CFG_SUPPORT_CFG_FILE -+ wlanCfgApply(prAdapter); -+#endif -+ -+ /* kalMemCopy(&prGlueInfo->rRegInfo, prRegInfo, sizeof(REG_INFO_T)); */ -+ -+ prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF; -+ prRegInfo->fgEnArpFilter = TRUE; -+ -+ if (kalFirmwareImageMapping(prGlueInfo, &prFwBuffer, &u4FwSize) == NULL) { -+ i4Status = -EIO; -+ DBGLOG(INIT, ERROR, "kalFirmwareImageMapping fail!\n"); -+ goto bailout; -+ } else { -+ -+ if (wlanAdapterStart(prAdapter, prRegInfo, prFwBuffer, -+ u4FwSize) != WLAN_STATUS_SUCCESS) { -+ i4Status = -EIO; -+ } -+ } -+ -+ kalFirmwareImageUnmapping(prGlueInfo, NULL, prFwBuffer); -+ -+bailout: -+ /* kfree(prRegInfo); */ -+ -+ DBGLOG(INIT, TRACE, "download firmware status = %d\n", i4Status); -+ -+ if (i4Status < 0) { -+ GL_HIF_INFO_T *HifInfo; -+ UINT_32 u4FwCnt; -+ -+ DBGLOG(INIT, WARN, "CONNSYS FW CPUINFO:\n"); -+ HifInfo = &prAdapter->prGlueInfo->rHifInfo; -+ for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++) -+ DBGLOG(INIT, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR)); -+ /* CONSYS_REG_READ(CONSYS_CPUPCR_REG) */ -+ -+ /* dump HIF/DMA registers, if fgIsBusAccessFailed is FALSE, otherwise, */ -+ /* dump HIF register may be hung */ -+ if (!fgIsBusAccessFailed) -+ HifRegDump(prGlueInfo->prAdapter); -+/* if (prGlueInfo->rHifInfo.DmaOps->DmaRegDump != NULL) */ -+/* prGlueInfo->rHifInfo.DmaOps->DmaRegDump(&prGlueInfo->rHifInfo); */ -+ eFailReason = ADAPTER_START_FAIL; -+ break; -+ } -+ } -+#else -+ /* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL); */ -+ kalMemSet(&prGlueInfo->rRegInfo, 0, sizeof(REG_INFO_T)); -+ P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo; -+ -+ /* Load NVRAM content to REG_INFO_T */ -+ glLoadNvram(prGlueInfo, prRegInfo); -+ -+ prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF; -+ -+ if (wlanAdapterStart(prAdapter, prRegInfo, NULL, 0) != WLAN_STATUS_SUCCESS) { -+ i4Status = -EIO; -+ eFailReason = ADAPTER_START_FAIL; -+ break; -+ } -+#endif -+ if (FALSE == prAdapter->fgEnable5GBand) -+ prWdev->wiphy->bands[NL80211_BAND_5GHZ] = NULL; -+ -+ prGlueInfo->main_thread = kthread_run(tx_thread, prGlueInfo->prDevHandler, "tx_thread"); -+ kalSetHalted(FALSE); -+#if CFG_SUPPORT_ROAMING_ENC -+ /* adjust roaming threshold */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ CMD_ROAMING_INFO_T rRoamingInfo; -+ UINT_32 u4SetInfoLen = 0; -+ -+ prAdapter->fgIsRoamingEncEnabled = TRUE; -+ -+ /* suggestion from Tsaiyuan.Hsu */ -+ kalMemZero(&rRoamingInfo, sizeof(CMD_ROAMING_INFO_T)); -+ rRoamingInfo.fgIsFastRoamingApplied = TRUE; -+ -+ DBGLOG(INIT, TRACE, "Enable roaming enhance function\n"); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRoamingInfo, -+ &rRoamingInfo, sizeof(rRoamingInfo), TRUE, TRUE, TRUE, FALSE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(INIT, ERROR, "set roaming advance info fail 0x%x\n", rStatus); -+ } -+#endif /* CFG_SUPPORT_ROAMING_ENC */ -+ -+#if (CFG_SUPPORT_TXR_ENC == 1) -+ /* adjust tx rate switch threshold */ -+ rlmTxRateEnhanceConfig(prGlueInfo->prAdapter); -+#endif /* CFG_SUPPORT_TXR_ENC */ -+ -+ /* set MAC address */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ struct sockaddr MacAddr; -+ UINT_32 u4SetInfoLen = 0; -+ -+ kalMemZero(MacAddr.sa_data, sizeof(MacAddr.sa_data)); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryCurrentAddr, -+ &MacAddr.sa_data, -+ PARAM_MAC_ADDR_LEN, TRUE, TRUE, TRUE, FALSE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, WARN, "set MAC addr fail 0x%x\n", rStatus); -+ prGlueInfo->u4ReadyFlag = 0; -+ } else { -+ ether_addr_copy(prGlueInfo->prDevHandler->dev_addr, (const u8 *)&(MacAddr.sa_data)); -+ ether_addr_copy(prGlueInfo->prDevHandler->perm_addr, -+ prGlueInfo->prDevHandler->dev_addr); -+ -+ /* card is ready */ -+ prGlueInfo->u4ReadyFlag = 1; -+#if CFG_SHOW_MACADDR_SOURCE -+ DBGLOG(INIT, INFO, "MAC address: %pM ", (&MacAddr.sa_data)); -+#endif -+ } -+ } -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ /* set HW checksum offload */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_32 u4CSUMFlags = CSUM_OFFLOAD_EN_ALL; -+ UINT_32 u4SetInfoLen = 0; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetCSUMOffload, -+ (PVOID) &u4CSUMFlags, -+ sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(INIT, WARN, "set HW checksum offload fail 0x%x\n", rStatus); -+ } -+#endif -+ -+ /* 4 <3> Register the card */ -+ DBGLOG(INIT, TRACE, "wlanNetRegister...\n"); -+ i4DevIdx = wlanNetRegister(prWdev); -+ if (i4DevIdx < 0) { -+ i4Status = -ENXIO; -+ DBGLOG(INIT, ERROR, "wlanProbe: Cannot register the net_device context to the kernel\n"); -+ eFailReason = NET_REGISTER_FAIL; -+ break; -+ } -+ -+ wlanRegisterNotifier(); -+ /* 4 <6> Initialize /proc filesystem */ -+#ifdef WLAN_INCLUDE_PROC -+ DBGLOG(INIT, TRACE, "init procfs...\n"); -+ i4Status = procCreateFsEntry(prGlueInfo); -+ if (i4Status < 0) { -+ DBGLOG(INIT, ERROR, "wlanProbe: init procfs failed\n"); -+ eFailReason = PROC_INIT_FAIL; -+ break; -+ } -+#endif /* WLAN_INCLUDE_PROC */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE; -+ prGlueInfo->rBowInfo.fgIsRegistered = FALSE; -+ glRegisterAmpc(prGlueInfo); -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ DBGLOG(INIT, TRACE, "wlanSubModInit...\n"); -+ -+ /* wlan is launched */ -+ prGlueInfo->prAdapter->fgIsWlanLaunched = TRUE; -+ /* if p2p module is inserted, notify tx_thread to init p2p network */ -+ if (rSubModHandler[P2P_MODULE].subModInit) -+ wlanSubModInit(prGlueInfo); -+ /* register set_p2p_mode handler to mtk_wmt_wifi */ -+ register_set_p2p_mode_handler(set_p2p_mode_handler); -+#endif -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+ if (glIsChipNeedWakelock(prGlueInfo)) -+ KAL_WAKE_LOCK_INIT(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock, "WLAN AP"); -+#endif -+ } while (FALSE); -+ -+ if (i4Status != WLAN_STATUS_SUCCESS) { -+ switch (eFailReason) { -+ case PROC_INIT_FAIL: -+ wlanNetUnregister(prWdev); -+ set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ /* wait main thread stops */ -+ wait_for_completion_interruptible(&prGlueInfo->rHaltComp); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); -+ wlanAdapterStop(prAdapter); -+ glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); -+ wlanNetDestroy(prWdev); -+ break; -+ case NET_REGISTER_FAIL: -+ set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ /* wait main thread stops */ -+ wait_for_completion_interruptible(&prGlueInfo->rHaltComp); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); -+ wlanAdapterStop(prAdapter); -+ glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); -+ wlanNetDestroy(prWdev); -+ break; -+ case ADAPTER_START_FAIL: -+ glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); -+ wlanNetDestroy(prWdev); -+ break; -+ case BUS_SET_IRQ_FAIL: -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); -+ wlanNetDestroy(prWdev); -+ break; -+ case NET_CREATE_FAIL: -+ break; -+ case BUS_INIT_FAIL: -+ break; -+ default: -+ break; -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ { -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2PEnding = 0; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ } -+#endif -+#if CFG_SUPPORT_AGPS_ASSIST -+ if (i4Status == WLAN_STATUS_SUCCESS) -+ kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_ON, NULL, 0); -+#endif -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ { -+ int iMetInitRet = WLAN_STATUS_FAILURE; -+ -+ if (i4Status == WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, TRACE, "init MET procfs...\n"); -+ iMetInitRet = kalMetInitProcfs(prGlueInfo); -+ if (iMetInitRet < 0) -+ DBGLOG(INIT, ERROR, "wlanProbe: init MET procfs failed\n"); -+ } -+ } -+#endif -+ if (i4Status == WLAN_STATUS_SUCCESS) { -+ /*Init performance monitor structure */ -+ kalPerMonInit(prGlueInfo); -+ /* probe ok */ -+ DBGLOG(INIT, TRACE, "wlanProbe ok\n"); -+ } else { -+ /* we don't care the return value of mtk_wcn_set_connsys_power_off_flag, -+ * because even this function returns -+ * error, we can also call core dump but only core dump failed. */ -+ if (g_IsNeedDoChipReset) -+ mtk_wcn_set_connsys_power_off_flag(0); -+ /* probe failed */ -+ DBGLOG(INIT, ERROR, "wlanProbe failed\n"); -+ } -+ -+ return i4Status; -+} /* end of wlanProbe() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A method to stop driver operation and release all resources. Following -+* this call, no frame should go up or down through this interface. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID wlanRemove(VOID) -+{ -+#define KAL_WLAN_REMOVE_TIMEOUT_MSEC 3000 -+ struct net_device *prDev = NULL; -+ P_WLANDEV_INFO_T prWlandevInfo = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ -+ DBGLOG(INIT, LOUD, "Remove wlan!\n"); -+ -+ /* 4 <0> Sanity check */ -+ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); -+ if (0 == u4WlanDevNum) { -+ DBGLOG(INIT, ERROR, "0 == u4WlanDevNum\n"); -+ return; -+ } -+ /* unregister set_p2p_mode handler to mtk_wmt_wifi */ -+ register_set_p2p_mode_handler(NULL); -+ -+ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; -+ prWlandevInfo = &arWlanDevInfo[u4WlanDevNum - 1]; -+ -+ ASSERT(prDev); -+ if (NULL == prDev) { -+ DBGLOG(INIT, ERROR, "NULL == prDev\n"); -+ return; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ if (NULL == prGlueInfo) { -+ DBGLOG(INIT, ERROR, "NULL == prGlueInfo\n"); -+ free_netdev(prDev); -+ return; -+ } -+ -+ kalPerMonDestroy(prGlueInfo); -+#if CFG_ENABLE_WIFI_DIRECT -+ /* avoid remove & p2p off command simultaneously */ -+ { -+ BOOLEAN fgIsP2POnOffing; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2PEnding = 1; -+ fgIsP2POnOffing = g_u4P2POnOffing; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ -+ DBGLOG(INIT, TRACE, "waiting for fgIsP2POnOffing...\n"); -+ -+ /* History: cannot use down() here, sometimes we cannot come back here */ -+ /* waiting for p2p off command finishes, we cannot skip the remove */ -+ while (1) { -+ if (fgIsP2POnOffing == 0) -+ break; -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ fgIsP2POnOffing = g_u4P2POnOffing; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ } -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (prGlueInfo->rBowInfo.fgIsNetRegistered) { -+ bowNotifyAllLinkDisconnected(prGlueInfo->prAdapter); -+ /* wait 300ms for BoW module to send deauth */ -+ kalMsleep(300); -+ } -+#endif -+ -+ /* 4 <1> Stopping handling interrupt and free IRQ */ -+ DBGLOG(INIT, TRACE, "free IRQ...\n"); -+ glBusFreeIrq(prDev, *((P_GLUE_INFO_T *) netdev_priv(prDev))); -+ -+ kalMemSet(&(prGlueInfo->prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T)); -+ -+ kalSetHalted(TRUE); /* before flush_delayed_work() */ -+ if (fgIsWorkMcStart == TRUE) { -+ DBGLOG(INIT, TRACE, "flush_delayed_work...\n"); -+ flush_delayed_work(&workq); /* flush_delayed_work_sync is deprecated */ -+ } -+ -+ flush_delayed_work(&sched_workq); -+ -+ DBGLOG(INIT, INFO, "down g_halt_sem...\n"); -+ kalHaltLock(KAL_WLAN_REMOVE_TIMEOUT_MSEC); -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+ if (glIsChipNeedWakelock(prGlueInfo)) -+ KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock); -+#endif -+ -+/* flush_delayed_work_sync(&workq); */ -+/* flush_delayed_work(&workq); */ /* flush_delayed_work_sync is deprecated */ -+ -+ /* 4 <2> Mark HALT, notify main thread to stop, and clean up queued requests */ -+/* prGlueInfo->u4Flag |= GLUE_FLAG_HALT; */ -+ set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); -+ DBGLOG(INIT, TRACE, "waiting for tx_thread stop...\n"); -+ -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+ DBGLOG(INIT, TRACE, "wait_for_completion_interruptible\n"); -+ -+ /* wait main thread stops */ -+ wait_for_completion_interruptible(&prGlueInfo->rHaltComp); -+ -+ DBGLOG(INIT, TRACE, "mtk_sdiod stopped\n"); -+ -+ KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rTxThreadWakeLock); -+ KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->rAhbIsrWakeLock); -+ -+ /* prGlueInfo->rHifInfo.main_thread = NULL; */ -+ prGlueInfo->main_thread = NULL; -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (prGlueInfo->rBowInfo.fgIsRegistered) -+ glUnregisterAmpc(prGlueInfo); -+#endif -+ -+ /* 4 <3> Remove /proc filesystem. */ -+#ifdef WLAN_INCLUDE_PROC -+ procRemoveProcfs(); -+#endif /* WLAN_INCLUDE_PROC */ -+ -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ kalMetRemoveProcfs(); -+#endif -+ -+ /* Force to do DMA reset */ -+ DBGLOG(INIT, TRACE, "glResetHif\n"); -+ glResetHif(prGlueInfo); -+ -+ /* 4 <4> wlanAdapterStop */ -+ prAdapter = prGlueInfo->prAdapter; -+#if CFG_SUPPORT_AGPS_ASSIST -+ kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_OFF, NULL, 0); -+#endif -+ -+ wlanAdapterStop(prAdapter); -+ DBGLOG(INIT, TRACE, "Number of Stalled Packets = %d\n", prGlueInfo->i4TxPendingFrameNum); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ prGlueInfo->prAdapter->fgIsWlanLaunched = FALSE; -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) { -+ DBGLOG(INIT, TRACE, "p2pNetUnregister...\n"); -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ p2pNetUnregister(prGlueInfo, FALSE); -+#endif -+ DBGLOG(INIT, INFO, "p2pRemove...\n"); -+ p2pRemove(prGlueInfo); -+ } -+#endif -+ -+ /* 4 <5> Release the Bus */ -+ glBusRelease(prDev); -+ -+ kalHaltUnlock(); -+ wlanDebugUninit(); -+ /* 4 <6> Unregister the card */ -+ wlanNetUnregister(prDev->ieee80211_ptr); -+ -+ /* 4 <7> Destroy the device */ -+ wlanNetDestroy(prDev->ieee80211_ptr); -+ prDev = NULL; -+ -+ DBGLOG(INIT, LOUD, "wlanUnregisterNotifier...\n"); -+ wlanUnregisterNotifier(); -+ -+ DBGLOG(INIT, INFO, "wlanRemove ok\n"); -+} /* end of wlanRemove() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver entry point when the driver is configured as a Linux Module, and -+* is called once at module load time, by the user-level modutils -+* application: insmod or modprobe. -+* -+* \retval 0 Success -+*/ -+/*----------------------------------------------------------------------------*/ -+/* 1 Module Entry Point */ -+static int initWlan(void) -+{ -+ int ret = 0, i; -+#if DBG -+ for (i = 0; i < DBG_MODULE_NUM; i++) -+ aucDebugModule[i] = DBG_CLASS_MASK; /* enable all */ -+#else -+ /* Initial debug level is D1 */ -+ for (i = 0; i < DBG_MODULE_NUM; i++) -+ aucDebugModule[i] = DBG_CLASS_ERROR | DBG_CLASS_WARN | DBG_CLASS_INFO | DBG_CLASS_STATE; -+#endif /* DBG */ -+ DBGLOG(INIT, INFO, "initWlan\n"); -+ -+ spin_lock_init(&g_p2p_lock); -+ -+ /* memory pre-allocation */ -+ kalInitIOBuffer(); -+ procInitFs(); -+ createWirelessDevice(); -+ if (gprWdev) -+ glP2pCreateWirelessDevice((P_GLUE_INFO_T) wiphy_priv(gprWdev->wiphy)); -+ -+ ret = ((glRegisterBus(wlanProbe, wlanRemove) == WLAN_STATUS_SUCCESS) ? 0 : -EIO); -+ -+ if (ret == -EIO) { -+ kalUninitIOBuffer(); -+ return ret; -+ } -+#if (CFG_CHIP_RESET_SUPPORT) -+ glResetInit(); -+#endif -+ -+ /* register set_dbg_level handler to mtk_wmt_wifi */ -+ register_set_dbg_level_handler(set_dbg_level_handler); -+ -+ /* Set the initial DEBUG CLASS of each module */ -+ return ret; -+} /* end of initWlan() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver exit point when the driver as a Linux Module is removed. Called -+* at module unload time, by the user level modutils application: rmmod. -+* This is our last chance to clean up after ourselves. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+/* 1 Module Leave Point */ -+static VOID exitWlan(void) -+{ -+ DBGLOG(INIT, INFO, "exitWlan\n"); -+ -+ /* unregister set_dbg_level handler to mtk_wmt_wifi */ -+ register_set_dbg_level_handler(NULL); -+ -+#if CFG_CHIP_RESET_SUPPORT -+ glResetUninit(); -+#endif -+ destroyWirelessDevice(); -+ glP2pDestroyWirelessDevice(); -+ -+ glUnregisterBus(wlanRemove); -+ -+ /* free pre-allocated memory */ -+ kalUninitIOBuffer(); -+ -+ DBGLOG(INIT, INFO, "exitWlan\n"); -+ procUninitProcFs(); -+ -+} /* end of exitWlan() */ -+ -+#ifdef MTK_WCN_BUILT_IN_DRIVER -+ -+int mtk_wcn_wlan_gen2_init(void) -+{ -+ return initWlan(); -+} -+EXPORT_SYMBOL(mtk_wcn_wlan_gen2_init); -+ -+void mtk_wcn_wlan_gen2_exit(void) -+{ -+ return exitWlan(); -+} -+EXPORT_SYMBOL(mtk_wcn_wlan_gen2_exit); -+ -+#else -+ -+module_init(initWlan); -+module_exit(exitWlan); -+ -+#endif -+ -+MODULE_AUTHOR(NIC_AUTHOR); -+MODULE_DESCRIPTION(NIC_DESC); -+MODULE_SUPPORTED_DEVICE(NIC_NAME); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c -new file mode 100644 -index 0000000000000..3a257c9f85c4d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c -@@ -0,0 +1,4799 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_kal.c#3 -+*/ -+ -+/*! \file gl_kal.c -+ \brief GLUE Layer will export the required procedures here for internal driver stack. -+ -+ This file contains all routines which are exported from GLUE Layer to internal -+ driver stack. -+*/ -+ -+/* -+** Log: gl_kal.c -+** -+** 08 20 2012 yuche.tsai -+** NULL -+** Fix possible KE issue. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 05 31 2012 terry.wu -+ * NULL -+ * . -+ * -+ * 03 26 2012 cp.wu -+ * [WCXRP00001187] [MT6620 Wi-Fi][Driver][Android] Add error handling while firmware image doesn't exist -+ * invoke put_cred() after get_current_cred() calls. -+ * -+ * 03 07 2012 yuche.tsai -+ * NULL -+ * Fix compile error when WiFi Direct is off. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 02 20 2012 cp.wu -+ * [WCXRP00001187] [MT6620 Wi-Fi][Driver][Android] Add error handling while firmware image doesn't exist -+ * do not need to invoke free() while firmware image file doesn't exist -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 01 02 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. -+ * -+ * 11 21 2011 cp.wu -+ * [WCXRP00001118] [MT6620 Wi-Fi][Driver] Corner case protections to pass Monkey testing -+ * 1. wlanoidQueryBssIdList might be passed with a non-zero length but a NULL pointer of buffer -+ * add more checking for such cases -+ * -+ * 2. kalSendComplete() might be invoked with a packet belongs to P2P network right after P2P is unregistered. -+ * add some tweaking to protect such cases because that net device has become invalid. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 16 2011 yuche.tsai -+ * NULL -+ * Avoid using work thread. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 23 2011 yuche.tsai -+ * [WCXRP00000998] [Volunteer Patch][WiFi Direct][FW] P2P Social Channel & country domain issue -+ * Regulation domain feature check in. -+ * -+ * 08 12 2011 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * load WIFI_RAM_CODE_E6 for MT6620 E6 ASIC. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 06 13 2011 eddie.chen -+ * [WCXRP00000779] [MT6620 Wi-Fi][DRV] Add tx rx statistics in linux and use netif_rx_ni -+ * Add tx rx statistics and netif_rx_ni. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated -+ * network type -+ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected -+ * -+ * 04 08 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * correct i4TxPendingFrameNum decreasing. -+ * -+ * 03 23 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * apply multi-queue operation only for linux kernel > 2.6.26 -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability for compatible with linux 2.6.12. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * improve portability for awareness of early version of linux kernel and wireless extension. -+ * -+ * 03 18 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * refix ... -+ * -+ * 03 18 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * correct compiling warning/error. -+ * -+ * 03 18 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * add more robust fault tolerance design when pre-allocation failed. (rarely happen) -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * use pre-allocated buffer for storing enhanced interrupt response as well -+ * -+ * 03 16 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * 1. pre-allocate physical continuous buffer while module is being loaded -+ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer -+ * -+ * The windows part remained the same as before, but added similar APIs to hide the difference. -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 14 2011 jeffrey.chang -+ * [WCXRP00000546] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] fix kernel build warning message -+ * fix kernel build warning message -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 06 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Sync BOW Driver to latest person development branch version.. -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * support concurrent network -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * modify net device relative functions to support multiple H/W queues -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after -+ * connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 21 2011 cp.wu -+ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain -+ * simplify logic for checking NVRAM existence only once. -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 19 2011 cp.wu -+ * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7 -+ * add compile option to check linux version 2.6.35 for different usage of system API to improve portability -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues -+ * due to multiple access -+ * use mutex to protect kalIoctl() for thread safe. -+ * -+ * 11 26 2010 cp.wu -+ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only with necessary data field -+ * checking -+ * 1. NVRAM error is now treated as warning only, thus normal operation is still available but extra scan result used -+ * to indicate user is attached -+ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 11 02 2010 jeffrey.chang -+ * [WCXRP00000145] [MT6620 Wi-Fi][Driver] fix issue of byte endian in packet classifier which discards BoW packets -+ * . -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add code to run WlanIST in SDIO callback. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] -+ * Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 25 2010 jeffrey.chang -+ * [WCXRP00000129] [MT6620] [Driver] Kernel panic when rmmod module on Andriod platform -+ * Remove redundant code which cause mismatch of power control release -+ * -+ * 10 25 2010 jeffrey.chang -+ * [WCXRP00000129] [MT6620] [Driver] Kernel panic when rmmod module on Andriod platform -+ * Remove redundant GLUE_HALT condfition to avoid unmatched release of power control -+ * -+ * 10 18 2010 jeffrey.chang -+ * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue -+ * refine the scan ioctl to prevent hanging of Android UI -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * if there is NVRAM, then use MAC address on NVRAM as default MAC address. -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ * associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * API added: nicTxPendingPackets(), for simplifying porting layer -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Support second interface indicate when enabling P2P. -+ * -+ * 08 18 2010 yarco.yang -+ * NULL -+ * 1. Fixed HW checksum offload function not work under Linux issue. -+ * 2. Add debug message. -+ * -+ * 08 16 2010 jeffrey.chang -+ * NULL -+ * remove redundant code which cause kernel panic -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * simplify post-handling after TX_DONE interrupt is handled. -+ * -+ * 07 28 2010 jeffrey.chang -+ * NULL -+ * 1) remove unused spinlocks -+ * 2) enable encyption ioctls -+ * 3) fix scan ioctl which may cause supplicant to hang -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) re-enable AIS-FSM beacon timeout handling. -+ * 2) scan done API revised -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * add new KAL api -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * bug fix: allocate regInfo when disabling firmware download -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * use glue layer api to decrease or increase counter atomically -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * modify tx thread and remove some spinlock -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * use different spin lock for security frame -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * add new spinlock -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add spinlock for pending security frame count -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * adjust the timer unit to microsecond -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * timer should return value greater than zero -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add kal api for scanning done -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * modify cmd/data path for new design -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add new kal api -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * for linux driver migration -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change MAC address updating logic. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * remove unused files. -+ * -+ * 05 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix private ioctl for rftest -+ * -+ * 05 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * workaround for fixing request_firmware() failure on android 2.1 -+ * -+ * 05 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix kernel panic when debug mode enabled -+ * -+ * 05 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) Modify set mac address code -+ * 2) remove power management macro -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Disable network interface after disassociation -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * fill network type field while doing frame identification. -+ * -+ * 05 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * prevent supplicant accessing driver during resume -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * identify BT Over Wi-Fi Security frame and mark it as 802.1X frame -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) fix firmware download bug -+ * 2) remove query statistics for acelerating firmware download -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * follow Linux's firmware framework, and remove unused kal API -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * -+ * 1) modify rx path code for supporting Wi-Fi direct -+ * 2) modify config.h since Linux dont need to consider retaining packet -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+ * -+ * 04 15 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * change firmware name -+ * -+ * 04 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * flush pending TX packets while unloading driver -+ * -+ * 04 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Set driver own before handling cmd queue -+ * -+ * 04 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used -+ * 2) fix ioctl -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler -+ * * * * * * * * * * * * * * * * * * capability -+ * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix spinlock usage -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add spinlock for i4TxPendingFrameNum access -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) add spinlock -+ * * 2) add KAPI for handling association info -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix spinlock usage -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding firmware download KAPI -+ * -+ * 04 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Set MAC address from firmware -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. free cmdinfo after command is emiited. -+ * 2. for BoW frames, user priority is extracted from sk_buff directly. -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * finish non-glue layer access to glue variables -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * accessing to firmware load/start address, and access to OID handling information -+ * * * are now handled in glue layer -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * * * are done in adapter layer. -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * (1)deliver the kalOidComplete status to upper layer -+ * (2) fix spin lock -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add KAL API: kalFlushPendingTxPackets(), and take use of the API -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add timeout check in the kalOidComplete -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) for some OID, never do timeout expiration -+ * * * 2) add 2 kal API for later integration -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * raising the priority of processing interrupt -+ * -+ * 04 01 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Bug fix: the tx thread will cause starvation of MMC thread, and the interrupt will never come in -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * emulate NDIS Pending OID facility -+ * -+ * 03 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding secondary command queue for improving non-glue code portability -+ * -+ * 03 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * adding firmware download kal api -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add Bluetooth-over-Wifi frame header check -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\50 2009-09-28 20:19:08 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\49 2009-08-18 22:56:44 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\48 2009-06-23 23:18:58 GMT mtk01090 -+** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support -+** \main\maintrunk.MT5921\47 2008-11-19 11:55:43 GMT mtk01088 -+** fixed some lint warning, and rename some variable with pre-fix to avoid the misunderstanding -+** \main\maintrunk.MT5921\46 2008-09-02 21:07:42 GMT mtk01461 -+** Remove ASSERT(pvBuf) in kalIndicateStatusAndComplete(), this parameter can be NULL -+** \main\maintrunk.MT5921\45 2008-08-29 16:03:21 GMT mtk01088 -+** remove non-used code for code review, add assert check -+** \main\maintrunk.MT5921\44 2008-08-21 00:32:49 GMT mtk01461 -+** \main\maintrunk.MT5921\43 2008-05-30 20:27:02 GMT mtk01461 -+** Rename KAL function -+** \main\maintrunk.MT5921\42 2008-05-30 15:47:29 GMT mtk01461 -+** \main\maintrunk.MT5921\41 2008-05-30 15:13:04 GMT mtk01084 -+** rename wlanoid -+** \main\maintrunk.MT5921\40 2008-05-29 14:15:14 GMT mtk01084 -+** remove un-used KAL function -+** \main\maintrunk.MT5921\39 2008-05-03 15:17:30 GMT mtk01461 -+** Move Query Media Status to GLUE -+** \main\maintrunk.MT5921\38 2008-04-24 11:59:44 GMT mtk01461 -+** change awake queue threshold and remove code which mark #if 0 -+** \main\maintrunk.MT5921\37 2008-04-17 23:06:35 GMT mtk01461 -+** Add iwpriv support for AdHocMode setting -+** \main\maintrunk.MT5921\36 2008-04-08 15:38:56 GMT mtk01084 -+** add KAL function to setting pattern search function enable/ disable -+** \main\maintrunk.MT5921\35 2008-04-01 23:53:13 GMT mtk01461 -+** Add comment -+** \main\maintrunk.MT5921\34 2008-03-26 15:36:48 GMT mtk01461 -+** Add update MAC Address for Linux -+** \main\maintrunk.MT5921\33 2008-03-18 11:49:34 GMT mtk01084 -+** update function for initial value access -+** \main\maintrunk.MT5921\32 2008-03-18 10:25:22 GMT mtk01088 -+** use kal update associate request at linux -+** \main\maintrunk.MT5921\31 2008-03-06 23:43:08 GMT mtk01385 -+** 1. add Query Registry Mac address function. -+** \main\maintrunk.MT5921\30 2008-02-26 09:47:57 GMT mtk01084 -+** modify KAL set network address/ checksum offload part -+** \main\maintrunk.MT5921\29 2008-02-12 23:26:53 GMT mtk01461 -+** Add debug option - Packet Order for Linux -+** \main\maintrunk.MT5921\28 2008-01-09 17:54:43 GMT mtk01084 -+** modify the argument of kalQueryPacketInfo() -+** \main\maintrunk.MT5921\27 2007-12-24 16:02:03 GMT mtk01425 -+** 1. Revise csum offload -+** \main\maintrunk.MT5921\26 2007-11-30 17:03:36 GMT mtk01425 -+** 1. Fix bugs -+** -+** \main\maintrunk.MT5921\25 2007-11-29 01:57:17 GMT mtk01461 -+** Fix Windows RX multiple packet retain problem -+** \main\maintrunk.MT5921\24 2007-11-20 11:24:07 GMT mtk01088 -+** CR90, not doing the netif_carrier_off to let supplicant 1x pkt can be rcv at hardstattXmit -+** \main\maintrunk.MT5921\23 2007-11-09 16:36:44 GMT mtk01425 -+** 1. Modify for CSUM offloading with Tx Fragment -+** \main\maintrunk.MT5921\22 2007-11-07 18:37:39 GMT mtk01461 -+** Add Tx Fragmentation Support -+** \main\maintrunk.MT5921\21 2007-11-06 19:34:06 GMT mtk01088 -+** add the WPS code, indicate the mgmt frame to upper layer -+** \main\maintrunk.MT5921\20 2007-11-02 01:03:21 GMT mtk01461 -+** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning -+** \main\maintrunk.MT5921\19 2007-10-30 11:59:38 GMT MTK01425 -+** 1. Update wlanQueryInformation -+** \main\maintrunk.MT5921\18 2007-10-30 10:44:57 GMT mtk01425 -+** 1. Refine multicast list code -+** 2. Refine TCP/IP csum offload code -+** -+** Revision 1.5 2007/07/17 13:01:18 MTK01088 -+** add associate req and rsp function -+** -+** Revision 1.4 2007/07/13 05:19:19 MTK01084 -+** provide timer set functions -+** -+** Revision 1.3 2007/06/27 02:18:51 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+** Revision 1.2 2007/06/25 06:16:24 MTK01461 -+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include "gl_os.h" -+#include "gl_wext.h" -+#include "precomp.h" -+#if defined(CONFIG_MTK_TC1_FEATURE) -+#include -+#endif -+#if CFG_SUPPORT_AGPS_ASSIST -+#include -+#endif -+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG -+#include -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if DBG -+int allocatedMemSize = 0; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+/* #define MTK_DMA_BUF_MEMCPY_SUP */ -+static PVOID pvIoBuffer; -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+static PVOID pvIoPhyBuf; -+static PVOID pvDmaBuffer; -+static PVOID pvDmaPhyBuf; -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+static UINT_32 pvIoBufferSize; -+static UINT_32 pvIoBufferUsage; -+static struct KAL_HALT_CTRL_T rHaltCtrl = { -+ .lock = __SEMAPHORE_INITIALIZER(rHaltCtrl.lock, 1), -+ .owner = NULL, -+ .fgHalt = TRUE, -+ .fgHeldByKalIoctl = FALSE, -+ .u4HoldStart = 0, -+}; -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+#if defined(MT6620) && CFG_MULTI_ECOVER_SUPPORT -+typedef enum _ENUM_WMTHWVER_TYPE_T { -+ WMTHWVER_MT6620_E1 = 0x0, -+ WMTHWVER_MT6620_E2 = 0x1, -+ WMTHWVER_MT6620_E3 = 0x2, -+ WMTHWVER_MT6620_E4 = 0x3, -+ WMTHWVER_MT6620_E5 = 0x4, -+ WMTHWVER_MT6620_E6 = 0x5, -+ WMTHWVER_MT6620_MAX, -+ WMTHWVER_INVALID = 0xff -+} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T; -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+VOID kalHifAhbKalWakeLockTimeout(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ KAL_WAKE_LOCK_TIMEOUT(prGlueInfo->prAdapter, &(prGlueInfo->rAhbIsrWakeLock), (HZ / 10)); /* 100ms */ -+} -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+ -+static struct file *filp; -+static uid_t orgfsuid; -+static gid_t orgfsgid; -+static mm_segment_t orgfs; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to -+* open firmware image in kernel space -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS. -+* \retval WLAN_STATUS_FAILURE. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS kalFirmwareOpen(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ UINT_8 aucFilePath[50]; -+ -+ /* FIX ME: since we don't have hotplug script in the filesystem -+ * , so the request_firmware() KAPI can not work properly -+ */ -+ -+ /* save uid and gid used for filesystem access. -+ * set user and group to 0(root) */ -+ struct cred *cred = (struct cred *)get_current_cred(); -+ -+ orgfsuid = cred->fsuid.val; -+ orgfsgid = cred->fsgid.val; -+ cred->fsuid.val = cred->fsgid.val = 0; -+ -+ ASSERT(prGlueInfo); -+ -+ orgfs = get_fs(); -+ set_fs(get_ds()); -+ -+ /* open the fw file */ -+#if defined(MT6620) & CFG_MULTI_ECOVER_SUPPORT -+ switch (mtk_wcn_wmt_hwver_get()) { -+ case WMTHWVER_MT6620_E1: -+ case WMTHWVER_MT6620_E2: -+ case WMTHWVER_MT6620_E3: -+ case WMTHWVER_MT6620_E4: -+ case WMTHWVER_MT6620_E5: -+ filp = filp_open("/lib/firmware/mediatek/" CFG_FW_FILENAME, O_RDONLY, 0); -+ break; -+ -+ case WMTHWVER_MT6620_E6: -+ default: -+ filp = filp_open("/lib/firmware/mediatek/" CFG_FW_FILENAME "_E6", O_RDONLY, 0); -+ break; -+ } -+#elif defined(MT6628) -+/* filp = filp_open("/lib/firmware/mediatek/"CFG_FW_FILENAME"_MT6628", O_RDONLY, 0); */ -+/* filp = filp_open("/lib/firmware/mediatek/"CFG_FW_FILENAME"_MT6582", O_RDONLY, 0); */ -+#if 0 /* new wifi ram code mechanism, waiting firmware ready, then we can enable these code */ -+ kalMemZero(aucFilePath, sizeof(aucFilePath)); -+ kalMemCopy(aucFilePath, "/lib/firmware/mediatek/" CFG_FW_FILENAME "_AD", sizeof("/lib/firmware/mediatek/" CFG_FW_FILENAME "_AD")); -+ filp = filp_open(aucFilePath, O_RDONLY, 0); -+ if (!IS_ERR(filp)) -+ goto open_success; -+#endif -+ kalMemZero(aucFilePath, sizeof(aucFilePath)); -+ kalMemCopy(aucFilePath, "/lib/firmware/mediatek/" CFG_FW_FILENAME "_", strlen("/lib/firmware/mediatek/" CFG_FW_FILENAME "_")); -+ glGetChipInfo(prGlueInfo, &aucFilePath[strlen("/lib/firmware/mediatek/" CFG_FW_FILENAME "_")]); -+ -+ DBGLOG(INIT, INFO, "open file: %s\n", aucFilePath); -+ -+ filp = filp_open(aucFilePath, O_RDONLY, 0); -+#else -+ filp = filp_open("/lib/firmware/mediatek/" CFG_FW_FILENAME, O_RDONLY, 0); -+#endif -+ if (IS_ERR(filp)) { -+ DBGLOG(INIT, ERROR, "Open FW image: %s failed\n", CFG_FW_FILENAME); -+ goto error_open; -+ } -+#if 0 -+open_success: -+#endif -+ DBGLOG(INIT, TRACE, "Open FW image: %s done\n", CFG_FW_FILENAME); -+ return WLAN_STATUS_SUCCESS; -+ -+error_open: -+ /* restore */ -+ set_fs(orgfs); -+ cred->fsuid.val = orgfsuid; -+ cred->fsgid.val = orgfsgid; -+ put_cred(cred); -+ return WLAN_STATUS_FAILURE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to -+* release firmware image in kernel space -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS. -+* \retval WLAN_STATUS_FAILURE. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS kalFirmwareClose(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ if ((filp != NULL) && !IS_ERR(filp)) { -+ /* close firmware file */ -+ filp_close(filp, NULL); -+ -+ /* restore */ -+ set_fs(orgfs); -+ { -+ struct cred *cred = (struct cred *)get_current_cred(); -+ -+ cred->fsuid.val = orgfsuid; -+ cred->fsgid.val = orgfsgid; -+ put_cred(cred); -+ } -+ filp = NULL; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to -+* load firmware image in kernel space -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS. -+* \retval WLAN_STATUS_FAILURE. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS kalFirmwareLoad(IN P_GLUE_INFO_T prGlueInfo, OUT PVOID prBuf, IN UINT_32 u4Offset, OUT PUINT_32 pu4Size) -+{ -+ ASSERT(prGlueInfo); -+ ASSERT(pu4Size); -+ ASSERT(prBuf); -+ -+ /* l = filp->f_path.dentry->d_inode->i_size; */ -+#if 0 -+ /* the object must have a read method */ -+ if ((filp == NULL) || IS_ERR(filp) || (filp->f_op == NULL) || (filp->f_op->read == NULL)) { -+ goto error_read; -+ } else { -+ filp->f_pos = u4Offset; -+ *pu4Size = filp->f_op->read(filp, prBuf, *pu4Size, &filp->f_pos); -+ } -+#else -+ /* the object must have a read method */ -+ if ((filp == NULL) || IS_ERR(filp) || (filp->f_op == NULL) ) { -+ goto error_read; -+ } else { -+ filp->f_pos = u4Offset; -+ *pu4Size = vfs_read(filp, prBuf, *pu4Size, &filp->f_pos); -+ } -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+ -+error_read: -+ return WLAN_STATUS_FAILURE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to -+* query firmware image size in kernel space -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS. -+* \retval WLAN_STATUS_FAILURE. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS kalFirmwareSize(IN P_GLUE_INFO_T prGlueInfo, OUT PUINT_32 pu4Size) -+{ -+ ASSERT(prGlueInfo); -+ ASSERT(pu4Size); -+ -+ //*pu4Size = filp->f_path.dentry->d_inode->i_size; -+ *pu4Size = filp->f_op->llseek(filp, 0, 2); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to load firmware image -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* \param ppvMapFileBuf Pointer of pointer to memory-mapped firmware image -+* \param pu4FileLength File length and memory mapped length as well -+ -+* \retval Map File Handle, used for unammping -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength) -+{ -+ UINT_32 u4FwSize = 0; -+ PVOID prFwBuffer = NULL; -+ -+ DEBUGFUNC("kalFirmwareImageMapping"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(ppvMapFileBuf); -+ ASSERT(pu4FileLength); -+ -+ do { -+ /* <1> Open firmware */ -+ if (kalFirmwareOpen(prGlueInfo) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, TRACE, "kalFirmwareOpen fail!\n"); -+ break; -+ } -+ -+ /* <2> Query firmare size */ -+ kalFirmwareSize(prGlueInfo, &u4FwSize); -+ printk(KERN_ERR "%s firmware size %d\n", __FUNCTION__, u4FwSize); -+ /* <3> Use vmalloc for allocating large memory trunk */ -+ prFwBuffer = vmalloc(ALIGN_4(u4FwSize)); -+ /* <4> Load image binary into buffer */ -+ if (kalFirmwareLoad(prGlueInfo, prFwBuffer, 0, &u4FwSize) != WLAN_STATUS_SUCCESS) { -+ vfree(prFwBuffer); -+ kalFirmwareClose(prGlueInfo); -+ DBGLOG(INIT, TRACE, "kalFirmwareLoad fail!\n"); -+ break; -+ } -+ /* <5> write back info */ -+ *pu4FileLength = u4FwSize; -+ *ppvMapFileBuf = prFwBuffer; -+ -+ return prFwBuffer; -+ -+ } while (FALSE); -+ -+ return NULL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to unload firmware image mapped memory -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* \param pvFwHandle Pointer to mapping handle -+* \param pvMapFileBuf Pointer to memory-mapped firmware image -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf) -+{ -+ DEBUGFUNC("kalFirmwareImageUnmapping"); -+ -+ ASSERT(prGlueInfo); -+ -+ /* pvMapFileBuf might be NULL when file doesn't exist */ -+ if (pvMapFileBuf) -+ vfree(pvMapFileBuf); -+ -+ kalFirmwareClose(prGlueInfo); -+} -+ -+#endif -+ -+#if 0 -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to load firmware image -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* \param ppvMapFileBuf Pointer of pointer to memory-mapped firmware image -+* \param pu4FileLength File length and memory mapped length as well -+ -+* \retval Map File Handle, used for unammping -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength) -+{ -+ INT_32 i4Ret = 0; -+ -+ DEBUGFUNC("kalFirmwareImageMapping"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(ppvMapFileBuf); -+ ASSERT(pu4FileLength); -+ -+ do { -+ GL_HIF_INFO_T *prHifInfo = &prGlueInfo->rHifInfo; -+ -+ prGlueInfo->prFw = NULL; -+ -+ /* <1> Open firmware */ -+ i4Ret = request_firmware(&prGlueInfo->prFw, CFG_FW_FILENAME, prHifInfo->Dev); -+ -+ if (i4Ret) { -+ DBGLOG(INIT, TRACE, "fw %s:request failed %d\n", CFG_FW_FILENAME, i4Ret); -+ break; -+ } -+ *pu4FileLength = prGlueInfo->prFw->size; -+ *ppvMapFileBuf = prGlueInfo->prFw->data; -+ return prGlueInfo->prFw->data; -+ -+ } while (FALSE); -+ -+ return NULL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to unload firmware image mapped memory -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* \param pvFwHandle Pointer to mapping handle -+* \param pvMapFileBuf Pointer to memory-mapped firmware image -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf) -+{ -+ DEBUGFUNC("kalFirmwareImageUnmapping"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(pvMapFileBuf); -+ -+ release_firmware(prGlueInfo->prFw); -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to acquire -+* OS SPIN_LOCK. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] rLockCategory Specify which SPIN_LOCK -+* \param[out] pu4Flags Pointer of a variable for saving IRQ flags -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalAcquireSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, OUT unsigned long *pu4Flags) -+{ -+ unsigned long u4Flags = 0; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(pu4Flags); -+ -+ if (rLockCategory < SPIN_LOCK_NUM) { -+ -+#if CFG_USE_SPIN_LOCK_BOTTOM_HALF -+ spin_lock_bh(&prGlueInfo->rSpinLock[rLockCategory]); -+#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+ spin_lock_irqsave(&prGlueInfo->rSpinLock[rLockCategory], u4Flags); -+#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+ -+ *pu4Flags = u4Flags; -+/* DBGLOG(INIT, TRACE, ("A+%d\n", rLockCategory)); */ -+ } -+ -+} /* end of kalAcquireSpinLock() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to release -+* OS SPIN_LOCK. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] rLockCategory Specify which SPIN_LOCK -+* \param[in] u4Flags Saved IRQ flags -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalReleaseSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, IN UINT_32 u4Flags) -+{ -+ ASSERT(prGlueInfo); -+ -+ if (rLockCategory < SPIN_LOCK_NUM) { -+ /* DBGLOG(INIT, TRACE, ("A-%d %d %d\n", rLockCategory, u4MemAllocCnt, u4MemFreeCnt)); */ -+#if CFG_USE_SPIN_LOCK_BOTTOM_HALF -+ spin_unlock_bh(&prGlueInfo->rSpinLock[rLockCategory]); -+#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+ spin_unlock_irqrestore(&prGlueInfo->rSpinLock[rLockCategory], u4Flags); -+#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+ -+ } -+ -+} /* end of kalReleaseSpinLock() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to update -+* current MAC address. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pucMacAddr Pointer of current MAC address -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalUpdateMACAddress(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucMacAddr) -+{ -+ ASSERT(prGlueInfo); -+ ASSERT(pucMacAddr); -+ -+ if (UNEQUAL_MAC_ADDR(prGlueInfo->prDevHandler->dev_addr, pucMacAddr)) -+ memcpy(prGlueInfo->prDevHandler->dev_addr, pucMacAddr, PARAM_MAC_ADDR_LEN); -+ -+} -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To query the packet information for offload related parameters. -+* -+* \param[in] pvPacket Pointer to the packet descriptor. -+* \param[in] pucFlag Points to the offload related parameter. -+* -+* \return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalQueryTxChksumOffloadParam(IN PVOID pvPacket, OUT PUINT_8 pucFlag) -+{ -+ struct sk_buff *skb = (struct sk_buff *)pvPacket; -+ UINT_8 ucFlag = 0; -+ -+ ASSERT(pvPacket); -+ ASSERT(pucFlag); -+ -+ -+ if (skb->ip_summed == CHECKSUM_PARTIAL) { -+#if DBG -+ /* Kevin: do double check, we can remove this part in Normal Driver. -+ * Because we register NIC feature with NETIF_F_IP_CSUM for MT5912B MAC, so -+ * we'll process IP packet only. -+ */ -+ if (skb->protocol != htons(ETH_P_IP)) { -+ /* printk("Wrong skb->protocol( = %08x) for TX Checksum Offload.\n", skb->protocol); */ -+ } else -+#endif -+ ucFlag |= (TX_CS_IP_GEN | TX_CS_TCP_UDP_GEN); -+ } -+ -+ *pucFlag = ucFlag; -+ -+} /* kalQueryChksumOffloadParam */ -+ -+/* 4 2007/10/8, mikewu, this is rewritten by Mike */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To update the checksum offload status to the packet to be indicated to OS. -+* -+* \param[in] pvPacket Pointer to the packet descriptor. -+* \param[in] pucFlag Points to the offload related parameter. -+* -+* \return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalUpdateRxCSUMOffloadParam(IN PVOID pvPacket, IN ENUM_CSUM_RESULT_T aeCSUM[]) -+{ -+ struct sk_buff *skb = (struct sk_buff *)pvPacket; -+ -+ ASSERT(pvPacket); -+ -+ if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS || aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS) && -+ ((aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS) || (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS))) { -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ } else { -+ skb->ip_summed = CHECKSUM_NONE; -+#if DBG -+ if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE && aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE) -+ DBGLOG(RX, TRACE, "RX: \"non-IPv4/IPv6\" Packet\n"); -+ else if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED) -+ DBGLOG(RX, TRACE, "RX: \"bad IP Checksum\" Packet\n"); -+ else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED) -+ DBGLOG(RX, TRACE, "RX: \"bad TCP Checksum\" Packet\n"); -+ else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED) -+ DBGLOG(RX, TRACE, "RX: \"bad UDP Checksum\" Packet\n"); -+ else -+ /* Do nothing */ -+#endif -+ } -+ -+} /* kalUpdateRxCSUMOffloadParam */ -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to free packet allocated from kalPacketAlloc. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of the packet descriptor -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalPacketFree(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket) -+{ -+ dev_kfree_skb((struct sk_buff *)pvPacket); -+ if (prGlueInfo) -+ prGlueInfo->u8SkbFreed++; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Only handles driver own creating packet (coalescing buffer). -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* \param u4Size Pointer of Packet Handle -+* \param ppucData Status Code for OS upper layer -+* -+* \return NULL: Failed to allocate skb, Not NULL get skb -+*/ -+/*----------------------------------------------------------------------------*/ -+PVOID kalPacketAlloc(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Size, OUT PUINT_8 *ppucData) -+{ -+ struct sk_buff *prSkb = dev_alloc_skb(u4Size); -+ -+ if (prSkb) -+ *ppucData = (PUINT_8) (prSkb->data); -+#if DBG -+ { -+ PUINT_32 pu4Head = (PUINT_32) &prSkb->cb[0]; -+ *pu4Head = (UINT_32) prSkb->head; -+ DBGLOG(RX, TRACE, "prSkb->head = %#x, prSkb->cb = %#x\n", (UINT_32) prSkb->head, *pu4Head); -+ } -+#endif -+ return (PVOID) prSkb; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Process the received packet for indicating to OS. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure. -+* \param[in] pvPacket Pointer of the packet descriptor -+* \param[in] pucPacketStart The starting address of the buffer of Rx packet. -+* \param[in] u4PacketLen The packet length. -+* \param[in] pfgIsRetain Is the packet to be retained. -+* \param[in] aerCSUM The result of TCP/ IP checksum offload. -+* -+* \retval WLAN_STATUS_SUCCESS. -+* \retval WLAN_STATUS_FAILURE. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+kalProcessRxPacket(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN PUINT_8 pucPacketStart, IN UINT_32 u4PacketLen, -+ /* IN PBOOLEAN pfgIsRetain, */ -+ IN BOOLEAN fgIsRetain, IN ENUM_CSUM_RESULT_T aerCSUM[]) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ struct sk_buff *skb = (struct sk_buff *)pvPacket; -+ -+ skb->data = pucPacketStart; -+ skb_reset_tail_pointer(skb); /* reset tail pointer first, for 64bit kernel,we should call linux kernel API */ -+ skb_trim(skb, 0); /* only if skb->len > len, then skb_trim has effect */ -+ skb_put(skb, u4PacketLen); /* shift tail and skb->len to correct value */ -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ kalUpdateRxCSUMOffloadParam(skb, aerCSUM); -+#endif -+ -+ return rStatus; -+} -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Do HIF loopback test. -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+unsigned int testmode = 0; -+unsigned int testlen = 64; -+ -+void kalDevLoopbkAuto(IN GLUE_INFO_T *GlueInfo) -+{ -+#define HIF_LOOPBK_AUTO_TEST_LEN 1600 -+/* GL_HIF_INFO_T *HifInfo; */ -+ static unsigned int txcnt; -+ struct sk_buff *MsduInfo; -+ UINT_8 *Pkt; -+ UINT_32 RegVal; -+ UINT_32 PktLen = 16; -+ -+ /* Init */ -+ if (testmode != 0) { -+ PktLen = kalRandomNumber() % 1520; -+ if (PktLen < 64) -+ PktLen = 64; -+ } else { -+ PktLen = testlen++; -+ if (PktLen > 1520) { -+ testmode = 1; -+ PktLen = 64; -+ } -+ } -+ -+/* PktLen = 100; */ -+ DBGLOG(INIT, INFO, "kalDevLoopbkAuto> Send a packet to HIF (len = %d) (total = %d)...\n", PktLen, ++txcnt); -+/* HifInfo = &GlueInfo->rHifInfo; */ -+ -+ /* Allocate a MSDU_INFO_T */ -+ MsduInfo = kalPacketAlloc(GlueInfo, HIF_LOOPBK_AUTO_TEST_LEN, &Pkt); -+ if (MsduInfo == NULL) { -+ DBGLOG(INIT, WARN, "No PKT_INFO_T for sending loopback packet!\n"); -+ return; -+ } -+ -+ /* Init the packet */ -+ MsduInfo->dev = GlueInfo->prDevHandler; -+ if (MsduInfo->dev == NULL) { -+ DBGLOG(INIT, WARN, "MsduInfo->dev == NULL!!\n"); -+ kalPacketFree(GlueInfo, MsduInfo); -+ return; -+ } -+ -+ MsduInfo->len = PktLen; -+ kalMemSet(MsduInfo->data, 0xff, 6); -+ kalMemSet(MsduInfo->data + 6, 0x5a, PktLen - 6); -+ -+ /* Simulate OS to send the packet */ -+ wlanHardStartXmit(MsduInfo, MsduInfo->dev); -+ -+#if 0 -+ PktLen += 4; -+ if (PktLen >= 1600) -+ PktLen = 16; -+#endif -+ -+ /* Note: in FPGA, clock is not accuracy so 3000 here, not 10000 */ -+/* HifInfo->HifTmrLoopbkFn.expires = jiffies + MSEC_TO_SYSTIME(1000); */ -+/* add_timer(&(HifInfo->HifTmrLoopbkFn)); */ -+} -+ -+int kalDevLoopbkThread(IN void *data) -+{ -+ struct net_device *dev = data; -+ P_GLUE_INFO_T GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev)); -+ GL_HIF_INFO_T *HifInfo = &GlueInfo->rHifInfo; -+ int ret; -+ static int test; -+ -+ while (TRUE) { -+ ret = wait_event_interruptible(HifInfo->HifWaitq, (HifInfo->HifLoopbkFlg != 0)); -+ -+ if (HifInfo->HifLoopbkFlg == 0xFFFFFFFF) -+ break; -+ -+ while (TRUE) { -+ /* if ((HifInfo->HifLoopbkFlg & 0x01) == 0) */ -+ if (GlueInfo->i4TxPendingFrameNum < 64) { -+ DBGLOG(INIT, INFO, "GlueInfo->i4TxPendingFrameNum = %d\n", -+ GlueInfo->i4TxPendingFrameNum); -+ kalDevLoopbkAuto(GlueInfo); -+ -+ if (testmode == 0) -+ kalMsleep(3000); -+ } else -+ kalMsleep(1); -+ } -+ } -+} -+ -+void kalDevLoopbkRxHandle(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ static unsigned int rxcnt; -+ UINT_32 i; -+ UINT_8 *Buf = prSwRfb->pucRecvBuff + sizeof(HIF_TX_HEADER_T); -+ P_HIF_RX_HEADER_T prHifRxHdr = prSwRfb->prHifRxHdr; -+ UINT_32 len = prHifRxHdr->u2PacketLen - sizeof(HIF_TX_HEADER_T); -+ -+ if (len > 1600) { -+ while (1) -+ DBGLOG(INIT, ERROR, "HIF> Loopback len > 1600!!! error!!!\n"); -+ } -+ -+ for (i = 0; i < 6; i++) { -+ if (Buf[i] != 0xff) { -+ while (1) { -+ DBGLOG(INIT, ERROR, "HIF> Loopbk dst addr error (len = %d)!\n", len); -+ dumpMemory8(prSwRfb->pucRecvBuff, prHifRxHdr->u2PacketLen); -+ } -+ } -+ } -+ -+ for (i = 6; i < len; i++) { -+ if (Buf[i] != 0x5a) { -+ while (1) { -+ DBGLOG(INIT, ERROR, "HIF> Loopbk error (len = %d)!\n", len); -+ dumpMemory8(prSwRfb->pucRecvBuff, prHifRxHdr->u2PacketLen); -+ } -+ } -+ } -+ -+ DBGLOG(INIT, INFO, "HIF> Loopbk OK (len = %d) (total = %d)!\n", len, ++rxcnt); -+} -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate an array of received packets is available for higher -+* level protocol uses. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure. -+* \param[in] apvPkts The packet array to be indicated -+* \param[in] ucPktNum The number of packets to be indicated -+* -+* \retval TRUE Success. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS kalRxIndicatePkts(IN P_GLUE_INFO_T prGlueInfo, IN PVOID apvPkts[], IN UINT_8 ucPktNum) -+{ -+ UINT_8 ucIdx = 0; -+ struct net_device *prNetDev = prGlueInfo->prDevHandler; -+ struct sk_buff *prSkb = NULL; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(apvPkts); -+ -+#if CFG_BOW_TEST -+ UINT_32 i; -+#endif -+ -+ for (ucIdx = 0; ucIdx < ucPktNum; ucIdx++) { -+ prSkb = apvPkts[ucIdx]; -+#if DBG -+ do { -+ PUINT_8 pu4Head = (PUINT_8) &prSkb->cb[0]; -+ UINT_32 u4HeadValue = 0; -+ -+ kalMemCopy(&u4HeadValue, pu4Head, sizeof(u4HeadValue)); -+ DBGLOG(RX, TRACE, "prSkb->head = %p, prSkb->cb = 0x%x\n", pu4Head, u4HeadValue); -+ } while (0); -+#endif -+ -+ if (GLUE_GET_PKT_IS_P2P(prSkb)) { -+ /* P2P */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ prNetDev = kalP2PGetDevHdlr(prGlueInfo); -+ /* prNetDev->stats.rx_bytes += prSkb->len; */ -+ /* prNetDev->stats.rx_packets++; */ -+ prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes += prSkb->len; -+ prGlueInfo->prP2PInfo->rNetDevStats.rx_packets++; -+ -+#else -+ prNetDev = prGlueInfo->prDevHandler; -+#endif -+ } else if (GLUE_GET_PKT_IS_PAL(prSkb)) { -+ /* BOW */ -+#if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_SEPARATE_DATA_PATH -+ if (prGlueInfo->rBowInfo.fgIsNetRegistered) -+ prNetDev = prGlueInfo->rBowInfo.prDevHandler; -+#else -+ prNetDev = prGlueInfo->prDevHandler; -+#endif -+ } else { -+ /* AIS */ -+ prNetDev = prGlueInfo->prDevHandler; -+ prGlueInfo->rNetDevStats.rx_bytes += prSkb->len; -+ prGlueInfo->rNetDevStats.rx_packets++; -+ -+ } -+ -+ /* check if the "unicast" packet is from us */ -+ if (kalMemCmp(prSkb->data, prSkb->data + 6, 6) == 0) { -+ /* we will filter broadcast/multicast packet sent from us in hardware */ -+ /* source address = destination address ? */ -+ DBGLOG(RX, EVENT, -+ "kalRxIndicatePkts got from us!!! Drop it! ([ %pM ] len %d)\n", -+ prSkb->data, prSkb->len); -+ wlanReturnPacket(prGlueInfo->prAdapter, prSkb); -+ continue; -+ } -+#if (CFG_SUPPORT_TDLS == 1) -+ if (TdlsexRxFrameDrop(prGlueInfo, prSkb->data) == TRUE) { -+ /* drop the received TDLS action frame */ -+ DBGLOG(TDLS, WARN, -+ " %s: drop a received packet from %pM %u\n", -+ __func__, prSkb->data, -+ (UINT32) ((P_ADAPTER_T) (prGlueInfo->prAdapter))->rRxCtrl.rFreeSwRfbList.u4NumElem); -+ wlanReturnPacket(prGlueInfo->prAdapter, prSkb); -+ continue; -+ } -+ -+ /* -+ get a TDLS request/response/confirm, we need to parse the HT IE -+ because older supplicant does not pass HT IE to us -+ */ -+ TdlsexRxFrameHandle(prGlueInfo, prSkb->data, prSkb->len); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ STATS_RX_PKT_INFO_DISPLAY(prSkb->data); -+ -+ //prNetDev->last_rx = jiffies; -+ prSkb->protocol = eth_type_trans(prSkb, prNetDev); -+ prSkb->dev = prNetDev; -+ /* DBGLOG_MEM32(RX, TRACE, (PUINT_32)prSkb->data, prSkb->len); */ -+ DBGLOG(RX, TRACE, "kalRxIndicatePkts len = %d\n", prSkb->len); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, "Rx sk_buff->len: %d\n", prSkb->len); -+ DBGLOG(BOW, TRACE, "Rx sk_buff->data_len: %d\n", prSkb->data_len); -+ DBGLOG(BOW, TRACE, "Rx sk_buff->data:\n"); -+ -+ for (i = 0; i < prSkb->len; i++) { -+ DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]); -+ -+ if ((i + 1) % 16 == 0) -+ DBGLOG(BOW, TRACE, "\n"); -+ } -+ -+ DBGLOG(BOW, TRACE, "\n"); -+#endif -+ -+ if (!in_interrupt()) -+ netif_rx_ni(prSkb); /* only in non-interrupt context */ -+ else -+ netif_rx(prSkb); -+ -+ wlanReturnPacket(prGlueInfo->prAdapter, NULL); -+ } -+ -+ kalPerMonStart(prGlueInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Called by driver to indicate event to upper layer, for example, the wpa -+* supplicant or wireless tools. -+* -+* \param[in] pvAdapter Pointer to the adapter descriptor. -+* \param[in] eStatus Indicated status. -+* \param[in] pvBuf Indicated message buffer. -+* \param[in] u4BufLen Indicated message buffer size. -+* -+* \return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 ScanCnt = 0, ScanDoneFailCnt = 0; -+VOID -+kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus, IN PVOID pvBuf, IN UINT_32 u4BufLen) -+{ -+ UINT_32 bufLen; -+ P_PARAM_STATUS_INDICATION_T pStatus = (P_PARAM_STATUS_INDICATION_T) pvBuf; -+ P_PARAM_AUTH_EVENT_T pAuth = (P_PARAM_AUTH_EVENT_T) pStatus; -+ P_PARAM_PMKID_CANDIDATE_LIST_T pPmkid = (P_PARAM_PMKID_CANDIDATE_LIST_T) (pStatus + 1); -+ PARAM_MAC_ADDRESS arBssid; -+ struct cfg80211_scan_request *prScanRequest = NULL; -+ PARAM_SSID_T ssid; -+ struct ieee80211_channel *prChannel = NULL; -+ struct cfg80211_bss *bss; -+ UINT_8 ucChannelNum; -+ P_BSS_DESC_T prBssDesc = NULL; -+ struct cfg80211_scan_info info = { -+ .aborted = false, -+ }; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ kalMemZero(arBssid, MAC_ADDR_LEN); -+ -+ ASSERT(prGlueInfo); -+ -+ switch (eStatus) { -+ case WLAN_STATUS_ROAM_OUT_FIND_BEST: -+ case WLAN_STATUS_MEDIA_CONNECT: -+ -+ prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_CONNECTED; -+ -+ /* indicate assoc event */ -+ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &bufLen); -+ wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, arBssid, bufLen); -+ -+ /* switch netif on */ -+ netif_carrier_on(prGlueInfo->prDevHandler); -+ -+ do { -+ /* print message on console */ -+ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQuerySsid, &ssid, sizeof(ssid), &bufLen); -+ -+ ssid.aucSsid[(ssid.u4SsidLen >= PARAM_MAX_LEN_SSID) ? -+ (PARAM_MAX_LEN_SSID - 1) : ssid.u4SsidLen] = '\0'; -+ DBGLOG(AIS, INFO, " %s netif_carrier_on [ssid:%s %pM ]\n", -+ prGlueInfo->prDevHandler->name, ssid.aucSsid, arBssid); -+ } while (0); -+ -+ if (prGlueInfo->fgIsRegistered == TRUE) { -+ struct cfg80211_bss *bss_others = NULL; -+ UINT_8 ucLoopCnt = 15; /* only loop 15 times to avoid dead loop */ -+ -+ /* retrieve channel */ -+ ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); -+ if (ucChannelNum <= 14) { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, -+ NL80211_BAND_2GHZ)); -+ } else { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, -+ NL80211_BAND_5GHZ)); -+ } -+ -+ /* ensure BSS exists */ -+ bss = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), prChannel, arBssid, -+ ssid.aucSsid, ssid.u4SsidLen, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); -+ -+ if (bss == NULL) { -+ /* create BSS on-the-fly */ -+ prBssDesc = -+ wlanGetTargetBssDescByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ if (prBssDesc != NULL) { -+ bss = cfg80211_inform_bss(priv_to_wiphy(prGlueInfo), prChannel, -+ CFG80211_BSS_FTYPE_PRESP, -+ arBssid, 0, /* TSF */ -+ WLAN_CAPABILITY_ESS, -+ prBssDesc->u2BeaconInterval, /* beacon interval */ -+ prBssDesc->aucIEBuf, /* IE */ -+ prBssDesc->u2IELength, /* IE Length */ -+ RCPI_TO_dBm(prBssDesc->ucRCPI) * 100, /* MBM */ -+ GFP_KERNEL); -+ } -+ } -+ /* remove all bsses that before and only channel different with the current connected one -+ if without this patch, UI will show channel A is connected even if AP has change channel -+ from A to B */ -+ while (ucLoopCnt--) { -+ bss_others = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), NULL, arBssid, -+ ssid.aucSsid, ssid.u4SsidLen, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); -+ if (bss && bss_others && bss_others != bss) { -+ DBGLOG(SCN, INFO, "remove BSSes that only channel different\n"); -+ cfg80211_unlink_bss(priv_to_wiphy(prGlueInfo), bss_others); -+ } else -+ break; -+ } -+ -+ /* CFG80211 Indication */ -+ if (eStatus == WLAN_STATUS_ROAM_OUT_FIND_BEST) { -+ /*cfg80211_roamed_bss(prGlueInfo->prDevHandler, -+ bss, -+ prGlueInfo->aucReqIe, -+ prGlueInfo->u4ReqIeLength, -+ prGlueInfo->aucRspIe, prGlueInfo->u4RspIeLength, GFP_KERNEL); -+ */ -+ struct cfg80211_roam_info roam_info = { -+ .bss = bss, -+ .req_ie = prGlueInfo->aucReqIe, -+ .req_ie_len = prGlueInfo->u4ReqIeLength, -+ .resp_ie = prGlueInfo->aucRspIe, -+ .resp_ie_len = prGlueInfo->u4RspIeLength -+ }; -+ cfg80211_roamed(prGlueInfo->prDevHandler, -+ &roam_info, -+ GFP_KERNEL); -+ } else { -+ /* to support user space roaming, cfg80211 will change the sme_state to connecting -+ before reassociate */ -+ cfg80211_connect_result(prGlueInfo->prDevHandler, -+ arBssid, -+ prGlueInfo->aucReqIe, -+ prGlueInfo->u4ReqIeLength, -+ prGlueInfo->aucRspIe, -+ prGlueInfo->u4RspIeLength, WLAN_STATUS_SUCCESS, GFP_KERNEL); -+ } -+ } -+ -+ break; -+ -+ case WLAN_STATUS_MEDIA_DISCONNECT: -+ case WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY: -+ /* indicate disassoc event */ -+ wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, NULL, 0); -+ /* For CR 90 and CR99, While supplicant do reassociate, driver will do netif_carrier_off first, -+ after associated success, at joinComplete(), do netif_carier_on, -+ but for unknown reason, the supplicant 1x pkt will not called the driver -+ hardStartXmit, for template workaround these bugs, add this compiling flag -+ */ -+ /* switch netif off */ -+ -+ DBGLOG(AIS, INFO, "[wifi] %s netif_carrier_off\n", -+ prGlueInfo->prDevHandler->name); -+ -+ netif_carrier_off(prGlueInfo->prDevHandler); -+ -+ if (prGlueInfo->fgIsRegistered == TRUE) { -+ P_WIFI_VAR_T prWifiVar = &prGlueInfo->prAdapter->rWifiVar; -+ UINT_16 u2DeauthReason = prWifiVar->arBssInfo[NETWORK_TYPE_AIS_INDEX].u2DeauthReason; -+ /* CFG80211 Indication */ -+ DBGLOG(AIS, INFO, "[wifi] %s cfg80211_disconnected\n", prGlueInfo->prDevHandler->name); -+ cfg80211_disconnected(prGlueInfo->prDevHandler, u2DeauthReason, NULL, 0, false, GFP_KERNEL); -+ } -+ -+ prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; -+ -+ break; -+ -+ case WLAN_STATUS_SCAN_COMPLETE: -+ /* indicate scan complete event */ -+ wext_indicate_wext_event(prGlueInfo, SIOCGIWSCAN, NULL, 0); -+ -+ /* 1. reset first for newly incoming request */ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueInfo->prScanRequest != NULL) { -+ prScanRequest = prGlueInfo->prScanRequest; -+ prGlueInfo->prScanRequest = NULL; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ /* 2. then CFG80211 Indication */ -+ DBGLOG(SCN, TRACE, "[ais] scan complete %p %d %d\n", prScanRequest, ScanCnt, ScanDoneFailCnt); -+ -+ if (prScanRequest != NULL) -+ cfg80211_scan_done(prScanRequest, &info); -+ break; -+ case WLAN_STATUS_CONNECT_INDICATION: -+ /* indicate AIS Jion fail event -+ if (prGlueInfo->prDevHandler->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTING) */ -+ cfg80211_connect_result(prGlueInfo->prDevHandler, -+ prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc->aucBSSID, -+ prGlueInfo->aucReqIe, -+ prGlueInfo->u4ReqIeLength, -+ prGlueInfo->aucRspIe, -+ prGlueInfo->u4RspIeLength, WLAN_STATUS_AUTH_TIMEOUT, GFP_KERNEL); -+ break; -+ -+#if 0 -+ case WLAN_STATUS_MSDU_OK: -+ if (netif_running(prGlueInfo->prDevHandler)) -+ netif_wake_queue(prGlueInfo->prDevHandler); -+ break; -+#endif -+ -+ case WLAN_STATUS_MEDIA_SPECIFIC_INDICATION: -+ if (pStatus) { -+ switch (pStatus->eStatusType) { -+ case ENUM_STATUS_TYPE_AUTHENTICATION: -+ /* -+ printk(KERN_NOTICE "ENUM_STATUS_TYPE_AUTHENTICATION: L(%ld) [ %pM ] F:%lx\n", -+ pAuth->Request[0].Length, -+ pAuth->Request[0].Bssid, -+ pAuth->Request[0].Flags); -+ */ -+ /* indicate (UC/GC) MIC ERROR event only */ -+ if ((pAuth->arRequest[0].u4Flags == -+ PARAM_AUTH_REQUEST_PAIRWISE_ERROR) || -+ (pAuth->arRequest[0].u4Flags == PARAM_AUTH_REQUEST_GROUP_ERROR)) { -+ cfg80211_michael_mic_failure(prGlueInfo->prDevHandler, NULL, -+ (pAuth->arRequest[0].u4Flags == -+ PARAM_AUTH_REQUEST_PAIRWISE_ERROR) ? -+ NL80211_KEYTYPE_PAIRWISE : NL80211_KEYTYPE_GROUP, -+ 0, NULL, GFP_KERNEL); -+ wext_indicate_wext_event(prGlueInfo, IWEVMICHAELMICFAILURE, -+ (unsigned char *)&pAuth->arRequest[0], -+ pAuth->arRequest[0].u4Length); -+ } -+ break; -+ -+ case ENUM_STATUS_TYPE_CANDIDATE_LIST: -+ /* -+ printk(KERN_NOTICE "Param_StatusType_PMKID_CandidateList: Ver(%ld) Num(%ld)\n", -+ pPmkid->u2Version, -+ pPmkid->u4NumCandidates); -+ if (pPmkid->u4NumCandidates > 0) { -+ printk(KERN_NOTICE "candidate[ %pM ] preAuth Flag:%lx\n", -+ pPmkid->arCandidateList[0].rBSSID, -+ pPmkid->arCandidateList[0].fgFlags); -+ } -+ */ -+ { -+ UINT_32 i = 0; -+ /*struct net_device *prDev = prGlueInfo->prDevHandler; */ -+ P_PARAM_PMKID_CANDIDATE_T prCand = NULL; -+ /* indicate pmk candidate via cfg80211 to supplicant, -+ the second parameter is 1000 for -+ cfg80211_pmksa_candidate_notify, because wpa_supplicant defined it. */ -+ for (i = 0; i < pPmkid->u4NumCandidates; i++) { -+ prCand = &pPmkid->arCandidateList[i]; -+ cfg80211_pmksa_candidate_notify(prGlueInfo->prDevHandler, 1000, -+ prCand->arBSSID, prCand->u4Flags, -+ GFP_KERNEL); -+ -+ wext_indicate_wext_event(prGlueInfo, -+ IWEVPMKIDCAND, -+ (unsigned char *)prCand, -+ pPmkid->u4NumCandidates); -+ } -+ } -+ break; -+ -+ default: -+ /* case ENUM_STATUS_TYPE_MEDIA_STREAM_MODE */ -+ /* -+ printk(KERN_NOTICE "unknown media specific indication type:%x\n", -+ pStatus->StatusType); -+ */ -+ break; -+ } -+ } else { -+ /* -+ printk(KERN_WARNING "media specific indication buffer NULL\n"); -+ */ -+ } -+ break; -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+ case WLAN_STATUS_BWCS_UPDATE: -+ { -+ wext_indicate_wext_event(prGlueInfo, IWEVCUSTOM, pvBuf, sizeof(PTA_IPC_T)); -+ } -+ -+ break; -+ -+#endif -+ -+ default: -+ /* -+ printk(KERN_WARNING "unknown indication:%lx\n", eStatus); -+ */ -+ break; -+ } -+} /* kalIndicateStatusAndComplete */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to update the (re)association request -+* information to the structure used to query and set -+* OID_802_11_ASSOCIATION_INFORMATION. -+* -+* \param[in] prGlueInfo Pointer to the Glue structure. -+* \param[in] pucFrameBody Pointer to the frame body of the last (Re)Association -+* Request frame from the AP. -+* \param[in] u4FrameBodyLen The length of the frame body of the last -+* (Re)Association Request frame. -+* \param[in] fgReassocRequest TRUE, if it is a Reassociation Request frame. -+* -+* \return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalUpdateReAssocReqInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest) -+{ -+ PUINT_8 cp; -+ -+ ASSERT(prGlueInfo); -+ -+ /* reset */ -+ prGlueInfo->u4ReqIeLength = 0; -+ -+ if (fgReassocRequest) { -+ if (u4FrameBodyLen < 15) { -+ /* -+ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); -+ */ -+ return; -+ } -+ } else { -+ if (u4FrameBodyLen < 9) { -+ /* -+ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); -+ */ -+ return; -+ } -+ } -+ -+ cp = pucFrameBody; -+ -+ if (fgReassocRequest) { -+ /* Capability information field 2 */ -+ /* Listen interval field 2 */ -+ /* Current AP address 6 */ -+ cp += 10; -+ u4FrameBodyLen -= 10; -+ } else { -+ /* Capability information field 2 */ -+ /* Listen interval field 2 */ -+ cp += 4; -+ u4FrameBodyLen -= 4; -+ } -+ -+ wext_indicate_wext_event(prGlueInfo, IWEVASSOCREQIE, cp, u4FrameBodyLen); -+ -+ if (u4FrameBodyLen <= CFG_CFG80211_IE_BUF_LEN) { -+ prGlueInfo->u4ReqIeLength = u4FrameBodyLen; -+ kalMemCopy(prGlueInfo->aucReqIe, cp, u4FrameBodyLen); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is called to update the (re)association -+* response information to the structure used to reply with -+* cfg80211_connect_result -+* -+* @param prGlueInfo Pointer to adapter descriptor -+* @param pucFrameBody Pointer to the frame body of the last (Re)Association -+* Response frame from the AP -+* @param u4FrameBodyLen The length of the frame body of the last -+* (Re)Association Response frame -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalUpdateReAssocRspInfo(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen) -+{ -+ UINT_32 u4IEOffset = 6; /* cap_info, status_code & assoc_id */ -+ UINT_32 u4IELength = u4FrameBodyLen - u4IEOffset; -+ -+ ASSERT(prGlueInfo); -+ -+ /* reset */ -+ prGlueInfo->u4RspIeLength = 0; -+ -+ if (u4IELength <= CFG_CFG80211_IE_BUF_LEN) { -+ prGlueInfo->u4RspIeLength = u4IELength; -+ kalMemCopy(prGlueInfo->aucRspIe, pucFrameBody + u4IEOffset, u4IELength); -+ } -+ -+} /* kalUpdateReAssocRspInfo */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Notify OS with SendComplete event of the specific packet. Linux should -+* free packets here. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of Packet Handle -+* \param[in] status Status Code for OS upper layer -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalSendCompleteAndAwakeQueue(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket) -+{ -+ -+ struct net_device *prDev = NULL; -+ struct sk_buff *prSkb = NULL; -+ UINT_16 u2QueueIdx = 0; -+ UINT_8 ucNetworkType = 0; -+ BOOLEAN fgIsValidDevice = TRUE; -+ -+ ASSERT(pvPacket); -+ ASSERT(prGlueInfo->i4TxPendingFrameNum); -+ -+ prSkb = (struct sk_buff *)pvPacket; -+ u2QueueIdx = skb_get_queue_mapping(prSkb); -+ ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); -+ -+ if (GLUE_GET_PKT_IS_PAL(prSkb)) { -+ ucNetworkType = NETWORK_TYPE_BOW_INDEX; -+ } else if (GLUE_GET_PKT_IS_P2P(prSkb)) { -+ ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* in case packet was sent after P2P device is unregistered */ -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) -+ fgIsValidDevice = FALSE; -+#endif -+ } else { -+ ucNetworkType = NETWORK_TYPE_AIS_INDEX; -+ } -+ -+ GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); -+ if (u2QueueIdx < CFG_MAX_TXQ_NUM) -+ GLUE_DEC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx]); -+ prDev = prSkb->dev; -+ -+ ASSERT(prDev); -+ -+ if ((fgIsValidDevice == TRUE) && (u2QueueIdx < CFG_MAX_TXQ_NUM)) { -+ if (netif_subqueue_stopped(prDev, prSkb) && -+ prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx] <= -+ CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD) { -+ DBGLOG(TX, INFO, "netif_wake_subqueue for bss: %d. Queue len: %d\n", -+ ucNetworkType, -+ prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx]); -+ netif_wake_subqueue(prDev, u2QueueIdx); -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+ prGlueInfo->rHifInfo.HifLoopbkFlg &= ~0x01; -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ } -+ } -+ -+ dev_kfree_skb((struct sk_buff *)pvPacket); -+ prGlueInfo->u8SkbFreed++; -+ -+ DBGLOG(TX, EVENT, "----- pending frame %d -----\n", prGlueInfo->i4TxPendingFrameNum); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Copy Mac Address setting from registry. It's All Zeros in Linux. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* \param[out] paucMacAddr Pointer to the Mac Address buffer -+* -+* \retval WLAN_STATUS_SUCCESS -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalQueryRegistryMacAddr(IN P_GLUE_INFO_T prGlueInfo, OUT PUINT_8 paucMacAddr) -+{ -+ UINT_8 aucZeroMac[MAC_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 } -+ -+ DEBUGFUNC("kalQueryRegistryMacAddr"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(paucMacAddr); -+ -+ kalMemCopy((PVOID) paucMacAddr, (PVOID) aucZeroMac, MAC_ADDR_LEN); -+ -+} /* end of kalQueryRegistryMacAddr() */ -+ -+#if CFG_SUPPORT_EXT_CONFIG -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Read external configuration, ex. NVRAM or file -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalReadExtCfg(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ /* External data is given from user space by ioctl or /proc, not read by -+ driver. -+ */ -+ if (0 != prGlueInfo->u4ExtCfgLength) -+ DBGLOG(INIT, TRACE, "Read external configuration data -- OK\n"); -+ else -+ DBGLOG(INIT, TRACE, "Read external configuration data -- fail\n"); -+ -+ return prGlueInfo->u4ExtCfgLength; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This inline function is to extract some packet information, including -+* user priority, packet length, destination address, 802.1x and BT over Wi-Fi -+* or not. -+* -+* @param prGlueInfo Pointer to the glue structure -+* @param prNdisPacket Packet descriptor -+* @param pucPriorityParam User priority -+* @param pu4PacketLen Packet length -+* @param pucEthDestAddr Destination address -+* @param pfgIs1X 802.1x packet or not -+* @param pfgIsPAL BT over Wi-Fi packet or not -+* @prGenUse General used param -+* -+* @retval TRUE Success to extract information -+* @retval FALSE Fail to extract correct information -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+BOOLEAN -+kalQoSFrameClassifierAndPacketInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_NATIVE_PACKET prPacket, -+ OUT PUINT_8 pucPriorityParam, -+ OUT PUINT_32 pu4PacketLen, -+ OUT PUINT_8 pucEthDestAddr, -+ OUT PBOOLEAN pfgIs1X, -+ OUT PBOOLEAN pfgIsPAL, OUT PUINT_8 pucNetworkType, -+ OUT PVOID prGenUse) -+{ -+ -+ UINT_32 u4PacketLen; -+ -+ UINT_8 ucUserPriority = USER_PRIORITY_DEFAULT; /* Default */ -+ UINT_16 u2EtherTypeLen; -+ struct sk_buff *prSkb = (struct sk_buff *)prPacket; -+ PUINT_8 aucLookAheadBuf = NULL; -+ -+ DEBUGFUNC("kalQoSFrameClassifierAndPacketInfo"); -+ -+ u4PacketLen = prSkb->len; -+ -+ if (u4PacketLen < ETH_HLEN) { -+ DBGLOG(TX, WARN, "Invalid Ether packet length: %u\n", (UINT_32) u4PacketLen); -+ return FALSE; -+ } -+ -+ aucLookAheadBuf = prSkb->data; -+ -+ *pfgIs1X = FALSE; -+ *pfgIsPAL = FALSE; -+ -+ /* 4 <3> Obtain the User Priority for WMM */ -+ u2EtherTypeLen = (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET] << 8) | (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ if ((u2EtherTypeLen == ETH_P_IP) && (u4PacketLen >= LOOK_AHEAD_LEN)) { -+ PUINT_8 pucIpHdr = &aucLookAheadBuf[ETH_HLEN]; -+ UINT_8 ucIpVersion; -+ -+ ucIpVersion = (pucIpHdr[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; -+ if (ucIpVersion == IPVERSION) { -+ UINT_8 ucIpTos; -+ /* Get the DSCP value from the header of IP packet. */ -+ ucIpTos = pucIpHdr[1]; -+ ucUserPriority = ((ucIpTos & IPTOS_PREC_MASK) >> IPTOS_PREC_OFFSET); -+ } -+ -+ /* TODO(Kevin): Add TSPEC classifier here */ -+ } else if (u2EtherTypeLen == ETH_P_1X || u2EtherTypeLen == ETH_P_PRE_1X) { /* For Port Control */ -+ PUINT_8 pucEapol = &aucLookAheadBuf[ETH_HLEN]; -+ UINT_8 ucEapolType = pucEapol[1]; -+ UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6]; -+ /* -+ * generate a seq number used to trace security frame TX -+ */ -+ if (prGenUse) -+ *(UINT_8 *)prGenUse = nicIncreaseCmdSeqNum(prGlueInfo->prAdapter); -+ -+ switch (ucEapolType) { -+ case 0: /* eap packet */ -+ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d, seqNo %d\n", -+ pucEapol[4], pucEapol[5], pucEapol[7], -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ case 1: /* eapol start */ -+ DBGLOG(TX, INFO, " EAPOL: start, seqNo %d\n", -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ case 3: /* key */ -+ DBGLOG(TX, INFO, -+ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x... seqNo %d\n", -+ u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], -+ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24], -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ } -+ *pfgIs1X = TRUE; -+ } -+#if CFG_SUPPORT_WAPI -+ else if (u2EtherTypeLen == ETH_WPI_1X) { -+ PUINT_8 pucEthBody = &aucLookAheadBuf[ETH_HLEN]; -+ UINT_8 ucSubType = pucEthBody[3]; /* sub type filed*/ -+ UINT_16 u2Length = *(PUINT_16)&pucEthBody[6]; -+ UINT_16 u2Seq = *(PUINT_16)&pucEthBody[8]; -+ -+ DBGLOG(TX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", -+ ucSubType, u2Length, u2Seq); -+ *pfgIs1X = TRUE; -+ } -+#endif -+#if (CFG_SUPPORT_TDLS == 1) -+ else if (u2EtherTypeLen == TDLS_FRM_PROT_TYPE) { -+ /* TDLS case */ -+ TDLSEX_UP_ASSIGN(ucUserPriority); -+ } -+#endif /* CFG_SUPPORT_TDLS */ -+ else if (u2EtherTypeLen <= 1500) { /* 802.3 Frame */ -+ UINT_8 ucDSAP, ucSSAP, ucControl; -+ UINT_8 aucOUI[3]; -+ -+ ucDSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET]; -+ ucSSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 1]; -+ ucControl = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 2]; -+ -+ aucOUI[0] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET]; -+ aucOUI[1] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1]; -+ aucOUI[2] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2]; -+ -+ if (ucDSAP == ETH_LLC_DSAP_SNAP && -+ ucSSAP == ETH_LLC_SSAP_SNAP && -+ ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION && -+ aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 && -+ aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 && aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) { -+ -+ UINT_16 tmp = -+ ((aucLookAheadBuf[ETH_SNAP_OFFSET + 3] << 8) | aucLookAheadBuf[ETH_SNAP_OFFSET + 4]); -+ -+ *pfgIsPAL = TRUE; -+ ucUserPriority = (UINT_8) prSkb->priority; -+ -+ if (tmp == BOW_PROTOCOL_ID_SECURITY_FRAME) { -+ PUINT_8 pucEapol = &aucLookAheadBuf[ETH_SNAP_OFFSET + 5]; -+ UINT_8 ucEapolType = pucEapol[1]; -+ UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6]; -+ if (prGenUse) -+ *(UINT_8 *)prGenUse = nicIncreaseCmdSeqNum(prGlueInfo->prAdapter); -+ -+ switch (ucEapolType) { -+ case 0: /* eap packet */ -+ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d, seqNo %d\n", -+ pucEapol[4], pucEapol[5], pucEapol[7], -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ case 1: /* eapol start */ -+ DBGLOG(TX, INFO, " EAPOL: start, seqNo %d\n", -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ case 3: /* key */ -+ DBGLOG(TX, INFO, -+ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x seqNo %d\n", -+ u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], -+ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24], -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ } -+ *pfgIs1X = TRUE; -+ } -+ } -+ } -+ /* 4 <4> Return the value of Priority Parameter. */ -+ *pucPriorityParam = ucUserPriority; -+ -+ /* 4 <5> Retrieve Packet Information - DA */ -+ /* Packet Length/ Destination Address */ -+ *pu4PacketLen = u4PacketLen; -+ -+ kalMemCopy(pucEthDestAddr, aucLookAheadBuf, PARAM_MAC_ADDR_LEN); -+ -+ /* <6> Network type */ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (*pfgIsPAL == TRUE) { -+ *pucNetworkType = NETWORK_TYPE_BOW_INDEX; -+ } else -+#endif -+ { -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered && GLUE_GET_PKT_IS_P2P(prPacket)) { -+ *pucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ } else -+#endif -+ { -+ *pucNetworkType = NETWORK_TYPE_AIS_INDEX; -+ } -+ } -+ return TRUE; -+} /* end of kalQoSFrameClassifier() */ -+ -+VOID -+kalOidComplete(IN P_GLUE_INFO_T prGlueInfo, -+ IN BOOLEAN fgSetQuery, IN UINT_32 u4SetQueryInfoLen, IN WLAN_STATUS rOidStatus) -+{ -+ -+ ASSERT(prGlueInfo); -+ /* remove timeout check timer */ -+ wlanoidClearTimeoutCheck(prGlueInfo->prAdapter); -+ -+ /* if (prGlueInfo->u4TimeoutFlag != 1) { */ -+ prGlueInfo->rPendStatus = rOidStatus; -+ DBGLOG(OID, TEMP, "kalOidComplete, caller: %p\n", __builtin_return_address(0)); -+ complete(&prGlueInfo->rPendComp); -+ prGlueInfo->u4OidCompleteFlag = 1; -+ /* } */ -+ /* else let it timeout on kalIoctl entry */ -+} -+ -+VOID kalOidClearance(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ /* if (prGlueInfo->u4TimeoutFlag != 1) { */ -+ /* clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->u4Flag); */ -+ if (prGlueInfo->u4OidCompleteFlag != 1) { -+ DBGLOG(OID, TEMP, "kalOidClearance, caller: %p\n", __builtin_return_address(0)); -+ complete(&prGlueInfo->rPendComp); -+ } -+ /* } */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to transfer linux ioctl to OID, and we -+* need to specify the behavior of the OID by ourself -+* -+* @param prGlueInfo Pointer to the glue structure -+* @param pvInfoBuf Data buffer -+* @param u4InfoBufLen Data buffer length -+* @param fgRead Is this a read OID -+* @param fgWaitResp does this OID need to wait for values -+* @param fgCmd does this OID compose command packet -+* @param pu4QryInfoLen The data length of the return values -+* -+* @retval TRUE Success to extract information -+* @retval FALSE Fail to extract correct information -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+/* todo: enqueue the i/o requests for multiple processes access */ -+/* */ -+/* currently, return -1 */ -+/* */ -+ -+/* static GL_IO_REQ_T OidEntry; */ -+ -+WLAN_STATUS -+kalIoctl(IN P_GLUE_INFO_T prGlueInfo, -+ IN PFN_OID_HANDLER_FUNC pfnOidHandler, -+ IN PVOID pvInfoBuf, -+ IN UINT_32 u4InfoBufLen, -+ IN BOOLEAN fgRead, IN BOOLEAN fgWaitResp, IN BOOLEAN fgCmd, IN BOOLEAN fgIsP2pOid, OUT PUINT_32 pu4QryInfoLen) -+{ -+ P_GL_IO_REQ_T prIoReq = NULL; -+ WLAN_STATUS ret = WLAN_STATUS_SUCCESS; -+ -+ if (fgIsResetting == TRUE) -+ return WLAN_STATUS_SUCCESS; -+ -+ /* GLUE_SPIN_LOCK_DECLARATION(); */ -+ ASSERT(prGlueInfo); -+ -+ /* <1> Check if driver is halt */ -+ /* if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { */ -+ /* return WLAN_STATUS_ADAPTER_NOT_READY; */ -+ /* } */ -+ -+ /* if wait longer than double OID timeout timer, then will show backtrace who held halt lock. -+ at this case, we will return kalIoctl failure because tx_thread may be hung */ -+ if (kalHaltLock(2 * WLAN_OID_TIMEOUT_THRESHOLD)) -+ return WLAN_STATUS_FAILURE; -+ -+ if (kalIsHalted()) { -+ kalHaltUnlock(); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ if (down_interruptible(&prGlueInfo->ioctl_sem)) { -+ kalHaltUnlock(); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* <2> TODO: thread-safe */ -+ -+ /* <3> point to the OidEntry of Glue layer */ -+ -+ prIoReq = &(prGlueInfo->OidEntry); -+ -+ ASSERT(prIoReq); -+ -+ /* <4> Compose the I/O request */ -+ prIoReq->prAdapter = prGlueInfo->prAdapter; -+ prIoReq->pfnOidHandler = pfnOidHandler; -+ prIoReq->pvInfoBuf = pvInfoBuf; -+ prIoReq->u4InfoBufLen = u4InfoBufLen; -+ prIoReq->pu4QryInfoLen = pu4QryInfoLen; -+ prIoReq->fgRead = fgRead; -+ prIoReq->fgWaitResp = fgWaitResp; -+ prIoReq->rStatus = WLAN_STATUS_FAILURE; -+#if CFG_ENABLE_WIFI_DIRECT -+ prIoReq->fgIsP2pOid = fgIsP2pOid; -+#endif -+ -+ /* <5> Reset the status of pending OID */ -+ prGlueInfo->rPendStatus = WLAN_STATUS_FAILURE; -+ /* prGlueInfo->u4TimeoutFlag = 0; */ -+ /* prGlueInfo->u4OidCompleteFlag = 0; */ -+ -+ /* <6> Check if we use the command queue */ -+ prIoReq->u4Flag = fgCmd; -+ -+ /* <7> schedule the OID bit */ -+ set_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag); -+ -+ /* <8> Wake up tx thread to handle kick start the I/O request */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+ /* <9> Block and wait for event or timeout, current the timeout is 5 secs */ -+ /* if (wait_for_completion_interruptible_timeout(&prGlueInfo->rPendComp, 5 * KAL_HZ)) { */ -+ /* if (!wait_for_completion_interruptible(&prGlueInfo->rPendComp)) { */ -+ DBGLOG(OID, TEMP, "kalIoctl: before wait, caller: %p\n", __builtin_return_address(0)); -+ wait_for_completion(&prGlueInfo->rPendComp); { -+ /* Case 1: No timeout. */ -+ /* if return WLAN_STATUS_PENDING, the status of cmd is stored in prGlueInfo */ -+ if (prIoReq->rStatus == WLAN_STATUS_PENDING) -+ ret = prGlueInfo->rPendStatus; -+ else -+ ret = prIoReq->rStatus; -+ } -+#if 0 -+ else { -+ /* Case 2: timeout */ -+ /* clear pending OID's cmd in CMD queue */ -+ if (fgCmd) { -+ prGlueInfo->u4TimeoutFlag = 1; -+ wlanReleasePendingOid(prGlueInfo->prAdapter, 0); -+ } -+ ret = WLAN_STATUS_FAILURE; -+ } -+#endif -+ DBGLOG(OID, TEMP, "kalIoctl: done\n"); -+ up(&prGlueInfo->ioctl_sem); -+ kalHaltUnlock(); -+ -+ return ret; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to clear all pending security frames -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearSecurityFrames(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ /* Clear pending security frames in prGlueInfo->rCmdQueue */ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) { -+ prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); -+ } else { -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to clear pending security frames -+* belongs to dedicated network type -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* \param eNetworkTypeIdx Network Type Index -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearSecurityFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ /* Clear pending security frames in prGlueInfo->rCmdQueue */ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME && prCmdInfo->eNetworkType == eNetworkTypeIdx) { -+ prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); -+ } else { -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to clear all pending management frames -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearMgmtFrames(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ /* Clear pending management frames in prGlueInfo->rCmdQueue */ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { -+ wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); -+ } else { -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to clear all pending management frames -+* belongs to dedicated network type -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearMgmtFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ /* Clear pending management frames in prGlueInfo->rCmdQueue */ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME && -+ prCmdInfo->eNetworkType == eNetworkTypeIdx) { -+ wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); -+ } else { -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+} /* kalClearMgmtFramesByNetType */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is a kernel thread function for handling command packets -+* Tx requests and interrupt events -+* -+* @param data data pointer to private data of tx_thread -+* -+* @retval If the function succeeds, the return value is 0. -+* Otherwise, an error code is returned. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+int tx_thread(void *data) -+{ -+ struct net_device *dev = data; -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev)); -+ -+ P_QUE_ENTRY_T prQueueEntry = NULL; -+ P_GL_IO_REQ_T prIoReq = NULL; -+ P_QUE_T prTxQueue = NULL; -+ P_QUE_T prCmdQue = NULL; -+ -+ int ret = 0; -+ -+ BOOLEAN fgNeedHwAccess = FALSE; -+ -+ struct sk_buff *prSkb = NULL; -+ -+ /* for spin lock acquire and release */ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ prTxQueue = &prGlueInfo->rTxQueue; -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ current->flags |= PF_NOFREEZE; -+ -+ DBGLOG(INIT, INFO, "tx_thread starts running...\n"); -+ -+ while (TRUE) { -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /*run p2p multicast list work. */ -+ if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag)) -+ p2pSetMulticastListWorkQueueWrapper(prGlueInfo); -+#endif -+ -+ if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag)) { -+ P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL; -+ /* printk("prGlueInfo->u4OsMgmtFrameFilter = %x", prGlueInfo->u4OsMgmtFrameFilter); */ -+ prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo); -+ prAisFsmInfo->u4AisPacketFilter = prGlueInfo->u4OsMgmtFrameFilter; -+ } -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); -+ DBGLOG(INIT, INFO, "tx_thread should stop now...\n"); -+ break; -+ } -+ -+ /* -+ * sleep on waitqueue if no events occurred. Event contain (1) GLUE_FLAG_INT -+ * (2) GLUE_FLAG_OID (3) GLUE_FLAG_TXREQ (4) GLUE_FLAG_HALT -+ * -+ */ -+ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); -+ -+ ret = wait_event_interruptible(prGlueInfo->waitq, (prGlueInfo->ulFlag != 0)); -+ -+ KAL_WAKE_LOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); -+ -+/* #if (CONF_HIF_LOOPBACK_AUTO == 1) */ -+/* if (test_and_clear_bit(GLUE_FLAG_HIF_LOOPBK_AUTO_BIT, &prGlueInfo->u4Flag)) { */ -+/* kalDevLoopbkAuto(prGlueInfo); */ -+/* } */ -+/* #endif */ /* CONF_HIF_LOOPBACK_AUTO */ -+ -+#if CFG_DBG_GPIO_PINS -+ /* TX thread Wake up */ -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_LOW); -+#endif -+#if CFG_ENABLE_WIFI_DIRECT -+ /*run p2p multicast list work. */ -+ if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag)) -+ p2pSetMulticastListWorkQueueWrapper(prGlueInfo); -+ -+ if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_BIT, &prGlueInfo->ulFlag)) { -+ p2pFuncUpdateMgmtFrameRegister(prGlueInfo->prAdapter, -+ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter); -+ } -+#endif -+ if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag)) { -+ P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL; -+ /* printk("prGlueInfo->u4OsMgmtFrameFilter = %x", prGlueInfo->u4OsMgmtFrameFilter); */ -+ prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo); -+ prAisFsmInfo->u4AisPacketFilter = prGlueInfo->u4OsMgmtFrameFilter; -+ } -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); -+ DBGLOG(INIT, INFO, "<1>tx_thread should stop now...\n"); -+ break; -+ } -+ -+ fgNeedHwAccess = FALSE; -+ -+ /* Handle Interrupt */ -+ if (test_and_clear_bit(GLUE_FLAG_INT_BIT, &prGlueInfo->ulFlag)) { -+ if (fgNeedHwAccess == FALSE) { -+ fgNeedHwAccess = TRUE; -+ -+ wlanAcquirePowerControl(prGlueInfo->prAdapter); -+ } -+ -+ /* the Wi-Fi interrupt is already disabled in mmc thread, -+ so we set the flag only to enable the interrupt later */ -+ prGlueInfo->prAdapter->fgIsIntEnable = FALSE; -+ /* wlanISR(prGlueInfo->prAdapter, TRUE); */ -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ /* Should stop now... skip pending interrupt */ -+ DBGLOG(INIT, INFO, "ignore pending interrupt\n"); -+ } else { -+ prGlueInfo->TaskIsrCnt++; -+ wlanIST(prGlueInfo->prAdapter); -+ } -+ } -+ -+ /* transfer ioctl to OID request */ -+#if 0 -+ if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { -+ DBGLOG(INIT, INFO, "<2>tx_thread should stop now...\n"); -+ break; -+ } -+#endif -+ -+ do { -+ if (test_and_clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag)) { -+ /* get current prIoReq */ -+ prGlueInfo->u4OidCompleteFlag = 0; -+ -+ prIoReq = &(prGlueInfo->OidEntry); -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE && prIoReq->fgIsP2pOid == TRUE) { -+ /* if this Oid belongs to p2p and p2p module is removed -+ * do nothing, -+ */ -+ } else -+#endif -+ { -+ if (FALSE == prIoReq->fgRead) { -+ prIoReq->rStatus = wlanSetInformation(prIoReq->prAdapter, -+ prIoReq->pfnOidHandler, -+ prIoReq->pvInfoBuf, -+ prIoReq->u4InfoBufLen, -+ prIoReq->pu4QryInfoLen); -+ } else { -+ prIoReq->rStatus = wlanQueryInformation(prIoReq->prAdapter, -+ prIoReq->pfnOidHandler, -+ prIoReq->pvInfoBuf, -+ prIoReq->u4InfoBufLen, -+ prIoReq->pu4QryInfoLen); -+ } -+ -+ if (prIoReq->rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(OID, TEMP, "tx_thread, complete\n"); -+ complete(&prGlueInfo->rPendComp); -+ } else { -+ wlanoidTimeoutCheck(prGlueInfo->prAdapter, prIoReq->pfnOidHandler); -+ } -+ } -+ } -+ -+ } while (FALSE); -+ -+ /* -+ * -+ * if TX request, clear the TXREQ flag. TXREQ set by kalSetEvent/GlueSetEvent -+ * indicates the following requests occur -+ * -+ */ -+#if 0 -+ if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { -+ DBGLOG(INIT, INFO, "<3>tx_thread should stop now...\n"); -+ break; -+ } -+#endif -+ -+ if (test_and_clear_bit(GLUE_FLAG_TXREQ_BIT, &prGlueInfo->ulFlag)) { -+ /* Process Mailbox Messages */ -+ wlanProcessMboxMessage(prGlueInfo->prAdapter); -+ -+ /* Process CMD request */ -+ do { -+ if (prCmdQue->u4NumElem > 0) { -+ if (fgNeedHwAccess == FALSE) { -+ fgNeedHwAccess = TRUE; -+ -+ wlanAcquirePowerControl(prGlueInfo->prAdapter); -+ } -+ wlanProcessCommandQueue(prGlueInfo->prAdapter, prCmdQue); -+ } -+ } while (FALSE); -+ -+ /* Handle Packet Tx */ -+ { -+ while (QUEUE_IS_NOT_EMPTY(prTxQueue)) { -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_REMOVE_HEAD(prTxQueue, prQueueEntry, P_QUE_ENTRY_T); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ -+ ASSERT(prQueueEntry); -+ if (NULL == prQueueEntry) -+ break; -+ -+ prSkb = (struct sk_buff *)GLUE_GET_PKT_DESCRIPTOR(prQueueEntry); -+ ASSERT(prSkb); -+ if (NULL == prSkb) { -+ DBGLOG(INIT, ERROR, "prSkb == NULL!\n"); -+ continue; -+ } -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ UINT8 *pkt = prSkb->data; -+ UINT16 u2Identifier; -+ -+ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { -+ /* ip */ -+ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); -+ DBGLOG(INIT, LOUD, " %d\n", u2Identifier); -+ } -+#endif -+ if (wlanEnqueueTxPacket(prGlueInfo->prAdapter, -+ (P_NATIVE_PACKET) prSkb) == WLAN_STATUS_RESOURCES) { -+ /* no available entry in rFreeMsduInfoList */ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_INSERT_HEAD(prTxQueue, prQueueEntry); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ -+ break; -+ } -+ } -+ -+ if (wlanGetTxPendingFrameCount(prGlueInfo->prAdapter) > 0) { -+ /* send packets to HIF here */ -+ wlanTxPendingPackets(prGlueInfo->prAdapter, &fgNeedHwAccess); -+ } -+ } -+ -+ } -+ -+ /* Process RX, In linux, we don't need to free sk_buff by ourself */ -+ -+ /* In linux, we don't need to free sk_buff by ourself */ -+ -+ /* In linux, we don't do reset */ -+ if (fgNeedHwAccess == TRUE) -+ wlanReleasePowerControl(prGlueInfo->prAdapter); -+ -+ /* handle cnmTimer time out */ -+ if (test_and_clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag)) -+ wlanTimerTimeoutCheck(prGlueInfo->prAdapter); -+#if CFG_DBG_GPIO_PINS -+ /* TX thread go to sleep */ -+ if (!prGlueInfo->ulFlag) -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_HIGH); -+#endif -+ } -+ -+#if 0 -+ if (fgNeedHwAccess == TRUE) -+ wlanReleasePowerControl(prGlueInfo->prAdapter); -+#endif -+ -+ /* exit while loop, tx thread is closed so we flush all pending packets */ -+ /* flush the pending TX packets */ -+ if (prGlueInfo->i4TxPendingFrameNum > 0) -+ kalFlushPendingTxPackets(prGlueInfo); -+ -+ /* flush pending security frames */ -+ if (prGlueInfo->i4TxPendingSecurityFrameNum > 0) -+ kalClearSecurityFrames(prGlueInfo); -+ -+ /* remove pending oid */ -+ wlanReleasePendingOid(prGlueInfo->prAdapter, 0); -+ -+ /* In linux, we don't need to free sk_buff by ourself */ -+ -+ DBGLOG(INIT, INFO, "mtk_sdiod stops\n"); -+ complete(&prGlueInfo->rHaltComp); -+ -+ return 0; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to check if card is removed -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* -+* \retval TRUE: card is removed -+* FALSE: card is still attached -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsCardRemoved(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return FALSE; -+ /* Linux MMC doesn't have removal notification yet */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief This routine is used to send command to firmware for overriding netweork address -+ * -+ * \param pvGlueInfo Pointer of GLUE Data Structure -+ -+ * \retval TRUE -+ * FALSE -+ */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalRetrieveNetworkAddress(IN P_GLUE_INFO_T prGlueInfo, IN OUT PARAM_MAC_ADDRESS *prMacAddr) -+{ -+ ASSERT(prGlueInfo); -+ -+ if (prGlueInfo->fgIsMacAddrOverride == FALSE) { -+#if !defined(CONFIG_X86) -+#if !defined(CONFIG_MTK_TC1_FEATURE) -+ UINT_32 i; -+#endif -+ BOOLEAN fgIsReadError = FALSE; -+ -+#if !defined(CONFIG_MTK_TC1_FEATURE) -+ for (i = 0; i < MAC_ADDR_LEN; i += 2) { -+ if (kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i, -+ (PUINT_16) (((PUINT_8) prMacAddr) + i)) == FALSE) { -+ fgIsReadError = TRUE; -+ break; -+ } -+ } -+#else -+ TC1_FAC_NAME(FacReadWifiMacAddr) ((unsigned char *)prMacAddr); -+#endif -+ -+ if (fgIsReadError == TRUE) -+ return FALSE; -+ else -+ return TRUE; -+#else -+ /* x86 Linux doesn't need to override network address so far */ -+ return FALSE; -+#endif -+ } else { -+ COPY_MAC_ADDR(prMacAddr, prGlueInfo->rMacAddrOverride); -+ -+ return TRUE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to flush pending TX packets in glue layer -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalFlushPendingTxPackets(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_QUE_T prTxQue; -+ P_QUE_ENTRY_T prQueueEntry; -+ PVOID prPacket; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ prTxQue = &(prGlueInfo->rTxQueue); -+ -+ if (prGlueInfo->i4TxPendingFrameNum) { -+ while (TRUE) { -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_REMOVE_HEAD(prTxQue, prQueueEntry, P_QUE_ENTRY_T); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ -+ if (prQueueEntry == NULL) -+ break; -+ -+ prPacket = GLUE_GET_PKT_DESCRIPTOR(prQueueEntry); -+ -+ kalSendComplete(prGlueInfo, prPacket, WLAN_STATUS_NOT_ACCEPTED); -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is get indicated media state -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* -+* \retval -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_PARAM_MEDIA_STATE_T kalGetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->eParamMediaStateIndicated; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set indicated media state -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalSetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicate) -+{ -+ ASSERT(prGlueInfo); -+ -+ prGlueInfo->eParamMediaStateIndicated = eParamMediaStateIndicate; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to clear pending OID staying in command queue -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalOidCmdClearance(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ -+ if (((P_CMD_INFO_T) prQueueEntry)->fgIsOid) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ break; -+ } -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ -+ if (prCmdInfo) { -+ if (prCmdInfo->pfCmdTimeoutHandler) -+ prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo); -+ else -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_NOT_ACCEPTED); -+ -+ prGlueInfo->u4OidCompleteFlag = 1; -+ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to insert command into prCmdQueue -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* prQueueEntry Pointer of queue entry to be inserted -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalEnqueueCommand(IN P_GLUE_INFO_T prGlueInfo, IN P_QUE_ENTRY_T prQueueEntry) -+{ -+ P_QUE_T prCmdQue; -+ P_CMD_INFO_T prCmdInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prQueueEntry); -+ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ if (prCmdInfo->prPacket && prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { -+ prMsduInfo = (P_MSDU_INFO_T) (prCmdInfo->prPacket); -+ prMsduInfo->eCmdType = prCmdInfo->eCmdType; -+ prMsduInfo->ucCID = prCmdInfo->ucCID; -+ prMsduInfo->u4InqueTime = kalGetTimeTick(); -+ } -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Handle EVENT_ID_ASSOC_INFO event packet by indicating to OS with -+* proper information -+* -+* @param pvGlueInfo Pointer of GLUE Data Structure -+* @param prAssocInfo Pointer of EVENT_ID_ASSOC_INFO Packet -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalHandleAssocInfo(IN P_GLUE_INFO_T prGlueInfo, IN P_EVENT_ASSOC_INFO prAssocInfo) -+{ -+ /* to do */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to get firmware load address from registry -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetFwLoadAddress(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->rRegInfo.u4LoadAddress; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to get firmware start address from registry -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetFwStartAddress(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->rRegInfo.u4StartAddress; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * * @brief Notify OS with SendComplete event of the specific packet. Linux should -+ * * free packets here. -+ * * -+ * * @param pvGlueInfo Pointer of GLUE Data Structure -+ * * @param pvPacket Pointer of Packet Handle -+ * * @param status Status Code for OS upper layer -+ * * -+ * * @return none -+ * */ -+/*----------------------------------------------------------------------------*/ -+ -+/* / Todo */ -+VOID kalSecurityFrameSendComplete(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN WLAN_STATUS rStatus) -+{ -+ ASSERT(pvPacket); -+ -+ dev_kfree_skb((struct sk_buff *)pvPacket); -+ if (prGlueInfo) -+ prGlueInfo->u8SkbFreed++; -+ GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); -+} -+ -+UINT_32 kalGetTxPendingFrameCount(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return (UINT_32) (prGlueInfo->i4TxPendingFrameNum); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to retrieve the number of pending commands -+* (including MMPDU, 802.1X and command packets) -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetTxPendingCmdCount(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_QUE_T prCmdQue; -+ -+ ASSERT(prGlueInfo); -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ return prCmdQue->u4NumElem; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Timer Initialization Procedure -+* -+* \param[in] prGlueInfo Pointer to GLUE Data Structure -+* \param[in] prTimerHandler Pointer to timer handling function, whose only -+* argument is "prAdapter" -+* -+* \retval none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+/* static struct timer_list tickfn; */ -+ -+VOID kalOsTimerInitialize(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prTimerHandler) -+{ -+ -+ ASSERT(prGlueInfo); -+ -+ timer_setup(&(prGlueInfo->tickfn), prTimerHandler, 0); -+} -+ -+/* Todo */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the time to do the time out check. -+* -+* \param[in] prGlueInfo Pointer to GLUE Data Structure -+* \param[in] rInterval Time out interval from current time. -+* -+* \retval TRUE Success. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Interval) -+{ -+ ASSERT(prGlueInfo); -+ del_timer_sync(&(prGlueInfo->tickfn)); -+ -+ prGlueInfo->tickfn.expires = jiffies + u4Interval * HZ / MSEC_PER_SEC; -+ add_timer(&(prGlueInfo->tickfn)); -+ -+ return TRUE; /* success */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to cancel -+* -+* \param[in] prGlueInfo Pointer to GLUE Data Structure -+* -+* \retval TRUE : Timer has been canceled -+* FALAE : Timer doens't exist -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalCancelTimer(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag); -+ -+ if (del_timer_sync(&(prGlueInfo->tickfn)) >= 0) -+ return TRUE; -+ else -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is a callback function for scanning done -+* -+* \param[in] prGlueInfo Pointer to GLUE Data Structure -+* -+* \retval none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalScanDone(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN WLAN_STATUS status) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ ASSERT(prGlueInfo); -+ -+ prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo); -+ /* report all queued beacon/probe response frames to upper layer */ -+ scanReportBss2Cfg80211(prGlueInfo->prAdapter, BSS_TYPE_INFRASTRUCTURE, NULL); -+ cnmTimerStopTimer(prGlueInfo->prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ -+ /* check for system configuration for generating error message on scan list */ -+ wlanCheckSystemConfiguration(prGlueInfo->prAdapter); -+ -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to generate a random number -+* -+* \param none -+* -+* \retval UINT_32 -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalRandomNumber(VOID) -+{ -+ UINT_32 number = 0; -+ -+ get_random_bytes(&number, 4); -+ -+ return number; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief command timeout call-back function -+ * -+ * \param[in] prGlueInfo Pointer to the GLUE data structure. -+ * -+ * \retval (none) -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID kalTimeoutHandler(struct timer_list *t) -+{ -+ -+ P_GLUE_INFO_T prGlueInfo = from_timer(prGlueInfo, t, tickfn); -+ -+ ASSERT(prGlueInfo); -+ -+ /* Notify tx thread for timeout event */ -+ set_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag); -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+} -+ -+VOID kalSetEvent(P_GLUE_INFO_T pr) -+{ -+ set_bit(GLUE_FLAG_TXREQ_BIT, &pr->ulFlag); -+ wake_up_interruptible(&pr->waitq); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to check if configuration file (NVRAM/Registry) exists -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsConfigurationExist(IN P_GLUE_INFO_T prGlueInfo) -+{ -+#if !defined(CONFIG_X86) -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->fgNvramAvailable; -+#else -+ /* there is no configuration data for x86-linux */ -+ return FALSE; -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Registry information -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* Pointer of REG_INFO_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_REG_INFO_T kalGetConfiguration(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return &(prGlueInfo->rRegInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve version information of corresponding configuration file -+* -+* \param[in] -+* prGlueInfo -+* -+* \param[out] -+* pu2Part1CfgOwnVersion -+* pu2Part1CfgPeerVersion -+* pu2Part2CfgOwnVersion -+* pu2Part2CfgPeerVersion -+* -+* \return -+* NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalGetConfigurationVersion(IN P_GLUE_INFO_T prGlueInfo, -+ OUT PUINT_16 pu2Part1CfgOwnVersion, -+ OUT PUINT_16 pu2Part1CfgPeerVersion, -+ OUT PUINT_16 pu2Part2CfgOwnVersion, OUT PUINT_16 pu2Part2CfgPeerVersion) -+{ -+ ASSERT(prGlueInfo); -+ -+ ASSERT(pu2Part1CfgOwnVersion); -+ ASSERT(pu2Part1CfgPeerVersion); -+ ASSERT(pu2Part2CfgOwnVersion); -+ ASSERT(pu2Part2CfgPeerVersion); -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1OwnVersion), pu2Part1CfgOwnVersion); -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1PeerVersion), pu2Part1CfgPeerVersion); -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2OwnVersion), pu2Part2CfgOwnVersion); -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2PeerVersion), pu2Part2CfgPeerVersion); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to check if the WPS is active or not -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalWSCGetActiveState(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->fgWpsActive; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief update RSSI and LinkQuality to GLUE layer -+* -+* \param[in] -+* prGlueInfo -+* eNetTypeIdx -+* cRssi -+* cLinkQuality -+* -+* \return -+* None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalUpdateRSSI(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality) -+{ -+ struct iw_statistics *pStats = (struct iw_statistics *)NULL; -+ -+ ASSERT(prGlueInfo); -+ -+ switch (eNetTypeIdx) { -+ case KAL_NETWORK_TYPE_AIS_INDEX: -+ pStats = (struct iw_statistics *)(&(prGlueInfo->rIwStats)); -+ break; -+#if CFG_ENABLE_WIFI_DIRECT -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ case KAL_NETWORK_TYPE_P2P_INDEX: -+ pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats)); -+ break; -+#endif -+#endif -+ default: -+ break; -+ -+ } -+ -+ if (pStats) { -+ pStats->qual.qual = cLinkQuality; -+ pStats->qual.noise = 0; -+ pStats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM; -+ pStats->qual.level = 0x100 + cRssi; -+ pStats->qual.updated |= IW_QUAL_LEVEL_UPDATED; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Pre-allocate I/O buffer -+* -+* \param[in] -+* none -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalInitIOBuffer(VOID) -+{ -+ UINT_32 u4Size; -+ -+ if (CFG_COALESCING_BUFFER_SIZE >= CFG_RX_COALESCING_BUFFER_SIZE) -+ u4Size = CFG_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T); -+ else -+ u4Size = CFG_RX_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T); -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ pvDmaBuffer = dma_alloc_coherent(NULL, CFG_RX_MAX_PKT_SIZE, &pvDmaPhyBuf, GFP_KERNEL); -+ if (pvDmaBuffer == NULL) -+ return FALSE; -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+ pvIoBuffer = kmalloc(u4Size, GFP_KERNEL); -+/* pvIoBuffer = dma_alloc_coherent(NULL, u4Size, &pvIoPhyBuf, GFP_KERNEL); */ -+ if (pvIoBuffer) { -+ pvIoBufferSize = u4Size; -+ pvIoBufferUsage = 0; -+ -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Free pre-allocated I/O buffer -+* -+* \param[in] -+* none -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalUninitIOBuffer(VOID) -+{ -+ kfree(pvIoBuffer); -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ dma_free_coherent(NULL, CFG_RX_MAX_PKT_SIZE, pvDmaBuffer, pvDmaPhyBuf); -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ /* dma_free_coherent(NULL, pvIoBufferSize, pvIoBuffer, pvIoPhyBuf); */ -+ -+ pvIoBuffer = (PVOID) NULL; -+ pvIoBufferSize = 0; -+ pvIoBufferUsage = 0; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dispatch pre-allocated I/O buffer -+* -+* \param[in] -+* u4AllocSize -+* -+* \return -+* PVOID for pointer of pre-allocated I/O buffer -+*/ -+/*----------------------------------------------------------------------------*/ -+PVOID kalAllocateIOBuffer(IN UINT_32 u4AllocSize) -+{ -+ PVOID ret = (PVOID) NULL; -+ -+ if (pvIoBuffer) { -+ if (u4AllocSize <= (pvIoBufferSize - pvIoBufferUsage)) { -+ ret = (PVOID) &(((PUINT_8) (pvIoBuffer))[pvIoBufferUsage]); -+ pvIoBufferUsage += u4AllocSize; -+ } -+ } else { -+ /* fault tolerance */ -+ ret = (PVOID) kalMemAlloc(u4AllocSize, PHY_MEM_TYPE); -+ } -+ -+ return ret; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Release all dispatched I/O buffer -+* -+* \param[in] -+* none -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalReleaseIOBuffer(IN PVOID pvAddr, IN UINT_32 u4Size) -+{ -+ if (pvIoBuffer) { -+ pvIoBufferUsage -= u4Size; -+ } else { -+ /* fault tolerance */ -+ kalMemFree(pvAddr, PHY_MEM_TYPE, u4Size); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalGetChannelList(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_BAND_T eSpecificBand, -+ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList) -+{ -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, eSpecificBand, FALSE, ucMaxChannelNum, -+ pucNumOfChannel, paucChannelList); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsAPmode(IN P_GLUE_INFO_T prGlueInfo) -+{ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (IS_NET_ACTIVE(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX) && -+ p2pFuncIsAPMode(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo)) -+ return TRUE; -+#endif -+ -+ return FALSE; -+} -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function gets the physical address for Pre-allocate I/O buffer. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] rLockCategory Specify which SPIN_LOCK -+* \param[out] pu4Flags Pointer of a variable for saving IRQ flags -+* -+* \return physical addr -+*/ -+/*----------------------------------------------------------------------------*/ -+ULONG kalIOPhyAddrGet(IN ULONG VirtAddr) -+{ -+ ULONG PhyAddr; -+ -+ if ((VirtAddr >= (ULONG) pvIoBuffer) && (VirtAddr <= ((ULONG) (pvIoBuffer) + pvIoBufferSize))) { -+ PhyAddr = (ULONG) pvIoPhyBuf; -+ PhyAddr += (VirtAddr - (ULONG) (pvIoBuffer)); -+ return PhyAddr; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function gets the physical address for Pre-allocate I/O buffer. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] rLockCategory Specify which SPIN_LOCK -+* \param[out] pu4Flags Pointer of a variable for saving IRQ flags -+* -+* \return physical addr -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalDmaBufGet(OUT VOID **VirtAddr, OUT VOID **PhyAddr) -+{ -+ *VirtAddr = pvDmaBuffer; -+ *PhyAddr = pvDmaPhyBuf; -+} -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+#if CFG_SUPPORT_802_11W -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to check if the MFP is active or not -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetMfpSetting(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->rWpaInfo.u4Mfp; -+} -+#endif -+ -+struct file *kalFileOpen(const char *path, int flags, int rights) -+{ -+ struct file *filp = NULL; -+ mm_segment_t oldfs; -+ int err = 0; -+ -+ oldfs = get_fs(); -+ set_fs(get_ds()); -+ filp = filp_open(path, flags, rights); -+ set_fs(oldfs); -+ if (IS_ERR(filp)) { -+ err = PTR_ERR(filp); -+ return NULL; -+ } -+ return filp; -+} -+ -+VOID kalFileClose(struct file *file) -+{ -+ filp_close(file, NULL); -+} -+ -+UINT_32 kalFileRead(struct file *file, UINT_64 offset, UINT_8 *data, UINT_32 size) -+{ -+ mm_segment_t oldfs; -+ INT_32 ret; -+ -+ oldfs = get_fs(); -+ set_fs(get_ds()); -+ -+ ret = vfs_read(file, data, size, &offset); -+ -+ set_fs(oldfs); -+ return ret; -+} -+ -+UINT_32 kalFileWrite(struct file *file, UINT_64 offset, UINT_8 *data, UINT_32 size) -+{ -+ mm_segment_t oldfs; -+ INT_32 ret; -+ -+ oldfs = get_fs(); -+ set_fs(get_ds()); -+ -+ ret = vfs_write(file, data, size, &offset); -+ -+ set_fs(oldfs); -+ return ret; -+} -+ -+UINT_32 kalWriteToFile(const PUINT_8 pucPath, BOOLEAN fgDoAppend, PUINT_8 pucData, UINT_32 u4Size) -+{ -+ struct file *file = NULL; -+ UINT_32 ret = -1; -+ UINT_32 u4Flags = 0; -+ -+ if (fgDoAppend) -+ u4Flags = O_APPEND; -+ -+ file = kalFileOpen(pucPath, O_WRONLY | O_CREAT | u4Flags, S_IRWXU); -+ if (file) { -+ ret = kalFileWrite(file, 0, pucData, u4Size); -+ kalFileClose(file); -+ } -+ -+ return ret; -+} -+ -+INT_32 kalReadToFile(const PUINT_8 pucPath, PUINT_8 pucData, UINT_32 u4Size, PUINT_32 pu4ReadSize) -+{ -+ struct file *file = NULL; -+ INT_32 ret = -1; -+ UINT_32 u4ReadSize = 0; -+ -+ DBGLOG(INIT, LOUD, "kalReadToFile() path %s\n", pucPath); -+ -+ file = kalFileOpen(pucPath, O_RDONLY, 0); -+ -+ if ((file != NULL) && !IS_ERR(file)) { -+ u4ReadSize = kalFileRead(file, 0, pucData, u4Size); -+ kalFileClose(file); -+ if (pu4ReadSize) -+ *pu4ReadSize = u4ReadSize; -+ ret = 0; -+ } -+ return ret; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate BSS-INFO to NL80211 as scanning result -+* -+* \param[in] -+* prGlueInfo -+* pucBeaconProbeResp -+* u4FrameLen -+* -+* -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucBeaconProbeResp, -+ IN UINT_32 u4FrameLen, IN UINT_8 ucChannelNum, IN INT_32 i4SignalStrength) -+{ -+ struct wiphy *wiphy; -+ struct ieee80211_channel *prChannel = NULL; -+ -+ ASSERT(prGlueInfo); -+ wiphy = priv_to_wiphy(prGlueInfo); -+ -+ /* search through channel entries */ -+ if (ucChannelNum <= 14) { -+ prChannel = -+ ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ)); -+ } else { -+ prChannel = -+ ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ)); -+ } -+ -+ if (prChannel != NULL && (prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL)) { -+ struct cfg80211_bss *bss; -+#if CFG_SUPPORT_TSF_USING_BOOTTIME -+ struct ieee80211_mgmt *prMgmtFrame = (struct ieee80211_mgmt *)pucBeaconProbeResp; -+ -+ prMgmtFrame->u.beacon.timestamp = kalGetBootTime(); -+#endif -+ ScanCnt++; -+ -+ /* indicate to NL80211 subsystem */ -+ bss = cfg80211_inform_bss_frame(wiphy, -+ prChannel, -+ (struct ieee80211_mgmt *)pucBeaconProbeResp, -+ u4FrameLen, i4SignalStrength * 100, GFP_KERNEL); -+ -+ if (!bss) { -+ ScanDoneFailCnt++; -+ DBGLOG(SCN, WARN, "inform bss to cfg80211 failed, bss channel %d, rcpi %d\n", -+ ucChannelNum, i4SignalStrength); -+ } else { -+ cfg80211_put_bss(wiphy, bss); -+ DBGLOG(SCN, TRACE, "inform bss to cfg80211, bss channel %d, rcpi %d\n", -+ ucChannelNum, i4SignalStrength); -+ } -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate channel ready -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalReadyOnChannel(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, -+ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum, IN UINT_32 u4DurationMs) -+{ -+ struct ieee80211_channel *prChannel = NULL; -+ enum nl80211_channel_type rChannelType; -+ -+ /* ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); */ -+ -+ if (prGlueInfo->fgIsRegistered == TRUE) { -+ if (ucChannelNum <= 14) { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ)); -+ } else { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ)); -+ } -+ -+ switch (eSco) { -+ case CHNL_EXT_SCN: -+ rChannelType = NL80211_CHAN_NO_HT; -+ break; -+ -+ case CHNL_EXT_SCA: -+ rChannelType = NL80211_CHAN_HT40MINUS; -+ break; -+ -+ case CHNL_EXT_SCB: -+ rChannelType = NL80211_CHAN_HT40PLUS; -+ break; -+ -+ case CHNL_EXT_RES: -+ default: -+ rChannelType = NL80211_CHAN_HT20; -+ break; -+ } -+ -+ cfg80211_ready_on_channel(prGlueInfo->prDevHandler->ieee80211_ptr, u8Cookie, prChannel, u4DurationMs, -+ GFP_KERNEL); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate channel expiration -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalRemainOnChannelExpired(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum) -+{ -+ struct ieee80211_channel *prChannel = NULL; -+ enum nl80211_channel_type rChannelType; -+ -+ ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ if (prGlueInfo->fgIsRegistered == TRUE) { -+ if (ucChannelNum <= 14) { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ)); -+ } else { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ)); -+ } -+ -+ switch (eSco) { -+ case CHNL_EXT_SCN: -+ rChannelType = NL80211_CHAN_NO_HT; -+ break; -+ -+ case CHNL_EXT_SCA: -+ rChannelType = NL80211_CHAN_HT40MINUS; -+ break; -+ -+ case CHNL_EXT_SCB: -+ rChannelType = NL80211_CHAN_HT40PLUS; -+ break; -+ -+ case CHNL_EXT_RES: -+ default: -+ rChannelType = NL80211_CHAN_HT20; -+ break; -+ } -+ -+ cfg80211_remain_on_channel_expired(prGlueInfo->prDevHandler->ieee80211_ptr, u8Cookie, prChannel, -+ GFP_KERNEL); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate Mgmt tx status -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen) -+{ -+ -+ do { -+ if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (u4FrameLen == 0)) { -+ DBGLOG(AIS, TRACE, "Unexpected pointer PARAM. %p, %p, %u.", -+ prGlueInfo, pucFrameBuf, u4FrameLen); -+ ASSERT(FALSE); -+ break; -+ } -+ -+ cfg80211_mgmt_tx_status(prGlueInfo->prDevHandler->ieee80211_ptr, -+ u8Cookie, pucFrameBuf, u4FrameLen, fgIsAck, GFP_KERNEL); -+ } while (FALSE); -+ -+} /* kalIndicateMgmtTxStatus */ -+ -+VOID kalIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb) -+{ -+#define DBG_MGMT_FRAME_INDICATION 1 -+ INT_32 i4Freq = 0; -+ UINT_8 ucChnlNum = 0; -+#if DBG_MGMT_FRAME_INDICATION -+ P_WLAN_MAC_HEADER_T prWlanHeader = (P_WLAN_MAC_HEADER_T) NULL; -+#endif -+ -+ do { -+ if ((prGlueInfo == NULL) || (prSwRfb == NULL)) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ ucChnlNum = prSwRfb->prHifRxHdr->ucHwChannelNum; -+ -+#if DBG_MGMT_FRAME_INDICATION -+ prWlanHeader = (P_WLAN_MAC_HEADER_T) prSwRfb->pvHeader; -+ -+ switch (prWlanHeader->u2FrameCtrl) { -+ case MAC_FRAME_PROBE_REQ: -+ DBGLOG(AIS, TRACE, "RX Probe Req at channel %d ", ucChnlNum); -+ break; -+ case MAC_FRAME_PROBE_RSP: -+ DBGLOG(AIS, TRACE, "RX Probe Rsp at channel %d ", ucChnlNum); -+ break; -+ case MAC_FRAME_ACTION: -+ DBGLOG(AIS, TRACE, "RX Action frame at channel %d ", ucChnlNum); -+ break; -+ default: -+ DBGLOG(AIS, TRACE, "RX Packet:%d at channel %d ", prWlanHeader->u2FrameCtrl, ucChnlNum); -+ break; -+ } -+ -+#endif -+ i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000; -+ -+ cfg80211_rx_mgmt(prGlueInfo->prDevHandler->ieee80211_ptr, /* struct net_device * dev, */ -+ i4Freq, -+ RCPI_TO_dBm(prSwRfb->prHifRxHdr->ucRcpi), -+ prSwRfb->pvHeader, prSwRfb->u2PacketLen, GFP_KERNEL); -+ } while (FALSE); -+ -+} /* kalIndicateRxMgmtFrame */ -+ -+#if CFG_SUPPORT_AGPS_ASSIST -+BOOLEAN kalIndicateAgpsNotify(P_ADAPTER_T prAdapter, UINT_8 cmd, PUINT_8 data, UINT_16 dataLen) -+{ -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ struct sk_buff *skb = cfg80211_testmode_alloc_event_skb(priv_to_wiphy(prGlueInfo), -+ dataLen, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(AIS, ERROR, "kalIndicateAgpsNotify: alloc skb failed\n"); -+ return FALSE; -+ } -+ -+ /* DBGLOG(CCX, INFO, ("WLAN_STATUS_AGPS_NOTIFY, cmd=%d\n", cmd)); */ -+ if (unlikely(nla_put(skb, MTK_ATTR_AGPS_CMD, sizeof(cmd), &cmd) < 0)) -+ goto nla_put_failure; -+ if (dataLen > 0 && data && unlikely(nla_put(skb, MTK_ATTR_AGPS_DATA, dataLen, data) < 0)) -+ goto nla_put_failure; -+ if (unlikely(nla_put(skb, MTK_ATTR_AGPS_IFINDEX, sizeof(UINT_32), &prGlueInfo->prDevHandler->ifindex) < 0)) -+ goto nla_put_failure; -+ /* currently, the ifname maybe wlan0, p2p0, so the maximum name length will be 5 bytes */ -+ if (unlikely(nla_put(skb, MTK_ATTR_AGPS_IFNAME, 5, prGlueInfo->prDevHandler->name) < 0)) -+ goto nla_put_failure; -+ cfg80211_testmode_event(skb, GFP_KERNEL); -+ return TRUE; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return FALSE; -+} -+#endif -+ -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+#define PROC_MET_PROF_CTRL "met_ctrl" -+#define PROC_MET_PROF_PORT "met_port" -+ -+struct proc_dir_entry *pMetProcDir; -+void *pMetGlobalData = NULL; -+static unsigned long __read_mostly tracing_mark_write_addr; -+ -+static inline void __mt_update_tracing_mark_write_addr(void) -+{ -+ if (unlikely(0 == tracing_mark_write_addr)) -+ tracing_mark_write_addr = kallsyms_lookup_name("tracing_mark_write"); -+} -+ -+VOID kalMetProfilingStart(IN P_GLUE_INFO_T prGlueInfo, IN struct sk_buff *prSkb) -+{ -+ UINT_8 ucIpVersion; -+ UINT_16 u2UdpSrcPort; -+ UINT_16 u2RtpSn; -+ PUINT_8 pucEthHdr = prSkb->data; -+ PUINT_8 pucIpHdr, pucUdpHdr, pucRtpHdr; -+ -+ /* | Ethernet(14) | IP(20) | UDP(8)| RTP(12) | */ -+ /* UDP==> |SRC_PORT(2)|DST_PORT(2)|LEN(2)|CHKSUM(2)| */ -+ /* RTP==> |CTRL(2)|SEQ(2)|TimeStamp(4)|... */ -+ /* printk("MET_PROF: MET enable=%d(HardXmit)\n", prGlueInfo->u8MetProfEnable); */ -+ if (prGlueInfo->u8MetProfEnable == 1) { -+ u2UdpSrcPort = prGlueInfo->u16MetUdpPort; -+ if ((*(pucEthHdr + 12) == 0x08) && (*(pucEthHdr + 13) == 0x00)) { -+ /* IP */ -+ pucIpHdr = pucEthHdr + ETH_HLEN; -+ ucIpVersion = (*pucIpHdr & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; -+ if ((ucIpVersion == IPVERSION) && (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP)) { -+ /* UDP */ -+ pucUdpHdr = pucIpHdr + IP_HEADER_LEN; -+ /* check UDP port number */ -+ if (((UINT_16) pucUdpHdr[0] << 8 | (UINT_16) pucUdpHdr[1]) == u2UdpSrcPort) { -+ /* RTP */ -+ pucRtpHdr = pucUdpHdr + 8; -+ u2RtpSn = (UINT_16) pucRtpHdr[2] << 8 | pucRtpHdr[3]; -+ /* trace_printk("S|%d|%s|%d\n", current->tgid, "WIFI-CHIP", u2RtpSn); -+ //frm_sequence); */ -+#ifdef CONFIG_TRACING -+ __mt_update_tracing_mark_write_addr(); -+ if (tracing_mark_write_addr != 0) { -+ event_trace_printk(tracing_mark_write_addr, "S|%d|%s|%d\n", -+ current->tgid, "WIFI-CHIP", u2RtpSn); -+ } -+#endif -+ } -+ } -+ } -+ } -+} -+ -+VOID kalMetProfilingFinish(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ UINT_8 ucIpVersion; -+ UINT_16 u2UdpSrcPort; -+ UINT_16 u2RtpSn; -+ struct sk_buff *prSkb = (struct sk_buff *)prMsduInfo->prPacket; -+ PUINT_8 pucEthHdr = prSkb->data; -+ PUINT_8 pucIpHdr, pucUdpHdr, pucRtpHdr; -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* | Ethernet(14) | IP(20) | UDP(8)| RTP(12) | */ -+ /* UDP==> |SRC_PORT(2)|DST_PORT(2)|LEN(2)|CHKSUM(2)| */ -+ /* RTP==> |CTRL(2)|SEQ(2)|TimeStamp(4)|... */ -+ /* printk("MET_PROF: MET enable=%d(TxMsdu)\n", prGlueInfo->u8MetProfEnable); */ -+ if (prGlueInfo->u8MetProfEnable == 1) { -+ u2UdpSrcPort = prGlueInfo->u16MetUdpPort; -+ if ((*(pucEthHdr + 12) == 0x08) && (*(pucEthHdr + 13) == 0x00)) { -+ /* IP */ -+ pucIpHdr = pucEthHdr + ETH_HLEN; -+ ucIpVersion = (*pucIpHdr & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; -+ if ((ucIpVersion == IPVERSION) && (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP)) { -+ /* UDP */ -+ pucUdpHdr = pucIpHdr + IP_HEADER_LEN; -+ /* check UDP port number */ -+ if (((UINT_16) pucUdpHdr[0] << 8 | (UINT_16) pucUdpHdr[1]) == u2UdpSrcPort) { -+ /* RTP */ -+ pucRtpHdr = pucUdpHdr + 8; -+ u2RtpSn = (UINT_16) pucRtpHdr[2] << 8 | pucRtpHdr[3]; -+ /* trace_printk("F|%d|%s|%d\n", current->tgid, "WIFI-CHIP", u2RtpSn); -+ //frm_sequence); */ -+#ifdef CONFIG_TRACING -+ __mt_update_tracing_mark_write_addr(); -+ if (tracing_mark_write_addr != 0) { -+ event_trace_printk(tracing_mark_write_addr, "F|%d|%s|%d\n", -+ current->tgid, "WIFI-CHIP", u2RtpSn); -+ } -+#endif -+ } -+ } -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for adjusting Debug Level to turn on/off debugging message. -+* -+* \param[in] file pointer to file. -+* \param[in] buffer Buffer from user space. -+* \param[in] count Number of characters to write -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters write from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static ssize_t kalMetCtrlWriteProcfs(struct file *file, const char __user *buffer, size_t count, loff_t *off) -+{ -+ char acBuf[128 + 1]; /* + 1 for "\0" */ -+ UINT_32 u4CopySize; -+ int u8MetProfEnable; -+ -+ IN P_GLUE_INFO_T prGlueInfo; -+ -+ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); -+ if (copy_from_user(acBuf, buffer, u4CopySize)) -+ return -1; -+ acBuf[u4CopySize] = '\0'; -+ -+ if (sscanf(acBuf, " %d", &u8MetProfEnable) == 1) -+ DBGLOG(INIT, INFO, "MET_PROF: Write MET PROC Enable=%d\n", u8MetProfEnable); -+ if (pMetGlobalData != NULL) { -+ prGlueInfo = (P_GLUE_INFO_T) pMetGlobalData; -+ prGlueInfo->u8MetProfEnable = (UINT_8) u8MetProfEnable; -+ } -+ return count; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for adjusting Debug Level to turn on/off debugging message. -+* -+* \param[in] file pointer to file. -+* \param[in] buffer Buffer from user space. -+* \param[in] count Number of characters to write -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters write from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static ssize_t kalMetPortWriteProcfs(struct file *file, const char __user *buffer, size_t count, loff_t *off) -+{ -+ char acBuf[128 + 1]; /* + 1 for "\0" */ -+ UINT_32 u4CopySize; -+ int u16MetUdpPort; -+ -+ IN P_GLUE_INFO_T prGlueInfo; -+ -+ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); -+ if (copy_from_user(acBuf, buffer, u4CopySize)) -+ return -1; -+ acBuf[u4CopySize] = '\0'; -+ -+ if (sscanf(acBuf, " %d", &u16MetUdpPort) == 1) -+ DBGLOG(INIT, INFO, "MET_PROF: Write MET PROC UDP_PORT=%d\n", u16MetUdpPort); -+ if (pMetGlobalData != NULL) { -+ prGlueInfo = (P_GLUE_INFO_T) pMetGlobalData; -+ prGlueInfo->u16MetUdpPort = (UINT_16) u16MetUdpPort; -+ } -+ return count; -+} -+ -+const struct file_operations rMetProcCtrlFops = { -+.write = kalMetCtrlWriteProcfs -+}; -+ -+const struct file_operations rMetProcPortFops = { -+.write = kalMetPortWriteProcfs -+}; -+ -+int kalMetInitProcfs(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ /* struct proc_dir_entry *pMetProcDir; */ -+ if (init_net.proc_net == (struct proc_dir_entry *)NULL) { -+ DBGLOG(INIT, INFO, "init proc fs fail: proc_net == NULL\n"); -+ return -ENOENT; -+ } -+ /* -+ * Directory: Root (/proc/net/wlan0) -+ */ -+ pMetProcDir = proc_mkdir("wlan0", init_net.proc_net); -+ if (pMetProcDir == NULL) -+ return -ENOENT; -+ /* -+ /proc/net/wlan0 -+ |-- met_ctrl (PROC_MET_PROF_CTRL) -+ |-- met_port (PROC_MET_PROF_PORT) -+ */ -+ /* proc_create(PROC_MET_PROF_CTRL, 0x0644, pMetProcDir, &rMetProcFops); */ -+ proc_create(PROC_MET_PROF_CTRL, 0, pMetProcDir, &rMetProcCtrlFops); -+ proc_create(PROC_MET_PROF_PORT, 0, pMetProcDir, &rMetProcPortFops); -+ -+ pMetGlobalData = (void *)prGlueInfo; -+ -+ return 0; -+} -+ -+int kalMetRemoveProcfs(void) -+{ -+ -+ if (init_net.proc_net == (struct proc_dir_entry *)NULL) { -+ DBGLOG(INIT, WARN, "remove proc fs fail: proc_net == NULL\n"); -+ return -ENOENT; -+ } -+ remove_proc_entry(PROC_MET_PROF_CTRL, pMetProcDir); -+ remove_proc_entry(PROC_MET_PROF_PORT, pMetProcDir); -+ /* remove root directory (proc/net/wlan0) */ -+ remove_proc_entry("wlan0", init_net.proc_net); -+ /* clear MetGlobalData */ -+ pMetGlobalData = NULL; -+ -+ return 0; -+} -+#endif -+UINT_64 kalGetBootTime(void) -+{ -+ struct timespec ts; -+ UINT_64 bootTime = 0; -+ -+ get_monotonic_boottime(&ts); -+ /* we assign ts.tv_sec to bootTime first, then multiply USEC_PER_SEC -+ this will prevent multiply result turn to a negative value on 32bit system */ -+ bootTime = ts.tv_sec; -+ bootTime *= USEC_PER_SEC; -+ bootTime += ts.tv_nsec / NSEC_PER_USEC; -+ return bootTime; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate scheduled scan results are avilable -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalSchedScanResults(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ cfg80211_sched_scan_results(priv_to_wiphy(prGlueInfo),0); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate scheduled scan has been stopped -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalSchedScanStopped(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ /* 1. reset first for newly incoming request */ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueInfo->prSchedScanRequest != NULL) -+ prGlueInfo->prSchedScanRequest = NULL; -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ DBGLOG(SCN, INFO, "cfg80211_sched_scan_stopped send event\n"); -+ -+ /* 2. indication to cfg80211 */ -+ /* 20150205 change cfg80211_sched_scan_stopped to work queue to use K thread to send event instead of Tx thread -+ due to sched_scan_mtx dead lock issue by Tx thread serves oid cmds and send event in the same time */ -+ DBGLOG(SCN, TRACE, "start work queue to send event\n"); -+ schedule_delayed_work(&sched_workq, 0); -+ DBGLOG(SCN, TRACE, "tx_thread return from kalSchedScanStoppped\n"); -+ -+} -+ -+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG -+/* if SPM is not implement this function, we will use this default one */ -+wake_reason_t __weak slp_get_wake_reason(VOID) -+{ -+ return WR_NONE; -+} -+/* if SPM is not implement this function, we will use this default one */ -+UINT_32 __weak spm_get_last_wakeup_src(VOID) -+{ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To check if device if wake up by wlan -+* -+* \param[in] -+* prAdapter -+* -+* \return -+* TRUE: wake up by wlan; otherwise, FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsWakeupByWlan(P_ADAPTER_T prAdapter) -+{ -+ /* SUSPEND_FLAG_FOR_WAKEUP_REASON is set means system has suspended, but may be failed -+ duo to some driver suspend failed. so we need help of function slp_get_wake_reason */ -+ if (test_and_clear_bit(SUSPEND_FLAG_FOR_WAKEUP_REASON, &prAdapter->ulSuspendFlag) == 0) -+ return FALSE; -+ /* if slp_get_wake_reason or spm_get_last_wakeup_src is NULL, it means SPM module didn't implement -+ it. then we should return FALSE always. otherwise, if slp_get_wake_reason returns WR_WAKE_SRC, -+ then it means the host is suspend successfully. */ -+ if (slp_get_wake_reason() != WR_WAKE_SRC) -+ return FALSE; -+ /* spm_get_last_wakeup_src will returns the last wakeup source, -+ WAKE_SRC_CONN2AP is connsys */ -+ return !!(spm_get_last_wakeup_src() & WAKE_SRC_CONN2AP); -+} -+#endif -+ -+INT_32 kalHaltLock(UINT_32 waitMs) -+{ -+ INT_32 i4Ret = 0; -+ -+ if (waitMs) { -+ i4Ret = down_timeout(&rHaltCtrl.lock, MSEC_TO_JIFFIES(waitMs)); -+ if (!i4Ret) -+ goto success; -+ if (i4Ret != -ETIME) -+ return i4Ret; -+ if (rHaltCtrl.fgHeldByKalIoctl) { -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ wlanExportGlueInfo(&prGlueInfo); -+ -+ DBGLOG(INIT, ERROR, -+ "kalIoctl was executed longer than %u ms, show backtrace of tx_thread!\n", -+ kalGetTimeTick() - rHaltCtrl.u4HoldStart); -+ if (prGlueInfo) -+ show_stack(prGlueInfo->main_thread, NULL); -+ } else { -+ DBGLOG(INIT, ERROR, "halt lock held by %s pid %d longer than %u ms!\n", -+ rHaltCtrl.owner->comm, rHaltCtrl.owner->pid, -+ kalGetTimeTick() - rHaltCtrl.u4HoldStart); -+ show_stack(rHaltCtrl.owner, NULL); -+ } -+ return i4Ret; -+ } -+ down(&rHaltCtrl.lock); -+success: -+ rHaltCtrl.owner = current; -+ rHaltCtrl.u4HoldStart = kalGetTimeTick(); -+ return 0; -+} -+ -+INT_32 kalHaltTryLock(VOID) -+{ -+ INT_32 i4Ret = 0; -+ -+ i4Ret = down_trylock(&rHaltCtrl.lock); -+ if (i4Ret) -+ return i4Ret; -+ rHaltCtrl.owner = current; -+ rHaltCtrl.u4HoldStart = kalGetTimeTick(); -+ return 0; -+} -+ -+VOID kalHaltUnlock(VOID) -+{ -+ if (kalGetTimeTick() - rHaltCtrl.u4HoldStart > WLAN_OID_TIMEOUT_THRESHOLD * 2 && -+ rHaltCtrl.owner) -+ DBGLOG(INIT, ERROR, "process %s pid %d hold halt lock longer than 4s!\n", -+ rHaltCtrl.owner->comm, rHaltCtrl.owner->pid); -+ rHaltCtrl.owner = NULL; -+ up(&rHaltCtrl.lock); -+} -+ -+VOID kalSetHalted(BOOLEAN fgHalt) -+{ -+ rHaltCtrl.fgHalt = fgHalt; -+} -+ -+BOOLEAN kalIsHalted(VOID) -+{ -+ return rHaltCtrl.fgHalt; -+} -+VOID kalPerMonDump(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ DBGLOG(SW4, WARN, "ulPerfMonFlag:0x%lx\n", prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, WARN, "ulLastTxBytes:%ld\n", prPerMonitor->ulLastTxBytes); -+ DBGLOG(SW4, WARN, "ulLastRxBytes:%ld\n", prPerMonitor->ulLastRxBytes); -+ DBGLOG(SW4, WARN, "ulP2PLastTxBytes:%ld\n", prPerMonitor->ulP2PLastTxBytes); -+ DBGLOG(SW4, WARN, "ulP2PLastRxBytes:%ld\n", prPerMonitor->ulP2PLastRxBytes); -+ DBGLOG(SW4, WARN, "ulThroughput:%ld\n", prPerMonitor->ulThroughput); -+ DBGLOG(SW4, WARN, "u4UpdatePeriod:%d\n", prPerMonitor->u4UpdatePeriod); -+ DBGLOG(SW4, WARN, "u4TarPerfLevel:%d\n", prPerMonitor->u4TarPerfLevel); -+ DBGLOG(SW4, WARN, "u4CurrPerfLevel:%d\n", prPerMonitor->u4CurrPerfLevel); -+ DBGLOG(SW4, WARN, "netStats tx_bytes:%ld\n", prGlueInfo->rNetDevStats.tx_bytes); -+ DBGLOG(SW4, WARN, "netStats tx_bytes:%ld\n", prGlueInfo->rNetDevStats.rx_bytes); -+ DBGLOG(SW4, WARN, "p2p netStats tx_bytes:%ld\n", prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes); -+ DBGLOG(SW4, WARN, "p2p netStats tx_bytes:%ld\n", prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes); -+} -+ -+inline INT32 kalPerMonInit(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ DBGLOG(SW4, INFO, "enter %s\n", __func__); -+ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) -+ DBGLOG(SW4, WARN, "abnormal, perf monitory already running\n"); -+ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ KAL_CLR_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ KAL_SET_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ prPerMonitor->u4UpdatePeriod = 1000; -+ cnmTimerInitTimer(prGlueInfo->prAdapter, -+ &prPerMonitor->rPerfMonTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) kalPerMonHandler, (ULONG) NULL); -+ DBGLOG(SW4, INFO, "exit %s\n", __func__); -+ return 0; -+} -+ -+inline INT32 kalPerMonDisable(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ -+ DBGLOG(SW4, INFO, "enter %s\n", __func__); -+ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ DBGLOG(SW4, TRACE, "need to stop before disable\n"); -+ kalPerMonStop(prGlueInfo); -+ } -+ KAL_SET_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, TRACE, "exit %s\n", __func__); -+ return 0; -+} -+ -+inline INT32 kalPerMonEnable(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ -+ DBGLOG(SW4, INFO, "enter %s\n", __func__); -+ KAL_CLR_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, TRACE, "exit %s\n", __func__); -+ return 0; -+} -+ -+inline INT32 kalPerMonStart(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ DBGLOG(SW4, TRACE, "enter %s\n", __func__); -+ if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) -+ return 0; -+ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ DBGLOG(SW4, TRACE, "perf monitor already running\n"); -+ return 0; -+ } -+ cnmTimerStartTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer, prPerMonitor->u4UpdatePeriod); -+ KAL_SET_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ KAL_CLR_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, INFO, "perf monitor started\n"); -+ return 0; -+} -+ -+inline INT32 kalPerMonStop(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ DBGLOG(SW4, TRACE, "enter %s\n", __func__); -+ -+ if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ DBGLOG(SW4, TRACE, "perf monitory disabled\n"); -+ return 0; -+ } -+ -+ if (KAL_TEST_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ DBGLOG(SW4, TRACE, "perf monitory already stopped\n"); -+ return 0; -+ } -+ -+ KAL_SET_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ cnmTimerStopTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer); -+ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ prPerMonitor->ulLastRxBytes = 0; -+ prPerMonitor->ulLastTxBytes = 0; -+ prPerMonitor->ulP2PLastRxBytes = 0; -+ prPerMonitor->ulP2PLastTxBytes = 0; -+ prPerMonitor->ulThroughput = 0; -+ prPerMonitor->u4CurrPerfLevel = 0; -+ prPerMonitor->u4TarPerfLevel = 0; -+ /*Cancel CPU performance mode request*/ -+ kalBoostCpu(0); -+ } -+ DBGLOG(SW4, TRACE, "exit %s\n", __func__); -+ return 0; -+} -+ -+inline INT32 kalPerMonDestroy(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ kalPerMonDisable(prGlueInfo); -+ return 0; -+} -+ -+VOID kalPerMonHandler(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ /*Calculate current throughput*/ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ LONG latestTxBytes, latestRxBytes, txDiffBytes, rxDiffBytes; -+ LONG p2pLatestTxBytes, p2pLatestRxBytes, p2pTxDiffBytes, p2pRxDiffBytes; -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ if ((prGlueInfo->ulFlag & GLUE_FLAG_HALT) || (!prAdapter->fgIsP2PRegistered)) -+ return; -+ -+ prPerMonitor = &prAdapter->rPerMonitor; -+ DBGLOG(SW4, TRACE, "enter kalPerMonHandler\n"); -+ if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, WARN, "perf monitory disabled, omit timeout event\n"); -+ return; -+ } -+ -+ if (KAL_TEST_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, WARN, "perf monitory stopped, omit timeout event\n"); -+ return; -+ } -+ latestTxBytes = prGlueInfo->rNetDevStats.tx_bytes; -+ latestRxBytes = prGlueInfo->rNetDevStats.rx_bytes; -+ p2pLatestTxBytes = prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes; -+ p2pLatestRxBytes = prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes; -+ if (0 == prPerMonitor->ulLastRxBytes && -+ 0 == prPerMonitor->ulLastTxBytes && -+ 0 == prPerMonitor->ulP2PLastRxBytes && -+ 0 == prPerMonitor->ulP2PLastTxBytes) { -+ prPerMonitor->ulThroughput = 0; -+ } else { -+ txDiffBytes = latestTxBytes - prPerMonitor->ulLastTxBytes; -+ rxDiffBytes = latestRxBytes - prPerMonitor->ulLastRxBytes; -+ if (0 > txDiffBytes) -+ txDiffBytes = -(txDiffBytes); -+ if (0 > rxDiffBytes) -+ rxDiffBytes = -(rxDiffBytes); -+ -+ p2pTxDiffBytes = p2pLatestTxBytes - prPerMonitor->ulP2PLastTxBytes; -+ p2pRxDiffBytes = p2pLatestRxBytes - prPerMonitor->ulP2PLastRxBytes; -+ if (0 > p2pTxDiffBytes) -+ p2pTxDiffBytes = -(p2pTxDiffBytes); -+ if (0 > p2pRxDiffBytes) -+ p2pRxDiffBytes = -(p2pRxDiffBytes); -+ -+ prPerMonitor->ulThroughput = txDiffBytes + rxDiffBytes + p2pTxDiffBytes + p2pRxDiffBytes; -+ prPerMonitor->ulThroughput *= 1000; -+ prPerMonitor->ulThroughput /= prPerMonitor->u4UpdatePeriod; -+ prPerMonitor->ulThroughput <<= 3; -+ } -+ /*start the timer again to make sure we can cancel performance mode request in the end*/ -+ cnmTimerStartTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer, prPerMonitor->u4UpdatePeriod); -+ -+ prPerMonitor->ulLastTxBytes = latestTxBytes; -+ prPerMonitor->ulLastRxBytes = latestRxBytes; -+ prPerMonitor->ulP2PLastTxBytes = p2pLatestTxBytes; -+ prPerMonitor->ulP2PLastRxBytes = p2pLatestRxBytes; -+ -+ if (prPerMonitor->ulThroughput < THROUGHPUT_L1_THRESHOLD) -+ prPerMonitor->u4TarPerfLevel = 0; -+ else if (prPerMonitor->ulThroughput < THROUGHPUT_L2_THRESHOLD) -+ prPerMonitor->u4TarPerfLevel = 1; -+ else if (prPerMonitor->ulThroughput < THROUGHPUT_L3_THRESHOLD) -+ prPerMonitor->u4TarPerfLevel = 2; -+ else -+ prPerMonitor->u4TarPerfLevel = 3; -+ if (prPerMonitor->u4TarPerfLevel != prPerMonitor->u4CurrPerfLevel) { -+ if (0 == prPerMonitor->u4TarPerfLevel) { -+ /*cancel CPU performance mode request*/ -+ kalPerMonStop(prGlueInfo); -+ } else{ -+ DBGLOG(SW4, TRACE, "throughput:%ld bps\n", prPerMonitor->ulThroughput); -+ /*adjust CPU core number to prPerMonitor->u4TarPerfLevel+1*/ -+ kalBoostCpu(prPerMonitor->u4TarPerfLevel+1); -+ /*start the timer again to make sure we can cancel performance mode request in the end*/ -+ cnmTimerStartTimer(prGlueInfo->prAdapter, -+ &prPerMonitor->rPerfMonTimer, -+ prPerMonitor->u4UpdatePeriod); -+ } -+ } -+ prPerMonitor->u4CurrPerfLevel = prPerMonitor->u4TarPerfLevel; -+ DBGLOG(SW4, TRACE, "exit kalPerMonHandler\n"); -+} -+ -+INT32 __weak kalBoostCpu(UINT_32 core_num) -+{ -+ DBGLOG(SW4, WARN, "enter weak kalBoostCpu, core_num:%d\n", core_num); -+ return 0; -+} -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c -new file mode 100644 -index 0000000000000..945a6c03978b8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c -@@ -0,0 +1,4672 @@ -+/* -+** Id: @(#) gl_p2p.c@@ -+*/ -+ -+/*! \file gl_p2p.c -+ \brief Main routines of Linux driver interface for Wi-Fi Direct -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_p2p.c -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 17 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 16 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 14 2012 yuche.tsai -+** NULL -+** FPB from ALPS.JB to phase 2 release. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Fix compile error for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 01 09 2012 terry.wu -+ * [WCXRP00001166] [Wi-Fi] [Driver] cfg80211 integration for p2p newtork -+ * cfg80211 integration for p2p network. -+ * -+ * 12 19 2011 terry.wu -+ * [WCXRP00001142] [Wi-Fi] [P2P Driver] XOR local admin bit to generate p2p net device MAC -+ * XOR local administrated bit to generate net device MAC of p2p network. -+ * -+ * 12 02 2011 yuche.tsai -+ * NULL -+ * Fix possible KE when unload p2p. -+ * -+ * 11 24 2011 yuche.tsai -+ * NULL -+ * Fix P2P IOCTL of multicast address bug, add low power driver stop control. -+ * -+ * 11 22 2011 yuche.tsai -+ * NULL -+ * Update RSSI link quality of P2P Network query method. (Bug fix) -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Add RSSI support for P2P network. -+ * -+ * 11 16 2011 yuche.tsai -+ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. -+ * Avoid using work thread in set p2p multicast address callback. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix default device name issue. -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service -+ * discovery version check. -+ * Add support for driver version query & p2p supplicant verseion set. -+ * For new service discovery mechanism sync. -+ * -+ * 11 07 2011 yuche.tsai -+ * NULL -+ * [ALPS 00087243] KE in worker thread. -+ * The multicast address list is scheduled in worker thread. -+ * Before the worker thread is excuted, if P2P is unloaded, a KE may occur. -+ * -+ * 10 26 2011 terry.wu -+ * [WCXRP00001066] [MT6620 Wi-Fi] [P2P Driver] Fix P2P Oid Issue -+ * Fix some P2P OID functions didn't raise its flag "fgIsP2pOid" issue. -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * . -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * Support Channel Query. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 08 26 2011 yuche.tsai -+ * NULL -+ * Fix bug of parsing secondary device list type issue. -+ * -+ * 08 24 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Invitation Abort. -+ * -+ * 08 23 2011 yuche.tsai -+ * NULL -+ * Fix multicast address list issue of P2P. -+ * -+ * 08 22 2011 chinglan.wang -+ * NULL -+ * Fix invitation indication bug.. -+ * -+ * 08 16 2011 cp.wu -+ * [WCXRP00000934] [MT6620 Wi-Fi][Driver][P2P] Wi-Fi hot spot with auto sparse channel residence -+ * auto channel decision for 2.4GHz hot spot mode -+ * -+ * 08 16 2011 chinglan.wang -+ * NULL -+ * Add the group id information in the invitation indication. -+ * -+ * 08 09 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Invitation Feature add on. -+ * -+ * 08 05 2011 yuche.tsai -+ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution. -+ * Add Password ID check for quick connection. -+ * Also modify some connection policy. -+ * -+ * 07 18 2011 chinglan.wang -+ * NULL -+ * Add IOC_P2P_GO_WSC_IE (p2p capability). -+ * -+ * 06 14 2011 yuche.tsai -+ * NULL -+ * Add compile flag to disable persistent group support. -+ * -+ * 05 04 2011 chinglan.wang -+ * [WCXRP00000698] [MT6620 Wi-Fi][P2P][Driver] Add p2p invitation command for the p2p driver -+ * . -+ * -+ * 05 02 2011 yuche.tsai -+ * [WCXRP00000693] [Volunteer Patch][MT6620][Driver] Clear Formation Flag after TX lifetime timeout. -+ * Clear formation flag after formation timeout. -+ * -+ * 04 22 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * . -+ * -+ * 04 21 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * 1. Revise P2P power mode setting. -+ * 2. Revise fast-PS for concurrent -+ * -+ * 04 19 2011 wh.su -+ * NULL -+ * Adding length check before doing WPA RSN IE parsing for scan results indicate. -+ * -+ * 04 14 2011 yuche.tsai -+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. -+ * Connection flow refine for Sigma test. -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discoverability support. -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 04 07 2011 terry.wu -+ * [WCXRP00000619] [MT6620 Wi-Fi][Driver] fix kernel panic may occur when removing wlan -+ * Fix kernel panic may occur when removing wlan driver. -+ * -+ * 03 31 2011 wh.su -+ * [WCXRP00000614] [MT6620 Wi-Fi][Driver] P2P: Update beacon content while setting WSC IE -+ * Update the wsc ie to beacon content. -+ * -+ * 03 25 2011 wh.su -+ * NULL -+ * add the sample code for set power mode and get power mode. -+ * -+ * 03 25 2011 yuche.tsai -+ * NULL -+ * Improve some error handleing. -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 22 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Modify formation policy. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * Modify formation policy setting. -+ * -+ * 03 18 2011 yuche.tsai -+ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow -+ * Modify connection flow after Group Formation Complete, or device connect to a GO. -+ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN. -+ * -+ * 03 15 2011 wh.su -+ * [WCXRP00000563] [MT6620 Wi-Fi] [P2P] Set local config method while set password Id ready -+ * set lccal config method method while set password Id ready. -+ * -+ * 03 15 2011 yuche.tsai -+ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue -+ * Fix some configure method issue. -+ * -+ * 03 15 2011 jeffrey.chang -+ * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM -+ * refine queue_select function -+ * -+ * 03 13 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * add code for avoid compiling warning. -+ * -+ * 03 10 2011 yuche.tsai -+ * NULL -+ * Add P2P API. -+ * -+ * 03 10 2011 terry.wu -+ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration -+ * Remove unnecessary assert and message. -+ * -+ * 03 08 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * support the power save related p2p setting. -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * support concurrent network -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * modify P2P's netdevice functions to support multiple H/W queues -+ * -+ * 03 03 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * for get request, the buffer length to be copied is header + payload. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add code to let the beacon and probe response for Auto GO WSC . -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * add a missed break. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation -+ * Update channel issue when doing GO formation.. -+ * -+ * 02 25 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * add the Operation channel setting. -+ * -+ * 02 23 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * fixed the set int ioctl set index and value map to driver issue. -+ * -+ * 02 22 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * adding the ioctl set int from supplicant, and can used to set the p2p parameters -+ * -+ * 02 21 2011 terry.wu -+ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P -+ * Clean P2P scan list while removing P2P. -+ * -+ * 02 18 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * fixed the ioctl setting that index not map to spec defined config method. -+ * -+ * 02 17 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * append the WSC IE config method attribute at provision discovery request. -+ * -+ * 02 17 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * modify the structure pointer for set WSC IE. -+ * -+ * 02 16 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * fixed the probe request send out without WSC IE issue (at P2P). -+ * -+ * 02 09 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * fix typo -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add Support for MLME deauthentication for Hot-Spot. -+ * -+ * 01 25 2011 terry.wu -+ * [WCXRP00000393] [MT6620 Wi-Fi][Driver] Add new module insert parameter -+ * Add a new module parameter to indicate current runnig mode, P2P or AP. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * 1. Modify Channel Acquire Time of AP mode from 5s to 1s. -+ * 2. Call cnmP2pIsPermit() before active P2P network. -+ * 3. Add channel selection support for AP mode. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * ioctl implementations for P2P Service Discovery -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+ * 12 15 2010 cp.wu -+ * NULL -+ * invoke nicEnableInterrupt() before leaving from wlanAdapterStart() -+ * -+ * 12 08 2010 yuche.tsai -+ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in -+ * [WCXRP000000245][MT6620][Driver] Invitation Request Feature Add -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Invitation & Provision Discovery Indication. -+ * -+ * 11 17 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] Set the Tx -+ * lowest rate at wlan table for normal operation -+ * fixed some ASSERT check. -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * add a kal function for set cipher. -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * fixed compiling error while enable p2p. -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 10 2010 george.huang -+ * NULL -+ * update iwpriv LP related -+ * -+ * 09 10 2010 wh.su -+ * NULL -+ * fixed the compiling error at win XP. -+ * -+ * 09 09 2010 cp.wu -+ * NULL -+ * add WPS/WPA/RSN IE for Wi-Fi Direct scanning result. -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 06 2010 wh.su -+ * NULL -+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * add netdev_ops(NDO) for linux kernel 2.6.31 or greater -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 08 20 2010 cp.wu -+ * NULL -+ * correct typo. -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Invert Connection request provision status parameter. -+ * -+ * 08 19 2010 cp.wu -+ * NULL -+ * add set mac address interface for further possibilities of wpa_supplicant overriding interface address. -+ * -+ * 08 18 2010 cp.wu -+ * NULL -+ * modify pwp ioctls attribution by removing FIXED_SIZE. -+ * -+ * 08 18 2010 jeffrey.chang -+ * NULL -+ * support multi-function sdio -+ * -+ * 08 17 2010 cp.wu -+ * NULL -+ * correct p2p net device registration with NULL pointer access issue. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add subroutines for P2P to set multicast list. -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * add wext handlers to link P2P set PS profile/ network address function (TBD) -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * revised implementation of Wi-Fi Direct io controls. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * follow-up with ioctl interface update for Wi-Fi Direct application -+ * -+ * 08 06 2010 cp.wu -+ * NULL -+ * driver hook modifications corresponding to ioctl interface change. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * add basic support for ioctl of getting scan result. (only address and SSID are reporterd though) -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct Driver Hook] change event indication API to be consistent with supplicant -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct] add framework for driver hooks -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * p2p interface revised to be sync. with HAL -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 01 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl to configure scan mode for p2p connection -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add cfg80211 interface, which is to replace WE, for further extension -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement private io controls for Wi-Fi Direct -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement get scan result. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic handling framework for wireless extension ioctls. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement wireless extension ioctls in iw_handler form. -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * p2p ioctls revised. -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl for controlling p2p scan phase parameters -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement basic wi-fi direct framework -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic framework for implementating P2P driver hook. -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+ -+#include "gl_os.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include "gl_p2p_os.h" -+#include "gl_p2p_ioctl.h" -+#include "gl_vendor.h" -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define ARGV_MAX_NUM (4) -+ -+/*For CFG80211 - wiphy parameters*/ -+#define MAX_SCAN_LIST_NUM (1) -+#define MAX_SCAN_IE_LEN (512) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+static struct cfg80211_ops mtk_p2p_ops = { -+ .change_virtual_intf = mtk_p2p_cfg80211_change_iface, /* 1st */ -+ .change_bss = mtk_p2p_cfg80211_change_bss, -+ .scan = mtk_p2p_cfg80211_scan, -+ .remain_on_channel = mtk_p2p_cfg80211_remain_on_channel, -+ .cancel_remain_on_channel = mtk_p2p_cfg80211_cancel_remain_on_channel, -+ .mgmt_tx = mtk_p2p_cfg80211_mgmt_tx, -+ .connect = mtk_p2p_cfg80211_connect, -+ .disconnect = mtk_p2p_cfg80211_disconnect, -+ .deauth = mtk_p2p_cfg80211_deauth, -+ .disassoc = mtk_p2p_cfg80211_disassoc, -+ .start_ap = mtk_p2p_cfg80211_start_ap, -+ .change_beacon = mtk_p2p_cfg80211_change_beacon, -+ .stop_ap = mtk_p2p_cfg80211_stop_ap, -+ .set_wiphy_params = mtk_p2p_cfg80211_set_wiphy_params, -+ .del_station = mtk_p2p_cfg80211_del_station, -+ .set_monitor_channel = mtk_p2p_cfg80211_set_channel, -+ .set_bitrate_mask = mtk_p2p_cfg80211_set_bitrate_mask, -+ .mgmt_frame_register = mtk_p2p_cfg80211_mgmt_frame_register, -+ .get_station = mtk_p2p_cfg80211_get_station, -+ .add_key = mtk_p2p_cfg80211_add_key, -+ .get_key = mtk_p2p_cfg80211_get_key, -+ .del_key = mtk_p2p_cfg80211_del_key, -+ .set_default_key = mtk_p2p_cfg80211_set_default_key, -+ .join_ibss = mtk_p2p_cfg80211_join_ibss, -+ .leave_ibss = mtk_p2p_cfg80211_leave_ibss, -+ .set_tx_power = mtk_p2p_cfg80211_set_txpower, -+ .get_tx_power = mtk_p2p_cfg80211_get_txpower, -+ .set_power_mgmt = mtk_p2p_cfg80211_set_power_mgmt, -+#ifdef CONFIG_NL80211_TESTMODE -+ .testmode_cmd = mtk_p2p_cfg80211_testmode_cmd, -+#endif -+}; -+ -+static const struct wiphy_vendor_command mtk_p2p_vendor_ops[] = { -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = WIFI_SUBCMD_GET_CHANNEL_LIST -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_get_channel_list -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_set_country_code -+ }, -+}; -+ -+/* There isn't a lot of sense in it, but you can transmit anything you like */ -+static const struct ieee80211_txrx_stypes -+ mtk_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { -+ [NL80211_IFTYPE_ADHOC] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_STATION] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) -+ }, -+ [NL80211_IFTYPE_AP] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_AP_VLAN] = { -+ /* copy AP */ -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | -+ BIT(IEEE80211_STYPE_DISASSOC >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4) | -+ BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_P2P_CLIENT] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) -+ }, -+ [NL80211_IFTYPE_P2P_GO] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ } -+}; -+ -+#endif -+ -+/* the legacy wireless extension stuff */ -+static const iw_handler rP2PIwStandardHandler[] = { -+ [SIOCGIWPRIV - SIOCIWFIRST] = mtk_p2p_wext_get_priv, -+ [SIOCGIWSCAN - SIOCIWFIRST] = mtk_p2p_wext_discovery_results, -+ [SIOCSIWESSID - SIOCIWFIRST] = mtk_p2p_wext_reconnect, -+ [SIOCSIWAUTH - SIOCIWFIRST] = mtk_p2p_wext_set_auth, -+ [SIOCSIWENCODEEXT - SIOCIWFIRST] = mtk_p2p_wext_set_key, -+ [SIOCSIWPOWER - SIOCIWFIRST] = mtk_p2p_wext_set_powermode, -+ [SIOCGIWPOWER - SIOCIWFIRST] = mtk_p2p_wext_get_powermode, -+ [SIOCSIWTXPOW - SIOCIWFIRST] = mtk_p2p_wext_set_txpow, -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ [SIOCGIWSTATS - SIOCIWFIRST] = mtk_p2p_wext_get_rssi, -+#endif -+ [SIOCSIWMLME - SIOCIWFIRST] = mtk_p2p_wext_mlme_handler, -+}; -+ -+static const iw_handler rP2PIwPrivHandler[] = { -+ [IOC_P2P_CFG_DEVICE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_local_dev_info, -+ [IOC_P2P_PROVISION_COMPLETE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_provision_complete, -+ [IOC_P2P_START_STOP_DISCOVERY - SIOCIWFIRSTPRIV] = mtk_p2p_wext_start_stop_discovery, -+ [IOC_P2P_DISCOVERY_RESULTS - SIOCIWFIRSTPRIV] = mtk_p2p_wext_discovery_results, -+ [IOC_P2P_WSC_BEACON_PROBE_RSP_IE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_wsc_ie, -+ [IOC_P2P_CONNECT_DISCONNECT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_connect_disconnect, -+ [IOC_P2P_PASSWORD_READY - SIOCIWFIRSTPRIV] = mtk_p2p_wext_password_ready, -+/* [IOC_P2P_SET_PWR_MGMT_PARAM - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_pm_param, */ -+ [IOC_P2P_SET_INT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_int, -+ [IOC_P2P_GET_STRUCT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_get_struct, -+ [IOC_P2P_SET_STRUCT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_struct, -+ [IOC_P2P_GET_REQ_DEVICE_INFO - SIOCIWFIRSTPRIV] = mtk_p2p_wext_request_dev_info, -+}; -+ -+static const struct iw_priv_args rP2PIwPrivTable[] = { -+ { -+ .cmd = IOC_P2P_CFG_DEVICE, -+ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_CFG_DEVICE_TYPE), -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_CFG_DEVICE"} -+ , -+ { -+ .cmd = IOC_P2P_START_STOP_DISCOVERY, -+ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_REQ_DEVICE_TYPE), -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_DISCOVERY"} -+ , -+ { -+ .cmd = IOC_P2P_DISCOVERY_RESULTS, -+ .set_args = IW_PRIV_TYPE_NONE, -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_RESULT"} -+ , -+ { -+ .cmd = IOC_P2P_WSC_BEACON_PROBE_RSP_IE, -+ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_HOSTAPD_PARAM), -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_WSC_IE"} -+ , -+ { -+ .cmd = IOC_P2P_CONNECT_DISCONNECT, -+ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_CONNECT_DEVICE), -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_CONNECT"} -+ , -+ { -+ .cmd = IOC_P2P_PASSWORD_READY, -+ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_PASSWORD_READY), -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_PASSWD_RDY"} -+ , -+ { -+ .cmd = IOC_P2P_GET_STRUCT, -+ .set_args = IW_PRIV_TYPE_NONE, -+ .get_args = 256, -+ .name = "P2P_GET_STRUCT"} -+ , -+ { -+ .cmd = IOC_P2P_SET_STRUCT, -+ .set_args = 256, -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_SET_STRUCT"} -+ , -+ { -+ .cmd = IOC_P2P_GET_REQ_DEVICE_INFO, -+ .set_args = IW_PRIV_TYPE_NONE, -+ .get_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_DEVICE_REQ), -+ .name = "P2P_GET_REQDEV"} -+ , -+ { -+ /* SET STRUCT sub-ioctls commands */ -+ .cmd = PRIV_CMD_OID, -+ .set_args = 256, -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "set_oid"} -+ , -+ { -+ /* GET STRUCT sub-ioctls commands */ -+ .cmd = PRIV_CMD_OID, -+ .set_args = IW_PRIV_TYPE_NONE, -+ .get_args = 256, -+ .name = "get_oid"} -+}; -+ -+const struct iw_handler_def mtk_p2p_wext_handler_def = { -+ .num_standard = (__u16) sizeof(rP2PIwStandardHandler) / sizeof(iw_handler), -+ .num_private = (__u16) sizeof(rP2PIwPrivHandler) / sizeof(iw_handler), -+ .num_private_args = (__u16) sizeof(rP2PIwPrivTable) / sizeof(struct iw_priv_args), -+ .standard = rP2PIwStandardHandler, -+ .private = rP2PIwPrivHandler, -+ .private_args = rP2PIwPrivTable, -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ .get_wireless_stats = mtk_p2p_wext_get_wireless_stats, -+#else -+ .get_wireless_stats = NULL, -+#endif -+}; -+ -+#ifdef CONFIG_PM -+static const struct wiphy_wowlan_support p2p_wowlan_support = { -+ .flags = WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_ANY, -+}; -+#endif -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* for IE Searching */ -+extern BOOLEAN -+wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); -+ -+#if CFG_SUPPORT_WPS -+extern BOOLEAN -+wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); -+#endif -+ -+/* Net Device Hooks */ -+static int p2pOpen(IN struct net_device *prDev); -+ -+static int p2pStop(IN struct net_device *prDev); -+ -+static struct net_device_stats *p2pGetStats(IN struct net_device *prDev); -+ -+static void p2pSetMulticastList(IN struct net_device *prDev); -+ -+static int p2pHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev); -+ -+static int p2pDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd); -+ -+static int p2pSetMACAddress(IN struct net_device *prDev, void *addr); -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Override the implementation of select queue -+* -+* \param[in] dev Pointer to struct net_device -+* \param[in] skb Pointer to struct skb_buff -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+unsigned int _p2p_cfg80211_classify8021d(struct sk_buff *skb) -+{ -+ unsigned int dscp = 0; -+ -+ /* skb->priority values from 256->263 are magic values -+ * directly indicate a specific 802.1d priority. This is -+ * to allow 802.1d priority to be passed directly in from -+ * tags -+ */ -+ -+ if (skb->priority >= 256 && skb->priority <= 263) -+ return skb->priority - 256; -+ switch (skb->protocol) { -+ case htons(ETH_P_IP): -+ dscp = ip_hdr(skb)->tos & 0xfc; -+ break; -+ } -+ return dscp >> 5; -+} -+ -+static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; -+ -+static UINT_16 p2pSelectQueue(struct net_device *dev, struct sk_buff *skb, -+ struct net_device *sb_dev, -+ select_queue_fallback_t fallback) -+{ -+ skb->priority = _p2p_cfg80211_classify8021d(skb); -+ -+ return au16Wlan1dToQueueIdx[skb->priority]; -+} -+ -+static struct net_device *g_P2pPrDev; -+static struct wireless_dev *gprP2pWdev; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->init -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \retval 0 The execution of wlanInit succeeds. -+* \retval -ENXIO No such device. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int p2pInit(struct net_device *prDev) -+{ -+/* P_GLUE_INFO_T prGlueInfo; */ -+ if (!prDev) -+ return -ENXIO; -+ -+ DBGLOG(P2P, INFO, "dev name=%s\n", prDev->name); -+ return 0; /* success */ -+} /* end of p2pInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->uninit -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static void p2pUninit(IN struct net_device *prDev) -+{ -+ -+} /* end of p2pUninit() */ -+ -+static const struct net_device_ops p2p_netdev_ops = { -+ .ndo_open = p2pOpen, -+ .ndo_stop = p2pStop, -+ .ndo_set_mac_address = p2pSetMACAddress, -+ .ndo_set_rx_mode = p2pSetMulticastList, -+ .ndo_get_stats = p2pGetStats, -+ .ndo_do_ioctl = p2pDoIOCTL, -+ .ndo_start_xmit = p2pHardStartXmit, -+ .ndo_select_queue = p2pSelectQueue, -+ .ndo_init = p2pInit, -+ .ndo_uninit = p2pUninit, -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Allocate memory for P2P_INFO, GL_P2P_INFO, P2P_CONNECTION_SETTINGS -+* P2P_SPECIFIC_BSS_INFO, P2P_FSM_INFO -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2PAllocInfo(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_WIFI_VAR_T prWifiVar = NULL; -+ -+ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ prWifiVar = &(prAdapter->rWifiVar); -+ -+ if (!prWifiVar) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ do { -+ if (prGlueInfo->prP2PInfo == NULL) { -+ /*alloc memory for p2p info */ -+ prGlueInfo->prP2PInfo = kalMemAlloc(sizeof(GL_P2P_INFO_T), VIR_MEM_TYPE); -+ prAdapter->prP2pInfo = kalMemAlloc(sizeof(P2P_INFO_T), VIR_MEM_TYPE); -+ prWifiVar->prP2PConnSettings = kalMemAlloc(sizeof(P2P_CONNECTION_SETTINGS_T), VIR_MEM_TYPE); -+ prWifiVar->prP2pFsmInfo = kalMemAlloc(sizeof(P2P_FSM_INFO_T), VIR_MEM_TYPE); -+ prWifiVar->prP2pSpecificBssInfo = kalMemAlloc(sizeof(P2P_SPECIFIC_BSS_INFO_T), VIR_MEM_TYPE); -+ } else { -+ ASSERT(prAdapter->prP2pInfo != NULL); -+ ASSERT(prWifiVar->prP2PConnSettings != NULL); -+ ASSERT(prWifiVar->prP2pFsmInfo != NULL); -+ ASSERT(prWifiVar->prP2pSpecificBssInfo != NULL); -+ } -+ /*MUST set memory to 0 */ -+ if (prGlueInfo->prP2PInfo) -+ kalMemZero(prGlueInfo->prP2PInfo, sizeof(GL_P2P_INFO_T)); -+ if (prAdapter->prP2pInfo) -+ kalMemZero(prAdapter->prP2pInfo, sizeof(P2P_INFO_T)); -+ if (prWifiVar->prP2PConnSettings) -+ kalMemZero(prWifiVar->prP2PConnSettings, sizeof(P2P_CONNECTION_SETTINGS_T)); -+ if (prWifiVar->prP2pFsmInfo) -+ kalMemZero(prWifiVar->prP2pFsmInfo, sizeof(P2P_FSM_INFO_T)); -+ if (prWifiVar->prP2pSpecificBssInfo) -+ kalMemZero(prWifiVar->prP2pSpecificBssInfo, sizeof(P2P_SPECIFIC_BSS_INFO_T)); -+ -+ } while (FALSE); -+ -+ /* chk if alloc successful or not */ -+ if (prGlueInfo->prP2PInfo && -+ prAdapter->prP2pInfo && -+ prWifiVar->prP2PConnSettings && prWifiVar->prP2pFsmInfo && prWifiVar->prP2pSpecificBssInfo) { -+ return TRUE; -+ } -+ -+ if (prWifiVar->prP2pSpecificBssInfo) { -+ kalMemFree(prWifiVar->prP2pSpecificBssInfo, VIR_MEM_TYPE, sizeof(P2P_SPECIFIC_BSS_INFO_T)); -+ -+ prWifiVar->prP2pSpecificBssInfo = NULL; -+ } -+ if (prWifiVar->prP2pFsmInfo) { -+ kalMemFree(prWifiVar->prP2pFsmInfo, VIR_MEM_TYPE, sizeof(P2P_FSM_INFO_T)); -+ -+ prWifiVar->prP2pFsmInfo = NULL; -+ } -+ if (prWifiVar->prP2PConnSettings) { -+ kalMemFree(prWifiVar->prP2PConnSettings, VIR_MEM_TYPE, sizeof(P2P_CONNECTION_SETTINGS_T)); -+ -+ prWifiVar->prP2PConnSettings = NULL; -+ } -+ if (prGlueInfo->prP2PInfo) { -+ kalMemFree(prGlueInfo->prP2PInfo, VIR_MEM_TYPE, sizeof(GL_P2P_INFO_T)); -+ -+ prGlueInfo->prP2PInfo = NULL; -+ } -+ if (prAdapter->prP2pInfo) { -+ kalMemFree(prAdapter->prP2pInfo, VIR_MEM_TYPE, sizeof(P2P_INFO_T)); -+ -+ prAdapter->prP2pInfo = NULL; -+ } -+ return FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Free memory for P2P_INFO, GL_P2P_INFO, P2P_CONNECTION_SETTINGS -+* P2P_SPECIFIC_BSS_INFO, P2P_FSM_INFO -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2PFreeInfo(P_GLUE_INFO_T prGlueInfo) -+{ -+ -+ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ /* free memory after p2p module is ALREADY unregistered */ -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) { -+ -+ kalMemFree(prGlueInfo->prAdapter->prP2pInfo, VIR_MEM_TYPE, sizeof(P2P_INFO_T)); -+ kalMemFree(prGlueInfo->prP2PInfo, VIR_MEM_TYPE, sizeof(GL_P2P_INFO_T)); -+ kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings, VIR_MEM_TYPE, -+ sizeof(P2P_CONNECTION_SETTINGS_T)); -+ kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo, VIR_MEM_TYPE, sizeof(P2P_FSM_INFO_T)); -+ kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo, VIR_MEM_TYPE, -+ sizeof(P2P_SPECIFIC_BSS_INFO_T)); -+ -+ /*Reomve p2p bss scan list */ -+ scanRemoveAllP2pBssDesc(prGlueInfo->prAdapter); -+ -+ /*reset all pointer to NULL */ -+ prGlueInfo->prP2PInfo = NULL; -+ prGlueInfo->prAdapter->prP2pInfo = NULL; -+ prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings = NULL; -+ prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo = NULL; -+ prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo = NULL; -+ -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+ -+} -+ -+#if !CFG_SUPPORT_PERSIST_NETDEV -+BOOLEAN p2pNetRegister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired) -+{ -+ BOOLEAN fgDoRegister = FALSE; -+/* BOOLEAN fgRollbackRtnlLock = FALSE; */ -+ BOOLEAN ret; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueInfo->prAdapter->rP2PNetRegState == ENUM_NET_REG_STATE_UNREGISTERED) { -+ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_REGISTERING; -+ fgDoRegister = TRUE; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ if (!fgDoRegister) -+ return TRUE; -+ -+ /* net device initialize */ -+ netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler); -+ netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); -+ -+ /* register for net device */ -+ if (register_netdev(prGlueInfo->prP2PInfo->prDevHandler) < 0) { -+ DBGLOG(P2P, WARN, "unable to register netdevice for p2p\n"); -+ -+ free_netdev(prGlueInfo->prP2PInfo->prDevHandler); -+ -+ ret = FALSE; -+ } else { -+ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_REGISTERED; -+ ret = TRUE; -+ } -+ return ret; -+} -+ -+BOOLEAN p2pNetUnregister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired) -+{ -+ BOOLEAN fgDoUnregister = FALSE; -+/* BOOLEAN fgRollbackRtnlLock = FALSE; */ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueInfo->prAdapter->rP2PNetRegState == ENUM_NET_REG_STATE_REGISTERED) { -+ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERING; -+ fgDoUnregister = TRUE; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ if (!fgDoUnregister) -+ return TRUE; -+ -+ /* prepare for removal */ -+ if (netif_carrier_ok(prGlueInfo->prP2PInfo->prDevHandler)) -+ netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler); -+ -+ netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); -+ DBGLOG(P2P, INFO, "P2P unregister_netdev 0x%p\n", prGlueInfo->prP2PInfo->prDevHandler); -+ unregister_netdev(prGlueInfo->prP2PInfo->prDevHandler); -+ -+ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERED; -+ -+ return TRUE; -+} -+#endif -+ -+BOOLEAN glP2pCreateWirelessDevice(P_GLUE_INFO_T prGlueInfo) -+{ -+ struct wiphy *prWiphy = NULL; -+ struct wireless_dev *prWdev = NULL; -+#if CFG_SUPPORT_PERSIST_NETDEV -+ struct net_device *prNetDev = NULL; -+#endif -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); -+ if (!prWdev) { -+ DBGLOG(P2P, ERROR, "allocate p2p wireless device fail, no memory\n"); -+ return FALSE; -+ } -+ /* 1. allocate WIPHY */ -+ prWiphy = wiphy_new(&mtk_p2p_ops, sizeof(P_GLUE_INFO_T)); -+ if (!prWiphy) { -+ DBGLOG(P2P, ERROR, "unable to allocate wiphy for p2p\n"); -+ goto free_wdev; -+ } -+ -+ prWiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_CLIENT) | -+ BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_STATION); -+ -+ prWiphy->bands[NL80211_BAND_2GHZ] = &mtk_band_2ghz; -+ prWiphy->bands[NL80211_BAND_5GHZ] = &mtk_band_5ghz; -+ -+ prWiphy->mgmt_stypes = mtk_cfg80211_default_mgmt_stypes; -+ prWiphy->max_remain_on_channel_duration = 5000; -+ prWiphy->cipher_suites = mtk_cipher_suites; -+ prWiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites); -+ prWiphy->flags = WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | WIPHY_FLAG_HAVE_AP_SME; -+ prWiphy->regulatory_flags = REGULATORY_CUSTOM_REG; -+ prWiphy->ap_sme_capa = 1; -+ -+ prWiphy->max_scan_ssids = MAX_SCAN_LIST_NUM; -+ prWiphy->max_scan_ie_len = MAX_SCAN_IE_LEN; -+ prWiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; -+ prWiphy->vendor_commands = mtk_p2p_vendor_ops; -+ prWiphy->n_vendor_commands = sizeof(mtk_p2p_vendor_ops) / sizeof(struct wiphy_vendor_command); -+ -+#ifdef CONFIG_PM -+ prWiphy->wowlan = &p2p_wowlan_support; -+#endif -+ -+ /* 2.1 set priv as pointer to glue structure */ -+ *((P_GLUE_INFO_T *) wiphy_priv(prWiphy)) = prGlueInfo; -+ if (wiphy_register(prWiphy) < 0) { -+ DBGLOG(P2P, ERROR, "fail to register wiphy for p2p\n"); -+ goto free_wiphy; -+ } -+ prWdev->wiphy = prWiphy; -+#if CFG_SUPPORT_PERSIST_NETDEV -+ /* 3. allocate netdev */ -+ prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), P2P_MODE_INF_NAME, NET_NAME_PREDICTABLE, -+ ether_setup, CFG_MAX_TXQ_NUM); -+ if (!prNetDev) { -+ DBGLOG(P2P, ERROR, "unable to allocate netdevice for p2p\n"); -+ goto unregister_wiphy; -+ } -+ -+ /* 4. setup netdev */ -+ /* 4.1 Point to shared glue structure */ -+ *((P_GLUE_INFO_T *) netdev_priv(prNetDev)) = prGlueInfo; -+ -+ /* 4.2 fill hardware address */ -+ /* COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); -+ rMacAddr[0] ^= 0x2; // change to local administrated address -+ memcpy(prGlueInfo->prP2PInfo->prDevHandler->dev_addr, rMacAddr, ETH_ALEN); -+ memcpy(prGlueInfo->prP2PInfo->prDevHandler->perm_addr, -+ prGlueInfo->prP2PInfo->prDevHandler->dev_addr, ETH_ALEN);*/ -+ -+ /* 4.3 register callback functions */ -+ prNetDev->netdev_ops = &p2p_netdev_ops; -+ /* prGlueInfo->prP2PInfo->prDevHandler->wireless_handlers = &mtk_p2p_wext_handler_def;*/ -+ -+ prNetDev->ieee80211_ptr = prWdev; -+ prWdev->netdev = prNetDev; -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ prNetDev->features = NETIF_F_IP_CSUM; -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ /* net device initialize */ -+ netif_carrier_off(prNetDev); -+ netif_tx_stop_all_queues(prNetDev); -+ -+ /* register for net device */ -+ if (register_netdev(prNetDev) < 0) { -+ DBGLOG(P2P, ERROR, "unable to register netdevice for p2p\n"); -+ free_netdev(prNetDev); -+ goto unregister_wiphy; -+ } -+#endif -+ gprP2pWdev = prWdev; -+ return TRUE; -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+unregister_wiphy: -+ wiphy_unregister(prWiphy); -+#endif -+free_wiphy: -+ wiphy_free(prWiphy); -+free_wdev: -+ kfree(prWdev); -+#endif -+ return FALSE; -+} -+ -+void glP2pDestroyWirelessDevice(VOID) -+{ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#if CFG_SUPPORT_PERSIST_NETDEV -+ unregister_netdev(gprP2pWdev->netdev); -+ free_netdev(gprP2pWdev->netdev); -+#endif -+ wiphy_unregister(gprP2pWdev->wiphy); -+ wiphy_free(gprP2pWdev->wiphy); -+ kfree(gprP2pWdev); -+ gprP2pWdev = NULL; -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Register for cfg80211 for Wi-Fi Direct -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glRegisterP2P(P_GLUE_INFO_T prGlueInfo, const char *prDevName, BOOLEAN fgIsApMode) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GL_HIF_INFO_T prHif = NULL; -+ PARAM_MAC_ADDRESS rMacAddr; -+ struct net_device *prDevHandler = NULL; -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ struct device *prDev; -+#endif -+ -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prHif = &prGlueInfo->rHifInfo; -+ ASSERT(prHif); -+ -+ DBGLOG(P2P, TRACE, "glRegisterP2P\n"); -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ if (!gprP2pWdev) { -+ DBGLOG(P2P, ERROR, "gl_p2p, wireless device is not exist\n"); -+ return FALSE; -+ } -+#endif -+ /*0. allocate p2pinfo */ -+ if (!p2PAllocInfo(prGlueInfo)) { -+ DBGLOG(P2P, ERROR, "Allocate memory for p2p FAILED\n"); -+ ASSERT(0); -+ return FALSE; -+ } -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ prGlueInfo->prP2PInfo->prWdev = gprP2pWdev; -+ /* 1. fill wiphy parameters */ -+#if MTK_WCN_HIF_SDIO -+ mtk_wcn_hif_sdio_get_dev(prHif->cltCtx, &prDev); -+ if (!prDev) -+ DBGLOG(P2P, WARN, "unable to get struct dev for p2p\n"); -+#else -+ prDev = prHif->Dev; -+#endif -+ /*set_wiphy_dev(gprP2pWdev->wiphy, prDev);*/ -+ if (!prGlueInfo->prAdapter->fgEnable5GBand) -+ gprP2pWdev->wiphy->bands[NL80211_BAND_5GHZ] = NULL; -+ -+ /* 2 set priv as pointer to glue structure */ -+ *(P_GLUE_INFO_T *) wiphy_priv(gprP2pWdev->wiphy) = prGlueInfo; -+ -+ if (fgIsApMode) { -+ gprP2pWdev->iftype = NL80211_IFTYPE_AP; -+#if CFG_SUPPORT_PERSIST_NETDEV -+ if (kalStrnCmp(gprP2pWdev->netdev->name, AP_MODE_INF_NAME, 2)) { -+ rtnl_lock(); -+ dev_change_name(gprP2pWdev->netdev->name, AP_MODE_INF_NAME); -+ rtnl_unlock(); -+ } -+#endif -+ } else { -+#if CFG_SUPPORT_PERSIST_NETDEV -+ if (kalStrnCmp(gprP2pWdev->netdev->name, P2P_MODE_INF_NAME, 3)) { -+ rtnl_lock(); -+ dev_change_name(gprP2pWdev->netdev->name, P2P_MODE_INF_NAME); -+ rtnl_unlock(); -+ } -+#endif -+ gprP2pWdev->iftype = NL80211_IFTYPE_P2P_CLIENT; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+ prP2PInfo->prDevHandler = gprP2pWdev->netdev; -+#else /* CFG_SUPPORT_PERSIST_NETDEV */ -+ /* 3. allocate netdev */ -+ prDevHandler = -+ alloc_netdev_mq(sizeof(P_GLUE_INFO_T), prDevName, NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); -+ if (!prDevHandler) { -+ DBGLOG(P2P, ERROR, "unable to allocate netdevice for p2p\n"); -+ return FALSE; -+ } -+ prGlueInfo->prP2PInfo->prDevHandler = prDevHandler; -+ /* 4. setup netdev */ -+ /* 4.1 Point to shared glue structure */ -+ *((P_GLUE_INFO_T *) netdev_priv(prDevHandler)) = prGlueInfo; -+ -+ /* 4.2 fill hardware address */ -+ COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); -+ rMacAddr[0] ^= 0x2; /* change to local administrated address */ -+ ether_addr_copy(prDevHandler->dev_addr, rMacAddr); -+ ether_addr_copy(prDevHandler->perm_addr, prDevHandler->dev_addr); -+ -+ /* 4.3 register callback functions */ -+ prDevHandler->netdev_ops = &p2p_netdev_ops; -+ /* prGlueInfo->prP2PInfo->prDevHandler->wireless_handlers = &mtk_p2p_wext_handler_def; */ -+ -+#if (MTK_WCN_HIF_SDIO == 0) -+ SET_NETDEV_DEV(prDevHandler, prHif->Dev); -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ prDevHandler->ieee80211_ptr = gprP2pWdev; -+ gprP2pWdev->netdev = prDevHandler; -+#endif -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ prDevHandler->features = NETIF_F_IP_CSUM; -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+#endif /* CFG_SUPPORT_PERSIST_NETDEV */ -+ -+ /* 5. set p2p net device register state */ -+ prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERED; -+ -+ /* 6. setup running mode */ -+ prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode = fgIsApMode; -+ -+ /* 7. finish */ -+ p2pFsmInit(prAdapter); -+ -+ p2pFuncInitConnectionSettings(prAdapter, prAdapter->rWifiVar.prP2PConnSettings); -+ -+ /* Active network too early would cause HW not able to sleep. -+ * Defer the network active time. -+ */ -+/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+ return TRUE; -+} /* end of glRegisterP2P() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Unregister Net Device for Wi-Fi Direct -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glUnregisterP2P(P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ /* normal flow: this func will called first before wlanRemove, and it can do fsmUninit/deactivateNetwork -+ gracefully. */ -+ /* when reset: because tx_thread with fw has stopped, so it can't do these job and the recovery will be -+ dependent on chip system reset. */ -+ /* if so, just skip it by flag GLUE_FLAG_HALT(warning: when tx_thread was stop, this flag was not cleared, -+ and NEED TO KEEP IT NOT CLEARED!). */ -+ if (!(prGlueInfo->ulFlag & GLUE_FLAG_HALT)) { -+ p2pFsmUninit(prGlueInfo->prAdapter); -+ nicDeactivateNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+#if CFG_SUPPORT_PERSIST_NETDEV -+ dev_close(prGlueInfo->prP2PInfo->prDevHandler); -+#else -+ free_netdev(prGlueInfo->prP2PInfo->prDevHandler); -+ prGlueInfo->prP2PInfo->prDevHandler = NULL; -+#endif -+ /* Free p2p memory */ -+ if (!p2PFreeInfo(prGlueInfo)) { -+ DBGLOG(P2P, ERROR, "Free memory for p2p FAILED\n"); -+ ASSERT(0); -+ return FALSE; -+ } -+ return TRUE; -+} /* end of glUnregisterP2P() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A function for stop p2p fsm immediate -+ * -+ * \param[in] prGlueInfo Pointer to struct P_GLUE_INFO_T. -+ * -+ * \retval TRUE The execution succeeds. -+ * \retval FALSE The execution failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pStopImmediate(P_GLUE_INFO_T prGlueInfo) -+{ -+/* P_ADAPTER_T prAdapter = NULL; */ -+/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ -+ -+ ASSERT(prGlueInfo); -+ -+/* prAdapter = prGlueInfo->prAdapter; */ -+/* ASSERT(prAdapter); */ -+ -+ /* 1. stop TX queue */ -+ netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); -+ -+#if 0 -+ /* 2. switch P2P-FSM off */ -+ /* 2.1 allocate for message */ -+ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ -+ if (!prFuncSwitch) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ DBGLOG(P2P, ERROR, "Allocate for p2p mesasage FAILED\n"); -+ /* return -ENOMEM; */ -+ } -+ -+ /* 2.2 fill message */ -+ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ prFuncSwitch->fgIsFuncOn = FALSE; -+ -+ /* 2.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_UNBUF); -+ -+#endif -+ -+ /* 3. stop queue and turn off carrier */ -+ prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_DISCONNECTED; -+ -+ return TRUE; -+} /* end of p2pStop() */ -+ -+/* Net Device Hooks */ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A function for net_device open (ifup) -+ * -+ * \param[in] prDev Pointer to struct net_device. -+ * -+ * \retval 0 The execution succeeds. -+ * \retval < 0 The execution failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+static int p2pOpen(IN struct net_device *prDev) -+{ -+/* P_GLUE_INFO_T prGlueInfo = NULL; */ -+/* P_ADAPTER_T prAdapter = NULL; */ -+/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ -+ -+ ASSERT(prDev); -+ -+#if 0 /* Move after device name set. (mtk_p2p_set_local_dev_info) */ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* 1. switch P2P-FSM on */ -+ /* 1.1 allocate for message */ -+ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ -+ if (!prFuncSwitch) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ /* 1.2 fill message */ -+ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ prFuncSwitch->fgIsFuncOn = TRUE; -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF); -+#endif -+ -+ /* 2. carrier on & start TX queue */ -+ netif_carrier_on(prDev); -+ netif_tx_start_all_queues(prDev); -+ -+ return 0; /* success */ -+} /* end of p2pOpen() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A function for net_device stop (ifdown) -+ * -+ * \param[in] prDev Pointer to struct net_device. -+ * -+ * \retval 0 The execution succeeds. -+ * \retval < 0 The execution failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+static int p2pStop(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ /* P_ADAPTER_T prAdapter = NULL; */ -+/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ -+ struct cfg80211_scan_info info = { -+ .aborted = true, -+ }; -+ -+ struct cfg80211_scan_request *prScanRequest = NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ ASSERT(prGlueP2pInfo); -+ -+ /* CFG80211 down */ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueP2pInfo->prScanRequest != NULL) { -+ prScanRequest = prGlueP2pInfo->prScanRequest; -+ prGlueP2pInfo->prScanRequest = NULL; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ if (prScanRequest) -+ cfg80211_scan_done(prScanRequest, &info); -+#if 0 -+ -+ /* 1. stop TX queue */ -+ netif_tx_stop_all_queues(prDev); -+ -+ /* 2. switch P2P-FSM off */ -+ /* 2.1 allocate for message */ -+ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ -+ if (!prFuncSwitch) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ /* 2.2 fill message */ -+ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ prFuncSwitch->fgIsFuncOn = FALSE; -+ -+ /* 2.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF); -+#endif -+ /* 3. stop queue and turn off carrier */ -+ prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_DISCONNECTED; -+ -+ netif_tx_stop_all_queues(prDev); -+ if (netif_carrier_ok(prDev)) -+ netif_carrier_off(prDev); -+ -+ return 0; -+} /* end of p2pStop() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A method of struct net_device, to get the network interface statistical -+ * information. -+ * -+ * Whenever an application needs to get statistics for the interface, this method -+ * is called. This happens, for example, when ifconfig or netstat -i is run. -+ * -+ * \param[in] prDev Pointer to struct net_device. -+ * -+ * \return net_device_stats buffer pointer. -+ */ -+/*----------------------------------------------------------------------------*/ -+struct net_device_stats *p2pGetStats(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+ /* @FIXME */ -+ /* prDev->stats.rx_packets = 0; */ -+ /* prDev->stats.tx_packets = 0; */ -+ prDev->stats.tx_errors = 0; -+ prDev->stats.rx_errors = 0; -+ /* prDev->stats.rx_bytes = 0; */ -+ /* prDev->stats.tx_bytes = 0; */ -+ prDev->stats.multicast = 0; -+ -+ return &prDev->stats; -+ -+#else -+ /* prGlueInfo->prP2PInfo->rNetDevStats.rx_packets = 0; */ -+ /* prGlueInfo->prP2PInfo->rNetDevStats.tx_packets = 0; */ -+ prGlueInfo->prP2PInfo->rNetDevStats.tx_errors = 0; -+ prGlueInfo->prP2PInfo->rNetDevStats.rx_errors = 0; -+ /* prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes = 0; */ -+ /* prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes = 0; */ -+ /* prGlueInfo->prP2PInfo->rNetDevStats.rx_errors = 0; */ -+ prGlueInfo->prP2PInfo->rNetDevStats.multicast = 0; -+ -+ return &prGlueInfo->prP2PInfo->rNetDevStats; -+#endif -+} /* end of p2pGetStats() */ -+ -+static void p2pSetMulticastList(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; -+ -+ ASSERT(prDev); -+ ASSERT(prGlueInfo); -+ if (!prDev || !prGlueInfo) { -+ DBGLOG(P2P, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo); -+ return; -+ } -+ -+ g_P2pPrDev = prDev; -+ -+ /* 4 Mark HALT, notify main thread to finish current job */ -+/* prGlueInfo->u4Flag |= GLUE_FLAG_SUB_MOD_MULTICAST; */ -+ set_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag); -+ -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+} /* p2pSetMulticastList */ -+ -+/* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange -+ * another workqueue for sleeping. We don't want to block -+ * tx_thread, so we can't let tx_thread to do this */ -+ -+void p2pSetMulticastListWorkQueueWrapper(P_GLUE_INFO_T prGlueInfo) -+{ -+ if (!prGlueInfo) { -+ DBGLOG(INIT, ERROR, "prGlueInfo is NULL\n"); -+ return; -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ mtk_p2p_wext_set_Multicastlist(prGlueInfo); -+#endif -+} /* end of p2pSetMulticastListWorkQueueWrapper() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief This function is to set multicast list and set rx mode. -+ * -+ * \param[in] prDev Pointer to struct net_device -+ * -+ * \return (none) -+ */ -+/*----------------------------------------------------------------------------*/ -+void mtk_p2p_wext_set_Multicastlist(P_GLUE_INFO_T prGlueInfo) -+{ -+ UINT_32 u4SetInfoLen = 0; -+ struct net_device *prDev = g_P2pPrDev; -+ -+ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; -+ -+ ASSERT(prDev); -+ ASSERT(prGlueInfo); -+ if (!prDev || !prGlueInfo) { -+ DBGLOG(P2P, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo); -+ return; -+ } -+ -+ if (prDev->flags & IFF_PROMISC) -+ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS; -+ -+ if (prDev->flags & IFF_BROADCAST) -+ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST; -+ -+ if (prDev->flags & IFF_MULTICAST) { -+ if ((prDev->flags & IFF_ALLMULTI) || -+ (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) { -+ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; -+ } else { -+ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST; -+ } -+ } -+ -+ if (prGlueInfo->prP2PInfo->u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) { -+ /* Prepare multicast address list */ -+ struct netdev_hw_addr *ha; -+ UINT_32 i = 0; -+ -+ netdev_for_each_mc_addr(ha, prDev) { -+ if (i < MAX_NUM_GROUP_ADDR) { -+ COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucMCAddrList[i]), ha->addr); -+ i++; -+ } -+ } -+ -+ DBGLOG(P2P, TRACE, "SEt Multicast Address List\n"); -+ -+ if (i >= MAX_NUM_GROUP_ADDR) -+ return; -+ wlanoidSetP2PMulticastList(prGlueInfo->prAdapter, -+ &(prGlueInfo->prP2PInfo->aucMCAddrList[0]), (i * ETH_ALEN), &u4SetInfoLen); -+ -+ } -+ -+} /* end of mtk_p2p_wext_set_Multicastlist */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * * \brief This function is TX entry point of NET DEVICE. -+ * * -+ * * \param[in] prSkb Pointer of the sk_buff to be sent -+ * * \param[in] prDev Pointer to struct net_device -+ * * -+ * * \retval NETDEV_TX_OK - on success. -+ * * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. -+ * */ -+/*----------------------------------------------------------------------------*/ -+int p2pHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev) -+{ -+ P_QUE_ENTRY_T prQueueEntry = NULL; -+ P_QUE_T prTxQueue = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_16 u2QueueIdx = 0; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prSkb); -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ prGlueInfo->u8SkbToDriver++; -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ DBGLOG(P2P, ERROR, "GLUE_FLAG_HALT skip tx\n"); -+ prGlueInfo->u8SkbFreed++; -+ dev_kfree_skb(prSkb); -+ return NETDEV_TX_OK; -+ } -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ kalMetProfilingStart(prGlueInfo, prSkb); -+#endif -+ -+ /* mark as P2P packets */ -+ GLUE_SET_PKT_FLAG_P2P(prSkb); -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ GLUE_SET_PKT_ARRIVAL_TIME(prSkb, kalGetTimeTick()); -+#endif -+ -+ STATS_TX_TIME_ARRIVE(prSkb); -+ prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); -+ prTxQueue = &prGlueInfo->rTxQueue; -+ -+ if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) { -+ -+ u2QueueIdx = skb_get_queue_mapping(prSkb); -+ ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); -+ -+ if (u2QueueIdx >= CFG_MAX_TXQ_NUM) { -+ DBGLOG(P2P, ERROR, "Incorrect queue index, skip this frame\n"); -+ prGlueInfo->u8SkbFreed++; -+ dev_kfree_skb(prSkb); -+ return NETDEV_TX_OK; -+ } -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); -+ GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx]); -+ -+ if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx] >= -+ CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) { -+ DBGLOG(TX, INFO, "netif_stop_subqueue for p2p0, Queue len: %d\n", -+ prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx]); -+ netif_stop_subqueue(prDev, u2QueueIdx); -+ } -+ } else { -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); -+ } -+ -+ kalSetEvent(prGlueInfo); -+ -+ /* Statistic usage. */ -+ prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes += prSkb->len; -+ prGlueInfo->prP2PInfo->rNetDevStats.tx_packets++; -+ /* prDev->stats.tx_packets++; */ -+ kalPerMonStart(prGlueInfo); -+ return NETDEV_TX_OK; -+} /* end of p2pHardStartXmit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A method of struct net_device, a primary SOCKET interface to configure -+ * the interface lively. Handle an ioctl call on one of our devices. -+ * Everything Linux ioctl specific is done here. Then we pass the contents -+ * of the ifr->data to the request message handler. -+ * -+ * \param[in] prDev Linux kernel netdevice -+ * -+ * \param[in] prIfReq Our private ioctl request structure, typed for the generic -+ * struct ifreq so we can use ptr to function -+ * -+ * \param[in] cmd Command ID -+ * -+ * \retval 0 The IOCTL command is executed successfully. -+ * \retval <0 The execution of IOCTL command is failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+int p2pDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ int ret = 0; -+ char *prExtraBuf = NULL; -+ UINT_32 u4ExtraSize = 0; -+ struct iwreq *prIwReq = (struct iwreq *)prIfReq; -+ struct iw_request_info rIwReqInfo; -+ -+ ASSERT(prDev && prIfReq); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ if (!prGlueInfo) { -+ DBGLOG(P2P, ERROR, "prGlueInfo is NULL\n"); -+ return -EFAULT; -+ } -+ -+ if (prGlueInfo->u4ReadyFlag == 0) { -+ DBGLOG(P2P, ERROR, "Adapter is not ready\n"); -+ return -EINVAL; -+ } -+ -+ rIwReqInfo.cmd = (__u16) i4Cmd; -+ rIwReqInfo.flags = 0; -+ -+ switch (i4Cmd) { -+ case SIOCSIWENCODEEXT: -+ /* Set Encryption Material after 4-way handshaking is done */ -+ if (prIwReq->u.encoding.pointer) { -+ u4ExtraSize = prIwReq->u.encoding.length; -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, prIwReq->u.encoding.pointer, prIwReq->u.encoding.length)) -+ ret = -EFAULT; -+ } else if (prIwReq->u.encoding.length != 0) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (ret == 0) -+ ret = mtk_p2p_wext_set_key(prDev, &rIwReqInfo, &(prIwReq->u), prExtraBuf); -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ break; -+ -+ case SIOCSIWMLME: -+ /* IW_MLME_DISASSOC used for disconnection */ -+ if (prIwReq->u.data.length != sizeof(struct iw_mlme)) { -+ DBGLOG(P2P, WARN, "MLME buffer strange:%d\n", prIwReq->u.data.length); -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (!prIwReq->u.data.pointer) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, prIwReq->u.data.pointer, sizeof(struct iw_mlme))) -+ ret = -EFAULT; -+ else -+ ret = mtk_p2p_wext_mlme_handler(prDev, &rIwReqInfo, &(prIwReq->u), prExtraBuf); -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_mlme)); -+ prExtraBuf = NULL; -+ break; -+ -+ case SIOCGIWPRIV: -+ /* This ioctl is used to list all IW privilege ioctls */ -+ ret = mtk_p2p_wext_get_priv(prDev, &rIwReqInfo, &(prIwReq->u), NULL); -+ break; -+ -+ case SIOCGIWSCAN: -+ ret = mtk_p2p_wext_discovery_results(prDev, &rIwReqInfo, &(prIwReq->u), NULL); -+ break; -+ -+ case SIOCSIWAUTH: -+ ret = mtk_p2p_wext_set_auth(prDev, &rIwReqInfo, &(prIwReq->u), NULL); -+ break; -+ -+ case IOC_P2P_CFG_DEVICE: -+ case IOC_P2P_PROVISION_COMPLETE: -+ case IOC_P2P_START_STOP_DISCOVERY: -+ case IOC_P2P_DISCOVERY_RESULTS: -+ case IOC_P2P_WSC_BEACON_PROBE_RSP_IE: -+ case IOC_P2P_CONNECT_DISCONNECT: -+ case IOC_P2P_PASSWORD_READY: -+ case IOC_P2P_GET_STRUCT: -+ case IOC_P2P_SET_STRUCT: -+ case IOC_P2P_GET_REQ_DEVICE_INFO: -+ ret = -+ rP2PIwPrivHandler[i4Cmd - SIOCIWFIRSTPRIV] (prDev, &rIwReqInfo, &(prIwReq->u), -+ (char *)&(prIwReq->u)); -+ break; -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ case SIOCGIWSTATS: -+ ret = mtk_p2p_wext_get_rssi(prDev, &rIwReqInfo, &(prIwReq->u), NULL); -+ break; -+#endif -+ case IOC_GET_PRIVATE_IOCTL_CMD: -+ ret = priv_support_driver_cmd(prDev, prIfReq, i4Cmd); -+ -+ break; -+ default: -+ ret = -ENOTTY; -+ } -+ -+ return ret; -+} /* end of p2pDoIOCTL() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief To report the iw private args table to user space. -+ * -+ * \param[in] prDev Net device requested. -+ * \param[in] info Pointer to iw_request_info. -+ * \param[inout] wrqu Pointer to iwreq_data. -+ * \param[inout] extra -+ * -+ * \retval 0 For success. -+ * \retval -E2BIG For user's buffer size is too small. -+ * \retval -EFAULT For fail. -+ * -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_priv(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ UINT_16 u2BufferSize = prData->length; -+ -+ /* Update our private args table size */ -+ prData->length = (__u16)sizeof(rP2PIwPrivTable); -+ if (u2BufferSize < prData->length) -+ return -E2BIG; -+ -+ if (prData->length) { -+ if (copy_to_user(prData->pointer, rP2PIwPrivTable, sizeof(rP2PIwPrivTable))) -+ return -EFAULT; -+ } -+ -+ return 0; -+} /* end of mtk_p2p_wext_get_priv() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief To indicate P2P-FSM for re-associate to the connecting device -+ * -+ * \param[in] prDev Net device requested. -+ * \param[inout] wrqu Pointer to iwreq_data -+ * -+ * \retval 0 For success. -+ * \retval -EFAULT For fail. -+ * -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_reconnect(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+#if 0 -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_MSG_HDR_T prMsgHdr; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T)); -+ if (!prMsgHdr) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ /* 1.2 fill message */ -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_wext_reconnect: P2P Reconnect\n"); -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF); -+#endif -+ return 0; -+} /* end of mtk_p2p_wext_reconnect() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief MLME command handler -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_mlme_handler(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+#if 0 -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_mlme *mlme = (struct iw_mlme *)extra; -+ P_MSG_P2P_CONNECTION_ABORT_T prMsgP2PConnAbt = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_wext_mlme_handler:\n"); -+ -+ switch (mlme->cmd) { -+ case IW_MLME_DISASSOC: -+ prMsgP2PConnAbt = -+ (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_ABORT_T)); -+ if (!prMsgP2PConnAbt) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ COPY_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, mlme->addr.sa_data); -+ -+ prMsgP2PConnAbt->u2ReasonCode = mlme->reason_code; -+ -+ if (EQUAL_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, prP2pBssInfo->aucOwnMacAddr)) { -+ DBGLOG(P2P, TRACE, "P2P Connection Abort:\n"); -+ -+ /* 1.2 fill message */ -+ prMsgP2PConnAbt->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; -+ } else { -+ DBGLOG(P2P, TRACE, "P2P Connection Pause:\n"); -+ -+ /* 1.2 fill message */ -+ } -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnAbt, MSG_SEND_METHOD_BUF); -+ -+ break; -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+#endif -+ return 0; -+} /* end of mtk_p2p_wext_mlme_handler() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_PROVISION_COMPLETE) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_provision_complete(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+#if 0 -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ P_MSG_HDR_T prMsgHdr; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ switch (prData->flags) { -+ case P2P_PROVISIONING_SUCCESS: -+ prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T)); -+ if (!prMsgHdr) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ /* 1.2 fill message */ -+ -+ prGlueInfo->prP2PInfo->u4CipherPairwise = IW_AUTH_CIPHER_CCMP; -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF); -+ -+ break; -+ -+ case P2P_PROVISIONING_FAIL: -+ -+ break; -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+#endif -+ -+ return 0; -+} /* end of mtk_p2p_wext_set_provision_complete() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_START_STOP_DISCOVERY) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_start_stop_discovery(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+#if 0 -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ P_IW_P2P_REQ_DEVICE_TYPE prReqDeviceType = (P_IW_P2P_REQ_DEVICE_TYPE) extra; -+ UINT_8 au4IeBuf[MAX_IE_LENGTH]; -+ P_MSG_HDR_T prMsgHdr; -+ P_MSG_P2P_DEVICE_DISCOVER_T prDiscoverMsg; -+ P_P2P_CONNECTION_SETTINGS_T prConnSettings; -+ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ if (prData->flags == P2P_STOP_DISCOVERY) { -+ prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T)); -+ -+ if (!prMsgHdr) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF); -+ } else if (prData->flags == P2P_START_DISCOVERY) { -+ -+ /* retrieve IE for Probe Response */ -+ if (prReqDeviceType->probe_rsp_len > 0) { -+ if (prReqDeviceType->probe_rsp_len <= MAX_IE_LENGTH) { -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[2], prReqDeviceType->probe_rsp_ie, -+ prReqDeviceType->probe_rsp_len)) { -+ return -EFAULT; -+ } -+ prGlueInfo->prP2PInfo->u2WSCIELen[2] = prReqDeviceType->probe_rsp_len; -+ } else { -+ return -E2BIG; -+ } -+ } -+ -+ /* retrieve IE for Probe Request */ -+ if (prReqDeviceType->probe_req_len > 0) { -+ if (prReqDeviceType->probe_req_len <= MAX_IE_LENGTH) { -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[1], prReqDeviceType->probe_req_ie, -+ prReqDeviceType->probe_req_len)) { -+ return -EFAULT; -+ } -+ prGlueInfo->prP2PInfo->u2WSCIELen[1] = prReqDeviceType->probe_req_len; -+ } else { -+ return -E2BIG; -+ } -+ } -+ /* update IE for Probe Request */ -+ -+ if (prReqDeviceType->scan_type == P2P_LISTEN) { -+ /* update listening parameter */ -+ -+ /* @TODO: update prConnSettings for Probe Response IE */ -+ } else { -+ /* indicate P2P-FSM with MID_MNY_P2P_DEVICE_DISCOVERY */ -+ prDiscoverMsg = (P_MSG_P2P_DEVICE_DISCOVER_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, -+ sizeof(MSG_P2P_DEVICE_DISCOVER_T)); -+ -+ if (!prDiscoverMsg) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ prDiscoverMsg->rMsgHdr.eMsgId = MID_MNY_P2P_DEVICE_DISCOVERY; -+ prDiscoverMsg->u4DevDiscoverTime = 0; /* unlimited */ -+ prDiscoverMsg->fgIsSpecificType = TRUE; -+ prDiscoverMsg->rTargetDeviceType.u2CategoryID = -+ *(PUINT_16) (&(prReqDeviceType->pri_device_type[0])); -+ prDiscoverMsg->rTargetDeviceType.u2SubCategoryID = -+ *(PUINT_16) (&(prReqDeviceType->pri_device_type[6])); -+ COPY_MAC_ADDR(prDiscoverMsg->aucTargetDeviceID, aucNullAddr); -+ -+ /* @FIXME: parameter to be refined, where to pass IE buffer ? */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDiscoverMsg, MSG_SEND_METHOD_BUF); -+ } -+ } else { -+ return -EINVAL; -+ } -+#endif -+ -+ return 0; -+} /* end of mtk_p2p_wext_start_stop_discovery() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Setting parameters not support. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_invitation_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int i4Status = 0; -+#if 0 -+ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ P_IW_P2P_IOCTL_INVITATION_STRUCT prIoctlInvitation = (P_IW_P2P_IOCTL_INVITATION_STRUCT) NULL; -+ -+ do { -+ if ((prDev == NULL) || (extra == NULL)) { -+ ASSERT(FALSE); -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ prIoctlInvitation = (P_IW_P2P_IOCTL_INVITATION_STRUCT) extra; -+ -+ if (prGlueInfo == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ if (prAdapter == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ if (prIoctlInvitation->ucReinvoke == 1) { -+ /* TODO: Set Group ID */ -+ p2pFuncSetGroupID(prAdapter, prIoctlInvitation->aucGroupID, prIoctlInvitation->aucSsid, -+ prIoctlInvitation->u4SsidLen); -+ } -+ -+ else { -+ P_MSG_P2P_INVITATION_REQUEST_T prMsgP2PInvitationReq = (P_MSG_P2P_INVITATION_REQUEST_T) NULL; -+ -+ /* TODO: Do Invitation. */ -+ prMsgP2PInvitationReq = -+ (P_MSG_P2P_INVITATION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_INVITATION_REQUEST_T)); -+ if (!prMsgP2PInvitationReq) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ i4Status = -ENOMEM; -+ break; -+ } -+ -+ /* 1.2 fill message */ -+ kalMemCopy(prMsgP2PInvitationReq->aucDeviceID, prIoctlInvitation->aucDeviceID, MAC_ADDR_LEN); -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_wext_invitation_request: P2P Invitation Req\n"); -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PInvitationReq, MSG_SEND_METHOD_BUF); -+ -+ } -+ -+ } while (FALSE); -+#endif -+ -+ return i4Status; -+ -+} -+ -+/* mtk_p2p_wext_invitation_request */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Setting parameters not support. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_invitation_abort(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int i4Status = 0; -+#if 0 -+ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ P_IW_P2P_IOCTL_ABORT_INVITATION prIoctlInvitationAbort = (P_IW_P2P_IOCTL_ABORT_INVITATION) NULL; -+ -+ UINT_8 bssid[MAC_ADDR_LEN]; -+ -+ do { -+ if ((prDev == NULL) || (extra == NULL)) { -+ ASSERT(FALSE); -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ prIoctlInvitationAbort = (P_IW_P2P_IOCTL_ABORT_INVITATION) extra; -+ -+ if (prGlueInfo == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ if (prAdapter == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ P_MSG_P2P_INVITATION_REQUEST_T prMsgP2PInvitationAbort = (P_MSG_P2P_INVITATION_REQUEST_T) NULL; -+ -+ prMsgP2PInvitationAbort = -+ (P_MSG_P2P_INVITATION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_INVITATION_REQUEST_T)); -+ -+ if (!prMsgP2PInvitationAbort) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ i4Status = -ENOMEM; -+ break; -+ } -+ -+ /* 1.2 fill message */ -+ kalMemCopy(prMsgP2PInvitationAbort->aucDeviceID, prIoctlInvitationAbort->dev_addr, -+ MAC_ADDR_LEN); -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_wext_invitation_request: P2P Invitation Req\n"); -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PInvitationAbort, MSG_SEND_METHOD_BUF); -+ -+ -+ } while (FALSE); -+#endif -+ -+ return i4Status; -+ -+} -+ -+/* mtk_p2p_wext_invitation_abort */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief To override p2p interface address -+ * -+ * \param[in] prDev Net device requested. -+ * \param[in] addr Pointer to address -+ * -+ * \retval 0 For success. -+ * \retval -E2BIG For user's buffer size is too small. -+ * \retval -EFAULT For fail. -+ * -+ */ -+/*----------------------------------------------------------------------------*/ -+int p2pSetMACAddress(IN struct net_device *prDev, void *addr) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* @FIXME */ -+ return eth_mac_addr(prDev, addr); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set encryption cipher suite -+* -+* \param[in] prDev Net device requested. -+* \param[out] -+* -+* \retval 0 Success. -+* \retval -EINVAL Invalid parameter -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_auth(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_param *prAuth = (struct iw_param *)wrqu; -+ -+ ASSERT(prDev); -+ ASSERT(prAuth); -+ if (FALSE == GLUE_CHK_PR2(prDev, prAuth)) -+ return -EINVAL; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ /* Save information to glue info and process later when ssid is set. */ -+ switch (prAuth->flags & IW_AUTH_INDEX) { -+ case IW_AUTH_WPA_VERSION: -+ break; -+ case IW_AUTH_CIPHER_PAIRWISE: -+ prGlueInfo->prP2PInfo->u4CipherPairwise = prAuth->value; -+ break; -+ case IW_AUTH_CIPHER_GROUP: -+ case IW_AUTH_KEY_MGMT: -+ case IW_AUTH_TKIP_COUNTERMEASURES: -+ case IW_AUTH_DROP_UNENCRYPTED: -+ case IW_AUTH_80211_AUTH_ALG: -+ case IW_AUTH_WPA_ENABLED: -+ case IW_AUTH_RX_UNENCRYPTED_EAPOL: -+ case IW_AUTH_ROAMING_CONTROL: -+ case IW_AUTH_PRIVACY_INVOKED: -+ default: -+ /* @TODO */ -+ break; -+ } -+ -+ return 0; -+} /* end of mtk_p2p_wext_set_auth() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set encryption cipher and key. -+* -+* \param[in] prDev Net device requested. -+* \param[out] prIfReq Pointer to ifreq structure, content is copied back to -+* user space buffer in gl_iwpriv_table. -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note Securiry information is stored in pEnc. -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_key(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int ret = 0; -+ struct iw_encode_ext *prIWEncExt; -+ struct iw_point *prEnc; -+ char *prExtraBuf = NULL; -+ UINT_32 u4ExtraSize = 0; -+ UINT_8 keyStructBuf[100]; -+ P_PARAM_REMOVE_KEY_T prRemoveKey = (P_PARAM_REMOVE_KEY_T) keyStructBuf; -+ P_PARAM_KEY_T prKey = (P_PARAM_KEY_T) keyStructBuf; -+ P_GLUE_INFO_T prGlueInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ do { -+ if (wrqu->encoding.pointer) { -+ u4ExtraSize = wrqu->encoding.length; -+ /*need confirm u4ExtraSize > 0 but is not very large*/ -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ /* here should set prExtraBuf default value */ -+ memset(prExtraBuf, 0, u4ExtraSize); -+ if (copy_from_user(prExtraBuf, wrqu->encoding.pointer, wrqu->encoding.length)) { -+ ret = -EFAULT; -+ break; -+ } -+ } else if (wrqu->encoding.length != 0) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ prEnc = &wrqu->encoding; -+ /* here, need confirm (struct iw_encode_ext) < u4ExtraSize */ -+ prIWEncExt = (struct iw_encode_ext *)prExtraBuf; -+ -+ if (GLUE_CHK_PR3(prDev, prEnc, prExtraBuf) != TRUE) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ memset(keyStructBuf, 0, sizeof(keyStructBuf)); -+ -+ if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { /* Key Removal */ -+ prRemoveKey->u4Length = sizeof(*prRemoveKey); -+ memcpy(prRemoveKey->arBSSID, prIWEncExt->addr.sa_data, 6); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRemoveP2PKey, -+ prRemoveKey, -+ prRemoveKey->u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ ret = -EFAULT; -+ } else { -+ if (prIWEncExt->alg == IW_ENCODE_ALG_CCMP) { -+ /* KeyID */ -+ prKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? -+ ((prEnc->flags & IW_ENCODE_INDEX) - 1) : 0; -+ if (prKey->u4KeyIndex <= 3) { -+ /* bit(31) and bit(30) are shared by pKey and pRemoveKey */ -+ /* Tx Key Bit(31) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) -+ prKey->u4KeyIndex |= 0x1UL << 31; -+ -+ /* Pairwise Key Bit(30) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { -+ /* group key */ -+ } else { -+ /* pairwise key */ -+ prKey->u4KeyIndex |= 0x1UL << 30; -+ } -+ -+ /* Rx SC Bit(29) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { -+ prKey->u4KeyIndex |= 0x1UL << 29; -+ memcpy(&prKey->rKeyRSC, prIWEncExt->rx_seq, -+ IW_ENCODE_SEQ_MAX_SIZE); -+ } -+ -+ /* BSSID */ -+ memcpy(prKey->arBSSID, prIWEncExt->addr.sa_data, 6); -+ memcpy(prKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len); -+ -+ prKey->u4KeyLength = prIWEncExt->key_len; -+ prKey->u4Length = -+ ((ULONG)&(((P_PARAM_KEY_T) 0)->aucKeyMaterial)) + -+ prKey->u4KeyLength; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAddP2PKey, -+ prKey, -+ prKey->u4Length, -+ FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ ret = -EFAULT; -+ } else { -+ ret = -EINVAL; -+ } -+ } else { -+ ret = -EINVAL; -+ } -+ } -+ -+ } while (FALSE); -+ -+ if (prExtraBuf) { -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ } -+ -+ return ret; -+} /* end of mtk_p2p_wext_set_key() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief set the p2p gc power mode -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_powermode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ /* printk("set_powermode = %d, value = %d\n", wrqu->power.disabled, wrqu->power.value); */ -+ struct iw_param *prPower = (struct iw_param *)&wrqu->power; -+#if 1 -+ PARAM_POWER_MODE ePowerMode; -+ INT_32 i4PowerValue; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prPower); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n", */ -+ /* prPower->value, prPower->disabled, prPower->flags); */ -+ -+ if (prPower->disabled) { -+ ePowerMode = Param_PowerModeCAM; -+ } else { -+ i4PowerValue = prPower->value; -+#if WIRELESS_EXT < 21 -+ i4PowerValue /= 1000000; -+#endif -+ if (i4PowerValue == 0) { -+ ePowerMode = Param_PowerModeCAM; -+ } else if (i4PowerValue == 1) { -+ ePowerMode = Param_PowerModeMAX_PSP; -+ } else if (i4PowerValue == 2) { -+ ePowerMode = Param_PowerModeFast_PSP; -+ } else { -+ DBGLOG(P2P, ERROR, "%s(): unsupported power management mode value = %d.\n", -+ __func__, prPower->value); -+ -+ return -EINVAL; -+ } -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus); */ -+ return -EFAULT; -+ } -+#endif -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief get the p2p gc power mode -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_powermode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ /* printk("mtk_p2p_wext_get_powermode\n"); */ -+ /* wrqu->power.disabled = 0; */ -+ /* wrqu->power.value = 1; */ -+ -+ struct iw_param *prPower = (struct iw_param *)&wrqu->power; -+ PARAM_POWER_MODE ePowerMode = Param_PowerModeMax; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prPower); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) -+ return -EINVAL; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ ASSERT(prGlueInfo); -+ -+#if 1 -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryP2pPowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), TRUE, FALSE, FALSE, TRUE, &u4BufLen); -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryP2pPowerSaveProfile, &ePowerMode, sizeof(ePowerMode), &u4BufLen); -+#endif -+ -+ prPower->value = 0; -+ prPower->disabled = 1; -+ -+ if (Param_PowerModeCAM == ePowerMode) { -+ prPower->value = 0; -+ prPower->disabled = 1; -+ } else if (Param_PowerModeMAX_PSP == ePowerMode) { -+ prPower->value = 1; -+ prPower->disabled = 0; -+ } else if (Param_PowerModeFast_PSP == ePowerMode) { -+ prPower->value = 2; -+ prPower->disabled = 0; -+ } -+ -+ prPower->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE; -+#if WIRELESS_EXT < 21 -+ prPower->value *= 1000000; -+#endif -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_CFG_DEVICE) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_local_dev_info(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_CFG_DEVICE_TYPE prDeviceCfg = (P_IW_P2P_CFG_DEVICE_TYPE) extra; -+ P_P2P_CONNECTION_SETTINGS_T prConnSettings; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ /* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T)NULL; */ -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ /* update connection settings for P2P-FSM */ -+ /* 1. update SSID */ -+ if (prDeviceCfg->ssid_len > ELEM_MAX_LEN_SSID) -+ prConnSettings->ucSSIDLen = ELEM_MAX_LEN_SSID; -+ else -+ prConnSettings->ucSSIDLen = prDeviceCfg->ssid_len; -+ -+ if (copy_from_user(prConnSettings->aucSSID, prDeviceCfg->ssid, prConnSettings->ucSSIDLen)) -+ return -EFAULT; -+ /* 2. update device type (WPS IE) */ -+ kalMemCopy(&(prConnSettings->rPrimaryDevTypeBE), &(prDeviceCfg->pri_device_type), sizeof(DEVICE_TYPE_T)); -+#if P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT -+ kalMemCopy(&(prConnSettings->arSecondaryDevTypeBE[0]), &(prDeviceCfg->snd_device_type), sizeof(DEVICE_TYPE_T)); -+#endif -+ -+ /* 3. update device name */ -+ if (prDeviceCfg->device_name_len > WPS_ATTRI_MAX_LEN_DEVICE_NAME) -+ prConnSettings->ucDevNameLen = WPS_ATTRI_MAX_LEN_DEVICE_NAME; -+ else -+ prConnSettings->ucDevNameLen = prDeviceCfg->device_name_len; -+ if (copy_from_user(prConnSettings->aucDevName, prDeviceCfg->device_name, prConnSettings->ucDevNameLen)) -+ return -EFAULT; -+ /* 4. update GO intent */ -+ prConnSettings->ucGoIntent = prDeviceCfg->intend; -+ -+ /* Preferred channel bandwidth */ -+ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = prDeviceCfg->ch_width ? CONFIG_BW_20_40M : CONFIG_BW_20M; -+ prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = prDeviceCfg->ch_width ? CONFIG_BW_20_40M : CONFIG_BW_20M; -+ -+#if 0 -+ /* 1. switch P2P-FSM on */ -+ /* 1.1 allocate for message */ -+ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ -+ if (!prFuncSwitch) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ /* 1.2 fill message */ -+ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ prFuncSwitch->fgIsFuncOn = TRUE; -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF); -+#endif -+ return 0; -+} /* end of mtk_p2p_wext_set_local_dev_info() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief I/O Control handler for both -+ * IOC_P2P_START_STOP_DISCOVERY & SIOCGIWSCAN -+ * -+ * \param[in] prDev Net device requested. -+ * \param[inout] wrqu Pointer to iwreq_data -+ * -+ * \retval 0 Success. -+ * \retval -EFAULT Setting parameters to driver fail. -+ * \retval -EOPNOTSUPP Key size not supported. -+ * -+ * \note -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_discovery_results(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ struct iw_event iwe; -+ char *current_ev = extra; -+ UINT_32 i; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ P_P2P_INFO_T prP2PInfo = (P_P2P_INFO_T) NULL; -+ P_EVENT_P2P_DEV_DISCOVER_RESULT_T prTargetResult = (P_EVENT_P2P_DEV_DISCOVER_RESULT_T) NULL; -+ P_PARAM_VARIABLE_IE_T prDesiredIE = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prP2PInfo = prAdapter->prP2pInfo; -+ -+ for (i = 0; i < prP2PInfo->u4DeviceNum; i++) { -+ prTargetResult = &prP2PInfo->arP2pDiscoverResult[i]; -+ -+ /* SIOCGIWAP */ -+ iwe.cmd = SIOCGIWAP; -+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER; -+ memcpy(iwe.u.ap_addr.sa_data, prTargetResult->aucInterfaceAddr, 6); -+ -+ current_ev = iwe_stream_add_event(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN); -+ -+ /* SIOCGIWESSID */ -+ iwe.cmd = SIOCGIWESSID; -+ iwe.u.data.flags = 1; -+ iwe.u.data.length = prTargetResult->u2NameLength; -+ -+ current_ev = iwe_stream_add_point(info, current_ev, -+ extra + IW_SCAN_MAX_DATA, &iwe, prTargetResult->aucName); -+ -+ /* IWEVGENIE for WPA IE */ -+ if (prTargetResult->u2IELength <= 600 && wextSrchDesiredWPAIE(prTargetResult->pucIeBuf, -+ prTargetResult->u2IELength, -+ 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ -+ iwe.cmd = IWEVGENIE; -+ iwe.u.data.flags = 1; -+ iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ -+ current_ev = iwe_stream_add_point(info, current_ev, -+ extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE); -+ } -+#if CFG_SUPPORT_WPS -+ -+ /* IWEVGENIE for WPS IE */ -+ if ((prTargetResult->u2IELength <= 600) && wextSrchDesiredWPSIE(prTargetResult->pucIeBuf, -+ prTargetResult->u2IELength, -+ 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ -+ iwe.cmd = IWEVGENIE; -+ iwe.u.data.flags = 1; -+ iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ -+ current_ev = iwe_stream_add_point(info, current_ev, -+ extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE); -+ } -+#endif -+ -+ /* IWEVGENIE for RSN IE */ -+ if ((prTargetResult->u2IELength <= 600) && wextSrchDesiredWPAIE(prTargetResult->pucIeBuf, -+ prTargetResult->u2IELength, -+ 0x30, (PUINT_8 *) &prDesiredIE)) { -+ -+ iwe.cmd = IWEVGENIE; -+ iwe.u.data.flags = 1; -+ iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ -+ current_ev = iwe_stream_add_point(info, current_ev, -+ extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE); -+ } -+ -+ /* IOC_P2P_GO_WSC_IE */ -+#if 1 -+ /* device capability */ -+ if (1) { -+ UINT_8 data[40]; -+ -+ iwe.cmd = IWEVCUSTOM; -+ iwe.u.data.flags = 0; -+ iwe.u.data.length = 9 + sizeof("p2p_cap="); -+ if (iwe.u.data.length > 40) -+ iwe.u.data.length = 40; -+ -+ snprintf(data, iwe.u.data.length, "p2p_cap=%02x%02x%02x%02x%c", -+ prTargetResult->ucDeviceCapabilityBitmap, prTargetResult->ucGroupCapabilityBitmap, -+ (UINT_8) prTargetResult->u2ConfigMethod, -+ (UINT_8) (prTargetResult->u2ConfigMethod >> 8), '\0'); -+ current_ev = -+ iwe_stream_add_point(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, (char *)data); -+ -+ /* printk("%s\n", data); */ -+ kalMemZero(data, 40); -+ -+ iwe.cmd = IWEVCUSTOM; -+ iwe.u.data.flags = 0; -+ iwe.u.data.length = 13 + sizeof("p2p_dev_type="); -+ if (iwe.u.data.length > 40) -+ iwe.u.data.length = 40; -+ -+ snprintf(data, iwe.u.data.length, "p2p_dev_type=%02x%02x%02x%02x%02x%02x%c", -+ (UINT_8) prTargetResult->rPriDevType.u2CategoryID, -+ (UINT_8) prTargetResult->rPriDevType.u2SubCategoryID, -+ (UINT_8) prTargetResult->arSecDevType[0].u2CategoryID, -+ (UINT_8) prTargetResult->arSecDevType[0].u2SubCategoryID, -+ (UINT_8) prTargetResult->arSecDevType[1].u2CategoryID, -+ (UINT_8) prTargetResult->arSecDevType[1].u2SubCategoryID, '\0'); -+ current_ev = -+ iwe_stream_add_point(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, (char *)data); -+ /* printk("%s\n", data); */ -+ -+ kalMemZero(data, 40); -+ -+ iwe.cmd = IWEVCUSTOM; -+ iwe.u.data.flags = 0; -+ iwe.u.data.length = 17 + sizeof("p2p_grp_bssid="); -+ if (iwe.u.data.length > 40) -+ iwe.u.data.length = 40; -+ -+ snprintf(data, iwe.u.data.length, "p2p_grp_bssid= %pM %c", -+ prTargetResult->aucBSSID, '\0'); -+ current_ev = iwe_stream_add_point(info, current_ev, -+ extra + IW_SCAN_MAX_DATA, &iwe, (char *)data); -+ /* printk("%s\n", data); */ -+ -+ } -+#endif -+ } -+ -+ /* Length of data */ -+ wrqu->data.length = (current_ev - extra); -+ wrqu->data.flags = 0; -+ -+ return 0; -+} /* end of mtk_p2p_wext_discovery_results() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_WSC_BEACON_PROBE_RSP_IE) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_wsc_ie(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_HOSTAPD_PARAM prHostapdParam = (P_IW_P2P_HOSTAPD_PARAM) extra; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ if (prHostapdParam->len > 0) { -+ if (prHostapdParam->len <= MAX_WSC_IE_LENGTH) { -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[0], prHostapdParam->data, prHostapdParam->len)) { -+ return -EFAULT; -+ } -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[2], prHostapdParam->data, prHostapdParam->len)) { -+ return -EFAULT; -+ } -+ } else { -+ return -E2BIG; -+ } -+ } -+ -+ prGlueInfo->prP2PInfo->u2WSCIELen[0] = prHostapdParam->len; -+ prGlueInfo->prP2PInfo->u2WSCIELen[2] = prHostapdParam->len; -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* @TODO: send message to P2P-FSM */ -+ -+ return 0; -+} /* end of mtk_p2p_wext_wsc_ie() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_CONNECT_DISCONNECT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_connect_disconnect(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+/* P_IW_P2P_CONNECT_DEVICE prConnectDevice = (P_IW_P2P_CONNECT_DEVICE)extra; */ -+/* P_MSG_HDR_T prMsgHdr; */ -+/* P_MSG_P2P_CONNECTION_REQUEST_T prMsgP2PConnReq; */ -+/* P_MSG_P2P_CONNECTION_ABORT_T prMsgP2PConnAbt; */ -+/* UINT_8 aucBCAddr[] = BC_MAC_ADDR; */ -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ if (prData->flags == P2P_CONNECT) { -+#if 0 -+ /* indicate P2P-FSM with MID_MNY_P2P_CONNECTION_REQ */ -+ prMsgP2PConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, -+ sizeof(MSG_P2P_CONNECTION_REQUEST_T)); -+ -+ if (!prMsgP2PConnReq) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnReq, MSG_SEND_METHOD_BUF); -+#endif -+ } else if (prData->flags == P2P_DISCONNECT) { -+#if 0 -+ /* indicate P2P-FSM with MID_MNY_P2P_CONNECTION_ABORT */ -+ prMsgP2PConnAbt = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_ABORT_T)); -+ -+ if (!prMsgP2PConnAbt) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ COPY_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, prConnectDevice->sta_addr); -+ -+ prMsgP2PConnAbt->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnAbt, MSG_SEND_METHOD_BUF); -+#endif -+ } else { -+ return -EINVAL; -+ } -+ -+ return 0; -+} /* end of mtk_p2p_wext_connect_disconnect() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_PASSWORD_READY) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_password_ready(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_PASSWORD_READY prPasswordReady = (P_IW_P2P_PASSWORD_READY) extra; -+ P_P2P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ /* retrieve IE for Probe Request */ -+ if (prPasswordReady->probe_req_len > 0) { -+ if (prPasswordReady->probe_req_len <= MAX_WSC_IE_LENGTH) { -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[1], prPasswordReady->probe_req_ie, -+ prPasswordReady->probe_req_len)) { -+ return -EFAULT; -+ } -+ } else { -+ return -E2BIG; -+ } -+ } -+ -+ prGlueInfo->prP2PInfo->u2WSCIELen[1] = prPasswordReady->probe_req_len; -+ -+ /* retrieve IE for Probe Response */ -+ if (prPasswordReady->probe_rsp_len > 0) { -+ if (prPasswordReady->probe_rsp_len <= MAX_WSC_IE_LENGTH) { -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[2], prPasswordReady->probe_rsp_ie, -+ prPasswordReady->probe_rsp_len)) { -+ return -EFAULT; -+ } -+ } else { -+ return -E2BIG; -+ } -+ } -+ -+ prGlueInfo->prP2PInfo->u2WSCIELen[2] = prPasswordReady->probe_rsp_len; -+ -+ switch (prPasswordReady->active_config_method) { -+ case 1: -+ prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_PUSH_BUTTON; -+ break; -+ case 2: -+ prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_KEYPAD; -+ break; -+ case 3: -+ prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_DISPLAY; -+ break; -+ default: -+ break; -+ } -+ -+ prConnSettings->fgIsPasswordIDRdy = TRUE; -+ return 0; -+} /* end of mtk_p2p_wext_password_ready() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_GET_REQ_DEVICE_INFO) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_request_dev_info(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_DEVICE_REQ prDeviceReq = (P_IW_P2P_DEVICE_REQ) extra; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* specify data length */ -+ wrqu->data.length = sizeof(IW_P2P_DEVICE_REQ); -+ -+ /* copy to upper-layer supplied buffer */ -+ kalMemCopy(prDeviceReq->name, prGlueInfo->prP2PInfo->aucConnReqDevName, -+ prGlueInfo->prP2PInfo->u4ConnReqNameLength); -+ prDeviceReq->name_len = prGlueInfo->prP2PInfo->u4ConnReqNameLength; -+ prDeviceReq->name[prDeviceReq->name_len] = '\0'; -+ COPY_MAC_ADDR(prDeviceReq->device_addr, prGlueInfo->prP2PInfo->rConnReqPeerAddr); -+ prDeviceReq->device_type = prGlueInfo->prP2PInfo->ucConnReqDevType; -+ prDeviceReq->config_method = prGlueInfo->prP2PInfo->i4ConnReqConfigMethod; -+ prDeviceReq->active_config_method = prGlueInfo->prP2PInfo->i4ConnReqActiveConfigMethod; -+ -+ return 0; -+} /* end of mtk_p2p_wext_request_dev_info() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_invitation_indicate(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_IOCTL_INVITATION_INDICATE prInvIndicate = (P_IW_P2P_IOCTL_INVITATION_INDICATE) extra; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* specify data length */ -+ wrqu->data.length = sizeof(IW_P2P_IOCTL_INVITATION_INDICATE); -+ -+ /* copy to upper-layer supplied buffer */ -+ kalMemCopy(prInvIndicate->dev_name, prGlueInfo->prP2PInfo->aucConnReqDevName, -+ prGlueInfo->prP2PInfo->u4ConnReqNameLength); -+ kalMemCopy(prInvIndicate->group_bssid, prGlueInfo->prP2PInfo->rConnReqGroupAddr, MAC_ADDR_LEN); -+ prInvIndicate->name_len = prGlueInfo->prP2PInfo->u4ConnReqNameLength; -+ prInvIndicate->dev_name[prInvIndicate->name_len] = '\0'; -+ COPY_MAC_ADDR(prInvIndicate->dev_addr, prGlueInfo->prP2PInfo->rConnReqPeerAddr); -+ prInvIndicate->config_method = prGlueInfo->prP2PInfo->i4ConnReqConfigMethod; -+ prInvIndicate->operating_channel = prGlueInfo->prP2PInfo->ucOperatingChnl; -+ prInvIndicate->invitation_type = prGlueInfo->prP2PInfo->ucInvitationType; -+ -+ return 0; -+} /* end of mtk_p2p_wext_invitation_indicate() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_invitation_status(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_IOCTL_INVITATION_STATUS prInvStatus = (P_IW_P2P_IOCTL_INVITATION_STATUS) extra; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* specify data length */ -+ wrqu->data.length = sizeof(IW_P2P_IOCTL_INVITATION_STATUS); -+ -+ /* copy to upper-layer supplied buffer */ -+ prInvStatus->status_code = prGlueInfo->prP2PInfo->u4InvStatus; -+ -+ return 0; -+} /* end of mtk_p2p_wext_invitation_status() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief indicate an event to supplicant for device found -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* -+* \retval TRUE Success. -+* \retval FALSE Failure -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalP2PIndicateFound(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_DVC_FND"); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate IWEVP2PDVCFND event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+ return FALSE; -+} /* end of kalP2PIndicateFound() */ -+ -+int -+mtk_p2p_wext_set_network_address(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* @TODO: invoke wlan_p2p functions */ -+#if 0 -+ rStatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pNetworkAddress, -+ prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen); -+#endif -+ -+ return 0; -+ -+} -+ -+int -+mtk_p2p_wext_set_ps_profile(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* @TODO: invoke wlan_p2p functions */ -+#if 0 -+ rStatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pPowerSaveProfile, -+ prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen); -+#endif -+ -+ return 0; -+ -+} -+ -+int -+mtk_p2p_wext_set_pm_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* @TODO: invoke wlan_p2p functions */ -+#if 0 -+ rStatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pPowerSaveProfile, -+ prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen); -+#endif -+ -+ return 0; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Setting parameters not support. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_start_formation(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int i4Status = 0; -+ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+/* struct iw_point *prData = (struct iw_point*)&wrqu->data; */ -+ P_IW_P2P_IOCTL_START_FORMATION prIoctlStartFormation = (P_IW_P2P_IOCTL_START_FORMATION) NULL; -+ -+ do { -+ if ((prDev == NULL) || (extra == NULL)) { -+ ASSERT(FALSE); -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ prIoctlStartFormation = (P_IW_P2P_IOCTL_START_FORMATION) extra; -+ -+ if (prGlueInfo == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ if (prAdapter == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ } while (FALSE); -+ -+ return i4Status; -+ -+} -+ -+/* mtk_p2p_wext_start_formation */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Setting parameters not support. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_int(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int status = 0; -+ UINT_32 u4SubCmd = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 index; -+ INT_32 value; -+ PUINT_32 pu4IntBuf; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ UINT_32 u4Leng; -+ -+ ASSERT(prDev); -+ ASSERT(wrqu); -+ -+ /* printk("mtk_p2p_wext_set_int\n"); */ -+ pu4IntBuf = (PUINT_32) extra; -+ -+ if (FALSE == GLUE_CHK_PR2(prDev, wrqu)) -+ return -EINVAL; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; -+ prP2pFsmInfo = prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ u4SubCmd = (UINT_32) wrqu->mode; -+ index = pu4IntBuf[1]; -+ value = pu4IntBuf[2]; -+ -+ DBGLOG(P2P, INFO, "set parameter, u4SubCmd=%d idx=%d value=%d\n", (INT_16) u4SubCmd, (INT_16) index, value); -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_INT_P2P_SET: -+ switch (index) { -+ case 0: /* Listen CH */ -+ { -+ UINT_8 ucSuggestChnl = 0; -+ -+ prP2pConnSettings->ucListenChnl = value; -+ -+ /* 20110920 - frog: User configurations are placed in ConnSettings. */ -+ if (rlmFuncFindAvailableChannel -+ (prGlueInfo->prAdapter, value, &ucSuggestChnl, TRUE, TRUE)) { -+ prP2pSpecificBssInfo->ucListenChannel = value; -+ } else { -+ prP2pSpecificBssInfo->ucListenChannel = ucSuggestChnl; -+ } -+ -+ break; -+ } -+ case 1: /* P2p mode */ -+ break; -+ case 4: /* Noa duration */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, -+ (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 5: /* Noa interval */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, -+ (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 6: /* Noa count */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; -+ status = -+ mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); -+ break; -+ case 100: /* Oper CH */ -+ /* 20110920 - frog: User configurations are placed in ConnSettings. */ -+ prP2pConnSettings->ucOperatingChnl = value; -+ break; -+ case 101: /* Local config Method, for P2P SDK */ -+ /* prP2pConnSettings->u2LocalConfigMethod; */ -+ break; -+ case 102: /* Sigma P2p reset */ -+ kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); -+ /* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */ -+ break; -+ case 103: /* WPS MODE */ -+ kalP2PSetWscMode(prGlueInfo, value); -+ break; -+ case 104: /* P2p send persence, duration */ -+ break; -+ case 105: /* P2p send persence, interval */ -+ break; -+ case 106: /* P2P set sleep */ -+ value = 1; -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, -+ &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ break; -+ case 107: /* P2P set opps, CTWindowl */ -+ prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; -+ status = -+ mtk_p2p_wext_set_oppps_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rOppPsParam); -+ break; -+ case 108: /* p2p_set_power_save */ -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, -+ &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ -+ break; -+ -+ default: -+ break; -+ } -+ break; -+ default: -+ break; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_SET_STRUCT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_struct(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int status = 0; -+ UINT_32 u4SubCmd = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = NULL; -+ -+ ASSERT(prDev); -+ ASSERT(wrqu); -+ -+ if (FALSE == GLUE_CHK_PR2(prDev, wrqu)) -+ return -EINVAL; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ u4SubCmd = (UINT_32) wrqu->data.flags; -+ -+ kalMemZero(&prGlueInfo->prP2PInfo->aucOidBuf[0], sizeof(prGlueInfo->prP2PInfo->aucOidBuf)); -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_OID: -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), wrqu->data.pointer, wrqu->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ -+ if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, wrqu->data.length)) -+ DBGLOG(P2P, INFO, "extra buffer is valid\n"); -+ else -+ DBGLOG(P2P, INFO, "extra 0x%p\n", extra); -+ -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_SEND_SD_RESPONSE: -+ status = mtk_p2p_wext_send_service_discovery_response(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ -+ case P2P_CMD_ID_SEND_SD_REQUEST: -+ status = mtk_p2p_wext_send_service_discovery_request(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ -+ case P2P_CMD_ID_TERMINATE_SD_PHASE: -+ status = mtk_p2p_wext_terminate_service_discovery_phase(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ -+ case P2P_CMD_ID_INVITATION: -+ if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_INVITATION_STRUCT)) { -+ /* Do nothing */ -+ /* status = mtk_p2p_wext_invitation_request(prDev, info, wrqu, -+ (char *)(prP2PReq->aucBuffer)); */ -+ } -+ break; -+ -+ case P2P_CMD_ID_INVITATION_ABORT: -+ if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_ABORT_INVITATION)) { -+ /* Do nothing */ -+ /* status = mtk_p2p_wext_invitation_abort(prDev, info, wrqu, -+ (char *)(prP2PReq->aucBuffer)); */ -+ } -+ break; -+ -+ case P2P_CMD_ID_START_FORMATION: -+ if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_START_FORMATION)) -+ status = mtk_p2p_wext_start_formation(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ } -+ -+ break; -+#if CFG_SUPPORT_ANTI_PIRACY -+ case PRIV_SEC_CHECK_OID: -+ if (wrqu->data.length > 256) { -+ status = -EOPNOTSUPP; -+ break; -+ } -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), wrqu->data.pointer, wrqu->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ -+ if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), extra, wrqu->data.length)) -+ DBGLOG(P2P, INFO, "extra buffer is valid\n"); -+ else -+ DBGLOG(P2P, INFO, "extra 0x%p\n", extra); -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucSecCheck[0])); -+ -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_SEC_CHECK: -+ status = mtk_p2p_wext_set_sec_check_request(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ } -+ break; -+#endif -+ case PRIV_CMD_P2P_VERSION: -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), wrqu->data.pointer, wrqu->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ -+ if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, wrqu->data.length)) -+ DBGLOG(P2P, INFO, "extra buffer is valid\n"); -+ else -+ DBGLOG(P2P, INFO, "extra 0x%p\n", extra); -+ -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_P2P_VERSION: -+ status = mtk_p2p_wext_set_p2p_version(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ break; -+ } -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ break; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_struct(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int status = 0; -+ UINT_32 u4SubCmd = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = NULL; -+ -+ ASSERT(prDev); -+ ASSERT(wrqu); -+ -+ if (!prDev || !wrqu) { -+ DBGLOG(P2P, WARN, "%s(): invalid param(0x%p, 0x%p)\n", __func__, prDev, wrqu); -+ return -EINVAL; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ u4SubCmd = (UINT_32) wrqu->data.flags; -+ -+ kalMemZero(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), sizeof(prGlueInfo->prP2PInfo->aucOidBuf)); -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_OID: -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { -+ DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__); -+ return -EFAULT; -+ } -+ -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); -+ -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_GET_SD_REQUEST: -+ status = mtk_p2p_wext_get_service_discovery_request(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ -+ case P2P_CMD_ID_GET_SD_RESPONSE: -+ status = mtk_p2p_wext_get_service_discovery_response(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ -+ case P2P_CMD_ID_INVITATION_INDICATE: -+ { -+ status = -+ mtk_p2p_wext_invitation_indicate(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); -+ prP2PReq->outBufferLength = wrqu->data.length; -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ wrqu->data.length + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } else { -+ return 0; -+ } -+ break; -+ } -+ case P2P_CMD_ID_INVITATION_STATUS: -+ { -+ status = -+ mtk_p2p_wext_invitation_status(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); -+ prP2PReq->outBufferLength = wrqu->data.length; -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ wrqu->data.length + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } else { -+ return 0; -+ } -+ break; -+ } -+ case P2P_CMD_ID_GET_CH_LIST: -+ { -+ UINT_16 i; -+ UINT_8 NumOfChannel = 50; -+ RF_CHANNEL_INFO_T aucChannelList[50]; -+ UINT_8 ucMaxChannelNum = 50; -+ PUINT_8 pucChnlList = (PUINT_8) prP2PReq->aucBuffer; -+ -+ kalGetChnlList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, aucChannelList); -+ if (NumOfChannel > 50) -+ NumOfChannel = 50; -+ prP2PReq->outBufferLength = NumOfChannel; -+ /*here must confirm NumOfChannel < 16, for prP2PReq->aucBuffer 16 byte*/ -+ if (NumOfChannel >= 15) { -+ /*DBGLOG(P2P, ERROR, "channel num > 15\n", __func__);*/ -+ ASSERT(FALSE); -+ } -+ -+ for (i = 0; i < NumOfChannel; i++) { -+#if 0 -+ /* 20120208 frog: modify to avoid clockwork warning. */ -+ prP2PReq->aucBuffer[i] = aucChannelList[i].ucChannelNum; -+#else -+ *pucChnlList = aucChannelList[i].ucChannelNum; -+ pucChnlList++; -+#endif -+ } -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ NumOfChannel + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } else { -+ return 0; -+ } -+ break; -+ } -+ -+ case P2P_CMD_ID_GET_OP_CH: -+ { -+ prP2PReq->inBufferLength = 4; -+ -+ status = wlanoidQueryP2pOpChannel(prGlueInfo->prAdapter, -+ prP2PReq->aucBuffer, -+ prP2PReq->inBufferLength, &prP2PReq->outBufferLength); -+ -+ if (status == 0) { /* WLAN_STATUS_SUCCESS */ -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ prP2PReq->outBufferLength + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, -+ aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ } else { -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ } -+ break; -+ } -+ -+ default: -+ status = -EOPNOTSUPP; -+ } -+ -+ break; -+#if CFG_SUPPORT_ANTI_PIRACY -+ case PRIV_SEC_CHECK_OID: -+ if (wrqu->data.length > 256) { -+ status = -EOPNOTSUPP; -+ break; -+ } -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), -+ wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { -+ DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__); -+ return -EFAULT; -+ } -+ -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucSecCheck[0])); -+ -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_SEC_CHECK: -+ status = mtk_p2p_wext_get_sec_check_response(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ } -+ break; -+#endif -+ case PRIV_CMD_P2P_VERSION: -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { -+ DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__); -+ return -EFAULT; -+ } -+ -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); -+ -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_P2P_VERSION: -+ status = mtk_p2p_wext_get_p2p_version(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ break; -+ } -+ -+ /* Copy queried data to user. */ -+ if (status == 0) { /* WLAN_STATUS_SUCCESS */ -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ prP2PReq->outBufferLength + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ } -+ -+ else { -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ } -+ -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* getting service discovery request frame from driver -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_service_discovery_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen = 0; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidGetP2PSDRequest, -+ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ -+ prP2PReq->outBufferLength = u4QueryInfoLen; -+ -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } else { -+ return 0; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* getting service discovery response frame from driver -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_service_discovery_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen = 0; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidGetP2PSDResponse, -+ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ -+ prP2PReq->outBufferLength = u4QueryInfoLen; -+ -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ return 0; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* sending service discovery request frame -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_send_service_discovery_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSendP2PSDRequest, -+ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* sending service discovery response frame -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_send_service_discovery_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSendP2PSDResponse, -+ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_sec_check_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetSecCheckRequest, -+ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_sec_check_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen = 0; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(P2P, INFO, "mtk_p2p_wext_get_sec_check_response\n"); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidGetSecCheckResponse, -+ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ -+ prP2PReq->outBufferLength = u4QueryInfoLen; -+ -+ if (copy_to_user(wrqu->data.pointer, -+ prP2PReq->aucBuffer, u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ return 0; -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* terminating service discovery phase -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_terminate_service_discovery_phase(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2PTerminateSDPhase, -+ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_noa_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+ /* P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra; */ -+ P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(P2P, INFO, "mtk_p2p_wext_set_noa_param\n"); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetNoaParam, prNoaParam, /* prP2PReq->aucBuffer, */ -+ sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T), /* prP2PReq->inBufferLength, */ -+ FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_oppps_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+/* P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra; */ -+ P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(P2P, INFO, "mtk_p2p_wext_set_oppps_param\n"); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetOppPsParam, prOppPsParam, /* prP2PReq->aucBuffer, */ -+ sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T), /* prP2PReq->inBufferLength, */ -+ FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+int -+mtk_p2p_wext_set_p2p_version(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ UINT_32 u4SetInfoLen; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2pSupplicantVersion, -+ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return rStatus; -+ -+} -+ -+/* mtk_p2p_wext_set_p2p_version */ -+ -+int -+mtk_p2p_wext_get_p2p_version(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryP2pVersion, -+ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return rStatus; -+ -+} /* mtk_p2p_wext_get_p2p_version */ -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ -+int -+mtk_p2p_wext_get_rssi(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ UINT_16 u2BufferSize = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Rssi; -+ struct iw_statistics *pStats = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ if (!prGlueInfo) { -+ rStatus = WLAN_STATUS_FAILURE; -+ goto stat_out; -+ } -+ -+ pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryP2pRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, TRUE, &u4QueryInfoLen); -+ -+ u2BufferSize = prData->length; -+ -+ if (u2BufferSize < sizeof(struct iw_statistics)) -+ return -E2BIG; -+ -+ if (copy_to_user(prData->pointer, pStats, sizeof(struct iw_statistics))) -+ rStatus = WLAN_STATUS_FAILURE; -+ -+stat_out: -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return rStatus; -+ -+} /* mtk_p2p_wext_get_rssi */ -+ -+struct iw_statistics *mtk_p2p_wext_get_wireless_stats(struct net_device *prDev) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_statistics *pStats = NULL; -+ INT_32 i4Rssi; -+ UINT_32 bufLen = 0; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ if (!prGlueInfo) -+ goto stat_out; -+ -+ pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats)); -+ -+ if (!prDev || !netif_carrier_ok(prDev)) { -+ /* network not connected */ -+ goto stat_out; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidQueryP2pRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, TRUE, &bufLen); -+ -+stat_out: -+ return pStats; -+} /* mtk_p2p_wext_get_wireless_stats */ -+ -+#endif /* CFG_SUPPORT_P2P_RSSI_QUERY */ -+ -+int -+mtk_p2p_wext_set_txpow(IN struct net_device *prDev, -+ IN struct iw_request_info *prIwrInfo, IN OUT union iwreq_data *prTxPow, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; -+#if 0 -+ P_MSG_P2P_FUNCTION_SWITCH_T prMsgFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) NULL; -+#endif -+ int i4Ret = 0; -+ -+ ASSERT(prDev); -+ ASSERT(prTxPow); -+ -+ do { -+ if ((!prDev) || (!prTxPow)) { -+ i4Ret = -EINVAL; -+ break; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ if (!prGlueInfo) { -+ i4Ret = -EINVAL; -+ break; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+#if 0 -+ prMsgFuncSwitch = -+ (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ if (!prMsgFuncSwitch) { -+ ASSERT(0); -+ return -ENOMEM; -+ } -+ -+ prMsgFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ -+ if (prTxPow->disabled) { -+ /* Dissolve. */ -+ prMsgFuncSwitch->fgIsFuncOn = FALSE; -+ } else { -+ -+ /* Re-enable function. */ -+ prMsgFuncSwitch->fgIsFuncOn = TRUE; -+ } -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgFuncSwitch, MSG_SEND_METHOD_BUF); -+#endif -+ -+ } while (FALSE); -+ -+ return i4Ret; -+} /* mtk_p2p_wext_set_txpow */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c -new file mode 100644 -index 0000000000000..4d71e0c59b05d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c -@@ -0,0 +1,1935 @@ -+/* -+** Id: @(#) gl_p2p_cfg80211.c@@ -+*/ -+ -+/*! \file gl_p2p_cfg80211.c -+ \brief Main routines of Linux driver interface for Wi-Fi Direct -+ using cfg80211 interface -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_p2p_cfg80211.c -+** -+** 01 30 2013 yuche.tsai -+** [ALPS00455459] [GN_WIFI]??wifi direct??????????? -+** Fix possible race condition under GO mode. -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 09 05 2012 wh.su -+** [ALPS00351547] [6577JB][WiFi direct]The 3rd device fail to establish p2p connection with GO sometimes -+** sync with the ICS code. -+** -+** 08 31 2012 yuche.tsai -+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected to AP previously, -+** one device reboots automatically with KE -+** Fix possible KE when concurrent & disconnect. -+** -+** 08 21 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 20 2012 yuche.tsai -+** NULL -+** Fix possible KE issue. -+** -+** 08 17 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 16 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 14 2012 yuche.tsai -+** NULL -+** Fix p2p bug find on ALPS.JB trunk. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Fix compile error for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add cfg80211 interface, which is to replace WE, for further extension -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "config.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "precomp.h" -+#include "gl_cfg80211.h" -+#include "gl_p2p_ioctl.h" -+ -+#ifdef __GNUC__ -+#pragma GCC diagnostic ignored "-Wformat" -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+BOOLEAN -+mtk_p2p_cfg80211func_channel_format_switch(IN struct ieee80211_channel *channel, -+ IN enum nl80211_channel_type channel_type, -+ IN P_RF_CHANNEL_INFO_T prRfChnlInfo, IN P_ENUM_CHNL_EXT_T prChnlSco); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+int mtk_p2p_cfg80211_add_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Rslt = -EINVAL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ P2P_PARAM_KEY_T rKey; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ kalMemZero(&rKey, sizeof(P2P_PARAM_KEY_T)); -+ -+ rKey.u4KeyIndex = key_index; -+ if (mac_addr) { -+ ether_addr_copy(rKey.arBSSID, mac_addr); -+ if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) && -+ (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) { -+ rKey.arBSSID[0] = 0xff; -+ rKey.arBSSID[1] = 0xff; -+ rKey.arBSSID[2] = 0xff; -+ rKey.arBSSID[3] = 0xff; -+ rKey.arBSSID[4] = 0xff; -+ rKey.arBSSID[5] = 0xff; -+ } -+ if (rKey.arBSSID[0] != 0xFF) { -+ rKey.u4KeyIndex |= BIT(31); -+ if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) || -+ (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00)) -+ rKey.u4KeyIndex |= BIT(30); -+ } else { -+ rKey.u4KeyIndex |= BIT(31); -+ } -+ } else { -+ rKey.arBSSID[0] = 0xff; -+ rKey.arBSSID[1] = 0xff; -+ rKey.arBSSID[2] = 0xff; -+ rKey.arBSSID[3] = 0xff; -+ rKey.arBSSID[4] = 0xff; -+ rKey.arBSSID[5] = 0xff; -+ rKey.u4KeyIndex |= BIT(31); /* ???? */ -+ } -+ if (params->key) { -+ /* rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE); */ -+ kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len); -+ } -+ rKey.u4KeyLength = params->key_len; -+ rKey.u4Length = ((ULONG)&(((P_P2P_PARAM_KEY_T) 0)->aucKeyMaterial)) + rKey.u4KeyLength; -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetAddP2PKey, &rKey, rKey.u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ if (rStatus == WLAN_STATUS_SUCCESS) -+ i4Rslt = 0; -+ -+ return i4Rslt; -+} -+ -+int mtk_p2p_cfg80211_get_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, -+ bool pairwise, -+ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *) -+) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} -+ -+int mtk_p2p_cfg80211_del_key(struct wiphy *wiphy, -+ struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ PARAM_REMOVE_KEY_T prRemoveKey; -+ INT_32 i4Rslt = -EINVAL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ i4Rslt = 0; -+ return i4Rslt; -+ } -+ -+ kalMemZero(&prRemoveKey, sizeof(PARAM_REMOVE_KEY_T)); -+ if (mac_addr) -+ memcpy(prRemoveKey.arBSSID, mac_addr, PARAM_MAC_ADDR_LEN); -+ prRemoveKey.u4KeyIndex = key_index; -+ prRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRemoveP2PKey, -+ &prRemoveKey, prRemoveKey.u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ -+ if (rStatus == WLAN_STATUS_SUCCESS) -+ i4Rslt = 0; -+ -+ return i4Rslt; -+} -+ -+int -+mtk_p2p_cfg80211_set_default_key(struct wiphy *wiphy, -+ struct net_device *netdev, u8 key_index, bool unicast, bool multicast) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_info *sinfo) -+{ -+ INT_32 i4RetRslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL; -+ P2P_STATION_INFO_T rP2pStaInfo; -+ -+ ASSERT(wiphy); -+ -+ do { -+ if ((wiphy == NULL) || (ndev == NULL) || (sinfo == NULL) || (mac == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_get_station\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ prP2pGlueInfo = prGlueInfo->prP2PInfo; -+ -+ sinfo->filled = 0; -+ -+ /* Get station information. */ -+ /* 1. Inactive time? */ -+ p2pFuncGetStationInfo(prGlueInfo->prAdapter, (PUINT_8)mac, &rP2pStaInfo); -+ -+ /* Inactive time. */ -+ sinfo->filled |= NL80211_STA_INFO_INACTIVE_TIME; -+ sinfo->inactive_time = rP2pStaInfo.u4InactiveTime; -+ sinfo->generation = prP2pGlueInfo->i4Generation; -+ -+ i4RetRslt = 0; -+ } while (FALSE); -+ -+ return i4RetRslt; -+} -+ -+int mtk_p2p_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL; -+ P_MSG_P2P_SCAN_REQUEST_T prMsgScanRequest = (P_MSG_P2P_SCAN_REQUEST_T) NULL; -+ UINT_32 u4MsgSize = 0, u4Idx = 0; -+ INT_32 i4RetRslt = -EINVAL; -+ P_RF_CHANNEL_INFO_T prRfChannelInfo = (P_RF_CHANNEL_INFO_T) NULL; -+ P_P2P_SSID_STRUCT_T prSsidStruct = (P_P2P_SSID_STRUCT_T) NULL; -+ struct ieee80211_channel *prChannel = NULL; -+ struct cfg80211_ssid *prSsid = NULL; -+ -+ /* [---------Channel---------] [---------SSID---------][---------IE---------] */ -+ DBGLOG(INIT, TRACE, "mtk_p2p_cfg80211_scan\n"); -+ -+ do { -+ if ((wiphy == NULL) || (request == NULL)) -+ break; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prP2pGlueInfo = prGlueInfo->prP2PInfo; -+ -+ if (prP2pGlueInfo == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_scan.\n"); -+ -+ if (prP2pGlueInfo->prScanRequest != NULL) { -+ /* There have been a scan request on-going processing. */ -+ DBGLOG(P2P, TRACE, "There have been a scan request on-going processing.\n"); -+ break; -+ } -+ -+ prP2pGlueInfo->prScanRequest = request; -+ -+ /* Should find out why the n_channels so many? */ -+ if (request->n_channels > MAXIMUM_OPERATION_CHANNEL_LIST) { -+ request->n_channels = MAXIMUM_OPERATION_CHANNEL_LIST; -+ DBGLOG(P2P, TRACE, "Channel list exceed the maximun support.\n"); -+ } -+ -+ u4MsgSize = sizeof(MSG_P2P_SCAN_REQUEST_T) + -+ (request->n_channels * sizeof(RF_CHANNEL_INFO_T)) + -+ (request->n_ssids * sizeof(PARAM_SSID_T)) + request->ie_len; -+ -+ prMsgScanRequest = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, u4MsgSize); -+ -+ if (prMsgScanRequest == NULL) { -+ ASSERT(FALSE); -+ i4RetRslt = -ENOMEM; -+ prP2pGlueInfo->prScanRequest = NULL; -+ DBGLOG(INIT, TRACE, "mtk_p2p_cfg80211_scan Allocate Mem failed\n"); -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "Generating scan request message.\n"); -+ -+ prMsgScanRequest->rMsgHdr.eMsgId = MID_MNY_P2P_DEVICE_DISCOVERY; -+ -+ DBGLOG(P2P, INFO, "Requesting channel number:%d.\n", request->n_channels); -+ -+ for (u4Idx = 0; u4Idx < request->n_channels; u4Idx++) { -+ /* Translate Freq from MHz to channel number. */ -+ prRfChannelInfo = &(prMsgScanRequest->arChannelListInfo[u4Idx]); -+ prChannel = request->channels[u4Idx]; -+ -+ prRfChannelInfo->ucChannelNum = nicFreq2ChannelNum(prChannel->center_freq * 1000); -+ DBGLOG(P2P, TRACE, "Scanning Channel:%d, freq: %d\n", -+ prRfChannelInfo->ucChannelNum, prChannel->center_freq); -+ switch (prChannel->band) { -+ case NL80211_BAND_2GHZ: -+ prRfChannelInfo->eBand = BAND_2G4; -+ break; -+ case NL80211_BAND_5GHZ: -+ prRfChannelInfo->eBand = BAND_5G; -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "UNKNOWN Band info from supplicant\n"); -+ prRfChannelInfo->eBand = BAND_NULL; -+ break; -+ } -+ -+ /* Iteration. */ -+ prRfChannelInfo++; -+ } -+ prMsgScanRequest->u4NumChannel = request->n_channels; -+ -+ DBGLOG(P2P, TRACE, "Finish channel list.\n"); -+ -+ /* SSID */ -+ prSsid = request->ssids; -+ prSsidStruct = (P_P2P_SSID_STRUCT_T) prRfChannelInfo; -+ if (prSsidStruct) { -+ if (request->n_ssids) { -+ ASSERT((ULONG) prSsidStruct == (ULONG)&(prMsgScanRequest->arChannelListInfo[u4Idx])); -+ prMsgScanRequest->prSSID = prSsidStruct; -+ } -+ -+ for (u4Idx = 0; u4Idx < request->n_ssids; u4Idx++) { -+ COPY_SSID(prSsidStruct->aucSsid, -+ prSsidStruct->ucSsidLen, request->ssids->ssid, request->ssids->ssid_len); -+ -+ prSsidStruct++; -+ prSsid++; -+ } -+ -+ prMsgScanRequest->i4SsidNum = request->n_ssids; -+ -+ DBGLOG(P2P, TRACE, "Finish SSID list:%d.\n", request->n_ssids); -+ -+ /* IE BUFFERS */ -+ prMsgScanRequest->pucIEBuf = (PUINT_8) prSsidStruct; -+ if (request->ie_len) { -+ kalMemCopy(prMsgScanRequest->pucIEBuf, request->ie, request->ie_len); -+ prMsgScanRequest->u4IELen = request->ie_len; -+ } -+ } -+ -+ DBGLOG(P2P, TRACE, "Finish IE Buffer.\n"); -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit = FALSE; -+#endif -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgScanRequest, MSG_SEND_METHOD_BUF); -+ -+ i4RetRslt = 0; -+ } while (FALSE); -+ -+ return i4RetRslt; -+} /* mtk_p2p_cfg80211_scan */ -+ -+int mtk_p2p_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ do { -+ if (wiphy == NULL) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_wiphy_params\n"); -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ if (changed & WIPHY_PARAM_RETRY_SHORT) { -+ /* TODO: */ -+ DBGLOG(P2P, TRACE, "The RETRY short param is changed.\n"); -+ } -+ -+ if (changed & WIPHY_PARAM_RETRY_LONG) { -+ /* TODO: */ -+ DBGLOG(P2P, TRACE, "The RETRY long param is changed.\n"); -+ } -+ -+ if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { -+ /* TODO: */ -+ DBGLOG(P2P, TRACE, "The RETRY fragmentation threshold is changed.\n"); -+ } -+ -+ if (changed & WIPHY_PARAM_RTS_THRESHOLD) { -+ /* TODO: */ -+ DBGLOG(P2P, TRACE, "The RETRY RTS threshold is changed.\n"); -+ } -+ -+ if (changed & WIPHY_PARAM_COVERAGE_CLASS) { -+ /* TODO: */ -+ DBGLOG(P2P, TRACE, "The coverage class is changed???\n"); -+ } -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_set_wiphy_params */ -+ -+int mtk_p2p_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} -+ -+int mtk_p2p_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} -+ -+int mtk_p2p_cfg80211_set_txpower(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ enum nl80211_tx_power_setting type, int mbm) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} -+ -+int mtk_p2p_cfg80211_get_txpower(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ int *dbm) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} -+ -+int mtk_p2p_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 value; -+ UINT_32 u4Leng; -+ -+ ASSERT(wiphy); -+ -+ if (enabled) -+ value = 2; -+ else -+ value = 0; -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_power_mgmt ps=%d.\n", enabled); -+ -+ /* p2p_set_power_save */ -+ kalIoctl(prGlueInfo, wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ return 0; -+} -+ -+/* &&&&&&&&&&&&&&&&&&&&&&&&&& Add for ICS Wi-Fi Direct Support. &&&&&&&&&&&&&&&&&&&&&&& */ -+int mtk_p2p_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_P2P_BEACON_UPDATE_T prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL; -+ P_MSG_P2P_START_AP_T prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) NULL; -+ PUINT_8 pucBuffer = (PUINT_8) NULL; -+ /* P_IE_SSID_T prSsidIE = (P_IE_SSID_T)NULL; */ -+ -+ struct wireless_dev *wdev = dev->ieee80211_ptr; -+ struct cfg80211_chan_def *chandef = &wdev->preset_chandef; -+ -+ do { -+ if ((wiphy == NULL) || (settings == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_start_ap.\n"); -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+#if 1 -+ mtk_p2p_cfg80211_set_channel(wiphy, chandef); -+#else -+ prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings->ucOperatingChnl = -+ (chandef->chan->center_freq - 2407) / 5; -+ prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings->eBand = BAND_2G4; -+#endif -+ -+ prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, -+ (sizeof(MSG_P2P_BEACON_UPDATE_T) + -+ settings->beacon.head_len + -+ settings->beacon.tail_len)); -+ -+ if (prP2pBcnUpdateMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prP2pBcnUpdateMsg->rMsgHdr.eMsgId = MID_MNY_P2P_BEACON_UPDATE; -+ pucBuffer = prP2pBcnUpdateMsg->aucBuffer; -+ -+ if (settings->beacon.head_len != 0) { -+ kalMemCopy(pucBuffer, settings->beacon.head, settings->beacon.head_len); -+ -+ prP2pBcnUpdateMsg->u4BcnHdrLen = settings->beacon.head_len; -+ -+ prP2pBcnUpdateMsg->pucBcnHdr = pucBuffer; -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuffer + (UINT_32) settings->beacon.head_len); -+ } else { -+ prP2pBcnUpdateMsg->u4BcnHdrLen = 0; -+ -+ prP2pBcnUpdateMsg->pucBcnHdr = NULL; -+ } -+ -+ if (settings->beacon.tail_len != 0) { -+ UINT_32 ucLen = settings->beacon.tail_len; -+ -+ prP2pBcnUpdateMsg->pucBcnBody = pucBuffer; -+ -+ /*Add TIM IE */ -+ /* IEEE 802.11 2007 - 7.3.2.6 */ -+ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; -+ TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP) /*((u4N2 - u4N1) + 4) */; -+ /* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */ -+ TIM_IE(pucBuffer)->ucDTIMCount = 0 /*prBssInfo->ucDTIMCount */; /* will be overwrite by FW */ -+ TIM_IE(pucBuffer)->ucDTIMPeriod = 1; -+ TIM_IE(pucBuffer)->ucBitmapControl = 0 /*ucBitmapControl | (UINT_8)u4N1 */; -+ /* will be overwrite by FW */ -+ ucLen += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ -+ kalMemCopy(pucBuffer, settings->beacon.tail, settings->beacon.tail_len); -+ -+ prP2pBcnUpdateMsg->u4BcnBodyLen = ucLen; -+ } else { -+ prP2pBcnUpdateMsg->u4BcnBodyLen = 0; -+ -+ prP2pBcnUpdateMsg->pucBcnBody = NULL; -+ } -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pBcnUpdateMsg, MSG_SEND_METHOD_BUF); -+ -+ prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_START_AP_T)); -+ -+ if (prP2pStartAPMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prP2pStartAPMsg->rMsgHdr.eMsgId = MID_MNY_P2P_START_AP; -+ -+ prP2pStartAPMsg->fgIsPrivacy = settings->privacy; -+ -+ prP2pStartAPMsg->u4BcnInterval = settings->beacon_interval; -+ -+ prP2pStartAPMsg->u4DtimPeriod = settings->dtim_period; -+ -+ /* Copy NO SSID. */ -+ prP2pStartAPMsg->ucHiddenSsidType = settings->hidden_ssid; -+ -+ COPY_SSID(prP2pStartAPMsg->aucSsid, prP2pStartAPMsg->u2SsidLen, settings->ssid, settings->ssid_len); -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pStartAPMsg, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+ if (glIsChipNeedWakelock(prGlueInfo)) -+ KAL_WAKE_LOCK(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock); -+#endif -+ -+ } while (FALSE); -+ -+ return i4Rslt; -+ -+/* /////////////////////// */ -+ /** -+ * struct cfg80211_ap_settings - AP configuration -+ * -+ * Used to configure an AP interface. -+ * -+ * @beacon: beacon data -+ * @beacon_interval: beacon interval -+ * @dtim_period: DTIM period -+ * @ssid: SSID to be used in the BSS (note: may be %NULL if not provided from -+ * user space) -+ * @ssid_len: length of @ssid -+ * @hidden_ssid: whether to hide the SSID in Beacon/Probe Response frames -+ * @crypto: crypto settings -+ * @privacy: the BSS uses privacy -+ * @auth_type: Authentication type (algorithm) -+ * @inactivity_timeout: time in seconds to determine station's inactivity. -+ */ -+/* struct cfg80211_ap_settings { */ -+/* struct cfg80211_beacon_data beacon; */ -+/* */ -+/* int beacon_interval, dtim_period; */ -+/* const u8 *ssid; */ -+/* size_t ssid_len; */ -+/* enum nl80211_hidden_ssid hidden_ssid; */ -+/* struct cfg80211_crypto_settings crypto; */ -+/* bool privacy; */ -+/* enum nl80211_auth_type auth_type; */ -+/* int inactivity_timeout; */ -+/* }; */ -+/* ////////////////// */ -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_start_ap */ -+ -+int mtk_p2p_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_beacon_data *info) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_P2P_BEACON_UPDATE_T prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL; -+ PUINT_8 pucBuffer = (PUINT_8) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (info == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_change_beacon.\n"); -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, -+ (sizeof(MSG_P2P_BEACON_UPDATE_T) + -+ info->head_len + info->tail_len)); -+ -+ if (prP2pBcnUpdateMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prP2pBcnUpdateMsg->rMsgHdr.eMsgId = MID_MNY_P2P_BEACON_UPDATE; -+ pucBuffer = prP2pBcnUpdateMsg->aucBuffer; -+ -+ if (info->head_len != 0) { -+ kalMemCopy(pucBuffer, info->head, info->head_len); -+ -+ prP2pBcnUpdateMsg->u4BcnHdrLen = info->head_len; -+ -+ prP2pBcnUpdateMsg->pucBcnHdr = pucBuffer; -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuffer + (UINT_32) info->head_len); -+ } else { -+ prP2pBcnUpdateMsg->u4BcnHdrLen = 0; -+ -+ prP2pBcnUpdateMsg->pucBcnHdr = NULL; -+ } -+ -+ if (info->tail_len != 0) { -+ UINT_32 ucLen = info->tail_len; -+ -+ prP2pBcnUpdateMsg->pucBcnBody = pucBuffer; -+ -+ /*Add TIM IE */ -+ /* IEEE 802.11 2007 - 7.3.2.6 */ -+ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; -+ TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP) /*((u4N2 - u4N1) + 4) */; -+ /* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */ -+ TIM_IE(pucBuffer)->ucDTIMCount = 0 /*prBssInfo->ucDTIMCount */; /* will be overwrite by FW */ -+ TIM_IE(pucBuffer)->ucDTIMPeriod = 1; -+ TIM_IE(pucBuffer)->ucBitmapControl = 0 /*ucBitmapControl | (UINT_8)u4N1 */; -+ /* will be overwrite by FW */ -+ ucLen += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ -+ kalMemCopy(pucBuffer, info->tail, info->tail_len); -+ -+ prP2pBcnUpdateMsg->u4BcnBodyLen = ucLen; -+ } else { -+ prP2pBcnUpdateMsg->u4BcnBodyLen = 0; -+ -+ prP2pBcnUpdateMsg->pucBcnBody = NULL; -+ } -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pBcnUpdateMsg, MSG_SEND_METHOD_BUF); -+ -+/* ////////////////////////// */ -+/** -+ * struct cfg80211_beacon_data - beacon data -+ * @head: head portion of beacon (before TIM IE) -+ * or %NULL if not changed -+ * @tail: tail portion of beacon (after TIM IE) -+ * or %NULL if not changed -+ * @head_len: length of @head -+ * @tail_len: length of @tail -+ * @beacon_ies: extra information element(s) to add into Beacon frames or %NULL -+ * @beacon_ies_len: length of beacon_ies in octets -+ * @proberesp_ies: extra information element(s) to add into Probe Response -+ * frames or %NULL -+ * @proberesp_ies_len: length of proberesp_ies in octets -+ * @assocresp_ies: extra information element(s) to add into (Re)Association -+ * Response frames or %NULL -+ * @assocresp_ies_len: length of assocresp_ies in octets -+ * @probe_resp_len: length of probe response template (@probe_resp) -+ * @probe_resp: probe response template (AP mode only) -+ */ -+/* struct cfg80211_beacon_data { */ -+/* const u8 *head, *tail; */ -+/* const u8 *beacon_ies; */ -+/* const u8 *proberesp_ies; */ -+/* const u8 *assocresp_ies; */ -+/* const u8 *probe_resp; */ -+ -+/* size_t head_len, tail_len; */ -+/* size_t beacon_ies_len; */ -+/* size_t proberesp_ies_len; */ -+/* size_t assocresp_ies_len; */ -+/* size_t probe_resp_len; */ -+/* }; */ -+ -+/* ////////////////////////// */ -+ -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_change_beacon */ -+ -+int mtk_p2p_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_P2P_SWITCH_OP_MODE_T prP2pSwitchMode = (P_MSG_P2P_SWITCH_OP_MODE_T) NULL; -+ -+ do { -+ if (wiphy == NULL) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_stop_ap.\n"); -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* Switch OP MOde. */ -+ prP2pSwitchMode = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_SWITCH_OP_MODE_T)); -+ -+ if (prP2pSwitchMode == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prP2pSwitchMode->rMsgHdr.eMsgId = MID_MNY_P2P_STOP_AP; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pSwitchMode, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+ if (glIsChipNeedWakelock(prGlueInfo)) -+ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock); -+#endif -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_stop_ap */ -+ -+/* TODO: */ -+int mtk_p2p_cfg80211_deauth(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_deauth_request *req) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_deauth.\n"); -+ -+ return -EINVAL; -+} /* mtk_p2p_cfg80211_deauth */ -+ -+/* TODO: */ -+int mtk_p2p_cfg80211_disassoc(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_disassoc_request *req) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_disassoc.\n"); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} /* mtk_p2p_cfg80211_disassoc */ -+ -+int mtk_p2p_cfg80211_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct ieee80211_channel *chan, -+ unsigned int duration, u64 *cookie) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ P_MSG_P2P_CHNL_REQUEST_T prMsgChnlReq = (P_MSG_P2P_CHNL_REQUEST_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL) || (chan == NULL) || (cookie == NULL)) -+ break; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ *cookie = prGlueP2pInfo->u8Cookie++; -+ -+ prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CHNL_REQUEST_T)); -+ -+ if (prMsgChnlReq == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_remain_on_channel\n"); -+ -+ prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_P2P_CHNL_REQ; -+ prMsgChnlReq->u8Cookie = *cookie; -+ prMsgChnlReq->u4Duration = duration; -+ -+ mtk_p2p_cfg80211func_channel_format_switch(chan, NL80211_CHAN_HT20, /* 4 KH Need Check */ -+ &prMsgChnlReq->rChannelInfo, &prMsgChnlReq->eChnlSco); -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlReq, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} -+ -+/* mtk_p2p_cfg80211_remain_on_channel */ -+int mtk_p2p_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ u64 cookie) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_MSG_P2P_CHNL_ABORT_T prMsgChnlAbort = (P_MSG_P2P_CHNL_ABORT_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL)) -+ break; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prMsgChnlAbort = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CHNL_ABORT_T)); -+ -+ if (prMsgChnlAbort == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_cancel_remain_on_channel\n"); -+ -+ prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_P2P_CHNL_ABORT; -+ prMsgChnlAbort->u8Cookie = cookie; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlAbort, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_cancel_remain_on_channel */ -+ -+int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct cfg80211_mgmt_tx_params *params, -+ u64 *cookie) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *prMsgExtListenReq = NULL; -+ P_MSG_P2P_MGMT_TX_REQUEST_T prMsgTxReq = (P_MSG_P2P_MGMT_TX_REQUEST_T) NULL; -+ P_MSDU_INFO_T prMgmtFrame = (P_MSDU_INFO_T) NULL; -+ PUINT_8 pucFrameBuf = (PUINT_8) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL) || (params == 0) || (cookie == NULL)) -+ break; -+ /* DBGLOG(P2P, TRACE, ("mtk_p2p_cfg80211_mgmt_tx\n")); */ -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ *cookie = prGlueP2pInfo->u8Cookie++; -+ -+ /* Channel & Channel Type & Wait time are ignored. */ -+ prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_MGMT_TX_REQUEST_T)); -+ -+ if (prMsgTxReq == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ /* Here need to extend the listen interval */ -+ prMsgExtListenReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, -+ sizeof(struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T)); -+ if (prMsgExtListenReq) { -+ prMsgExtListenReq->rMsgHdr.eMsgId = MID_MNY_P2P_EXTEND_LISTEN_INTERVAL; -+ prMsgExtListenReq->wait = params->wait; -+ DBGLOG(P2P, INFO, "ext listen, wait: %d\n", prMsgExtListenReq->wait); -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T)prMsgExtListenReq, -+ MSG_SEND_METHOD_BUF); -+ } -+ -+ prMsgTxReq->fgNoneCckRate = FALSE; -+ prMsgTxReq->fgIsWaitRsp = TRUE; -+ -+ prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, (UINT_32) (params->len + MAC_TX_RESERVED_FIELD)); -+ -+ prMsgTxReq->prMgmtMsduInfo = prMgmtFrame; -+ if (prMsgTxReq->prMgmtMsduInfo == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prMsgTxReq->u8Cookie = *cookie; -+ prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_TX; -+ -+ pucFrameBuf = (PUINT_8) ((ULONG) prMgmtFrame->prPacket + MAC_TX_RESERVED_FIELD); -+ -+ kalMemCopy(pucFrameBuf, params->buf, params->len); -+ -+ prMgmtFrame->u2FrameLength = params->len; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgTxReq, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ if ((i4Rslt != 0) && (prMsgTxReq != NULL)) { -+ if (prMsgTxReq->prMgmtMsduInfo != NULL) -+ cnmMgtPktFree(prGlueInfo->prAdapter, prMsgTxReq->prMgmtMsduInfo); -+ -+ cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq); -+ } -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_mgmt_tx */ -+ -+int mtk_p2p_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ switch (params->use_cts_prot) { -+ case -1: -+ DBGLOG(P2P, TRACE, "CTS protection no change\n"); -+ break; -+ case 0: -+ DBGLOG(P2P, TRACE, "CTS protection disable.\n"); -+ break; -+ case 1: -+ DBGLOG(P2P, TRACE, "CTS protection enable\n"); -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "CTS protection unknown\n"); -+ break; -+ } -+ -+ switch (params->use_short_preamble) { -+ case -1: -+ DBGLOG(P2P, TRACE, "Short prreamble no change\n"); -+ break; -+ case 0: -+ DBGLOG(P2P, TRACE, "Short prreamble disable.\n"); -+ break; -+ case 1: -+ DBGLOG(P2P, TRACE, "Short prreamble enable\n"); -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "Short prreamble unknown\n"); -+ break; -+ } -+ -+#if 0 -+ /* not implemented yet */ -+ p2pFuncChangeBssParam(prGlueInfo->prAdapter, -+ prBssInfo->fgIsProtection, -+ prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortSlotTime, -+ /* Basic rates */ -+ /* basic rates len */ -+ /* ap isolate */ -+ /* ht opmode. */ -+ ); -+#else -+ i4Rslt = 0; -+#endif -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_change_bss */ -+ -+int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, struct station_del_parameters *params) -+//int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_P2P_CONNECTION_ABORT_T prDisconnectMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; -+ UINT_8 aucBcMac[] = BC_MAC_ADDR; -+ const UINT_8 *mac = NULL; -+ -+ do { -+ if ((wiphy == NULL) || (dev == NULL)) -+ break; -+ -+ if (params->mac == NULL) -+ mac = aucBcMac; -+ else -+ mac = params->mac; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_del_station.\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* prDisconnectMsg = (P_MSG_P2P_CONNECTION_ABORT_T)kalMemAlloc(sizeof(MSG_P2P_CONNECTION_ABORT_T), -+ VIR_MEM_TYPE); */ -+ prDisconnectMsg = -+ (P_MSG_P2P_CONNECTION_ABORT_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_CONNECTION_ABORT_T)); -+ -+ if (prDisconnectMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prDisconnectMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; -+ COPY_MAC_ADDR(prDisconnectMsg->aucTargetID, mac); -+ prDisconnectMsg->u2ReasonCode = REASON_CODE_UNSPECIFIED; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDisconnectMsg, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+ -+} /* mtk_p2p_cfg80211_del_station */ -+ -+int mtk_p2p_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_MSG_P2P_CONNECTION_REQUEST_T prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (dev == NULL) || (sme == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_connect.\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prConnReqMsg = -+ (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, -+ (sizeof(MSG_P2P_CONNECTION_REQUEST_T) + sme->ie_len)); -+ -+ if (prConnReqMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prConnReqMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; -+ -+ COPY_SSID(prConnReqMsg->rSsid.aucSsid, prConnReqMsg->rSsid.ucSsidLen, sme->ssid, sme->ssid_len); -+ -+ COPY_MAC_ADDR(prConnReqMsg->aucBssid, sme->bssid); -+ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_connect to %pM, IE len: %d\n", -+ prConnReqMsg->aucBssid, sme->ie_len); -+ -+ DBGLOG(P2P, TRACE, "Assoc Req IE Buffer Length:%d\n", sme->ie_len); -+ kalMemCopy(prConnReqMsg->aucIEBuf, sme->ie, sme->ie_len); -+ prConnReqMsg->u4IELen = sme->ie_len; -+ -+ mtk_p2p_cfg80211func_channel_format_switch(sme->channel, -+ NL80211_CHAN_NO_HT, -+ &prConnReqMsg->rChannelInfo, &prConnReqMsg->eChnlSco); -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prConnReqMsg, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_connect */ -+ -+int mtk_p2p_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_MSG_P2P_CONNECTION_ABORT_T prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; -+ UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+ -+ do { -+ if ((wiphy == NULL) || (dev == NULL)) -+ break; -+ -+ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_disconnect.\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+/* prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T)kalMemAlloc(sizeof(P_MSG_P2P_CONNECTION_ABORT_T), VIR_MEM_TYPE); */ -+ prDisconnMsg = -+ (P_MSG_P2P_CONNECTION_ABORT_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_CONNECTION_ABORT_T)); -+ -+ if (prDisconnMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_disconnect.Allocate Memory Failed.\n"); -+ break; -+ } -+ -+ prDisconnMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; -+ prDisconnMsg->u2ReasonCode = reason_code; -+ prDisconnMsg->fgSendDeauth = TRUE; -+ COPY_MAC_ADDR(prDisconnMsg->aucTargetID, aucBCAddr); -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDisconnMsg, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_disconnect */ -+ -+int -+mtk_p2p_cfg80211_change_iface(IN struct wiphy *wiphy, -+ IN struct net_device *ndev, -+ IN enum nl80211_iftype type,/* IN u32 *flags,*/ IN struct vif_params *params) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_P2P_SWITCH_OP_MODE_T prSwitchModeMsg = (P_MSG_P2P_SWITCH_OP_MODE_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (ndev == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_change_iface.\n"); -+ -+ if (ndev->ieee80211_ptr) -+ ndev->ieee80211_ptr->iftype = type; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* Switch OP MOde. */ -+ prSwitchModeMsg = -+ (P_MSG_P2P_SWITCH_OP_MODE_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_SWITCH_OP_MODE_T)); -+ -+ if (prSwitchModeMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prSwitchModeMsg->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ -+ switch (type) { -+ case NL80211_IFTYPE_P2P_CLIENT: -+ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_P2P_CLIENT.\n"); -+ case NL80211_IFTYPE_STATION: -+ if (type == NL80211_IFTYPE_STATION) -+ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_STATION.\n"); -+ prSwitchModeMsg->eOpMode = OP_MODE_INFRASTRUCTURE; -+ break; -+ case NL80211_IFTYPE_AP: -+ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_AP.\n"); -+ case NL80211_IFTYPE_P2P_GO: -+ if (type == NL80211_IFTYPE_P2P_GO) -+ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_P2P_GO not AP.\n"); -+ prSwitchModeMsg->eOpMode = OP_MODE_ACCESS_POINT; -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "Other type :%d .\n", type); -+ prSwitchModeMsg->eOpMode = OP_MODE_P2P_DEVICE; -+ break; -+ } -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSwitchModeMsg, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ -+ } while (FALSE); -+ -+ return i4Rslt; -+ -+} /* mtk_p2p_cfg80211_change_iface */ -+ -+int mtk_p2p_cfg80211_set_channel(IN struct wiphy *wiphy, -+ struct cfg80211_chan_def *chandef) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ RF_CHANNEL_INFO_T rRfChnlInfo; -+ -+ do { -+ if (wiphy == NULL) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_channel.\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ mtk_p2p_cfg80211func_channel_format_switch(chandef->chan, chandef->width, &rRfChnlInfo, NULL); -+ p2pFuncSetChannel(prGlueInfo->prAdapter, &rRfChnlInfo); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+ -+} -+ -+/* mtk_p2p_cfg80211_set_channel */ -+ -+int -+mtk_p2p_cfg80211_set_bitrate_mask(IN struct wiphy *wiphy, -+ IN struct net_device *dev, -+ IN const u8 *peer, IN const struct cfg80211_bitrate_mask *mask) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (dev == NULL) || (mask == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_bitrate_mask\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* TODO: Set bitrate mask of the peer? */ -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_set_bitrate_mask */ -+ -+void mtk_p2p_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ IN u16 frame_type, IN bool reg) -+{ -+#if 0 -+ P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL; -+#endif -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_mgmt_frame_register\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ switch (frame_type) { -+ case MAC_FRAME_PROBE_REQ: -+ if (reg) { -+ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(P2P, TRACE, "Open packet filer probe request\n"); -+ } else { -+ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(P2P, TRACE, "Close packet filer probe request\n"); -+ } -+ break; -+ case MAC_FRAME_ACTION: -+ if (reg) { -+ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(P2P, TRACE, "Open packet filer action frame.\n"); -+ } else { -+ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(P2P, TRACE, "Close packet filer action frame.\n"); -+ } -+ break; -+ default: -+ DBGLOG(P2P, ERROR, "Ask frog to add code for mgmt:%x\n", frame_type); -+ break; -+ } -+ -+ if ((prGlueInfo->prAdapter != NULL) && (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE)) { -+ -+ /* prGlueInfo->u4Flag |= GLUE_FLAG_FRAME_FILTER; */ -+ set_bit(GLUE_FLAG_FRAME_FILTER_BIT, &prGlueInfo->ulFlag); -+ -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+ if (in_interrupt()) -+ DBGLOG(P2P, TRACE, "It is in interrupt level\n"); -+ } -+#if 0 -+ -+ prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, -+ sizeof -+ (MSG_P2P_MGMT_FRAME_REGISTER_T)); -+ -+ if (prMgmtFrameRegister == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prMgmtFrameRegister->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_FRAME_REGISTER; -+ -+ prMgmtFrameRegister->u2FrameType = frame_type; -+ prMgmtFrameRegister->fgIsRegister = reg; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMgmtFrameRegister, MSG_SEND_METHOD_BUF); -+ -+#endif -+ -+ } while (FALSE); -+ -+} /* mtk_p2p_cfg80211_mgmt_frame_register */ -+ -+BOOLEAN -+mtk_p2p_cfg80211func_channel_format_switch(IN struct ieee80211_channel *channel, -+ IN enum nl80211_channel_type channel_type, -+ IN P_RF_CHANNEL_INFO_T prRfChnlInfo, IN P_ENUM_CHNL_EXT_T prChnlSco) -+{ -+ BOOLEAN fgIsValid = FALSE; -+ -+ do { -+ if (channel == NULL) -+ break; -+ -+ if (prRfChnlInfo) { -+ prRfChnlInfo->ucChannelNum = nicFreq2ChannelNum(channel->center_freq * 1000); -+ -+ switch (channel->band) { -+ case NL80211_BAND_2GHZ: -+ prRfChnlInfo->eBand = BAND_2G4; -+ break; -+ case NL80211_BAND_5GHZ: -+ prRfChnlInfo->eBand = BAND_5G; -+ break; -+ default: -+ prRfChnlInfo->eBand = BAND_2G4; -+ break; -+ } -+ -+ } -+ -+ if (prChnlSco) { -+ -+ switch (channel_type) { -+ case NL80211_CHAN_NO_HT: -+ *prChnlSco = CHNL_EXT_SCN; -+ break; -+ case NL80211_CHAN_HT20: -+ *prChnlSco = CHNL_EXT_SCN; -+ break; -+ case NL80211_CHAN_HT40MINUS: -+ *prChnlSco = CHNL_EXT_SCA; -+ break; -+ case NL80211_CHAN_HT40PLUS: -+ *prChnlSco = CHNL_EXT_SCB; -+ break; -+ default: -+ ASSERT(FALSE); -+ *prChnlSco = CHNL_EXT_SCN; -+ break; -+ } -+ } -+ -+ fgIsValid = TRUE; -+ } while (FALSE); -+ -+ return fgIsValid; -+} -+ -+/* mtk_p2p_cfg80211func_channel_format_switch */ -+ -+#if CONFIG_NL80211_TESTMODE -+int mtk_p2p_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_TEST_PARAMS prParams = (P_NL80211_DRIVER_TEST_PARAMS) NULL; -+ INT_32 i4Status = -EINVAL; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = NULL; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_cmd\n"); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_TEST_PARAMS) data; -+ } else { -+ DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_cmd, data is NULL\n"); -+ return i4Status; -+ } -+ -+ if (prParams->index >> 24 == 0x01) { -+ /* New version */ -+ } else { -+ /* Old version */ -+ mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(wiphy, data, len); -+ i4Status = 0; -+ return i4Status; -+ } -+ -+ /* Clear the version byte */ -+ prParams->index = prParams->index & ~BITS(24, 31); -+ -+ if (prParams) { -+ switch (prParams->index) { -+ case 1: /* P2P Simga */ -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ { -+ P_NL80211_DRIVER_SW_CMD_PARAMS prParamsCmd; -+ -+ prParamsCmd = (P_NL80211_DRIVER_SW_CMD_PARAMS) data; -+ -+ if ((prParamsCmd->adr & 0xffff0000) == 0xffff0000) { -+ i4Status = mtk_p2p_cfg80211_testmode_sw_cmd(wiphy, data, len); -+ break; -+ } -+ } -+#endif -+ i4Status = mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(wiphy, data, len); -+ break; -+#if CFG_SUPPORT_WFD -+ case 2: /* WFD */ -+ i4Status = mtk_p2p_cfg80211_testmode_wfd_update_cmd(wiphy, data, len); -+ break; -+#endif -+ case 3: /* Hotspot Client Management */ -+ i4Status = mtk_p2p_cfg80211_testmode_hotspot_block_cmd(wiphy, data, len); -+ break; -+ case 0x10: -+ i4Status = mtk_cfg80211_testmode_get_sta_statistics(wiphy, data, len, prGlueInfo); -+ break; -+#if 1 -+ case 0x11: /*NFC Beam + Indication */ -+ prChnlReqInfo = &prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo; -+ if (data && len) { -+ P_NL80211_DRIVER_SET_NFC_PARAMS prParams = (P_NL80211_DRIVER_SET_NFC_PARAMS) data; -+ -+ prChnlReqInfo->NFC_BEAM = prParams->NFC_Enable; -+ DBGLOG(P2P, INFO, "NFC: BEAM[%d]\n", prChnlReqInfo->NFC_BEAM); -+ } -+ break; -+ case 0x12: /*NFC Beam + Indication */ -+ DBGLOG(P2P, INFO, "NFC: Polling\n"); -+ i4Status = mtk_cfg80211_testmode_get_scan_done(wiphy, data, len, prGlueInfo); -+ break; -+#endif -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ case 0x30: -+ i4Status = mtk_cfg80211_testmode_get_lte_channel(wiphy, data, len, prGlueInfo); -+ break; -+#endif -+ -+ default: -+ i4Status = -EINVAL; -+ break; -+ } -+ } -+ -+ return i4Status; -+} -+ -+int mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ NL80211_DRIVER_TEST_PRE_PARAMS rParams; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ UINT_32 index_mode; -+ UINT_32 index; -+ INT_32 value; -+ int status = 0; -+ UINT_32 u4Leng; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ kalMemZero(&rParams, sizeof(NL80211_DRIVER_TEST_PRE_PARAMS)); -+ -+ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd\n"); -+ -+ if (data && len) -+ memcpy(&rParams, data, len); -+ -+ DBGLOG(P2P, TRACE, "NL80211_ATTR_TESTDATA,idx_mode=%d idx=%d value=%u\n", -+ (INT_16) rParams.idx_mode, (INT_16) rParams.idx, rParams.value); -+ -+ index_mode = rParams.idx_mode; -+ index = rParams.idx; -+ value = rParams.value; -+ -+ switch (index) { -+ case 0: /* Listen CH */ -+ break; -+ case 1: /* P2p mode */ -+ break; -+ case 4: /* Noa duration */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 5: /* Noa interval */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 6: /* Noa count */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 100: /* Oper CH */ -+ /* 20110920 - frog: User configurations are placed in ConnSettings. */ -+ /* prP2pConnSettings->ucOperatingChnl = value; */ -+ break; -+ case 101: /* Local config Method, for P2P SDK */ -+ prP2pConnSettings->u2LocalConfigMethod = value; -+ break; -+ case 102: /* Sigma P2p reset */ -+ /* kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); */ -+ /* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */ -+ p2pFsmUninit(prGlueInfo->prAdapter); -+ p2pFsmInit(prGlueInfo->prAdapter); -+ break; -+ case 103: /* WPS MODE */ -+ kalP2PSetWscMode(prGlueInfo, value); -+ break; -+ case 104: /* P2p send persence, duration */ -+ break; -+ case 105: /* P2p send persence, interval */ -+ break; -+ case 106: /* P2P set sleep */ -+ value = 1; -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ break; -+ case 107: /* P2P set opps, CTWindowl */ -+ prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; -+ /* status = mtk_p2p_wext_set_oppps_param(prDev,info,wrqu,(char *)&prP2pSpecificBssInfo->rOppPsParam); */ -+ break; -+ case 108: /* p2p_set_power_save */ -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ -+ break; -+ default: -+ break; -+ } -+ -+ return status; -+ -+} -+ -+int mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_P2P_SIGMA_PARAMS prParams = (P_NL80211_DRIVER_P2P_SIGMA_PARAMS) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ UINT_32 index; -+ INT_32 value; -+ int status = 0; -+ UINT_32 u4Leng; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_p2p_sigma_cmd\n"); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_P2P_SIGMA_PARAMS) data; -+ } else { -+ DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_p2p_sigma_cmd, data is NULL or len is 0\n"); -+ return -EINVAL; -+ } -+ -+ index = (INT_32) prParams->idx; -+ value = (INT_32) prParams->value; -+ -+ DBGLOG(P2P, TRACE, "NL80211_ATTR_TESTDATA, idx=%d value=%d\n", -+ (INT_32) prParams->idx, (INT_32) prParams->value); -+ -+ switch (index) { -+ case 0: /* Listen CH */ -+ break; -+ case 1: /* P2p mode */ -+ break; -+ case 4: /* Noa duration */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 5: /* Noa interval */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 6: /* Noa count */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 100: /* Oper CH */ -+ /* 20110920 - frog: User configurations are placed in ConnSettings. */ -+ /* prP2pConnSettings->ucOperatingChnl = value; */ -+ break; -+ case 101: /* Local config Method, for P2P SDK */ -+ prP2pConnSettings->u2LocalConfigMethod = value; -+ break; -+ case 102: /* Sigma P2p reset */ -+ /* kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); */ -+ /* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */ -+ break; -+ case 103: /* WPS MODE */ -+ kalP2PSetWscMode(prGlueInfo, value); -+ break; -+ case 104: /* P2p send persence, duration */ -+ break; -+ case 105: /* P2p send persence, interval */ -+ break; -+ case 106: /* P2P set sleep */ -+ value = 1; -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ break; -+ case 107: /* P2P set opps, CTWindowl */ -+ prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; -+ /* status = mtk_p2p_wext_set_oppps_param(prDev,info,wrqu,(char *)&prP2pSpecificBssInfo->rOppPsParam); */ -+ break; -+ case 108: /* p2p_set_power_save */ -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ -+ break; -+ case 109: /* Max Clients */ -+ kalP2PSetMaxClients(prGlueInfo, value); -+ break; -+ case 110: /* Hotspot WPS mode */ -+ kalIoctl(prGlueInfo, wlanoidSetP2pWPSmode, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ break; -+ default: -+ break; -+ } -+ -+ return status; -+ -+} -+ -+#if CFG_SUPPORT_WFD -+int mtk_p2p_cfg80211_testmode_wfd_update_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_WFD_PARAMS prParams = (P_NL80211_DRIVER_WFD_PARAMS) NULL; -+ int status = 0; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL; -+ static UINT_8 prevWfdEnable; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prParams = (P_NL80211_DRIVER_WFD_PARAMS) data; -+ -+ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_testmode_wfd_update_cmd\n"); -+ -+ /* to reduce log, print when state changed */ -+ if (prevWfdEnable != prParams->WfdEnable) { -+ prevWfdEnable = prParams->WfdEnable; -+ DBGLOG(P2P, INFO, "WFD Enable:%x\n", prParams->WfdEnable); -+ DBGLOG(P2P, INFO, "WFD Session Available:%x\n", prParams->WfdSessionAvailable); -+ DBGLOG(P2P, INFO, "WFD Couple Sink Status:%x\n", prParams->WfdCoupleSinkStatus); -+ /* aucReserved0[2] */ -+ DBGLOG(P2P, INFO, "WFD Device Info:%x\n", prParams->WfdDevInfo); -+ DBGLOG(P2P, INFO, "WFD Control Port:%x\n", prParams->WfdControlPort); -+ DBGLOG(P2P, INFO, "WFD Maximum Throughput:%x\n", prParams->WfdMaximumTp); -+ DBGLOG(P2P, INFO, "WFD Extend Capability:%x\n", prParams->WfdExtendCap); -+ DBGLOG(P2P, INFO, "WFD Couple Sink Addr %pM\n", prParams->WfdCoupleSinkAddress); -+ DBGLOG(P2P, INFO, "WFD Associated BSSID %pM\n", prParams->WfdAssociatedBssid); -+ /* UINT_8 aucVideolp[4]; */ -+ /* UINT_8 aucAudiolp[4]; */ -+ DBGLOG(P2P, INFO, "WFD Video Port:%x\n", prParams->WfdVideoPort); -+ DBGLOG(P2P, INFO, "WFD Audio Port:%x\n", prParams->WfdAudioPort); -+ DBGLOG(P2P, INFO, "WFD Flag:%x\n", prParams->WfdFlag); -+ DBGLOG(P2P, INFO, "WFD Policy:%x\n", prParams->WfdPolicy); -+ DBGLOG(P2P, INFO, "WFD State:%x\n", prParams->WfdState); -+ /* UINT_8 aucWfdSessionInformationIE[24*8]; */ -+ DBGLOG(P2P, INFO, "WFD Session Info Length:%x\n", prParams->WfdSessionInformationIELen); -+ /* UINT_8 aucReserved1[2]; */ -+ DBGLOG(P2P, INFO, "WFD Primary Sink Addr %pM\n", prParams->aucWfdPrimarySinkMac); -+ DBGLOG(P2P, INFO, "WFD Secondary Sink Addr %pM\n", prParams->aucWfdSecondarySinkMac); -+ DBGLOG(P2P, INFO, "WFD Advanced Flag:%x\n", prParams->WfdAdvanceFlag); -+ DBGLOG(P2P, INFO, "WFD Sigma mode:%x\n", prParams->WfdSigmaMode); -+ /* UINT_8 aucReserved2[64]; */ -+ /* UINT_8 aucReserved3[64]; */ -+ /* UINT_8 aucReserved4[64]; */ -+ } -+ -+ prWfdCfgSettings = &(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ kalMemCopy(&prWfdCfgSettings->u4WfdCmdType, &prParams->WfdCmdType, sizeof(WFD_CFG_SETTINGS_T)); -+ -+ prMsgWfdCfgUpdate = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_WFD_CONFIG_SETTINGS_CHANGED_T)); -+ -+ if (prMsgWfdCfgUpdate == NULL) { -+ ASSERT(FALSE); -+ return status; -+ } -+ -+ prMsgWfdCfgUpdate->rMsgHdr.eMsgId = MID_MNY_P2P_WFD_CFG_UPDATE; -+ prMsgWfdCfgUpdate->prWfdCfgSettings = prWfdCfgSettings; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgWfdCfgUpdate, MSG_SEND_METHOD_BUF); -+#if 0 /* Test Only */ -+/* prWfdCfgSettings->ucWfdEnable = 1; */ -+/* prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_DEV_INFO_VALID; */ -+ prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_DEV_INFO_VALID; -+ prWfdCfgSettings->u2WfdDevInfo = 123; -+ prWfdCfgSettings->u2WfdControlPort = 456; -+ prWfdCfgSettings->u2WfdMaximumTp = 789; -+ -+ prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_SINK_INFO_VALID; -+ prWfdCfgSettings->ucWfdCoupleSinkStatus = 0xAB; -+ { -+ UINT_8 aucTestAddr[MAC_ADDR_LEN] = { 0x77, 0x66, 0x55, 0x44, 0x33, 0x22 }; -+ -+ COPY_MAC_ADDR(prWfdCfgSettings->aucWfdCoupleSinkAddress, aucTestAddr); -+ } -+ -+ prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_EXT_CAPABILITY_VALID; -+ prWfdCfgSettings->u2WfdExtendCap = 0xCDE; -+ -+#endif -+ -+ return status; -+ -+} -+#endif /* CFG_SUPPORT_WFD */ -+ -+int mtk_p2p_cfg80211_testmode_hotspot_block_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS prParams = (P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS) NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS) data; -+ } else { -+ DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_hotspot_block_cmd, data is NULL or len is 0\n"); -+ return -EINVAL; -+ } -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_hotspot_block_cmd\n"); -+ -+ return kalP2PSetBlackList(prGlueInfo, prParams->aucBssid, prParams->ucblocked); -+} -+ -+int mtk_p2p_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_SW_CMD_PARAMS prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) NULL; -+ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; -+ int fgIsValid = 0; -+ UINT_32 u4SetInfoLen = 0; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+#if 1 -+ DBGLOG(P2P, TRACE, "--> %s()\n", __func__); -+#endif -+ -+ if (data && len) -+ prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) data; -+ -+ if (prParams) { -+ if (prParams->set == 1) { -+ rstatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC) wlanoidSetSwCtrlWrite, -+ &prParams->adr, (UINT_32) 8, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ } -+ } -+ -+ if (WLAN_STATUS_SUCCESS != rstatus) -+ fgIsValid = -EFAULT; -+ -+ return fgIsValid; -+} -+ -+#endif -+ -+#endif /* CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c -new file mode 100644 -index 0000000000000..d0f2d25a4529f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c -@@ -0,0 +1,433 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* 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, see . -+*/ -+ -+/* -+** Id: @(#) gl_p2p_init.c@@ -+*/ -+ -+/*! \file gl_p2p_init.c -+ \brief init and exit routines of Linux driver interface for Wi-Fi Direct -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define P2P_MODE_INF_NAME "p2p%d" -+#if CFG_TC1_FEATURE -+#define AP_MODE_INF_NAME "wlan%d" -+#else -+#define AP_MODE_INF_NAME "ap%d" -+#endif -+/* #define MAX_INF_NAME_LEN 15 */ -+/* #define MIN_INF_NAME_LEN 1 */ -+ -+#define RUNNING_P2P_MODE 0 -+#define RUNNING_AP_MODE 1 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* Get interface name and running mode from module insertion parameter -+* Usage: insmod p2p.ko mode=1 -+* default: interface name is p2p%d -+* running mode is P2P -+*/ -+static PUCHAR ifname = P2P_MODE_INF_NAME; -+static UINT_16 mode = RUNNING_P2P_MODE; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief check interface name parameter is valid or not -+* if invalid, set ifname to P2P_MODE_INF_NAME -+* -+* -+* \retval -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pCheckInterfaceName(VOID) -+{ -+ -+ if (mode) { -+ mode = RUNNING_AP_MODE; -+ ifname = AP_MODE_INF_NAME; -+ } -+#if 0 -+ UINT_32 ifLen = 0; -+ -+ if (ifname) { -+ ifLen = strlen(ifname); -+ -+ if (ifLen > MAX_INF_NAME_LEN) -+ ifname[MAX_INF_NAME_LEN] = '\0'; -+ else if (ifLen < MIN_INF_NAME_LEN) -+ ifname = P2P_MODE_INF_NAME; -+ } else { -+ ifname = P2P_MODE_INF_NAME; -+ } -+#endif -+} -+ -+void p2pHandleSystemSuspend(void) -+{ -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_8 ip[4] = { 0 }; -+ UINT_32 u4NumIPv4 = 0; -+#ifdef CONFIG_IPV6 -+ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ -+ UINT_32 u4NumIPv6 = 0; -+#endif -+ UINT_32 i; -+ P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr; -+ -+ -+ if (!wlanExportGlueInfo(&prGlueInfo)) { -+ DBGLOG(P2P, INFO, "No glue info\n"); -+ return; -+ } -+ -+ ASSERT(prGlueInfo); -+ /* <1> Sanity check and acquire the net_device */ -+ prDev = prGlueInfo->prP2PInfo->prDevHandler; -+ ASSERT(prDev); -+ -+ /* <3> get the IPv4 address */ -+ if (!prDev || !(prDev->ip_ptr) || -+ !((struct in_device *)(prDev->ip_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(P2P, INFO, "ip is not available.\n"); -+ return; -+ } -+ /* <4> copy the IPv4 address */ -+ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); -+ -+ /* todo: traverse between list to find whole sets of IPv4 addresses */ -+ if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0))) -+ u4NumIPv4++; -+#ifdef CONFIG_IPV6 -+ /* <5> get the IPv6 address */ -+ if (!prDev || !(prDev->ip6_ptr) || -+ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(P2P, INFO, "ipv6 is not available.\n"); -+ return; -+ } -+ /* <6> copy the IPv6 address */ -+ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); -+ DBGLOG(P2P, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", -+ ip6[0], ip6[1], ip6[2], ip6[3], -+ ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]); -+ /* todo: traverse between list to find whole sets of IPv6 addresses */ -+ -+ if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) -+ ; /* Do nothing */ -+#endif -+ /* <7> set up the ARP filter */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_32 u4SetInfoLen = 0; -+/* UINT_8 aucBuf[32] = {0}; */ -+ UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress); -+ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; -+ /* aucBuf; */ -+ P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress; -+ -+ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); -+ -+ prParamNetAddrList->u4AddressCount = u4NumIPv4; -+#ifdef CONFIG_IPV6 -+ prParamNetAddrList->u4AddressCount += u4NumIPv6; -+#endif -+ -+ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ for (i = 0; i < u4NumIPv4; i++) { -+ prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */ -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+#if 0 -+ kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip)); -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr + sizeof(ip)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip); -+#else -+ prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress; -+ kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip)); -+ -+/* prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); -+// TODO: frog. The pointer is not right. */ -+ -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + -+ (ULONG) (prParamNetAddr->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, -+ aucAddress))); -+ -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP); -+#endif -+ } -+#ifdef CONFIG_IPV6 -+ for (i = 0; i < u4NumIPv6; i++) { -+ prParamNetAddr->u2AddressLength = 6; -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6)); -+/* prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip6)); */ -+ -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + -+ (ULONG) (prParamNetAddr->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, -+ aucAddress))); -+ -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); -+ } -+#endif -+ ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2pSetNetworkAddress, -+ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus); -+ } -+} -+ -+void p2pHandleSystemResume(void) -+{ -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_8 ip[4] = { 0 }; -+#ifdef CONFIG_IPV6 -+ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ -+#endif -+ -+ if (!wlanExportGlueInfo(&prGlueInfo)) { -+ DBGLOG(P2P, WARN, "no glue info\n"); -+ return; -+ } -+ -+ ASSERT(prGlueInfo); -+ /* <1> Sanity check and acquire the net_device */ -+ prDev = prGlueInfo->prP2PInfo->prDevHandler; -+ ASSERT(prDev); -+ -+ /* <3> get the IPv4 address */ -+ if (!prDev || !(prDev->ip_ptr) || -+ !((struct in_device *)(prDev->ip_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(P2P, INFO, "ip is not available.\n"); -+ return; -+ } -+ /* <4> copy the IPv4 address */ -+ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); -+ -+#ifdef CONFIG_IPV6 -+ /* <5> get the IPv6 address */ -+ if (!prDev || !(prDev->ip6_ptr) || -+ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(P2P, INFO, "ipv6 is not available.\n"); -+ return; -+ } -+ /* <6> copy the IPv6 address */ -+ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); -+ DBGLOG(P2P, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", -+ ip6[0], ip6[1], ip6[2], ip6[3], -+ ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]); -+#endif -+ /* <7> clear the ARP filter */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_32 u4SetInfoLen = 0; -+/* UINT_8 aucBuf[32] = {0}; */ -+ UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST); -+ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; -+ /* aucBuf; */ -+ -+ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); -+ -+ prParamNetAddrList->u4AddressCount = 0; -+ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ -+ ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */)); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2pSetNetworkAddress, -+ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* run p2p init procedure, include register pointer to wlan -+* glue register p2p -+* set p2p registered flag -+* \retval 1 Success -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pLaunch(P_GLUE_INFO_T prGlueInfo) -+{ -+ -+ DBGLOG(P2P, TRACE, "p2pLaunch\n"); -+ -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE) { -+ DBGLOG(P2P, INFO, "p2p already registered\n"); -+ return FALSE; -+ } else if (glRegisterP2P(prGlueInfo, ifname, (BOOLEAN) mode)) { -+ prGlueInfo->prAdapter->fgIsP2PRegistered = TRUE; -+ -+ DBGLOG(P2P, TRACE, "Launch success, fgIsP2PRegistered TRUE.\n"); -+ return TRUE; -+ } -+ DBGLOG(P2P, ERROR, "Launch Fail\n"); -+ -+ return FALSE; -+} -+ -+VOID p2pSetMode(IN BOOLEAN fgIsAPMOde) -+{ -+ if (fgIsAPMOde) { -+ mode = RUNNING_AP_MODE; -+ ifname = AP_MODE_INF_NAME; -+ } else { -+ mode = RUNNING_P2P_MODE; -+ ifname = P2P_MODE_INF_NAME; -+ } -+ -+} /* p2pSetMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* run p2p exit procedure, include unregister pointer to wlan -+* glue unregister p2p -+* set p2p registered flag -+ -+* \retval 1 Success -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pRemove(P_GLUE_INFO_T prGlueInfo) -+{ -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) { -+ DBGLOG(P2P, INFO, "p2p is not Registered.\n"); -+ return FALSE; -+ } -+ /*Check p2p fsm is stop or not. If not then stop now */ -+ if (IS_P2P_ACTIVE(prGlueInfo->prAdapter)) -+ p2pStopImmediate(prGlueInfo); -+ prGlueInfo->prAdapter->fgIsP2PRegistered = FALSE; -+ glUnregisterP2P(prGlueInfo); -+ /*p2p is removed successfully */ -+ return TRUE; -+ -+} -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver entry point when the driver is configured as a Linux Module, and -+* is called once at module load time, by the user-level modutils -+* application: insmod or modprobe. -+* -+* \retval 0 Success -+*/ -+/*----------------------------------------------------------------------------*/ -+static int initP2P(void) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ /*check interface name validation */ -+ p2pCheckInterfaceName(); -+ -+ DBGLOG(P2P, INFO, "InitP2P, Ifname: %s, Mode: %s\n", ifname, mode ? "AP" : "P2P"); -+ -+ /*register p2p init & exit function to wlan sub module handler */ -+ wlanSubModRegisterInitExit(p2pLaunch, p2pRemove, P2P_MODULE); -+ -+ /*if wlan is not start yet, do nothing -+ * p2pLaunch will be called by txthread while wlan start -+ */ -+ /*if wlan is not started yet, return FALSE */ -+ if (wlanExportGlueInfo(&prGlueInfo)) { -+ wlanSubModInit(prGlueInfo); -+ return prGlueInfo->prAdapter->fgIsP2PRegistered ? 0 : -EIO; -+ } -+ -+ return 0; -+} /* end of initP2P() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver exit point when the driver as a Linux Module is removed. Called -+* at module unload time, by the user level modutils application: rmmod. -+* This is our last chance to clean up after ourselves. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+/* 1 Module Leave Point */ -+static VOID __exit exitP2P(void) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ DBGLOG(P2P, INFO, KERN_INFO DRV_NAME "ExitP2P\n"); -+ -+ /*if wlan is not started yet, return FALSE */ -+ if (wlanExportGlueInfo(&prGlueInfo)) -+ wlanSubModExit(prGlueInfo); -+ /*UNregister p2p init & exit function to wlan sub module handler */ -+ wlanSubModRegisterInitExit(NULL, NULL, P2P_MODULE); -+} /* end of exitP2P() */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c -new file mode 100644 -index 0000000000000..11a417e4c74c9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c -@@ -0,0 +1,1314 @@ -+/* -+** Id: @(#) gl_p2p_cfg80211.c@@ -+*/ -+ -+/*! \file gl_p2p_kal.c -+ \brief -+ -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "net/cfg80211.h" -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Wi-Fi Direct state from glue layer -+* -+* \param[in] -+* prGlueInfo -+* rPeerAddr -+* \return -+* ENUM_BOW_DEVICE_STATE -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_PARAM_MEDIA_STATE_T kalP2PGetState(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->prP2PInfo->eState; -+} /* end of kalP2PGetState() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to update the assoc req to p2p -+* -+* \param[in] -+* prGlueInfo -+* pucFrameBody -+* u4FrameBodyLen -+* fgReassocRequest -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalP2PUpdateAssocInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest) -+{ -+ union iwreq_data wrqu; -+ unsigned char *pucExtraInfo = NULL; -+ unsigned char *pucDesiredIE = NULL; -+/* unsigned char aucExtraInfoBuf[200]; */ -+ PUINT_8 cp; -+ -+ memset(&wrqu, 0, sizeof(wrqu)); -+ -+ if (fgReassocRequest) { -+ if (u4FrameBodyLen < 15) { -+ /* -+ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); -+ */ -+ return; -+ } -+ } else { -+ if (u4FrameBodyLen < 9) { -+ /* -+ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); -+ */ -+ return; -+ } -+ } -+ -+ cp = pucFrameBody; -+ -+ if (fgReassocRequest) { -+ /* Capability information field 2 */ -+ /* Listen interval field 2 */ -+ /* Current AP address 6 */ -+ cp += 10; -+ u4FrameBodyLen -= 10; -+ } else { -+ /* Capability information field 2 */ -+ /* Listen interval field 2 */ -+ cp += 4; -+ u4FrameBodyLen -= 4; -+ } -+ -+ /* do supplicant a favor, parse to the start of WPA/RSN IE */ -+ if (wextSrchDesiredWPSIE(cp, u4FrameBodyLen, 0xDD, &pucDesiredIE)) { -+ /* printk("wextSrchDesiredWPSIE!!\n"); */ -+ /* WPS IE found */ -+ } else if (wextSrchDesiredWPAIE(cp, u4FrameBodyLen, 0x30, &pucDesiredIE)) { -+ /* printk("wextSrchDesiredWPAIE!!\n"); */ -+ /* RSN IE found */ -+ } else if (wextSrchDesiredWPAIE(cp, u4FrameBodyLen, 0xDD, &pucDesiredIE)) { -+ /* printk("wextSrchDesiredWPAIE!!\n"); */ -+ /* WPA IE found */ -+ } else { -+ /* no WPA/RSN IE found, skip this event */ -+ goto skip_indicate_event; -+ } -+ -+ /* IWEVASSOCREQIE, indicate binary string */ -+ pucExtraInfo = pucDesiredIE; -+ wrqu.data.length = pucDesiredIE[1] + 2; -+ -+ /* Send event to user space */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVASSOCREQIE, &wrqu, pucExtraInfo); -+ -+skip_indicate_event: -+ return; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set Wi-Fi Direct state in glue layer -+* -+* \param[in] -+* prGlueInfo -+* eBowState -+* rPeerAddr -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalP2PSetState(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_PARAM_MEDIA_STATE_T eState, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucRole) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ if (eState == PARAM_MEDIA_STATE_CONNECTED) { -+ prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_CONNECTED; -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_STA_CONNECT=%pM ", rPeerAddr); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate in IWECUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+ } else if (eState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_STA_DISCONNECT=%pM ", rPeerAddr); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate in IWECUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ } else { -+ ASSERT(0); -+ } -+ -+} /* end of kalP2PSetState() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Wi-Fi Direct operating frequency -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* in unit of KHz -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalP2PGetFreqInKHz(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->prP2PInfo->u4FreqInKHz; -+} /* end of kalP2PGetFreqInKHz() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi role -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* 0: P2P Device -+* 1: Group Client -+* 2: Group Owner -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 kalP2PGetRole(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->prP2PInfo->ucRole; -+} /* end of kalP2PGetRole() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set Wi-Fi Direct role -+* -+* \param[in] -+* prGlueInfo -+* ucResult -+* 0: successful -+* 1: error -+* ucRole -+* 0: P2P Device -+* 1: Group Client -+* 2: Group Owner -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalP2PSetRole(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_8 ucResult, IN PUINT_8 pucSSID, IN UINT_8 ucSSIDLen, IN UINT_8 ucRole) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(ucRole <= 2); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ if (ucResult == 0) -+ prGlueInfo->prP2PInfo->ucRole = ucRole; -+ -+ if (pucSSID) -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_FORMATION_RST=%d%d%d%c%c", ucResult, ucRole, -+ 1 /* persistence or not */ , pucSSID[7], pucSSID[8]); -+ else -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_FORMATION_RST=%d%d%d%c%c", ucResult, ucRole, -+ 1 /* persistence or not */ , '0', '0'); -+ -+ evt.data.length = strlen(aucBuffer); -+ -+ /* if (pucSSID) */ -+ /* printk("P2P GO SSID DIRECT-%c%c\n", pucSSID[7], pucSSID[8]); */ -+ -+ /* indicate in IWECUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* end of kalP2PSetRole() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set the cipher for p2p -+* -+* \param[in] -+* prGlueInfo -+* u4Cipher -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PSetCipher(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Cipher) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prGlueInfo->prP2PInfo->u4CipherPairwise = u4Cipher; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to get the cipher, return for cipher is ccmp -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* TRUE: cipher is ccmp -+* FALSE: cipher is none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalP2PGetCipher(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) -+ return TRUE; -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) -+ return TRUE; -+ -+ return FALSE; -+} -+ -+BOOLEAN kalP2PGetCcmpCipher(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) -+ return TRUE; -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) -+ return FALSE; -+ -+ return FALSE; -+} -+ -+BOOLEAN kalP2PGetTkipCipher(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) -+ return FALSE; -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) -+ return TRUE; -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set the status of WSC -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PSetWscMode(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucWscMode) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prGlueInfo->prP2PInfo->ucWSCRunning = ucWscMode; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to get the status of WSC -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 kalP2PGetWscMode(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return 0; -+ } -+ -+ return prGlueInfo->prP2PInfo->ucWSCRunning; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to get the wsc ie length -+* -+* \param[in] -+* prGlueInfo -+* ucType : 0 for beacon, 1 for probe req, 2 for probe resp -+* -+* \return -+* The WSC IE length -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_16 kalP2PCalWSC_IELen(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType) -+{ -+ ASSERT(prGlueInfo); -+ -+ ASSERT(ucType < 3); -+ -+ return prGlueInfo->prP2PInfo->u2WSCIELen[ucType]; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to copy the wsc ie setting from p2p supplicant -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* The WPS IE length -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PGenWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer) -+{ -+ P_GL_P2P_INFO_T prGlP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ -+ do { -+ if ((prGlueInfo == NULL) || (ucType >= 3) || (pucBuffer == NULL)) -+ break; -+ -+ prGlP2pInfo = prGlueInfo->prP2PInfo; -+ -+ kalMemCopy(pucBuffer, prGlP2pInfo->aucWSCIE[ucType], prGlP2pInfo->u2WSCIELen[ucType]); -+ -+ } while (FALSE); -+ -+} -+ -+VOID kalP2PUpdateWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer, IN UINT_16 u2BufferLength) -+{ -+ P_GL_P2P_INFO_T prGlP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ -+ do { -+ if ((prGlueInfo == NULL) || (ucType >= 3) || ((u2BufferLength > 0) && (pucBuffer == NULL))) -+ break; -+ -+ if (u2BufferLength > 400) { -+ DBGLOG(P2P, ERROR, -+ "Buffer length is not enough, GLUE only 400 bytes but %d received\n", u2BufferLength); -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlP2pInfo = prGlueInfo->prP2PInfo; -+ -+ kalMemCopy(prGlP2pInfo->aucWSCIE[ucType], pucBuffer, u2BufferLength); -+ -+ prGlP2pInfo->u2WSCIELen[ucType] = u2BufferLength; -+ -+ } while (FALSE); -+ -+} /* kalP2PUpdateWSC_IE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief indicate an event to supplicant for device connection request -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PIndicateConnReq(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucDevName, IN INT_32 u4NameLength, -+ IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucDevType, /* 0: P2P Device / 1: GC / 2: GO */ -+ IN INT_32 i4ConfigMethod, IN INT_32 i4ActiveConfigMethod) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ /* buffer peer information for later IOC_P2P_GET_REQ_DEVICE_INFO access */ -+ prGlueInfo->prP2PInfo->u4ConnReqNameLength = u4NameLength > 32 ? 32 : u4NameLength; -+ kalMemCopy(prGlueInfo->prP2PInfo->aucConnReqDevName, pucDevName, prGlueInfo->prP2PInfo->u4ConnReqNameLength); -+ COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqPeerAddr, rPeerAddr); -+ prGlueInfo->prP2PInfo->ucConnReqDevType = ucDevType; -+ prGlueInfo->prP2PInfo->i4ConnReqConfigMethod = i4ConfigMethod; -+ prGlueInfo->prP2PInfo->i4ConnReqActiveConfigMethod = i4ActiveConfigMethod; -+ -+ /* prepare event structure */ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_DVC_REQ"); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate in IWEVCUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* end of kalP2PIndicateConnReq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Indicate an event to supplicant for device connection request from other device. -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* \param[in] pucGroupBssid Only valid when invitation Type equals to 0. -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalP2PInvitationIndication(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_P2P_DEVICE_DESC_T prP2pDevDesc, -+ IN PUINT_8 pucSsid, -+ IN UINT_8 ucSsidLen, -+ IN UINT_8 ucOperatingChnl, IN UINT_8 ucInvitationType, IN PUINT_8 pucGroupBssid) -+{ -+#if 1 -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ /* buffer peer information for later IOC_P2P_GET_STRUCT access */ -+ prGlueInfo->prP2PInfo->u4ConnReqNameLength = -+ (UINT_32) ((prP2pDevDesc->u2NameLength > 32) ? 32 : prP2pDevDesc->u2NameLength); -+ kalMemCopy(prGlueInfo->prP2PInfo->aucConnReqDevName, prP2pDevDesc->aucName, -+ prGlueInfo->prP2PInfo->u4ConnReqNameLength); -+ COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqPeerAddr, prP2pDevDesc->aucDeviceAddr); -+ COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqGroupAddr, pucGroupBssid); -+ prGlueInfo->prP2PInfo->i4ConnReqConfigMethod = (INT_32) (prP2pDevDesc->u2ConfigMethod); -+ prGlueInfo->prP2PInfo->ucOperatingChnl = ucOperatingChnl; -+ prGlueInfo->prP2PInfo->ucInvitationType = ucInvitationType; -+ -+ /* prepare event structure */ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_INV_INDICATE"); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate in IWEVCUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ return; -+ -+#else -+ P_MSG_P2P_CONNECTION_REQUEST_T prP2pConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prGlueInfo != NULL) && (prP2pDevDesc != NULL)); -+ -+ /* Not a real solution */ -+ -+ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; -+ -+ prP2pConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, -+ sizeof(MSG_P2P_CONNECTION_REQUEST_T)); -+ -+ if (prP2pConnReq == NULL) -+ break; -+ -+ kalMemZero(prP2pConnReq, sizeof(MSG_P2P_CONNECTION_REQUEST_T)); -+ -+ prP2pConnReq->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; -+ -+ prP2pConnReq->eFormationPolicy = ENUM_P2P_FORMATION_POLICY_AUTO; -+ -+ COPY_MAC_ADDR(prP2pConnReq->aucDeviceID, prP2pDevDesc->aucDeviceAddr); -+ -+ prP2pConnReq->u2ConfigMethod = prP2pDevDesc->u2ConfigMethod; -+ -+ if (ucInvitationType == P2P_INVITATION_TYPE_INVITATION) { -+ prP2pConnReq->fgIsPersistentGroup = FALSE; -+ prP2pConnReq->fgIsTobeGO = FALSE; -+ -+ } -+ -+ else if (ucInvitationType == P2P_INVITATION_TYPE_REINVOKE) { -+ DBGLOG(P2P, TRACE, "Re-invoke Persistent Group\n"); -+ prP2pConnReq->fgIsPersistentGroup = TRUE; -+ prP2pConnReq->fgIsTobeGO = (prGlueInfo->prP2PInfo->ucRole == 2) ? TRUE : FALSE; -+ -+ } -+ -+ p2pFsmRunEventDeviceDiscoveryAbort(prGlueInfo->prAdapter, NULL); -+ -+ if (ucOperatingChnl != 0) -+ prP2pSpecificBssInfo->ucPreferredChannel = ucOperatingChnl; -+ -+ if ((ucSsidLen < 32) && (pucSsid != NULL)) -+ COPY_SSID(prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen, pucSsid, ucSsidLen); -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pConnReq, MSG_SEND_METHOD_BUF); -+ -+ } while (FALSE); -+ -+ /* frog add. */ -+ /* TODO: Invitation Indication */ -+ -+ return; -+#endif -+ -+} /* kalP2PInvitationIndication */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Indicate an status to supplicant for device invitation status. -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PInvitationStatus(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4InvStatus) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ /* buffer peer information for later IOC_P2P_GET_STRUCT access */ -+ prGlueInfo->prP2PInfo->u4InvStatus = u4InvStatus; -+ -+ /* prepare event structure */ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_INV_STATUS"); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate in IWEVCUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* kalP2PInvitationStatus */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Indicate an event to supplicant for Service Discovery request from other device. -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PIndicateSDRequest(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_REQ %d", ucSeqNum); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate IWEVP2PSDREQ event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* end of kalP2PIndicateSDRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Indicate an event to supplicant for Service Discovery response -+* from other device. -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+void kalP2PIndicateSDResponse(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_RESP %d", ucSeqNum); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate IWEVP2PSDREQ event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* end of kalP2PIndicateSDResponse() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Indicate an event to supplicant for Service Discovery TX Done -+* from other device. -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* \param[in] ucSeqNum Sequence number of the frame -+* \param[in] ucStatus Status code for TX -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PIndicateTXDone(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucSeqNum, IN UINT_8 ucStatus) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_XMITTED: %d %d", ucSeqNum, ucStatus); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate IWEVP2PSDREQ event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* end of kalP2PIndicateSDResponse() */ -+ -+struct net_device *kalP2PGetDevHdlr(P_GLUE_INFO_T prGlueInfo) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return NULL; -+ } -+ -+ return prGlueInfo->prP2PInfo->prDevHandler; -+} -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PIndicateSecCheckRsp(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucRsp, IN UINT_16 u2RspLen) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SEC_CHECK_RSP="); -+ -+ kalMemCopy(prGlueInfo->prP2PInfo->aucSecCheckRsp, pucRsp, u2RspLen); -+ evt.data.length = strlen(aucBuffer); -+ -+#if DBG -+ DBGLOG_MEM8(SEC, LOUD, prGlueInfo->prP2PInfo->aucSecCheckRsp, u2RspLen); -+#endif -+ /* indicate in IWECUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+} /* p2pFsmRunEventRxDisassociation */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalGetChnlList(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_BAND_T eSpecificBand, -+ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList) -+{ -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, eSpecificBand, FALSE, ucMaxChannelNum, -+ pucNumOfChannel, paucChannelList); -+} /* kalGetChnlList */ -+ -+/* ////////////////////////////////////ICS SUPPORT////////////////////////////////////// */ -+ -+VOID -+kalP2PIndicateChannelReady(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8SeqNum, -+ IN UINT_32 u4ChannelNum, -+ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_32 u4Duration) -+{ -+ struct ieee80211_channel *prIEEE80211ChnlStruct = (struct ieee80211_channel *)NULL; -+ RF_CHANNEL_INFO_T rChannelInfo; -+ enum nl80211_channel_type eChnlType = NL80211_CHAN_NO_HT; -+ -+ do { -+ if (prGlueInfo == NULL) -+ break; -+ -+ kalMemZero(&rChannelInfo, sizeof(RF_CHANNEL_INFO_T)); -+ -+ rChannelInfo.ucChannelNum = u4ChannelNum; -+ rChannelInfo.eBand = eBand; -+ -+ prIEEE80211ChnlStruct = kalP2pFuncGetChannelEntry(prGlueInfo->prP2PInfo, &rChannelInfo); -+ -+ kalP2pFuncGetChannelType(eSco, &eChnlType); -+ -+ cfg80211_ready_on_channel(prGlueInfo->prP2PInfo->prWdev, /* struct wireless_dev, */ -+ u8SeqNum, /* u64 cookie, */ -+ prIEEE80211ChnlStruct, /* struct ieee80211_channel * chan, */ -+ u4Duration, /* unsigned int duration, */ -+ GFP_KERNEL); /* gfp_t gfp */ /* allocation flags */ -+ } while (FALSE); -+ -+} /* kalP2PIndicateChannelReady */ -+ -+VOID kalP2PIndicateChannelExpired(IN P_GLUE_INFO_T prGlueInfo, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo) -+{ -+ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ struct ieee80211_channel *prIEEE80211ChnlStruct = (struct ieee80211_channel *)NULL; -+ enum nl80211_channel_type eChnlType = NL80211_CHAN_NO_HT; -+ RF_CHANNEL_INFO_T rRfChannelInfo; -+ -+ do { -+ if ((prGlueInfo == NULL) || (prChnlReqInfo == NULL)) { -+ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ if (prGlueP2pInfo == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "kalP2PIndicateChannelExpired\n"); -+ -+ rRfChannelInfo.eBand = prChnlReqInfo->eBand; -+ rRfChannelInfo.ucChannelNum = prChnlReqInfo->ucReqChnlNum; -+ -+ prIEEE80211ChnlStruct = kalP2pFuncGetChannelEntry(prGlueP2pInfo, &rRfChannelInfo); -+ -+ kalP2pFuncGetChannelType(prChnlReqInfo->eChnlSco, &eChnlType); -+ -+ cfg80211_remain_on_channel_expired(prGlueP2pInfo->prWdev, /* struct wireless_dev, */ -+ prChnlReqInfo->u8Cookie, prIEEE80211ChnlStruct, GFP_KERNEL); -+ } while (FALSE); -+ -+} /* kalP2PIndicateChannelExpired */ -+ -+VOID kalP2PIndicateScanDone(IN P_GLUE_INFO_T prGlueInfo, IN BOOLEAN fgIsAbort) -+{ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ struct cfg80211_scan_request *prScanRequest = NULL; -+ struct cfg80211_scan_info info = { -+ .aborted = true, -+ }; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ do { -+ if (prGlueInfo == NULL) { -+ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ if (prGlueP2pInfo == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ DBGLOG(INIT, TRACE, "[p2p] scan complete %p\n", prGlueP2pInfo->prScanRequest); -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueP2pInfo->prScanRequest != NULL) { -+ prScanRequest = prGlueP2pInfo->prScanRequest; -+ prGlueP2pInfo->prScanRequest = NULL; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ /* 2. then CFG80211 Indication */ -+ -+ if (prScanRequest != NULL) { -+ -+ /* report all queued beacon/probe response frames to upper layer */ -+ scanReportBss2Cfg80211(prGlueInfo->prAdapter, BSS_TYPE_P2P_DEVICE, NULL); -+ -+ info.aborted = fgIsAbort; -+ DBGLOG(INIT, TRACE, "DBG:p2p_cfg_scan_done\n"); -+ cfg80211_scan_done(prScanRequest, &info); -+ } -+ -+ } while (FALSE); -+ -+} /* kalP2PIndicateScanDone */ -+ -+VOID -+kalP2PIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBuf, -+ IN UINT_32 u4BufLen, IN P_RF_CHANNEL_INFO_T prChannelInfo, IN INT_32 i4SignalStrength) -+{ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ struct ieee80211_channel *prChannelEntry = (struct ieee80211_channel *)NULL; -+ struct ieee80211_mgmt *prBcnProbeRspFrame = (struct ieee80211_mgmt *)pucFrameBuf; -+ struct cfg80211_bss *prCfg80211Bss = (struct cfg80211_bss *)NULL; -+ -+ do { -+ if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (prChannelInfo == NULL)) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ if (prGlueP2pInfo == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prChannelEntry = kalP2pFuncGetChannelEntry(prGlueP2pInfo, prChannelInfo); -+ -+ if (prChannelEntry == NULL) { -+ DBGLOG(P2P, WARN, "Unknown channel info\n"); -+ break; -+ } -+ /* rChannelInfo.center_freq = nicChannelNum2Freq((UINT_32)prChannelInfo->ucChannelNum) / 1000; */ -+ -+ prCfg80211Bss = cfg80211_inform_bss_frame(prGlueP2pInfo->prWdev->wiphy, /* struct wiphy * wiphy, */ -+ prChannelEntry, -+ prBcnProbeRspFrame, u4BufLen, i4SignalStrength, GFP_KERNEL); -+ -+ /* Return this structure. */ -+ if (!prCfg80211Bss) { -+ DBGLOG(P2P, WARN, "inform bss to cfg80211 failed, bss channel %d, rcpi %d\n", -+ prChannelInfo->ucChannelNum, i4SignalStrength); -+ } else { -+ cfg80211_put_bss(prGlueP2pInfo->prWdev->wiphy, prCfg80211Bss); -+ DBGLOG(P2P, TRACE, "inform bss to cfg80211, bss channel %d, rcpi %d\n", -+ prChannelInfo->ucChannelNum, i4SignalStrength); -+ } -+ } while (FALSE); -+ -+} /* kalP2PIndicateBssInfo */ -+ -+VOID -+kalP2PIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen) -+{ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ -+ do { -+ if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (u4FrameLen == 0)) { -+ DBGLOG(P2P, TRACE, "Unexpected pointer PARAM. %p, %p, %u.", -+ prGlueInfo, pucFrameBuf, u4FrameLen); -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ cfg80211_mgmt_tx_status(prGlueP2pInfo->prWdev, /* struct net_device * dev, */ -+ u8Cookie, pucFrameBuf, u4FrameLen, fgIsAck, GFP_KERNEL); -+ -+ } while (FALSE); -+ -+} /* kalP2PIndicateMgmtTxStatus */ -+ -+VOID kalP2PIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb) -+{ -+#define DBG_P2P_MGMT_FRAME_INDICATION 0 -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ INT_32 i4Freq = 0; -+ UINT_8 ucChnlNum = 0; -+#if DBG_P2P_MGMT_FRAME_INDICATION -+ P_WLAN_MAC_HEADER_T prWlanHeader = (P_WLAN_MAC_HEADER_T) NULL; -+#endif -+ -+ do { -+ if ((prGlueInfo == NULL) || (prSwRfb == NULL)) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ ucChnlNum = prSwRfb->prHifRxHdr->ucHwChannelNum; -+ -+#if DBG_P2P_MGMT_FRAME_INDICATION -+ -+ prWlanHeader = (P_WLAN_MAC_HEADER_T) prSwRfb->pvHeader; -+ -+ switch (prWlanHeader->u2FrameCtrl) { -+ case MAC_FRAME_PROBE_REQ: -+ DBGLOG(P2P, TRACE, "RX Probe Req at channel %d ", ucChnlNum); -+ break; -+ case MAC_FRAME_PROBE_RSP: -+ DBGLOG(P2P, TRACE, "RX Probe Rsp at channel %d ", ucChnlNum); -+ break; -+ case MAC_FRAME_ACTION: -+ DBGLOG(P2P, TRACE, "RX Action frame at channel %d ", ucChnlNum); -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "RX Packet:%d at channel %d ", prWlanHeader->u2FrameCtrl, ucChnlNum); -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "from: %pM\n", prWlanHeader->aucAddr2); -+#endif -+ i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000; -+ -+ cfg80211_rx_mgmt(prGlueP2pInfo->prWdev, /* struct net_device * dev, */ -+ i4Freq, -+ RCPI_TO_dBm(prSwRfb->prHifRxHdr->ucRcpi), -+ prSwRfb->pvHeader, prSwRfb->u2PacketLen, GFP_ATOMIC); -+ } while (FALSE); -+ -+} /* kalP2PIndicateRxMgmtFrame */ -+ -+VOID -+kalP2PGCIndicateConnectionStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_P2P_CONNECTION_REQ_INFO_T prP2pConnInfo, -+ IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELen, IN UINT_16 u2StatusReason, -+ IN WLAN_STATUS eStatus) -+{ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ -+ do { -+ if (prGlueInfo == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ if (prP2pConnInfo) { -+ cfg80211_connect_result(prGlueP2pInfo->prDevHandler, /* struct net_device * dev, */ -+ prP2pConnInfo->aucBssid, prP2pConnInfo->aucIEBuf, -+ prP2pConnInfo->u4BufLength, -+ pucRxIEBuf, u2RxIELen, u2StatusReason, GFP_KERNEL); -+ /* gfp_t gfp */ /* allocation flags */ -+ prP2pConnInfo->fgIsConnRequest = FALSE; -+ } else { -+ /* Disconnect, what if u2StatusReason == 0? */ -+ cfg80211_disconnected(prGlueP2pInfo->prDevHandler, /* struct net_device * dev, */ -+ u2StatusReason, pucRxIEBuf, u2RxIELen, -+ eStatus == WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY ? true : false, -+ GFP_KERNEL); -+ } -+ -+ } while (FALSE); -+ -+} /* kalP2PGCIndicateConnectionStatus */ -+ -+VOID kalP2PGOStationUpdate(IN P_GLUE_INFO_T prGlueInfo, IN P_STA_RECORD_T prCliStaRec, IN BOOLEAN fgIsNew) -+{ -+ P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL; -+ struct station_info rStationInfo; -+ -+ memset(&rStationInfo, 0, sizeof(struct station_info)); -+ -+ do { -+ if ((prGlueInfo == NULL) || (prCliStaRec == NULL)) -+ break; -+ -+ prP2pGlueInfo = prGlueInfo->prP2PInfo; -+ -+ if (fgIsNew) { -+ //rStationInfo.filled = STATION_INFO_ASSOC_REQ_IES; -+ rStationInfo.generation = ++prP2pGlueInfo->i4Generation; -+ -+ rStationInfo.assoc_req_ies = prCliStaRec->pucAssocReqIe; -+ rStationInfo.assoc_req_ies_len = prCliStaRec->u2AssocReqIeLen; -+/* rStationInfo.filled |= STATION_INFO_ASSOC_REQ_IES; */ -+ -+ cfg80211_new_sta(prGlueInfo->prP2PInfo->prDevHandler, /* struct net_device * dev, */ -+ prCliStaRec->aucMacAddr, &rStationInfo, GFP_KERNEL); -+ } else { -+ ++prP2pGlueInfo->i4Generation; -+ -+ cfg80211_del_sta(prGlueInfo->prP2PInfo->prDevHandler, /* struct net_device * dev, */ -+ prCliStaRec->aucMacAddr, GFP_KERNEL); -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* kalP2PGOStationUpdate */ -+ -+BOOLEAN kalP2pFuncGetChannelType(IN ENUM_CHNL_EXT_T rChnlSco, OUT enum nl80211_channel_type *channel_type) -+{ -+ BOOLEAN fgIsValid = FALSE; -+ -+ do { -+ if (channel_type) { -+ -+ switch (rChnlSco) { -+ case CHNL_EXT_SCN: -+ *channel_type = NL80211_CHAN_NO_HT; -+ break; -+ case CHNL_EXT_SCA: -+ *channel_type = NL80211_CHAN_HT40MINUS; -+ break; -+ case CHNL_EXT_SCB: -+ *channel_type = NL80211_CHAN_HT40PLUS; -+ break; -+ default: -+ ASSERT(FALSE); -+ *channel_type = NL80211_CHAN_NO_HT; -+ break; -+ } -+ -+ } -+ -+ fgIsValid = TRUE; -+ } while (FALSE); -+ -+ return fgIsValid; -+} /* kalP2pFuncGetChannelType */ -+ -+struct ieee80211_channel *kalP2pFuncGetChannelEntry(IN P_GL_P2P_INFO_T prP2pInfo, IN P_RF_CHANNEL_INFO_T prChannelInfo) -+{ -+ struct ieee80211_channel *prTargetChannelEntry = (struct ieee80211_channel *)NULL; -+ UINT_32 u4TblSize = 0, u4Idx = 0; -+ struct ieee80211_supported_band **bands; -+ -+ do { -+ if ((prP2pInfo == NULL) || (prChannelInfo == NULL)) -+ break; -+ bands = &prP2pInfo->prWdev->wiphy->bands[0]; -+ switch (prChannelInfo->eBand) { -+ case BAND_2G4: -+ prTargetChannelEntry = bands[NL80211_BAND_2GHZ]->channels; -+ u4TblSize = bands[NL80211_BAND_2GHZ]->n_channels; -+ break; -+ case BAND_5G: -+ prTargetChannelEntry = bands[NL80211_BAND_5GHZ]->channels; -+ u4TblSize = bands[NL80211_BAND_5GHZ]->n_channels; -+ break; -+ default: -+ break; -+ } -+ -+ if (prTargetChannelEntry == NULL) -+ break; -+ -+ for (u4Idx = 0; u4Idx < u4TblSize; u4Idx++, prTargetChannelEntry++) { -+ if (prTargetChannelEntry->hw_value == prChannelInfo->ucChannelNum) -+ break; -+ } -+ -+ if (u4Idx == u4TblSize) { -+ prTargetChannelEntry = NULL; -+ break; -+ } -+ -+ } while (FALSE); -+ -+ return prTargetChannelEntry; -+} /* kalP2pFuncGetChannelEntry */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set the block list of Hotspot -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+INT_32 kalP2PSetBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid, IN BOOLEAN fgIsblock) -+{ -+ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; -+ UINT_32 i; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prGlueInfo->prP2PInfo); -+ -+ if (EQUAL_MAC_ADDR(rbssid, aucNullAddr)) -+ return -EINVAL; -+ -+ if (fgIsblock) { -+ for (i = 0; i < 8; i++) { -+ if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) { -+ break; -+ } else if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), aucNullAddr)) { -+ COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid); -+ break; -+ } -+ } -+ if (i >= 8) { -+ DBGLOG(P2P, ERROR, "AP black list is full, cannot block more STA!!\n"); -+ return -ENOBUFS; -+ } -+ } else { -+ for (i = 0; i < 8; i++) { -+ if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) { -+ COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), aucNullAddr); -+ break; -+ } -+ } -+ if (i >= 8) -+ DBGLOG(P2P, ERROR, "The STA is not found in black list!!\n"); -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to compare the black list of Hotspot -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalP2PCmpBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid) -+{ -+ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; -+ BOOLEAN fgIsExsit = FALSE; -+ UINT_32 i; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prGlueInfo->prP2PInfo); -+ -+ for (i = 0; i < 8; i++) { -+ if (UNEQUAL_MAC_ADDR(rbssid, aucNullAddr)) { -+ if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) { -+ fgIsExsit = TRUE; -+ return fgIsExsit; -+ } -+ } -+ } -+ -+ return fgIsExsit; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to return the max clients of Hotspot -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PSetMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4MaxClient) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ if (u4MaxClient == 0 || prGlueInfo->prP2PInfo->ucMaxClients >= P2P_MAXIMUM_CLIENT_COUNT) -+ prGlueInfo->prP2PInfo->ucMaxClients = P2P_MAXIMUM_CLIENT_COUNT; -+ else -+ prGlueInfo->prP2PInfo->ucMaxClients = u4MaxClient; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to return the max clients of Hotspot -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalP2PMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4NumClient) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ if (prGlueInfo->prP2PInfo->ucMaxClients) { -+ if ((UINT_8) u4NumClient > prGlueInfo->prP2PInfo->ucMaxClients) -+ return TRUE; -+ else -+ return FALSE; -+ } -+ -+ return FALSE; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c -new file mode 100644 -index 0000000000000..075045f547b7c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c -@@ -0,0 +1,1020 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_proc.c#1 -+*/ -+ -+/*! \file "gl_proc.c" -+ \brief This file defines the interface which can interact with users in /proc fs. -+ -+ Detail description. -+*/ -+ -+/* -+** Log: gl_proc.c -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 12 10 2010 kevin.huang -+ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check -+ * Add Linux Proc Support -+** \main\maintrunk.MT5921\19 2008-09-02 21:08:37 GMT mtk01461 -+** Fix the compile error of SPRINTF() -+** \main\maintrunk.MT5921\18 2008-08-10 18:48:28 GMT mtk01461 -+** Update for Driver Review -+** \main\maintrunk.MT5921\17 2008-08-04 16:52:01 GMT mtk01461 -+** Add proc dbg print message of DOMAIN_INDEX level -+** \main\maintrunk.MT5921\16 2008-07-10 00:45:16 GMT mtk01461 -+** Remove the check of MCR offset, we may use the MCR address which is not align to DW boundary or proprietary usage. -+** \main\maintrunk.MT5921\15 2008-06-03 20:49:44 GMT mtk01461 -+** \main\maintrunk.MT5921\14 2008-06-02 22:56:00 GMT mtk01461 -+** Rename some functions for linux proc -+** \main\maintrunk.MT5921\13 2008-06-02 20:23:18 GMT mtk01461 -+** Revise PROC mcr read / write for supporting TELNET -+** \main\maintrunk.MT5921\12 2008-03-28 10:40:25 GMT mtk01461 -+** Remove temporary set desired rate in linux proc -+** \main\maintrunk.MT5921\11 2008-01-07 15:07:29 GMT mtk01461 -+** Add User Update Desired Rate Set for QA in Linux -+** \main\maintrunk.MT5921\10 2007-12-11 00:11:14 GMT mtk01461 -+** Fix SPIN_LOCK protection -+** \main\maintrunk.MT5921\9 2007-12-04 18:07:57 GMT mtk01461 -+** Add additional debug category to proc -+** \main\maintrunk.MT5921\8 2007-11-02 01:03:23 GMT mtk01461 -+** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning -+** \main\maintrunk.MT5921\7 2007-10-25 18:08:14 GMT mtk01461 -+** Add VOIP SCAN Support & Refine Roaming -+** Revision 1.3 2007/07/05 07:25:33 MTK01461 -+** Add Linux initial code, modify doc, add 11BB, RF init code -+** -+** Revision 1.2 2007/06/27 02:18:51 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/* #include "wlan_lib.h" */ -+/* #include "debug.h" */ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define PROC_WLAN_THERMO "wlanThermo" -+#define PROC_DRV_STATUS "status" -+#define PROC_RX_STATISTICS "rx_statistics" -+#define PROC_TX_STATISTICS "tx_statistics" -+#define PROC_DBG_LEVEL_NAME "dbgLevel" -+#define PROC_NEED_TX_DONE "TxDoneCfg" -+#define PROC_AUTO_PER_CFG "autoPerCfg" -+#define PROC_ROOT_NAME "wlan" -+#define PROC_CMD_DEBUG_NAME "cmdDebug" -+ -+#define PROC_MCR_ACCESS_MAX_USER_INPUT_LEN 20 -+#define PROC_RX_STATISTICS_MAX_USER_INPUT_LEN 10 -+#define PROC_TX_STATISTICS_MAX_USER_INPUT_LEN 10 -+#define PROC_DBG_LEVEL_MAX_USER_INPUT_LEN (20*10) -+#define PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN 8 -+ -+#define PROC_UID_SHELL 2000 -+#define PROC_GID_WIFI 1010 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+/* static UINT_32 u4McrOffset; */ -+#if CFG_SUPPORT_THERMO_THROTTLING -+static P_GLUE_INFO_T g_prGlueInfo_proc; -+#endif -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reading MCR register to User Space, the offset of -+* the MCR is specified in u4McrOffset. -+* -+* \param[in] page Buffer provided by kernel. -+* \param[in out] start Start Address to read(3 methods). -+* \param[in] off Offset. -+* \param[in] count Allowable number to read. -+* \param[out] eof End of File indication. -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters print to the buffer from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+#if 0 -+static int procMCRRead(char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ PARAM_CUSTOM_MCR_RW_STRUCT_T rMcrInfo; -+ UINT_32 u4BufLen; -+ char *p = page; -+ UINT_32 u4Count; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(data); -+ -+ /* Kevin: Apply PROC read method 1. */ -+ if (off != 0) -+ return 0; /* To indicate end of file. */ -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv((struct net_device *)data)); -+ -+ rMcrInfo.u4McrOffset = u4McrOffset; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryMcrRead, -+ (PVOID)&rMcrInfo, sizeof(rMcrInfo), TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ -+ /* SPRINTF(p, ("MCR (0x%08lxh): 0x%08lx\n", */ -+ /* rMcrInfo.u4McrOffset, rMcrInfo.u4McrData)); */ -+ -+ u4Count = (UINT_32) (p - page); -+ -+ *eof = 1; -+ -+ return (int)u4Count; -+ -+} /* end of procMCRRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for writing MCR register to HW or update u4McrOffset -+* for reading MCR later. -+* -+* \param[in] file pointer to file. -+* \param[in] buffer Buffer from user space. -+* \param[in] count Number of characters to write -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters write from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procMCRWrite(struct file *file, const char *buffer, unsigned long count, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ char acBuf[PROC_MCR_ACCESS_MAX_USER_INPUT_LEN + 1]; /* + 1 for "\0" */ -+ int i4CopySize; -+ PARAM_CUSTOM_MCR_RW_STRUCT_T rMcrInfo; -+ UINT_32 u4BufLen; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(data); -+ -+ i4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); -+ if (copy_from_user(acBuf, buffer, i4CopySize)) -+ return 0; -+ acBuf[i4CopySize] = '\0'; -+ -+ if (sscanf(acBuf, "0x%lx 0x%lx", &rMcrInfo.u4McrOffset, &rMcrInfo.u4McrData) == 2) { -+ /* NOTE: Sometimes we want to test if bus will still be ok, after accessing -+ * the MCR which is not align to DW boundary. -+ */ -+ /* if (IS_ALIGN_4(rMcrInfo.u4McrOffset)) */ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv((struct net_device *)data)); -+ -+ u4McrOffset = rMcrInfo.u4McrOffset; -+ -+ /* printk("Write 0x%lx to MCR 0x%04lx\n", */ -+ /* rMcrInfo.u4McrOffset, rMcrInfo.u4McrData); */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetMcrWrite, -+ (PVOID)&rMcrInfo, sizeof(rMcrInfo), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ } -+ -+ if (sscanf(acBuf, "0x%lx 0x%lx", &rMcrInfo.u4McrOffset, &rMcrInfo.u4McrData) == 1) { -+ /* if (IS_ALIGN_4(rMcrInfo.u4McrOffset)) */ -+ u4McrOffset = rMcrInfo.u4McrOffset; -+ } -+ -+ return count; -+ -+} /* end of procMCRWrite() */ -+#endif -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reading Driver Status to User Space. -+* -+* \param[in] page Buffer provided by kernel. -+* \param[in out] start Start Address to read(3 methods). -+* \param[in] off Offset. -+* \param[in] count Allowable number to read. -+* \param[out] eof End of File indication. -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters print to the buffer from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procDrvStatusRead(char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; -+ char *p = page; -+ UINT_32 u4Count; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(data); -+ -+ /* Kevin: Apply PROC read method 1. */ -+ if (off != 0) -+ return 0; /* To indicate end of file. */ -+ -+ SPRINTF(p, ("GLUE LAYER STATUS:")); -+ SPRINTF(p, ("\n==================")); -+ -+ SPRINTF(p, ("\n* Number of Pending Frames: %ld\n", prGlueInfo->u4TxPendingFrameNum)); -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ wlanoidQueryDrvStatusForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); -+ -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ u4Count += (UINT_32) (p - page); -+ -+ *eof = 1; -+ -+ return (int)u4Count; -+ -+} /* end of procDrvStatusRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reading Driver RX Statistic Counters to User Space. -+* -+* \param[in] page Buffer provided by kernel. -+* \param[in out] start Start Address to read(3 methods). -+* \param[in] off Offset. -+* \param[in] count Allowable number to read. -+* \param[out] eof End of File indication. -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters print to the buffer from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procRxStatisticsRead(char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; -+ char *p = page; -+ UINT_32 u4Count; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(data); -+ -+ /* Kevin: Apply PROC read method 1. */ -+ if (off != 0) -+ return 0; /* To indicate end of file. */ -+ -+ SPRINTF(p, ("RX STATISTICS (Write 1 to clear):")); -+ SPRINTF(p, ("\n=================================\n")); -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ wlanoidQueryRxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); -+ -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ u4Count += (UINT_32) (p - page); -+ -+ *eof = 1; -+ -+ return (int)u4Count; -+ -+} /* end of procRxStatisticsRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reset Driver RX Statistic Counters. -+* -+* \param[in] file pointer to file. -+* \param[in] buffer Buffer from user space. -+* \param[in] count Number of characters to write -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters write from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procRxStatisticsWrite(struct file *file, const char *buffer, unsigned long count, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; -+ char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1]; /* + 1 for "\0" */ -+ UINT_32 u4CopySize; -+ UINT_32 u4ClearCounter; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(data); -+ -+ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); -+ copy_from_user(acBuf, buffer, u4CopySize); -+ acBuf[u4CopySize] = '\0'; -+ -+ if (kstrtoint(acBuf, 10, &u4ClearCounter) == 1) { -+ if (u4ClearCounter == 1) { -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ wlanoidSetRxStatisticsForLinuxProc(prGlueInfo->prAdapter); -+ -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ } -+ } -+ -+ return count; -+ -+} /* end of procRxStatisticsWrite() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reading Driver TX Statistic Counters to User Space. -+* -+* \param[in] page Buffer provided by kernel. -+* \param[in out] start Start Address to read(3 methods). -+* \param[in] off Offset. -+* \param[in] count Allowable number to read. -+* \param[out] eof End of File indication. -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters print to the buffer from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procTxStatisticsRead(char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; -+ char *p = page; -+ UINT_32 u4Count; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(data); -+ -+ /* Kevin: Apply PROC read method 1. */ -+ if (off != 0) -+ return 0; /* To indicate end of file. */ -+ -+ SPRINTF(p, ("TX STATISTICS (Write 1 to clear):")); -+ SPRINTF(p, ("\n=================================\n")); -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ wlanoidQueryTxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); -+ -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ u4Count += (UINT_32) (p - page); -+ -+ *eof = 1; -+ -+ return (int)u4Count; -+ -+} /* end of procTxStatisticsRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reset Driver TX Statistic Counters. -+* -+* \param[in] file pointer to file. -+* \param[in] buffer Buffer from user space. -+* \param[in] count Number of characters to write -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters write from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procTxStatisticsWrite(struct file *file, const char *buffer, unsigned long count, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; -+ char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1]; /* + 1 for "\0" */ -+ UINT_32 u4CopySize; -+ UINT_32 u4ClearCounter; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(data); -+ -+ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); -+ copy_from_user(acBuf, buffer, u4CopySize); -+ acBuf[u4CopySize] = '\0'; -+ -+ if (kstrtoint(acBuf, 10, &u4ClearCounter) == 1) { -+ if (u4ClearCounter == 1) { -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ wlanoidSetTxStatisticsForLinuxProc(prGlueInfo->prAdapter); -+ -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ } -+ } -+ -+ return count; -+ -+} /* end of procTxStatisticsWrite() */ -+#endif -+static struct proc_dir_entry *gprProcRoot; -+static UINT_8 aucDbModuleName[][PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN] = { -+ "INIT", "HAL", "INTR", "REQ", "TX", "RX", "RFTEST", "EMU", "SW1", "SW2", -+ "SW3", "SW4", "HEM", "AIS", "RLM", "MEM", "CNM", "RSN", "BSS", "SCN", -+ "SAA", "AAA", "P2P", "QM", "SEC", "BOW", "WAPI", "ROAMING", "TDLS", "OID", -+ "NIC" -+}; -+static UINT_8 aucProcBuf[1536]; -+static ssize_t procDbgLevelRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ UINT_8 *temp = &aucProcBuf[0]; -+ UINT_32 u4CopySize = 0; -+ UINT_16 i; -+ UINT_16 u2ModuleNum = 0; -+ -+ /* if *f_ops>0, we should return 0 to make cat command exit */ -+ if (*f_pos > 0) -+ return 0; -+ -+ kalStrCpy(temp, "\nTEMP |LOUD |INFO |TRACE|EVENT|STATE|WARN |ERROR\n" -+ "bit7 |bit6 |bit5 |bit4 |bit3 |bit2 |bit1 |bit0\n\n" -+ "Debug Module\tIndex\tLevel\tDebug Module\tIndex\tLevel\n\n"); -+ temp += kalStrLen(temp); -+ -+ u2ModuleNum = (sizeof(aucDbModuleName) / PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN) & 0xfe; -+ for (i = 0; i < u2ModuleNum; i += 2) -+ SPRINTF(temp, ("DBG_%s_IDX\t(0x%02x):\t0x%02x\tDBG_%s_IDX\t(0x%02x):\t0x%02x\n", -+ &aucDbModuleName[i][0], i, aucDebugModule[i], -+ &aucDbModuleName[i+1][0], i+1, aucDebugModule[i+1])); -+ -+ if ((sizeof(aucDbModuleName) / PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN) & 0x1) -+ SPRINTF(temp, ("DBG_%s_IDX\t(0x%02x):\t0x%02x\n", -+ &aucDbModuleName[u2ModuleNum][0], u2ModuleNum, aucDebugModule[u2ModuleNum])); -+ -+ u4CopySize = kalStrLen(aucProcBuf); -+ if (u4CopySize > count) -+ u4CopySize = count; -+ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { -+ kalPrint("copy to user failed\n"); -+ return -EFAULT; -+ } -+ -+ *f_pos += u4CopySize; -+ return (ssize_t)u4CopySize; -+} -+ -+static ssize_t procDbgLevelWrite(struct file *file, const char *buffer, size_t count, loff_t *data) -+{ -+ UINT_32 u4NewDbgModule, u4NewDbgLevel; -+ UINT_8 i = 0; -+ UINT_32 u4CopySize = kalStrLen(aucProcBuf);//sizeof(aucProcBuf); -+ UINT_8 *temp = &aucProcBuf[0]; -+ -+ if (u4CopySize >= count + 1) -+ u4CopySize = count; -+ -+ kalMemSet(aucProcBuf, 0, u4CopySize); -+ -+ if (copy_from_user(aucProcBuf, buffer, u4CopySize)) { -+ kalPrint("error of copy from user\n"); -+ return -EFAULT; -+ } -+ aucProcBuf[u4CopySize] = '\0'; -+ -+ while (temp) { -+ if (sscanf(temp, "0x%x:0x%x", &u4NewDbgModule, &u4NewDbgLevel) != 2) { -+ kalPrint("debug module and debug level should be one byte in length\n"); -+ break; -+ } -+ if (u4NewDbgModule == 0xFF) { -+ for (i = 0; i < DBG_MODULE_NUM; i++) -+ aucDebugModule[i] = u4NewDbgLevel & DBG_CLASS_MASK; -+ -+ break; -+ } else if (u4NewDbgModule >= DBG_MODULE_NUM) { -+ kalPrint("debug module index should less than %d\n", DBG_MODULE_NUM); -+ break; -+ } -+ aucDebugModule[u4NewDbgModule] = u4NewDbgLevel & DBG_CLASS_MASK; -+ temp = kalStrChr(temp, ','); -+ if (!temp) -+ break; -+ temp++; /* skip ',' */ -+ } -+ return count; -+} -+ -+ -+static const struct file_operations dbglevel_ops = { -+ .owner = THIS_MODULE, -+ .read = procDbgLevelRead, -+ .write = procDbgLevelWrite, -+}; -+ -+static ssize_t procTxDoneCfgRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ UINT_8 *temp = &aucProcBuf[0]; -+ UINT_32 u4CopySize = 0; -+ UINT_16 u2TxDoneCfg = 0; -+ -+ /* if *f_ops>0, we should return 0 to make cat command exit */ -+ if (*f_pos > 0) -+ return 0; -+ -+ u2TxDoneCfg = StatsGetCfgTxDone(); -+ SPRINTF(temp, ("Tx Done Configure:\nARP %d\tDNS %d\nTCP %d\tUDP %d\nEAPOL %d\tDHCP %d\nICMP %d\n", -+ !!(u2TxDoneCfg & CFG_ARP), !!(u2TxDoneCfg & CFG_DNS), !!(u2TxDoneCfg & CFG_TCP), -+ !!(u2TxDoneCfg & CFG_UDP), !!(u2TxDoneCfg & CFG_EAPOL), !!(u2TxDoneCfg & CFG_DHCP), -+ !!(u2TxDoneCfg & CFG_ICMP))); -+ -+ u4CopySize = kalStrLen(aucProcBuf); -+ if (u4CopySize > count) -+ u4CopySize = count; -+ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { -+ kalPrint("copy to user failed\n"); -+ return -EFAULT; -+ } -+ -+ *f_pos += u4CopySize; -+ return (ssize_t)u4CopySize; -+} -+ -+static ssize_t procTxDoneCfgWrite(struct file *file, const char *buffer, size_t count, loff_t *data) -+{ -+#define MODULE_NAME_LENGTH 6 -+ -+ UINT_8 i = 0; -+ UINT_32 u4CopySize = kalStrLen(aucProcBuf);//sizeof(aucProcBuf); -+ UINT_8 *temp = &aucProcBuf[0]; -+ UINT_16 u2SetTxDoneCfg = 0; -+ UINT_16 u2ClsTxDoneCfg = 0; -+ UINT_8 aucModule[MODULE_NAME_LENGTH]; -+ UINT_32 u4Enabled; -+ UINT_8 aucModuleArray[][MODULE_NAME_LENGTH] = {"ARP", "DNS", "TCP", "UDP", "EAPOL", "DHCP", "ICMP"}; -+ -+ if (u4CopySize >= count + 1) -+ u4CopySize = count; -+ -+ kalMemSet(aucProcBuf, 0, u4CopySize); -+ if (copy_from_user(aucProcBuf, buffer, u4CopySize)) { -+ kalPrint("error of copy from user\n"); -+ return -EFAULT; -+ } -+ aucProcBuf[u4CopySize] = '\0'; -+ temp = &aucProcBuf[0]; -+ while (temp) { -+ /* pick up a string and teminated after meet : */ -+ if (sscanf(temp, "%s %d", aucModule, &u4Enabled) != 2) { -+ kalPrint("read param fail, aucModule=%s\n", aucModule); -+ break; -+ } -+ for (i = 0; i < sizeof(aucModuleArray)/MODULE_NAME_LENGTH; i++) { -+ if (kalStrniCmp(aucModule, aucModuleArray[i], MODULE_NAME_LENGTH) == 0) { -+ if (u4Enabled) -+ u2SetTxDoneCfg |= 1 << i; -+ else -+ u2ClsTxDoneCfg |= 1 << i; -+ break; -+ } -+ } -+ temp = kalStrChr(temp, ','); -+ if (!temp) -+ break; -+ temp++; /* skip ',' */ -+ } -+ if (u2SetTxDoneCfg) -+ StatsSetCfgTxDone(u2SetTxDoneCfg, TRUE); -+ -+ if (u2ClsTxDoneCfg) -+ StatsSetCfgTxDone(u2ClsTxDoneCfg, FALSE); -+ return count; -+} -+ -+static const struct file_operations proc_txdone_ops = { -+ .owner = THIS_MODULE, -+ .read = procTxDoneCfgRead, -+ .write = procTxDoneCfgWrite, -+}; -+ -+static ssize_t procAutoPerCfgRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ UINT_8 *temp = &aucProcBuf[0]; -+ UINT_32 u4CopySize = 0; -+ -+ /* if *f_ops>0, we should return 0 to make cat command exit */ -+ if (*f_pos > 0) -+ return 0; -+ -+ SPRINTF(temp, ("Auto Performance Configure:\nperiod\tL1\nL2\tL3\n")); -+ -+ u4CopySize = kalStrLen(aucProcBuf); -+ if (u4CopySize > count) -+ u4CopySize = count; -+ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { -+ kalPrint("copy to user failed\n"); -+ return -EFAULT; -+ } -+ -+ *f_pos += u4CopySize; -+ return (ssize_t)u4CopySize; -+} -+ -+static ssize_t procAutoPerCfgWrite(struct file *file, const char *buffer, size_t count, loff_t *data) -+{ -+ DBGLOG(INIT, WARN, "%s\n", __func__); -+ return 0; -+} -+ -+static const struct file_operations auto_per_ops = { -+ .owner = THIS_MODULE, -+ .read = procAutoPerCfgRead, -+ .write = procAutoPerCfgWrite, -+}; -+ -+ -+static ssize_t procCmdDebug(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ UINT_32 u4CopySize = 0; -+ -+ /* if *f_ops>0, we should return 0 to make cat command exit */ -+ if (*f_pos > 0) -+ return 0; -+ -+ wlanDumpTcResAndTxedCmd(aucProcBuf, sizeof(aucProcBuf)); -+ -+ u4CopySize = kalStrLen(aucProcBuf); -+ if (u4CopySize > count) -+ u4CopySize = count; -+ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { -+ kalPrint("copy to user failed\n"); -+ return -EFAULT; -+ } -+ -+ *f_pos += u4CopySize; -+ return (ssize_t)u4CopySize; -+} -+ -+static const struct file_operations proc_CmdDebug_ops = { -+ .owner = THIS_MODULE, -+ .read = procCmdDebug, -+}; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function create a PROC fs in linux /proc/net subdirectory. -+* -+* \param[in] prDev Pointer to the struct net_device. -+* \param[in] pucDevName Pointer to the name of net_device. -+* -+* \return N/A -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+#if CFG_SUPPORT_THERMO_THROTTLING -+ -+/** -+ * This function is called then the /proc file is read -+ * -+ */ -+typedef struct _COEX_BUF1 { -+ UINT8 buffer[128]; -+ INT32 availSize; -+} COEX_BUF1, *P_COEX_BUF1; -+ -+COEX_BUF1 gCoexBuf1; -+ -+static ssize_t procfile_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ -+ INT32 retval = 0; -+ INT32 i_ret = 0; -+ CHAR *warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"; -+ -+ if (*f_pos > 0) { -+ retval = 0; -+ } else { -+ /*len = sprintf(page, "%d\n", g_psm_enable); */ -+#if 1 -+ if (gCoexBuf1.availSize <= 0) { -+ DBGLOG(INIT, WARN, "no data available\n"); -+ retval = strlen(warn_msg) + 1; -+ if (count < retval) -+ retval = count; -+ i_ret = copy_to_user(buf, warn_msg, retval); -+ if (i_ret) { -+ DBGLOG(INIT, ERROR, "copy to buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ *f_pos += retval; -+ } else -+#endif -+ { -+ INT32 i = 0; -+ INT32 len = 0; -+ CHAR msg_info[128]; -+ INT32 max_num = 0; -+ /*we do not check page buffer, because there are only 100 bytes in g_coex_buf, no reason page -+ buffer is not enough, a bomb is placed here on unexpected condition */ -+ -+ DBGLOG(INIT, TRACE, "%d bytes available\n", gCoexBuf1.availSize); -+ max_num = ((sizeof(msg_info) > count ? sizeof(msg_info) : count) - 1) / 5; -+ -+ if (max_num > gCoexBuf1.availSize) -+ max_num = gCoexBuf1.availSize; -+ else -+ DBGLOG(INIT, TRACE, -+ "round to %d bytes due to local buffer size limitation\n", max_num); -+ -+ for (i = 0; i < max_num; i++) -+ len += sprintf(msg_info + len, "%d", gCoexBuf1.buffer[i]); -+ -+ len += sprintf(msg_info + len, "\n"); -+ retval = len; -+ -+ i_ret = copy_to_user(buf, msg_info, retval); -+ if (i_ret) { -+ DBGLOG(INIT, ERROR, "copy to buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ *f_pos += retval; -+ } -+ } -+ gCoexBuf1.availSize = 0; -+err_exit: -+ -+ return retval; -+} -+ -+#if 1 -+typedef INT32 (*WLAN_DEV_DBG_FUNC)(void); -+static INT32 wlan_get_thermo_power(void); -+static INT32 wlan_get_link_mode(void); -+ -+static const WLAN_DEV_DBG_FUNC wlan_dev_dbg_func[] = { -+ [0] = wlan_get_thermo_power, -+ [1] = wlan_get_link_mode, -+ -+}; -+ -+INT32 wlan_get_thermo_power(void) -+{ -+ P_ADAPTER_T prAdapter; -+ -+ prAdapter = g_prGlueInfo_proc->prAdapter; -+ -+ if (prAdapter->u4AirDelayTotal > 100) -+ gCoexBuf1.buffer[0] = 100; -+ else -+ gCoexBuf1.buffer[0] = prAdapter->u4AirDelayTotal; -+ gCoexBuf1.availSize = 1; -+ DBGLOG(RLM, TRACE, "PROC %s thrmo_power(%d)\n", __func__, gCoexBuf1.buffer[0]); -+ -+ return 0; -+} -+ -+INT32 wlan_get_link_mode(void) -+{ -+ UINT_8 ucLinkMode = 0; -+ P_ADAPTER_T prAdapter; -+ BOOLEAN fgIsAPmode; -+ -+ prAdapter = g_prGlueInfo_proc->prAdapter; -+ fgIsAPmode = p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo); -+ -+ DBGLOG(RLM, TRACE, "PROC %s AIS(%d)P2P(%d)AP(%d)\n", -+ __func__, -+ prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState, -+ prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState, fgIsAPmode); -+ -+#if 1 -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) -+ ucLinkMode |= BIT(0); -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) -+ ucLinkMode |= BIT(1); -+ if (fgIsAPmode) -+ ucLinkMode |= BIT(2); -+ -+#endif -+ gCoexBuf1.buffer[0] = ucLinkMode; -+ gCoexBuf1.availSize = 1; -+ -+ return 0; -+} -+ -+static ssize_t procfile_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos) -+{ -+ char buf[256]; -+ char *pBuf; -+ ULONG len = count; -+ INT32 x = 0, y = 0, z = 0; -+ char *pToken = NULL; -+ char *pDelimiter = " \t"; -+ INT32 i4Ret = 0; -+ -+ if (copy_from_user(gCoexBuf1.buffer, buffer, count)) -+ return -EFAULT; -+ /* gCoexBuf1.availSize = count; */ -+ -+ /* return gCoexBuf1.availSize; */ -+#if 1 -+ DBGLOG(INIT, TRACE, "write parameter len = %d\n\r", (INT32) len); -+ if (len >= sizeof(buf)) { -+ DBGLOG(INIT, ERROR, "input handling fail!\n"); -+ len = sizeof(buf) - 1; -+ return -1; -+ } -+ -+ if (copy_from_user(buf, buffer, len)) -+ return -EFAULT; -+ buf[len] = '\0'; -+ DBGLOG(INIT, TRACE, "write parameter data = %s\n\r", buf); -+ -+ pBuf = buf; -+ pToken = strsep(&pBuf, pDelimiter); -+ -+ if (pToken) /* x = NULL != pToken ? simple_strtol(pToken, NULL, 16) : 0; */ -+ i4Ret = kalkStrtos32(pToken, 16, &x); -+ if (!i4Ret) -+ DBGLOG(INIT, TRACE, "x = 0x%x\n", x); -+ -+#if 1 -+ pToken = strsep(&pBuf, "\t\n "); -+ if (pToken != NULL) { -+ i4Ret = kalkStrtos32(pToken, 16, &y); /* y = simple_strtol(pToken, NULL, 16); */ -+ if (!i4Ret) -+ DBGLOG(INIT, TRACE, "y = 0x%08x\n\r", y); -+ } else { -+ y = 3000; -+ /*efuse, register read write default value */ -+ if (0x11 == x || 0x12 == x || 0x13 == x) -+ y = 0x80000000; -+ } -+ -+ pToken = strsep(&pBuf, "\t\n "); -+ if (pToken != NULL) { -+ i4Ret = kalkStrtos32(pToken, 16, &z); /* z = simple_strtol(pToken, NULL, 16); */ -+ if (!i4Ret) -+ DBGLOG(INIT, TRACE, "z = 0x%08x\n\r", z); -+ } else { -+ z = 10; -+ /*efuse, register read write default value */ -+ if (0x11 == x || 0x12 == x || 0x13 == x) -+ z = 0xffffffff; -+ } -+ -+ DBGLOG(INIT, TRACE, " x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); -+#endif -+ -+ if (((sizeof(wlan_dev_dbg_func) / sizeof(wlan_dev_dbg_func[0])) > x) && NULL != wlan_dev_dbg_func[x]) -+ (*wlan_dev_dbg_func[x]) (); -+ else -+ DBGLOG(INIT, ERROR, "no handler defined for command id(0x%08x)\n\r", x); -+#endif -+ -+ /* len = gCoexBuf1.availSize; */ -+ return len; -+} -+#endif -+ static const struct file_operations proc_fops = { -+ .owner = THIS_MODULE, -+ .read = procfile_read, -+ .write = procfile_write, -+ }; -+#endif -+ -+INT_32 procInitFs(VOID) -+{ -+ struct proc_dir_entry *prEntry; -+ -+ if (init_net.proc_net == (struct proc_dir_entry *)NULL) { -+ kalPrint("init proc fs fail: proc_net == NULL\n"); -+ return -ENOENT; -+ } -+ -+ /* -+ * Directory: Root (/proc/net/wlan0) -+ */ -+ -+ gprProcRoot = proc_mkdir(PROC_ROOT_NAME, init_net.proc_net); -+ if (!gprProcRoot) { -+ kalPrint("gprProcRoot == NULL\n"); -+ return -ENOENT; -+ } -+ proc_set_user(gprProcRoot, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); -+ -+ prEntry = proc_create(PROC_DBG_LEVEL_NAME, 0664, gprProcRoot, &dbglevel_ops); -+ if (prEntry == NULL) { -+ kalPrint("Unable to create /proc entry dbgLevel\n\r"); -+ return -1; -+ } -+ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); -+ -+ prEntry = proc_create(PROC_NEED_TX_DONE, 0664, gprProcRoot, &proc_txdone_ops); -+ if (prEntry == NULL) { -+ kalPrint("Unable to create /proc entry dbgLevel\n\r"); -+ return -1; -+ } -+ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); -+ -+ prEntry = proc_create(PROC_AUTO_PER_CFG, 0664, gprProcRoot, &auto_per_ops); -+ if (prEntry == NULL) { -+ kalPrint("Unable to create /proc entry autoPerCfg\n\r"); -+ return -1; -+ } -+ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); -+ -+ return 0; -+} /* end of procInitProcfs() */ -+ -+INT_32 procUninitProcFs(VOID) -+{ -+ remove_proc_entry(PROC_DBG_LEVEL_NAME, gprProcRoot); -+ remove_proc_subtree(PROC_ROOT_NAME, init_net.proc_net); -+ remove_proc_entry(PROC_AUTO_PER_CFG, gprProcRoot); -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function clean up a PROC fs created by procInitProcfs(). -+* -+* \param[in] prDev Pointer to the struct net_device. -+* \param[in] pucDevName Pointer to the name of net_device. -+* -+* \return N/A -+*/ -+/*----------------------------------------------------------------------------*/ -+INT_32 procRemoveProcfs(VOID) -+{ -+ /* remove root directory (proc/net/wlan0) */ -+ /* remove_proc_entry(pucDevName, init_net.proc_net); */ -+ remove_proc_entry(PROC_WLAN_THERMO, gprProcRoot); -+ remove_proc_entry(PROC_CMD_DEBUG_NAME, gprProcRoot); -+#if CFG_SUPPORT_THERMO_THROTTLING -+ g_prGlueInfo_proc = NULL; -+#endif -+ return 0; -+} /* end of procRemoveProcfs() */ -+ -+INT_32 procCreateFsEntry(P_GLUE_INFO_T prGlueInfo) -+{ -+ struct proc_dir_entry *prEntry; -+ -+ DBGLOG(INIT, TRACE, "[%s]\n", __func__); -+ -+#if CFG_SUPPORT_THERMO_THROTTLING -+ g_prGlueInfo_proc = prGlueInfo; -+#endif -+ -+ prGlueInfo->pProcRoot = gprProcRoot; -+ -+ prEntry = proc_create(PROC_WLAN_THERMO, 0664, gprProcRoot, &proc_fops); -+ if (prEntry == NULL) { -+ DBGLOG(INIT, ERROR, "Unable to create /proc entry\n\r"); -+ return -1; -+ } -+ -+ prEntry = proc_create(PROC_CMD_DEBUG_NAME, 0444, gprProcRoot, &proc_CmdDebug_ops); -+ if (prEntry == NULL) { -+ kalPrint("Unable to create /proc entry dbgLevel\n\r"); -+ return -1; -+ } -+ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); -+ return 0; -+} -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c -new file mode 100644 -index 0000000000000..f97db8a69fd21 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c -@@ -0,0 +1,228 @@ -+/* -+** Id: @(#) gl_rst.c@@ -+*/ -+ -+/*! \file gl_rst.c -+ \brief Main routines for supporintg MT6620 whole-chip reset mechanism -+ -+ This file contains the support routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_rst.c -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 04 22 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * skip power-off handshaking when RESET indication is received. -+ * -+ * 04 14 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected -+ * 2. add dummy function for both Win32 and Linux part. -+ * -+ * 03 30 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * use netlink unicast instead of broadcast -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+ -+#include "precomp.h" -+#include "gl_rst.h" -+ -+#if CFG_CHIP_RESET_SUPPORT -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+BOOLEAN fgIsResetting = FALSE; -+UINT_32 g_IsNeedDoChipReset = 0; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static RESET_STRUCT_T wifi_rst; -+ -+static void mtk_wifi_reset(struct work_struct *work); -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static void *glResetCallback(ENUM_WMTDRV_TYPE_T eSrcType, -+ ENUM_WMTDRV_TYPE_T eDstType, -+ ENUM_WMTMSG_TYPE_T eMsgType, void *prMsgBody, unsigned int u4MsgLength); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for -+ * 1. register wifi reset callback -+ * 2. initialize wifi reset work -+ * -+ * @param none -+ * -+ * @retval none -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID glResetInit(VOID) -+{ -+#if (MTK_WCN_SINGLE_MODULE == 0) -+ /* 1. Register reset callback */ -+ mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_WIFI, (PF_WMT_CB) glResetCallback); -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ -+ /* 2. Initialize reset work */ -+ INIT_WORK(&(wifi_rst.rst_work), mtk_wifi_reset); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for -+ * 1. deregister wifi reset callback -+ * -+ * @param none -+ * -+ * @retval none -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID glResetUninit(VOID) -+{ -+#if (MTK_WCN_SINGLE_MODULE == 0) -+ /* 1. Deregister reset callback */ -+ mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_WIFI); -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is invoked when there is reset messages indicated -+ * -+ * @param eSrcType -+ * eDstType -+ * eMsgType -+ * prMsgBody -+ * u4MsgLength -+ * -+ * @retval -+ */ -+/*----------------------------------------------------------------------------*/ -+static void *glResetCallback(ENUM_WMTDRV_TYPE_T eSrcType, -+ ENUM_WMTDRV_TYPE_T eDstType, -+ ENUM_WMTMSG_TYPE_T eMsgType, void *prMsgBody, unsigned int u4MsgLength) -+{ -+ switch (eMsgType) { -+ case WMTMSG_TYPE_RESET: -+ if (u4MsgLength == sizeof(ENUM_WMTRSTMSG_TYPE_T)) { -+ P_ENUM_WMTRSTMSG_TYPE_T prRstMsg = (P_ENUM_WMTRSTMSG_TYPE_T) prMsgBody; -+ -+ switch (*prRstMsg) { -+ case WMTRSTMSG_RESET_START: -+ DBGLOG(INIT, WARN, "Whole chip reset start!\n"); -+ fgIsResetting = TRUE; -+ wifi_reset_start(); -+ break; -+ -+ case WMTRSTMSG_RESET_END: -+ DBGLOG(INIT, WARN, "Whole chip reset end!\n"); -+ fgIsResetting = FALSE; -+ wifi_rst.rst_data = RESET_SUCCESS; -+ schedule_work(&(wifi_rst.rst_work)); -+ break; -+ -+ case WMTRSTMSG_RESET_END_FAIL: -+ DBGLOG(INIT, WARN, "Whole chip reset fail!\n"); -+ fgIsResetting = FALSE; -+ wifi_rst.rst_data = RESET_FAIL; -+ schedule_work(&(wifi_rst.rst_work)); -+ break; -+ -+ default: -+ break; -+ } -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ return NULL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is called for wifi reset -+ * -+ * @param skb -+ * info -+ * -+ * @retval 0 -+ * nonzero -+ */ -+/*----------------------------------------------------------------------------*/ -+static void mtk_wifi_reset(struct work_struct *work) -+{ -+ RESET_STRUCT_T *rst = container_of(work, RESET_STRUCT_T, rst_work); -+ -+ wifi_reset_end(rst->rst_data); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is called for generating reset request to WMT -+ * -+ * @param None -+ * -+ * @retval None -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID glSendResetRequest(VOID) -+{ -+ /* WMT thread would trigger whole chip reset itself */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is called for checking if connectivity chip is resetting -+ * -+ * @param None -+ * -+ * @retval TRUE -+ * FALSE -+ */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsResetting(VOID) -+{ -+ return fgIsResetting; -+} -+ -+#endif /* CFG_CHIP_RESET_SUPPORT */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c -new file mode 100644 -index 0000000000000..862d011a43df3 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c -@@ -0,0 +1,1220 @@ -+/* -+** Id: @(#) gl_cfg80211.c@@ -+*/ -+ -+/*! \file gl_cfg80211.c -+ \brief Main routines for supporintg MT6620 cfg80211 control interface -+ -+ This file contains the support routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_cfg80211.c -+** -+** 09 05 2013 cp.wu -+** correct length to pass to wlanoidSetBssid() -+** -+** 09 04 2013 cp.wu -+** fix typo -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+** -+** 11 23 2012 yuche.tsai -+** [ALPS00398671] [Acer-Tablet] Remove Wi-Fi Direct completely -+** Fix bug of WiFi may reboot under user load, when WiFi Direct is removed.. -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 30 2012 chinglan.wang -+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only -+** . -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+ -+#include "gl_os.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include "precomp.h" -+#include "gl_cfg80211.h" -+#include "gl_vendor.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+static struct nla_policy nla_parse_policy[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1] = { -+ [GSCAN_ATTRIBUTE_NUM_BUCKETS] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BASE_PERIOD] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BUCKETS_BAND] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BUCKET_ID] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BUCKET_PERIOD] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BUCKET_CHANNELS] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_REPORT_THRESHOLD] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_REPORT_EVENTS] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BSSID] = {.type = NLA_UNSPEC}, -+ [GSCAN_ATTRIBUTE_RSSI_LOW] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_RSSI_HIGH] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE] = {.type = NLA_U16}, -+ [GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_MIN_BREACHING] = {.type = NLA_U16}, -+ [GSCAN_ATTRIBUTE_NUM_AP] = {.type = NLA_U16}, -+ [GSCAN_ATTRIBUTE_HOTLIST_FLUSH] = {.type = NLA_U8}, -+ [GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH] = {.type = NLA_U8}, -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+int mtk_cfg80211_vendor_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ struct nlattr *attr; -+ UINT_32 band = 0; -+ UINT_8 ucNumOfChannel, i, j; -+ RF_CHANNEL_INFO_T aucChannelList[64]; -+ UINT_32 num_channels; -+ wifi_channel channels[64]; -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy && wdev); -+ if ((data == NULL) || !data_len) -+ return -EINVAL; -+ -+ DBGLOG(REQ, INFO, "vendor command: data_len=%d\n", data_len); -+ -+ attr = (struct nlattr *)data; -+ if (attr->nla_type == WIFI_ATTRIBUTE_BAND) -+ band = nla_get_u32(attr); -+ -+ DBGLOG(REQ, INFO, "Get channel list for band: %d\n", band); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ if (!prGlueInfo) -+ return -EFAULT; -+ -+ if (band == 0) { /* 2.4G band */ -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_2G4, TRUE, -+ 64, &ucNumOfChannel, aucChannelList); -+ } else { /* 5G band */ -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_5G, TRUE, -+ 64, &ucNumOfChannel, aucChannelList); -+ } -+ -+ kalMemZero(channels, sizeof(channels)); -+ for (i = 0, j = 0; i < ucNumOfChannel; i++) { -+ /* We need to report frequency list to HAL */ -+ channels[j] = nicChannelNum2Freq(aucChannelList[i].ucChannelNum) / 1000; -+ if (channels[j] == 0) -+ continue; -+ else if ((prGlueInfo->prAdapter->rWifiVar.rConnSettings.u2CountryCode == COUNTRY_CODE_TW) && -+ (channels[j] >= 5180 && channels[j] <= 5260)) { -+ /* Taiwan NCC has resolution to follow FCC spec to support 5G Band 1/2/3/4 -+ * (CH36~CH48, CH52~CH64, CH100~CH140, CH149~CH165) -+ * Filter CH36~CH52 for compatible with some old devices. -+ */ -+ continue; -+ } else { -+ DBGLOG(REQ, INFO, "channels[%d] = %d\n", j, channels[j]); -+ j++; -+ } -+ } -+ num_channels = j; -+ -+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(channels)); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "Allocate skb failed\n"); -+ return -ENOMEM; -+ } -+ -+ if (unlikely(nla_put_u32(skb, WIFI_ATTRIBUTE_NUM_CHANNELS, num_channels) < 0)) -+ goto nla_put_failure; -+ -+ if (unlikely(nla_put(skb, WIFI_ATTRIBUTE_CHANNEL_LIST, -+ (sizeof(wifi_channel) * num_channels), channels) < 0)) -+ goto nla_put_failure; -+ -+ return cfg80211_vendor_cmd_reply(skb); -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -EFAULT; -+} -+ -+int mtk_cfg80211_vendor_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ struct nlattr *attr; -+ UINT_8 country[2] = {0, 0}; -+ -+ ASSERT(wiphy && wdev); -+ if ((data == NULL) || (data_len == 0)) -+ return -EINVAL; -+ -+ DBGLOG(REQ, INFO, "vendor command: data_len=%d\n", data_len); -+ -+ attr = (struct nlattr *)data; -+ if (attr->nla_type == WIFI_ATTRIBUTE_COUNTRY_CODE) { -+ country[0] = *((PUINT_8)nla_data(attr)); -+ country[1] = *((PUINT_8)nla_data(attr) + 1); -+ } -+ -+ DBGLOG(REQ, INFO, "Set country code: %c%c\n", country[0], country[1]); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ if (!prGlueInfo) -+ return -EFAULT; -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetCountryCode, country, 2, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "Set country code error: %x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+int mtk_cfg80211_vendor_get_gscan_capabilities(struct wiphy *wiphy, -+ struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Status = -EINVAL; -+ PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T rGscanCapabilities; -+ struct sk_buff *skb; -+ /* UINT_32 u4BufLen; */ -+ -+ DBGLOG(REQ, TRACE, "%s for vendor command \r\n", __func__); -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(rGscanCapabilities)); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed:%x\n", __func__, i4Status); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(&rGscanCapabilities, sizeof(rGscanCapabilities)); -+ -+ /*rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStatistics, -+ &rGscanCapabilities, -+ sizeof(rGscanCapabilities), -+ TRUE, -+ TRUE, -+ TRUE, -+ FALSE, -+ &u4BufLen); */ -+ rGscanCapabilities.max_scan_cache_size = PSCAN_MAX_SCAN_CACHE_SIZE; -+ rGscanCapabilities.max_scan_buckets = GSCAN_MAX_BUCKETS; -+ rGscanCapabilities.max_ap_cache_per_scan = PSCAN_MAX_AP_CACHE_PER_SCAN; -+ rGscanCapabilities.max_rssi_sample_size = 10; -+ rGscanCapabilities.max_scan_reporting_threshold = GSCAN_MAX_REPORT_THRESHOLD; -+ rGscanCapabilities.max_hotlist_aps = MAX_HOTLIST_APS; -+ rGscanCapabilities.max_significant_wifi_change_aps = MAX_SIGNIFICANT_CHANGE_APS; -+ rGscanCapabilities.max_bssid_history_entries = PSCAN_MAX_AP_CACHE_PER_SCAN * PSCAN_MAX_SCAN_CACHE_SIZE; -+ -+ /* NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0); */ -+ /* NLA_PUT_U32(skb, NL80211_ATTR_VENDOR_ID, GOOGLE_OUI); */ -+ /* NLA_PUT_U32(skb, NL80211_ATTR_VENDOR_SUBCMD, GSCAN_SUBCMD_GET_CAPABILITIES); */ -+ /*NLA_PUT(skb, GSCAN_ATTRIBUTE_CAPABILITIES, sizeof(rGscanCapabilities), &rGscanCapabilities);*/ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_CAPABILITIES, -+ sizeof(rGscanCapabilities), &rGscanCapabilities) < 0)) -+ goto nla_put_failure; -+ -+ i4Status = cfg80211_vendor_cmd_reply(skb); -+ return i4Status; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ /* CMD_GSCN_REQ_T rCmdGscnParam; */ -+ -+ /* INT_32 i4Status = -EINVAL; */ -+ P_PARAM_WIFI_GSCAN_CMD_PARAMS prWifiScanCmd = NULL; -+ struct nlattr *attr[GSCAN_ATTRIBUTE_REPORT_EVENTS + 1]; -+ struct nlattr *pbucket, *pchannel; -+ UINT_32 len_basic, len_bucket, len_channel; -+ int i, j, k; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ -+ prWifiScanCmd = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), VIR_MEM_TYPE); -+ if (!prWifiScanCmd) { -+ DBGLOG(REQ, ERROR, "Can not alloc memory for PARAM_WIFI_GSCAN_CMD_PARAMS\n"); -+ return -ENOMEM; -+ } -+ -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); -+ kalMemZero(prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_REPORT_EVENTS + 1)); -+ -+ nla_parse_nested(attr, GSCAN_ATTRIBUTE_REPORT_EVENTS, (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL); -+ len_basic = 0; -+ for (k = GSCAN_ATTRIBUTE_NUM_BUCKETS; k <= GSCAN_ATTRIBUTE_REPORT_EVENTS; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_BASE_PERIOD: -+ prWifiScanCmd->base_period = nla_get_u32(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_NUM_BUCKETS: -+ prWifiScanCmd->num_buckets = nla_get_u32(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ DBGLOG(REQ, TRACE, "attr=0x%x, num_buckets=%d nla_len=%d, \r\n", -+ *(UINT_32 *) attr[k], prWifiScanCmd->num_buckets, attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ pbucket = (struct nlattr *)((UINT_8 *) data + len_basic); -+ DBGLOG(REQ, TRACE, "+++basic attribute size=%d pbucket=%p\r\n", len_basic, pbucket); -+ -+ for (i = 0; i < prWifiScanCmd->num_buckets; i++) { -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_REPORT_EVENTS, (struct nlattr *)pbucket, -+ nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ len_bucket = 0; -+ for (k = GSCAN_ATTRIBUTE_NUM_BUCKETS; k <= GSCAN_ATTRIBUTE_REPORT_EVENTS; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_BUCKETS_BAND: -+ prWifiScanCmd->buckets[i].band = nla_get_u32(attr[k]); -+ len_bucket += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_BUCKET_ID: -+ prWifiScanCmd->buckets[i].bucket = nla_get_u32(attr[k]); -+ len_bucket += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_BUCKET_PERIOD: -+ prWifiScanCmd->buckets[i].period = nla_get_u32(attr[k]); -+ len_bucket += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_REPORT_EVENTS: -+ prWifiScanCmd->buckets[i].report_events = nla_get_u32(attr[k]); -+ len_bucket += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS: -+ prWifiScanCmd->buckets[i].num_channels = nla_get_u32(attr[k]); -+ len_bucket += NLA_ALIGN(attr[k]->nla_len); -+ DBGLOG(REQ, TRACE, "bucket%d: attr=0x%x, num_channels=%d nla_len = %d, \r\n", -+ i, *(UINT_32 *) attr[k], nla_get_u32(attr[k]), attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ pbucket = (struct nlattr *)((UINT_8 *) pbucket + NLA_HDRLEN); -+ /* request.attr_start(i) as nested attribute */ -+ DBGLOG(REQ, TRACE, "+++pure bucket size=%d pbucket=%p \r\n", len_bucket, pbucket); -+ pbucket = (struct nlattr *)((UINT_8 *) pbucket + len_bucket); -+ /* pure bucket payload, not include channels */ -+ -+ /*don't need to use nla_parse_nested to parse channels */ -+ /* the header of channel in bucket i */ -+ pchannel = (struct nlattr *)((UINT_8 *) pbucket + NLA_HDRLEN); -+ for (j = 0; j < prWifiScanCmd->buckets[i].num_channels; j++) { -+ prWifiScanCmd->buckets[i].channels[j].channel = nla_get_u32(pchannel); -+ len_channel = NLA_ALIGN(pchannel->nla_len); -+ DBGLOG(REQ, TRACE, -+ "attr=0x%x, channel=%d, \r\n", *(UINT_32 *) pchannel, nla_get_u32(pchannel)); -+ -+ pchannel = (struct nlattr *)((UINT_8 *) pchannel + len_channel); -+ } -+ pbucket = pchannel; -+ } -+ -+ DBGLOG(REQ, TRACE, "base_period=%d, num_buckets=%d, bucket0: %d %d %d %d", -+ prWifiScanCmd->base_period, prWifiScanCmd->num_buckets, -+ prWifiScanCmd->buckets[0].bucket, prWifiScanCmd->buckets[0].period, -+ prWifiScanCmd->buckets[0].band, prWifiScanCmd->buckets[0].report_events); -+ -+ DBGLOG(REQ, TRACE, "num_channels=%d, channel0=%d, channel1=%d; num_channels=%d, channel0=%d, channel1=%d", -+ prWifiScanCmd->buckets[0].num_channels, -+ prWifiScanCmd->buckets[0].channels[0].channel, prWifiScanCmd->buckets[0].channels[1].channel, -+ prWifiScanCmd->buckets[1].num_channels, -+ prWifiScanCmd->buckets[1].channels[0].channel, prWifiScanCmd->buckets[1].channels[1].channel); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetGSCNAParam, -+ prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ return 0; -+ -+nla_put_failure: -+ if (prWifiScanCmd != NULL) -+ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_set_scan_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ INT_32 i4Status = -EINVAL; -+ /*PARAM_WIFI_GSCAN_CMD_PARAMS rWifiScanCmd;*/ -+ P_PARAM_WIFI_GSCAN_CMD_PARAMS prWifiScanCmd = NULL; -+ struct nlattr *attr[GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE + 1]; -+ /* UINT_32 num_scans = 0; */ /* another attribute */ -+ int k; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); -+ /*kalMemZero(&rWifiScanCmd, sizeof(rWifiScanCmd));*/ -+ prWifiScanCmd = kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), VIR_MEM_TYPE); -+ if (prWifiScanCmd == NULL) -+ goto nla_put_failure; -+ kalMemZero(prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE + 1)); -+ -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, -+ (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ for (k = GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN; k <= GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN: -+ prWifiScanCmd->max_ap_per_scan = nla_get_u32(attr[k]); -+ break; -+ case GSCAN_ATTRIBUTE_REPORT_THRESHOLD: -+ prWifiScanCmd->report_threshold = nla_get_u32(attr[k]); -+ break; -+ case GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE: -+ prWifiScanCmd->num_scans = nla_get_u32(attr[k]); -+ break; -+ } -+ } -+ } -+ DBGLOG(REQ, TRACE, "attr=0x%x, attr2=0x%x ", *(UINT_32 *) attr[GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN], -+ *(UINT_32 *) attr[GSCAN_ATTRIBUTE_REPORT_THRESHOLD]); -+ -+ DBGLOG(REQ, TRACE, "max_ap_per_scan=%d, report_threshold=%d num_scans=%d \r\n", -+ prWifiScanCmd->max_ap_per_scan, prWifiScanCmd->report_threshold, prWifiScanCmd->num_scans); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetGSCNAConfig, -+ prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ return 0; -+ -+nla_put_failure: -+ if (prWifiScanCmd != NULL) -+ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_set_significant_change(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len) -+{ -+ INT_32 i4Status = -EINVAL; -+ P_PARAM_WIFI_SIGNIFICANT_CHANGE prWifiChangeCmd = NULL; -+ UINT_8 flush = 0; -+ /* struct nlattr *attr[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1]; */ -+ struct nlattr **attr = NULL; -+ struct nlattr *paplist; -+ int i, k; -+ UINT_32 len_basic, len_aplist; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); -+ for (i = 0; i < 6; i++) -+ DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", -+ *((UINT_32 *) data + i * 4), *((UINT_32 *) data + i * 4 + 1), -+ *((UINT_32 *) data + i * 4 + 2), *((UINT_32 *) data + i * 4 + 3)); -+ prWifiChangeCmd = kalMemAlloc(sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE), VIR_MEM_TYPE); -+ if (prWifiChangeCmd == NULL) -+ goto nla_put_failure; -+ kalMemZero(prWifiChangeCmd, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); -+ attr = kalMemAlloc(sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1), VIR_MEM_TYPE); -+ if (attr == NULL) -+ goto nla_put_failure; -+ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, -+ (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ len_basic = 0; -+ for (k = GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE; k <= GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE: -+ prWifiChangeCmd->rssi_sample_size = nla_get_u16(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE: -+ prWifiChangeCmd->lost_ap_sample_size = nla_get_u16(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_MIN_BREACHING: -+ prWifiChangeCmd->min_breaching = nla_get_u16(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_NUM_AP: -+ prWifiChangeCmd->num_ap = nla_get_u16(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ DBGLOG(REQ, TRACE, "attr=0x%x, num_ap=%d nla_len=%d, \r\n", -+ *(UINT_32 *) attr[k], prWifiChangeCmd->num_ap, attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH: -+ flush = nla_get_u8(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ paplist = (struct nlattr *)((UINT_8 *) data + len_basic); -+ DBGLOG(REQ, TRACE, "+++basic attribute size=%d flush=%d\r\n", len_basic, flush); -+ -+ if (paplist->nla_type == GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS) -+ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); -+ -+ for (i = 0; i < prWifiChangeCmd->num_ap; i++) { -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_RSSI_HIGH, (struct nlattr *)paplist, nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); -+ /* request.attr_start(i) as nested attribute */ -+ len_aplist = 0; -+ for (k = GSCAN_ATTRIBUTE_BSSID; k <= GSCAN_ATTRIBUTE_RSSI_HIGH; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_BSSID: -+ kalMemCopy(prWifiChangeCmd->ap[i].bssid, nla_data(attr[k]), sizeof(mac_addr)); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_RSSI_LOW: -+ prWifiChangeCmd->ap[i].low = nla_get_u32(attr[k]); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_RSSI_HIGH: -+ prWifiChangeCmd->ap[i].high = nla_get_u32(attr[k]); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ if (((i + 1) % 4 == 0) || (i == prWifiChangeCmd->num_ap - 1)) -+ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d\n", i, len_aplist); -+ else -+ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d \t", i, len_aplist); -+ paplist = (struct nlattr *)((UINT_8 *) paplist + len_aplist); -+ } -+ -+ DBGLOG(REQ, TRACE, -+ "flush=%d, rssi_sample_size=%d lost_ap_sample_size=%d min_breaching=%d", -+ flush, prWifiChangeCmd->rssi_sample_size, prWifiChangeCmd->lost_ap_sample_size, -+ prWifiChangeCmd->min_breaching); -+ DBGLOG(REQ, TRACE, -+ "ap[0].channel=%d low=%d high=%d, ap[1].channel=%d low=%d high=%d", -+ prWifiChangeCmd->ap[0].channel, prWifiChangeCmd->ap[0].low, prWifiChangeCmd->ap[0].high, -+ prWifiChangeCmd->ap[1].channel, prWifiChangeCmd->ap[1].low, prWifiChangeCmd->ap[1].high); -+ kalMemFree(prWifiChangeCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); -+ kalMemFree(attr, VIR_MEM_TYPE, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ return 0; -+ -+nla_put_failure: -+ if (prWifiChangeCmd) -+ kalMemFree(prWifiChangeCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); -+ if (attr) -+ kalMemFree(attr, VIR_MEM_TYPE, -+ sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_set_hotlist(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ /*WLAN_STATUS rStatus;*/ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ CMD_SET_PSCAN_ADD_HOTLIST_BSSID rCmdPscnAddHotlist; -+ -+ INT_32 i4Status = -EINVAL; -+ P_PARAM_WIFI_BSSID_HOTLIST prWifiHotlistCmd = NULL; -+ UINT_8 flush = 0; -+ /* struct nlattr *attr[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1]; */ -+ struct nlattr **attr = NULL; -+ struct nlattr *paplist; -+ int i, k; -+ UINT_32 len_basic, len_aplist; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); -+ for (i = 0; i < 5; i++) -+ DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", -+ *((UINT_32 *) data + i * 4), *((UINT_32 *) data + i * 4 + 1), -+ *((UINT_32 *) data + i * 4 + 2), *((UINT_32 *) data + i * 4 + 3)); -+ prWifiHotlistCmd = kalMemAlloc(sizeof(PARAM_WIFI_BSSID_HOTLIST), VIR_MEM_TYPE); -+ if (prWifiHotlistCmd == NULL) -+ goto nla_put_failure; -+ kalMemZero(prWifiHotlistCmd, sizeof(PARAM_WIFI_BSSID_HOTLIST)); -+ attr = kalMemAlloc(sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1), VIR_MEM_TYPE); -+ if (attr == NULL) -+ goto nla_put_failure; -+ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_NUM_AP, (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ len_basic = 0; -+ for (k = GSCAN_ATTRIBUTE_HOTLIST_FLUSH; k <= GSCAN_ATTRIBUTE_NUM_AP; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE: -+ prWifiHotlistCmd->lost_ap_sample_size = nla_get_u32(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_NUM_AP: -+ prWifiHotlistCmd->num_ap = nla_get_u16(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ DBGLOG(REQ, TRACE, "attr=0x%x, num_ap=%d nla_len=%d, \r\n", -+ *(UINT_32 *) attr[k], prWifiHotlistCmd->num_ap, attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_HOTLIST_FLUSH: -+ flush = nla_get_u8(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ paplist = (struct nlattr *)((UINT_8 *) data + len_basic); -+ DBGLOG(REQ, TRACE, "+++basic attribute size=%d flush=%d\r\n", len_basic, flush); -+ -+ if (paplist->nla_type == GSCAN_ATTRIBUTE_HOTLIST_BSSIDS) -+ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); -+ -+ for (i = 0; i < prWifiHotlistCmd->num_ap; i++) { -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_RSSI_HIGH, (struct nlattr *)paplist, nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); -+ /* request.attr_start(i) as nested attribute */ -+ len_aplist = 0; -+ for (k = GSCAN_ATTRIBUTE_BSSID; k <= GSCAN_ATTRIBUTE_RSSI_HIGH; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_BSSID: -+ kalMemCopy(prWifiHotlistCmd->ap[i].bssid, nla_data(attr[k]), sizeof(mac_addr)); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_RSSI_LOW: -+ prWifiHotlistCmd->ap[i].low = nla_get_u32(attr[k]); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_RSSI_HIGH: -+ prWifiHotlistCmd->ap[i].high = nla_get_u32(attr[k]); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ if (((i + 1) % 4 == 0) || (i == prWifiHotlistCmd->num_ap - 1)) -+ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d\n", i, len_aplist); -+ else -+ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d \t", i, len_aplist); -+ paplist = (struct nlattr *)((UINT_8 *) paplist + len_aplist); -+ } -+ -+ DBGLOG(REQ, TRACE, -+ "flush=%d, lost_ap_sample_size=%d, Hotlist:ap[0].channel=%d low=%d high=%d, ap[1].channel=%d low=%d high=%d", -+ flush, prWifiHotlistCmd->lost_ap_sample_size, -+ prWifiHotlistCmd->ap[0].channel, prWifiHotlistCmd->ap[0].low, prWifiHotlistCmd->ap[0].high, -+ prWifiHotlistCmd->ap[1].channel, prWifiHotlistCmd->ap[1].low, prWifiHotlistCmd->ap[1].high); -+ -+ memcpy(&(rCmdPscnAddHotlist.aucMacAddr), &(prWifiHotlistCmd->ap[0].bssid), 6 * sizeof(UINT_8)); -+ rCmdPscnAddHotlist.ucFlags = (UINT_8) TRUE; -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemFree(prWifiHotlistCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_BSSID_HOTLIST)); -+ kalMemFree(attr, VIR_MEM_TYPE, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ return 0; -+ -+nla_put_failure: -+ if (prWifiHotlistCmd) -+ kalMemFree(prWifiHotlistCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_BSSID_HOTLIST)); -+ if (attr) -+ kalMemFree(attr, VIR_MEM_TYPE, -+ sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_enable_scan(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS rWifiScanActionCmd; -+ -+ INT_32 i4Status = -EINVAL; -+ struct nlattr *attr; -+ UINT_8 gGScanEn = 0; -+ -+ static UINT_8 k; /* only for test */ -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d, data=0x%x 0x%x\r\n", -+ __func__, data_len, *((UINT_32 *) data), *((UINT_32 *) data + 1)); -+ -+ attr = (struct nlattr *)data; -+ if (attr->nla_type == GSCAN_ATTRIBUTE_ENABLE_FEATURE) -+ gGScanEn = nla_get_u32(attr); -+ DBGLOG(REQ, INFO, "gGScanEn=%d, \r\n", gGScanEn); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ if (gGScanEn == TRUE) -+ rWifiScanActionCmd.ucPscanAct = ENABLE; -+ else -+ rWifiScanActionCmd.ucPscanAct = DISABLE; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetGSCNAction, -+ &rWifiScanActionCmd, -+ sizeof(PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ /* mtk_cfg80211_vendor_get_scan_results(wiphy, wdev, data, data_len ); */ -+ -+ return 0; -+ -+ /* only for test */ -+ if (k % 3 == 1) { -+ mtk_cfg80211_vendor_event_significant_change_results(wiphy, wdev, NULL, 0); -+ mtk_cfg80211_vendor_event_hotlist_ap_found(wiphy, wdev, NULL, 0); -+ mtk_cfg80211_vendor_event_hotlist_ap_lost(wiphy, wdev, NULL, 0); -+ } -+ k++; -+ -+ return 0; -+ -+nla_put_failure: -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_enable_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len) -+{ -+ INT_32 i4Status = -EINVAL; -+ struct nlattr *attr; -+ UINT_8 gFullScanResultsEn = 0; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d, data=0x%x 0x%x\r\n", -+ __func__, data_len, *((UINT_32 *) data), *((UINT_32 *) data + 1)); -+ -+ attr = (struct nlattr *)data; -+ if (attr->nla_type == GSCAN_ENABLE_FULL_SCAN_RESULTS) -+ gFullScanResultsEn = nla_get_u32(attr); -+ DBGLOG(REQ, INFO, "gFullScanResultsEn=%d, \r\n", gFullScanResultsEn); -+ -+ return 0; -+ -+ /* only for test */ -+ mtk_cfg80211_vendor_event_complete_scan(wiphy, wdev, WIFI_SCAN_COMPLETE); -+ mtk_cfg80211_vendor_event_scan_results_available(wiphy, wdev, 4); -+ if (gFullScanResultsEn == TRUE) -+ mtk_cfg80211_vendor_event_full_scan_results(wiphy, wdev, NULL, 0); -+ -+ return 0; -+ -+nla_put_failure: -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_get_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ /*WLAN_STATUS rStatus;*/ -+ UINT_32 u4BufLen; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ PARAM_WIFI_GSCAN_GET_RESULT_PARAMS rGSscnResultParm; -+ -+ INT_32 i4Status = -EINVAL; -+ struct nlattr *attr; -+ UINT_32 get_num = 0, real_num = 0; -+ UINT_8 flush = 0; -+ /*PARAM_WIFI_GSCAN_RESULT result[4], *pResult; -+ struct sk_buff *skb;*/ -+ int i; /*int j;*/ -+ /*UINT_32 scan_id;*/ -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, TRACE, "%s for vendor command: data_len=%d \r\n", __func__, data_len); -+ for (i = 0; i < 2; i++) -+ DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", *((UINT_32 *) data + i * 4), -+ *((UINT_32 *) data + i * 4 + 1), *((UINT_32 *) data + i * 4 + 2), -+ *((UINT_32 *) data + i * 4 + 3)); -+ -+ attr = (struct nlattr *)data; -+ if (attr->nla_type == GSCAN_ATTRIBUTE_NUM_OF_RESULTS) { -+ get_num = nla_get_u32(attr); -+ attr = (struct nlattr *)((UINT_8 *) attr + attr->nla_len); -+ } -+ if (attr->nla_type == GSCAN_ATTRIBUTE_FLUSH_RESULTS) { -+ flush = nla_get_u8(attr); -+ attr = (struct nlattr *)((UINT_8 *) attr + attr->nla_len); -+ } -+ DBGLOG(REQ, TRACE, "number=%d, flush=%d \r\n", get_num, flush); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ real_num = (get_num < PSCAN_MAX_SCAN_CACHE_SIZE) ? get_num : PSCAN_MAX_SCAN_CACHE_SIZE; -+ get_num = real_num; -+ -+#if 0 /* driver buffer FW results and reports by buffer workaround for FW mismatch with hal results numbers */ -+ g_GetResultsCmdCnt++; -+ DBGLOG(REQ, INFO, -+ "(g_GetResultsCmdCnt [%d], g_GetResultsBufferedCnt [%d]\n", g_GetResultsCmdCnt, -+ g_GetResultsBufferedCnt); -+ -+ BOOLEAN fgIsGetResultFromBuffer = FALSE; -+ UINT_8 BufferedResultReportIndex = 0; -+ -+ if (g_GetResultsBufferedCnt > 0) { -+ -+ DBGLOG(REQ, INFO, -+ "(g_GetResultsBufferedCnt > 0), report buffered results instead of ask from FW\n"); -+ -+ /* reply the results to wifi_hal */ -+ for (i = 0; i < MAX_BUFFERED_GSCN_RESULTS; i++) { -+ -+ if (g_arGscanResultsIndicateNumber[i] > 0) { -+ real_num = g_arGscanResultsIndicateNumber[i]; -+ get_num = real_num; -+ g_arGscanResultsIndicateNumber[i] = 0; -+ fgIsGetResultFromBuffer = TRUE; -+ BufferedResultReportIndex = i; -+ break; -+ } -+ } -+ if (i == MAX_BUFFERED_GSCN_RESULTS) -+ DBGLOG(REQ, TRACE, "all buffered results are invalid, unexpected case \r\n"); -+ DBGLOG(REQ, TRACE, "BufferedResultReportIndex[%d] i = %d real_num[%d] get_num[%d] \r\n", -+ BufferedResultReportIndex, i, real_num, get_num); -+ } -+#endif -+ -+ rGSscnResultParm.get_num = get_num; -+ rGSscnResultParm.flush = flush; -+#if 0/* //driver buffer FW results and reports by buffer workaround for FW results mismatch with hal results number */ -+ if (fgIsGetResultFromBuffer) { -+ nicRxProcessGSCNEvent(prGlueInfo->prAdapter, g_arGscnResultsTempBuffer[BufferedResultReportIndex]); -+ g_GetResultsBufferedCnt--; -+ g_GetResultsCmdCnt--; -+ nicRxReturnRFB(prGlueInfo->prAdapter, g_arGscnResultsTempBuffer[BufferedResultReportIndex]); -+ } else -+#endif -+ { -+ kalIoctl(prGlueInfo, -+ wlanoidGetGSCNResult, -+ &rGSscnResultParm, -+ sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ } -+ return 0; -+ -+nla_put_failure: -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_get_rtt_capabilities(struct wiphy *wiphy, -+ struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Status = -EINVAL; -+ PARAM_WIFI_RTT_CAPABILITIES rRttCapabilities; -+ struct sk_buff *skb; -+ -+ DBGLOG(REQ, TRACE, "%s for vendor command \r\n", __func__); -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(rRttCapabilities)); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed:%x\n", __func__, i4Status); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(&rRttCapabilities, sizeof(rRttCapabilities)); -+ -+ /*rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStatistics, -+ &rRttCapabilities, -+ sizeof(rRttCapabilities), -+ TRUE, -+ TRUE, -+ TRUE, -+ FALSE, -+ &u4BufLen); */ -+ rRttCapabilities.rtt_one_sided_supported = 0; -+ rRttCapabilities.rtt_ftm_supported = 0; -+ rRttCapabilities.lci_support = 0; -+ rRttCapabilities.lcr_support = 0; -+ rRttCapabilities.preamble_support = 0; -+ rRttCapabilities.bw_support = 0; -+ -+ if (unlikely(nla_put(skb, RTT_ATTRIBUTE_CAPABILITIES, -+ sizeof(rRttCapabilities), &rRttCapabilities) < 0)) -+ goto nla_put_failure; -+ -+ i4Status = cfg80211_vendor_cmd_reply(skb); -+ return i4Status; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_llstats_get_info(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ INT_32 i4Status = -EINVAL; -+ WIFI_RADIO_STAT *pRadioStat; -+ struct sk_buff *skb; -+ UINT_32 u4BufLen; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ -+ u4BufLen = sizeof(WIFI_RADIO_STAT) + sizeof(WIFI_IFACE_STAT); -+ pRadioStat = kalMemAlloc(u4BufLen, VIR_MEM_TYPE); -+ if (!pRadioStat) { -+ DBGLOG(REQ, ERROR, "%s kalMemAlloc pRadioStat failed\n", __func__); -+ return -ENOMEM; -+ } -+ kalMemZero(pRadioStat, u4BufLen); -+ -+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, u4BufLen); -+ if (!skb) { -+ DBGLOG(REQ, TRACE, "%s allocate skb failed:%x\n", __func__, i4Status); -+ return -ENOMEM; -+ } -+ -+ /*rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStatistics, -+ &rRadioStat, -+ sizeof(rRadioStat), -+ TRUE, -+ TRUE, -+ TRUE, -+ FALSE, -+ &u4BufLen); */ -+ /* only for test */ -+ pRadioStat->radio = 10; -+ pRadioStat->on_time = 11; -+ pRadioStat->tx_time = 12; -+ pRadioStat->num_channels = 4; -+ -+ /*NLA_PUT(skb, LSTATS_ATTRIBUTE_STATS, u4BufLen, pRadioStat);*/ -+ if (unlikely(nla_put(skb, LSTATS_ATTRIBUTE_STATS, u4BufLen, pRadioStat) < 0)) -+ goto nla_put_failure; -+ -+ i4Status = cfg80211_vendor_cmd_reply(skb); -+ kalMemFree(pRadioStat, VIR_MEM_TYPE, u4BufLen); -+ return -1; /* not support LLS now*/ -+ /* return i4Status; */ -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_event_complete_scan(struct wiphy *wiphy, struct wireless_dev *wdev, WIFI_SCAN_EVENT complete) -+{ -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ /* WIFI_SCAN_EVENT complete_scan; */ -+ -+ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(complete), GSCAN_EVENT_COMPLETE_SCAN, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ /* complete_scan = WIFI_SCAN_COMPLETE; */ -+ /*NLA_PUT_U32(skb, GSCAN_EVENT_COMPLETE_SCAN, complete);*/ -+ { -+ unsigned int __tmp = complete; -+ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_COMPLETE_SCAN, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_event_scan_results_available(struct wiphy *wiphy, struct wireless_dev *wdev, UINT_32 num) -+{ -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ /* UINT_32 scan_result; */ -+ -+ DBGLOG(REQ, INFO, "%s for vendor command %d \r\n", __func__, num); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(num), GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ /* scan_result = 2; */ -+ /*NLA_PUT_U32(skb, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, num);*/ -+ { -+ unsigned int __tmp = num; -+ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_event_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len) -+{ -+ struct sk_buff *skb; -+ PARAM_WIFI_GSCAN_RESULT result; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(result), GSCAN_EVENT_FULL_SCAN_RESULTS, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(&result, sizeof(result)); -+ kalMemCopy(result.ssid, "Gscan_full_test", sizeof("Gscan_full_test")); -+ result.channel = 2437; -+ -+ /* kalMemCopy(&result, pdata, sizeof(PARAM_WIFI_GSCAN_RESULT); */ -+ /*NLA_PUT(skb, GSCAN_EVENT_FULL_SCAN_RESULTS, sizeof(result), &result);*/ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_FULL_SCAN_RESULTS, -+ sizeof(result), &result) < 0)) -+ goto nla_put_failure; -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_event_significant_change_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_CHANGE_RESULT pdata, UINT_32 data_len) -+{ -+ struct sk_buff *skb; -+ PARAM_WIFI_CHANGE_RESULT result[2], *presult; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_CHANGE_RESULT), -+ GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ presult = result; -+ kalMemZero(presult, (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2)); -+ /* only for test */ -+ kalMemCopy(presult->bssid, "213123", sizeof(mac_addr)); -+ presult->channel = 2437; -+ presult->rssi[0] = -45; -+ presult->rssi[1] = -46; -+ presult++; -+ presult->channel = 2439; -+ presult->rssi[0] = -47; -+ presult->rssi[1] = -48; -+ /*NLA_PUT(skb, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2), result);*/ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, -+ (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2), result) < 0)) -+ goto nla_put_failure; -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_event_hotlist_ap_found(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len) -+{ -+ struct sk_buff *skb; -+ PARAM_WIFI_GSCAN_RESULT result[2], *presult; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_GSCAN_RESULT), -+ GSCAN_EVENT_HOTLIST_RESULTS_FOUND, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ presult = result; -+ kalMemZero(presult, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2)); -+ /* only for test */ -+ kalMemCopy(presult->bssid, "123123", sizeof(mac_addr)); -+ presult->channel = 2441; -+ presult->rssi = -45; -+ presult++; -+ presult->channel = 2443; -+ presult->rssi = -47; -+ /*NLA_PUT(skb, GSCAN_EVENT_HOTLIST_RESULTS_FOUND, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result);*/ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_HOTLIST_RESULTS_FOUND, -+ (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result) < 0)) -+ goto nla_put_failure; -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_event_hotlist_ap_lost(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len) -+{ -+ struct sk_buff *skb; -+ PARAM_WIFI_GSCAN_RESULT result[2], *presult; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_GSCAN_RESULT), -+ GSCAN_EVENT_HOTLIST_RESULTS_LOST, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ presult = result; -+ kalMemZero(presult, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2)); -+ /* only for test */ -+ kalMemCopy(presult->bssid, "321321", sizeof(mac_addr)); -+ presult->channel = 2445; -+ presult->rssi = -46; -+ presult++; -+ presult->channel = 2447; -+ presult->rssi = -48; -+ /*NLA_PUT(skb, GSCAN_EVENT_HOTLIST_RESULTS_LOST, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result);*/ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_HOTLIST_RESULTS_LOST, -+ (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result) < 0)) -+ goto nla_put_failure; -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c -new file mode 100644 -index 0000000000000..1793742e98022 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c -@@ -0,0 +1,4158 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_wext.c#3 -+*/ -+ -+/*! \file gl_wext.c -+ \brief ioctl() (mostly Linux Wireless Extensions) routines for STA driver. -+*/ -+ -+/* -+** Log: gl_wext.c -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 01 16 2012 wh.su -+ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl -+ * Adding the template code for set / get band IOCTL (with ICS supplicant_6).. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 01 02 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 23 2011 tsaiyuan.hsu -+ * [WCXRP00000979] [MT6620 Wi-Fi][DRV]] stop attempting to connect to config AP after D3 state -+ * avoid entering D3 state after deep sleep. -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 27 2011 wh.su -+ * [WCXRP00000877] [MT6620 Wi-Fi][Driver] Remove the netif_carry_ok check for avoid the wpa_supplicant fail to query -+ * the ap address -+ * Remove the netif check while query bssid and ssid -+ * -+ * 07 26 2011 chinglan.wang -+ * NULL -+ * [MT6620][WiFi Driver] Do not include the WSC IE in the association info packet when not do the wps connection.. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 05 17 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Initialize the vairlabes. -+ * -+ * 05 11 2011 jeffrey.chang -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * modify set_tx_pow ioctl -+ * -+ * 03 29 2011 terry.wu -+ * [WCXRP00000610] [MT 6620 Wi-Fi][Driver] Fix klocwork waring -+ * [MT6620 Wi-Fi][Driver] Fix klocwork warning. Add Null pointer check on wext_get_essid. Limit the upper bound of -+ * essid storage array. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * improve portability for awareness of early version of linux kernel and wireless extension. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 02 21 2011 wh.su -+ * [WCXRP00000483] [MT6620 Wi-Fi][Driver] Check the kalIoctl return value before doing the memory copy at linux get -+ * essid -+ * fixed the potential error to do a larget memory copy while wlanoid get essid not actually running. -+ * -+ * 02 08 2011 george.huang -+ * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler -+ * Support querying power mode OID. -+ * -+ * 01 29 2011 wh.su -+ * [WCXRP00000408] [MT6620 Wi-Fi][Driver] Not doing memory alloc while ioctl set ie with length 0 -+ * not doing mem alloc. while set ie length already 0 -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Remove debug text. -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Adjust OID order. -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 01 11 2011 chinglan.wang -+ * NULL -+ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. Connection establish -+ * successfully. -+ * Use the WPS function to connect AP, the privacy bit always is set to 1. . -+ * -+ * 01 07 2011 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add a new compiling option to control if MCR read/write is permitted -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous types -+ * to ease slab system pressure -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 31 2010 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add some iwpriv commands to support test mode operation -+ * -+ * 12 15 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * Support set PS profile and set WMM-PS related iwpriv. -+ * -+ * 12 15 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * Allow change PS profile function (through wext_set_power()). -+ * -+ * 12 14 2010 jeffrey.chang -+ * [WCXRP00000262] [MT6620 Wi-Fi][Driver] modify the scan request ioctl to handle hidden SSID -+ * handle hidden SSID -+ * -+ * 12 13 2010 chinglan.wang -+ * NULL -+ * Add WPS 1.0 feature flag to enable the WPS 1.0 function. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * Fix compiling error -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 30 2010 cp.wu -+ * [WCXRP00000213] [MT6620 Wi-Fi][Driver] Implement scanning with specified SSID for wpa_supplicant with ap_scan=1 -+ * . -+ * -+ * 11 08 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * add the message check code from mt5921. -+ * -+ * 10 19 2010 jeffrey.chang -+ * [WCXRP00000121] [MT6620 Wi-Fi][Driver] Temporarily disable set power mode ioctl which may cause 6620 to enter power -+ * saving -+ * Temporarily disable set power mode ioctl which may cause MT6620 to enter power saving -+ * -+ * 10 18 2010 jeffrey.chang -+ * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue -+ * refine the scan ioctl to prevent hanging of Android UI -+ * -+ * 10 01 2010 wh.su -+ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function -+ * add the scan result with wapi ie. -+ * -+ * 09 30 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * fixed the wapi ie assigned issue. -+ * -+ * 09 27 2010 wh.su -+ * NULL -+ * [WCXRP00000067][MT6620 Wi-Fi][Driver] Support the android+ WAPI function. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 09 2010 cp.wu -+ * NULL -+ * add WPS/WPA/RSN IE for Wi-Fi Direct scanning result. -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * Androi/Linux: return current operating channel information -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * enable remove key ioctl -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 28 2010 jeffrey.chang -+ * NULL -+ * 1) enable encyption ioctls -+ * 2) temporarily disable remove keys ioctl to prevent TX1 busy -+ * -+ * 07 28 2010 jeffrey.chang -+ * NULL -+ * 1) remove unused spinlocks -+ * 2) enable encyption ioctls -+ * 3) fix scan ioctl which may cause supplicant to hang -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add kal api for scanning done -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * for linux driver migration -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * remove unused macro and debug messages -+ * -+ * 05 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Add dissassoication support for wpa supplicant -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * -+ * 1) modify rx path code for supporting Wi-Fi direct -+ * 2) modify config.h since Linux dont need to consider retaining packet -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Add ioctl of power management -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * remove debug message -+ * -+ * 04 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used -+ * * 2) fix ioctl -+ * -+ * 04 12 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * remove debug messages for pre-release -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * * * * are done in adapter layer. -+ * -+ * 04 02 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix ioctl type -+ * -+ * 04 01 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * enable pmksa cache operation -+ * -+ * 03 31 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix ioctl which may cause cmdinfo memory leak -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * emulate NDIS Pending OID facility -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\38 2009-10-08 10:33:22 GMT mtk01090 -+** Avoid accessing private data of net_device directly. Replace with netdev_priv(). -+** Add more checking for input parameters and pointers. -+** \main\maintrunk.MT5921\37 2009-09-29 16:49:48 GMT mtk01090 -+** Remove unused variables -+** \main\maintrunk.MT5921\36 2009-09-28 20:19:11 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\35 2009-09-03 11:42:30 GMT mtk01088 -+** adding the wapi ioctl support -+** \main\maintrunk.MT5921\34 2009-08-18 22:56:50 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\33 2009-05-14 22:43:47 GMT mtk01089 -+** fix compiling warning -+** \main\maintrunk.MT5921\32 2009-05-07 22:26:18 GMT mtk01089 -+** Add mandatory and private IO control for Linux BWCS -+** \main\maintrunk.MT5921\31 2009-02-07 15:11:14 GMT mtk01088 -+** fixed the compiling error -+** \main\maintrunk.MT5921\30 2009-02-07 14:46:51 GMT mtk01088 -+** add the privacy setting from linux supplicant ap selection -+** \main\maintrunk.MT5921\29 2008-11-19 15:18:50 GMT mtk01088 -+** fixed the compling error -+** \main\maintrunk.MT5921\28 2008-11-19 11:56:18 GMT mtk01088 -+** rename some variable with pre-fix to avoid the misunderstanding -+** \main\maintrunk.MT5921\27 2008-08-29 16:59:43 GMT mtk01088 -+** fixed compiling error -+** \main\maintrunk.MT5921\26 2008-08-29 14:55:53 GMT mtk01088 -+** adjust the code for meet the coding style, and add assert check -+** \main\maintrunk.MT5921\25 2008-06-02 11:15:19 GMT mtk01461 -+** Update after wlanoidSetPowerMode changed -+** \main\maintrunk.MT5921\24 2008-05-30 15:13:12 GMT mtk01084 -+** rename wlanoid -+** \main\maintrunk.MT5921\23 2008-03-28 10:40:28 GMT mtk01461 -+** Add set desired rate in Linux STD IOCTL -+** \main\maintrunk.MT5921\22 2008-03-18 10:31:24 GMT mtk01088 -+** add pmkid ioctl and indicate -+** \main\maintrunk.MT5921\21 2008-03-11 15:21:24 GMT mtk01461 -+** \main\maintrunk.MT5921\20 2008-03-11 14:50:55 GMT mtk01461 -+** Refine WPS related priv ioctl for unified interface -+** -+** \main\maintrunk.MT5921\19 2008-03-06 16:30:41 GMT mtk01088 -+** move the configuration code from set essid function, -+** remove the non-used code -+** \main\maintrunk.MT5921\18 2008-02-21 15:47:09 GMT mtk01461 -+** Fix CR[489] -+** \main\maintrunk.MT5921\17 2008-02-12 23:38:31 GMT mtk01461 -+** Add Set Frequency & Channel oid support for Linux -+** \main\maintrunk.MT5921\16 2008-01-24 12:07:34 GMT mtk01461 -+** \main\maintrunk.MT5921\15 2008-01-24 12:00:10 GMT mtk01461 -+** Modify the wext_essid for set up correct information for IBSS, and fix the wrong input ptr for prAdapter -+** \main\maintrunk.MT5921\14 2007-12-06 09:30:12 GMT mtk01425 -+** 1. Branch Test -+** \main\maintrunk.MT5921\13 2007-12-04 18:07:59 GMT mtk01461 -+** fix typo -+** \main\maintrunk.MT5921\12 2007-11-30 17:10:21 GMT mtk01425 -+** 1. Fix compiling erros -+** -+** \main\maintrunk.MT5921\11 2007-11-27 10:43:22 GMT mtk01425 -+** 1. Add WMM-PS setting -+** \main\maintrunk.MT5921\10 2007-11-06 20:33:32 GMT mtk01088 -+** fixed the compiler error -+** \main\maintrunk.MT5921\9 2007-11-06 19:33:15 GMT mtk01088 -+** add WPS code -+** \main\maintrunk.MT5921\8 2007-10-30 12:00:44 GMT MTK01425 -+** 1. Update wlanQueryInformation -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "gl_os.h" -+ -+#include "config.h" -+#include "wlan_oid.h" -+ -+#include "gl_wext.h" -+#include "gl_wext_priv.h" -+ -+#include "precomp.h" -+ -+#if CFG_SUPPORT_WAPI -+#include "gl_sec.h" -+#endif -+ -+/* compatibility to wireless extensions */ -+#ifdef WIRELESS_EXT -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+const long channel_freq[] = { -+ 2412, 2417, 2422, 2427, 2432, 2437, 2442, -+ 2447, 2452, 2457, 2462, 2467, 2472, 2484 -+}; -+ -+ -+#define NUM_CHANNELS (sizeof(channel_freq) / sizeof(channel_freq[0])) -+ -+#define MAX_SSID_LEN 32 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+/* NOTE: name in iwpriv_args only have 16 bytes */ -+static const struct iw_priv_args rIwPrivTable[] = { -+ {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""}, -+ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""}, -+ {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, ""}, -+ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, ""}, -+ {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, ""}, -+ -+ {IOCTL_GET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""}, -+ {IOCTL_GET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""}, -+ -+ {IOCTL_SET_INTS, IW_PRIV_TYPE_INT | 4, 0, ""}, -+ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | 50, ""}, -+ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_CHAR | 16, ""}, -+ -+ {IOCTL_SET_STRING, IW_PRIV_TYPE_CHAR | 256, 0, ""}, -+ -+ /* added for set_oid and get_oid */ -+ {IOCTL_SET_STRUCT, 256, 0, ""}, -+ {IOCTL_GET_STRUCT, 0, 256, ""}, -+ -+ /* sub-ioctl definitions */ -+#if 0 -+ {PRIV_CMD_REG_DOMAIN, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_reg_domain"}, -+ {PRIV_CMD_REG_DOMAIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_reg_domain"}, -+#endif -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ {PRIV_CMD_CSUM_OFFLOAD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_tcp_csum"}, -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+ {PRIV_CMD_POWER_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power_mode"}, -+ {PRIV_CMD_POWER_MODE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_power_mode"}, -+ -+ {PRIV_CMD_WMM_PS, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "set_wmm_ps"}, -+ -+ {PRIV_CMD_TEST_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_test_mode"}, -+ {PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_test_cmd"}, -+ {PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ "get_test_result"}, -+#if CFG_SUPPORT_PRIV_MCR_RW -+ {PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_mcr"}, -+ {PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ "get_mcr"}, -+#endif -+ {PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_sw_ctrl"}, -+ {PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ "get_sw_ctrl"}, -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+ {PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_bwcs"}, -+ /* GET STRUCT sub-ioctls commands */ -+ {PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ "get_bwcs"}, -+#endif -+ -+ /* SET STRUCT sub-ioctls commands */ -+ {PRIV_CMD_OID, 256, 0, "set_oid"}, -+ /* GET STRUCT sub-ioctls commands */ -+ {PRIV_CMD_OID, 0, 256, "get_oid"}, -+ -+ {PRIV_CMD_BAND_CONFIG, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_band"}, -+ {PRIV_CMD_BAND_CONFIG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_band"}, -+ -+ {PRIV_CMD_SET_TX_POWER, IW_PRIV_TYPE_INT | 4, 0, "set_txpower"}, -+ {PRIV_CMD_GET_CH_LIST, 0, IW_PRIV_TYPE_INT | 50, "get_ch_list"}, -+ {PRIV_CMD_DUMP_MEM, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ "get_mem"}, -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ {PRIV_CMD_P2P_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_p2p_mode"}, -+#endif -+ {PRIV_CMD_GET_BUILD_DATE_CODE, 0, IW_PRIV_TYPE_CHAR | 16, "get_date_code"}, -+ {PRIV_CMD_GET_DEBUG_CODE, 0, IW_PRIV_TYPE_CHAR | 16, "get_dbg_code"}, -+ /* handle any command with many input parameters */ -+ {PRIV_CMD_OTHER, IW_PRIV_TYPE_CHAR | 256, 0, "set_str_cmd"}, -+ -+ {PRIV_CMD_WFD_DEBUG_CODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_wfd_dbg_code"}, -+}; -+ -+static const iw_handler rIwPrivHandler[] = { -+ [IOCTL_SET_INT - SIOCIWFIRSTPRIV] = priv_set_int, -+ [IOCTL_GET_INT - SIOCIWFIRSTPRIV] = priv_get_int, -+ [IOCTL_SET_ADDRESS - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_GET_ADDRESS - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_SET_STR - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_GET_STR - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_SET_KEY - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_GET_KEY - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_SET_STRUCT - SIOCIWFIRSTPRIV] = priv_set_struct, -+ [IOCTL_GET_STRUCT - SIOCIWFIRSTPRIV] = priv_get_struct, -+ [IOCTL_SET_STRUCT_FOR_EM - SIOCIWFIRSTPRIV] = priv_set_struct, -+ [IOCTL_SET_INTS - SIOCIWFIRSTPRIV] = priv_set_ints, -+ [IOCTL_GET_INTS - SIOCIWFIRSTPRIV] = priv_get_ints, -+ [IOCTL_SET_STRING - SIOCIWFIRSTPRIV] = priv_set_string, -+}; -+ -+const struct iw_handler_def wext_handler_def = { -+ .num_standard = 0, -+ .num_private = (__u16) sizeof(rIwPrivHandler) / sizeof(iw_handler), -+ .num_private_args = (__u16) sizeof(rIwPrivTable) / sizeof(struct iw_priv_args), -+ .standard = (iw_handler *) NULL, -+ .private = rIwPrivHandler, -+ .private_args = rIwPrivTable, -+ .get_wireless_stats = wext_get_wireless_stats, -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired WPA/RSN Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ucDesiredElemId && i4InfoElemLen <= i4TotalIeLen) { -+ if (ucDesiredElemId != 0xDD) { -+ /* Non 0xDD, OK! */ -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ /* EID == 0xDD, check WPA IE */ -+ if (pucIEStart[1] >= 4) { -+ if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x01", 4) == 0) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ } /* check WPA IE length */ -+ /* check EID == 0xDD */ -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* parseSearchDesiredWPAIE */ -+ -+#if CFG_SUPPORT_WAPI -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired WAPI Information Element . -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextSrchDesiredWAPIIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ELEM_ID_WAPI && i4InfoElemLen <= i4TotalIeLen) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* wextSrchDesiredWAPIIE */ -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Check if exist the desired HS2.0 Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextIsDesiredHS20IE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucCurIE); -+ -+ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; -+ -+ if (pucCurIE[0] == ELEM_ID_VENDOR && i4InfoElemLen <= i4TotalIeLen) { -+ if (pucCurIE[1] >= ELEM_MIN_LEN_HS20_INDICATION) { -+ if (memcmp(&pucCurIE[2], "\x50\x6f\x9a\x10", 4) == 0) -+ return TRUE; -+ } -+ } -+ /* check desired EID */ -+ return FALSE; -+} /* wextIsDesiredHS20IE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Check if exist the desired interworking Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextIsDesiredInterworkingIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucCurIE); -+ -+ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; -+ -+ if (pucCurIE[0] == ELEM_ID_INTERWORKING && i4InfoElemLen <= i4TotalIeLen) { -+ switch (pucCurIE[1]) { -+ case IW_IE_LENGTH_ANO: -+ case IW_IE_LENGTH_ANO_HESSID: -+ case IW_IE_LENGTH_ANO_VENUE: -+ case IW_IE_LENGTH_ANO_VENUE_HESSID: -+ return TRUE; -+ -+ default: -+ break; -+ } -+ -+ } -+ /* check desired EID */ -+ return FALSE; -+} /* wextIsDesiredInterworkingIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Check if exist the desired Adv Protocol Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextIsDesiredAdvProtocolIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucCurIE); -+ -+ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; -+ -+ if (pucCurIE[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL && i4InfoElemLen <= i4TotalIeLen) -+ return TRUE; -+ /* check desired EID */ -+ return FALSE; -+} /* wextIsDesiredAdvProtocolIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Check if exist the desired Roaming Consortium Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextIsDesiredRoamingConsortiumIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucCurIE); -+ -+ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; -+ -+ if (pucCurIE[0] == ELEM_ID_ROAMING_CONSORTIUM && i4InfoElemLen <= i4TotalIeLen) -+ return TRUE; -+ /* check desired EID */ -+ return FALSE; -+} /* wextIsDesiredRoamingConsortiumIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired HS2.0 Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextSrchDesiredHS20IE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ELEM_ID_VENDOR && i4InfoElemLen <= i4TotalIeLen) { -+ if (pucIEStart[1] >= ELEM_MIN_LEN_HS20_INDICATION) { -+ if (memcmp(&pucIEStart[2], "\x50\x6f\x9a\x10", 4) == 0) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ } -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* wextSrchDesiredHS20IE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired interworking Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextSrchDesiredInterworkingIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ELEM_ID_INTERWORKING && i4InfoElemLen <= i4TotalIeLen) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* wextSrchDesiredInterworkingIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired Adv Protocol Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextSrchDesiredAdvProtocolIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL && i4InfoElemLen <= i4TotalIeLen) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* wextSrchDesiredAdvProtocolIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired Roaming Consortium Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextSrchDesiredRoamingConsortiumIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ELEM_ID_ROAMING_CONSORTIUM && i4InfoElemLen <= i4TotalIeLen) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* wextSrchDesiredRoamingConsortiumIE */ -+#endif -+ -+#if CFG_SUPPORT_WPS -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired WPS Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ucDesiredElemId && i4InfoElemLen <= i4TotalIeLen) { -+ if (ucDesiredElemId != 0xDD) { -+ /* Non 0xDD, OK! */ -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ /* EID == 0xDD, check WPS IE */ -+ if (pucIEStart[1] >= 4) { -+ if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x04", 4) == 0) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ } /* check WPS IE length */ -+ /* check EID == 0xDD */ -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* parseSearchDesiredWPSIE */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Get the name of the protocol used on the air. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] pcName Buffer to store protocol name string -+* \param[in] pcExtra NULL. -+* -+* \retval 0 For success. -+* -+* \note If netif_carrier_ok, protocol name is returned; -+* otherwise, "disconnected" is returned. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_name(IN struct net_device *prNetDev, IN struct iw_request_info *prIwrInfo, OUT char *pcName, IN char *pcExtra) -+{ -+ ENUM_PARAM_NETWORK_TYPE_T eNetWorkType = PARAM_NETWORK_TYPE_NUM; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(pcName); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcName)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (netif_carrier_ok(prNetDev)) { -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryNetworkTypeInUse, -+ &eNetWorkType, sizeof(eNetWorkType), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ switch (eNetWorkType) { -+ case PARAM_NETWORK_TYPE_DS: -+ strcpy(pcName, "IEEE 802.11b"); -+ break; -+ case PARAM_NETWORK_TYPE_OFDM24: -+ strcpy(pcName, "IEEE 802.11bgn"); -+ break; -+ case PARAM_NETWORK_TYPE_AUTOMODE: -+ case PARAM_NETWORK_TYPE_OFDM5: -+ strcpy(pcName, "IEEE 802.11abgn"); -+ break; -+ case PARAM_NETWORK_TYPE_FH: -+ default: -+ strcpy(pcName, "IEEE 802.11"); -+ break; -+ } -+ } else { -+ strcpy(pcName, "Disconnected"); -+ } -+ -+ return 0; -+} /* wext_get_name */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set the operating channel in the wireless device. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL -+* \param[in] prFreq Buffer to store frequency information -+* \param[in] pcExtra NULL -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If infrastructure mode is not NET NET_TYPE_IBSS. -+* \retval -EINVAL Invalid channel frequency. -+* -+* \note If infrastructure mode is IBSS, new channel frequency is set to device. -+* The range of channel number depends on different regulatory domain. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_freq(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN struct iw_freq *prIwFreq, IN char *pcExtra) -+{ -+ -+#if 0 -+ UINT_32 u4ChnlFreq; /* Store channel or frequency information */ -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwFreq); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prIwFreq)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* -+ printk("set m:%d, e:%d, i:%d, flags:%d\n", -+ prIwFreq->m, prIwFreq->e, prIwFreq->i, prIwFreq->flags); -+ */ -+ -+ /* If setting by frequency, convert to a channel */ -+ if ((prIwFreq->e == 1) && (prIwFreq->m >= (int)2.412e8) && (prIwFreq->m <= (int)2.484e8)) { -+ -+ /* Change to KHz format */ -+ u4ChnlFreq = (UINT_32) (prIwFreq->m / (KILO / 10)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetFrequency, -+ &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (WLAN_STATUS_SUCCESS != rStatus) -+ return -EINVAL; -+ } -+ /* Setting by channel number */ -+ else if ((prIwFreq->m > KILO) || (prIwFreq->e > 0)) -+ return -EOPNOTSUPP; -+ -+ /* Change to channel number format */ -+ u4ChnlFreq = (UINT_32) prIwFreq->m; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetChannel, &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (WLAN_STATUS_SUCCESS != rStatus) -+ return -EINVAL; -+ -+#endif -+ -+ return 0; -+ -+} /* wext_set_freq */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get the operating channel in the wireless device. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prFreq Buffer to store frequency information. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 If netif_carrier_ok. -+* \retval -ENOTCONN Otherwise -+* -+* \note If netif_carrier_ok, channel frequency information is stored in pFreq. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_freq(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_freq *prIwFreq, IN char *pcExtra) -+{ -+ UINT_32 u4Channel = 0; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwFreq); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prIwFreq)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* GeorgeKuo: TODO skip checking in IBSS mode */ -+ if (!netif_carrier_ok(prNetDev)) -+ return -ENOTCONN; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryFrequency, &u4Channel, sizeof(u4Channel), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ prIwFreq->m = (int)u4Channel; /* freq in KHz */ -+ prIwFreq->e = 3; -+ -+ return 0; -+ -+} /* wext_get_freq */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set operating mode. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] pu4Mode Pointer to new operation mode. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If new mode is not supported. -+* -+* \note Device will run in new operation mode if it is valid. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_mode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN unsigned int *pu4Mode, IN char *pcExtra) -+{ -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(pu4Mode); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pu4Mode)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ switch (*pu4Mode) { -+ case IW_MODE_AUTO: -+ eOpMode = NET_TYPE_AUTO_SWITCH; -+ break; -+ -+ case IW_MODE_ADHOC: -+ eOpMode = NET_TYPE_IBSS; -+ break; -+ -+ case IW_MODE_INFRA: -+ eOpMode = NET_TYPE_INFRA; -+ break; -+ -+ default: -+ DBGLOG(REQ, ERROR, "%s(): Set UNSUPPORTED Mode = %d.\n", __func__, *pu4Mode); -+ return -EOPNOTSUPP; -+ } -+ -+ /* printk("%s(): Set Mode = %d\n", __FUNCTION__, *pu4Mode); */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetInfrastructureMode, -+ &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ /* after set operation mode, key table are cleared */ -+ -+ /* reset wpa info */ -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+#if CFG_SUPPORT_802_11W -+ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; -+#endif -+ -+ return 0; -+} /* wext_set_mode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get operating mode. -+* -+* \param[in] prNetDev Net device requested. -+* \param[in] prIwReqInfo NULL. -+* \param[out] pu4Mode Buffer to store operating mode information. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 If data is valid. -+* \retval -EINVAL Otherwise. -+* -+* \note If netif_carrier_ok, operating mode information is stored in pu4Mode. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_mode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, OUT unsigned int *pu4Mode, IN char *pcExtra) -+{ -+ ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_NUM; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(pu4Mode); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pu4Mode)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryInfrastructureMode, -+ &eOpMode, sizeof(eOpMode), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ switch (eOpMode) { -+ case NET_TYPE_IBSS: -+ *pu4Mode = IW_MODE_ADHOC; -+ break; -+ -+ case NET_TYPE_INFRA: -+ *pu4Mode = IW_MODE_INFRA; -+ break; -+ -+ case NET_TYPE_AUTO_SWITCH: -+ *pu4Mode = IW_MODE_AUTO; -+ break; -+ -+ default: -+ DBGLOG(REQ, ERROR, "%s(): Get UNKNOWN Mode.\n", __func__); -+ return -EINVAL; -+ } -+ -+ return 0; -+} /* wext_get_mode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get the valid range for each configurable STA setting value. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prData Pointer to iw_point structure, not used. -+* \param[out] pcExtra Pointer to buffer which is allocated by caller of this -+* function, wext_support_ioctl() or ioctl_standard_call() in -+* wireless.c. -+* -+* \retval 0 If data is valid. -+* -+* \note The extra buffer (pcExtra) is filled with information from driver. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_range(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prData, OUT char *pcExtra) -+{ -+ struct iw_range *prRange = NULL; -+ PARAM_RATES_EX aucSuppRate = { 0 }; /* data buffers */ -+ int i = 0; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ prRange = (struct iw_range *)pcExtra; -+ -+ memset(prRange, 0, sizeof(*prRange)); -+ prRange->throughput = 20000000; /* 20Mbps */ -+ prRange->min_nwid = 0; /* not used */ -+ prRange->max_nwid = 0; /* not used */ -+ -+ /* scan_capa not implemented */ -+ -+ /* event_capa[6]: kernel + driver capabilities */ -+ prRange->event_capa[0] = (IW_EVENT_CAPA_K_0 | IW_EVENT_CAPA_MASK(SIOCGIWAP) -+ | IW_EVENT_CAPA_MASK(SIOCGIWSCAN) -+ /* can't display meaningful string in iwlist -+ | IW_EVENT_CAPA_MASK(SIOCGIWTXPOW) -+ | IW_EVENT_CAPA_MASK(IWEVMICHAELMICFAILURE) -+ | IW_EVENT_CAPA_MASK(IWEVASSOCREQIE) -+ | IW_EVENT_CAPA_MASK(IWEVPMKIDCAND) -+ */ -+ ); -+ prRange->event_capa[1] = IW_EVENT_CAPA_K_1; -+ -+ /* report 2.4G channel and frequency only */ -+ prRange->num_channels = (__u16) NUM_CHANNELS; -+ prRange->num_frequency = (__u8) NUM_CHANNELS; -+ for (i = 0; i < NUM_CHANNELS; i++) { -+ /* iwlib takes this number as channel number */ -+ prRange->freq[i].i = i + 1; -+ prRange->freq[i].m = channel_freq[i]; -+ prRange->freq[i].e = 6; /* Values in table in MHz */ -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQuerySupportedRates, -+ &aucSuppRate, sizeof(aucSuppRate), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ for (i = 0; i < IW_MAX_BITRATES && i < PARAM_MAX_LEN_RATES_EX; i++) { -+ if (aucSuppRate[i] == 0) -+ break; -+ prRange->bitrate[i] = (aucSuppRate[i] & 0x7F) * 500000; /* 0.5Mbps */ -+ } -+ prRange->num_bitrates = i; -+ -+ prRange->min_rts = 0; -+ prRange->max_rts = 2347; -+ prRange->min_frag = 256; -+ prRange->max_frag = 2346; -+ -+ prRange->min_pmp = 0; /* power management by driver */ -+ prRange->max_pmp = 0; /* power management by driver */ -+ prRange->min_pmt = 0; /* power management by driver */ -+ prRange->max_pmt = 0; /* power management by driver */ -+ prRange->pmp_flags = IW_POWER_RELATIVE; /* pm default flag */ -+ prRange->pmt_flags = IW_POWER_ON; /* pm timeout flag */ -+ prRange->pm_capa = IW_POWER_ON; /* power management by driver */ -+ -+ prRange->encoding_size[0] = 5; /* wep40 */ -+ prRange->encoding_size[1] = 16; /* tkip */ -+ prRange->encoding_size[2] = 16; /* ckip */ -+ prRange->encoding_size[3] = 16; /* ccmp */ -+ prRange->encoding_size[4] = 13; /* wep104 */ -+ prRange->encoding_size[5] = 16; /* wep128 */ -+ prRange->num_encoding_sizes = 6; -+ prRange->max_encoding_tokens = 6; /* token? */ -+ -+#if WIRELESS_EXT < 17 -+ prRange->txpower_capa = 0x0002; /* IW_TXPOW_RELATIVE */ -+#else -+ prRange->txpower_capa = IW_TXPOW_RELATIVE; -+#endif -+ prRange->num_txpower = 5; -+ prRange->txpower[0] = 0; /* minimum */ -+ prRange->txpower[1] = 25; /* 25% */ -+ prRange->txpower[2] = 50; /* 50% */ -+ prRange->txpower[3] = 100; /* 100% */ -+ -+ prRange->we_version_compiled = WIRELESS_EXT; -+ prRange->we_version_source = WIRELESS_EXT; -+ -+ prRange->retry_capa = IW_RETRY_LIMIT; -+ prRange->retry_flags = IW_RETRY_LIMIT; -+ prRange->min_retry = 7; -+ prRange->max_retry = 7; -+ prRange->r_time_flags = IW_RETRY_ON; -+ prRange->min_r_time = 0; -+ prRange->max_r_time = 0; -+ -+ /* signal strength and link quality */ -+ /* Just define range here, reporting value moved to wext_get_stats() */ -+ prRange->sensitivity = -83; /* fixed value */ -+ prRange->max_qual.qual = 100; /* max 100% */ -+ prRange->max_qual.level = (__u8) (0x100 - 0); /* max 0 dbm */ -+ prRange->max_qual.noise = (__u8) (0x100 - 0); /* max 0 dbm */ -+ -+ /* enc_capa */ -+#if WIRELESS_EXT > 17 -+ prRange->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; -+#endif -+ -+ /* min_pms; Minimal PM saving */ -+ /* max_pms; Maximal PM saving */ -+ /* pms_flags; How to decode max/min PM saving */ -+ -+ /* modul_capa; IW_MODUL_* bit field */ -+ /* bitrate_capa; Types of bitrates supported */ -+ -+ return 0; -+} /* wext_get_range */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set BSSID of AP to connect. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prAddr Pointer to struct sockaddr structure containing AP's BSSID. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 For success. -+* -+* \note Desired AP's BSSID is set to driver. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_ap(IN struct net_device *prDev, -+ IN struct iw_request_info *prIwrInfo, IN struct sockaddr *prAddr, IN char *pcExtra) -+{ -+ return 0; -+} /* wext_set_ap */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get AP MAC address. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prAddr Pointer to struct sockaddr structure storing AP's BSSID. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 If netif_carrier_ok. -+* \retval -ENOTCONN Otherwise. -+* -+* \note If netif_carrier_ok, AP's mac address is stored in pAddr->sa_data. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_ap(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct sockaddr *prAddr, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prAddr); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prAddr)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* if (!netif_carrier_ok(prNetDev)) { */ -+ /* return -ENOTCONN; */ -+ /* } */ -+ -+ if (prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_DISCONNECTED) { -+ /*memset(prAddr, 0, 6);*/ -+ memset(prAddr, 0, sizeof(struct sockaddr)); -+ return 0; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryBssid, prAddr->sa_data, ETH_ALEN, TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ return 0; -+} /* wext_get_ap */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set mlme operation request. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prData Pointer of iw_point header. -+* \param[in] pcExtra Pointer to iw_mlme structure mlme request information. -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP unsupported IW_MLME_ command. -+* \retval -EINVAL Set MLME Fail, different bssid. -+* -+* \note Driver will start mlme operation if valid. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_mlme(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prData, IN char *pcExtra) -+{ -+ struct iw_mlme *prMlme = NULL; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ prMlme = (struct iw_mlme *)pcExtra; -+ if (prMlme->cmd == IW_MLME_DEAUTH || prMlme->cmd == IW_MLME_DISASSOC) { -+ if (!netif_carrier_ok(prNetDev)) { -+ DBGLOG(REQ, WARN, "[wifi] Set MLME Deauth/Disassoc, but netif_carrier_off\n"); -+ return 0; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ return 0; -+ } -+ DBGLOG(REQ, WARN, "[wifi] unsupported IW_MLME_ command :%d\n", prMlme->cmd); -+ return -EOPNOTSUPP; -+ -+} /* wext_set_mlme */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To issue scan request. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prData NULL. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 For success. -+* \retval -EFAULT Tx power is off. -+* -+* \note Device will start scanning. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_scan(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN union iwreq_data *prData, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ int essid_len = 0; -+ -+ ASSERT(prNetDev); -+ if (FALSE == GLUE_CHK_DEV(prNetDev)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+#if WIRELESS_EXT > 17 -+ /* retrieve SSID */ -+ if (prData) -+ essid_len = ((struct iw_scan_req *)(((struct iw_point *)prData)->pointer))->essid_len; -+#endif -+ -+ init_completion(&prGlueInfo->rScanComp); -+ -+ /* TODO: parse flags and issue different scan requests? */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetBssidListScan, pcExtra, essid_len, FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ /* wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 2 * KAL_HZ); */ -+ /* kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); */ -+ -+ return 0; -+} /* wext_set_scan */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To write the ie to buffer -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline int snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) -+{ -+ size_t i; -+ char *pos = buf, *end = buf + buf_size; -+ int ret; -+ -+ if (buf_size == 0) -+ return 0; -+ -+ for (i = 0; i < len; i++) { -+ ret = snprintf(pos, end - pos, "%02x", data[i]); -+ if (ret < 0 || ret >= end - pos) { -+ end[-1] = '\0'; -+ return pos - buf; -+ } -+ pos += ret; -+ } -+ end[-1] = '\0'; -+ return pos - buf; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get scan results, transform results from driver's format to WE's. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prData Pointer to iw_point structure, pData->length is the size of -+* pcExtra buffer before used, and is updated after filling scan -+* results. -+* \param[out] pcExtra Pointer to buffer which is allocated by caller of this -+* function, wext_support_ioctl() or ioctl_standard_call() in -+* wireless.c. -+* -+* \retval 0 For success. -+* \retval -ENOMEM If dynamic memory allocation fail. -+* \retval -E2BIG Invalid length. -+* -+* \note Scan results is filled into pcExtra buffer, data size is updated in -+* pData->length. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_scan(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN OUT struct iw_point *prData, IN char *pcExtra) -+{ -+ UINT_32 i = 0; -+ UINT_32 j = 0; -+ P_PARAM_BSSID_LIST_EX_T prList = NULL; -+ P_PARAM_BSSID_EX_T prBss = NULL; -+ P_PARAM_VARIABLE_IE_T prDesiredIE = NULL; -+ struct iw_event iwEvent; /* local iw_event buffer */ -+ -+ /* write pointer of extra buffer */ -+ char *pcCur = NULL; -+ /* pointer to the end of last full entry in extra buffer */ -+ char *pcValidEntryEnd = NULL; -+ char *pcEnd = NULL; /* end of extra buffer */ -+ -+ UINT_32 u4AllocBufLen = 0; -+ -+ /* arrange rate information */ -+ UINT_32 u4HighestRate = 0; -+ char aucRatesBuf[64]; -+ UINT_32 u4BufIndex; -+ -+ /* return value */ -+ int ret = 0; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prData); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prData, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* Initialize local variables */ -+ pcCur = pcExtra; -+ pcValidEntryEnd = pcExtra; -+ pcEnd = pcExtra + prData->length; /* end of extra buffer */ -+ -+ /* Allocate another query buffer with the same size of extra buffer */ -+ u4AllocBufLen = prData->length; -+ prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE); -+ if (prList == NULL) { -+ DBGLOG(REQ, ERROR, "[wifi] no memory for scan list:%d\n", prData->length); -+ ret = -ENOMEM; -+ goto error; -+ } -+ prList->u4NumberOfItems = 0; -+ -+ /* wait scan done */ -+ /* printk ("wait for scan results\n"); */ -+ /* wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 4 * KAL_HZ); */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryBssidList, prList, u4AllocBufLen, TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus == WLAN_STATUS_INVALID_LENGTH) { -+ /* Buffer length is not large enough. */ -+ /* printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen); */ -+ -+#if WIRELESS_EXT >= 17 -+ /* This feature is supported in WE-17 or above, limited by iwlist. -+ ** Return -E2BIG and iwlist will request again with a larger buffer. -+ */ -+ ret = -E2BIG; -+ /* Update length to give application a hint on result length */ -+ prData->length = (__u16) u4BufLen; -+ goto error; -+#else -+ /* Realloc a larger query buffer here, but don't write too much to extra -+ ** buffer when filling it later. -+ */ -+ kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen); -+ -+ u4AllocBufLen = u4BufLen; -+ prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE); -+ if (prList == NULL) { -+ DBGLOG(REQ, ERROR, "[wifi] no memory for larger scan list :%u\n", u4BufLen); -+ ret = -ENOMEM; -+ goto error; -+ } -+ prList->NumberOfItems = 0; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryBssidList, prList, u4AllocBufLen, TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus == WLAN_STATUS_INVALID_LENGTH) { -+ DBGLOG(REQ, ERROR, "[wifi] larger buf:%u result:%u\n", u4AllocBufLen, u4BufLen); -+ ret = -E2BIG; -+ prData->length = (__u16) u4BufLen; -+ goto error; -+ } -+#endif /* WIRELESS_EXT >= 17 */ -+ -+ } -+ -+ if (prList->u4NumberOfItems > CFG_MAX_NUM_BSS_LIST) { -+ DBGLOG(REQ, WARN, "[wifi] strange scan result count:%u\n", prList->u4NumberOfItems); -+ goto error; -+ } -+ -+ /* Copy required data from pList to pcExtra */ -+ prBss = &prList->arBssid[0]; /* set to the first entry */ -+ for (i = 0; i < prList->u4NumberOfItems; ++i) { -+ /* BSSID */ -+ iwEvent.cmd = SIOCGIWAP; -+ iwEvent.len = IW_EV_ADDR_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.ap_addr.sa_family = ARPHRD_ETHER; -+ ether_addr_copy(iwEvent.u.ap_addr.sa_data, prBss->arMacAddress); -+ memcpy(pcCur, &iwEvent, IW_EV_ADDR_LEN); -+ pcCur += IW_EV_ADDR_LEN; -+ -+ /* SSID */ -+ iwEvent.cmd = SIOCGIWESSID; -+ /* Modification to user space pointer(essid.pointer) is not needed. */ -+ iwEvent.u.essid.length = (__u16) prBss->rSsid.u4SsidLen; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.essid.length; -+ -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.essid.flags = 1; -+ iwEvent.u.essid.pointer = NULL; -+ -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, iwEvent.len); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, prBss->rSsid.aucSsid, iwEvent.u.essid.length); -+ pcCur += iwEvent.len; -+ /* Frequency */ -+ iwEvent.cmd = SIOCGIWFREQ; -+ iwEvent.len = IW_EV_FREQ_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.freq.m = prBss->rConfiguration.u4DSConfig; -+ iwEvent.u.freq.e = 3; /* (in KHz) */ -+ iwEvent.u.freq.i = 0; -+ memcpy(pcCur, &iwEvent, IW_EV_FREQ_LEN); -+ pcCur += IW_EV_FREQ_LEN; -+ -+ /* Operation Mode */ -+ iwEvent.cmd = SIOCGIWMODE; -+ iwEvent.len = IW_EV_UINT_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ if (prBss->eOpMode == NET_TYPE_IBSS) -+ iwEvent.u.mode = IW_MODE_ADHOC; -+ else if (prBss->eOpMode == NET_TYPE_INFRA) -+ iwEvent.u.mode = IW_MODE_INFRA; -+ else -+ iwEvent.u.mode = IW_MODE_AUTO; -+ memcpy(pcCur, &iwEvent, IW_EV_UINT_LEN); -+ pcCur += IW_EV_UINT_LEN; -+ -+ /* Quality */ -+ iwEvent.cmd = IWEVQUAL; -+ iwEvent.len = IW_EV_QUAL_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.qual.qual = 0; /* Quality not available now */ -+ /* -100 < Rssi < -10, normalized by adding 0x100 */ -+ iwEvent.u.qual.level = 0x100 + prBss->rRssi; -+ iwEvent.u.qual.noise = 0; /* Noise not available now */ -+ iwEvent.u.qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID; -+ memcpy(pcCur, &iwEvent, IW_EV_QUAL_LEN); -+ pcCur += IW_EV_QUAL_LEN; -+ -+ /* Security Mode */ -+ iwEvent.cmd = SIOCGIWENCODE; -+ iwEvent.len = IW_EV_POINT_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.data.pointer = NULL; -+ iwEvent.u.data.flags = 0; -+ iwEvent.u.data.length = 0; -+ if (!prBss->u4Privacy) -+ iwEvent.u.data.flags |= IW_ENCODE_DISABLED; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ pcCur += IW_EV_POINT_LEN; -+ -+ /* rearrange rate information */ -+ u4BufIndex = sprintf(aucRatesBuf, "Rates (Mb/s):"); -+ u4HighestRate = 0; -+ for (j = 0; j < PARAM_MAX_LEN_RATES_EX; ++j) { -+ UINT_8 curRate = prBss->rSupportedRates[j] & 0x7F; -+ -+ if (curRate == 0) -+ break; -+ -+ if (curRate > u4HighestRate) -+ u4HighestRate = curRate; -+ -+ if (curRate == RATE_5_5M) -+ u4BufIndex += sprintf(aucRatesBuf + u4BufIndex, " 5.5"); -+ else -+ u4BufIndex += sprintf(aucRatesBuf + u4BufIndex, " %d", curRate / 2); -+#if DBG -+ if (u4BufIndex > sizeof(aucRatesBuf)) { -+ /* printk("rate info too long\n"); */ -+ break; -+ } -+#endif -+ } -+ /* Report Highest Rates */ -+ iwEvent.cmd = SIOCGIWRATE; -+ iwEvent.len = IW_EV_PARAM_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.bitrate.value = u4HighestRate * 500000; -+ iwEvent.u.bitrate.fixed = 0; -+ iwEvent.u.bitrate.disabled = 0; -+ iwEvent.u.bitrate.flags = 0; -+ memcpy(pcCur, &iwEvent, iwEvent.len); -+ pcCur += iwEvent.len; -+ -+#if WIRELESS_EXT >= 15 /* IWEVCUSTOM is available in WE-15 or above */ -+ /* Report Residual Rates */ -+ iwEvent.cmd = IWEVCUSTOM; -+ iwEvent.u.data.length = u4BufIndex; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.data.flags = 0; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, aucRatesBuf, u4BufIndex); -+ pcCur += iwEvent.len; -+#endif /* WIRELESS_EXT >= 15 */ -+ -+ if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], -+ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), -+ 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ iwEvent.cmd = IWEVGENIE; -+ iwEvent.u.data.flags = 1; -+ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, -+ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); -+ pcCur += iwEvent.len; -+ } -+#if CFG_SUPPORT_WPS /* search WPS IE (0xDD, 221, OUI: 0x0050f204 ) */ -+ if (wextSrchDesiredWPSIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], -+ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), -+ 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ iwEvent.cmd = IWEVGENIE; -+ iwEvent.u.data.flags = 1; -+ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, -+ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); -+ pcCur += iwEvent.len; -+ } -+#endif -+ -+ /* Search RSN IE (0x30, 48). pBss->IEs starts from timestamp. */ -+ /* pBss->IEs starts from timestamp */ -+ if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], -+ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), -+ 0x30, (PUINT_8 *) &prDesiredIE)) { -+ -+ iwEvent.cmd = IWEVGENIE; -+ iwEvent.u.data.flags = 1; -+ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, -+ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); -+ pcCur += iwEvent.len; -+ } -+#if CFG_SUPPORT_WAPI /* Android+ */ -+ if (wextSrchDesiredWAPIIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], -+ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), (PUINT_8 *) &prDesiredIE)) { -+ -+#if 0 -+ iwEvent.cmd = IWEVGENIE; -+ iwEvent.u.data.flags = 1; -+ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, -+ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); -+ pcCur += iwEvent.len; -+#else -+ iwEvent.cmd = IWEVCUSTOM; -+ iwEvent.u.data.length = (2 + prDesiredIE->ucLength) * 2 + 8 /* wapi_ie= */; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.data.flags = 1; -+ -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, -+ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+ -+ pcCur += (IW_EV_POINT_LEN); -+ -+ pcCur += sprintf(pcCur, "wapi_ie="); -+ -+ snprintf_hex(pcCur, pcEnd - pcCur, (UINT_8 *) prDesiredIE, prDesiredIE->ucLength + 2); -+ -+ pcCur += (2 + prDesiredIE->ucLength) * 2 /* iwEvent.len */; -+#endif -+ } -+#endif -+ /* Complete an entry. Update end of valid entry */ -+ pcValidEntryEnd = pcCur; -+ /* Extract next bss */ -+ prBss = (P_PARAM_BSSID_EX_T) ((char *)prBss + prBss->u4Length); -+ } -+ -+ /* Update valid data length for caller function and upper layer -+ * applications. -+ */ -+ prData->length = (pcValidEntryEnd - pcExtra); -+ /* printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen); */ -+ -+ /* kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); */ -+ -+error: -+ /* free local query buffer */ -+ if (prList) -+ kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen); -+ -+ return ret; -+} /* wext_get_scan */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set desired network name ESSID. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prEssid Pointer of iw_point header. -+* \param[in] pcExtra Pointer to buffer srtoring essid string. -+* -+* \retval 0 If netif_carrier_ok. -+* \retval -E2BIG Essid string length is too big. -+* \retval -EINVAL pcExtra is null pointer. -+* \retval -EFAULT Driver fail to set new essid. -+* -+* \note If string length is ok, device will try connecting to the new network. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_essid(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEssid, IN char *pcExtra) -+{ -+ PARAM_SSID_T rNewSsid; -+ UINT_32 cipher; -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prEssid); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prEssid, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (prEssid->length > IW_ESSID_MAX_SIZE) -+ return -E2BIG; -+ -+ /* set auth mode */ -+ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { -+ eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ? -+ AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH; -+ /* printk(KERN_INFO "IW_AUTH_WPA_VERSION_DISABLED->Param_AuthMode%s\n", */ -+ /* (eAuthMode == AUTH_MODE_OPEN) ? "Open" : "Shared"); */ -+ } else { -+ /* set auth mode */ -+ switch (prGlueInfo->rWpaInfo.u4KeyMgmt) { -+ case IW_AUTH_KEY_MGMT_802_1X: -+ eAuthMode = -+ (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) ? -+ AUTH_MODE_WPA : AUTH_MODE_WPA2; -+ /* printk("IW_AUTH_KEY_MGMT_802_1X->AUTH_MODE_WPA%s\n", */ -+ /* (eAuthMode == AUTH_MODE_WPA) ? "" : "2"); */ -+ break; -+ case IW_AUTH_KEY_MGMT_PSK: -+ eAuthMode = -+ (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) ? -+ AUTH_MODE_WPA_PSK : AUTH_MODE_WPA2_PSK; -+ /* printk("IW_AUTH_KEY_MGMT_PSK->AUTH_MODE_WPA%sPSK\n", */ -+ /* (eAuthMode == AUTH_MODE_WPA_PSK) ? "" : "2"); */ -+ break; -+#if CFG_SUPPORT_WAPI /* Android+ */ -+ case IW_AUTH_KEY_MGMT_WAPI_PSK: -+ break; -+ case IW_AUTH_KEY_MGMT_WAPI_CERT: -+ break; -+#endif -+ -+/* #if defined (IW_AUTH_KEY_MGMT_WPA_NONE) */ -+/* case IW_AUTH_KEY_MGMT_WPA_NONE: */ -+/* eAuthMode = AUTH_MODE_WPA_NONE; */ -+/* //printk("IW_AUTH_KEY_MGMT_WPA_NONE->AUTH_MODE_WPA_NONE\n"); */ -+/* break; */ -+/* #endif */ -+#if CFG_SUPPORT_802_11W -+ case IW_AUTH_KEY_MGMT_802_1X_SHA256: -+ eAuthMode = AUTH_MODE_WPA2; -+ break; -+ case IW_AUTH_KEY_MGMT_PSK_SHA256: -+ eAuthMode = AUTH_MODE_WPA2_PSK; -+ break; -+#endif -+ default: -+ /* printk(KERN_INFO DRV_NAME"strange IW_AUTH_KEY_MGMT : %ld set auto switch\n", */ -+ /* prGlueInfo->rWpaInfo.u4KeyMgmt); */ -+ eAuthMode = AUTH_MODE_AUTO_SWITCH; -+ break; -+ } -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAuthMode, &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ /* set encryption status */ -+ cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise; -+ if (cipher & IW_AUTH_CIPHER_CCMP) { -+ /* printk("IW_AUTH_CIPHER_CCMP->ENUM_ENCRYPTION3_ENABLED\n"); */ -+ eEncStatus = ENUM_ENCRYPTION3_ENABLED; -+ } else if (cipher & IW_AUTH_CIPHER_TKIP) { -+ /* printk("IW_AUTH_CIPHER_TKIP->ENUM_ENCRYPTION2_ENABLED\n"); */ -+ eEncStatus = ENUM_ENCRYPTION2_ENABLED; -+ } else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) { -+ /* printk("IW_AUTH_CIPHER_WEPx->ENUM_ENCRYPTION1_ENABLED\n"); */ -+ eEncStatus = ENUM_ENCRYPTION1_ENABLED; -+ } else if (cipher & IW_AUTH_CIPHER_NONE) { -+ /* printk("IW_AUTH_CIPHER_NONE->ENUM_ENCRYPTION_DISABLED\n"); */ -+ if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) -+ eEncStatus = ENUM_ENCRYPTION1_ENABLED; -+ else -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ } else { -+ /* printk("unknown IW_AUTH_CIPHER->Param_EncryptionDisabled\n"); */ -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetEncryptionStatus, -+ &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+#if WIRELESS_EXT < 21 -+ /* GeorgeKuo: a length error bug exists in (WE < 21) cases, kernel before -+ ** 2.6.19. Cut the trailing '\0'. -+ */ -+ rNewSsid.u4SsidLen = (prEssid->length) ? prEssid->length - 1 : 0; -+#else -+ rNewSsid.u4SsidLen = prEssid->length; -+#endif -+ kalMemCopy(rNewSsid.aucSsid, pcExtra, rNewSsid.u4SsidLen); -+ -+ /* -+ rNewSsid.aucSsid[rNewSsid.u4SsidLen] = '\0'; -+ printk("set ssid(%lu): %s\n", rNewSsid.u4SsidLen, rNewSsid.aucSsid); -+ */ -+ -+ if (kalIoctl(prGlueInfo, -+ wlanoidSetSsid, -+ (PVOID)&rNewSsid, -+ sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen) != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_WARNING "Fail to set ssid\n"); */ -+ return -EFAULT; -+ } -+ -+ return 0; -+} /* wext_set_essid */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get current network name ESSID. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prEssid Pointer to iw_point structure containing essid information. -+* \param[out] pcExtra Pointer to buffer srtoring essid string. -+* -+* \retval 0 If netif_carrier_ok. -+* \retval -ENOTCONN Otherwise. -+* -+* \note If netif_carrier_ok, network essid is stored in pcExtra. -+*/ -+/*----------------------------------------------------------------------------*/ -+/* static PARAM_SSID_T ssid; */ -+static int -+wext_get_essid(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEssid, OUT char *pcExtra) -+{ -+ /* PARAM_SSID_T ssid; */ -+ -+ P_PARAM_SSID_T prSsid; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prEssid); -+ ASSERT(pcExtra); -+ -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prEssid, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* if (!netif_carrier_ok(prNetDev)) { */ -+ /* return -ENOTCONN; */ -+ /* } */ -+ -+ prSsid = kalMemAlloc(sizeof(PARAM_SSID_T), VIR_MEM_TYPE); -+ -+ if (!prSsid) -+ return -ENOMEM; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQuerySsid, prSsid, sizeof(PARAM_SSID_T), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if ((rStatus == WLAN_STATUS_SUCCESS) && (prSsid->u4SsidLen <= MAX_SSID_LEN)) { -+ kalMemCopy(pcExtra, prSsid->aucSsid, prSsid->u4SsidLen); -+ prEssid->length = prSsid->u4SsidLen; -+ prEssid->flags = 1; -+ } -+ -+ kalMemFree(prSsid, VIR_MEM_TYPE, sizeof(PARAM_SSID_T)); -+ -+ return 0; -+} /* wext_get_essid */ -+ -+#if 0 -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set tx desired bit rate. Three cases here -+* iwconfig wlan0 auto -> Set to origianl supported rate set. -+* iwconfig wlan0 18M -> Imply "fixed" case, set to 18Mbps as desired rate. -+* iwconfig wlan0 18M auto -> Set to auto rate lower and equal to 18Mbps -+* -+* \param[in] prNetDev Pointer to the net_device handler. -+* \param[in] prIwReqInfo Pointer to the Request Info. -+* \param[in] prRate Pointer to the Rate Parameter. -+* \param[in] pcExtra Pointer to the extra buffer. -+* -+* \retval 0 Update desired rate. -+* \retval -EINVAL Wrong parameter -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+wext_set_rate(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN struct iw_param *prRate, IN char *pcExtra) -+{ -+ PARAM_RATES_EX aucSuppRate = { 0 }; -+ PARAM_RATES_EX aucNewRate = { 0 }; -+ UINT_32 u4NewRateLen = 0; -+ UINT_32 i; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prRate); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prRate)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* -+ printk("value = %d, fixed = %d, disable = %d, flags = %d\n", -+ prRate->value, prRate->fixed, prRate->disabled, prRate->flags); -+ */ -+ -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQuerySupportedRates, &aucSuppRate, sizeof(aucSuppRate), &u4BufLen); -+ -+ /* Case: AUTO */ -+ if (prRate->value < 0) { -+ if (prRate->fixed == 0) { -+ /* iwconfig wlan0 rate auto */ -+ -+ /* set full supported rate to device */ -+ /* printk("wlanoidQuerySupportedRates():u4BufLen = %ld\n", u4BufLen); */ -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetDesiredRates, -+ &aucSuppRate, sizeof(aucSuppRate), &u4BufLen); -+ return 0; -+ } -+ /* iwconfig wlan0 rate fixed */ -+ -+ /* fix rate to what? DO NOTHING */ -+ return -EINVAL; -+ } -+ -+ aucNewRate[0] = prRate->value / 500000; /* In unit of 500k */ -+ -+ for (i = 0; i < PARAM_MAX_LEN_RATES_EX; i++) { -+ /* check the given value is supported */ -+ if (aucSuppRate[i] == 0) -+ break; -+ -+ if (aucNewRate[0] == aucSuppRate[i]) { -+ u4NewRateLen = 1; -+ break; -+ } -+ } -+ -+ if (u4NewRateLen == 0) { -+ /* the given value is not supported */ -+ /* return error or use given rate as upper bound? */ -+ return -EINVAL; -+ } -+ -+ if (prRate->fixed == 0) { -+ /* add all rates lower than desired rate */ -+ for (i = 0; i < PARAM_MAX_LEN_RATES_EX; ++i) { -+ if (aucSuppRate[i] == 0) -+ break; -+ -+ if (aucSuppRate[i] < aucNewRate[0]) -+ aucNewRate[u4NewRateLen++] = aucSuppRate[i]; -+ } -+ } -+ -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetDesiredRates, &aucNewRate, sizeof(aucNewRate), &u4BufLen); -+ return 0; -+} /* wext_set_rate */ -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get current tx bit rate. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prRate Pointer to iw_param structure to store current tx rate. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 If netif_carrier_ok. -+* \retval -ENOTCONN Otherwise. -+* -+* \note If netif_carrier_ok, current tx rate is stored in pRate. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_rate(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prRate, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ UINT_32 u4Rate = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prRate); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prRate)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (!netif_carrier_ok(prNetDev)) -+ return -ENOTCONN; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryLinkSpeed, &u4Rate, sizeof(u4Rate), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ -+ prRate->value = u4Rate * 100; /* u4Rate is in unit of 100bps */ -+ prRate->fixed = 0; -+ -+ return 0; -+} /* wext_get_rate */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set RTS/CTS theshold. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prRts Pointer to iw_param structure containing rts threshold. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 For success. -+* \retval -EINVAL Given value is out of range. -+* -+* \note If given value is valid, device will follow the new setting. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_rts(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prRts, IN char *pcExtra) -+{ -+ PARAM_RTS_THRESHOLD u4RtsThresh; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prRts); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prRts)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (prRts->disabled == 1) -+ u4RtsThresh = 2347; -+ else if (prRts->value < 0 || prRts->value > 2347) -+ return -EINVAL; -+ -+ u4RtsThresh = (PARAM_RTS_THRESHOLD) prRts->value; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRtsThreshold, -+ &u4RtsThresh, sizeof(u4RtsThresh), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ prRts->value = (typeof(prRts->value)) u4RtsThresh; -+ prRts->disabled = (prRts->value > 2347) ? 1 : 0; -+ prRts->fixed = 1; -+ -+ return 0; -+} /* wext_set_rts */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get RTS/CTS theshold. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prRts Pointer to iw_param structure containing rts threshold. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note RTS threshold is stored in pRts. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_rts(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prRts, IN char *pcExtra) -+{ -+ PARAM_RTS_THRESHOLD u4RtsThresh = 0; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prRts); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prRts)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryRtsThreshold, -+ &u4RtsThresh, sizeof(u4RtsThresh), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ prRts->value = (typeof(prRts->value)) u4RtsThresh; -+ prRts->disabled = (prRts->value > 2347 || prRts->value < 0) ? 1 : 0; -+ prRts->fixed = 1; -+ -+ return 0; -+} /* wext_get_rts */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get fragmentation threshold. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prFrag Pointer to iw_param structure containing frag threshold. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note RTS threshold is stored in pFrag. Fragmentation is disabled. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_frag(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prFrag, IN char *pcExtra) -+{ -+ ASSERT(prFrag); -+ -+ prFrag->value = 2346; -+ prFrag->fixed = 1; -+ prFrag->disabled = 1; -+ return 0; -+} /* wext_get_frag */ -+ -+#if 1 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set TX power, or enable/disable the radio. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prTxPow Pointer to iw_param structure containing tx power setting. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note Tx power is stored in pTxPow. iwconfig wlan0 txpow on/off are used -+* to enable/disable the radio. -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+static int -+wext_set_txpow(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prTxPow, IN char *pcExtra) -+{ -+ int ret = 0; -+ /* PARAM_DEVICE_POWER_STATE ePowerState; */ -+ ENUM_ACPI_STATE_T ePowerState; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prTxPow); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prTxPow)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (prTxPow->disabled) { -+ /* <1> disconnect */ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, ERROR, "######set disassoc failed\n"); -+ else -+ DBGLOG(REQ, TRACE, "######set assoc ok\n"); -+ /* <2> mark to power state flag */ -+ ePowerState = ACPI_STATE_D0; -+ DBGLOG(REQ, INFO, "set to acpi d3(0)\n"); -+ wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState); -+ -+ } else { -+ ePowerState = ACPI_STATE_D0; -+ DBGLOG(REQ, INFO, "set to acpi d0\n"); -+ wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState); -+ } -+ -+ prGlueInfo->ePowerState = ePowerState; -+ -+ return ret; -+} /* wext_set_txpow */ -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get TX power. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prTxPow Pointer to iw_param structure containing tx power setting. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note Tx power is stored in pTxPow. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_txpow(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prTxPow, IN char *pcExtra) -+{ -+ /* PARAM_DEVICE_POWER_STATE ePowerState; */ -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prNetDev); -+ ASSERT(prTxPow); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prTxPow)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* GeorgeKuo: wlanoidQueryAcpiDevicePowerState() reports capability, not -+ * current state. Use GLUE_INFO_T to store state. -+ */ -+ /* ePowerState = prGlueInfo->ePowerState; */ -+ -+ /* TxPow parameters: Fixed at relative 100% */ -+#if WIRELESS_EXT < 17 -+ prTxPow->flags = 0x0002; /* IW_TXPOW_RELATIVE */ -+#else -+ prTxPow->flags = IW_TXPOW_RELATIVE; -+#endif -+ prTxPow->value = 100; -+ prTxPow->fixed = 1; -+ /* prTxPow->disabled = (ePowerState != ParamDeviceStateD3) ? FALSE : TRUE; */ -+ prTxPow->disabled = TRUE; -+ -+ return 0; -+} /* wext_get_txpow */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get encryption cipher and key. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prEnc Pointer to iw_point structure containing securiry information. -+* \param[in] pcExtra Buffer to store key content. -+* -+* \retval 0 Success. -+* -+* \note Securiry information is stored in pEnc except key content. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_encode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_point *prEnc, IN char *pcExtra) -+{ -+#if 1 -+ /* ENUM_ENCRYPTION_STATUS_T eEncMode; */ -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncMode = ENUM_WEP_ENABLED; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prEnc); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prEnc)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryEncryptionStatus, -+ &eEncMode, sizeof(eEncMode), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ switch (eEncMode) { -+ case ENUM_WEP_DISABLED: -+ prEnc->flags = IW_ENCODE_DISABLED; -+ break; -+ case ENUM_WEP_ENABLED: -+ prEnc->flags = IW_ENCODE_ENABLED; -+ break; -+ case ENUM_WEP_KEY_ABSENT: -+ prEnc->flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; -+ break; -+ default: -+ prEnc->flags = IW_ENCODE_ENABLED; -+ break; -+ } -+ -+ /* Cipher, Key Content, Key ID can't be queried */ -+ prEnc->flags |= IW_ENCODE_NOKEY; -+#endif -+ return 0; -+} /* wext_get_encode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set encryption cipher and key. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prEnc Pointer to iw_point structure containing securiry information. -+* \param[in] pcExtra Pointer to key string buffer. -+* -+* \retval 0 Success. -+* \retval -EINVAL Key ID error for WEP. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note Securiry information is stored in pEnc. -+*/ -+/*----------------------------------------------------------------------------*/ -+static UINT_8 wepBuf[48]; -+ -+static int -+wext_set_encode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEnc, IN char *pcExtra) -+{ -+#if 1 -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ /* UINT_8 wepBuf[48]; */ -+ P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prEnc); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prEnc, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* reset to default mode */ -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+#if CFG_SUPPORT_802_11W -+ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; -+#endif -+ -+ /* iwconfig wlan0 key off */ -+ if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { -+ eAuthMode = AUTH_MODE_OPEN; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAuthMode, -+ &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetEncryptionStatus, -+ &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ return 0; -+ } -+ -+ /* iwconfig wlan0 key 0123456789 */ -+ /* iwconfig wlan0 key s:abcde */ -+ /* iwconfig wlan0 key 0123456789 [1] */ -+ /* iwconfig wlan0 key 01234567890123456789012345 [1] */ -+ /* check key size for WEP */ -+ if (prEnc->length == 5 || prEnc->length == 13 || prEnc->length == 16) { -+ /* prepare PARAM_WEP key structure */ -+ prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; -+ if (prWepKey->u4KeyIndex > 3) { -+ /* key id is out of range */ -+ return -EINVAL; -+ } -+ prWepKey->u4KeyIndex |= 0x80000000; -+ prWepKey->u4Length = 12 + prEnc->length; -+ prWepKey->u4KeyLength = prEnc->length; -+ kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prEnc->length); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAddWep, -+ prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ /* change to auto switch */ -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY | IW_AUTH_ALG_OPEN_SYSTEM; -+ eAuthMode = AUTH_MODE_AUTO_SWITCH; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAuthMode, -+ &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO DRV_NAME"wlanoidSetAuthMode fail 0x%lx\n", rStatus); */ -+ return -EFAULT; -+ } -+ -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; -+ -+ eEncStatus = ENUM_WEP_ENABLED; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetEncryptionStatus, -+ &eEncStatus, -+ sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO DRV_NAME"wlanoidSetEncryptionStatus fail 0x%lx\n", rStatus); */ -+ return -EFAULT; -+ } -+ -+ return 0; -+ } -+#endif -+ return -EOPNOTSUPP; -+} /* wext_set_encode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set power management. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prPower Pointer to iw_param structure containing tx power setting. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note New Power Management Mode is set to driver. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_power(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prPower, IN char *pcExtra) -+{ -+#if 1 -+ -+ PARAM_POWER_MODE ePowerMode; -+ INT_32 i4PowerValue; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prPower); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n", */ -+ /* prPower->value, prPower->disabled, prPower->flags); */ -+ -+ if (prPower->disabled) { -+ ePowerMode = Param_PowerModeCAM; -+ } else { -+ i4PowerValue = prPower->value; -+#if WIRELESS_EXT < 21 -+ i4PowerValue /= 1000000; -+#endif -+ if (i4PowerValue == 0) { -+ ePowerMode = Param_PowerModeCAM; -+ } else if (i4PowerValue == 1) { -+ ePowerMode = Param_PowerModeMAX_PSP; -+ } else if (i4PowerValue == 2) { -+ ePowerMode = Param_PowerModeFast_PSP; -+ } else { -+ DBGLOG(REQ, ERROR, "%s(): unsupported power management mode value = %d.\n", -+ __func__, prPower->value); -+ -+ return -EINVAL; -+ } -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSet802dot11PowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus); */ -+ return -EFAULT; -+ } -+#endif -+ return 0; -+} /* wext_set_power */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get power management. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prPower Pointer to iw_param structure containing tx power setting. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note Power management mode is stored in pTxPow->value. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_power(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prPower, IN char *pcExtra) -+{ -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ PARAM_POWER_MODE ePowerMode = Param_PowerModeCAM; -+ -+ ASSERT(prNetDev); -+ ASSERT(prPower); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+#if 0 -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidQuery802dot11PowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), TRUE, TRUE, &u4BufLen); -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQuery802dot11PowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), &u4BufLen); -+#endif -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQuery802dot11PowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), &u4BufLen); -+#endif -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ -+ prPower->value = 0; -+ prPower->disabled = 1; -+ -+ if (Param_PowerModeCAM == ePowerMode) { -+ prPower->value = 0; -+ prPower->disabled = 1; -+ } else if (Param_PowerModeMAX_PSP == ePowerMode) { -+ prPower->value = 1; -+ prPower->disabled = 0; -+ } else if (Param_PowerModeFast_PSP == ePowerMode) { -+ prPower->value = 2; -+ prPower->disabled = 0; -+ } -+ -+ prPower->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE; -+#if WIRELESS_EXT < 21 -+ prPower->value *= 1000000; -+#endif -+ -+ /* printk(KERN_INFO "wext_get_power value(%d) disabled(%d) flag(0x%x)\n", */ -+ /* prPower->value, prPower->disabled, prPower->flags); */ -+ -+ return 0; -+} /* wext_get_power */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set authentication parameters. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] rpAuth Pointer to iw_param structure containing authentication information. -+* \param[in] pcExtra Pointer to key string buffer. -+* -+* \retval 0 Success. -+* \retval -EINVAL Key ID error for WEP. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note Securiry information is stored in pEnc. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_auth(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prAuth, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prNetDev); -+ ASSERT(prAuth); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prAuth)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* Save information to glue info and process later when ssid is set. */ -+ switch (prAuth->flags & IW_AUTH_INDEX) { -+ case IW_AUTH_WPA_VERSION: -+#if CFG_SUPPORT_WAPI -+ if (wlanQueryWapiMode(prGlueInfo->prAdapter)) { -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+ } else { -+ prGlueInfo->rWpaInfo.u4WpaVersion = prAuth->value; -+ } -+#else -+ prGlueInfo->rWpaInfo.u4WpaVersion = prAuth->value; -+#endif -+ break; -+ -+ case IW_AUTH_CIPHER_PAIRWISE: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = prAuth->value; -+ break; -+ -+ case IW_AUTH_CIPHER_GROUP: -+ prGlueInfo->rWpaInfo.u4CipherGroup = prAuth->value; -+ break; -+ -+ case IW_AUTH_KEY_MGMT: -+ prGlueInfo->rWpaInfo.u4KeyMgmt = prAuth->value; -+#if CFG_SUPPORT_WAPI -+ if (prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WAPI_PSK || -+ prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WAPI_CERT) { -+ UINT_32 u4BufLen; -+ WLAN_STATUS rStatus; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiMode, -+ &prAuth->value, sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ DBGLOG(REQ, INFO, "IW_AUTH_WAPI_ENABLED :%d\n", prAuth->value); -+ } -+#endif -+ if (prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WPS) -+ prGlueInfo->fgWpsActive = TRUE; -+ else -+ prGlueInfo->fgWpsActive = FALSE; -+ break; -+ -+ case IW_AUTH_80211_AUTH_ALG: -+ prGlueInfo->rWpaInfo.u4AuthAlg = prAuth->value; -+ break; -+ -+ case IW_AUTH_PRIVACY_INVOKED: -+ prGlueInfo->rWpaInfo.fgPrivacyInvoke = prAuth->value; -+ break; -+#if CFG_SUPPORT_802_11W -+ case IW_AUTH_MFP: -+ /* printk("wext_set_auth IW_AUTH_MFP=%d\n", prAuth->value); */ -+ prGlueInfo->rWpaInfo.u4Mfp = prAuth->value; -+ break; -+#endif -+#if CFG_SUPPORT_WAPI -+ case IW_AUTH_WAPI_ENABLED: -+ { -+ UINT_32 u4BufLen; -+ WLAN_STATUS rStatus; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiMode, -+ &prAuth->value, sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ } -+ DBGLOG(REQ, INFO, "IW_AUTH_WAPI_ENABLED :%d\n", prAuth->value); -+ break; -+#endif -+ default: -+ /* -+ printk(KERN_INFO "[wifi] unsupported IW_AUTH_INDEX :%d\n", prAuth->flags); -+ */ -+ break; -+ } -+ return 0; -+} /* wext_set_auth */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set encryption cipher and key. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prEnc Pointer to iw_point structure containing securiry information. -+* \param[in] pcExtra Pointer to key string buffer. -+* -+* \retval 0 Success. -+* \retval -EINVAL Key ID error for WEP. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note Securiry information is stored in pEnc. -+*/ -+/*----------------------------------------------------------------------------*/ -+#if CFG_SUPPORT_WAPI -+UINT_8 keyStructBuf[320]; /* add/remove key shared buffer */ -+#else -+UINT_8 keyStructBuf[100]; /* add/remove key shared buffer */ -+#endif -+ -+static int -+wext_set_encode_ext(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEnc, IN char *pcExtra) -+{ -+ P_PARAM_REMOVE_KEY_T prRemoveKey = (P_PARAM_REMOVE_KEY_T) keyStructBuf; -+ P_PARAM_KEY_T prKey = (P_PARAM_KEY_T) keyStructBuf; -+ -+ P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; -+ -+ struct iw_encode_ext *prIWEncExt = (struct iw_encode_ext *)pcExtra; -+ -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ /* ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_AUTO_SWITCH; */ -+ -+#if CFG_SUPPORT_WAPI -+ P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf; -+#endif -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prEnc); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prEnc, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ memset(keyStructBuf, 0, sizeof(keyStructBuf)); -+ -+#if CFG_SUPPORT_WAPI -+ if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) { -+ if (prEnc->flags & IW_ENCODE_DISABLED) { -+ /* printk(KERN_INFO "[wapi] IW_ENCODE_DISABLED\n"); */ -+ return 0; -+ } -+ /* KeyID */ -+ prWpiKey->ucKeyID = (prEnc->flags & IW_ENCODE_INDEX); -+ prWpiKey->ucKeyID--; -+ if (prWpiKey->ucKeyID > 1) { -+ /* key id is out of range */ -+ /* printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID); */ -+ return -EINVAL; -+ } -+ -+ if (prIWEncExt->key_len != 32) { -+ /* key length not valid */ -+ /* printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len); */ -+ return -EINVAL; -+ } -+ /* printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags); */ -+ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { -+ prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY; -+ prWpiKey->eDirection = ENUM_WPI_RX; -+ } else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { -+ prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY; -+ prWpiKey->eDirection = ENUM_WPI_RX_TX; -+ } -+ -+ /* PN */ -+ { -+ UINT_32 i; -+ -+ for (i = 0; i < IW_ENCODE_SEQ_MAX_SIZE; i++) -+ prWpiKey->aucPN[i] = prIWEncExt->tx_seq[i]; -+ for (i = 0; i < IW_ENCODE_SEQ_MAX_SIZE; i++) -+ prWpiKey->aucPN[IW_ENCODE_SEQ_MAX_SIZE + i] = prIWEncExt->rx_seq[i]; -+ } -+ -+ /* BSSID */ -+ memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr.sa_data, 6); -+ -+ memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16); -+ prWpiKey->u4LenWPIEK = 16; -+ -+ memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16); -+ prWpiKey->u4LenWPICK = 16; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiKey, -+ prWpiKey, sizeof(PARAM_WPI_KEY_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus); */ -+ } -+ } else -+#endif -+ { -+ -+ if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { -+ prRemoveKey->u4Length = sizeof(*prRemoveKey); -+ memcpy(prRemoveKey->arBSSID, prIWEncExt->addr.sa_data, 6); -+ /* -+ printk("IW_ENCODE_DISABLED: ID:%d, Addr:[ %pM ]\n", -+ prRemoveKey->KeyIndex, prRemoveKey->BSSID); -+ */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRemoveKey, -+ prRemoveKey, prRemoveKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, INFO, "remove key error:%x\n", rStatus); -+ return 0; -+ } -+ /* return 0; */ -+ /* printk ("alg %x\n", prIWEncExt->alg); */ -+ -+ switch (prIWEncExt->alg) { -+ case IW_ENCODE_ALG_NONE: -+ break; -+ case IW_ENCODE_ALG_WEP: -+ /* iwconfig wlan0 key 0123456789 */ -+ /* iwconfig wlan0 key s:abcde */ -+ /* iwconfig wlan0 key 0123456789 [1] */ -+ /* iwconfig wlan0 key 01234567890123456789012345 [1] */ -+ /* check key size for WEP */ -+ if (prIWEncExt->key_len == 5 || prIWEncExt->key_len == 13 || prIWEncExt->key_len == 16) { -+ /* prepare PARAM_WEP key structure */ -+ prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? -+ (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; -+ if (prWepKey->u4KeyIndex > 3) { -+ /* key id is out of range */ -+ return -EINVAL; -+ } -+ prWepKey->u4KeyIndex |= 0x80000000; -+ prWepKey->u4Length = 12 + prIWEncExt->key_len; -+ prWepKey->u4KeyLength = prIWEncExt->key_len; -+ /* kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prIWEncExt->key_len); */ -+ kalMemCopy(prWepKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAddWep, -+ prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ /* change to auto switch */ -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY | IW_AUTH_ALG_OPEN_SYSTEM; -+ eAuthMode = AUTH_MODE_AUTO_SWITCH; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAuthMode, -+ &eAuthMode, -+ sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetAuthMode fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; -+ -+ eEncStatus = ENUM_WEP_ENABLED; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetEncryptionStatus, -+ &eEncStatus, -+ sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T), -+ FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetEncryptionStatus fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ } else { -+ DBGLOG(REQ, INFO, "key length %x\n", prIWEncExt->key_len); -+ DBGLOG(REQ, INFO, "key error\n"); -+ } -+ -+ break; -+ case IW_ENCODE_ALG_TKIP: -+ case IW_ENCODE_ALG_CCMP: -+#if CFG_SUPPORT_802_11W -+ case IW_ENCODE_ALG_AES_CMAC: -+#endif -+ { -+ -+ /* KeyID */ -+ prKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? -+ (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; -+#if CFG_SUPPORT_802_11W -+ if (prKey->u4KeyIndex > 5) { -+#else -+ if (prKey->u4KeyIndex > 3) { -+#endif -+ DBGLOG(REQ, ERROR, "key index error:0x%x\n", prKey->u4KeyIndex); -+ /* key id is out of range */ -+ return -EINVAL; -+ } -+ -+ /* bit(31) and bit(30) are shared by pKey and pRemoveKey */ -+ /* Tx Key Bit(31) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { -+ prKey->u4KeyIndex |= 0x1UL << 31; -+ /* Code style */ -+ } -+ /* Pairwise Key Bit(30) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { -+ /* Do nothing */ -+ /* group key */ -+ } else { -+ /* pairwise key */ -+ prKey->u4KeyIndex |= 0x1UL << 30; -+ } -+ } -+ /* Rx SC Bit(29) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { -+ prKey->u4KeyIndex |= 0x1UL << 29; -+ memcpy(&prKey->rKeyRSC, prIWEncExt->rx_seq, IW_ENCODE_SEQ_MAX_SIZE); -+ } -+ -+ /* BSSID */ -+ memcpy(prKey->arBSSID, prIWEncExt->addr.sa_data, 6); -+ -+ /* switch tx/rx MIC key for sta */ -+ if (prIWEncExt->alg == IW_ENCODE_ALG_TKIP && prIWEncExt->key_len == 32) { -+ memcpy(prKey->aucKeyMaterial, prIWEncExt->key, 16); -+ memcpy(((PUINT_8) prKey->aucKeyMaterial) + 16, prIWEncExt->key + 24, 8); -+ memcpy((prKey->aucKeyMaterial) + 24, prIWEncExt->key + 16, 8); -+ } else { -+ memcpy(prKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len); -+ } -+ -+ prKey->u4KeyLength = prIWEncExt->key_len; -+ prKey->u4Length = ((ULONG)&(((P_PARAM_KEY_T) 0)->aucKeyMaterial)) + prKey->u4KeyLength; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAddKey, -+ prKey, prKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "add key error:%x\n", rStatus); -+ return -EFAULT; -+ } -+ break; -+ } -+ } -+ -+ return 0; -+} /* wext_set_encode_ext */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Set country code -+* -+* \param[in] prNetDev Net device requested. -+* \param[in] prData iwreq.u.data carries country code value. -+* -+* \retval 0 For success. -+* \retval -EEFAULT For fail. -+* -+* \note Country code is stored and channel list is updated based on current country domain. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wext_set_country(IN struct net_device *prNetDev, IN struct iw_point *prData) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ UINT_8 aucCountry[2]; -+ -+ ASSERT(prNetDev); -+ -+ /* prData->pointer should be like "COUNTRY US", "COUNTRY EU" -+ * and "COUNTRY JP" -+ */ -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prData) || !prData->pointer || prData->length < 10) -+ return -EINVAL; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ aucCountry[0] = *((PUINT_8)prData->pointer + 8); -+ aucCountry[1] = *((PUINT_8)prData->pointer + 9); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetCountryCode, &aucCountry[0], 2, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "Set country code error: %x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To report the iw private args table to user space. -+* -+* \param[in] prNetDev Net device requested. -+* \param[out] prData iwreq.u.data to carry the private args table. -+* -+* \retval 0 For success. -+* \retval -E2BIG For user's buffer size is too small. -+* \retval -EFAULT For fail. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wext_get_priv(IN struct net_device *prNetDev, OUT struct iw_point *prData) -+{ -+ UINT_16 u2BufferSize = prData->length; -+ -+ /* Update our private args table size */ -+ prData->length = (__u16)sizeof(rIwPrivTable); -+ if (u2BufferSize < prData->length) -+ return -E2BIG; -+ -+ if (prData->length) { -+ if (copy_to_user(prData->pointer, rIwPrivTable, sizeof(rIwPrivTable))) -+ return -EFAULT; -+ } -+ -+ return 0; -+} /* wext_get_priv */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief ioctl() (Linux Wireless Extensions) routines -+* -+* \param[in] prDev Net device requested. -+* \param[in] ifr The ifreq structure for seeting the wireless extension. -+* \param[in] i4Cmd The wireless extension ioctl command. -+* -+* \retval zero On success. -+* \retval -EOPNOTSUPP If the cmd is not supported. -+* \retval -EFAULT If copy_to_user goes wrong. -+* \retval -EINVAL If any value's out of range. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int wext_support_ioctl(IN struct net_device *prDev, IN struct ifreq *prIfReq, IN int i4Cmd) -+{ -+ struct iwreq *iwr = (struct iwreq *)prIfReq; -+ struct iw_request_info rIwReqInfo; -+ int ret = 0; -+ char *prExtraBuf = NULL; -+ UINT_32 u4ExtraSize = 0; -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_PARAM_PMKID_T prPmkid; -+ -+ /* printk("%d CMD:0x%x\n", jiffies_to_msecs(jiffies), i4Cmd); */ -+ -+ rIwReqInfo.cmd = (__u16) i4Cmd; -+ rIwReqInfo.flags = 0; -+ -+ switch (i4Cmd) { -+ case SIOCGIWNAME: /* 0x8B01, get wireless protocol name */ -+ ret = wext_get_name(prDev, &rIwReqInfo, (char *)&iwr->u.name, NULL); -+ break; -+ -+ /* case SIOCSIWNWID: 0x8B02, deprecated */ -+ /* case SIOCGIWNWID: 0x8B03, deprecated */ -+ -+ case SIOCSIWFREQ: /* 0x8B04, set channel */ -+ ret = wext_set_freq(prDev, NULL, &iwr->u.freq, NULL); -+ break; -+ -+ case SIOCGIWFREQ: /* 0x8B05, get channel */ -+ ret = wext_get_freq(prDev, NULL, &iwr->u.freq, NULL); -+ break; -+ -+ case SIOCSIWMODE: /* 0x8B06, set operation mode */ -+ ret = wext_set_mode(prDev, NULL, &iwr->u.mode, NULL); -+ /* ret = 0; */ -+ break; -+ -+ case SIOCGIWMODE: /* 0x8B07, get operation mode */ -+ ret = wext_get_mode(prDev, NULL, &iwr->u.mode, NULL); -+ break; -+ -+ /* case SIOCSIWSENS: 0x8B08, unsupported */ -+ /* case SIOCGIWSENS: 0x8B09, unsupported */ -+ -+ /* case SIOCSIWRANGE: 0x8B0A, unused */ -+ case SIOCGIWRANGE: /* 0x8B0B, get range of parameters */ -+ if (iwr->u.data.pointer != NULL) { -+ /* Buffer size should be large enough */ -+ if (iwr->u.data.length < sizeof(struct iw_range)) { -+ ret = -E2BIG; -+ break; -+ } -+ -+ prExtraBuf = kalMemAlloc(sizeof(struct iw_range), VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ /* reset all fields */ -+ memset(prExtraBuf, 0, sizeof(struct iw_range)); -+ iwr->u.data.length = sizeof(struct iw_range); -+ -+ ret = wext_get_range(prDev, NULL, &iwr->u.data, prExtraBuf); -+ /* Push up to the caller */ -+ if (copy_to_user(iwr->u.data.pointer, prExtraBuf, iwr->u.data.length)) -+ ret = -EFAULT; -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_range)); -+ prExtraBuf = NULL; -+ } else { -+ ret = -EINVAL; -+ } -+ break; -+ -+ case SIOCSIWPRIV: /* 0x8B0C, set country code */ -+ ret = wext_set_country(prDev, &iwr->u.data); -+ break; -+ -+ case SIOCGIWPRIV: /* 0x8B0D, get private args table */ -+ ret = wext_get_priv(prDev, &iwr->u.data); -+ break; -+ -+ /* case SIOCSIWSTATS: 0x8B0E, unused */ -+ /* case SIOCGIWSTATS: -+ get statistics, intercepted by wireless_process_ioctl() in wireless.c, -+ redirected to dev_iwstats(), dev->get_wireless_stats(). -+ */ -+ /* case SIOCSIWSPY: 0x8B10, unsupported */ -+ /* case SIOCGIWSPY: 0x8B11, unsupported */ -+ /* case SIOCSIWTHRSPY: 0x8B12, unsupported */ -+ /* case SIOCGIWTHRSPY: 0x8B13, unsupported */ -+ -+ case SIOCSIWAP: /* 0x8B14, set access point MAC addresses (BSSID) */ -+ if (iwr->u.ap_addr.sa_data[0] == 0 && -+ iwr->u.ap_addr.sa_data[1] == 0 && -+ iwr->u.ap_addr.sa_data[2] == 0 && -+ iwr->u.ap_addr.sa_data[3] == 0 && -+ iwr->u.ap_addr.sa_data[4] == 0 && iwr->u.ap_addr.sa_data[5] == 0) { -+ /* WPA Supplicant will set 000000000000 in -+ ** wpa_driver_wext_deinit(), do nothing here or disassoc again? -+ */ -+ ret = 0; -+ break; -+ } -+ ret = wext_set_ap(prDev, NULL, &iwr->u.ap_addr, NULL); -+ -+ break; -+ -+ case SIOCGIWAP: /* 0x8B15, get access point MAC addresses (BSSID) */ -+ ret = wext_get_ap(prDev, NULL, &iwr->u.ap_addr, NULL); -+ break; -+ -+ case SIOCSIWMLME: /* 0x8B16, request MLME operation */ -+ /* Fixed length structure */ -+ if (iwr->u.data.length != sizeof(struct iw_mlme)) { -+ DBGLOG(REQ, ERROR, "MLME buffer strange:%d\n", iwr->u.data.length); -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (!iwr->u.data.pointer) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, iwr->u.data.pointer, sizeof(struct iw_mlme))) -+ ret = -EFAULT; -+ else -+ ret = wext_set_mlme(prDev, NULL, &(iwr->u.data), prExtraBuf); -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_mlme)); -+ prExtraBuf = NULL; -+ break; -+ -+ /* case SIOCGIWAPLIST: 0x8B17, deprecated */ -+ case SIOCSIWSCAN: /* 0x8B18, scan request */ -+ if (iwr->u.data.pointer == NULL) -+ ret = wext_set_scan(prDev, NULL, NULL, NULL); -+#if WIRELESS_EXT > 17 -+ else if (iwr->u.data.length == sizeof(struct iw_scan_req)) { -+ prExtraBuf = kalMemAlloc(MAX_SSID_LEN, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ if (copy_from_user(prExtraBuf, ((struct iw_scan_req *)(iwr->u.data.pointer))->essid, -+ ((struct iw_scan_req *)(iwr->u.data.pointer))->essid_len)) { -+ ret = -EFAULT; -+ } else { -+ ret = wext_set_scan(prDev, NULL, (union iwreq_data *)&(iwr->u.data), prExtraBuf); -+ } -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, MAX_SSID_LEN); -+ prExtraBuf = NULL; -+ } -+#endif -+ else -+ ret = -EINVAL; -+ break; -+#if 1 -+ case SIOCGIWSCAN: /* 0x8B19, get scan results */ -+ if (!iwr->u.data.pointer || !iwr->u.essid.pointer) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ u4ExtraSize = iwr->u.data.length; -+ /* allocate the same size of kernel buffer to store scan results. */ -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ /* iwr->u.data.length may be updated by wext_get_scan() */ -+ ret = wext_get_scan(prDev, NULL, &iwr->u.data, prExtraBuf); -+ if (ret != 0) { -+ if (ret == -E2BIG) -+ DBGLOG(REQ, WARN, "[wifi] wext_get_scan -E2BIG\n"); -+ } else { -+ /* check updated length is valid */ -+ ASSERT(iwr->u.data.length <= u4ExtraSize); -+ if (iwr->u.data.length > u4ExtraSize) { -+ DBGLOG(REQ, INFO, "Updated result length is larger than allocated (%d > %u)\n", -+ iwr->u.data.length, u4ExtraSize); -+ iwr->u.data.length = u4ExtraSize; -+ } -+ -+ if (copy_to_user(iwr->u.data.pointer, prExtraBuf, iwr->u.data.length)) -+ ret = -EFAULT; -+ } -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ -+ break; -+ -+#endif -+ -+#if 1 -+ case SIOCSIWESSID: /* 0x8B1A, set SSID (network name) */ -+ if (iwr->u.essid.length > IW_ESSID_MAX_SIZE) { -+ ret = -E2BIG; -+ break; -+ } -+ if (!iwr->u.essid.pointer) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE + 4, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, iwr->u.essid.pointer, iwr->u.essid.length)) { -+ ret = -EFAULT; -+ } else { -+ /* Add trailing '\0' for printk */ -+ /* prExtraBuf[iwr->u.essid.length] = 0; */ -+ /* printk(KERN_INFO "wext_set_essid: %s (%d)\n", prExtraBuf, iwr->u.essid.length); */ -+ ret = wext_set_essid(prDev, NULL, &iwr->u.essid, prExtraBuf); -+ /* printk ("set essid %d\n", ret); */ -+ } -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE + 4); -+ prExtraBuf = NULL; -+ break; -+ -+#endif -+ -+ case SIOCGIWESSID: /* 0x8B1B, get SSID */ -+ if (!iwr->u.essid.pointer) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (iwr->u.essid.length < IW_ESSID_MAX_SIZE) { -+ DBGLOG(REQ, ERROR, "[wifi] iwr->u.essid.length:%d too small\n", iwr->u.essid.length); -+ ret = -E2BIG; /* let caller try larger buffer */ -+ break; -+ } -+ -+ prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ /* iwr->u.essid.length is updated by wext_get_essid() */ -+ -+ ret = wext_get_essid(prDev, NULL, &iwr->u.essid, prExtraBuf); -+ if (ret == 0) { -+ if (copy_to_user(iwr->u.essid.pointer, prExtraBuf, iwr->u.essid.length)) -+ ret = -EFAULT; -+ } -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE); -+ prExtraBuf = NULL; -+ -+ break; -+ -+ /* case SIOCSIWNICKN: 0x8B1C, not supported */ -+ /* case SIOCGIWNICKN: 0x8B1D, not supported */ -+ -+ case SIOCSIWRATE: /* 0x8B20, set default bit rate (bps) */ -+ /* ret = wext_set_rate(prDev, &rIwReqInfo, &iwr->u.bitrate, NULL); */ -+ break; -+ -+ case SIOCGIWRATE: /* 0x8B21, get current bit rate (bps) */ -+ ret = wext_get_rate(prDev, NULL, &iwr->u.bitrate, NULL); -+ break; -+ -+ case SIOCSIWRTS: /* 0x8B22, set rts/cts threshold */ -+ ret = wext_set_rts(prDev, NULL, &iwr->u.rts, NULL); -+ break; -+ -+ case SIOCGIWRTS: /* 0x8B23, get rts/cts threshold */ -+ ret = wext_get_rts(prDev, NULL, &iwr->u.rts, NULL); -+ break; -+ -+ /* case SIOCSIWFRAG: 0x8B24, unsupported */ -+ case SIOCGIWFRAG: /* 0x8B25, get frag threshold */ -+ ret = wext_get_frag(prDev, NULL, &iwr->u.frag, NULL); -+ break; -+ -+ case SIOCSIWTXPOW: /* 0x8B26, set relative tx power (in %) */ -+ ret = wext_set_txpow(prDev, NULL, &iwr->u.txpower, NULL); -+ break; -+ -+ case SIOCGIWTXPOW: /* 0x8B27, get relative tx power (in %) */ -+ ret = wext_get_txpow(prDev, NULL, &iwr->u.txpower, NULL); -+ break; -+ -+ /* case SIOCSIWRETRY: 0x8B28, unsupported */ -+ /* case SIOCGIWRETRY: 0x8B29, unsupported */ -+ -+#if 1 -+ case SIOCSIWENCODE: /* 0x8B2A, set encoding token & mode */ -+ /* Only DISABLED case has NULL pointer and length == 0 */ -+ if (iwr->u.encoding.pointer) { -+ if (iwr->u.encoding.length > 16) { -+ ret = -E2BIG; -+ break; -+ } -+ -+ u4ExtraSize = iwr->u.encoding.length; -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, iwr->u.encoding.pointer, iwr->u.encoding.length)) -+ ret = -EFAULT; -+ } else if (iwr->u.encoding.length != 0) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (ret == 0) -+ ret = wext_set_encode(prDev, NULL, &iwr->u.encoding, prExtraBuf); -+ -+ if (prExtraBuf) { -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ } -+ break; -+ -+ case SIOCGIWENCODE: /* 0x8B2B, get encoding token & mode */ -+ /* check pointer */ -+ ret = wext_get_encode(prDev, NULL, &iwr->u.encoding, NULL); -+ break; -+ -+ case SIOCSIWPOWER: /* 0x8B2C, set power management */ -+ ret = wext_set_power(prDev, NULL, &iwr->u.power, NULL); -+ break; -+ -+ case SIOCGIWPOWER: /* 0x8B2D, get power management */ -+ ret = wext_get_power(prDev, NULL, &iwr->u.power, NULL); -+ break; -+ -+#if WIRELESS_EXT > 17 -+ case SIOCSIWGENIE: /* 0x8B30, set gen ie */ -+ if (iwr->u.data.pointer == NULL) -+ break; -+ -+ if (0 /* wlanQueryWapiMode(prGlueInfo->prAdapter) */) -+ break; -+ -+ /* Fixed length structure */ -+#if CFG_SUPPORT_WAPI -+ if (iwr->u.data.length > 42 /* The max wapi ie buffer */) { -+ ret = -EINVAL; -+ break; -+ } -+#endif -+ u4ExtraSize = iwr->u.data.length; -+ if (u4ExtraSize == 0) -+ break; -+ -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ if (copy_from_user(prExtraBuf, iwr->u.data.pointer, iwr->u.data.length)) { -+ ret = -EFAULT; -+ } else { -+#if CFG_SUPPORT_WAPI -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiAssocInfo, -+ prExtraBuf, -+ u4ExtraSize, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO "[wapi] set wapi assoc info error:%lx\n", -+ rStatus); */ -+#endif -+#if CFG_SUPPORT_WPS2 -+ PUINT_8 prDesiredIE = NULL; -+ -+ if (wextSrchDesiredWPSIE(prExtraBuf, -+ u4ExtraSize, -+ 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWSCAssocInfo, -+ prDesiredIE, -+ IE_SIZE(prDesiredIE), -+ FALSE, -+ FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO "[WSC] set WSC assoc info -+ error:%lx\n", rStatus); */ -+ } -+ } -+#endif -+#if CFG_SUPPORT_WAPI -+ } -+#endif -+ } -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ break; -+ -+ case SIOCGIWGENIE: /* 0x8B31, get gen ie, unused */ -+ break; -+ -+#endif -+ -+ case SIOCSIWAUTH: /* 0x8B32, set auth mode params */ -+ ret = wext_set_auth(prDev, NULL, &iwr->u.param, NULL); -+ break; -+ -+ /* case SIOCGIWAUTH: 0x8B33, unused? */ -+ case SIOCSIWENCODEEXT: /* 0x8B34, set extended encoding token & mode */ -+ if (iwr->u.encoding.pointer) { -+ u4ExtraSize = iwr->u.encoding.length; -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, iwr->u.encoding.pointer, iwr->u.encoding.length)) -+ ret = -EFAULT; -+ } else if (iwr->u.encoding.length != 0) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (ret == 0) -+ ret = wext_set_encode_ext(prDev, NULL, &iwr->u.encoding, prExtraBuf); -+ -+ if (prExtraBuf) { -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ } -+ break; -+ -+ /* case SIOCGIWENCODEEXT: 0x8B35, unused? */ -+ -+ case SIOCSIWPMKSA: /* 0x8B36, pmksa cache operation */ -+#if 1 -+ if (iwr->u.data.pointer) { -+ /* Fixed length structure */ -+ if (iwr->u.data.length != sizeof(struct iw_pmksa)) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ u4ExtraSize = sizeof(struct iw_pmksa); -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, iwr->u.data.pointer, sizeof(struct iw_pmksa))) { -+ ret = -EFAULT; -+ } else { -+ switch (((struct iw_pmksa *)prExtraBuf)->cmd) { -+ case IW_PMKSA_ADD: -+ /* -+ printk(KERN_INFO "IW_PMKSA_ADD [ %pM ]\n", -+ (((struct iw_pmksa *)pExtraBuf)->bssid.sa_data)); -+ */ -+ prPmkid = -+ (P_PARAM_PMKID_T) kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), -+ VIR_MEM_TYPE); -+ if (!prPmkid) { -+ DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_ADD\n"); -+ ret = -ENOMEM; -+ break; -+ } -+ -+ prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T); -+ prPmkid->u4BSSIDInfoCount = 1; -+ kalMemCopy(prPmkid->arBSSIDInfo->arBSSID, -+ ((struct iw_pmksa *)prExtraBuf)->bssid.sa_data, 6); -+ kalMemCopy(prPmkid->arBSSIDInfo->arPMKID, -+ ((struct iw_pmksa *)prExtraBuf)->pmkid, IW_PMKID_LEN); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetPmkid, -+ prPmkid, -+ sizeof(PARAM_PMKID_T), -+ FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, ERROR, "add pmkid error:%x\n", rStatus); -+ kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T)); -+ break; -+ case IW_PMKSA_REMOVE: -+ /* -+ printk(KERN_INFO "IW_PMKSA_REMOVE [ %pM ]\n", -+ (((struct iw_pmksa *)buf)->bssid.sa_data)); -+ */ -+ break; -+ case IW_PMKSA_FLUSH: -+ /* -+ printk(KERN_INFO "IW_PMKSA_FLUSH\n"); -+ */ -+ prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8, VIR_MEM_TYPE); -+ if (!prPmkid) { -+ DBGLOG(REQ, ERROR, -+ "Can not alloc memory for IW_PMKSA_FLUSH\n"); -+ ret = -ENOMEM; -+ break; -+ } -+ -+ prPmkid->u4Length = 8; -+ prPmkid->u4BSSIDInfoCount = 0; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetPmkid, -+ prPmkid, -+ sizeof(PARAM_PMKID_T), -+ FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, ERROR, "flush pmkid error:%x\n", rStatus); -+ kalMemFree(prPmkid, VIR_MEM_TYPE, 8); -+ break; -+ default: -+ DBGLOG(REQ, WARN, "UNKNOWN iw_pmksa command:%d\n", -+ ((struct iw_pmksa *)prExtraBuf)->cmd); -+ ret = -EFAULT; -+ break; -+ } -+ } -+ -+ if (prExtraBuf) { -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ } -+ } else if (iwr->u.data.length != 0) { -+ ret = -EINVAL; -+ break; -+ } -+#endif -+ break; -+ -+#endif -+ -+ default: -+ /* printk(KERN_NOTICE "unsupported IOCTL: 0x%x\n", i4Cmd); */ -+ ret = -EOPNOTSUPP; -+ break; -+ } -+ -+ /* printk("%ld CMD:0x%x ret:%d\n", jiffies_to_msecs(jiffies), i4Cmd, ret); */ -+ -+ return ret; -+} /* wext_support_ioctl */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To send an event (RAW socket pacekt) to user process actively. -+* -+* \param[in] prGlueInfo Glue layer info. -+* \param[in] u4cmd Whcih event command we want to indicate to user process. -+* \param[in] pData Data buffer to be indicated. -+* \param[in] dataLen Available data size in pData. -+* -+* \return (none) -+* -+* \note Event is indicated to upper layer if cmd is supported and data is valid. -+* Using of kernel symbol wireless_send_event(), which is defined in -+* after WE-14 (2.4.20). -+*/ -+/*----------------------------------------------------------------------------*/ -+void -+wext_indicate_wext_event(IN P_GLUE_INFO_T prGlueInfo, -+ IN unsigned int u4Cmd, IN unsigned char *pucData, IN unsigned int u4dataLen) -+{ -+ union iwreq_data wrqu; -+ unsigned char *pucExtraInfo = NULL; -+#if WIRELESS_EXT >= 15 -+ unsigned char *pucDesiredIE = NULL; -+ unsigned char aucExtraInfoBuf[200]; -+#endif -+#if WIRELESS_EXT < 18 -+ int i; -+#endif -+ -+ memset(&wrqu, 0, sizeof(wrqu)); -+ -+ switch (u4Cmd) { -+ case SIOCGIWTXPOW: -+ memcpy(&wrqu.power, pucData, u4dataLen); -+ break; -+ case SIOCGIWSCAN: -+ complete_all(&prGlueInfo->rScanComp); -+ break; -+ -+ case SIOCGIWAP: -+ if (pucData) -+ ether_addr_copy((u8 *)&(wrqu.ap_addr.sa_data), pucData); -+ /*memcpy(&wrqu.ap_addr.sa_data, pucData, ETH_ALEN);*/ -+ else -+ memset(&wrqu.ap_addr.sa_data, 0, ETH_ALEN); -+ break; -+ -+ case IWEVASSOCREQIE: -+#if WIRELESS_EXT < 15 -+ /* under WE-15, no suitable Event can be used */ -+ goto skip_indicate_event; -+#else -+ /* do supplicant a favor, parse to the start of WPA/RSN IE */ -+ if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0x30, &pucDesiredIE)) { -+ /* RSN IE found */ -+ /* Do nothing */ -+#if 0 -+ } else if (wextSrchDesiredWPSIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) { -+ /* WPS IE found */ -+ /* Do nothing */ -+#endif -+ } else if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) { -+ /* WPA IE found */ -+ /* Do nothing*/ -+#if CFG_SUPPORT_WAPI /* Android+ */ -+ } else if (wextSrchDesiredWAPIIE(pucData, u4dataLen, &pucDesiredIE)) { -+ /* WAPI IE found */ -+ /* printk("wextSrchDesiredWAPIIE!!\n"); */ -+#endif -+ } else { -+ /* no WPA/RSN IE found, skip this event */ -+ goto skip_indicate_event; -+ } -+#if WIRELESS_EXT < 18 -+ /* under WE-18, only IWEVCUSTOM can be used */ -+ u4Cmd = IWEVCUSTOM; -+ pucExtraInfo = aucExtraInfoBuf; -+ pucExtraInfo += sprintf(pucExtraInfo, "ASSOCINFO(ReqIEs="); -+ /* printk(KERN_DEBUG "assoc info buffer size needed:%d\n", infoElemLen * 2 + 17); */ -+ /* translate binary string to hex string, requirement of IWEVCUSTOM */ -+ for (i = 0; i < pucDesiredIE[1] + 2; ++i) -+ pucExtraInfo += sprintf(pucExtraInfo, "%02x", pucDesiredIE[i]); -+ pucExtraInfo = aucExtraInfoBuf; -+ wrqu.data.length = 17 + (pucDesiredIE[1] + 2) * 2; -+#else -+ /* IWEVASSOCREQIE, indicate binary string */ -+ pucExtraInfo = pucDesiredIE; -+ wrqu.data.length = pucDesiredIE[1] + 2; -+#endif -+#endif /* WIRELESS_EXT < 15 */ -+ break; -+ -+ case IWEVMICHAELMICFAILURE: -+#if WIRELESS_EXT < 15 -+ /* under WE-15, no suitable Event can be used */ -+ goto skip_indicate_event; -+#else -+ if (pucData) { -+ P_PARAM_AUTH_REQUEST_T pAuthReq = (P_PARAM_AUTH_REQUEST_T) pucData; -+ /* under WE-18, only IWEVCUSTOM can be used */ -+ u4Cmd = IWEVCUSTOM; -+ pucExtraInfo = aucExtraInfoBuf; -+ pucExtraInfo += sprintf(pucExtraInfo, "MLME-MICHAELMICFAILURE.indication "); -+ pucExtraInfo += sprintf(pucExtraInfo, -+ "%s", -+ (pAuthReq->u4Flags == PARAM_AUTH_REQUEST_GROUP_ERROR) ? -+ "groupcast " : "unicast "); -+ -+ wrqu.data.length = pucExtraInfo - aucExtraInfoBuf; -+ pucExtraInfo = aucExtraInfoBuf; -+ } -+#endif /* WIRELESS_EXT < 15 */ -+ break; -+ -+ case IWEVPMKIDCAND: -+ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2 && -+ prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_802_1X) { -+ -+ /* only used in WPA2 */ -+#if WIRELESS_EXT >= 18 -+ P_PARAM_PMKID_CANDIDATE_T prPmkidCand = (P_PARAM_PMKID_CANDIDATE_T) pucData; -+ -+ struct iw_pmkid_cand rPmkidCand; -+ -+ pucExtraInfo = aucExtraInfoBuf; -+ -+ rPmkidCand.flags = prPmkidCand->u4Flags; -+ rPmkidCand.index = 0; -+ rPmkidCand.bssid.sa_family = 0; -+ kalMemCopy(rPmkidCand.bssid.sa_data, prPmkidCand->arBSSID, 6); -+ -+ kalMemCopy(pucExtraInfo, (PUINT_8) &rPmkidCand, sizeof(struct iw_pmkid_cand)); -+ wrqu.data.length = sizeof(struct iw_pmkid_cand); -+ -+ /* pmkid canadidate list is supported after WE-18 */ -+ /* indicate struct iw_pmkid_cand */ -+#else -+ /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, WE < 18\n"); */ -+ goto skip_indicate_event; -+#endif -+ } else { -+ /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, NOT WPA2\n"); */ -+ goto skip_indicate_event; -+ } -+ break; -+ -+ case IWEVCUSTOM: -+ u4Cmd = IWEVCUSTOM; -+ pucExtraInfo = aucExtraInfoBuf; -+ kalMemCopy(pucExtraInfo, pucData, sizeof(PTA_IPC_T)); -+ wrqu.data.length = sizeof(PTA_IPC_T); -+ break; -+ -+ default: -+ /* printk(KERN_INFO "Unsupported wext event:%x\n", cmd); */ -+ goto skip_indicate_event; -+ } -+ -+ /* Send event to user space */ -+ wireless_send_event(prGlueInfo->prDevHandler, u4Cmd, &wrqu, pucExtraInfo); -+ -+skip_indicate_event: -+ return; -+} /* wext_indicate_wext_event */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A method of struct net_device, to get the network interface statistical -+* information. -+* -+* Whenever an application needs to get statistics for the interface, this method -+* is called. This happens, for example, when ifconfig or netstat -i is run. -+* -+* \param[in] pDev Pointer to struct net_device. -+* -+* \return net_device_stats buffer pointer. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+struct iw_statistics *wext_get_wireless_stats(struct net_device *prDev) -+{ -+ -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_statistics *pStats = NULL; -+ INT_32 i4Rssi; -+ UINT_32 bufLen = 0; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ if (!prGlueInfo) -+ goto stat_out; -+ -+ pStats = (struct iw_statistics *)(&(prGlueInfo->rIwStats)); -+ -+ if (!prDev || !netif_carrier_ok(prDev)) { -+ /* network not connected */ -+ goto stat_out; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidQueryRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, FALSE, &bufLen); -+ -+stat_out: -+ return pStats; -+} /* wlan_get_wireless_stats */ -+ -+ -+#endif /* WIRELESS_EXT */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c -new file mode 100644 -index 0000000000000..2b6c3df845942 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c -@@ -0,0 +1,3142 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_wext_priv.c#4 -+*/ -+ -+/*! \file gl_wext_priv.c -+ \brief This file includes private ioctl support. -+*/ -+ -+/* -+** Log: gl_wext_priv.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 03 20 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * [WCXRP00001202] [MT6628 Wi-Fi][FW] Adding the New PN init code -+ * use return to avoid the ioctl return not supported -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 01 16 2012 wh.su -+ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl -+ * Adding the template code for set / get band IOCTL (with ICS supplicant_6).. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 01 02 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 11 02 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Fixed typo. -+ * -+ * 09 20 2011 chinglan.wang -+ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. -+ * . -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 01 27 2011 cm.chang -+ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default -+ * . -+ * -+ * 01 26 2011 wh.su -+ * [WCXRP00000396] [MT6620 Wi-Fi][Driver] Support Sw Ctrl ioctl at linux -+ * adding the SW cmd ioctl support, use set/get structure ioctl. -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Adjust OID order. -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 01 07 2011 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add a new compiling option to control if MCR read/write is permitted -+ * -+ * 12 31 2010 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add some iwpriv commands to support test mode operation -+ * -+ * 12 15 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * Support set PS profile and set WMM-PS related iwpriv. -+ * -+ * 11 08 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * add the message check code from mt5921. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * correct typo for NVRAM access. -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * revert changelist #15371, efuse read/write access will be done by RF test approach -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add OID definitions for EFUSE read/write access. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * enable OID_CUSTOM_MTK_WIFI_TEST for RFTest & META tool -+ * -+ * 05 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix private ioctl for rftest -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+** \main\maintrunk.MT5921\32 2009-10-08 10:33:25 GMT mtk01090 -+** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input -+** parameters and pointers. -+** \main\maintrunk.MT5921\31 2009-09-29 16:46:21 GMT mtk01090 -+** Remove unused functions -+** \main\maintrunk.MT5921\30 2009-09-29 14:46:47 GMT mtk01090 -+** Fix compile warning -+** \main\maintrunk.MT5921\29 2009-09-29 14:28:48 GMT mtk01090 -+** Fix compile warning -+** \main\maintrunk.MT5921\28 2009-09-28 22:21:38 GMT mtk01090 -+** Refine lines to suppress compile warning -+** \main\maintrunk.MT5921\27 2009-09-28 20:19:14 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\26 2009-08-18 22:56:53 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\25 2009-05-07 22:26:15 GMT mtk01089 -+** Add mandatory and private IO control for Linux BWCS -+** \main\maintrunk.MT5921\24 2009-04-29 10:07:05 GMT mtk01088 -+** fixed the compiling error at linux -+** \main\maintrunk.MT5921\23 2009-04-24 09:09:45 GMT mtk01088 -+** mark the code not used at linux supplicant v0.6.7 -+** \main\maintrunk.MT5921\22 2008-11-24 21:03:51 GMT mtk01425 -+** 1. Add PTA_ENABLED flag -+** \main\maintrunk.MT5921\21 2008-08-29 14:55:59 GMT mtk01088 -+** adjust the code for meet the coding style, and add assert check -+** \main\maintrunk.MT5921\20 2008-07-16 15:23:20 GMT mtk01104 -+** Support GPIO2 mode -+** \main\maintrunk.MT5921\19 2008-07-15 17:43:11 GMT mtk01084 -+** modify variable name -+** \main\maintrunk.MT5921\18 2008-07-14 14:37:58 GMT mtk01104 -+** Add exception handle about length in function priv_set_struct() -+** \main\maintrunk.MT5921\17 2008-07-14 13:55:32 GMT mtk01104 -+** Support PRIV_CMD_BT_COEXIST -+** \main\maintrunk.MT5921\16 2008-07-09 00:20:15 GMT mtk01461 -+** Add priv oid to support WMM_PS_TEST -+** \main\maintrunk.MT5921\15 2008-06-02 11:15:22 GMT mtk01461 -+** Update after wlanoidSetPowerMode changed -+** \main\maintrunk.MT5921\14 2008-05-30 19:31:07 GMT mtk01461 -+** Add IOCTL for Power Mode -+** \main\maintrunk.MT5921\13 2008-05-30 18:57:15 GMT mtk01461 -+** Not use wlanoidSetCSUMOffloadForLinux() -+** \main\maintrunk.MT5921\12 2008-05-30 15:13:18 GMT mtk01084 -+** rename wlanoid -+** \main\maintrunk.MT5921\11 2008-05-29 14:16:31 GMT mtk01084 -+** rename for wlanoidSetBeaconIntervalForLinux -+** \main\maintrunk.MT5921\10 2008-04-17 23:06:37 GMT mtk01461 -+** Add iwpriv support for AdHocMode setting -+** \main\maintrunk.MT5921\9 2008-03-31 21:00:55 GMT mtk01461 -+** Add priv IOCTL for VOIP setting -+** \main\maintrunk.MT5921\8 2008-03-31 13:49:43 GMT mtk01461 -+** Add priv ioctl to turn on / off roaming -+** \main\maintrunk.MT5921\7 2008-03-26 15:35:14 GMT mtk01461 -+** Add CSUM offload priv ioctl for Linux -+** \main\maintrunk.MT5921\6 2008-03-11 14:50:59 GMT mtk01461 -+** Unify priv ioctl -+** \main\maintrunk.MT5921\5 2007-11-06 19:32:30 GMT mtk01088 -+** add WPS code -+** \main\maintrunk.MT5921\4 2007-10-30 12:01:39 GMT MTK01425 -+** 1. Update wlanQueryInformation and wlanSetInformation -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#include "gl_os.h" -+#include "gl_wext_priv.h" -+#if CFG_SUPPORT_WAPI -+#include "gl_sec.h" -+#endif -+#if CFG_ENABLE_WIFI_DIRECT -+#include "gl_p2p_os.h" -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define NUM_SUPPORTED_OIDS (sizeof(arWlanOidReqTable) / sizeof(WLAN_REQ_ENTRY)) -+#define CMD_START "START" -+#define CMD_STOP "STOP" -+#define CMD_SCAN_ACTIVE "SCAN-ACTIVE" -+#define CMD_SCAN_PASSIVE "SCAN-PASSIVE" -+#define CMD_RSSI "RSSI" -+#define CMD_LINKSPEED "LINKSPEED" -+#define CMD_RXFILTER_START "RXFILTER-START" -+#define CMD_RXFILTER_STOP "RXFILTER-STOP" -+#define CMD_RXFILTER_ADD "RXFILTER-ADD" -+#define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE" -+#define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START" -+#define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP" -+#define CMD_BTCOEXMODE "BTCOEXMODE" -+#define CMD_SETSUSPENDOPT "SETSUSPENDOPT" -+#define CMD_SETSUSPENDMODE "SETSUSPENDMODE" -+#define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR" -+#define CMD_SETFWPATH "SETFWPATH" -+#define CMD_SETBAND "SETBAND" -+#define CMD_GETBAND "GETBAND" -+#define CMD_COUNTRY "COUNTRY" -+#define CMD_P2P_SET_NOA "P2P_SET_NOA" -+#define CMD_P2P_GET_NOA "P2P_GET_NOA" -+#define CMD_P2P_SET_PS "P2P_SET_PS" -+#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" -+#define CMD_SETROAMMODE "SETROAMMODE" -+#define CMD_MIRACAST "MIRACAST" -+ -+#define CMD_PNOSSIDCLR_SET "PNOSSIDCLR" -+#define CMD_PNOSETUP_SET "PNOSETUP " -+#define CMD_PNOENABLE_SET "PNOFORCE" -+#define CMD_PNODEBUG_SET "PNODEBUG" -+#define CMD_WLS_BATCHING "WLS_BATCHING" -+ -+#define CMD_OKC_SET_PMK "SET_PMK" -+#define CMD_OKC_ENABLE "OKC_ENABLE" -+ -+/* miracast related definition */ -+#define MIRACAST_MODE_OFF 0 -+#define MIRACAST_MODE_SOURCE 1 -+#define MIRACAST_MODE_SINK 2 -+ -+#ifndef MIRACAST_AMPDU_SIZE -+#define MIRACAST_AMPDU_SIZE 8 -+#endif -+ -+#ifndef MIRACAST_MCHAN_ALGO -+#define MIRACAST_MCHAN_ALGO 1 -+#endif -+ -+#ifndef MIRACAST_MCHAN_BW -+#define MIRACAST_MCHAN_BW 25 -+#endif -+ -+#define CMD_BAND_AUTO 0 -+#define CMD_BAND_5G 1 -+#define CMD_BAND_2G 2 -+#define CMD_BAND_ALL 3 -+ -+/* Mediatek private command */ -+ -+#define CMD_SET_SW_CTRL "SET_SW_CTRL" -+#define CMD_GET_SW_CTRL "GET_SW_CTRL" -+#define CMD_SET_CFG "SET_CFG" -+#define CMD_GET_CFG "GET_CFG" -+#define CMD_SET_CHIP "SET_CHIP" -+#define CMD_GET_CHIP "GET_CHIP" -+#define CMD_SET_DBG_LEVEL "SET_DBG_LEVEL" -+#define CMD_GET_DBG_LEVEL "GET_DBG_LEVEL" -+#define PRIV_CMD_SIZE 512 -+ -+static UINT_32 g_ucMiracastMode = MIRACAST_MODE_OFF; -+ -+typedef struct cmd_tlv { -+ char prefix; -+ char version; -+ char subver; -+ char reserved; -+} cmd_tlv_t; -+ -+typedef struct priv_driver_cmd_s { -+ char buf[PRIV_CMD_SIZE]; -+ int used_len; -+ int total_len; -+} priv_driver_cmd_t; -+ -+#if CFG_SUPPORT_BATCH_SCAN -+#define CMD_BATCH_SET "WLS_BATCHING SET" -+#define CMD_BATCH_GET "WLS_BATCHING GET" -+#define CMD_BATCH_STOP "WLS_BATCHING STOP" -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static int -+priv_get_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen); -+ -+static int -+priv_set_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen); -+ -+#if 0 /* CFG_SUPPORT_WPS */ -+static int -+priv_set_appie(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, OUT char *pcExtra); -+ -+static int -+priv_set_filter(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, OUT char *pcExtra); -+#endif /* CFG_SUPPORT_WPS */ -+ -+static BOOLEAN reqSearchSupportedOidEntry(IN UINT_32 rOid, OUT P_WLAN_REQ_ENTRY * ppWlanReqEntry); -+ -+#if 0 -+static WLAN_STATUS -+reqExtQueryConfiguration(IN P_GLUE_INFO_T prGlueInfo, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+static WLAN_STATUS -+reqExtSetConfiguration(IN P_GLUE_INFO_T prGlueInfo, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+static WLAN_STATUS -+reqExtSetAcpiDevicePowerState(IN P_GLUE_INFO_T prGlueInfo, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static UINT_8 aucOidBuf[4096] = { 0 }; -+ -+/* OID processing table */ -+/* Order is important here because the OIDs should be in order of -+ increasing value for binary searching. */ -+static WLAN_REQ_ENTRY arWlanOidReqTable[] = { -+ /* -+ {(NDIS_OID)rOid, -+ (PUINT_8)pucOidName, -+ fgQryBufLenChecking, fgSetBufLenChecking, fgIsHandleInGlueLayerOnly, u4InfoBufLen, -+ pfOidQueryHandler, -+ pfOidSetHandler} -+ */ -+ /* General Operational Characteristics */ -+ -+ /* Ethernet Operational Characteristics */ -+ {OID_802_3_CURRENT_ADDRESS, -+ DISP_STRING("OID_802_3_CURRENT_ADDRESS"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 6, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryCurrentAddr, -+ NULL}, -+ -+ /* OID_802_3_MULTICAST_LIST */ -+ /* OID_802_3_MAXIMUM_LIST_SIZE */ -+ /* Ethernet Statistics */ -+ -+ /* NDIS 802.11 Wireless LAN OIDs */ -+ {OID_802_11_SUPPORTED_RATES, -+ DISP_STRING("OID_802_11_SUPPORTED_RATES"), -+ TRUE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_RATES_EX), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQuerySupportedRates, -+ NULL} -+ , -+ /* -+ {OID_802_11_CONFIGURATION, -+ DISP_STRING("OID_802_11_CONFIGURATION"), -+ TRUE, TRUE, ENUM_OID_GLUE_EXTENSION, sizeof(PARAM_802_11_CONFIG_T), -+ (PFN_OID_HANDLER_FUNC_REQ)reqExtQueryConfiguration, -+ (PFN_OID_HANDLER_FUNC_REQ)reqExtSetConfiguration}, -+ */ -+ {OID_PNP_SET_POWER, -+ DISP_STRING("OID_PNP_SET_POWER"), -+ TRUE, FALSE, ENUM_OID_GLUE_EXTENSION, sizeof(PARAM_DEVICE_POWER_STATE), -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) reqExtSetAcpiDevicePowerState} -+ , -+ -+ /* Custom OIDs */ -+ {OID_CUSTOM_OID_INTERFACE_VERSION, -+ DISP_STRING("OID_CUSTOM_OID_INTERFACE_VERSION"), -+ TRUE, FALSE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryOidInterfaceVersion, -+ NULL} -+ , -+ -+ /* -+ #if PTA_ENABLED -+ {OID_CUSTOM_BT_COEXIST_CTRL, -+ DISP_STRING("OID_CUSTOM_BT_COEXIST_CTRL"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_BT_COEXIST_T), -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBtCoexistCtrl}, -+ #endif -+ */ -+ -+ /* -+ {OID_CUSTOM_POWER_MANAGEMENT_PROFILE, -+ DISP_STRING("OID_CUSTOM_POWER_MANAGEMENT_PROFILE"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryPwrMgmtProfParam, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPwrMgmtProfParam}, -+ {OID_CUSTOM_PATTERN_CONFIG, -+ DISP_STRING("OID_CUSTOM_PATTERN_CONFIG"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_PATTERN_SEARCH_CONFIG_STRUCT_T), -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPatternConfig}, -+ {OID_CUSTOM_BG_SSID_SEARCH_CONFIG, -+ DISP_STRING("OID_CUSTOM_BG_SSID_SEARCH_CONFIG"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBgSsidParam}, -+ {OID_CUSTOM_VOIP_SETUP, -+ DISP_STRING("OID_CUSTOM_VOIP_SETUP"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryVoipConnectionStatus, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetVoipConnectionStatus}, -+ {OID_CUSTOM_ADD_TS, -+ DISP_STRING("OID_CUSTOM_ADD_TS"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidAddTS}, -+ {OID_CUSTOM_DEL_TS, -+ DISP_STRING("OID_CUSTOM_DEL_TS"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidDelTS}, -+ */ -+ -+ /* -+ #if CFG_LP_PATTERN_SEARCH_SLT -+ {OID_CUSTOM_SLT, -+ DISP_STRING("OID_CUSTOM_SLT"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQuerySltResult, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetSltMode}, -+ #endif -+ -+ {OID_CUSTOM_ROAMING_EN, -+ DISP_STRING("OID_CUSTOM_ROAMING_EN"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRoamingFunction, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetRoamingFunction}, -+ {OID_CUSTOM_WMM_PS_TEST, -+ DISP_STRING("OID_CUSTOM_WMM_PS_TEST"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetWiFiWmmPsTest}, -+ {OID_CUSTOM_COUNTRY_STRING, -+ DISP_STRING("OID_CUSTOM_COUNTRY_STRING"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryCurrentCountry, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetCurrentCountry}, -+ -+ #if CFG_SUPPORT_802_11D -+ {OID_CUSTOM_MULTI_DOMAIN_CAPABILITY, -+ DISP_STRING("OID_CUSTOM_MULTI_DOMAIN_CAPABILITY"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryMultiDomainCap, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetMultiDomainCap}, -+ #endif -+ -+ {OID_CUSTOM_GPIO2_MODE, -+ DISP_STRING("OID_CUSTOM_GPIO2_MODE"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_PARAM_GPIO2_MODE_T), -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetGPIO2Mode}, -+ {OID_CUSTOM_CONTINUOUS_POLL, -+ DISP_STRING("OID_CUSTOM_CONTINUOUS_POLL"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CONTINUOUS_POLL_T), -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryContinuousPollInterval, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetContinuousPollProfile}, -+ {OID_CUSTOM_DISABLE_BEACON_DETECTION, -+ DISP_STRING("OID_CUSTOM_DISABLE_BEACON_DETECTION"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryDisableBeaconDetectionFunc, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetDisableBeaconDetectionFunc}, -+ */ -+ -+ /* WPS */ -+ /* -+ {OID_CUSTOM_DISABLE_PRIVACY_CHECK, -+ DISP_STRING("OID_CUSTOM_DISABLE_PRIVACY_CHECK"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetDisablePriavcyCheck}, -+ */ -+ -+ {OID_CUSTOM_MCR_RW, -+ DISP_STRING("OID_CUSTOM_MCR_RW"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryMcrRead, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetMcrWrite} -+ , -+ -+ {OID_CUSTOM_EEPROM_RW, -+ DISP_STRING("OID_CUSTOM_EEPROM_RW"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryEepromRead, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetEepromWrite} -+ , -+ -+ {OID_CUSTOM_SW_CTRL, -+ DISP_STRING("OID_CUSTOM_SW_CTRL"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQuerySwCtrlRead, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetSwCtrlWrite} -+ , -+ -+ {OID_CUSTOM_MEM_DUMP, -+ DISP_STRING("OID_CUSTOM_MEM_DUMP"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_MEM_DUMP_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryMemDump, -+ NULL} -+ , -+ -+ {OID_CUSTOM_TEST_MODE, -+ DISP_STRING("OID_CUSTOM_TEST_MODE"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetTestMode} -+ , -+ -+ /* -+ {OID_CUSTOM_TEST_RX_STATUS, -+ DISP_STRING("OID_CUSTOM_TEST_RX_STATUS"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRfTestRxStatus, -+ NULL}, -+ {OID_CUSTOM_TEST_TX_STATUS, -+ DISP_STRING("OID_CUSTOM_TEST_TX_STATUS"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRfTestTxStatus, -+ NULL}, -+ */ -+ {OID_CUSTOM_ABORT_TEST_MODE, -+ DISP_STRING("OID_CUSTOM_ABORT_TEST_MODE"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetAbortTestMode} -+ , -+ {OID_CUSTOM_MTK_WIFI_TEST, -+ DISP_STRING("OID_CUSTOM_MTK_WIFI_TEST"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestQueryAutoTest, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetAutoTest} -+ , -+ -+ /* OID_CUSTOM_EMULATION_VERSION_CONTROL */ -+ -+ /* BWCS */ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+ {OID_CUSTOM_BWCS_CMD, -+ DISP_STRING("OID_CUSTOM_BWCS_CMD"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PTA_IPC_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryBT, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetBT} -+ , -+#endif -+ -+/* {OID_CUSTOM_SINGLE_ANTENNA, -+ DISP_STRING("OID_CUSTOM_SINGLE_ANTENNA"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryBtSingleAntenna, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBtSingleAntenna}, -+ {OID_CUSTOM_SET_PTA, -+ DISP_STRING("OID_CUSTOM_SET_PTA"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryPta, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPta}, -+ */ -+ -+ {OID_CUSTOM_MTK_NVRAM_RW, -+ DISP_STRING("OID_CUSTOM_MTK_NVRAM_RW"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryNvramRead, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetNvramWrite} -+ , -+ -+ {OID_CUSTOM_CFG_SRC_TYPE, -+ DISP_STRING("OID_CUSTOM_CFG_SRC_TYPE"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_CFG_SRC_TYPE_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryCfgSrcType, -+ NULL} -+ , -+ -+ {OID_CUSTOM_EEPROM_TYPE, -+ DISP_STRING("OID_CUSTOM_EEPROM_TYPE"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_EEPROM_TYPE_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryEepromType, -+ NULL} -+ , -+ -+#if CFG_SUPPORT_WAPI -+ {OID_802_11_WAPI_MODE, -+ DISP_STRING("OID_802_11_WAPI_MODE"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiMode} -+ , -+ {OID_802_11_WAPI_ASSOC_INFO, -+ DISP_STRING("OID_802_11_WAPI_ASSOC_INFO"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiAssocInfo} -+ , -+ {OID_802_11_SET_WAPI_KEY, -+ DISP_STRING("OID_802_11_SET_WAPI_KEY"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_WPI_KEY_T), -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiKey} -+ , -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+ {OID_802_11_WSC_ASSOC_INFO, -+ DISP_STRING("OID_802_11_WSC_ASSOC_INFO"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWSCAssocInfo} -+ , -+#endif -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dispatching function for private ioctl region (SIOCIWFIRSTPRIV ~ -+* SIOCIWLASTPRIV). -+* -+* \param[in] prNetDev Net device requested. -+* \param[in] prIfReq Pointer to ifreq structure. -+* \param[in] i4Cmd Command ID between SIOCIWFIRSTPRIV and SIOCIWLASTPRIV. -+* -+* \retval 0 for success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EFAULT For fail. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+int priv_support_ioctl(IN struct net_device *prNetDev, IN OUT struct ifreq *prIfReq, IN int i4Cmd) -+{ -+ /* prIfReq is verified in the caller function wlanDoIOCTL() */ -+ struct iwreq *prIwReq = (struct iwreq *)prIfReq; -+ struct iw_request_info rIwReqInfo; -+ -+ /* prDev is verified in the caller function wlanDoIOCTL() */ -+ -+ /* Prepare the call */ -+ rIwReqInfo.cmd = (__u16) i4Cmd; -+ rIwReqInfo.flags = 0; -+ -+ switch (i4Cmd) { -+ case IOCTL_SET_INT: -+ /* NOTE(Kevin): 1/3 INT Type <= IFNAMSIZ, so we don't need copy_from/to_user() */ -+ return priv_set_int(prNetDev, &rIwReqInfo, &(prIwReq->u), (char *)&(prIwReq->u)); -+ -+ case IOCTL_GET_INT: -+ /* NOTE(Kevin): 1/3 INT Type <= IFNAMSIZ, so we don't need copy_from/to_user() */ -+ return priv_get_int(prNetDev, &rIwReqInfo, &(prIwReq->u), (char *)&(prIwReq->u)); -+ -+ case IOCTL_SET_STRUCT: -+ case IOCTL_SET_STRUCT_FOR_EM: -+ return priv_set_struct(prNetDev, &rIwReqInfo, &prIwReq->u, (char *)&(prIwReq->u)); -+ -+ case IOCTL_GET_STRUCT: -+ return priv_get_struct(prNetDev, &rIwReqInfo, &prIwReq->u, (char *)&(prIwReq->u)); -+ -+ default: -+ return -EOPNOTSUPP; -+ -+ } /* end of switch */ -+ -+} /* priv_support_ioctl */ -+ -+#if CFG_SUPPORT_BATCH_SCAN -+ -+EVENT_BATCH_RESULT_T g_rEventBatchResult[CFG_BATCH_MAX_MSCAN]; -+ -+UINT_32 batchChannelNum2Freq(UINT_32 u4ChannelNum) -+{ -+ UINT_32 u4ChannelInMHz; -+ -+ if (u4ChannelNum >= 1 && u4ChannelNum <= 13) -+ u4ChannelInMHz = 2412 + (u4ChannelNum - 1) * 5; -+ else if (u4ChannelNum == 14) -+ u4ChannelInMHz = 2484; -+ else if (u4ChannelNum == 133) -+ u4ChannelInMHz = 3665; /* 802.11y */ -+ else if (u4ChannelNum == 137) -+ u4ChannelInMHz = 3685; /* 802.11y */ -+ else if (u4ChannelNum >= 34 && u4ChannelNum <= 165) -+ u4ChannelInMHz = 5000 + u4ChannelNum * 5; -+ else if (u4ChannelNum >= 183 && u4ChannelNum <= 196) -+ u4ChannelInMHz = 4000 + u4ChannelNum * 5; -+ else -+ u4ChannelInMHz = 0; -+ -+ return u4ChannelInMHz; -+} -+ -+#define TMP_TEXT_LEN_S 40 -+#define TMP_TEXT_LEN_L 60 -+static UCHAR text1[TMP_TEXT_LEN_S], text2[TMP_TEXT_LEN_L], text3[TMP_TEXT_LEN_L]; /* A safe len */ -+ -+WLAN_STATUS -+batchConvertResult(IN P_EVENT_BATCH_RESULT_T prEventBatchResult, -+ OUT PVOID pvBuffer, IN UINT_32 u4MaxBufferLen, OUT PUINT_32 pu4RetLen) -+{ -+ CHAR *p = pvBuffer; -+ CHAR ssid[ELEM_MAX_LEN_SSID + 1]; -+ INT_32 nsize = 0, nsize1, nsize2, nsize3, scancount; -+ INT_32 i, j, nleft; -+ UINT_32 freq; -+ -+ P_EVENT_BATCH_RESULT_ENTRY_T prEntry; -+ P_EVENT_BATCH_RESULT_T pBr; -+ -+ nleft = u4MaxBufferLen - 5; /* -5 for "----\n" */ -+ -+ pBr = prEventBatchResult; -+ scancount = 0; -+ for (j = 0; j < CFG_BATCH_MAX_MSCAN; j++) { -+ scancount += pBr->ucScanCount; -+ pBr++; -+ } -+ -+ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "scancount=%x\nnextcount=%x\n", scancount, scancount); -+ if (nsize1 < nleft) { -+ p += nsize1 = kalSprintf(p, "%s", text1); -+ nleft -= nsize1; -+ } else -+ goto short_buf; -+ -+ pBr = prEventBatchResult; -+ for (j = 0; j < CFG_BATCH_MAX_MSCAN; j++) { -+ DBGLOG(SCN, TRACE, "convert mscan = %d, apcount=%d, nleft=%d\n", j, pBr->ucScanCount, nleft); -+ -+ if (pBr->ucScanCount == 0) { -+ pBr++; -+ continue; -+ } -+ -+ nleft -= 5; /* -5 for "####\n" */ -+ -+ /* We only support one round scan result now. */ -+ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "apcount=%d\n", pBr->ucScanCount); -+ if (nsize1 < nleft) { -+ p += nsize1 = kalSprintf(p, "%s", text1); -+ nleft -= nsize1; -+ } else -+ goto short_buf; -+ -+ for (i = 0; i < pBr->ucScanCount; i++) { -+ prEntry = &pBr->arBatchResult[i]; -+ -+ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "bssid=" MACSTR "\n", -+ prEntry->aucBssid[0], -+ prEntry->aucBssid[1], -+ prEntry->aucBssid[2], -+ prEntry->aucBssid[3], -+ prEntry->aucBssid[4], prEntry->aucBssid[5]); -+ -+ kalMemCopy(ssid, -+ prEntry->aucSSID, -+ (prEntry->ucSSIDLen < ELEM_MAX_LEN_SSID ? prEntry->ucSSIDLen : ELEM_MAX_LEN_SSID)); -+ ssid[(prEntry->ucSSIDLen < -+ (ELEM_MAX_LEN_SSID - 1) ? prEntry->ucSSIDLen : (ELEM_MAX_LEN_SSID - 1))] = '\0'; -+ nsize2 = kalSnprintf(text2, TMP_TEXT_LEN_L, "ssid=%s\n", ssid); -+ -+ freq = batchChannelNum2Freq(prEntry->ucFreq); -+ nsize3 = -+ kalSnprintf(text3, TMP_TEXT_LEN_L, -+ "freq=%u\nlevel=%d\ndist=%u\ndistSd=%u\n====\n", freq, -+ prEntry->cRssi, prEntry->u4Dist, prEntry->u4Distsd); -+ -+ nsize = nsize1 + nsize2 + nsize3; -+ if (nsize < nleft) { -+ -+ kalStrnCpy(p, text1, TMP_TEXT_LEN_S); -+ p += nsize1; -+ -+ kalStrnCpy(p, text2, TMP_TEXT_LEN_L); -+ p += nsize2; -+ -+ kalStrnCpy(p, text3, TMP_TEXT_LEN_L); -+ p += nsize3; -+ -+ nleft -= nsize; -+ } else { -+ DBGLOG(SCN, TRACE, "Warning: Early break! (%d)\n", i); -+ break; /* discard following entries, TODO: apcount? */ -+ } -+ } -+ -+ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "%s", "####\n"); -+ p += kalSprintf(p, "%s", text1); -+ -+ pBr++; -+ } -+ -+ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "%s", "----\n"); -+ kalSprintf(p, "%s", text1); -+ -+ *pu4RetLen = u4MaxBufferLen - nleft; -+ DBGLOG(SCN, TRACE, "total len = %d (max len = %d)\n", *pu4RetLen, u4MaxBufferLen); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+short_buf: -+ DBGLOG(SCN, TRACE, -+ "Short buffer issue! %d > %d, %s\n", u4MaxBufferLen + (nsize - nleft), -+ u4MaxBufferLen, (char *)pvBuffer); -+ return WLAN_STATUS_INVALID_LENGTH; -+} -+#endif -+ -+#if CFG_SUPPORT_GET_CH_ENV -+WLAN_STATUS -+scanEnvResult(P_GLUE_INFO_T prGlueInfo, OUT PVOID pvBuffer, IN UINT_32 u4MaxBufferLen, OUT PUINT_32 pu4RetLen) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ CHAR *p = pvBuffer; -+ INT_32 nsize; -+ INT_32 i, nleft; -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ CH_ENV_T chEnvInfo[54]; /* 54: from FW define; TODO: sync MAXIMUM_OPERATION_CHANNEL_LIST */ -+ UINT_32 i4GetCh = 0; -+ INT_32 i4Argc = 0; -+ PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; -+ UINT_8 ucTextLen = 40; -+ UCHAR text[ucTextLen]; -+ INT_32 u4Ret; -+ -+ prAdapter = prGlueInfo->prAdapter; -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ kalMemZero(chEnvInfo, sizeof(chEnvInfo)); -+ -+ DBGLOG(SCN, TRACE, "pvBuffer:%s, pu4RetLen:%d\n", (char *)pvBuffer, *pu4RetLen); -+ -+ wlanCfgParseArgument(pvBuffer, &i4Argc, apcArgv); -+ DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); -+ -+ if (i4Argc >= 2) { -+ u4Ret = kalkStrtou32(apcArgv[1], 0, &i4GetCh); -+ if (u4Ret) -+ DBGLOG(SCN, TRACE, "parse pvBuffer error u4Ret=%d\n", u4Ret); -+ /* i4GetCh = kalStrtoul(apcArgv[1], NULL, 0); */ -+ } -+ -+ nleft = u4MaxBufferLen - 5; /* -5 for "----\n" */ -+ -+ nsize = kalSnprintf(text, ucTextLen, "%s", "scanEnvResult\nResult:1\n");/* Always return 1 for alpha version. */ -+ -+ if (nsize < nleft) { -+ p += nsize = kalSnprintf(p, ucTextLen, "%s", text); -+ nleft -= nsize; -+ } else -+ goto short_buf; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ if (prBssDesc->ucChannelNum > 0) { -+ if (prBssDesc->ucChannelNum <= 14) { /* 1~14 */ -+ chEnvInfo[prBssDesc->ucChannelNum - 1].ucChNum = prBssDesc->ucChannelNum; -+ chEnvInfo[prBssDesc->ucChannelNum - 1].ucApNum++; -+ } else if (prBssDesc->ucChannelNum <= 64) { /* 15~22 */ -+ chEnvInfo[prBssDesc->ucChannelNum / 4 + 5].ucChNum = prBssDesc->ucChannelNum; -+ chEnvInfo[prBssDesc->ucChannelNum / 4 + 5].ucApNum++; -+ } else if (prBssDesc->ucChannelNum <= 116) { /* 23~27 */ -+ chEnvInfo[prBssDesc->ucChannelNum / 4 - 3].ucChNum = prBssDesc->ucChannelNum; -+ chEnvInfo[prBssDesc->ucChannelNum / 4 - 3].ucApNum++; -+ } else if (prBssDesc->ucChannelNum <= 140) { /* 28~30 */ -+ chEnvInfo[prBssDesc->ucChannelNum / 4 - 6].ucChNum = prBssDesc->ucChannelNum; -+ chEnvInfo[prBssDesc->ucChannelNum / 4 - 6].ucApNum++; -+ } else if (prBssDesc->ucChannelNum <= 165) { /* 31~35 */ -+ chEnvInfo[(prBssDesc->ucChannelNum - 1) / 4 - 7].ucChNum = prBssDesc->ucChannelNum; -+ chEnvInfo[(prBssDesc->ucChannelNum - 1) / 4 - 7].ucApNum++; -+ } -+ } -+ } -+ -+ for (i = 0; i < 54; i++) { -+ if (chEnvInfo[i].ucChNum != 0) { -+ if (i4GetCh == 0 || (chEnvInfo[i].ucChNum == (UINT_8)i4GetCh)) { -+ DBGLOG(SCN, TRACE, "chNum=%d,apNum=%d\n", chEnvInfo[i].ucChNum, chEnvInfo[i].ucApNum); -+ p += nsize = -+ kalSnprintf(p, ucTextLen, "chNum=%d,apNum=%d\n", chEnvInfo[i].ucChNum, -+ chEnvInfo[i].ucApNum); -+ nleft -= nsize; -+ } -+ } -+ } -+ -+ p += nsize = kalSnprintf(p, ucTextLen, "%s", "----\n"); -+ nleft -= nsize; -+ -+ *pu4RetLen = u4MaxBufferLen - nleft; -+ DBGLOG(SCN, TRACE, "total len = %d (max len = %d)\n", *pu4RetLen, u4MaxBufferLen); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+short_buf: -+ DBGLOG(SCN, TRACE, "Short buffer issue! %d > %d, %s\n", u4MaxBufferLen + (nsize - nleft), u4MaxBufferLen, p); -+ return WLAN_STATUS_INVALID_LENGTH; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl set int handler. -+* -+* \param[in] prNetDev Net device requested. -+* \param[in] prIwReqInfo Pointer to iwreq structure. -+* \param[in] prIwReqData The ioctl data structure, use the field of sub-command. -+* \param[in] pcExtra The buffer with input value -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EINVAL If a value is out of range. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_set_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ UINT_32 u4SubCmd; -+ PUINT_32 pu4IntBuf; -+ P_NDIS_TRANSPORT_STRUCT prNdisReq; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4BufLen = 0; -+ int status = 0; -+ P_PTA_IPC_T prPtaIpc; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqInfo); -+ ASSERT(prIwReqData); -+ ASSERT(pcExtra); -+ -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ u4SubCmd = (UINT_32) prIwReqData->mode; -+ pu4IntBuf = (PUINT_32) pcExtra; -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_TEST_MODE: -+ /* printk("TestMode=%ld\n", pu4IntBuf[1]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY) { -+ prNdisReq->ndisOidCmd = OID_CUSTOM_TEST_MODE; -+ } else if (pu4IntBuf[1] == 0) { -+ prNdisReq->ndisOidCmd = OID_CUSTOM_ABORT_TEST_MODE; -+ } else { -+ status = 0; -+ break; -+ } -+ prNdisReq->inNdisOidlength = 0; -+ prNdisReq->outNdisOidLength = 0; -+ -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); -+ break; -+ -+ case PRIV_CMD_TEST_CMD: -+ /* printk("CMD=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_MTK_WIFI_TEST; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); -+ break; -+ -+#if CFG_SUPPORT_PRIV_MCR_RW -+ case PRIV_CMD_ACCESS_MCR: -+ /* printk("addr=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ if (!prGlueInfo->fgMcrAccessAllowed) { -+ if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY && pu4IntBuf[2] == PRIV_CMD_TEST_MAGIC_KEY) -+ prGlueInfo->fgMcrAccessAllowed = TRUE; -+ status = 0; -+ break; -+ } -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_MCR_RW; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); -+ break; -+#endif -+ -+ case PRIV_CMD_SW_CTRL: -+ /* printk("addr=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); -+ break; -+ -+#if 0 -+ case PRIV_CMD_BEACON_PERIOD: -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetBeaconInterval, -+ (PVOID)&pu4IntBuf[1],/* pu4IntBuf[0] is used as input SubCmd */ -+ sizeof(UINT_32), &u4BufLen); -+ break; -+#endif -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ case PRIV_CMD_CSUM_OFFLOAD: -+ { -+ UINT_32 u4CSUMFlags; -+ -+ if (pu4IntBuf[1] == 1) -+ u4CSUMFlags = CSUM_OFFLOAD_EN_ALL; -+ else if (pu4IntBuf[1] == 0) -+ u4CSUMFlags = 0; -+ else -+ return -EINVAL; -+ -+ if (kalIoctl(prGlueInfo, -+ wlanoidSetCSUMOffload, -+ (PVOID)&u4CSUMFlags, -+ sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen) == WLAN_STATUS_SUCCESS) { -+ if (pu4IntBuf[1] == 1) -+ prNetDev->features |= NETIF_F_HW_CSUM; -+ else if (pu4IntBuf[1] == 0) -+ prNetDev->features &= ~NETIF_F_HW_CSUM; -+ } -+ } -+ break; -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+ case PRIV_CMD_POWER_MODE: -+ kalIoctl(prGlueInfo, wlanoidSet802dot11PowerSaveProfile, -+ (PVOID)&pu4IntBuf[1], /* pu4IntBuf[0] is used as input SubCmd */ -+ sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ break; -+ -+ case PRIV_CMD_WMM_PS: -+ { -+ PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T rWmmPsTest; -+ -+ rWmmPsTest.bmfgApsdEnAc = (UINT_8) pu4IntBuf[1]; -+ rWmmPsTest.ucIsEnterPsAtOnce = (UINT_8) pu4IntBuf[2]; -+ rWmmPsTest.ucIsDisableUcTrigger = (UINT_8) pu4IntBuf[3]; -+ rWmmPsTest.reserved = 0; -+ -+ kalIoctl(prGlueInfo, -+ wlanoidSetWiFiWmmPsTest, -+ (PVOID)&rWmmPsTest, -+ sizeof(PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ } -+ break; -+ -+#if 0 -+ case PRIV_CMD_ADHOC_MODE: -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetAdHocMode, -+ (PVOID)&pu4IntBuf[1], /* pu4IntBuf[0] is used as input SubCmd */ -+ sizeof(UINT_32), &u4BufLen); -+ break; -+#endif -+ -+ case PRIV_CUSTOM_BWCS_CMD: -+ -+ DBGLOG(REQ, INFO, "pu4IntBuf[1] = %x, size of PTA_IPC_T = %zu.\n", -+ pu4IntBuf[1], sizeof(PARAM_PTA_IPC_T)); -+ -+ prPtaIpc = (P_PTA_IPC_T) aucOidBuf; -+ prPtaIpc->u.aucBTPParams[0] = (UINT_8) (pu4IntBuf[1] >> 24); -+ prPtaIpc->u.aucBTPParams[1] = (UINT_8) (pu4IntBuf[1] >> 16); -+ prPtaIpc->u.aucBTPParams[2] = (UINT_8) (pu4IntBuf[1] >> 8); -+ prPtaIpc->u.aucBTPParams[3] = (UINT_8) (pu4IntBuf[1]); -+ -+ DBGLOG(REQ, INFO, -+ "BCM BWCS CMD : BTPParams[0]=%02x, BTPParams[1]=%02x, BTPParams[2]=%02x, BTPParams[3]=%02x.\n", -+ prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], prPtaIpc->u.aucBTPParams[2], -+ prPtaIpc->u.aucBTPParams[3]); -+ -+#if 0 -+ status = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetBT, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); -+#endif -+ -+ status = wlanoidSetBT(prGlueInfo->prAdapter, -+ (PVOID)&aucOidBuf[0], sizeof(PARAM_PTA_IPC_T), &u4BufLen); -+ -+ if (WLAN_STATUS_SUCCESS != status) -+ status = -EFAULT; -+ -+ break; -+ -+ case PRIV_CMD_BAND_CONFIG: -+ { -+ DBGLOG(REQ, INFO, "CMD set_band=%u\n", (UINT_32) pu4IntBuf[1]); -+ } -+ break; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ case PRIV_CMD_P2P_MODE: -+ { -+ /* no use, move to set_p2p_mode_handler() */ -+ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; -+ -+ p2pmode.u4Enable = pu4IntBuf[1]; -+ p2pmode.u4Mode = pu4IntBuf[2]; -+ set_p2p_mode_handler(prNetDev, p2pmode); -+#if 0 -+ PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ BOOLEAN fgIsP2PEnding; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ /* avoid remove & p2p off command simultaneously */ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ fgIsP2PEnding = g_u4P2PEnding; -+ g_u4P2POnOffing = 1; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ -+ if (fgIsP2PEnding == 1) { -+ /* skip the command if we are removing */ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2POnOffing = 0; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ break; -+ } -+ rSetP2P.u4Enable = pu4IntBuf[1]; -+ rSetP2P.u4Mode = pu4IntBuf[2]; -+ -+ if (!rSetP2P.u4Enable) -+ p2pNetUnregister(prGlueInfo, TRUE); -+ -+ /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */ -+ /* -+ Scenario: -+ 1. System enters suspend/resume but not yet enter wlanearlysuspend() -+ or wlanlateresume(); -+ -+ 2. System switches to do PRIV_CMD_P2P_MODE and execute kalIoctl() -+ and get g_halt_sem then do glRegisterEarlySuspend() or -+ glUnregisterEarlySuspend(); -+ -+ But system suspend/resume procedure is not yet finished so we -+ suspend; -+ -+ 3. System switches back to do suspend/resume procedure and execute -+ kalIoctl(). But driver does not yet release g_halt_sem so system -+ suspend in wlanearlysuspend() or wlanlateresume(); -+ -+ ==> deadlock occurs. -+ */ -+ if ((!rSetP2P.u4Enable) && (g_u4HaltFlag == 0) && (fgIsResetting == FALSE)) { -+ /* fgIsP2PRegistered == TRUE means P2P is enabled */ -+ DBGLOG(P2P, INFO, "p2pEalySuspendReg\n"); -+ p2pEalySuspendReg(prGlueInfo, rSetP2P.u4Enable); /* p2p remove */ -+ } -+ -+ DBGLOG(P2P, INFO, -+ "wlanoidSetP2pMode 0x%p %d %d\n", &rSetP2P, rSetP2P.u4Enable, rSetP2P.u4Mode); -+ rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, -+ (PVOID)&rSetP2P, /* pu4IntBuf[0] is used as input SubCmd */ -+ sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), -+ FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ DBGLOG(P2P, INFO, "wlanoidSetP2pMode ok\n"); -+ -+ /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */ -+ if ((rSetP2P.u4Enable) && (g_u4HaltFlag == 0) && (fgIsResetting == FALSE)) { -+ /* fgIsP2PRegistered == TRUE means P2P on successfully */ -+ p2pEalySuspendReg(prGlueInfo, rSetP2P.u4Enable); /* p2p on */ -+ } -+ -+ if (rSetP2P.u4Enable) -+ p2pNetRegister(prGlueInfo, TRUE); -+ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2POnOffing = 0; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+#endif -+ } -+ break; -+#endif -+ -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ case PRIV_CMD_MET_PROFILING: -+ { -+ /* PARAM_CUSTOM_WFD_DEBUG_STRUCT_T rWfdDebugModeInfo; */ -+ /* rWfdDebugModeInfo.ucWFDDebugMode=(UINT_8)pu4IntBuf[1]; */ -+ /* rWfdDebugModeInfo.u2SNPeriod=(UINT_16)pu4IntBuf[2]; */ -+ /* DBGLOG(REQ, INFO,("WFD Debug Mode:%d Period:%d\n", -+ rWfdDebugModeInfo.ucWFDDebugMode,rWfdDebugModeInfo.u2SNPeriod)); */ -+ prGlueInfo->u8MetProfEnable = (UINT_8) pu4IntBuf[1]; -+ prGlueInfo->u16MetUdpPort = (UINT_16) pu4IntBuf[2]; -+ DBGLOG(REQ, INFO, "MET_PROF: Enable=%d UDP_PORT=%d\n", prGlueInfo->u8MetProfEnable, -+ prGlueInfo->u16MetUdpPort); -+ -+ } -+ break; -+ -+#endif -+ case PRIV_CMD_WFD_DEBUG_CODE: -+ { -+ PARAM_CUSTOM_WFD_DEBUG_STRUCT_T rWfdDebugModeInfo; -+ -+ rWfdDebugModeInfo.ucWFDDebugMode = (UINT_8) pu4IntBuf[1]; -+ rWfdDebugModeInfo.u2SNPeriod = (UINT_16) pu4IntBuf[2]; -+ DBGLOG(REQ, INFO, "WFD Debug Mode:%d Period:%d\n", rWfdDebugModeInfo.ucWFDDebugMode, -+ rWfdDebugModeInfo.u2SNPeriod); -+ kalIoctl(prGlueInfo, wlanoidSetWfdDebugMode, (PVOID)&rWfdDebugModeInfo, -+ sizeof(PARAM_CUSTOM_WFD_DEBUG_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ } -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl get int handler. -+* -+* \param[in] pDev Net device requested. -+* \param[out] pIwReq Pointer to iwreq structure. -+* \param[in] prIwReqData The ioctl req structure, use the field of sub-command. -+* \param[out] pcExtra The buffer with put the return value -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EFAULT For fail. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 gucBufDbgCode[1000]; -+ -+static int -+_priv_get_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ UINT_32 u4SubCmd; -+ PUINT_32 pu4IntBuf; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4BufLen = 0; -+ int status = 0; -+ P_NDIS_TRANSPORT_STRUCT prNdisReq; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqInfo); -+ ASSERT(prIwReqData); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ u4SubCmd = (UINT_32) prIwReqData->mode; -+ pu4IntBuf = (PUINT_32) pcExtra; -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_TEST_CMD: -+ /* printk("CMD=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_MTK_WIFI_TEST; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); -+ if (status == 0) { -+ /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ -+ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4]; -+ /* -+ if (copy_to_user(prIwReqData->data.pointer, -+ &prNdisReq->ndisOidContent[4], 4)) { -+ printk(KERN_NOTICE "priv_get_int() copy_to_user oidBuf fail(3)\n"); -+ return -EFAULT; -+ } -+ */ -+ } -+ return status; -+ -+#if CFG_SUPPORT_PRIV_MCR_RW -+ case PRIV_CMD_ACCESS_MCR: -+ /* printk("addr=0x%08lx\n", pu4IntBuf[1]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ if (!prGlueInfo->fgMcrAccessAllowed) { -+ status = 0; -+ return status; -+ } -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_MCR_RW; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); -+ if (status == 0) { -+ /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ -+ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4]; -+ } -+ return status; -+#endif -+ -+ case PRIV_CMD_DUMP_MEM: -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+#if 1 -+ if (!prGlueInfo->fgMcrAccessAllowed) { -+ status = 0; -+ return status; -+ } -+#endif -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_MEM_DUMP; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); -+ if (status == 0) -+ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[0]; -+ return status; -+ -+ case PRIV_CMD_SW_CTRL: -+ /* printk(" addr=0x%08lx\n", pu4IntBuf[1]); */ -+ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); -+ if (status == 0) { -+ /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ -+ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4]; -+ } -+ return status; -+ -+#if 0 -+ case PRIV_CMD_BEACON_PERIOD: -+ status = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryBeaconInterval, -+ (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen); -+ return status; -+ -+ case PRIV_CMD_POWER_MODE: -+ status = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQuery802dot11PowerSaveProfile, -+ (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen); -+ return status; -+ -+ case PRIV_CMD_ADHOC_MODE: -+ status = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryAdHocMode, (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen); -+ return status; -+#endif -+ -+ case PRIV_CMD_BAND_CONFIG: -+ DBGLOG(REQ, INFO, "CMD get_band=\n"); -+ prIwReqData->mode = 0; -+ return status; -+ -+ default: -+ break; -+ } -+ -+ u4SubCmd = (UINT_32) prIwReqData->data.flags; -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_GET_CH_LIST: -+ { -+ UINT_16 i, j = 0; -+ UINT_8 NumOfChannel = 50; -+ UINT_8 ucMaxChannelNum = 50; -+ INT_32 ch[50]; -+ /*RF_CHANNEL_INFO_T aucChannelList[50];*/ -+ P_RF_CHANNEL_INFO_T paucChannelList; -+ P_RF_CHANNEL_INFO_T ChannelList_t; -+ -+ paucChannelList = kalMemAlloc(sizeof(RF_CHANNEL_INFO_T) * 50, VIR_MEM_TYPE); -+ if (paucChannelList == NULL) { -+ DBGLOG(REQ, INFO, "alloc ChannelList fail\n"); -+ return -EFAULT; -+ } -+ kalMemZero(paucChannelList, sizeof(RF_CHANNEL_INFO_T) * 50); -+ kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, paucChannelList); -+ if (NumOfChannel > 50) { -+ ASSERT(0); -+ NumOfChannel = 50; -+ } -+ -+ ChannelList_t = paucChannelList; -+ if (kalIsAPmode(prGlueInfo)) { -+ for (i = 0; i < NumOfChannel; i++) { -+ if ((ChannelList_t->ucChannelNum <= 13) -+ || (ChannelList_t->ucChannelNum == 36 -+ || ChannelList_t->ucChannelNum == 40 -+ || ChannelList_t->ucChannelNum == 44 -+ || ChannelList_t->ucChannelNum == 48)) { -+ ch[j] = (INT_32) ChannelList_t->ucChannelNum; -+ ChannelList_t++; -+ j++; -+ } -+ } -+ } else { -+ for (j = 0; j < NumOfChannel; j++) { -+ ch[j] = (INT_32) ChannelList_t->ucChannelNum; -+ ChannelList_t++; -+ } -+ } -+ -+ kalMemFree(paucChannelList, VIR_MEM_TYPE, sizeof(RF_CHANNEL_INFO_T) * 50); -+ -+ prIwReqData->data.length = j; -+ if (copy_to_user(prIwReqData->data.pointer, ch, NumOfChannel * sizeof(INT_32))) -+ return -EFAULT; -+ else -+ return status; -+ } -+ -+ case PRIV_CMD_GET_BUILD_DATE_CODE: -+ { -+ UINT_8 aucBuffer[16]; -+ -+ if (kalIoctl(prGlueInfo, -+ wlanoidQueryBuildDateCode, -+ (PVOID) aucBuffer, -+ sizeof(UINT_8) * 16, TRUE, TRUE, TRUE, FALSE, &u4BufLen) == WLAN_STATUS_SUCCESS) { -+ prIwReqData->data.length = sizeof(UINT_8) * 16; -+ -+ if (copy_to_user(prIwReqData->data.pointer, aucBuffer, prIwReqData->data.length)) -+ return -EFAULT; -+ else -+ return status; -+ } else { -+ return -EFAULT; -+ } -+ } -+ -+ case PRIV_CMD_GET_DEBUG_CODE: -+ { -+ wlanQueryDebugCode(prGlueInfo->prAdapter); -+ -+ kalMemSet(gucBufDbgCode, '.', sizeof(gucBufDbgCode)); -+ if (copy_to_user(prIwReqData->data.pointer, gucBufDbgCode, prIwReqData->data.length)) -+ return -EFAULT; -+ else -+ return status; -+ } -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return status; -+} /* priv_get_int */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl set int array handler. -+* -+* \param[in] prNetDev Net device requested. -+* \param[in] prIwReqInfo Pointer to iwreq structure. -+* \param[in] prIwReqData The ioctl data structure, use the field of sub-command. -+* \param[in] pcExtra The buffer with input value -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EINVAL If a value is out of range. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_set_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ UINT_32 u4SubCmd, u4BufLen; -+ P_GLUE_INFO_T prGlueInfo; -+ int status = 0; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_SET_TXPWR_CTRL_T prTxpwr; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqInfo); -+ ASSERT(prIwReqData); -+ ASSERT(pcExtra); -+ -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ u4SubCmd = (UINT_32) prIwReqData->data.flags; -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_SET_TX_POWER: -+ { -+ INT_32 *setting = prIwReqData->data.pointer; -+ UINT_16 i; -+ -+#if 0 -+ DBGLOG(REQ, INFO, "Tx power num = %d\n", prIwReqData->data.length); -+ -+ DBGLOG(REQ, INFO, "Tx power setting = %d %d %d %d\n", -+ setting[0], setting[1], setting[2], setting[3]); -+#endif -+ prTxpwr = &prGlueInfo->rTxPwr; -+ if (setting[0] == 0 && prIwReqData->data.length == 4 /* argc num */) { -+ /* 0 (All networks), 1 (legacy STA), 2 (Hotspot AP), 3 (P2P), 4 (BT over Wi-Fi) */ -+ if (setting[1] == 1 || setting[1] == 0) { -+ if (setting[2] == 0 || setting[2] == 1) -+ prTxpwr->c2GLegacyStaPwrOffset = setting[3]; -+ if (setting[2] == 0 || setting[2] == 2) -+ prTxpwr->c5GLegacyStaPwrOffset = setting[3]; -+ } -+ if (setting[1] == 2 || setting[1] == 0) { -+ if (setting[2] == 0 || setting[2] == 1) -+ prTxpwr->c2GHotspotPwrOffset = setting[3]; -+ if (setting[2] == 0 || setting[2] == 2) -+ prTxpwr->c5GHotspotPwrOffset = setting[3]; -+ } -+ if (setting[1] == 3 || setting[1] == 0) { -+ if (setting[2] == 0 || setting[2] == 1) -+ prTxpwr->c2GP2pPwrOffset = setting[3]; -+ if (setting[2] == 0 || setting[2] == 2) -+ prTxpwr->c5GP2pPwrOffset = setting[3]; -+ } -+ if (setting[1] == 4 || setting[1] == 0) { -+ if (setting[2] == 0 || setting[2] == 1) -+ prTxpwr->c2GBowPwrOffset = setting[3]; -+ if (setting[2] == 0 || setting[2] == 2) -+ prTxpwr->c5GBowPwrOffset = setting[3]; -+ } -+ } else if (setting[0] == 1 && prIwReqData->data.length == 2) { -+ prTxpwr->ucConcurrencePolicy = setting[1]; -+ } else if (setting[0] == 2 && prIwReqData->data.length == 3) { -+ if (setting[1] == 0) { -+ for (i = 0; i < 14; i++) -+ prTxpwr->acTxPwrLimit2G[i] = setting[2]; -+ } else if (setting[1] <= 14) -+ prTxpwr->acTxPwrLimit2G[setting[1] - 1] = setting[2]; -+ } else if (setting[0] == 3 && prIwReqData->data.length == 3) { -+ if (setting[1] == 0) { -+ for (i = 0; i < 4; i++) -+ prTxpwr->acTxPwrLimit5G[i] = setting[2]; -+ } else if (setting[1] <= 4) -+ prTxpwr->acTxPwrLimit5G[setting[1] - 1] = setting[2]; -+ } else if (setting[0] == 4 && prIwReqData->data.length == 2) { -+ if (setting[1] == 0) -+ wlanDefTxPowerCfg(prGlueInfo->prAdapter); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetTxPower, -+ prTxpwr, -+ sizeof(SET_TXPWR_CTRL_T), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ } else -+ return -EFAULT; -+ } -+ return status; -+ default: -+ break; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl get int array handler. -+* -+* \param[in] pDev Net device requested. -+* \param[out] pIwReq Pointer to iwreq structure. -+* \param[in] prIwReqData The ioctl req structure, use the field of sub-command. -+* \param[out] pcExtra The buffer with put the return value -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EFAULT For fail. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_get_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ UINT_32 u4SubCmd; -+ P_GLUE_INFO_T prGlueInfo; -+ int status = 0; -+ INT_32 ch[50]; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqInfo); -+ ASSERT(prIwReqData); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ u4SubCmd = (UINT_32) prIwReqData->data.flags; -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_GET_CH_LIST: -+ { -+ UINT_16 i; -+ UINT_8 NumOfChannel = 50; -+ UINT_8 ucMaxChannelNum = 50; -+ /*RF_CHANNEL_INFO_T aucChannelList[50];*/ -+ P_RF_CHANNEL_INFO_T paucChannelList; -+ P_RF_CHANNEL_INFO_T ChannelList_t; -+ -+ paucChannelList = kalMemAlloc(sizeof(RF_CHANNEL_INFO_T) * 50, VIR_MEM_TYPE); -+ if (paucChannelList == NULL) { -+ DBGLOG(REQ, INFO, "alloc fail\n"); -+ return -EINVAL; -+ } -+ kalMemZero(paucChannelList, sizeof(RF_CHANNEL_INFO_T) * 50); -+ -+ kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, paucChannelList); -+ if (NumOfChannel > 50) -+ NumOfChannel = 50; -+ -+ ChannelList_t = paucChannelList; -+ for (i = 0; i < NumOfChannel; i++) { -+ ch[i] = (INT_32) ChannelList_t->ucChannelNum; -+ ChannelList_t++; -+ } -+ -+ kalMemFree(paucChannelList, VIR_MEM_TYPE, sizeof(RF_CHANNEL_INFO_T) * 50); -+ prIwReqData->data.length = NumOfChannel; -+ if (copy_to_user(prIwReqData->data.pointer, ch, NumOfChannel * sizeof(INT_32))) -+ return -EFAULT; -+ else -+ return status; -+ } -+ default: -+ break; -+ } -+ -+ return status; -+} /* priv_get_int */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl set structure handler. -+* -+* \param[in] pDev Net device requested. -+* \param[in] prIwReqData Pointer to iwreq_data structure. -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EINVAL If a value is out of range. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_set_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ UINT_32 u4SubCmd = 0; -+ int status = 0; -+ /* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */ -+ UINT_32 u4CmdLen = 0; -+ P_NDIS_TRANSPORT_STRUCT prNdisReq; -+ PUINT_32 pu4IntBuf = NULL; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ /* ASSERT(prIwReqInfo); */ -+ ASSERT(prIwReqData); -+ /* ASSERT(pcExtra); */ -+ -+ kalMemZero(&aucOidBuf[0], sizeof(aucOidBuf)); -+ -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prIwReqData)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ u4SubCmd = (UINT_32) prIwReqData->data.flags; -+ -+#if 0 -+ DBGLOG(REQ, INFO, "priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n", -+ prIwReqInfo->cmd, u4SubCmd); -+#endif -+ -+ switch (u4SubCmd) { -+#if 0 /* PTA_ENABLED */ -+ case PRIV_CMD_BT_COEXIST: -+ u4CmdLen = prIwReqData->data.length * sizeof(UINT_32); -+ ASSERT(sizeof(PARAM_CUSTOM_BT_COEXIST_T) >= u4CmdLen); -+ if (sizeof(PARAM_CUSTOM_BT_COEXIST_T) < u4CmdLen) -+ return -EFAULT; -+ -+ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) { -+ status = -EFAULT; /* return -EFAULT; */ -+ break; -+ } -+ -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetBtCoexistCtrl, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); -+ if (WLAN_STATUS_SUCCESS != rStatus) -+ status = -EFAULT; -+ break; -+#endif -+ -+ case PRIV_CUSTOM_BWCS_CMD: -+ u4CmdLen = prIwReqData->data.length * sizeof(UINT_32); -+ ASSERT(sizeof(PARAM_PTA_IPC_T) >= u4CmdLen); -+ if (sizeof(PARAM_PTA_IPC_T) < u4CmdLen) -+ return -EFAULT; -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG -+ DBGLOG(REQ, INFO, -+ "ucCmdLen = %d, size of PTA_IPC_T = %d, prIwReqData->data = 0x%x.\n", u4CmdLen, -+ sizeof(PARAM_PTA_IPC_T), prIwReqData->data); -+ -+ DBGLOG(REQ, INFO, "priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%u)\n", -+ prIwReqInfo->cmd, u4SubCmd); -+ -+ DBGLOG(REQ, INFO, "*pcExtra = 0x%x\n", *pcExtra); -+#endif -+ -+ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) { -+ status = -EFAULT; /* return -EFAULT; */ -+ break; -+ } -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG -+ DBGLOG(REQ, INFO, "priv_set_struct(): BWCS CMD = %02x%02x%02x%02x\n", -+ aucOidBuf[2], aucOidBuf[3], aucOidBuf[4], aucOidBuf[5]); -+#endif -+ -+#if 0 -+ status = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetBT, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); -+#endif -+ -+#if 1 -+ status = wlanoidSetBT(prGlueInfo->prAdapter, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); -+#endif -+ -+ if (WLAN_STATUS_SUCCESS != status) -+ status = -EFAULT; -+ -+ break; -+ -+#if CFG_SUPPORT_WPS2 -+ case PRIV_CMD_WSC_PROBE_REQ: -+ { -+ /* retrieve IE for Probe Request */ -+ if (prIwReqData->data.length > 0) { -+ if (copy_from_user(prGlueInfo->aucWSCIE, prIwReqData->data.pointer, -+ prIwReqData->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ prGlueInfo->u2WSCIELen = prIwReqData->data.length; -+ } else { -+ prGlueInfo->u2WSCIELen = 0; -+ } -+ } -+ break; -+#endif -+ case PRIV_CMD_OID: -+ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, prIwReqData->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ if (!kalMemCmp(&aucOidBuf[0], pcExtra, prIwReqData->data.length)) -+ DBGLOG(REQ, INFO, "pcExtra buffer is valid\n"); -+ else -+ DBGLOG(REQ, INFO, "pcExtra 0x%p\n", pcExtra); -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0], &u4BufLen); -+ /* Copy result to user space */ -+ ((P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0])->outNdisOidLength = u4BufLen; -+ -+ if (copy_to_user(prIwReqData->data.pointer, -+ &aucOidBuf[0], OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent))) { -+ DBGLOG(REQ, INFO, "copy_to_user oidBuf fail\n"); -+ status = -EFAULT; -+ } -+ -+ break; -+ -+ case PRIV_CMD_SW_CTRL: -+ pu4IntBuf = (PUINT_32) prIwReqData->data.pointer; -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ /* kalMemCopy(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, 8); */ -+ if (copy_from_user(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, -+ prIwReqData->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); -+ break; -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl get struct handler. -+* -+* \param[in] pDev Net device requested. -+* \param[out] pIwReq Pointer to iwreq structure. -+* \param[in] cmd Private sub-command. -+* -+* \retval 0 For success. -+* \retval -EFAULT If copy from user space buffer fail. -+* \retval -EOPNOTSUPP Parameter "cmd" not recognized. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_get_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ UINT_32 u4SubCmd = 0; -+ P_NDIS_TRANSPORT_STRUCT prNdisReq = NULL; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 u4BufLen = 0; -+ PUINT_32 pu4IntBuf = NULL; -+ int status = 0; -+ -+ kalMemZero(&aucOidBuf[0], sizeof(aucOidBuf)); -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqData); -+ if (!prNetDev || !prIwReqData) { -+ DBGLOG(REQ, INFO, "priv_get_struct(): invalid param(0x%p, 0x%p)\n", prNetDev, prIwReqData); -+ return -EINVAL; -+ } -+ -+ u4SubCmd = (UINT_32) prIwReqData->data.flags; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ ASSERT(prGlueInfo); -+ if (!prGlueInfo) { -+ DBGLOG(REQ, INFO, "priv_get_struct(): invalid prGlueInfo(0x%p, 0x%p)\n", -+ prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))); -+ return -EINVAL; -+ } -+#if 0 -+ DBGLOG(REQ, INFO, "priv_get_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n", -+ prIwReqInfo->cmd, u4SubCmd); -+#endif -+ memset(aucOidBuf, 0, sizeof(aucOidBuf)); -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_OID: -+ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, sizeof(NDIS_TRANSPORT_STRUCT))) { -+ DBGLOG(REQ, INFO, "priv_get_struct() copy_from_user oidBuf fail\n"); -+ return -EFAULT; -+ } -+ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+#if 0 -+ DBGLOG(REQ, INFO, "\n priv_get_struct cmd 0x%02x len:%d OID:0x%08x OID Len:%d\n", -+ cmd, pIwReq->u.data.length, ndisReq->ndisOidCmd, ndisReq->inNdisOidlength); -+#endif -+ if (priv_get_ndis(prNetDev, prNdisReq, &u4BufLen) == 0) { -+ prNdisReq->outNdisOidLength = u4BufLen; -+ if (copy_to_user(prIwReqData->data.pointer, -+ &aucOidBuf[0], -+ u4BufLen + sizeof(NDIS_TRANSPORT_STRUCT) - -+ sizeof(prNdisReq->ndisOidContent))) { -+ DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(1)\n"); -+ return -EFAULT; -+ } -+ return 0; -+ } -+ prNdisReq->outNdisOidLength = u4BufLen; -+ if (copy_to_user(prIwReqData->data.pointer, -+ &aucOidBuf[0], OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent))) { -+ DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(2)\n"); -+ } -+ return -EFAULT; -+ -+ case PRIV_CMD_SW_CTRL: -+ pu4IntBuf = (PUINT_32) prIwReqData->data.pointer; -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ if (copy_from_user(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, -+ prIwReqData->data.length)) { -+ DBGLOG(REQ, INFO, "priv_get_struct() copy_from_user oidBuf fail\n"); -+ return -EFAULT; -+ } -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); -+ if (status == 0) { -+ prNdisReq->outNdisOidLength = u4BufLen; -+ /* printk("len=%d Result=%08lx\n", u4BufLen, *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ -+ -+ if (copy_to_user(prIwReqData->data.pointer, -+ &prNdisReq->ndisOidContent[4], -+ 4 /* OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent) */)) { -+ DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(2)\n"); -+ } -+ } -+ return 0; -+ -+ default: -+ DBGLOG(REQ, WARN, "get struct cmd:0x%x\n", u4SubCmd); -+ return -EOPNOTSUPP; -+ } -+} /* priv_get_struct */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The routine handles a set operation for a single OID. -+* -+* \param[in] pDev Net device requested. -+* \param[in] ndisReq Ndis request OID information copy from user. -+* \param[out] outputLen_p If the call is successful, returns the number of -+* bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed.. -+* -+* \retval 0 On success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+priv_set_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen) -+{ -+ P_WLAN_REQ_ENTRY prWlanReqEntry = NULL; -+ WLAN_STATUS status = WLAN_STATUS_SUCCESS; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 u4SetInfoLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prNdisReq); -+ ASSERT(pu4OutputLen); -+ -+ if (!prNetDev || !prNdisReq || !pu4OutputLen) { -+ DBGLOG(REQ, INFO, "priv_set_ndis(): invalid param(0x%p, 0x%p, 0x%p)\n", -+ prNetDev, prNdisReq, pu4OutputLen); -+ return -EINVAL; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ ASSERT(prGlueInfo); -+ if (!prGlueInfo) { -+ DBGLOG(REQ, INFO, "priv_set_ndis(): invalid prGlueInfo(0x%p, 0x%p)\n", -+ prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))); -+ return -EINVAL; -+ } -+#if 0 -+ DBGLOG(REQ, INFO, "priv_set_ndis(): prNdisReq->ndisOidCmd(0x%lX)\n", prNdisReq->ndisOidCmd); -+#endif -+ -+ if (FALSE == reqSearchSupportedOidEntry(prNdisReq->ndisOidCmd, &prWlanReqEntry)) { -+ /* WARNLOG(("Set OID: 0x%08lx (unknown)\n", prNdisReq->ndisOidCmd)); */ -+ return -EOPNOTSUPP; -+ } -+ -+ if (NULL == prWlanReqEntry->pfOidSetHandler) { -+ /* WARNLOG(("Set %s: Null set handler\n", prWlanReqEntry->pucOidName)); */ -+ return -EOPNOTSUPP; -+ } -+#if 0 -+ DBGLOG(REQ, INFO, "priv_set_ndis(): %s\n", prWlanReqEntry->pucOidName); -+#endif -+ -+ if (prWlanReqEntry->fgSetBufLenChecking) { -+ if (prNdisReq->inNdisOidlength != prWlanReqEntry->u4InfoBufLen) { -+ DBGLOG(REQ, WARN, "Set %s: Invalid length (current=%u, needed=%u)\n", -+ prWlanReqEntry->pucOidName, -+ prNdisReq->inNdisOidlength, prWlanReqEntry->u4InfoBufLen); -+ -+ *pu4OutputLen = prWlanReqEntry->u4InfoBufLen; -+ return -EINVAL; -+ } -+ } -+ -+ if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_ONLY) { -+ /* GLUE sw info only */ -+ status = prWlanReqEntry->pfOidSetHandler(prGlueInfo, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, &u4SetInfoLen); -+ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_EXTENSION) { -+ /* multiple sw operations */ -+ status = prWlanReqEntry->pfOidSetHandler(prGlueInfo, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, &u4SetInfoLen); -+ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_DRIVER_CORE) { -+ /* driver core */ -+ -+ status = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC) prWlanReqEntry->pfOidSetHandler, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ } else { -+ DBGLOG(REQ, INFO, "priv_set_ndis(): unsupported OID method:0x%x\n", prWlanReqEntry->eOidMethod); -+ return -EOPNOTSUPP; -+ } -+ -+ *pu4OutputLen = u4SetInfoLen; -+ -+ switch (status) { -+ case WLAN_STATUS_SUCCESS: -+ break; -+ -+ case WLAN_STATUS_INVALID_LENGTH: -+ /* WARNLOG(("Set %s: Invalid length (current=%ld, needed=%ld)\n", */ -+ /* prWlanReqEntry->pucOidName, */ -+ /* prNdisReq->inNdisOidlength, */ -+ /* u4SetInfoLen)); */ -+ break; -+ } -+ -+ if (WLAN_STATUS_SUCCESS != status) -+ return -EFAULT; -+ -+ return 0; -+} /* priv_set_ndis */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The routine handles a query operation for a single OID. Basically we -+* return information about the current state of the OID in question. -+* -+* \param[in] pDev Net device requested. -+* \param[in] ndisReq Ndis request OID information copy from user. -+* \param[out] outputLen_p If the call is successful, returns the number of -+* bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed.. -+* -+* \retval 0 On success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EINVAL invalid input parameters -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+priv_get_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen) -+{ -+ P_WLAN_REQ_ENTRY prWlanReqEntry = NULL; -+ UINT_32 u4BufLen = 0; -+ WLAN_STATUS status = WLAN_STATUS_SUCCESS; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prNetDev); -+ ASSERT(prNdisReq); -+ ASSERT(pu4OutputLen); -+ -+ if (!prNetDev || !prNdisReq || !pu4OutputLen) { -+ DBGLOG(REQ, INFO, "priv_get_ndis(): invalid param(0x%p, 0x%p, 0x%p)\n", -+ prNetDev, prNdisReq, pu4OutputLen); -+ return -EINVAL; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ ASSERT(prGlueInfo); -+ if (!prGlueInfo) { -+ DBGLOG(REQ, INFO, "priv_get_ndis(): invalid prGlueInfo(0x%p, 0x%p)\n", -+ prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))); -+ return -EINVAL; -+ } -+#if 0 -+ DBGLOG(REQ, INFO, "priv_get_ndis(): prNdisReq->ndisOidCmd(0x%lX)\n", prNdisReq->ndisOidCmd); -+#endif -+ -+ if (FALSE == reqSearchSupportedOidEntry(prNdisReq->ndisOidCmd, &prWlanReqEntry)) { -+ /* WARNLOG(("Query OID: 0x%08lx (unknown)\n", prNdisReq->ndisOidCmd)); */ -+ return -EOPNOTSUPP; -+ } -+ -+ if (NULL == prWlanReqEntry->pfOidQueryHandler) { -+ /* WARNLOG(("Query %s: Null query handler\n", prWlanReqEntry->pucOidName)); */ -+ return -EOPNOTSUPP; -+ } -+#if 0 -+ DBGLOG(REQ, INFO, "priv_get_ndis(): %s\n", prWlanReqEntry->pucOidName); -+#endif -+ -+ if (prWlanReqEntry->fgQryBufLenChecking) { -+ if (prNdisReq->inNdisOidlength < prWlanReqEntry->u4InfoBufLen) { -+ /* Not enough room in InformationBuffer. Punt */ -+ /* WARNLOG(("Query %s: Buffer too short (current=%ld, needed=%ld)\n", */ -+ /* prWlanReqEntry->pucOidName, */ -+ /* prNdisReq->inNdisOidlength, */ -+ /* prWlanReqEntry->u4InfoBufLen)); */ -+ -+ *pu4OutputLen = prWlanReqEntry->u4InfoBufLen; -+ -+ status = WLAN_STATUS_INVALID_LENGTH; -+ return -EINVAL; -+ } -+ } -+ -+ if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_ONLY) { -+ /* GLUE sw info only */ -+ status = prWlanReqEntry->pfOidQueryHandler(prGlueInfo, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, &u4BufLen); -+ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_EXTENSION) { -+ /* multiple sw operations */ -+ status = prWlanReqEntry->pfOidQueryHandler(prGlueInfo, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, &u4BufLen); -+ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_DRIVER_CORE) { -+ /* driver core */ -+ -+ status = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC) prWlanReqEntry->pfOidQueryHandler, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ } else { -+ DBGLOG(REQ, INFO, "priv_set_ndis(): unsupported OID method:0x%x\n", prWlanReqEntry->eOidMethod); -+ return -EOPNOTSUPP; -+ } -+ -+ *pu4OutputLen = u4BufLen; -+ -+ switch (status) { -+ case WLAN_STATUS_SUCCESS: -+ break; -+ -+ case WLAN_STATUS_INVALID_LENGTH: -+ /* WARNLOG(("Set %s: Invalid length (current=%ld, needed=%ld)\n", */ -+ /* prWlanReqEntry->pucOidName, */ -+ /* prNdisReq->inNdisOidlength, */ -+ /* u4BufLen)); */ -+ break; -+ } -+ -+ if (WLAN_STATUS_SUCCESS != status) -+ return -EOPNOTSUPP; -+ -+ return 0; -+} /* priv_get_ndis */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Parse command value in a string. -+* -+* @param InStr Pointer to the string buffer. -+* @param OutStr Pointer to the next command value. -+* @param OutLen Record the resident buffer length. -+* -+* @retval Command value. -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 CmdStringDecParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen) -+{ -+ unsigned char Charc, *Buf; -+ unsigned int Num; -+ int Maxloop; -+ int ReadId; -+ int TotalLen; -+ -+ /* init */ -+ Num = 0; -+ Maxloop = 0; -+ ReadId = 0; -+ Buf = (unsigned char *)InStr; -+ TotalLen = *OutLen; -+ *OutStr = Buf; -+ -+ /* sanity check */ -+ if (Buf[0] == 0x00) -+ return 0; -+ -+ /* check the value is decimal or hex */ -+ if ((Buf[ReadId] == 'x') || ((Buf[ReadId] == '0') && (Buf[ReadId + 1] == 'x'))) { -+ /* skip x or 0x */ -+ if (Buf[ReadId] == 'x') -+ ReadId++; -+ else -+ ReadId += 2; -+ -+ /* translate the hex number */ -+ while (Maxloop++ < 10) { -+ Charc = Buf[ReadId]; -+ if ((Charc >= 0x30) && (Charc <= 0x39)) -+ Charc -= 0x30; -+ else if ((Charc >= 'a') && (Charc <= 'f')) -+ Charc -= 'a'; -+ else if ((Charc >= 'A') && (Charc <= 'F')) -+ Charc -= 'A'; -+ else -+ break; /* exit the parsing */ -+ Num = Num * 16 + Charc + 10; -+ ReadId++; -+ TotalLen--; -+ } -+ } else { -+ /* translate the decimal number */ -+ while (Maxloop++ < 10) { -+ Charc = Buf[ReadId]; -+ if ((Charc < 0x30) || (Charc > 0x39)) -+ break; /* exit the parsing */ -+ Charc -= 0x30; -+ Num = Num * 10 + Charc; -+ ReadId++; -+ TotalLen--; -+ } -+ } -+ -+ if (Buf[ReadId] == 0x00) -+ *OutStr = &Buf[ReadId]; -+ else -+ *OutStr = &Buf[ReadId + 1]; /* skip the character: _ */ -+ -+ *OutLen = TotalLen - 1; /* skip the character: _ */ -+ return Num; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Parse command MAC address in a string. -+* -+* @param InStr Pointer to the string buffer. -+* @param OutStr Pointer to the next command value. -+* @param OutLen Record the resident buffer length. -+* -+* @retval Command value. -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 CmdStringMacParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen, OUT UINT_8 *OutMac) -+{ -+ unsigned char Charc, *Buf; -+ unsigned int Num; -+ int Maxloop; -+ int ReadId; -+ int TotalLen; -+ -+ /* init */ -+ Num = 0; -+ Maxloop = 0; -+ ReadId = 0; -+ Buf = (unsigned char *)InStr; -+ TotalLen = *OutLen; -+ *OutStr = Buf; -+ -+ /* sanity check */ -+ if (Buf[0] == 0x00) -+ return 0; -+ -+ /* parse MAC */ -+ while (Maxloop < 6) { -+ Charc = Buf[ReadId]; -+ if ((Charc >= 0x30) && (Charc <= 0x39)) -+ Charc -= 0x30; -+ else if ((Charc >= 'a') && (Charc <= 'f')) -+ Charc = Charc - 'a' + 10; -+ else if ((Charc >= 'A') && (Charc <= 'F')) -+ Charc = Charc - 'A' + 10; -+ else -+ return -1; /* error, exit the parsing */ -+ -+ Num = Charc; -+ ReadId++; -+ TotalLen--; -+ -+ Charc = Buf[ReadId]; -+ if ((Charc >= 0x30) && (Charc <= 0x39)) -+ Charc -= 0x30; -+ else if ((Charc >= 'a') && (Charc <= 'f')) -+ Charc = Charc - 'a' + 10; -+ else if ((Charc >= 'A') && (Charc <= 'F')) -+ Charc = Charc - 'A' + 10; -+ else -+ return -1; /* error, exit the parsing */ -+ -+ Num = Num * 16 + Charc; -+ ReadId += 2; /* skip the character and ':' */ -+ TotalLen -= 2; -+ -+ OutMac[Maxloop] = Num; -+ Maxloop++; -+ } -+ -+ *OutStr = &Buf[ReadId]; /* skip the character: _ */ -+ *OutLen = TotalLen; /* skip the character: _ */ -+ return Num; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The routine handles a set operation for a single OID. -+* -+* \param[in] pDev Net device requested. -+* \param[in] ndisReq Ndis request OID information copy from user. -+* \param[out] outputLen_p If the call is successful, returns the number of -+* bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed.. -+* -+* \retval 0 On success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_set_string(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T GlueInfo; -+ INT_32 Status; -+ UINT_32 Subcmd; -+ UINT_8 *InBuf; -+ UINT_32 InBufLen; -+ -+ /* sanity check */ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqInfo); -+ ASSERT(prIwReqData); -+ ASSERT(pcExtra); -+ -+ /* init */ -+ DBGLOG(REQ, INFO, "priv_set_string (%s)(%d)\n", -+ (UINT8 *) prIwReqData->data.pointer, (INT32) prIwReqData->data.length); -+ -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) -+ return -EINVAL; -+ GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ InBuf = aucOidBuf; -+ InBufLen = prIwReqData->data.length; -+ Status = 0; -+ -+ if (copy_from_user(InBuf, prIwReqData->data.pointer, prIwReqData->data.length)) -+ return -EFAULT; -+ -+ Subcmd = CmdStringDecParse(prIwReqData->data.pointer, &InBuf, &InBufLen); -+ DBGLOG(REQ, INFO, "priv_set_string> command = %u\n", (UINT32) Subcmd); -+ -+ /* handle the command */ -+ switch (Subcmd) { -+#if (CFG_SUPPORT_TDLS == 1) -+ case PRIV_CMD_OTHER_TDLS: -+ TdlsexCmd(GlueInfo, InBuf, InBufLen); -+ break; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+#if (CFG_SUPPORT_TXR_ENC == 1) -+ case PRIV_CMD_OTHER_TAR: -+ { -+ rlmCmd(GlueInfo, InBuf, InBufLen); -+ break; -+ } -+#endif /* CFG_SUPPORT_TXR_ENC */ -+ default: -+ break; -+ } -+ -+ return Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to search desired OID. -+* -+* \param rOid[in] Desired NDIS_OID -+* \param ppWlanReqEntry[out] Found registered OID entry -+* -+* \retval TRUE: Matched OID is found -+* \retval FALSE: No matched OID is found -+*/ -+/*----------------------------------------------------------------------------*/ -+static BOOLEAN reqSearchSupportedOidEntry(IN UINT_32 rOid, OUT P_WLAN_REQ_ENTRY *ppWlanReqEntry) -+{ -+ INT_32 i, j, k; -+ -+ i = 0; -+ j = NUM_SUPPORTED_OIDS - 1; -+ -+ while (i <= j) { -+ k = (i + j) / 2; -+ -+ if (rOid == arWlanOidReqTable[k].rOid) { -+ *ppWlanReqEntry = &arWlanOidReqTable[k]; -+ return TRUE; -+ } else if (rOid < arWlanOidReqTable[k].rOid) { -+ j = k - 1; -+ } else { -+ i = k + 1; -+ } -+ } -+ -+ return FALSE; -+} /* reqSearchSupportedOidEntry */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the radio configuration used in IBSS -+* mode and RF test mode. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[out] pvQueryBuffer Pointer to the buffer that holds the result of the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+static WLAN_STATUS -+reqExtQueryConfiguration(IN P_GLUE_INFO_T prGlueInfo, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_802_11_CONFIG_T prQueryConfig = (P_PARAM_802_11_CONFIG_T) pvQueryBuffer; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen = 0; -+ -+ DEBUGFUNC("wlanoidQueryConfiguration"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_802_11_CONFIG_T); -+ if (u4QueryBufferLen < sizeof(PARAM_802_11_CONFIG_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvQueryBuffer); -+ -+ kalMemZero(prQueryConfig, sizeof(PARAM_802_11_CONFIG_T)); -+ -+ /* Update the current radio configuration. */ -+ prQueryConfig->u4Length = sizeof(PARAM_802_11_CONFIG_T); -+ -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidSetBeaconInterval, -+ &prQueryConfig->u4BeaconPeriod, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen); -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryBeaconInterval, -+ &prQueryConfig->u4BeaconPeriod, sizeof(UINT_32), &u4QueryInfoLen); -+#endif -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidQueryAtimWindow, -+ &prQueryConfig->u4ATIMWindow, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen); -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryAtimWindow, -+ &prQueryConfig->u4ATIMWindow, sizeof(UINT_32), &u4QueryInfoLen); -+#endif -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidQueryFrequency, -+ &prQueryConfig->u4DSConfig, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen); -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryFrequency, -+ &prQueryConfig->u4DSConfig, sizeof(UINT_32), &u4QueryInfoLen); -+#endif -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+ -+ prQueryConfig->rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); -+ -+ return rStatus; -+ -+} /* end of reqExtQueryConfiguration() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the radio configuration used in IBSS -+* mode. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_NOT_ACCEPTED -+*/ -+/*----------------------------------------------------------------------------*/ -+static WLAN_STATUS -+reqExtSetConfiguration(IN P_GLUE_INFO_T prGlueInfo, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_PARAM_802_11_CONFIG_T prNewConfig = (P_PARAM_802_11_CONFIG_T) pvSetBuffer; -+ UINT_32 u4SetInfoLen = 0; -+ -+ DEBUGFUNC("wlanoidSetConfiguration"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_802_11_CONFIG_T); -+ -+ if (u4SetBufferLen < *pu4SetInfoLen) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ /* OID_802_11_CONFIGURATION. If associated, NOT_ACCEPTED shall be returned. */ -+ if (prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED) -+ return WLAN_STATUS_NOT_ACCEPTED; -+ -+ ASSERT(pvSetBuffer); -+ -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidSetBeaconInterval, -+ &prNewConfig->u4BeaconPeriod, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen); -+#else -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetBeaconInterval, -+ &prNewConfig->u4BeaconPeriod, sizeof(UINT_32), &u4SetInfoLen); -+#endif -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidSetAtimWindow, -+ &prNewConfig->u4ATIMWindow, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen); -+#else -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetAtimWindow, &prNewConfig->u4ATIMWindow, sizeof(UINT_32), &u4SetInfoLen); -+#endif -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidSetFrequency, -+ &prNewConfig->u4DSConfig, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen); -+#else -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetFrequency, &prNewConfig->u4DSConfig, sizeof(UINT_32), &u4SetInfoLen); -+#endif -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+ -+ return rStatus; -+ -+} /* end of reqExtSetConfiguration() */ -+ -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set beacon detection function enable/disable state -+* This is mainly designed for usage under BT inquiry state (disable function). -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static WLAN_STATUS -+reqExtSetAcpiDevicePowerState(IN P_GLUE_INFO_T prGlueInfo, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ /* WIFI is enabled, when ACPI is D0 (ParamDeviceStateD0 = 1). And vice versa */ -+ -+ /* rStatus = wlanSetInformation(prGlueInfo->prAdapter, */ -+ /* wlanoidSetAcpiDevicePowerState, */ -+ /* pvSetBuffer, */ -+ /* u4SetBufferLen, */ -+ /* pu4SetInfoLen); */ -+ return rStatus; -+} -+ -+int priv_driver_set_chip_config(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ UINT_32 u4BufLen = 0; -+ INT_32 i4BytesWritten = 0; -+ UINT_32 u4CmdLen = 0; -+ UINT_32 u4PrefixLen = 0; -+ /* INT_32 i4Argc = 0; */ -+ /* PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = {0}; */ -+ -+ PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T rChipConfigInfo; -+ -+ ASSERT(prNetDev); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) -+ return -1; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ prAdapter = prGlueInfo->prAdapter; -+ DBGLOG(REQ, INFO, "priv_driver_set_chip_config command is %s\n", pcCommand); -+ /* wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); */ -+ /* DBGLOG(REQ, LOUD,("argc is %i\n",i4Argc)); */ -+ /* */ -+ u4CmdLen = kalStrnLen(pcCommand, i4TotalLen); -+ u4PrefixLen = kalStrLen(CMD_SET_CHIP) + 1 /*space */; -+ -+ kalMemZero(&rChipConfigInfo, sizeof(rChipConfigInfo)); -+ -+ /* if(i4Argc >= 2) { */ -+ if (u4CmdLen > u4PrefixLen) { -+ -+ rChipConfigInfo.ucType = CHIP_CONFIG_TYPE_WO_RESPONSE; -+ /* rChipConfigInfo.u2MsgSize = kalStrnLen(apcArgv[1],CHIP_CONFIG_RESP_SIZE); */ -+ rChipConfigInfo.u2MsgSize = u4CmdLen - u4PrefixLen; -+ /* kalStrnCpy(rChipConfigInfo.aucCmd,apcArgv[1],CHIP_CONFIG_RESP_SIZE); */ -+ if (u4PrefixLen <= CHIP_CONFIG_RESP_SIZE) { -+ kalStrnCpy(rChipConfigInfo.aucCmd, pcCommand + u4PrefixLen, -+ CHIP_CONFIG_RESP_SIZE - u4PrefixLen); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetChipConfig, -+ &rChipConfigInfo, -+ sizeof(rChipConfigInfo), FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ } else { -+ -+ DBGLOG(REQ, INFO, "%s: kalIoctl Command Len > %d\n", __func__, CHIP_CONFIG_RESP_SIZE); -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, INFO, "%s: kalIoctl ret=%d\n", __func__, rStatus); -+ i4BytesWritten = -1; -+ } -+ } -+ -+ return i4BytesWritten; -+ -+} -+ -+int priv_driver_set_miracast(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 i4BytesWritten = 0; -+ /* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */ -+ /* UINT_32 u4BufLen = 0; */ -+ INT_32 i4Argc = 0; -+ UINT_32 ucMode = 0; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL; -+ PCHAR apcArgv[WLAN_CFG_ARGV_MAX]; -+ INT_32 u4Ret; -+ -+ ASSERT(prNetDev); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) -+ return -1; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); -+ wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); -+ DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ if (i4Argc >= 2) { -+ u4Ret = kalkStrtou32(apcArgv[1], 0, &ucMode); /* ucMode = kalStrtoul(apcArgv[1], NULL, 0); */ -+ if (u4Ret) -+ DBGLOG(REQ, LOUD, "parse pcCommand error u4Ret=%d\n", u4Ret); -+ -+ if (g_ucMiracastMode == ucMode) -+ ; -+ /* XXX: continue or skip */ -+ -+ g_ucMiracastMode = ucMode; -+ prMsgWfdCfgUpdate = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_WFD_CONFIG_SETTINGS_CHANGED_T)); -+ -+ if (prMsgWfdCfgUpdate != NULL) { -+ -+ prWfdCfgSettings = &(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ prMsgWfdCfgUpdate->rMsgHdr.eMsgId = MID_MNY_P2P_WFD_CFG_UPDATE; -+ prMsgWfdCfgUpdate->prWfdCfgSettings = prWfdCfgSettings; -+ -+ if (ucMode == MIRACAST_MODE_OFF) { -+ prWfdCfgSettings->ucWfdEnable = 0; -+ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 0"); -+ } else if (ucMode == MIRACAST_MODE_SOURCE) { -+ prWfdCfgSettings->ucWfdEnable = 1; -+ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 1"); -+ } else if (ucMode == MIRACAST_MODE_SINK) { -+ prWfdCfgSettings->ucWfdEnable = 2; -+ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 2"); -+ } else { -+ prWfdCfgSettings->ucWfdEnable = 0; -+ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 0"); -+ } -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgWfdCfgUpdate, MSG_SEND_METHOD_BUF); -+ -+ priv_driver_set_chip_config(prNetDev, pcCommand, i4TotalLen); -+ -+ } /* prMsgWfdCfgUpdate */ -+ else { -+ ASSERT(FALSE); -+ i4BytesWritten = -1; -+ } -+ } -+ -+ /* i4Argc */ -+ return i4BytesWritten; -+} -+ -+int priv_support_driver_cmd(IN struct net_device *prNetDev, IN OUT struct ifreq *prReq, IN int i4Cmd) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ int ret = 0; -+ char *pcCommand = NULL; -+ priv_driver_cmd_t *priv_cmd = NULL; -+ int i4BytesWritten = 0; -+ int i4TotalLen = 0; -+ -+ if (!prReq->ifr_data) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (!prGlueInfo) { -+ DBGLOG(REQ, WARN, "No glue info\n"); -+ ret = -EFAULT; -+ goto exit; -+ } -+ if (prGlueInfo->u4ReadyFlag == 0) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ priv_cmd = kzalloc(sizeof(priv_driver_cmd_t), GFP_KERNEL); -+ if (!priv_cmd) { -+ DBGLOG(REQ, WARN, "%s, alloc mem failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ if (copy_from_user(priv_cmd, prReq->ifr_data, sizeof(priv_driver_cmd_t))) { -+ DBGLOG(REQ, INFO, "%s: copy_from_user fail\n", __func__); -+ ret = -EFAULT; -+ goto exit; -+ } -+ -+ i4TotalLen = priv_cmd->total_len; -+ -+ if (i4TotalLen <= 0) { -+ ret = -EINVAL; -+ DBGLOG(REQ, INFO, "%s: i4TotalLen invalid\n", __func__); -+ goto exit; -+ } -+ -+ pcCommand = priv_cmd->buf; -+ -+ DBGLOG(REQ, INFO, "%s: driver cmd \"%s\" on %s\n", __func__, pcCommand, prReq->ifr_name); -+ -+ i4BytesWritten = priv_driver_cmds(prNetDev, pcCommand, i4TotalLen); -+ -+ if (i4BytesWritten < 0) { -+ DBGLOG(REQ, INFO, "%s: command %s failed; Written is %d\n", -+ __func__, pcCommand, i4BytesWritten); -+ ret = -EFAULT; -+ } -+ -+exit: -+ kfree(priv_cmd); -+ -+ return ret; -+} -+ -+#if CFG_SUPPORT_BATCH_SCAN -+#define CMD_BATCH_SET "WLS_BATCHING SET" -+#define CMD_BATCH_GET "WLS_BATCHING GET" -+#define CMD_BATCH_STOP "WLS_BATCHING STOP" -+#endif -+ -+#if CFG_SUPPORT_GET_CH_ENV -+#define CMD_CH_ENV_GET "CH_ENV_GET" -+#endif -+ -+INT_32 priv_driver_cmds(IN struct net_device *prNetDev, IN PCHAR pcCommand, IN INT_32 i4TotalLen) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4BytesWritten = 0; -+ INT_32 i4CmdFound = 0; -+ -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) -+ return -1; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (i4CmdFound == 0) { -+ i4CmdFound = 1; -+ -+ if (strnicmp(pcCommand, CMD_MIRACAST, strlen(CMD_MIRACAST)) == 0) -+ i4BytesWritten = priv_driver_set_miracast(prNetDev, pcCommand, i4TotalLen); -+#if CFG_SUPPORT_BATCH_SCAN -+ else if (strnicmp(pcCommand, CMD_BATCH_SET, strlen(CMD_BATCH_SET)) == 0) { -+ kalIoctl(prGlueInfo, -+ wlanoidSetBatchScanReq, -+ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, FALSE, &i4BytesWritten); -+ } else if (strnicmp(pcCommand, CMD_BATCH_GET, strlen(CMD_BATCH_GET)) == 0) { -+ /* strcpy(pcCommand, "BATCH SCAN DATA FROM FIRMWARE"); */ -+ /* i4BytesWritten = strlen("BATCH SCAN DATA FROM FIRMWARE") + 1; */ -+ /* i4BytesWritten = priv_driver_get_linkspeed (prNetDev, pcCommand, i4TotalLen); */ -+ -+ UINT_32 u4BufLen; -+ int i; -+ /* int rlen=0; */ -+ -+ for (i = 0; i < CFG_BATCH_MAX_MSCAN; i++) { -+ g_rEventBatchResult[i].ucScanCount = i + 1; /* for get which mscan */ -+ kalIoctl(prGlueInfo, -+ wlanoidQueryBatchScanResult, -+ (PVOID)&g_rEventBatchResult[i], -+ sizeof(EVENT_BATCH_RESULT_T), TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ } -+ -+#if 0 -+ DBGLOG(SCN, INFO, "Batch Scan Results, scan count = %u\n", g_rEventBatchResult.ucScanCount); -+ for (i = 0; i < g_rEventBatchResult.ucScanCount; i++) { -+ prEntry = &g_rEventBatchResult.arBatchResult[i]; -+ DBGLOG(SCN, INFO, "Entry %u\n", i); -+ DBGLOG(SCN, INFO, " BSSID = %pM\n", prEntry->aucBssid); -+ DBGLOG(SCN, INFO, " SSID = %s\n", prEntry->aucSSID); -+ DBGLOG(SCN, INFO, " SSID len = %u\n", prEntry->ucSSIDLen); -+ DBGLOG(SCN, INFO, " RSSI = %d\n", prEntry->cRssi); -+ DBGLOG(SCN, INFO, " Freq = %u\n", prEntry->ucFreq); -+ } -+#endif -+ -+ batchConvertResult(&g_rEventBatchResult[0], pcCommand, i4TotalLen, &i4BytesWritten); -+ -+ /* Dump for debug */ -+ /* print_hex_dump(KERN_INFO, "BATCH", DUMP_PREFIX_ADDRESS, 16, 1, pcCommand, -+ i4BytesWritten, TRUE); */ -+ -+ } else if (strnicmp(pcCommand, CMD_BATCH_STOP, strlen(CMD_BATCH_STOP)) == 0) { -+ kalIoctl(prGlueInfo, -+ wlanoidSetBatchScanReq, -+ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, FALSE, &i4BytesWritten); -+ } -+#endif -+#if CFG_SUPPORT_GET_CH_ENV -+ else if (strnicmp(pcCommand, CMD_CH_ENV_GET, strlen(CMD_CH_ENV_GET)) == 0) -+ scanEnvResult(prGlueInfo, pcCommand, i4TotalLen, &i4BytesWritten); -+#endif -+ -+#if 0 -+ -+ else if (strnicmp(pcCommand, CMD_RSSI, strlen(CMD_RSSI)) == 0) { -+ /* i4BytesWritten = wl_android_get_rssi(net, command, i4TotalLen); */ -+ } else if (strnicmp(pcCommand, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) { -+ i4BytesWritten = priv_driver_get_linkspeed(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) { -+ /* Do nothing */ -+ } else if (strnicmp(pcCommand, CMD_PNOSETUP_SET, strlen(CMD_PNOSETUP_SET)) == 0) { -+ /* Do nothing */ -+ } else if (strnicmp(pcCommand, CMD_PNOENABLE_SET, strlen(CMD_PNOENABLE_SET)) == 0) { -+ /* Do nothing */ -+ } else if (strnicmp(pcCommand, CMD_SETSUSPENDOPT, strlen(CMD_SETSUSPENDOPT)) == 0) { -+ /* i4BytesWritten = wl_android_set_suspendopt(net, pcCommand, i4TotalLen); */ -+ } else if (strnicmp(pcCommand, CMD_SETSUSPENDMODE, strlen(CMD_SETSUSPENDMODE)) == 0) { -+ i4BytesWritten = priv_driver_set_suspend_mode(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) { -+ i4BytesWritten = priv_driver_set_band(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) { -+ /* i4BytesWritten = wl_android_get_band(net, pcCommand, i4TotalLen); */ -+ } else if (strnicmp(pcCommand, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) { -+ i4BytesWritten = priv_driver_set_country(prNetDev, pcCommand, i4TotalLen); -+ } -+ /* Mediatek private command */ -+ else if (strnicmp(pcCommand, CMD_SET_SW_CTRL, strlen(CMD_SET_SW_CTRL)) == 0) { -+ i4BytesWritten = priv_driver_set_sw_ctrl(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_GET_SW_CTRL, strlen(CMD_GET_SW_CTRL)) == 0) { -+ i4BytesWritten = priv_driver_get_sw_ctrl(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_SET_CFG, strlen(CMD_SET_CFG)) == 0) { -+ i4BytesWritten = priv_driver_set_cfg(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_GET_CFG, strlen(CMD_GET_CFG)) == 0) { -+ i4BytesWritten = priv_driver_get_cfg(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_SET_CHIP, strlen(CMD_SET_CHIP)) == 0) { -+ i4BytesWritten = priv_driver_set_chip_config(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_GET_CHIP, strlen(CMD_GET_CHIP)) == 0) { -+ i4BytesWritten = priv_driver_get_chip_config(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_SET_DBG_LEVEL, strlen(CMD_SET_DBG_LEVEL)) == 0) { -+ i4BytesWritten = priv_driver_set_dbg_level(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_GET_DBG_LEVEL, strlen(CMD_GET_DBG_LEVEL)) == 0) { -+ i4BytesWritten = priv_driver_get_dbg_level(prNetDev, pcCommand, i4TotalLen); -+ } -+#if CFG_SUPPORT_BATCH_SCAN -+ else if (strnicmp(pcCommand, CMD_BATCH_SET, strlen(CMD_BATCH_SET)) == 0) { -+ kalIoctl(prGlueInfo, -+ wlanoidSetBatchScanReq, -+ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, &i4BytesWritten); -+ } else if (strnicmp(pcCommand, CMD_BATCH_GET, strlen(CMD_BATCH_GET)) == 0) { -+ /* strcpy(pcCommand, "BATCH SCAN DATA FROM FIRMWARE"); */ -+ /* i4BytesWritten = strlen("BATCH SCAN DATA FROM FIRMWARE") + 1; */ -+ /* i4BytesWritten = priv_driver_get_linkspeed (prNetDev, pcCommand, i4TotalLen); */ -+ -+ UINT_32 u4BufLen; -+ int i; -+ /* int rlen=0; */ -+ -+ for (i = 0; i < CFG_BATCH_MAX_MSCAN; i++) { -+ g_rEventBatchResult[i].ucScanCount = i + 1; /* for get which mscan */ -+ kalIoctl(prGlueInfo, -+ wlanoidQueryBatchScanResult, -+ (PVOID)&g_rEventBatchResult[i], -+ sizeof(EVENT_BATCH_RESULT_T), TRUE, TRUE, TRUE, &u4BufLen); -+ } -+ -+#if 0 -+ DBGLOG(SCN, INFO, "Batch Scan Results, scan count = %u\n", g_rEventBatchResult.ucScanCount); -+ for (i = 0; i < g_rEventBatchResult.ucScanCount; i++) { -+ prEntry = &g_rEventBatchResult.arBatchResult[i]; -+ DBGLOG(SCN, INFO, "Entry %u\n", i); -+ DBGLOG(SCN, INFO, " BSSID = %pM\n", prEntry->aucBssid); -+ DBGLOG(SCN, INFO, " SSID = %s\n", prEntry->aucSSID); -+ DBGLOG(SCN, INFO, " SSID len = %u\n", prEntry->ucSSIDLen); -+ DBGLOG(SCN, INFO, " RSSI = %d\n", prEntry->cRssi); -+ DBGLOG(SCN, INFO, " Freq = %u\n", prEntry->ucFreq); -+ } -+#endif -+ -+ batchConvertResult(&g_rEventBatchResult[0], pcCommand, i4TotalLen, &i4BytesWritten); -+ -+ /* Dump for debug */ -+ /* print_hex_dump(KERN_INFO, "BATCH", DUMP_PREFIX_ADDRESS, 16, 1, pcCommand, i4BytesWritten, -+ TRUE); */ -+ -+ } else if (strnicmp(pcCommand, CMD_BATCH_STOP, strlen(CMD_BATCH_STOP)) == 0) { -+ kalIoctl(prGlueInfo, -+ wlanoidSetBatchScanReq, -+ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, &i4BytesWritten); -+ } -+#endif -+ -+#endif -+ -+ else -+ i4CmdFound = 0; -+ } -+ -+ /* i4CmdFound */ -+ if (i4CmdFound == 0) -+ DBGLOG(REQ, TRACE, "Unknown driver command %s - ignored\n", pcCommand); -+ -+ if (i4BytesWritten >= 0) { -+ if ((i4BytesWritten == 0) && (i4TotalLen > 0)) { -+ /* reset the command buffer */ -+ pcCommand[0] = '\0'; -+ } -+ -+ if (i4BytesWritten >= i4TotalLen) { -+ DBGLOG(REQ, INFO, -+ "%s: i4BytesWritten %d > i4TotalLen < %d\n", __func__, i4BytesWritten, i4TotalLen); -+ i4BytesWritten = i4TotalLen; -+ } else { -+ pcCommand[i4BytesWritten] = '\0'; -+ i4BytesWritten++; -+ } -+ } -+ -+ return i4BytesWritten; -+ -+} -+ -+static int compat_priv(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra, -+ int (*priv_func)(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra)) -+{ -+ struct iw_point *prIwp; -+ int ret = 0; -+#ifdef CONFIG_COMPAT -+ struct compat_iw_point *iwp_compat = NULL; -+ struct iw_point iwp; -+#endif -+ -+ if (!prIwReqData) -+ return -EINVAL; -+ -+#ifdef CONFIG_COMPAT -+ if (prIwReqInfo->flags & IW_REQUEST_FLAG_COMPAT) { -+ iwp_compat = (struct compat_iw_point *) &prIwReqData->data; -+ iwp.pointer = compat_ptr(iwp_compat->pointer); -+ iwp.length = iwp_compat->length; -+ iwp.flags = iwp_compat->flags; -+ prIwp = &iwp; -+ } else -+#endif -+ prIwp = &prIwReqData->data; -+ -+ -+ ret = priv_func(prNetDev, prIwReqInfo, (union iwreq_data *)prIwp, pcExtra); -+ -+#ifdef CONFIG_COMPAT -+ if (prIwReqInfo->flags & IW_REQUEST_FLAG_COMPAT) { -+ iwp_compat->pointer = ptr_to_compat(iwp.pointer); -+ iwp_compat->length = iwp.length; -+ iwp_compat->flags = iwp.flags; -+ } -+#endif -+ return ret; -+} -+ -+int -+priv_set_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_int); -+} -+ -+int -+priv_get_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_int); -+} -+ -+int -+priv_set_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_ints); -+} -+ -+int -+priv_get_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_ints); -+} -+ -+int -+priv_set_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_struct); -+} -+ -+int -+priv_get_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_struct); -+} -+ -+int -+priv_set_string(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_string); -+} -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c -new file mode 100644 -index 0000000000000..c13d24906bf88 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c -@@ -0,0 +1,1643 @@ -+/****************************************************************************** -+*[File] ahb.c -+*[Version] v1.0 -+*[Revision Date] 2013-01-16 -+*[Author] -+*[Description] -+* The program provides AHB HIF driver -+*[Copyright] -+* Copyright (C) 2013 MediaTek Incorporation. All Rights Reserved. -+******************************************************************************/ -+ -+/* -+** Log: ahb.c -+ * -+ * 01 16 2013 vend_samp.lin -+ * Port sdio.c to ahb.c on MT6572/MT6582 -+ * 1) Initial version -+ * -+ * 04 12 2012 terry.wu -+ * NULL -+ * Add AEE message support -+ * 1) Show AEE warning(red screen) if SDIO access error occurs -+ * -+ * 02 14 2012 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * include correct header file upon setting. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 09 20 2011 cp.wu -+ * [WCXRP00000994] [MT6620 Wi-Fi][Driver] dump message for bus error and reset bus error flag while re-initialized -+ * 1. always show error message for SDIO bus errors. -+ * 2. reset bus error flag when re-initialization -+ * -+ * 08 17 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628 related definitions for Linux/Android driver. -+ * -+ * 05 18 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * add device ID for MT5931. -+ * -+ * 04 08 2011 pat.lu -+ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver -+ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver -+ * -+ * 03 22 2011 pat.lu -+ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build -+ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. -+ * -+ * 03 18 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK. -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 11 15 2010 jeffrey.chang -+ * [WCXRP00000181] [MT6620 Wi-Fi][Driver] fix the driver message "GLUE_FLAG_HALT skip INT" during unloading -+ * Fix GLUE_FALG_HALT message which cause driver to hang -+ * -+ * 11 08 2010 cp.wu -+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period -+ * correct typo -+ * -+ * 11 08 2010 cp.wu -+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period -+ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add code to run WlanIST in SDIO callback. -+ * -+ * 10 19 2010 cp.wu -+ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration -+ * remove HIF_SDIO_ONE flags because the settings could be merged for runtime detection instead of compile-time. -+ * -+ * 10 19 2010 jeffrey.chang -+ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK -+ * HIF by default -+ * Refine linux kernel module to the license of MTK and enable MTK HIF -+ * -+ * 08 21 2010 jeffrey.chang -+ * NULL -+ * 1) add sdio two setting -+ * 2) bug fix of sdio glue -+ * -+ * 08 18 2010 jeffrey.chang -+ * NULL -+ * support multi-function sdio -+ * -+ * 08 18 2010 cp.wu -+ * NULL -+ * #if defined(__X86__) is not working, change to use #ifdef CONFIG_X86. -+ * -+ * 08 17 2010 cp.wu -+ * NULL -+ * add ENE SDIO host workaround for x86 linux platform. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Fix hotplug bug -+ * -+ * 03 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * clear sdio interrupt -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+/* #include */ -+#include -+/* #include */ -+#include -+/* #include */ -+/* #include */ -+/* #include */ -+ -+#include -+#ifndef CONFIG_X86 -+#include -+#endif -+ -+#ifdef CONFIG_OF -+#include -+#include -+#include -+#else -+ -+#endif -+ -+/* #include -+#include */ -+ -+#include "gl_os.h" -+ -+#if defined(MT6620) -+#include "mt6620_reg.h" -+#elif defined(MT6628) -+#include "mtreg.h" -+#endif -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+#include -+#endif -+ -+/* #define MTK_DMA_BUF_MEMCPY_SUP */ /* no virt_to_phys() use */ -+/* #define HIF_DEBUG_SUP */ -+/* #define HIF_DEBUG_SUP_TX */ -+ -+#ifdef HIF_DEBUG_SUP -+#define HIF_DBG(msg) (printk msg) -+#else -+#define HIF_DBG(msg) -+#endif /* HIF_DEBUG_SUP */ -+ -+#ifdef HIF_DEBUG_SUP_TX -+#define HIF_DBG_TX(msg) (printk msg) -+#else -+#define HIF_DBG_TX(msg) -+#endif /* HIF_DEBUG_SUP */ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static UINT_32 -+HifAhbDmaEnhanceModeConf(IN GLUE_INFO_T *GlueInfo, IN UINT_32 BurstLen, IN UINT_32 PortId, IN UINT_32 TransByte); -+ -+static irqreturn_t HifAhbISR(IN int Irq, IN void *Arg); -+ -+static int HifAhbProbe(VOID); -+ -+static int HifAhbRemove(VOID); -+ -+#if (MTK_WCN_SINGLE_MODULE == 0) -+static int HifAhbBusCntGet(VOID); -+ -+static int HifAhbBusCntClr(VOID); -+ -+static int HifTxCnt; -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ -+#if (CONF_HIF_DEV_MISC == 1) -+static ssize_t HifAhbMiscRead(IN struct file *Filp, OUT char __user *DstBuf, IN size_t Size, IN loff_t *Ppos); -+ -+static ssize_t HifAhbMiscWrite(IN struct file *Filp, IN const char __user *SrcBuf, IN size_t Size, IN loff_t *Ppos); -+ -+static int HifAhbMiscIoctl(IN struct file *Filp, IN unsigned int Cmd, IN unsigned long arg); -+ -+static int HifAhbMiscOpen(IN struct inode *Inodep, IN struct file *Filp); -+ -+static int HifAhbMiscClose(IN struct inode *Inodep, IN struct file *Filp); -+#else -+ -+static int HifAhbPltmProbe(IN struct platform_device *PDev); -+ -+static int __exit HifAhbPltmRemove(IN struct platform_device *PDev); -+ -+#ifdef CONFIG_PM -+static int HifAhbPltmSuspend(IN struct platform_device *PDev, pm_message_t Message); -+ -+static int HifAhbPltmResume(IN struct platform_device *PDev); -+#endif /* CONFIG_PM */ -+ -+#endif /* CONF_HIF_DEV_MISC */ -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) /* only for development test */ -+static VOID HifAhbLoopbkAuto(IN unsigned long arg); -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ -+#if (CONF_HIF_DMA_INT == 1) -+static irqreturn_t HifDmaISR(IN int Irq, IN void *Arg); -+#endif /* CONF_HIF_DMA_INT */ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* initialiation function from other module */ -+static probe_card pfWlanProbe; -+ -+/* release function from other module */ -+static remove_card pfWlanRemove; -+ -+static BOOLEAN WlanDmaFatalErr; -+ -+#if (CONF_HIF_DEV_MISC == 1) -+static const struct file_operations MtkAhbOps = { -+ .owner = THIS_MODULE, -+ .read = HifAhbMiscRead, -+ .write = HifAhbMiscWrite, -+ .unlocked_ioctl = HifAhbMiscIoctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = HifAhbMiscIoctl, -+#endif -+ .open = HifAhbMiscOpen, -+ .release = HifAhbMiscClose, -+}; -+ -+static struct miscdevice MtkAhbDriver = { -+ .minor = MISC_DYNAMIC_MINOR, /* any minor number */ -+ .name = HIF_MOD_NAME, -+ .fops = &MtkAhbOps, -+}; -+#else -+ -+#ifdef CONFIG_OF -+static const struct of_device_id apwifi_of_ids[] = { -+ {.compatible = "mediatek,wifi", .data = (void *)0}, -+ {.compatible = "mediatek,mt7623-wifi", .data = (void *)0x7623}, -+ {} -+}; -+#endif -+ -+struct platform_driver MtkPltmAhbDriver = { -+ .driver = { -+ .name = "mt-wifi", -+ .owner = THIS_MODULE, -+#ifdef CONFIG_OF -+ .of_match_table = apwifi_of_ids, -+#endif -+ }, -+ .probe = HifAhbPltmProbe, -+#ifdef CONFIG_PM -+ .suspend = HifAhbPltmSuspend, -+ .resume = HifAhbPltmResume, -+#else -+ .suspend = NULL, -+ .resume = NULL, -+#endif /* CONFIG_PM */ -+ .remove = __exit_p(HifAhbPltmRemove), -+}; -+ -+static struct platform_device *HifAhbPDev; -+ -+#endif /* CONF_HIF_DEV_MISC */ -+ -+/******************************************************************************* -+* P U B L I C F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will register sdio bus to the os -+* -+* \param[in] pfProbe Function pointer to detect card -+* \param[in] pfRemove Function pointer to remove card -+* -+* \return The result of registering HIF driver (WLAN_STATUS_SUCCESS = 0) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS glRegisterBus(probe_card pfProbe, remove_card pfRemove) -+{ -+ WLAN_STATUS Ret; -+ -+ ASSERT(pfProbe); -+ ASSERT(pfRemove); -+ -+ pfWlanProbe = pfProbe; /* wlan card initialization in other modules = wlanProbe() */ -+ pfWlanRemove = pfRemove; -+ -+#if (CONF_HIF_DEV_MISC == 1) -+ Ret = misc_register(&MtkAhbDriver); -+ if (Ret != 0) -+ return Ret; -+ HifAhbProbe(); -+#else -+ Ret = platform_driver_register(&MtkPltmAhbDriver); -+#endif /* CONF_HIF_DEV_MISC */ -+ -+ return Ret; -+ -+} /* end of glRegisterBus() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will unregister sdio bus to the os -+* -+* \param[in] pfRemove Function pointer to remove card -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glUnregisterBus(remove_card pfRemove) -+{ -+ ASSERT(pfRemove); -+ -+ pfRemove(); -+ -+#if (CONF_HIF_DEV_MISC == 1) -+ HifAhbRemove(); -+ -+ if ((misc_deregister(&MtkAhbDriver)) != 0) -+ ; -+#else -+ -+ platform_driver_unregister(&MtkPltmAhbDriver); -+#endif /* CONF_HIF_DEV_MISC */ -+ -+ return; -+ -+} /* end of glUnregisterBus() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will inform us whole chip reset start event. -+* -+* \param[in] GlueInfo Pointer to glue info structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glResetHif(GLUE_INFO_T *GlueInfo) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+ if (HifInfo->DmaOps) -+ HifInfo->DmaOps->DmaReset(HifInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function stores hif related info, which is initialized before. -+* -+* \param[in] GlueInfo Pointer to glue info structure -+* \param[in] u4Cookie Pointer to UINT_32 memory base variable for _HIF_HPI -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glSetHifInfo(GLUE_INFO_T *GlueInfo, ULONG ulCookie) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ const struct of_device_id *of_id; -+ -+ /* Init HIF */ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+#if (CONF_HIF_DEV_MISC == 1) -+ HifInfo->Dev = MtkAhbDriver.this_device; -+#else -+ HifInfo->Dev = &HifAhbPDev->dev; -+#endif /* CONF_HIF_DEV_MISC */ -+ SET_NETDEV_DEV(GlueInfo->prDevHandler, HifInfo->Dev); -+ -+ HifInfo->HifRegBaseAddr = ioremap(HIF_DRV_BASE, HIF_DRV_LENGTH); -+ HifInfo->McuRegBaseAddr = ioremap(CONN_MCU_DRV_BASE, CONN_MCU_REG_LENGTH); -+ DBGLOG(INIT, INFO, "[WiFi/HIF]HifInfo->HifRegBaseAddr=0x%p, HifInfo->McuRegBaseAddr=0x%p\n", -+ HifInfo->HifRegBaseAddr, HifInfo->McuRegBaseAddr); -+ -+ /* default disable DMA */ -+ HifInfo->fgDmaEnable = FALSE; -+ HifInfo->DmaRegBaseAddr = 0; -+ HifInfo->DmaOps = NULL; -+ of_id = of_match_node(apwifi_of_ids, HifAhbPDev->dev.of_node); -+ if (of_id && of_id->data) { -+ HifInfo->ChipID = (UINT_32)(unsigned long)of_id->data; -+ } else { -+ /* read chip ID */ -+ HifInfo->ChipID = HIF_REG_READL(HifInfo, MCR_WCIR) & 0xFFFF; -+ if (HifInfo->ChipID == 0x0321 || HifInfo->ChipID == 0x0335 || HifInfo->ChipID == 0x0337) -+ HifInfo->ChipID = 0x6735; /* Denali ChipID transition */ -+ if (HifInfo->ChipID == 0x0326) -+ HifInfo->ChipID = 0x6755; -+ } -+ DBGLOG(INIT, INFO, "[WiFi/HIF] ChipID = 0x%x\n", HifInfo->ChipID); -+#ifdef CONFIG_OF -+#if !defined(CONFIG_MTK_CLKMGR) -+ HifInfo->clk_wifi_dma = devm_clk_get(&HifAhbPDev->dev, "wifi-dma"); -+ if (IS_ERR(HifInfo->clk_wifi_dma)) -+ DBGLOG(INIT, ERROR, "[WiFi/HIF][CCF]cannot get HIF clk_wifi_dma clock.\n"); -+ DBGLOG(INIT, TRACE, "[WiFi/HIF][CCF]HIF clk_wifi_dma=0x%p\n", HifInfo->clk_wifi_dma); -+#endif -+#endif -+ -+ /* Init DMA */ -+ WlanDmaFatalErr = 0; /* reset error flag */ -+ -+#if (CONF_MTK_AHB_DMA == 1) -+ spin_lock_init(&HifInfo->DdmaLock); -+ -+ HifPdmaInit(HifInfo); -+#endif /* CONF_MTK_AHB_DMA */ -+ -+ /* Start loopback test after 10 seconds */ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) /* only for development test */ -+ { -+ init_timer(&(HifInfo->HifTmrLoopbkFn)); -+ HifInfo->HifTmrLoopbkFn.function = HifAhbLoopbkAuto; -+ HifInfo->HifTmrLoopbkFn.data = (unsigned long)GlueInfo; -+ -+ init_waitqueue_head(&HifInfo->HifWaitq); -+ HifInfo->HifTaskLoopbkFn = kthread_run(kalDevLoopbkThread, GlueInfo->prDevHandler, "LoopbkThread"); -+ HifInfo->HifLoopbkFlg = 0; -+ -+ /* Note: in FPGA, clock is not accuracy so 3000 here, not 10000 */ -+ HifInfo->HifTmrLoopbkFn.expires = jiffies + MSEC_TO_SYSTIME(30000); -+ add_timer(&(HifInfo->HifTmrLoopbkFn)); -+ -+ HIF_DBG(("[WiFi/HIF] Start loopback test after 10 seconds (jiffies = %u)...\n", jiffies)); -+ } -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ -+#if (CONF_HIF_DMA_INT == 1) -+ init_waitqueue_head(&HifInfo->HifDmaWaitq); -+ HifInfo->HifDmaWaitFlg = 0; -+#endif /* CONF_HIF_DMA_INT */ -+ -+} /* end of glSetHifInfo() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function clears hif related info. -+* -+* \param[in] GlueInfo Pointer to glue info structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glClearHifInfo(GLUE_INFO_T *GlueInfo) -+{ -+ iounmap(GlueInfo->rHifInfo.HifRegBaseAddr); -+ iounmap(GlueInfo->rHifInfo.DmaRegBaseAddr); -+ iounmap(GlueInfo->rHifInfo.McuRegBaseAddr); -+ return; -+ -+} /* end of glClearHifInfo() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function clears hif related info. -+* -+* \param[in] GlueInfo Pointer to glue info structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glGetChipInfo(GLUE_INFO_T *GlueInfo, UINT_8 *pucChipBuf) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ -+ HifInfo = &GlueInfo->rHifInfo; -+ DBGLOG(INIT, TRACE, "glGetChipInfo ChipID = 0x%x\n", HifInfo->ChipID); -+ switch (HifInfo->ChipID) { -+ case MTK_CHIP_ID_6571: -+ case MTK_CHIP_ID_8127: -+ case MTK_CHIP_ID_6752: -+ case MTK_CHIP_ID_8163: -+ case MTK_CHIP_ID_6735: -+ case MTK_CHIP_ID_6580: -+ case MTK_CHIP_ID_6755: -+ case MTK_CHIP_ID_7623: -+ kalSprintf(pucChipBuf, "%04x", HifInfo->ChipID); -+ break; -+ default: -+ kalMemCopy(pucChipBuf, "SOC", strlen("SOC")); -+ } -+} /* end of glGetChipInfo() */ -+ -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function to check if we need wakelock under Hotspot mode. -+* -+* \param[in] GlueInfo Pointer to glue info structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glIsChipNeedWakelock(GLUE_INFO_T *GlueInfo) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ -+ HifInfo = &GlueInfo->rHifInfo; -+ if (HifInfo->ChipID == MTK_CHIP_ID_6572 || HifInfo->ChipID == MTK_CHIP_ID_6582) -+ return TRUE; -+ else -+ return FALSE; -+} /* end of glIsChipNeedWakelock() */ -+#endif /* CFG_SPM_WORKAROUND_FOR_HOTSPOT */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Initialize bus operation and hif related information, request resources. -+* -+* \param[out] pvData A pointer to HIF-specific data type buffer. -+* For eHPI, pvData is a pointer to UINT_32 type and stores a -+* mapped base address. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glBusInit(PVOID pvData) -+{ -+ return TRUE; -+} /* end of glBusInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Stop bus operation and release resources. -+* -+* \param[in] pvData A pointer to struct net_device. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glBusRelease(PVOID pvData) -+{ -+} /* end of glBusRelease() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Setup bus interrupt operation and interrupt handler for os. -+* -+* \param[in] pvData A pointer to struct net_device. -+* \param[in] pfnIsr A pointer to interrupt handler function. -+* \param[in] pvCookie Private data for pfnIsr function. -+* -+* \retval WLAN_STATUS_SUCCESS if success -+* NEGATIVE_VALUE if fail -+*/ -+/*----------------------------------------------------------------------------*/ -+#ifdef CONFIG_OF -+INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie) -+{ -+ struct device_node *node = NULL; -+ unsigned int irq_info[3] = { 0, 0, 0 }; -+ /* unsigned int phy_base; */ -+ unsigned int irq_id = 0; -+ unsigned int irq_flags = 0; -+ -+ struct net_device *prNetDevice; -+ -+ ASSERT(pvData); -+ if (!pvData) -+ return -1; -+ prNetDevice = (struct net_device *)pvData; -+ -+ node = of_find_compatible_node(NULL, NULL, "mediatek,wifi"); -+ if (node) { -+ irq_id = irq_of_parse_and_map(node, 0); -+ DBGLOG(INIT, INFO, "WIFI-OF: get wifi irq(%d)\n", irq_id); -+ } else { -+ DBGLOG(INIT, ERROR, "WIFI-OF: get wifi device node fail\n"); -+ } -+ -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ DBGLOG(INIT, ERROR, "WIFI-OF: get interrupt flag from DTS fail\n"); -+ } else { -+ irq_flags = irq_info[2]; -+ DBGLOG(INIT, LOUD, "WIFI-OF: get interrupt flag(0x%x)\n", irq_flags); -+ } -+ -+ /* Register AHB IRQ */ -+ if (request_irq(irq_id, HifAhbISR, irq_flags, HIF_MOD_NAME, prNetDevice)) { -+ DBGLOG(INIT, ERROR, "WIFI-OF: request irq %d fail!\n", irq_id); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie) -+{ -+ struct device_node *node = NULL; -+ unsigned int irq_info[3] = { 0, 0, 0 }; -+ /* unsigned int phy_base; */ -+ unsigned int irq_id = 0; -+ unsigned int irq_flags = 0; -+ -+ struct net_device *prNetDevice; -+ -+ /* Init */ -+ ASSERT(pvData); -+ if (!pvData) -+ return; -+ prNetDevice = (struct net_device *)pvData; -+ -+ node = of_find_compatible_node(NULL, NULL, "mediatek,wifi"); -+ if (node) { -+ irq_id = irq_of_parse_and_map(node, 0); -+ DBGLOG(INIT, INFO, "WIFI-OF: get wifi irq(%d)\n", irq_id); -+ } else { -+ DBGLOG(INIT, ERROR, "WIFI-OF: get wifi device node fail\n"); -+ } -+ -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ DBGLOG(INIT, ERROR, "WIFI-OF: get interrupt flag from DTS fail\n"); -+ } else { -+ irq_flags = irq_info[2]; -+ DBGLOG(INIT, LOUD, "WIFI-OF: get interrupt flag(0x%x)\n", irq_flags); -+ } -+ -+ /* Free the IRQ */ -+ free_irq(irq_id, prNetDevice); -+ return; -+ -+} -+#else -+/* the name is different in 72 and 82 */ -+#ifndef MT_WF_HIF_IRQ_ID /* for MT6572/82/92 */ -+#define MT_WF_HIF_IRQ_ID WF_HIF_IRQ_ID -+#endif /* MT_WF_HIF_IRQ_ID */ -+ -+INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie) -+{ -+ int ret = 0; -+ struct net_device *prNetDevice; -+ GLUE_INFO_T *GlueInfo; -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* Init */ -+ ASSERT(pvData); -+ if (!pvData) -+ return -1; -+ -+ prNetDevice = (struct net_device *)pvData; -+ GlueInfo = (GLUE_INFO_T *) pvCookie; -+ ASSERT(GlueInfo); -+ if (!GlueInfo) { -+ DBGLOG(INIT, ERROR, "GlueInfo == NULL!\n"); -+ return -1; -+ } -+ -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ /* Register AHB IRQ */ -+ if (request_irq(MT_WF_HIF_IRQ_ID, HifAhbISR, IRQF_TRIGGER_LOW, HIF_MOD_NAME, prNetDevice)) { -+ DBGLOG(INIT, ERROR, "request irq %d fail!\n", MT_WF_HIF_IRQ_ID); -+ return -1; -+ } -+#if (CONF_HIF_DMA_INT == 1) -+ if (request_irq(MT_GDMA2_IRQ_ID, HifDmaISR, IRQF_TRIGGER_LOW, "AHB_DMA", prNetDevice)) { -+ DBGLOG(INIT, ERROR, "request irq %d fail!\n", MT_GDMA2_IRQ_ID); -+ free_irq(MT_WF_HIF_IRQ_ID, prNetDevice); -+ return -1; -+ } -+#endif /* CONF_HIF_DMA_INT */ -+ -+ return ret; -+ -+} /* end of glBusSetIrq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Stop bus interrupt operation and disable interrupt handling for os. -+* -+* \param[in] pvData A pointer to struct net_device. -+* \param[in] pvCookie Private data for pfnIsr function. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie) -+{ -+ struct net_device *prNetDevice; -+ GLUE_INFO_T *GlueInfo; -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* Init */ -+ ASSERT(pvData); -+ if (!pvData) -+ return; -+ -+ prNetDevice = (struct net_device *)pvData; -+ GlueInfo = (GLUE_INFO_T *) pvCookie; -+ ASSERT(GlueInfo); -+ if (!GlueInfo) -+ return; -+ -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ /* Free the IRQ */ -+ free_irq(MT_WF_HIF_IRQ_ID, prNetDevice); -+ return; -+ -+} /* end of glBusreeIrq() */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Read a 32-bit device register -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] RegOffset Register offset -+* \param[in] pu4Value Pointer to variable used to store read value -+* -+* \retval TRUE operation success -+* \retval FALSE operation fail -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalDevRegRead(IN GLUE_INFO_T *GlueInfo, IN UINT_32 RegOffset, OUT UINT_32 *pu4Value) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* sanity check and init */ -+ ASSERT(GlueInfo); -+ ASSERT(pu4Value); -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ /* use PIO mode to read register */ -+ if (WlanDmaFatalErr && RegOffset != MCR_WCIR && RegOffset != MCR_WHLPCR) -+ return FALSE; -+ *pu4Value = HIF_REG_READL(HifInfo, RegOffset); -+ -+ if ((RegOffset == MCR_WRDR0) || (RegOffset == MCR_WRDR1)) -+ HIF_DBG(("[WiFi/HIF] kalDevRegRead from Data Port 0 or 1\n")); -+ -+ return TRUE; -+ -+} /* end of kalDevRegRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Write a 32-bit device register -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] RegOffset Register offset -+* \param[in] RegValue RegValue to be written -+* -+* \retval TRUE operation success -+* \retval FALSE operation fail -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalDevRegWrite(IN GLUE_INFO_T *GlueInfo, IN UINT_32 RegOffset, IN UINT_32 RegValue) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* sanity check and init */ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ /* use PIO mode to write register */ -+ if (WlanDmaFatalErr && RegOffset != MCR_WCIR && RegOffset != MCR_WHLPCR) -+ return FALSE; -+ HIF_REG_WRITEL(HifInfo, RegOffset, RegValue); -+ -+ if ((RegOffset == MCR_WTDR0) || (RegOffset == MCR_WTDR1)) -+ HIF_DBG(("[WiFi/HIF] kalDevRegWrite to Data Port 0 or 1\n")); -+ -+ return TRUE; -+ -+} /* end of kalDevRegWrite() */ -+ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Read device I/O port -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] Port I/O port offset -+* \param[in] Size Length to be read -+* \param[out] Buf Pointer to read buffer -+* \param[in] MaxBufSize Length of the buffer valid to be accessed -+* -+* \retval TRUE operation success -+* \retval FALSE operation fail -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+kalDevPortRead(IN P_GLUE_INFO_T GlueInfo, IN UINT_16 Port, IN UINT_32 Size, OUT PUINT_8 Buf, IN UINT_32 MaxBufSize) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ UINT_32 u4HSTCRValue = 0; -+ UINT_32 RegWHLPCR = 0; -+ -+ /* sanity check */ -+ if ((WlanDmaFatalErr == 1) || (fgIsResetting == TRUE) || (HifIsFwOwn(GlueInfo->prAdapter) == TRUE)) { -+ DBGLOG(RX, ERROR, "WlanDmaFatalErr: %d, fgIsResetting: %d, HifIsFwOwn: %d\n", -+ WlanDmaFatalErr, fgIsResetting, HifIsFwOwn(GlueInfo->prAdapter)); -+ return FALSE; -+ } -+ /* Init */ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ ASSERT(Buf); -+ ASSERT(Size <= MaxBufSize); -+ -+ /* Note: burst length should be equal to the one used in DMA */ -+ if (Port == MCR_WRDR0) -+ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_RXD0, Size); -+ else if (Port == MCR_WRDR1) -+ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_RXD1, Size); -+ else if (Port == MCR_WHISR) -+ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_WHISR, Size); -+ -+ RegWHLPCR = HIF_REG_READL(HifInfo, MCR_WHLPCR); -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); -+ -+ /* Read */ -+#if (CONF_MTK_AHB_DMA == 1) -+ if ((HifInfo->fgDmaEnable == TRUE) && (HifInfo->DmaOps != NULL) -+ && ((Port == MCR_WRDR0) || (Port == MCR_WRDR1))) { -+ /* only for data port */ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ VOID *DmaVBuf = NULL, *DmaPBuf = NULL; -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ GL_HIF_DMA_OPS_T *prDmaOps = HifInfo->DmaOps; -+ MTK_WCN_HIF_DMA_CONF DmaConf; -+ UINT_32 LoopCnt; -+ unsigned long PollTimeout; -+#if (CONF_HIF_DMA_INT == 1) -+ INT_32 RtnVal = 0; -+#endif -+ /* config DMA, Port = MCR_WRDR0 or MCR_WRDR1 */ -+ DmaConf.Count = Size; -+ DmaConf.Dir = HIF_DMA_DIR_RX; -+ DmaConf.Src = HIF_DRV_BASE + Port; /* must be physical addr */ -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ DmaConf.Dst = kalIOPhyAddrGet(Buf); /* must be physical addr */ -+ -+ /* TODO: use virt_to_phys() */ -+ if (DmaConf.Dst == NULL) { -+ HIF_DBG(("[WiFi/HIF] Use Dma Buffer to RX packet (%d %d)...\n", Size, CFG_RX_MAX_PKT_SIZE)); -+ ASSERT(Size <= CFG_RX_MAX_PKT_SIZE); -+ -+ kalDmaBufGet(&DmaVBuf, &DmaPBuf); -+ DmaConf.Dst = (ULONG) DmaPBuf; -+ } -+#else -+ /* -+ http://kernelnewbies.org/KernelMemoryAllocation -+ Since the cache-coherent mapping may be expensive, also a streaming allocation exists. -+ -+ This is a buffer for one-way communication, which means coherency is limited to -+ flushing the data from the cache after a write finishes. The buffer has to be -+ pre-allocated (e.g. using kmalloc()). DMA for it is set up with dma_map_single(). -+ -+ When the DMA is finished (e.g. when the device has sent an interrupt signaling end of -+ DMA), call dma_unmap_single(). Between map and unmap, the device is in control of the -+ buffer: if you write to the device, do it before dma_map_single(), if you read from -+ it, do it after dma_unmap_single(). -+ */ -+ /* DMA_FROM_DEVICE invalidated (without writeback) the cache */ -+ /* TODO: if dst_off was not cacheline aligned */ -+ DmaConf.Dst = dma_map_single(HifInfo->Dev, Buf, Size, DMA_FROM_DEVICE); -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+ /* start to read data */ -+ AP_DMA_HIF_LOCK(HifInfo); /* lock to avoid other codes config GDMA */ -+ -+ prDmaOps->DmaClockCtrl(TRUE); -+ prDmaOps->DmaConfig(HifInfo, &DmaConf); -+ prDmaOps->DmaStart(HifInfo); -+ -+#if (CONF_HIF_DMA_INT == 1) -+ RtnVal = wait_event_interruptible_timeout(HifInfo->HifDmaWaitq, (HifInfo->HifDmaWaitFlg != 0), 1000); -+ if (RtnVal <= 0) -+ DBGLOG(RX, ERROR, "fatal error1! reset DMA!\n"); -+ HifInfo->HifDmaWaitFlg = 0; -+#else -+ PollTimeout = jiffies + HZ * 5; -+ -+ do { -+ if (time_before(jiffies, PollTimeout)) -+ continue; -+ DBGLOG(RX, INFO, "RX DMA Timeout, HSTCR: 0x%08x, and dump WHISR EnhanceMode data\n", -+ u4HSTCRValue); -+ HifDumpEnhanceModeData(GlueInfo->prAdapter); -+ if (prDmaOps->DmaRegDump != NULL) -+ prDmaOps->DmaRegDump(HifInfo); -+ WlanDmaFatalErr = 1; -+ /* we still need complete dma progress even dma timeout */ -+ break; -+ } while (!prDmaOps->DmaPollIntr(HifInfo)); -+#endif /* CONF_HIF_DMA_INT */ -+ /* we should disable dma interrupt then clear dma interrupt, otherwise, -+ for dma timeout case, interrupt may be set after we clear it */ -+ prDmaOps->DmaStop(HifInfo); -+ prDmaOps->DmaAckIntr(HifInfo); -+ -+ LoopCnt = 0; -+ do { -+ if (LoopCnt++ > 100000) { -+ /* TODO: impossible! reset DMA */ -+ DBGLOG(RX, ERROR, "fatal error2! reset DMA!\n"); -+ break; -+ } -+ } while (prDmaOps->DmaPollStart(HifInfo) != 0); -+ -+ prDmaOps->DmaClockCtrl(FALSE); -+ -+ AP_DMA_HIF_UNLOCK(HifInfo); -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ if (DmaVBuf != NULL) -+ kalMemCopy(Buf, DmaVBuf, Size); -+#else -+ dma_unmap_single(HifInfo->Dev, DmaConf.Dst, Size, DMA_FROM_DEVICE); -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); -+ -+ if (WlanDmaFatalErr) { -+ if (!fgIsResetting) -+ glDoChipReset(); -+ return FALSE; -+ } -+ HIF_DBG(("[WiFi/HIF] DMA RX OK!\n")); -+ } else -+#endif /* CONF_MTK_AHB_DMA */ -+ { -+ UINT_32 IdLoop, MaxLoop; -+ UINT_32 *LoopBuf; -+ -+ /* default PIO mode */ -+ MaxLoop = Size >> 2; -+ if (Size & 0x3) -+ MaxLoop++; -+ LoopBuf = (UINT_32 *) Buf; -+ -+ for (IdLoop = 0; IdLoop < MaxLoop; IdLoop++) { -+ -+ *LoopBuf = HIF_REG_READL(HifInfo, Port); -+ LoopBuf++; -+ } -+ -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); -+ } -+ -+ return TRUE; -+ -+} /* end of kalDevPortRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Write device I/O port -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] Port I/O port offset -+* \param[in] Size Length to be write -+* \param[in] Buf Pointer to write buffer -+* \param[in] MaxBufSize Length of the buffer valid to be accessed -+* -+* \retval TRUE operation success -+* \retval FALSE operation fail -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+kalDevPortWrite(IN P_GLUE_INFO_T GlueInfo, IN UINT_16 Port, IN UINT_32 Size, IN PUINT_8 Buf, IN UINT_32 MaxBufSize) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ UINT_32 u4HSTCRValue = 0; -+ UINT_32 RegWHLPCR = 0; -+ -+ /* sanity check */ -+ if ((WlanDmaFatalErr == 1) || (fgIsResetting == TRUE) || (HifIsFwOwn(GlueInfo->prAdapter) == TRUE)) { -+ DBGLOG(RX, ERROR, "WlanDmaFatalErr: %d, fgIsResetting: %d, HifIsFwOwn: %d\n", -+ WlanDmaFatalErr, fgIsResetting, HifIsFwOwn(GlueInfo->prAdapter)); -+ return FALSE; -+ } -+ -+ /* Init */ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ ASSERT(Buf); -+ ASSERT(Size <= MaxBufSize); -+ -+ HifTxCnt++; -+ -+ /* Note: burst length should be equal to the one used in DMA */ -+ if (Port == MCR_WTDR0) -+ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_TXD0, Size); -+ else if (Port == MCR_WTDR1) -+ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_TXD1, Size); -+ /* else other non-data port */ -+ -+ RegWHLPCR = HIF_REG_READL(HifInfo, MCR_WHLPCR); -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); -+ -+ /* Write */ -+#if (CONF_MTK_AHB_DMA == 1) -+ if ((HifInfo->fgDmaEnable == TRUE) && (HifInfo->DmaOps != NULL) && ((Port == MCR_WTDR0) || -+ (Port == MCR_WTDR1))) { -+ /* only for data port */ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ VOID *DmaVBuf = NULL, *DmaPBuf = NULL; -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ GL_HIF_DMA_OPS_T *prDmaOps = HifInfo->DmaOps; -+ MTK_WCN_HIF_DMA_CONF DmaConf; -+ UINT_32 LoopCnt; -+ unsigned long PollTimeout; -+#if (CONF_HIF_DMA_INT == 1) -+ INT_32 RtnVal = 0; -+#endif -+ -+ /* config GDMA */ -+ HIF_DBG_TX(("[WiFi/HIF/DMA] Prepare to send data...\n")); -+ DmaConf.Count = Size; -+ DmaConf.Dir = HIF_DMA_DIR_TX; -+ DmaConf.Dst = HIF_DRV_BASE + Port; /* must be physical addr */ -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ DmaConf.Src = kalIOPhyAddrGet(Buf); /* must be physical addr */ -+ -+ /* TODO: use virt_to_phys() */ -+ if (DmaConf.Src == NULL) { -+ HIF_DBG_TX(("[WiFi/HIF] Use Dma Buffer to TX packet (%d %d)...\n", Size, CFG_RX_MAX_PKT_SIZE)); -+ ASSERT(Size <= CFG_RX_MAX_PKT_SIZE); -+ -+ kalDmaBufGet(&DmaVBuf, &DmaPBuf); -+ DmaConf.Src = (ULONG) DmaPBuf; -+ -+ kalMemCopy(DmaVBuf, Buf, Size); -+ } -+#else -+ -+ /* DMA_TO_DEVICE writeback the cache */ -+ DmaConf.Src = dma_map_single(HifInfo->Dev, Buf, Size, DMA_TO_DEVICE); -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+ /* start to write */ -+ AP_DMA_HIF_LOCK(HifInfo); -+ -+ prDmaOps->DmaClockCtrl(TRUE); -+ prDmaOps->DmaConfig(HifInfo, &DmaConf); -+ prDmaOps->DmaStart(HifInfo); -+ -+#if (CONF_HIF_DMA_INT == 1) -+ RtnVal = wait_event_interruptible_timeout(HifInfo->HifDmaWaitq, (HifInfo->HifDmaWaitFlg != 0), 1000); -+ if (RtnVal <= 0) -+ DBGLOG(TX, ERROR, "fatal error1! reset DMA!\n"); -+ HifInfo->HifDmaWaitFlg = 0; -+#else -+ -+ LoopCnt = 0; -+ PollTimeout = jiffies + HZ * 5; -+ -+ do { -+ if (time_before(jiffies, PollTimeout)) -+ continue; -+ DBGLOG(TX, INFO, "TX DMA Timeout, HSTCR: 0x%08x\n", u4HSTCRValue); -+ if (prDmaOps->DmaRegDump != NULL) -+ prDmaOps->DmaRegDump(HifInfo); -+ WlanDmaFatalErr = 1; -+ /* we still need complete dma progress even dma timeout */ -+ break; -+ } while (!prDmaOps->DmaPollIntr(HifInfo)); -+#endif /* CONF_HIF_DMA_INT */ -+ /* we should disable dma interrupt then clear dma interrupt, otherwise, -+ for dma timeout case, interrupt may be set after we clear it */ -+ prDmaOps->DmaStop(HifInfo); -+ prDmaOps->DmaAckIntr(HifInfo); -+ -+ LoopCnt = 0; -+ do { -+ if (LoopCnt++ > 100000) { -+ DBGLOG(TX, ERROR, "fatal error2! reset DMA!\n"); -+ break; -+ } -+ } while (prDmaOps->DmaPollStart(HifInfo) != 0); -+ -+ prDmaOps->DmaClockCtrl(FALSE); -+ -+ AP_DMA_HIF_UNLOCK(HifInfo); -+ -+#ifndef MTK_DMA_BUF_MEMCPY_SUP -+ dma_unmap_single(HifInfo->Dev, DmaConf.Src, Size, DMA_TO_DEVICE); -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); -+ -+ if (WlanDmaFatalErr) { -+ if (!fgIsResetting) -+ glDoChipReset(); -+ return FALSE; -+ } -+ HIF_DBG_TX(("[WiFi/HIF] DMA TX OK!\n")); -+ } else -+#endif /* CONF_MTK_AHB_DMA */ -+ { -+ UINT_32 IdLoop, MaxLoop; -+ UINT_32 *LoopBuf; -+ -+ /* PIO mode */ -+ MaxLoop = Size >> 2; -+ LoopBuf = (UINT_32 *) Buf; -+ -+ HIF_DBG_TX(("[WiFi/HIF/PIO] Prepare to send data (%d 0x%p-0x%p)...\n", -+ Size, LoopBuf, (((UINT8 *) LoopBuf) + (Size & (~0x03))))); -+ -+ if (Size & 0x3) -+ MaxLoop++; -+ -+ for (IdLoop = 0; IdLoop < MaxLoop; IdLoop++) { -+ HIF_REG_WRITEL(HifInfo, Port, *LoopBuf); -+ LoopBuf++; -+ } -+ -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); -+ -+ HIF_DBG_TX(("\n\n")); -+ } -+ -+ return TRUE; -+ -+} /* end of kalDevPortWrite() */ -+ -+/******************************************************************************* -+* P R I V A T E F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a SDIO interrupt callback function -+* -+* \param[in] func pointer to SDIO handle -+* -+* \return void -+*/ -+/*----------------------------------------------------------------------------*/ -+static irqreturn_t HifAhbISR(IN int Irq, IN void *Arg) -+{ -+ struct net_device *prNetDevice = (struct net_device *)Arg; -+ GLUE_INFO_T *GlueInfo; -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* Init */ -+ IsrCnt++; -+ ASSERT(prNetDevice); -+ GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDevice)); -+ ASSERT(GlueInfo); -+ -+ if (!GlueInfo) -+ return IRQ_HANDLED; -+ -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ GlueInfo->IsrCnt++; -+ -+ if (GlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); -+ return IRQ_HANDLED; -+ } -+ -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); -+ -+ /* lock 100ms to avoid suspend */ -+ kalHifAhbKalWakeLockTimeout(GlueInfo); -+ -+ /* Wake up main thread */ -+ set_bit(GLUE_FLAG_INT_BIT, &GlueInfo->ulFlag); -+ -+ /* when we got sdio interrupt, we wake up the tx servie thread */ -+ wake_up_interruptible(&GlueInfo->waitq); -+ -+ IsrPassCnt++; -+ GlueInfo->IsrPassCnt++; -+ return IRQ_HANDLED; -+ -+} -+ -+#if (CONF_HIF_DMA_INT == 1) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a SDIO interrupt callback function -+* -+* \param[in] func pointer to SDIO handle -+* -+* \return void -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+static irqreturn_t HifDmaISR(IN int Irq, IN void *Arg) -+{ -+ struct net_device *prNetDevice = (struct net_device *)Arg; -+ GLUE_INFO_T *GlueInfo; -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* Init */ -+ ASSERT(prNetDevice); -+ GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDevice)); -+ ASSERT(GlueInfo); -+ -+ if (!GlueInfo) -+ return IRQ_HANDLED; -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ /* disable interrupt */ -+ HifInfo->DmaOps->DmaAckIntr(HifInfo); -+ -+ /* Wake up main thread */ -+ set_bit(1, &HifInfo->HifDmaWaitFlg); -+ -+ /* when we got sdio interrupt, we wake up the tx servie thread */ -+ wake_up_interruptible(&HifInfo->HifDmaWaitq); -+ -+ return IRQ_HANDLED; -+ -+} -+#endif /* CONF_HIF_DMA_INT */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a SDIO probe function -+* -+* \param[in] func pointer to SDIO handle -+* \param[in] id pointer to SDIO device id table -+* -+* \return void -+*/ -+/*----------------------------------------------------------------------------*/ -+#if defined(CONFIG_MTK_CLKMGR) -+#if defined(MTK_EXTERNAL_LDO) || defined(MTK_ALPS_BOX_SUPPORT) -+#include -+#endif -+#endif -+ -+static int HifAhbProbe(VOID) -+{ -+ int Ret = 0; -+ -+ DBGLOG(INIT, INFO, "HifAhbProbe()\n"); -+ -+ /* power on WiFi TX PA 3.3V and HIF GDMA clock */ -+ { -+#ifdef CONFIG_MTK_PMIC_MT6397 -+#if defined(CONFIG_MTK_CLKMGR) -+#ifdef MTK_EXTERNAL_LDO -+ /* for 8127 tablet */ -+ mt_set_gpio_mode(GPIO51, GPIO_MODE_04); -+ mt_set_gpio_dir(GPIO51, GPIO_DIR_OUT); -+ mt_set_gpio_pull_enable(GPIO51, GPIO_PULL_ENABLE); -+ mt_set_gpio_pull_select(GPIO51, GPIO_PULL_UP); -+#elif defined(MTK_ALPS_BOX_SUPPORT) -+ /* for 8127 box */ -+ mt_set_gpio_mode(GPIO89, GPIO_MODE_04); -+ mt_set_gpio_dir(GPIO89, GPIO_DIR_OUT); -+ mt_set_gpio_pull_enable(GPIO89, GPIO_PULL_ENABLE); -+ mt_set_gpio_pull_select(GPIO89, GPIO_PULL_UP); -+#else -+ hwPowerOn(MT65XX_POWER_LDO_VGP4, VOL_3300, "WLAN"); -+#endif -+#endif -+#else -+#ifdef CONFIG_OF /*for MT6752 */ -+ mtk_wcn_consys_hw_wifi_paldo_ctrl(1); /* switch to HW mode */ -+#else /*for MT6572/82/92 */ -+ hwPowerOn(MT6323_POWER_LDO_VCN33_WIFI, VOL_3300, "WLAN"); -+ upmu_set_vcn33_on_ctrl_wifi(1); /* switch to HW mode */ -+#endif -+#endif -+ -+ } -+ -+#if (CONF_HIF_DEV_MISC == 1) -+ if (pfWlanProbe((PVOID) &MtkAhbDriver.this_device) != WLAN_STATUS_SUCCESS) { -+#else -+ if (pfWlanProbe((PVOID) &HifAhbPDev->dev) != WLAN_STATUS_SUCCESS) { -+#endif /* CONF_HIF_DEV_MISC */ -+ -+ pfWlanRemove(); -+ Ret = -1; -+ } -+ -+ return Ret; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do module remove. -+* -+* \param[in] None -+* -+* \return The result of remove (WLAN_STATUS_SUCCESS = 0) -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbRemove(VOID) -+{ -+ DBGLOG(INIT, INFO, "HifAhbRemove()\n"); -+ -+ pfWlanRemove(); -+ -+ { -+#ifdef CONFIG_MTK_PMIC_MT6397 -+#if defined(CONFIG_MTK_CLKMGR) -+#ifdef MTK_EXTERNAL_LDO -+ /* for 8127 tablet */ -+ mt_set_gpio_mode(GPIO51, GPIO_MODE_04); -+ mt_set_gpio_dir(GPIO51, GPIO_DIR_OUT); -+ mt_set_gpio_pull_enable(GPIO51, GPIO_PULL_ENABLE); -+ mt_set_gpio_pull_select(GPIO51, GPIO_PULL_DOWN); -+#elif defined(MTK_ALPS_BOX_SUPPORT) -+ /* for 8127 box */ -+ mt_set_gpio_mode(GPIO89, GPIO_MODE_04); -+ mt_set_gpio_dir(GPIO89, GPIO_DIR_OUT); -+ mt_set_gpio_pull_enable(GPIO89, GPIO_PULL_ENABLE); -+ mt_set_gpio_pull_select(GPIO89, GPIO_PULL_DOWN); -+#else -+ hwPowerDown(MT65XX_POWER_LDO_VGP4, "WLAN"); -+#endif -+#endif -+#else -+#ifdef CONFIG_OF /*for MT6752 */ -+ mtk_wcn_consys_hw_wifi_paldo_ctrl(0); /* switch to SW mode */ -+#else /*for MT6572/82/92 */ -+ upmu_set_vcn33_on_ctrl_wifi(0); /* switch to SW mode */ -+ hwPowerDown(MT6323_POWER_LDO_VCN33_WIFI, "WLAN"); -+#endif -+#endif -+ -+ } -+ -+ return 0; -+} -+ -+#if (MTK_WCN_SINGLE_MODULE == 0) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function gets the TX count pass through HIF AHB bus. -+* -+* \param[in] None -+* -+* \return TX count -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbBusCntGet(VOID) -+{ -+ return HifTxCnt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function resets the TX count pass through HIF AHB bus. -+* -+* \param[in] None -+* -+* \return 0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbBusCntClr(VOID) -+{ -+ HifTxCnt = 0; -+ return 0; -+} -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function configs the DMA TX/RX settings before any real TX/RX. -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] BurstLen 0(1DW), 1(4DW), 2(8DW), Others(Reserved) -+* \param[in] PortId 0(TXD0), 1(TXD1), 2(RXD0), 3(RXD1), 4(WHISR enhance) -+* \param[in] TransByte Should be 4-byte align. -+* -+* \return void -+*/ -+/*----------------------------------------------------------------------------*/ -+static UINT_32 HifAhbDmaEnhanceModeConf(IN GLUE_INFO_T * GlueInfo, UINT_32 BurstLen, UINT_32 PortId, UINT_32 TransByte) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ UINT_32 RegHSTCR; -+ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ RegHSTCR = HIF_REG_READL(HifInfo, MCR_WHIER); -+ -+ RegHSTCR = HIF_REG_READL(HifInfo, MCR_HSTCR); -+ RegHSTCR = -+ ((BurstLen << HSTCR_AFF_BURST_LEN_OFFSET) & HSTCR_AFF_BURST_LEN) | -+ ((PortId << HSTCR_TRANS_TARGET_OFFSET) & HSTCR_TRANS_TARGET) | -+ (((TransByte & 0x3) == 0) ? (TransByte & HSTCR_HSIF_TRANS_CNT) : ((TransByte + 4) & HSTCR_HSIF_TRANS_CNT)); -+ HIF_REG_WRITEL(HifInfo, MCR_HSTCR, RegHSTCR); -+ return RegHSTCR; -+} -+ -+VOID glSetPowerState(IN GLUE_INFO_T *GlueInfo, IN UINT_32 ePowerMode) -+{ -+ -+} -+ -+#if (CONF_HIF_DEV_MISC == 1) -+/* no use */ -+static ssize_t HifAhbMiscRead(IN struct file *Filp, OUT char __user *DstBuf, IN size_t Size, IN loff_t *Ppos) -+{ -+ return 0; -+} -+ -+static ssize_t HifAhbMiscWrite(IN struct file *Filp, IN const char __user *SrcBuf, IN size_t Size, IN loff_t *Ppos) -+{ -+ return 0; -+} -+ -+static int HifAhbMiscIoctl(IN struct file *Filp, IN unsigned int Cmd, IN unsigned long arg) -+{ -+ return 0; -+} -+ -+static int HifAhbMiscOpen(IN struct inode *Inodep, IN struct file *Filp) -+{ -+ return 0; -+} -+ -+static int HifAhbMiscClose(IN struct inode *Inodep, IN struct file *Filp) -+{ -+ return 0; -+} -+#else -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by OS platform device module. -+* -+* \param[in] PDev Pointer to the platform device structure. -+* -+* \return 0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbPltmProbe(IN struct platform_device *PDev) -+{ -+ HifAhbPDev = PDev; -+ -+ DBGLOG(INIT, INFO, "HifAhbPltmProbe\n"); -+ -+#if (CONF_HIF_PMIC_TEST == 1) -+ wmt_set_jtag_for_mcu(); -+ wmt_set_jtag_for_gps(); -+ -+#endif /* CONF_HIF_PMIC_TEST */ -+ -+#if (MTK_WCN_SINGLE_MODULE == 1) -+ HifAhbProbe(); /* only for test purpose without WMT module */ -+ -+#else -+ -+ /* register WiFi function to WMT */ -+ DBGLOG(INIT, INFO, "mtk_wcn_wmt_wlan_reg\n"); -+ { -+ MTK_WCN_WMT_WLAN_CB_INFO WmtCb; -+ -+ WmtCb.wlan_probe_cb = HifAhbProbe; -+ WmtCb.wlan_remove_cb = HifAhbRemove; -+ WmtCb.wlan_bus_cnt_get_cb = HifAhbBusCntGet; -+ WmtCb.wlan_bus_cnt_clr_cb = HifAhbBusCntClr; -+ mtk_wcn_wmt_wlan_reg(&WmtCb); -+ } -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by OS platform device module. -+* -+* \param[in] PDev Pointer to the platform device structure. -+* -+* \return 0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static int __exit HifAhbPltmRemove(IN struct platform_device *PDev) -+{ -+#if (MTK_WCN_SINGLE_MODULE == 0) -+ mtk_wcn_wmt_wlan_unreg(); -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by OS platform device module. -+* -+* \param[in] PDev Pointer to the platform device structure. -+* \param[in] Message -+* -+* \return 0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbPltmSuspend(IN struct platform_device *PDev, pm_message_t Message) -+{ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by OS platform device module. -+* -+* \param[in] PDev Pointer to the platform device structure. -+* -+* \return 0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbPltmResume(IN struct platform_device *PDev) -+{ -+ return 0; -+} -+#endif /* CONFIG_PM */ -+ -+#endif /* CONF_HIF_DEV_MISC */ -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Trigger to do HIF loopback test. -+* -+* \param[in] arg Pointer to the GLUE_INFO_T structure. -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifAhbLoopbkAuto(IN unsigned long arg) -+{ -+ -+ P_GLUE_INFO_T GlueInfo = (P_GLUE_INFO_T) arg; -+ GL_HIF_INFO_T *HifInfo = &GlueInfo->rHifInfo; -+ -+ ASSERT(GlueInfo); -+ -+ HIF_DBG(("[WiFi/HIF] Trigger to do loopback test...\n")); -+ -+ set_bit(GLUE_FLAG_HIF_LOOPBK_AUTO_BIT, &HifInfo->HifLoopbkFlg); -+ wake_up_interruptible(&HifInfo->HifWaitq); -+ -+} -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ -+VOID glDumpConnSysCpuInfo(P_GLUE_INFO_T prGlueInfo) -+{ -+ GL_HIF_INFO_T *prHifInfo = &prGlueInfo->rHifInfo; -+ unsigned short j; -+ -+ for (j = 0; j < 512; j++) { -+ DBGLOG(INIT, WARN, "0x%08x ", MCU_REG_READL(prHifInfo, CONN_MCU_CPUPCR)); -+ if ((j + 1) % 16 == 0) -+ DBGLOG(INIT, WARN, "\n"); -+ } -+} -+ -+/* End of ahb.c */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c -new file mode 100644 -index 0000000000000..6b719028ae934 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c -@@ -0,0 +1,31 @@ -+/****************************************************************************** -+*[File] mt6516-evb.c -+*[Version] v1.0 -+*[Revision Date] 2010-03-01 -+*[Author] -+*[Description] -+* dummy file for build system -+*[Copyright] -+* Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. -+******************************************************************************/ -+ -+/* -+** Log: mt6516-evb.c -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * remove debug message -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** -+*/ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h -new file mode 100644 -index 0000000000000..1507d5560040e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h -@@ -0,0 +1,340 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1 -+*/ -+ -+/*! \file "hif.h" -+ \brief Functions for the driver to register bus and setup the IRQ -+ -+ Functions for the driver to register bus and setup the IRQ -+*/ -+ -+/* -+** Log: hif.h -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add GPIO debug function -+ * -+ * 10 19 2010 jeffrey.chang -+ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK -+ * HIF by default -+ * Refine linux kernel module to the license of MTK and enable MTK HIF -+ * -+ * 08 18 2010 jeffrey.chang -+ * NULL -+ * support multi-function sdio -+ * -+ * 08 17 2010 cp.wu -+ * NULL -+ * add ENE SDIO host workaround for x86 linux platform. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\4 2009-10-20 17:38:28 GMT mtk01090 -+** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, -+** and then stop hw. -+** \main\maintrunk.MT5921\3 2009-09-28 20:19:20 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\2 2009-08-18 22:57:05 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\2 2008-09-22 23:18:17 GMT mtk01461 -+** Update driver for code review -+** Revision 1.1 2007/07/05 07:25:33 MTK01461 -+** Add Linux initial code, modify doc, add 11BB, RF init code -+** -+** Revision 1.3 2007/06/27 02:18:51 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+*/ -+ -+#ifndef _HIF_H -+#define _HIF_H -+ -+#include "gl_typedef.h" -+#include "mtk_porting.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#define CONF_MTK_AHB_DMA 1 /* PIO mode is default mode if DMA is disabled */ -+ -+#define CONF_HIF_DEV_MISC 0 /* register as misc device */ -+#define CONF_HIF_LOOPBACK_AUTO 0 /* hif loopback test triggered by open() */ -+ /* only for development test */ -+ -+#define CONF_HIF_PMIC_TEST 0 /* test purpose: power on CONNSYS */ -+ -+#define CONF_HIF_DMA_INT 0 /* DMA interrupt mode */ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern phys_addr_t gConEmiPhyBase; -+extern BOOLEAN fgIsResetting; -+extern UINT_32 IsrCnt, IsrPassCnt; -+extern int kalDevLoopbkThread(IN void *data); -+ -+#ifdef CONFIG_MTK_PMIC_MT6397 -+#else -+#ifdef CONFIG_OF /*for MT6752 */ -+extern INT_32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT_32 enable); -+#else /*for MT6572/82/92 */ -+extern void upmu_set_vcn33_on_ctrl_wifi(UINT_32 val); -+#endif -+#endif -+ -+#if (CONF_HIF_DEV_MISC == 1) -+#else -+/* extern INT32 mtk_wcn_consys_hw_reg_ctrl(UINT32 on, UINT32 co_clock_en); */ -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#ifndef CONN_MCU_CONFIG_BASE -+#define CONN_MCU_CONFIG_BASE 0xF8070000 /* MT6572 */ -+#endif /* CONN_MCU_CONFIG_BASE */ -+ -+#define CONSYS_CPUPCR_REG (CONN_MCU_CONFIG_BASE + 0x00000160) -+#define CONSYS_REG_READ(addr) (*((volatile unsigned int *)(addr))) -+ -+#define CONN_MCU_DRV_BASE 0x18070000 -+#define CONN_MCU_REG_LENGTH 0x0200 -+#define CONN_MCU_CPUPCR 0x0160 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/* host interface's private data structure, which is attached to os glue -+** layer info structure. -+ */ -+typedef struct _GL_HIF_DMA_OPS_T { /* DMA Operators */ -+ VOID (*DmaConfig)(IN VOID *HifInfo, IN VOID *Conf); -+ -+ VOID (*DmaStart)(IN VOID *HifInfo); -+ -+ VOID (*DmaStop)(IN VOID *HifInfo); -+ -+ MTK_WCN_BOOL (*DmaPollStart)(IN VOID *HifInfo); -+ -+ MTK_WCN_BOOL (*DmaPollIntr)(IN VOID *HifInfo); -+ -+ VOID (*DmaAckIntr)(IN VOID *HifInfo); -+ -+ VOID (*DmaClockCtrl)(IN UINT_32 FlgIsEnabled); -+ -+ VOID (*DmaRegDump)(IN VOID *HifInfo); -+ -+ VOID (*DmaReset)(IN VOID *HifInfo); -+ -+} GL_HIF_DMA_OPS_T; -+ -+typedef struct _GL_HIF_INFO_T { -+ -+ /* General */ -+ VOID *Dev; /* struct device */ -+ -+#define MTK_CHIP_ID_6571 0x6571 -+#define MTK_CHIP_ID_6572 0x6572 -+#define MTK_CHIP_ID_6582 0x6582 -+#define MTK_CHIP_ID_8127 0x8127 -+#define MTK_CHIP_ID_6752 0x6752 -+#define MTK_CHIP_ID_8163 0x8163 -+#define MTK_CHIP_ID_6735 0x6735 -+#define MTK_CHIP_ID_6580 0x6580 -+#define MTK_CHIP_ID_6755 0x6755 -+#define MTK_CHIP_ID_7623 0x7623 -+ -+ UINT_32 ChipID; -+ -+ /* Control flag */ -+ BOOLEAN fgIntReadClear; -+ BOOLEAN fgMbxReadClear; -+ BOOLEAN fgDmaEnable; /* TRUE: DMA mode is used (default) */ -+ -+ /* HIF related */ -+ UINT_8 *HifRegBaseAddr; /* HIF register base */ -+ UINT_8 *McuRegBaseAddr; /* CONN MCU register base */ -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+ struct timer_list HifTmrLoopbkFn; /* HIF loopback test trigger timer */ -+ wait_queue_head_t HifWaitq; -+ UINT_32 HifLoopbkFlg; -+ struct task_struct *HifTaskLoopbkFn; /* HIF loopback test task */ -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ -+#if (CONF_HIF_DMA_INT == 1) -+ wait_queue_head_t HifDmaWaitq; -+ UINT_32 HifDmaWaitFlg; -+#endif /* CONF_HIF_DMA_INT */ -+ -+ /* DMA related */ -+#define AP_DMA_HIF_LOCK(_lock) /* spin_lock_bh(&(_lock)->DdmaLock) */ -+#define AP_DMA_HIF_UNLOCK(_lock) /* spin_unlock_bh(&(_lock)->DdmaLock) */ -+ spinlock_t DdmaLock; /* protect DMA access */ -+ -+ UINT_8 *DmaRegBaseAddr; /* DMA register base */ -+ GL_HIF_DMA_OPS_T *DmaOps; /* DMA Operators */ -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+ struct clk *clk_wifi_dma; -+#endif -+} GL_HIF_INFO_T, *P_GL_HIF_INFO_T; -+ -+#define HIF_MOD_NAME "AHB_SLAVE_HIF" -+ -+#define HIF_DRV_BASE 0x180F0000 -+#define HIF_DRV_LENGTH 0x005c -+ -+typedef enum _MTK_WCN_HIF_BURST_LEN { -+ HIF_BURST_1DW = 0, -+ HIF_BURST_4DW, -+ HIF_BURST_8DW -+} MTK_WCN_HIF_BURST_LEN; -+ -+typedef enum _MTK_WCN_HIF_TXRX_TARGET { -+ HIF_TARGET_TXD0 = 0, -+ HIF_TARGET_TXD1, -+ HIF_TARGET_RXD0, -+ HIF_TARGET_RXD1, -+ HIF_TARGET_WHISR -+} MTK_WCN_HIF_TXRX_TARGET; -+ -+typedef enum _MTK_WCN_HIF_DMA_DIR { -+ HIF_DMA_DIR_TX = 0, -+ HIF_DMA_DIR_RX -+} MTK_WCN_HIF_DMA_DIR; -+ -+typedef struct _MTK_WCN_HIF_DMA_CONF { -+ UINT_32 Count; -+ MTK_WCN_HIF_DMA_DIR Dir; -+ UINT_32 Burst; -+ UINT_32 Wsize; -+ UINT_32 Ratio; -+ UINT_32 Connect; -+ UINT_32 Fix_en; -+ ULONG Src; -+ ULONG Dst; -+} MTK_WCN_HIF_DMA_CONF; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define MCU_REG_READL(_hif, _addr) \ -+ readl((volatile UINT_32 *)((_hif)->McuRegBaseAddr + _addr)) -+ -+/* PIO mode HIF register read/write */ -+#define HIF_REG_READL(_hif, _addr) \ -+ readl((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr)) -+ -+#define HIF_REG_WRITEL(_hif, _addr, _val) \ -+ writel(_val, ((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr))) -+ -+#define HIF_REG_WRITEB(_hif, _addr, _val) \ -+ writeb(_val, ((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr))) -+ -+/* PIO mode DMA register read/write */ -+#define HIF_DMAR_READL(_hif, _addr) \ -+ readl((volatile UINT_32 *)((_hif)->DmaRegBaseAddr + _addr)) -+ -+#define HIF_DMAR_WRITEL(_hif, _addr, _val) \ -+ writel(_val, ((volatile UINT_32 *)((_hif)->DmaRegBaseAddr + _addr))) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#ifndef MODULE_AHB_DMA -+VOID HifDumpEnhanceModeData(P_ADAPTER_T prAdapter); -+ -+VOID HifRegDump(P_ADAPTER_T prAdapter); -+ -+BOOLEAN HifIsFwOwn(P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS glRegisterBus(probe_card pfProbe, remove_card pfRemove); -+ -+VOID glUnregisterBus(remove_card pfRemove); -+ -+VOID glResetHif(GLUE_INFO_T *GlueInfo); -+ -+VOID glSetHifInfo(P_GLUE_INFO_T prGlueInfo, ULONG ulCookie); -+ -+VOID glClearHifInfo(P_GLUE_INFO_T prGlueInfo); -+ -+VOID glGetChipInfo(GLUE_INFO_T *GlueInfo, UINT_8 *pucChipBuf); -+ -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+BOOLEAN glIsChipNeedWakelock(GLUE_INFO_T *GlueInfo); -+#endif -+ -+BOOLEAN glBusInit(PVOID pvData); -+ -+VOID glBusRelease(PVOID pData); -+ -+INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie); -+ -+VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie); -+ -+VOID glSetPowerState(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 ePowerMode); -+ -+VOID glDumpConnSysCpuInfo(P_GLUE_INFO_T prGlueInfo); -+ -+#endif /* MODULE_AHB_DMA */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Config GDMA TX/RX. -+* -+* \param[in] DmaRegBaseAddr Pointer to the IO register base. -+* \param[in] Conf Pointer to the DMA operator. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID HifGdmaInit(GL_HIF_INFO_T *HifInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Config PDMA TX/RX. -+* -+* \param[in] DmaRegBaseAddr Pointer to the IO register base. -+* \param[in] Conf Pointer to the DMA operator. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID HifPdmaInit(GL_HIF_INFO_T *HifInfo); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _HIF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h -new file mode 100644 -index 0000000000000..094c07f98eff2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h -@@ -0,0 +1,154 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1 -+*/ -+ -+/*! \file "hif_gdma.h" -+ \brief MARCO, definition, structure for GDMA. -+ -+ MARCO, definition, structure for GDMA. -+*/ -+ -+/* -+** Log: hif_gdma.h -+ * -+ * 01 16 2013 vend_samp.lin -+ * Add AHB GDMA support -+ * 1) Initial version -+** -+*/ -+ -+#ifndef _HIF_GDMA_H -+#define _HIF_GDMA_H -+ -+#include "mtk_porting.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _MTK_WCN_HIF_GDMA_BURST_LEN { -+ HIF_GDMA_BURST_1_8 = 0, -+ HIF_GDMA_BURST_2_8, -+ HIF_GDMA_BURST_3_8, -+ HIF_GDMA_BURST_4_8, -+ HIF_GDMA_BURST_5_8, -+ HIF_GDMA_BURST_6_8, -+ HIF_GDMA_BURST_7_8, -+ HIF_GDMA_BURST_8_8 /* same as HIF_GDMA_BURST_7_8 */ -+} MTK_WCN_HIF_GDMA_BURST_LEN; -+ -+typedef enum _MTK_WCN_HIF_GDMA_WRITE_LEN { -+ HIF_GDMA_WRITE_0 = 0, /* transaction size is 1 byte */ -+ HIF_GDMA_WRITE_1, /* transaction size is 2 byte */ -+ HIF_GDMA_WRITE_2, /* transaction size is 4 byte */ -+ HIF_GDMA_WRITE_3 /* transaction size is 1 byte */ -+} MTK_WCN_HIF_GDMA_WRITE_LEN; -+ -+typedef enum _MTK_WCN_HIF_GDMA_RATIO { -+ HIF_GDMA_RATIO_0 = 0, /* 1/2 */ -+ HIF_GDMA_RATIO_1 /* 1/1 */ -+} MTK_WCN_HIF_GDMA_RATIO; -+ -+typedef enum _MTK_WCN_HIF_GDMA_CONNECT { -+ HIF_GDMA_CONNECT_NO = 0, /* no connect */ -+ HIF_GDMA_CONNECT_SET1, /* connect set1 (req/ack) */ -+ HIF_GDMA_CONNECT_SET2, /* connect set2 (req/ack) */ -+ HIF_GDMA_CONNECT_SET3 /* connect set3 (req/ack) */ -+} MTK_WCN_HIF_GDMA_CONNECT; -+ -+/* reference to MT6572_AP_P_DMA_Spec.doc */ -+#define AP_DMA_HIF_BASE 0x11000100 -+ -+#define AP_P_DMA_G_DMA_2_INT_FLAG (0x0000) -+#define AP_P_DMA_G_DMA_2_CON (0x0018) -+#define AP_P_DMA_G_DMA_2_CONNECT (0x0034) -+#define AP_P_DMA_G_DMA_2_LEN1 (0x0024) -+#define AP_P_DMA_G_DMA_2_SRC_ADDR (0x001C) -+#define AP_P_DMA_G_DMA_2_DST_ADDR (0x0020) -+#define AP_P_DMA_G_DMA_2_INT_EN (0x0004) -+#define AP_P_DMA_G_DMA_2_EN (0x0008) -+#define AP_P_DMA_G_DMA_2_RST (0x000C) -+#define AP_P_DMA_G_DMA_2_STOP (0x0010) -+ -+#define AP_DMA_HIF_0_LENGTH 0x0038 -+ -+/* AP_DMA_HIF_0_INT_FLAG */ -+#define ADH_CR_FLAG_0 BIT(0) -+ -+/* AP_DMA_HIF_0_INT_EN */ -+#define ADH_CR_INTEN_FLAG_0 BIT(0) -+ -+/* AP_DMA_HIF_0_EN */ -+#define ADH_CR_EN BIT(0) -+#define ADH_CR_CONN_BUR_EN BIT(1) -+ -+/* AP_DMA_HIF_0_STOP */ -+#define ADH_CR_PAUSE BIT(1) -+#define ADH_CR_STOP BIT(0) -+ -+/* AP_P_DMA_G_DMA_2_CON */ -+#define ADH_CR_FLAG_FINISH BIT(30) -+#define ADH_CR_RSIZE BITS(28, 29) -+#define ADH_CR_RSIZE_OFFSET 28 -+#define ADH_CR_WSIZE BITS(24, 25) -+#define ADH_CR_WSIZE_OFFSET 24 -+#define ADH_CR_BURST_LEN BITS(16, 18) -+#define ADH_CR_BURST_LEN_OFFSET 16 -+#define ADH_CR_WADDR_FIX_EN BIT(3) -+#define ADH_CR_WADDR_FIX_EN_OFFSET 3 -+#define ADH_CR_RADDR_FIX_EN BIT(4) -+#define ADH_CR_RADDR_FIX_EN_OFFSET 4 -+ -+/* AP_P_DMA_G_DMA_2_CONNECT */ -+#define ADH_CR_RATIO BIT(3) -+#define ADH_CR_RATIO_OFFSET 3 -+#define ADH_CR_DIR BIT(2) -+#define ADH_CR_DIR_OFFSET 2 -+#define ADH_CR_CONNECT BITS(0, 1) -+ -+/* AP_DMA_HIF_0_LEN */ -+#define ADH_CR_LEN BITS(0, 19) -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _HIF_GDMA_H */ -+ -+/* End of hif_gdma.h */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h -new file mode 100644 -index 0000000000000..32224e8f17d85 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h -@@ -0,0 +1,141 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1 -+*/ -+ -+/*! \file "hif_pdma.h" -+ \brief MARCO, definition, structure for PDMA. -+ -+ MARCO, definition, structure for PDMA. -+*/ -+ -+/* -+** Log: hif_pdma.h -+ * -+ * 01 16 2013 vend_samp.lin -+ * Add AHB PDMA support -+ * 1) Initial version -+** -+*/ -+ -+#ifndef _HIF_PDMA_H -+#define _HIF_PDMA_H -+ -+#include "mtk_porting.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _MTK_WCN_HIF_PDMA_BURST_LEN { -+ HIF_PDMA_BURST_1_4 = 0, -+ HIF_PDMA_BURST_2_4, -+ HIF_PDMA_BURST_3_4, -+ HIF_PDMA_BURST_4_4 -+} MTK_WCN_HIF_PDMA_BURST_LEN; -+ -+/* reference to MT6572_AP_P_DMA_Spec.doc */ -+#ifdef CONFIG_OF -+/*for MT6752*/ -+#define AP_DMA_HIF_BASE 0x11000080 -+#else -+/*for MT6572/82/92*/ -+#define AP_DMA_HIF_BASE 0x11000180 -+#endif -+ -+#define AP_DMA_HIF_0_INT_FLAG (0x0000) -+#define AP_DMA_HIF_0_INT_EN (0x0004) -+#define AP_DMA_HIF_0_EN (0x0008) -+#define AP_DMA_HIF_0_RST (0x000C) -+#define AP_DMA_HIF_0_STOP (0x0010) -+#define AP_DMA_HIF_0_FLUSH (0x0014) -+#define AP_DMA_HIF_0_CON (0x0018) -+#define AP_DMA_HIF_0_SRC_ADDR (0x001C) -+#define AP_DMA_HIF_0_DST_ADDR (0x0020) -+#define AP_DMA_HIF_0_LEN (0x0024) -+#define AP_DMA_HIF_0_INT_BUF_SIZE (0x0038) -+#define AP_DMA_HIF_0_DEBUG_STATUS (0x0050) -+#define AP_DMA_HIF_0_SRC_ADDR2 (0x0054) -+#define AP_DMA_HIF_0_DST_ADDR2 (0x0058) -+ -+#define AP_DMA_HIF_0_LENGTH 0x0080 -+ -+/* AP_DMA_HIF_0_INT_FLAG */ -+#define ADH_CR_FLAG_0 BIT(0) -+ -+/* AP_DMA_HIF_0_INT_EN */ -+#define ADH_CR_INTEN_FLAG_0 BIT(0) -+ -+/* AP_DMA_HIF_0_EN */ -+#define ADH_CR_EN BIT(0) -+ -+/* AP_DMA_HIF_0_RST */ -+#define ADH_CR_HARD_RST BIT(1) -+#define ADH_CR_WARM_RST BIT(0) -+ -+/* AP_DMA_HIF_0_STOP */ -+#define ADH_CR_PAUSE BIT(1) -+#define ADH_CR_STOP BIT(0) -+ -+/* AP_DMA_HIF_0_FLUSH */ -+#define ADH_CR_FLUSH BIT(0) -+ -+/* AP_DMA_HIF_0_CON */ -+#define ADH_CR_BURST_LEN BITS(16, 17) -+#define ADH_CR_BURST_LEN_OFFSET 16 -+#define ADH_CR_SLOW_CNT BITS(5, 14) -+#define ADH_CR_SLOW_EN BIT(2) -+#define ADH_CR_FIX_EN BIT(1) -+#define ADH_CR_FIX_EN_OFFSET 1 -+#define ADH_CR_DIR BIT(0) -+ -+/* AP_DMA_HIF_0_LEN */ -+#define ADH_CR_LEN BITS(0, 19) -+ -+/* AP_DMA_HIF_0_SRC_ADDR2 */ -+#define ADH_CR_SRC_ADDR2 BIT(0) -+/* AP_DMA_HIF_0_DST_ADDR2 */ -+#define ADH_CR_DST_ADDR2 BIT(0) -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _HIF_PDMA_H */ -+ -+/* End of hif_gdma.h */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h -new file mode 100644 -index 0000000000000..91557137af9af ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h -@@ -0,0 +1,91 @@ -+/* porting layer */ -+/* Android */ -+ -+#ifndef _MTK_PORTING_H_ -+#define _MTK_PORTING_H_ -+ -+#include /* include stddef.h for NULL */ -+ -+#define CONF_MTK_AHB_DMA 1 -+ -+/* Type definition for signed integers */ -+/*typedef signed char INT8, *PINT8; -+typedef signed short INT16, *PINT16; -+typedef signed int INT_32, *PINT32;*/ -+ -+/* Type definition for unsigned integers */ -+/*typedef unsigned char UINT8, *PUINT8; -+typedef unsigned short UINT16, *PUINT16; -+typedef unsigned int UINT32, *PUINT32;*/ -+ -+#ifndef VOID -+/*typedef void VOID, *PVOID;*/ -+#endif -+ -+#ifndef IN -+#define IN -+#endif -+ -+#ifndef OUT -+#define OUT -+#endif -+ -+#ifndef INTOUT -+#define INOUT -+#endif -+ -+#ifndef TRUE -+#define TRUE 1 -+#endif -+ -+#ifndef FALSE -+#define FALSE 0 -+#endif -+ -+#ifndef BIT -+#define BIT(n) ((UINT_32) 1U << (n)) -+#endif /* BIT */ -+ -+#ifndef BITS -+/* bits range: for example BITS(16,23) = 0xFF0000 -+ * ==> (BIT(m)-1) = 0x0000FFFF ~(BIT(m)-1) => 0xFFFF0000 -+ * ==> (BIT(n+1)-1) = 0x00FFFFFF -+ */ -+#define BITS(m, n) (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n))) -+#endif /* BIT */ -+ -+#ifndef BOOLEAN -+#define BOOLEAN unsigned char -+#endif -+ -+typedef int MTK_WCN_BOOL; -+#ifndef MTK_WCN_BOOL_TRUE -+#define MTK_WCN_BOOL_FALSE ((MTK_WCN_BOOL) 0) -+#define MTK_WCN_BOOL_TRUE ((MTK_WCN_BOOL) 1) -+#endif -+ -+typedef int MTK_WCN_MUTEX; -+ -+typedef int MTK_WCN_TIMER; -+ -+/* system APIs */ -+/* mutex */ -+typedef MTK_WCN_MUTEX(*MUTEX_CREATE) (const char *const name); -+typedef INT_32(*MUTEX_DESTROY) (MTK_WCN_MUTEX mtx); -+typedef INT_32(*MUTEX_LOCK) (MTK_WCN_MUTEX mtx); -+typedef INT_32(*MUTEX_UNLOCK) (MTK_WCN_MUTEX mtx, unsigned long flags); -+/* debug */ -+typedef INT_32(*DBG_PRINT) (const char *str, ...); -+typedef INT_32(*DBG_ASSERT) (INT_32 expr, const char *file, INT_32 line); -+/* timer */ -+typedef void (*MTK_WCN_TIMER_CB) (void); -+typedef MTK_WCN_TIMER(*TIMER_CREATE) (const char *const name); -+typedef INT_32(*TIMER_DESTROY) (MTK_WCN_TIMER tmr); -+typedef INT_32(*TIMER_START) (MTK_WCN_TIMER tmr, UINT_32 timeout, MTK_WCN_TIMER_CB tmr_cb, void *param); -+typedef INT_32(*TIMER_STOP) (MTK_WCN_TIMER tmr); -+/* kernel lib */ -+typedef void *(*SYS_MEMCPY) (void *dest, const void *src, UINT_32 n); -+typedef void *(*SYS_MEMSET) (void *s, INT_32 c, UINT_32 n); -+typedef INT_32(*SYS_SPRINTF) (char *str, const char *format, ...); -+ -+#endif /* _MTK_PORTING_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c -new file mode 100644 -index 0000000000000..94cc05ba32249 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c -@@ -0,0 +1,480 @@ -+/****************************************************************************** -+*[File] ahb_pdma.c -+*[Version] v1.0 -+*[Revision Date] 2013-03-13 -+*[Author] -+*[Description] -+* The program provides AHB PDMA driver -+*[Copyright] -+* Copyright (C) 2013 MediaTek Incorporation. All Rights Reserved. -+******************************************************************************/ -+ -+/* -+** Log: ahb_pdma.c -+ * -+ * 03 13 2013 vend_samp.lin -+ * Add AHB PDMA support -+ * 1) Initial version -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#define MODULE_AHB_DMA -+ -+#include /* constant of kernel version */ -+ -+#include /* bitops.h */ -+ -+#include /* struct timer_list */ -+#include /* jiffies */ -+#include /* udelay and mdelay macro */ -+ -+#if 0 -+#if CONFIG_ANDROID -+#include -+#endif -+#endif -+ -+#include /* IRQT_FALLING */ -+ -+#include /* struct net_device, struct net_device_stats */ -+#include /* for eth_type_trans() function */ -+#include /* struct iw_statistics */ -+#include -+#include /* struct in_device */ -+ -+#include /* struct iphdr */ -+ -+#include /* for memcpy()/memset() function */ -+#include /* for offsetof() macro */ -+ -+#include /* The proc filesystem constants/structures */ -+ -+#include /* for rtnl_lock() and rtnl_unlock() */ -+#include /* kthread_should_stop(), kthread_run() */ -+#include /* for copy_from_user() */ -+#include /* for firmware download */ -+#include -+ -+#include /* for kfifo interface */ -+#include /* for cdev interface */ -+ -+#include /* for firmware download */ -+ -+#include -+ -+#include /* readw and writew */ -+ -+#include -+ -+#if defined(CONFIG_MTK_CLKMGR) -+#include -+#else -+#include -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ -+#include "hif.h" -+#include "hif_pdma.h" -+#include "gl_os.h" -+ -+/* #include */ -+ -+/* #if (CONF_MTK_AHB_DMA == 1) */ -+ -+/* #define PDMA_DEBUG_SUP */ -+ -+#ifdef PDMA_DEBUG_SUP -+#define PDMA_DBG pr_debug -+#else -+#define PDMA_DBG(_fmt, ...) -+#endif /* PDMA_DEBUG_SUP */ -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+struct clk *g_clk_wifi_pdma; -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static VOID HifPdmaConfig(IN void *HifInfoSrc, IN void *Conf); -+ -+static VOID HifPdmaStart(IN void *HifInfoSrc); -+ -+static VOID HifPdmaStop(IN void *HifInfoSrc); -+ -+static MTK_WCN_BOOL HifPdmaPollStart(IN void *HifInfoSrc); -+ -+static MTK_WCN_BOOL HifPdmaPollIntr(IN void *HifInfoSrc); -+ -+static VOID HifPdmaAckIntr(IN void *HifInfoSrc); -+ -+static VOID HifPdmaClockCtrl(IN UINT32 FlgIsEnabled); -+ -+static VOID HifPdmaRegDump(IN void *HifInfoSrc); -+ -+static VOID HifPdmaReset(IN void *HifInfoSrc); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+GL_HIF_DMA_OPS_T HifPdmaOps = { -+ .DmaConfig = HifPdmaConfig, -+ .DmaStart = HifPdmaStart, -+ .DmaStop = HifPdmaStop, -+ .DmaPollStart = HifPdmaPollStart, -+ .DmaPollIntr = HifPdmaPollIntr, -+ .DmaAckIntr = HifPdmaAckIntr, -+ .DmaClockCtrl = HifPdmaClockCtrl, -+ .DmaRegDump = HifPdmaRegDump, -+ .DmaReset = HifPdmaReset -+}; -+ -+/******************************************************************************* -+* P U B L I C F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Config PDMA TX/RX. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] Conf Pointer to the settings. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID HifPdmaInit(GL_HIF_INFO_T *HifInfo) -+{ -+ /* IO remap PDMA register memory */ -+#ifdef AP_DMA_HIF_BASE -+#undef AP_DMA_HIF_BASE -+#define AP_DMA_HIF_BASE 0x11000180 -+#endif -+ HifInfo->DmaRegBaseAddr = ioremap(AP_DMA_HIF_BASE, AP_DMA_HIF_0_LENGTH); -+ -+ /* assign PDMA operators */ -+ HifInfo->DmaOps = &HifPdmaOps; -+ -+ /* enable PDMA mode */ -+ HifInfo->fgDmaEnable = TRUE; -+ -+ /* Set EMI protection here */ -+#if 0 -+#ifdef MTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT -+ DBGLOG(INIT, INFO, "WIFI set EMI MPU for TEE project\n"); -+ emi_mpu_set_region_protection(gConEmiPhyBase, -+ gConEmiPhyBase + SZ_1M / 2, -+ 5, SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN)); -+#else -+ DBGLOG(INIT, INFO, "WIFI set EMI MPU for non-TEE project\n"); -+ emi_mpu_set_region_protection(gConEmiPhyBase, -+ gConEmiPhyBase + SZ_1M / 2, -+ 4, SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN)); -+#endif -+#endif -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+ g_clk_wifi_pdma = HifInfo->clk_wifi_dma; -+#endif -+ -+ PDMA_DBG("PDMA> HifPdmaInit ok!\n"); -+} -+ -+/******************************************************************************* -+* P R I V A T E F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Config PDMA TX/RX. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* \param[in] Param Pointer to the settings. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaConfig(IN void *HifInfoSrc, IN void *Param) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ MTK_WCN_HIF_DMA_CONF *Conf = (MTK_WCN_HIF_DMA_CONF *) Param; -+ UINT32 RegVal; -+ -+ /* Assign fixed value */ -+ Conf->Burst = HIF_PDMA_BURST_4_4; /* vs. HIF_BURST_4DW */ -+ Conf->Fix_en = FALSE; -+ -+ /* AP_P_DMA_G_DMA_2_CON */ -+ PDMA_DBG("PDMA> Conf->Dir = %d\n", Conf->Dir); -+ -+ /* AP_DMA_HIF_0_CON */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_CON); -+ RegVal &= ~(ADH_CR_BURST_LEN | ADH_CR_FIX_EN | ADH_CR_DIR); -+ RegVal |= (((Conf->Burst << ADH_CR_BURST_LEN_OFFSET) & ADH_CR_BURST_LEN) | -+ (Conf->Fix_en << ADH_CR_FIX_EN_OFFSET) | (Conf->Dir)); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_CON, RegVal); -+ PDMA_DBG("PDMA> AP_DMA_HIF_0_CON = 0x%08x\n", RegVal); -+ -+ /* AP_DMA_HIF_0_SRC_ADDR */ -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_SRC_ADDR, Conf->Src); -+ PDMA_DBG("PDMA> AP_DMA_HIF_0_SRC_ADDR = 0x%08lx\n", Conf->Src); -+ -+ /* AP_DMA_HIF_0_DST_ADDR */ -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_DST_ADDR, Conf->Dst); -+ PDMA_DBG("PDMA> AP_DMA_HIF_0_DST_ADDR = 0x%08lx\n", Conf->Dst); -+ -+ /* AP_DMA_HIF_0_LEN */ -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_LEN, (Conf->Count & ADH_CR_LEN)); -+ PDMA_DBG("PDMA> AP_DMA_HIF_0_LEN = %u\n", (UINT_32)(Conf->Count & ADH_CR_LEN)); -+ -+} /* End of HifPdmaConfig */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Start PDMA TX/RX. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaStart(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegVal; -+ -+ /* Enable interrupt */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_EN); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_EN, (RegVal | ADH_CR_INTEN_FLAG_0)); -+ -+ /* Start DMA */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_EN, (RegVal | ADH_CR_EN)); -+ -+ PDMA_DBG("PDMA> HifPdmaStart...\n"); -+ -+} /* End of HifPdmaStart */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Stop PDMA TX/RX. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaStop(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegVal; -+/* UINT32 pollcnt; */ -+ -+ /* Disable interrupt */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_EN); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_EN, (RegVal & ~(ADH_CR_INTEN_FLAG_0))); -+ -+#if 0 /* DE says we donot need to do it */ -+ /* Stop DMA */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_STOP); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_STOP, (RegVal | ADH_CR_STOP)); -+ -+ /* Polling START bit turn to 0 */ -+ pollcnt = 0; -+ do { -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN); -+ if (pollcnt++ > 100000) -+ ; /* TODO: warm reset PDMA */ -+ } while (RegVal & ADH_CR_EN); -+#endif -+ -+} /* End of HifPdmaStop */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Enable PDMA TX/RX. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static MTK_WCN_BOOL HifPdmaPollStart(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegVal; -+ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN); -+ return ((RegVal & ADH_CR_EN) != 0) ? TRUE : FALSE; -+ -+} /* End of HifPdmaPollStart */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Poll PDMA TX/RX done. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static MTK_WCN_BOOL HifPdmaPollIntr(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegVal; -+ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_FLAG); -+ return ((RegVal & ADH_CR_FLAG_0) != 0) ? TRUE : FALSE; -+ -+} /* End of HifPdmaPollIntr */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Acknowledge PDMA TX/RX done. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaAckIntr(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegVal; -+ -+ /* Write 0 to clear interrupt */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_FLAG); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_FLAG, (RegVal & ~ADH_CR_FLAG_0)); -+ -+} /* End of HifPdmaAckIntr */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Acknowledge PDMA TX/RX done. -+* -+* \param[in] FlgIsEnabled TRUE: enable; FALSE: disable -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaClockCtrl(IN UINT32 FlgIsEnabled) -+{ -+#if !defined(CONFIG_MTK_CLKMGR) -+ int ret = 0; -+#endif -+#if defined(CONFIG_MTK_CLKMGR) -+ if (FlgIsEnabled == TRUE) -+ enable_clock(MT_CG_INFRA_APDMA, "WLAN"); -+ else -+ disable_clock(MT_CG_INFRA_APDMA, "WLAN"); -+#else -+ if (FlgIsEnabled == TRUE) { -+ ret = clk_prepare_enable(g_clk_wifi_pdma); -+ if (ret) -+ DBGLOG(INIT, TRACE, "[CCF]clk_prepare_enable ret= %d\n", ret); -+ } else { -+ clk_disable_unprepare(g_clk_wifi_pdma); -+ } -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dump PDMA related registers. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaRegDump(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegId, RegVal; -+ UINT32 RegNum = 0; -+ -+ DBGLOG(INIT, INFO, "PDMA> Register content 0x%x=\n\t", AP_DMA_HIF_BASE); -+ for (RegId = 0; RegId < AP_DMA_HIF_0_LENGTH; RegId += 4) { -+ RegVal = HIF_DMAR_READL(HifInfo, RegId); -+ DBGLOG(INIT, INFO, "0x%08x ", RegVal); -+ -+ if (RegNum++ >= 3) { -+ DBGLOG(INIT, INFO, "\n"); -+ DBGLOG(INIT, INFO, "PDMA> Register content 0x%x=\n\t", AP_DMA_HIF_BASE + RegId + 4); -+ RegNum = 0; -+ } -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Reset DMA. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaReset(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 LoopCnt; -+ -+ /* do warm reset: DMA will wait for current traction finished */ -+ DBGLOG(INIT, INFO, "\nDMA> do warm reset...\n"); -+ -+ /* normally, we need to sure that bit0 of AP_P_DMA_G_DMA_2_EN is 1 here */ -+ -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x01); -+ -+ for (LoopCnt = 0; LoopCnt < 10000; LoopCnt++) { -+ if (!HifPdmaPollStart(HifInfo)) -+ break; /* reset ok */ -+ } -+ -+ if (HifPdmaPollStart(HifInfo)) { -+ /* do hard reset because warm reset fails */ -+ DBGLOG(INIT, INFO, "\nDMA> do hard reset...\n"); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x02); -+ mdelay(1); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x00); -+ } -+} -+ -+/* #endif */ /* CONF_MTK_AHB_DMA */ -+ -+/* End of ahb_pdma.c */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h -new file mode 100644 -index 0000000000000..ec9f46bdab2e4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h -@@ -0,0 +1,341 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_cfg80211.h#1 -+*/ -+ -+/*! \file gl_cfg80211.h -+ \brief This file is for Portable Driver linux cfg80211 support. -+*/ -+ -+/* -+** Log: gl_cfg80211.h -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 30 2012 chinglan.wang -+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only -+** . -+ * -+*/ -+ -+#ifndef _GL_CFG80211_H -+#define _GL_CFG80211_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#include -+#include -+ -+#include "gl_os.h" -+extern void wlanHandleSystemResume(void); -+extern void wlanHandleSystemSuspend(void); -+extern void p2pHandleSystemResume(void); -+extern void p2pHandleSystemSuspend(void); -+ -+#if CFG_SUPPORT_WAPI -+extern UINT_8 keyStructBuf[1024]; /* add/remove key shared buffer */ -+#else -+extern UINT_8 keyStructBuf[100]; /* add/remove key shared buffer */ -+#endif -+ -+extern struct delayed_work sched_workq; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#if CONFIG_NL80211_TESTMODE -+#define NL80211_DRIVER_TESTMODE_VERSION 2 -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+#if CONFIG_NL80211_TESTMODE -+ -+typedef struct _NL80211_DRIVER_GET_STA_STATISTICS_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_32 u4Version; -+ UINT_32 u4Flag; -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+} NL80211_DRIVER_GET_STA_STATISTICS_PARAMS, *P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS; -+ -+typedef struct _NL80211_DRIVER_POORLINK_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ INT_8 cRssi; /* cRssi=0 means it is a invalid value. */ -+ UINT_8 ucLinkSpeed; /* ucLinkSpeed=0 means it is a invalid value */ -+ UINT_16 u2Reserved; -+} NL80211_DRIVER_POORLINK_PARAMS, *P_NL80211_DRIVER_POORLINK_PARAMS; -+ -+typedef enum _ENUM_TESTMODE_STA_STATISTICS_ATTR { -+ NL80211_TESTMODE_STA_STATISTICS_INVALID = 0, -+ NL80211_TESTMODE_STA_STATISTICS_VERSION, -+ NL80211_TESTMODE_STA_STATISTICS_MAC, -+ NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, -+ NL80211_TESTMODE_STA_STATISTICS_FLAG, -+ -+ NL80211_TESTMODE_STA_STATISTICS_PER, -+ NL80211_TESTMODE_STA_STATISTICS_RSSI, -+ NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, -+ NL80211_TESTMODE_STA_STATISTICS_TX_RATE, -+ -+ NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, -+ -+ NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, -+ NL80211_TESTMODE_STA_STATISTICS_MAX_PROCESS_TIME, -+ NL80211_TESTMODE_STA_STATISTICS_AVG_HIF_PROCESS_TIME, -+ NL80211_TESTMODE_STA_STATISTICS_MAX_HIF_PROCESS_TIME, -+ -+ NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, -+ -+ NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, -+ NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, -+ -+ NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, -+ NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, -+ -+ /* -+ * how many packages TX during statistics interval -+ */ -+ NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, -+ -+ /* -+ * how many packages this TX during statistics interval -+ */ -+ NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, -+ -+ /* -+ * how many packages dequeue during statistics interval -+ */ -+ NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, -+ -+ /* -+ * how many packages this sta dequeue during statistics interval -+ */ -+ NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, -+ -+ /* -+ * how many TC[0-3] resource back from firmware during -+ * statistics interval -+ */ -+ NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, -+ NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, -+ NL80211_TESTMODE_STA_STATISTICS_USED_BFCT_ARRAY, -+ NL80211_TESTMODE_STA_STATISTICS_WANTED_BFCT_ARRAY, -+ -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, -+ -+ NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, -+ -+ NL80211_TESTMODE_STA_STATISTICS_NUM -+} ENUM_TESTMODE_STA_STATISTICS_ATTR; -+typedef struct _NL80211_DRIVER_SET_NFC_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_32 NFC_Enable; -+ -+} NL80211_DRIVER_SET_NFC_PARAMS, *P_NL80211_DRIVER_SET_NFC_PARAMS; -+typedef struct _NL80211_DRIVER_GET_SCANDONE_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_32 u4ScanDone; -+ -+} NL80211_DRIVER_GET_SCANDONE_PARAMS, *P_NL80211_DRIVER_GET_SCANDONE_PARAMS; -+ -+typedef enum _ENUM_TESTMODE_LINK_DETECTION_ATTR { -+ NL80211_TESTMODE_LINK_INVALID = 0, -+ NL80211_TESTMODE_LINK_TX_FAIL_CNT, -+ NL80211_TESTMODE_LINK_TX_RETRY_CNT, -+ NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, -+ NL80211_TESTMODE_LINK_ACK_FAIL_CNT, -+ NL80211_TESTMODE_LINK_FCS_ERR_CNT, -+ -+ NL80211_TESTMODE_LINK_DETECT_NUM, -+} ENUM_TESTMODE_LINK_DETECTION_ATTR; -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ -+typedef struct _NL80211_DRIVER_GET_LTE_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_32 u4Version; -+ UINT_32 u4Flag; -+ -+} NL80211_DRIVER_GET_LTE_PARAMS, *P_NL80211_DRIVER_GET_LTE_PARAMS; -+ -+/*typedef enum _ENUM_TESTMODE_AVAILABLE_CHAN_ATTR{ -+ NL80211_TESTMODE_AVAILABLE_CHAN_INVALID = 0, -+ NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, -+ -+ NL80211_TESTMODE_AVAILABLE_CHAN_NUM, -+}ENUM_TESTMODE_AVAILABLE_CHAN_ATTR;*/ -+ -+#endif -+#endif -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* cfg80211 hooks */ -+int -+mtk_cfg80211_change_iface(struct wiphy *wiphy, -+ struct net_device *ndev, enum nl80211_iftype type,/* u32 *flags,*/ struct vif_params *params); -+ -+int -+mtk_cfg80211_add_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params); -+ -+int -+mtk_cfg80211_get_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, -+ bool pairwise, -+ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *) -+); -+ -+int -+mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr); -+ -+int -+mtk_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool unicast, bool multicast); -+ -+int mtk_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index); -+ -+int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac, struct station_info *sinfo); -+ -+int mtk_cfg80211_add_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_parameters *params); -+ -+int mtk_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_parameters *params); -+ -+int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, struct station_del_parameters *params); -+//int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac); -+ -+int mtk_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request); -+ -+int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme); -+ -+int mtk_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code); -+ -+int mtk_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ibss_params *params); -+ -+int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev); -+ -+int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, bool enabled, int timeout); -+ -+int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa); -+ -+int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa); -+ -+int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev); -+ -+int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct ieee80211_channel *chan, -+ unsigned int duration, u64 *cookie); -+ -+int mtk_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); -+ -+int -+mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct cfg80211_mgmt_tx_params *params, -+ u64 *cookie); -+ -+void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, -+ IN struct wireless_dev *wdev, -+ IN u16 frame_type, IN bool reg); -+ -+int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); -+ -+int mtk_cfg80211_assoc(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_assoc_request *req); -+ -+int -+mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy, -+ IN struct net_device *ndev, IN struct cfg80211_sched_scan_request *request); -+ -+int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, IN struct net_device *ndev,u64 reqid); -+ -+#if CONFIG_NL80211_TESTMODE -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+WLAN_STATUS -+wlanoidQueryACSChannelList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+int -+mtk_cfg80211_testmode_get_lte_channel(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo); -+#endif -+int -+mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy *wiphy, -+ IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo); -+ -+int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo); -+ -+int mtk_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len); -+ -+int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+#if CFG_SUPPORT_WAPI -+int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy *wiphy, IN void *data, IN int len); -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+int mtk_p2p_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+#endif -+ -+#else -+#error "Please ENABLE kernel config (CONFIG_NL80211_TESTMODE) to support Wi-Fi Direct" -+#endif -+int mtk_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow); -+int mtk_cfg80211_resume(struct wiphy *wiphy); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _GL_CFG80211_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h -new file mode 100644 -index 0000000000000..1406905095e64 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h -@@ -0,0 +1,1565 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_kal.h#1 -+*/ -+ -+/*! \file gl_kal.h -+ \brief Declaration of KAL functions - kal*() which is provided by GLUE Layer. -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/* -+** Log: gl_kal.h -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 04 12 2012 terry.wu -+ * NULL -+ * Add AEE message support -+ * 1) Show AEE warning(red screen) if SDIO access error occurs -+ -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 02 06 2012 wh.su -+ * [WCXRP00001177] [MT6620 Wi-Fi][Driver][2.2] Adding the query channel filter for AP mode -+ * adding the channel query filter for AP mode. -+ * -+ * 01 02 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. -+ * -+ * 12 13 2011 cm.chang -+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer -+ * Add wake lock if timer timeout value is smaller than 5 seconds -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adjust the code for Non-DBG and no XLOG. -+ * -+ * 11 22 2011 cp.wu -+ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous to asynchronous -+ * approach to avoid incomplete state termination -+ * 1. change RDD related compile option brace position. -+ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state without join -+ * timeout timer ticking -+ * 3. otherwise, insert AIS_REQUEST into pending request queue -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Modify the QM xlog level and remove LOG_FUNC. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Using the new XLOG define for dum Memory. -+ * -+ * 11 08 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog function. -+ * -+ * 11 08 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters, eCurPsProf, for PS. -+ * -+ * 11 08 2011 cm.chang -+ * NULL -+ * Add RLM and CNM debug message for XLOG -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Add dumpMemory8 at XLOG support. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated -+ * network type -+ * include link.h for linux's port. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated -+ * network type -+ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected -+ * -+ * 04 01 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * 1. simplify config.h due to aggregation options could be also applied for eHPI/SPI interface -+ * 2. use spin-lock instead of semaphore for protecting eHPI access because of possible access from ISR -+ * 3. request_irq() API has some changes between linux kernel 2.6.12 and 2.6.26 -+ * -+ * 03 16 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * 1. pre-allocate physical continuous buffer while module is being loaded -+ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer -+ * -+ * The windows part remained the same as before, but added similar APIs to hide the difference. -+ * -+ * 03 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW table. -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 06 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Sync BOW Driver to latest person development branch version.. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after -+ * connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 24 2011 cp.wu -+ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep() won't sleep -+ * long enough for specified interval such as 500ms -+ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system -+ * scheduling -+ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being -+ * loaded -+ * -+ * 12 31 2010 jeffrey.chang -+ * [WCXRP00000332] [MT6620 Wi-Fi][Driver] add kal sleep function for delay which use blocking call -+ * modify the implementation of kalDelay to msleep -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Invitation & Provision Discovery Indication. -+ * -+ * 11 26 2010 cp.wu -+ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only with necessary data field -+ * checking -+ * 1. NVRAM error is now treated as warning only, thus normal operation is still available but extra scan result used -+ * to indicate user is attached -+ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown -+ * -+ * 11 08 2010 cp.wu -+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period -+ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * add a kal function for set cipher. -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * fixed compiling error while enable p2p. -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ * associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 10 2010 wh.su -+ * NULL -+ * fixed the compiling error at win XP. -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 06 2010 wh.su -+ * NULL -+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 06 2010 cp.wu -+ * NULL -+ * driver hook modifications corresponding to ioctl interface change. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct Driver Hook] change event indication API to be consistent with supplicant -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct] add framework for driver hooks -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * modify kalSetEvent declaration -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * simplify post-handling after TX_DONE interrupt is handled. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) re-enable AIS-FSM beacon timeout handling. -+ * 2) scan done API revised -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * fix kal header file -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * use different spin lock for security frame -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * add new spinlock -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add kal api for scanning done -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * modify cmd/data path for new design -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add new kal api -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change MAC address updating logic. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * gl_kal merged -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic handling framework for wireless extension ioctls. -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl for controlling p2p scan phase parameters -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * fill network type field while doing frame identification. -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement basic wi-fi direct framework -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic framework for implementating P2P driver hook. -+ * -+ * 05 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * modify kalMemAlloc method -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * follow Linux's firmware framework, and remove unused kal API -+ * -+ * 04 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * when acquiring driver-own, wait for up to 8 seconds. -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * -+ * 1) modify rx path code for supporting Wi-Fi direct -+ * 2) modify config.h since Linux dont need to consider retaining packet -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * don't need SPIN_LOCK_PWR_CTRL anymore, it will raise IRQL -+ * * and cause SdBusSubmitRequest running at DISPATCH_LEVEL as well. -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler -+ * * * * * * * * * * * * * * * * * * * capability -+ * * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) add spinlock -+ * * * 2) add KAPI for handling association info -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding firmware download KAPI -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * finish non-glue layer access to glue variables -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * accessing to firmware load/start address, and access to OID handling information -+ * * * * are now handled in glue layer -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * * * * * are done in adapter layer. -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add KAL API: kalFlushPendingTxPackets(), and take use of the API -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) for some OID, never do timeout expiration -+ * * * * 2) add 2 kal API for later integration -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * emulate NDIS Pending OID facility -+ * -+ * 03 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * adding firmware download KAPI -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\41 2009-09-28 20:19:23 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\40 2009-08-18 22:57:09 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\39 2009-06-23 23:19:15 GMT mtk01090 -+** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support -+** \main\maintrunk.MT5921\38 2009-02-09 14:03:17 GMT mtk01090 -+** Add KAL function kalDevSetPowerState(). It is not implemented yet. Only add an empty macro. -+** -+** \main\maintrunk.MT5921\37 2009-01-22 13:05:59 GMT mtk01088 -+** new defeine to got 1x value at packet reserved field -+** \main\maintrunk.MT5921\36 2008-12-08 16:15:02 GMT mtk01461 -+** Add kalQueryValidBufferLength() macro -+** \main\maintrunk.MT5921\35 2008-11-13 20:33:15 GMT mtk01104 -+** Remove lint warning -+** \main\maintrunk.MT5921\34 2008-10-22 11:05:52 GMT mtk01461 -+** Remove unused macro -+** \main\maintrunk.MT5921\33 2008-10-16 15:48:17 GMT mtk01461 -+** Update driver to fix lint warning -+** \main\maintrunk.MT5921\32 2008-09-02 11:50:51 GMT mtk01461 -+** SPIN_LOCK_SDIO_DDK_TX_QUE -+** \main\maintrunk.MT5921\31 2008-08-29 15:58:30 GMT mtk01088 -+** remove non-used function for code refine -+** \main\maintrunk.MT5921\30 2008-08-21 00:33:29 GMT mtk01461 -+** Update for Driver Review -+** \main\maintrunk.MT5921\29 2008-06-19 13:29:14 GMT mtk01425 -+** 1. Add declaration of SPIN_LOCK_SDIO_DDK_TX_QUE and SPIN_LOCK_SDIO_DDK_RX_QUE -+** \main\maintrunk.MT5921\28 2008-05-30 20:27:34 GMT mtk01461 -+** Rename KAL function -+** \main\maintrunk.MT5921\27 2008-05-30 14:42:05 GMT mtk01461 -+** Remove WMM Assoc Flag in KAL -+** \main\maintrunk.MT5921\26 2008-05-29 14:15:18 GMT mtk01084 -+** remove un-used function -+** \main\maintrunk.MT5921\25 2008-04-23 14:02:20 GMT mtk01084 -+** modify KAL port access function prototype -+** \main\maintrunk.MT5921\24 2008-04-17 23:06:41 GMT mtk01461 -+** Add iwpriv support for AdHocMode setting -+** \main\maintrunk.MT5921\23 2008-04-08 15:38:50 GMT mtk01084 -+** add KAL function to setting pattern search function enable/ disable -+** \main\maintrunk.MT5921\22 2008-03-26 15:34:48 GMT mtk01461 -+** Add update MAC address func -+** \main\maintrunk.MT5921\21 2008-03-18 15:56:15 GMT mtk01084 -+** update ENUM_NIC_INITIAL_PARAM_E -+** \main\maintrunk.MT5921\20 2008-03-18 11:49:28 GMT mtk01084 -+** update function for initial value access -+** \main\maintrunk.MT5921\19 2008-03-18 10:21:31 GMT mtk01088 -+** use kal update associate request at linux -+** \main\maintrunk.MT5921\18 2008-03-14 18:03:41 GMT mtk01084 -+** refine register and port access function -+** \main\maintrunk.MT5921\17 2008-03-11 14:51:02 GMT mtk01461 -+** Add copy_to(from)_user macro -+** \main\maintrunk.MT5921\16 2008-03-06 23:42:21 GMT mtk01385 -+** 1. add Query Registry Mac address function. -+** \main\maintrunk.MT5921\15 2008-02-26 09:48:04 GMT mtk01084 -+** modify KAL set network address/ checksum offload part -+** \main\maintrunk.MT5921\14 2008-01-09 17:54:58 GMT mtk01084 -+** Modify the argument of kalQueryPacketInfo -+** \main\maintrunk.MT5921\13 2007-11-29 02:05:20 GMT mtk01461 -+** Fix Windows RX multiple packet retain problem -+** \main\maintrunk.MT5921\12 2007-11-26 19:43:45 GMT mtk01461 -+** Add OS_TIMESTAMP macro -+** -+** \main\maintrunk.MT5921\11 2007-11-09 16:36:15 GMT mtk01425 -+** 1. Modify for CSUM offloading with Tx Fragment -+** \main\maintrunk.MT5921\10 2007-11-07 18:38:37 GMT mtk01461 -+** Add Tx Fragmentation Support -+** \main\maintrunk.MT5921\9 2007-11-06 19:36:50 GMT mtk01088 -+** add the WPS related code -+** \main\maintrunk.MT5921\8 2007-11-02 01:03:57 GMT mtk01461 -+** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning -+** Revision 1.4 2007/07/05 07:25:33 MTK01461 -+** Add Linux initial code, modify doc, add 11BB, RF init code -+** -+** Revision 1.3 2007/06/27 02:18:50 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+** Revision 1.2 2007/06/25 06:16:23 MTK01461 -+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API -+** -+*/ -+ -+#ifndef _GL_KAL_H -+#define _GL_KAL_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "config.h" -+#include "gl_typedef.h" -+#include "gl_os.h" -+#include "link.h" -+#include "nic/mac.h" -+#include "nic/wlan_def.h" -+#include "wlan_lib.h" -+#include "wlan_oid.h" -+#include "gl_wext_priv.h" -+#include -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+#include "nic/bow.h" -+#endif -+ -+#if DBG -+extern int allocatedMemSize; -+#endif -+ -+#if CFG_SUPPORT_MET_PROFILING -+#include "linux/kallsyms.h" -+#include -+#endif -+ -+extern BOOLEAN fgIsUnderSuspend; -+extern UINT_32 TaskIsrCnt; -+extern BOOLEAN fgIsResetting; -+extern int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev); -+extern UINT_32 u4MemAllocCnt, u4MemFreeCnt; -+ -+ -+extern struct delayed_work sched_workq; -+ -+#if defined(MT6620) && CFG_MULTI_ECOVER_SUPPORT -+extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID); -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* #define USEC_PER_MSEC (1000) */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_SPIN_LOCK_CATEGORY_E { -+ SPIN_LOCK_FSM = 0, -+ -+ /* FIX ME */ -+ SPIN_LOCK_RX_QUE, -+ SPIN_LOCK_TX_QUE, -+ SPIN_LOCK_CMD_QUE, -+ SPIN_LOCK_TX_RESOURCE, -+ SPIN_LOCK_CMD_RESOURCE, -+ SPIN_LOCK_QM_TX_QUEUE, -+ SPIN_LOCK_CMD_PENDING, -+ SPIN_LOCK_CMD_SEQ_NUM, -+ SPIN_LOCK_TX_MSDU_INFO_LIST, -+ SPIN_LOCK_TXING_MGMT_LIST, -+ SPIN_LOCK_TX_SEQ_NUM, -+ SPIN_LOCK_TX_COUNT, -+ SPIN_LOCK_TXS_COUNT, -+ /* end */ -+ SPIN_LOCK_TX, -+ SPIN_LOCK_IO_REQ, -+ SPIN_LOCK_INT, -+ -+ SPIN_LOCK_MGT_BUF, -+ SPIN_LOCK_MSG_BUF, -+ SPIN_LOCK_STA_REC, -+ -+ SPIN_LOCK_MAILBOX, -+ SPIN_LOCK_TIMER, -+ -+ SPIN_LOCK_BOW_TABLE, -+ -+ SPIN_LOCK_EHPI_BUS, /* only for EHPI */ -+ SPIN_LOCK_NET_DEV, -+ SPIN_LOCK_NUM -+} ENUM_SPIN_LOCK_CATEGORY_E; -+ -+/* event for assoc information update */ -+typedef struct _EVENT_ASSOC_INFO { -+ UINT_8 ucAssocReq; /* 1 for assoc req, 0 for assoc rsp */ -+ UINT_8 ucReassoc; /* 0 for assoc, 1 for reassoc */ -+ UINT_16 u2Length; -+ PUINT_8 pucIe; -+} EVENT_ASSOC_INFO, *P_EVENT_ASSOC_INFO; -+ -+typedef enum _ENUM_KAL_NETWORK_TYPE_INDEX_T { -+ KAL_NETWORK_TYPE_AIS_INDEX = 0, -+#if CFG_ENABLE_WIFI_DIRECT -+ KAL_NETWORK_TYPE_P2P_INDEX, -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ KAL_NETWORK_TYPE_BOW_INDEX, -+#endif -+ KAL_NETWORK_TYPE_INDEX_NUM -+} ENUM_KAL_NETWORK_TYPE_INDEX_T; -+ -+typedef enum _ENUM_KAL_MEM_ALLOCATION_TYPE_E { -+ PHY_MEM_TYPE, /* physically continuous */ -+ VIR_MEM_TYPE, /* virtually continuous */ -+ MEM_TYPE_NUM -+} ENUM_KAL_MEM_ALLOCATION_TYPE; -+ -+#if CONFIG_ANDROID /* Defined in Android kernel source */ -+typedef struct wake_lock KAL_WAKE_LOCK_T, *P_KAL_WAKE_LOCK_T; -+#else -+typedef UINT_32 KAL_WAKE_LOCK_T, *P_KAL_WAKE_LOCK_T; -+#endif -+ -+#if CFG_SUPPORT_AGPS_ASSIST -+typedef enum _ENUM_MTK_AGPS_ATTR { -+ MTK_ATTR_AGPS_INVALID, -+ MTK_ATTR_AGPS_CMD, -+ MTK_ATTR_AGPS_DATA, -+ MTK_ATTR_AGPS_IFINDEX, -+ MTK_ATTR_AGPS_IFNAME, -+ MTK_ATTR_AGPS_MAX -+} ENUM_MTK_CCX_ATTR; -+ -+typedef enum _ENUM_AGPS_EVENT { -+ AGPS_EVENT_WLAN_ON, -+ AGPS_EVENT_WLAN_OFF, -+ AGPS_EVENT_WLAN_AP_LIST, -+ WIFI_EVENT_CHIP_RESET, -+} ENUM_CCX_EVENT; -+BOOLEAN kalIndicateAgpsNotify(P_ADAPTER_T prAdapter, UINT_8 cmd, PUINT_8 data, UINT_16 dataLen); -+#endif -+ -+struct KAL_HALT_CTRL_T { -+ struct semaphore lock; -+ struct task_struct *owner; -+ BOOLEAN fgHalt; -+ BOOLEAN fgHeldByKalIoctl; -+ OS_SYSTIME u4HoldStart; -+}; -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros of bit operation */ -+/*----------------------------------------------------------------------------*/ -+#define KAL_SET_BIT(bitOffset, value) set_bit(bitOffset, &value) -+#define KAL_CLR_BIT(bitOffset, value) clear_bit(bitOffset, &value) -+#define KAL_TEST_AND_CLEAR_BIT(bitOffset, value) test_and_clear_bit(bitOffset, &value) -+#define KAL_TEST_BIT(bitOffset, value) test_bit(bitOffset, &value) -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros of SPIN LOCK operations for using in Driver Layer */ -+/*----------------------------------------------------------------------------*/ -+#define KAL_SPIN_LOCK_DECLARATION() unsigned long __u4Flags -+ -+#define KAL_ACQUIRE_SPIN_LOCK(_prAdapter, _rLockCategory) \ -+ kalAcquireSpinLock(((P_ADAPTER_T)_prAdapter)->prGlueInfo, _rLockCategory, &__u4Flags) -+ -+#define KAL_RELEASE_SPIN_LOCK(_prAdapter, _rLockCategory) \ -+ kalReleaseSpinLock(((P_ADAPTER_T)_prAdapter)->prGlueInfo, _rLockCategory, __u4Flags) -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros for accessing Reserved Fields of native packet */ -+/*----------------------------------------------------------------------------*/ -+#define KAL_GET_PKT_QUEUE_ENTRY(_p) GLUE_GET_PKT_QUEUE_ENTRY(_p) -+#define KAL_GET_PKT_DESCRIPTOR(_prQueueEntry) GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry) -+#define KAL_GET_PKT_TID(_p) GLUE_GET_PKT_TID(_p) -+#define KAL_GET_PKT_IS1X(_p) GLUE_GET_PKT_IS1X(_p) -+#define KAL_GET_PKT_HEADER_LEN(_p) GLUE_GET_PKT_HEADER_LEN(_p) -+#define KAL_GET_PKT_PAYLOAD_LEN(_p) GLUE_GET_PKT_PAYLOAD_LEN(_p) -+#define KAL_GET_PKT_ARRIVAL_TIME(_p) GLUE_GET_PKT_ARRIVAL_TIME(_p) -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros of wake_lock operations for using in Driver Layer */ -+/*----------------------------------------------------------------------------*/ -+#if CONFIG_ANDROID /* Defined in Android kernel source */ -+#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName) \ -+ wake_lock_init(_prWakeLock, WAKE_LOCK_SUSPEND, _pcName) -+ -+#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock) \ -+ wake_lock_destroy(_prWakeLock) -+ -+#define KAL_WAKE_LOCK(_prAdapter, _prWakeLock) \ -+ wake_lock(_prWakeLock) -+ -+#define KAL_WAKE_LOCK_TIMEOUT(_prAdapter, _prWakeLock, _u4Timeout) \ -+ wake_lock_timeout(_prWakeLock, _u4Timeout) -+ -+#define KAL_WAKE_UNLOCK(_prAdapter, _prWakeLock) \ -+ wake_unlock(_prWakeLock) -+ -+#else -+#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName) -+#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock) -+#define KAL_WAKE_LOCK(_prAdapter, _prWakeLock) -+#define KAL_WAKE_LOCK_TIMEOUT(_prAdapter, _prWakeLock, _u4Timeout) -+#define KAL_WAKE_UNLOCK(_prAdapter, _prWakeLock) -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Cache memory allocation -+* -+* \param[in] u4Size Required memory size. -+* \param[in] eMemType Memory allocation type -+* -+* \return Pointer to allocated memory -+* or NULL -+*/ -+/*----------------------------------------------------------------------------*/ -+#if DBG -+#define kalMemAlloc(u4Size, eMemType) ({ \ -+ void *pvAddr; \ -+ if (eMemType == PHY_MEM_TYPE) { \ -+ pvAddr = kmalloc(u4Size, GFP_KERNEL); \ -+ } \ -+ else { \ -+ pvAddr = vmalloc(u4Size); \ -+ } \ -+ if (pvAddr) { \ -+ allocatedMemSize += u4Size; \ -+ DBGLOG(INIT, INFO, "%p(%u) allocated (%s:%s)\n", \ -+ pvAddr, (UINT_32)u4Size, __FILE__, __func__); \ -+ } \ -+ pvAddr; \ -+}) -+#else -+#define kalMemAlloc(u4Size, eMemType) ({ \ -+ void *pvAddr; \ -+ if (eMemType == PHY_MEM_TYPE) { \ -+ pvAddr = kmalloc(u4Size, GFP_KERNEL); \ -+ } \ -+ else { \ -+ pvAddr = vmalloc(u4Size); \ -+ } \ -+ pvAddr; \ -+}) -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Free allocated cache memory -+* -+* \param[in] pvAddr Required memory size. -+* \param[in] eMemType Memory allocation type -+* \param[in] u4Size Allocated memory size. -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+#if DBG -+#define kalMemFree(pvAddr, eMemType, u4Size) \ -+{ \ -+ if (pvAddr) { \ -+ allocatedMemSize -= u4Size; \ -+ DBGLOG(INIT, INFO, "%p(%u) freed (%s:%s)\n", \ -+ pvAddr, (UINT_32)u4Size, __FILE__, __func__); \ -+ } \ -+ if (eMemType == PHY_MEM_TYPE) { \ -+ kfree(pvAddr); \ -+ } \ -+ else { \ -+ vfree(pvAddr); \ -+ } \ -+} -+#else -+#define kalMemFree(pvAddr, eMemType, u4Size) \ -+{ \ -+ if (eMemType == PHY_MEM_TYPE) { \ -+ kfree(pvAddr); \ -+ } \ -+ else { \ -+ vfree(pvAddr); \ -+ } \ -+} -+#endif -+ -+#define kalUdelay(u4USec) udelay(u4USec) -+ -+#define kalMdelay(u4MSec) mdelay(u4MSec) -+#define kalMsleep(u4MSec) msleep(u4MSec) -+ -+/* Copy memory from user space to kernel space */ -+#define kalMemCopyFromUser(_pvTo, _pvFrom, _u4N) copy_from_user(_pvTo, _pvFrom, _u4N) -+ -+/* Copy memory from kernel space to user space */ -+#define kalMemCopyToUser(_pvTo, _pvFrom, _u4N) copy_to_user(_pvTo, _pvFrom, _u4N) -+ -+/* Copy memory block with specific size */ -+#define kalMemCopy(pvDst, pvSrc, u4Size) memcpy(pvDst, pvSrc, u4Size) -+ -+/* Set memory block with specific pattern */ -+#define kalMemSet(pvAddr, ucPattern, u4Size) memset(pvAddr, ucPattern, u4Size) -+ -+/* Compare two memory block with specific length. -+ * Return zero if they are the same. -+ */ -+#define kalMemCmp(pvAddr1, pvAddr2, u4Size) memcmp(pvAddr1, pvAddr2, u4Size) -+ -+/* Zero specific memory block */ -+#define kalMemZero(pvAddr, u4Size) memset(pvAddr, 0, u4Size) -+ -+/* string operation */ -+#define kalStrCpy(dest, src) strcpy(dest, src) -+#define kalStrnCpy(dest, src, n) strncpy(dest, src, n) -+#define kalStrCmp(ct, cs) strcmp(ct, cs) -+#define kalStrnCmp(ct, cs, n) strncmp(ct, cs, n) -+#define kalStrChr(s, c) strchr(s, c) -+#define kalStrrChr(s, c) strrchr(s, c) -+#define kalStrnChr(s, n, c) strnchr(s, n, c) -+#define kalStrLen(s) strlen(s) -+#define kalStrnLen(s, b) strnlen(s, b) -+//#define kalStrniCmp(s1, s2, n) strnicmp(s1, s2, n) -+#define kalStrniCmp(s1, s2, n) strncasecmp(s1, s2, n) -+#define strnicmp(s1, s2, n) strncasecmp(s1, s2, n) -+/* #define kalStrtoul(cp, endp, base) simple_strtoul(cp, endp, base) -+#define kalStrtol(cp, endp, base) simple_strtol(cp, endp, base) */ -+#define kalkStrtou32(cp, base, resp) kstrtou32(cp, base, resp) -+#define kalkStrtos32(cp, base, resp) kstrtos32(cp, base, resp) -+#define kalSnprintf(buf, size, fmt, ...) snprintf(buf, size, fmt, __VA_ARGS__) -+#define kalSprintf(buf, fmt, ...) sprintf(buf, fmt, __VA_ARGS__) -+/* remove for AOSP */ -+/* #define kalSScanf(buf, fmt, ...) sscanf(buf, fmt, __VA_ARGS__) */ -+#define kalStrStr(ct, cs) strstr(ct, cs) -+#define kalStrSep(s, ct) strsep(s, ct) -+#define kalStrCat(dest, src) strcat(dest, src) -+ -+/* defined for wince sdio driver only */ -+#if defined(_HIF_SDIO) -+#define kalDevSetPowerState(prGlueInfo, ePowerMode) glSetPowerState(prGlueInfo, ePowerMode) -+#else -+#define kalDevSetPowerState(prGlueInfo, ePowerMode) -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Notify OS with SendComplete event of the specific packet. Linux should -+* free packets here. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of Packet Handle -+* \param[in] status Status Code for OS upper layer -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+#define kalSendComplete(prGlueInfo, pvPacket, status) \ -+ kalSendCompleteAndAwakeQueue(prGlueInfo, pvPacket) -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to locate the starting address of incoming ethernet -+* frame for skb. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of Packet Handle -+* -+* \return starting address of ethernet frame buffer. -+*/ -+/*----------------------------------------------------------------------------*/ -+#define kalQueryBufferPointer(prGlueInfo, pvPacket) \ -+ ((PUINT_8)((struct sk_buff *)pvPacket)->data) -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to query the length of valid buffer which is accessible during -+* port read/write. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of Packet Handle -+* -+* \return starting address of ethernet frame buffer. -+*/ -+/*----------------------------------------------------------------------------*/ -+#define kalQueryValidBufferLength(prGlueInfo, pvPacket) \ -+ ((UINT_32)((struct sk_buff *)pvPacket)->end - \ -+ (UINT_32)((struct sk_buff *)pvPacket)->data) -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to copy the entire frame from skb to the destination -+* address in the input parameter. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of Packet Handle -+* \param[in] pucDestBuffer Destination Address -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+#define kalCopyFrame(prGlueInfo, pvPacket, pucDestBuffer) \ -+ do {struct sk_buff *skb = (struct sk_buff *)pvPacket; \ -+ memcpy(pucDestBuffer, skb->data, skb->len); } while (0) -+ -+#define kalGetTimeTick() jiffies_to_msecs(jiffies) -+ -+#define kalPrint pr_debug -+ -+#if !DBG -+#define AIS_ERROR_LOGFUNC(_Fmt...) -+#define AIS_WARN_LOGFUNC(_Fmt...) -+#define AIS_INFO_LOGFUNC(_Fmt...) -+#define AIS_STATE_LOGFUNC(_Fmt...) -+#define AIS_EVENT_LOGFUNC(_Fmt...) -+#define AIS_TRACE_LOGFUNC(_Fmt...) -+#define AIS_LOUD_LOGFUNC(_Fmt...) -+#define AIS_TEMP_LOGFUNC(_Fmt...) -+ -+#define INTR_ERROR_LOGFUNC(_Fmt...) -+#define INTR_WARN_LOGFUNC(_Fmt...) -+#define INTR_INFO_LOGFUNC(_Fmt...) -+#define INTR_STATE_LOGFUNC(_Fmt...) -+#define INTR_EVENT_LOGFUNC(_Fmt...) -+#define INTR_TRACE_LOGFUNC(_Fmt...) -+#define INTR_LOUD_LOGFUNC(_Fmt...) -+#define INTR_TEMP_LOGFUNC(_Fmt...) -+ -+#define INIT_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define INIT_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define INIT_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define INIT_STATE_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define INIT_EVENT_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define INIT_TRACE_LOGFUNC(_Fmt...) -+#define INIT_LOUD_LOGFUNC(_Fmt...) -+#define INIT_TEMP_LOGFUNC(_Fmt...) -+ -+#define AAA_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_STATE_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_EVENT_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_LOUD_LOGFUNC(_Fmt...) -+#define AAA_TEMP_LOGFUNC(_Fmt...) -+ -+#define ROAMING_ERROR_LOGFUNC(_Fmt...) -+#define ROAMING_WARN_LOGFUNC(_Fmt...) -+#define ROAMING_INFO_LOGFUNC(_Fmt...) -+#define ROAMING_STATE_LOGFUNC(_Fmt...) -+#define ROAMING_EVENT_LOGFUNC(_Fmt...) -+#define ROAMING_TRACE_LOGFUNC(_Fmt...) -+#define ROAMING_LOUD_LOGFUNC(_Fmt...) -+#define ROAMING_TEMP_LOGFUNC(_Fmt...) -+ -+#define REQ_ERROR_LOGFUNC(_Fmt...) -+#define REQ_WARN_LOGFUNC(_Fmt...) -+#define REQ_INFO_LOGFUNC(_Fmt...) -+#define REQ_STATE_LOGFUNC(_Fmt...) -+#define REQ_EVENT_LOGFUNC(_Fmt...) -+#define REQ_TRACE_LOGFUNC(_Fmt...) -+#define REQ_LOUD_LOGFUNC(_Fmt...) -+#define REQ_TEMP_LOGFUNC(_Fmt...) -+ -+#define TX_ERROR_LOGFUNC(_Fmt...) -+#define TX_WARN_LOGFUNC(_Fmt...) -+#define TX_INFO_LOGFUNC(_Fmt...) -+#define TX_STATE_LOGFUNC(_Fmt...) -+#define TX_EVENT_LOGFUNC(_Fmt...) -+#define TX_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define TX_LOUD_LOGFUNC(_Fmt...) -+#define TX_TEMP_LOGFUNC(_Fmt...) -+ -+#define RX_ERROR_LOGFUNC(_Fmt...) -+#define RX_WARN_LOGFUNC(_Fmt...) -+#define RX_INFO_LOGFUNC(_Fmt...) -+#define RX_STATE_LOGFUNC(_Fmt...) -+#define RX_EVENT_LOGFUNC(_Fmt...) -+#define RX_TRACE_LOGFUNC(_Fmt...) -+#define RX_LOUD_LOGFUNC(_Fmt...) -+#define RX_TEMP_LOGFUNC(_Fmt...) -+ -+#define RFTEST_ERROR_LOGFUNC(_Fmt...) -+#define RFTEST_WARN_LOGFUNC(_Fmt...) -+#define RFTEST_INFO_LOGFUNC(_Fmt...) -+#define RFTEST_STATE_LOGFUNC(_Fmt...) -+#define RFTEST_EVENT_LOGFUNC(_Fmt...) -+#define RFTEST_TRACE_LOGFUNC(_Fmt...) -+#define RFTEST_LOUD_LOGFUNC(_Fmt...) -+#define RFTEST_TEMP_LOGFUNC(_Fmt...) -+ -+#define EMU_ERROR_LOGFUNC(_Fmt...) -+#define EMU_WARN_LOGFUNC(_Fmt...) -+#define EMU_INFO_LOGFUNC(_Fmt...) -+#define EMU_STATE_LOGFUNC(_Fmt...) -+#define EMU_EVENT_LOGFUNC(_Fmt...) -+#define EMU_TRACE_LOGFUNC(_Fmt...) -+#define EMU_LOUD_LOGFUNC(_Fmt...) -+#define EMU_TEMP_LOGFUNC(_Fmt...) -+ -+#define HEM_ERROR_LOGFUNC(_Fmt...) -+#define HEM_WARN_LOGFUNC(_Fmt...) -+#define HEM_INFO_LOGFUNC(_Fmt...) -+#define HEM_STATE_LOGFUNC(_Fmt...) -+#define HEM_EVENT_LOGFUNC(_Fmt...) -+#define HEM_TRACE_LOGFUNC(_Fmt...) -+#define HEM_LOUD_LOGFUNC(_Fmt...) -+#define HEM_TEMP_LOGFUNC(_Fmt...) -+ -+#define RLM_ERROR_LOGFUNC(_Fmt...) -+#define RLM_WARN_LOGFUNC(_Fmt...) -+#define RLM_INFO_LOGFUNC(_Fmt...) -+#define RLM_STATE_LOGFUNC(_Fmt...) -+#define RLM_EVENT_LOGFUNC(_Fmt...) -+#define RLM_TRACE_LOGFUNC(_Fmt...) -+#define RLM_LOUD_LOGFUNC(_Fmt...) -+#define RLM_TEMP_LOGFUNC(_Fmt...) -+ -+#define MEM_ERROR_LOGFUNC(_Fmt...) -+#define MEM_WARN_LOGFUNC(_Fmt...) -+#define MEM_INFO_LOGFUNC(_Fmt...) -+#define MEM_STATE_LOGFUNC(_Fmt...) -+#define MEM_EVENT_LOGFUNC(_Fmt...) -+#define MEM_TRACE_LOGFUNC(_Fmt...) -+#define MEM_LOUD_LOGFUNC(_Fmt...) -+#define MEM_TEMP_LOGFUNC(_Fmt...) -+ -+#define CNM_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define CNM_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define CNM_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define CNM_STATE_LOGFUNC(_Fmt...) -+#define CNM_EVENT_LOGFUNC(_Fmt...) -+#define CNM_TRACE_LOGFUNC(_Fmt...) -+#define CNM_LOUD_LOGFUNC(_Fmt...) -+#define CNM_TEMP_LOGFUNC(_Fmt...) -+ -+#define RSN_ERROR_LOGFUNC(_Fmt...) -+#define RSN_WARN_LOGFUNC(_Fmt...) -+#define RSN_INFO_LOGFUNC(_Fmt...) -+#define RSN_STATE_LOGFUNC(_Fmt...) -+#define RSN_EVENT_LOGFUNC(_Fmt...) -+#define RSN_TRACE_LOGFUNC(_Fmt...) -+#define RSN_LOUD_LOGFUNC(_Fmt...) -+#define RSN_TEMP_LOGFUNC(_Fmt...) -+ -+#define BSS_ERROR_LOGFUNC(_Fmt...) -+#define BSS_WARN_LOGFUNC(_Fmt...) -+#define BSS_INFO_LOGFUNC(_Fmt...) -+#define BSS_STATE_LOGFUNC(_Fmt...) -+#define BSS_EVENT_LOGFUNC(_Fmt...) -+#define BSS_TRACE_LOGFUNC(_Fmt...) -+#define BSS_LOUD_LOGFUNC(_Fmt...) -+#define BSS_TEMP_LOGFUNC(_Fmt...) -+ -+#define SCN_ERROR_LOGFUNC(_Fmt...) -+#define SCN_WARN_LOGFUNC(_Fmt...) -+#define SCN_INFO_LOGFUNC(_Fmt...) -+#define SCN_STATE_LOGFUNC(_Fmt...) -+#define SCN_EVENT_LOGFUNC(_Fmt...) -+#define SCN_TRACE_LOGFUNC(_Fmt...) -+#define SCN_LOUD_LOGFUNC(_Fmt...) -+#define SCN_TEMP_LOGFUNC(_Fmt...) -+ -+#define SAA_ERROR_LOGFUNC(_Fmt...) -+#define SAA_WARN_LOGFUNC(_Fmt...) -+#define SAA_INFO_LOGFUNC(_Fmt...) -+#define SAA_STATE_LOGFUNC(_Fmt...) -+#define SAA_EVENT_LOGFUNC(_Fmt...) -+#define SAA_TRACE_LOGFUNC(_Fmt...) -+#define SAA_LOUD_LOGFUNC(_Fmt...) -+#define SAA_TEMP_LOGFUNC(_Fmt...) -+ -+#define P2P_ERROR_LOGFUNC(_Fmt...) -+#define P2P_WARN_LOGFUNC(_Fmt...) -+#define P2P_INFO_LOGFUNC(_Fmt...) -+#define P2P_STATE_LOGFUNC(_Fmt...) -+#define P2P_EVENT_LOGFUNC(_Fmt...) -+#define P2P_TRACE_LOGFUNC(_Fmt...) -+#define P2P_LOUD_LOGFUNC(_Fmt...) -+#define P2P_TEMP_LOGFUNC(_Fmt...) -+ -+#define QM_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define QM_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define QM_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define QM_STATE_LOGFUNC(_Fmt...) -+#define QM_EVENT_LOGFUNC(_Fmt...) -+#define QM_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define QM_LOUD_LOGFUNC(_Fmt...) -+#define QM_TEMP_LOGFUNC(_Fmt...) -+ -+#define SEC_ERROR_LOGFUNC(_Fmt...) -+#define SEC_WARN_LOGFUNC(_Fmt...) -+#define SEC_INFO_LOGFUNC(_Fmt...) -+#define SEC_STATE_LOGFUNC(_Fmt...) -+#define SEC_EVENT_LOGFUNC(_Fmt...) -+#define SEC_TRACE_LOGFUNC(_Fmt...) -+#define SEC_LOUD_LOGFUNC(_Fmt...) -+#define SEC_TEMP_LOGFUNC(_Fmt...) -+ -+#define BOW_ERROR_LOGFUNC(_Fmt...) -+#define BOW_WARN_LOGFUNC(_Fmt...) -+#define BOW_INFO_LOGFUNC(_Fmt...) -+#define BOW_STATE_LOGFUNC(_Fmt...) -+#define BOW_EVENT_LOGFUNC(_Fmt...) -+#define BOW_TRACE_LOGFUNC(_Fmt...) -+#define BOW_LOUD_LOGFUNC(_Fmt...) -+#define BOW_TEMP_LOGFUNC(_Fmt...) -+ -+#define HAL_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define HAL_WARN_LOGFUNC(_Fmt...) -+#define HAL_INFO_LOGFUNC(_Fmt...) -+#define HAL_STATE_LOGFUNC(_Fmt...) -+#define HAL_EVENT_LOGFUNC(_Fmt...) -+#define HAL_TRACE_LOGFUNC(_Fmt...) -+#define HAL_LOUD_LOGFUNC(_Fmt...) -+#define HAL_TEMP_LOGFUNC(_Fmt...) -+ -+#define WAPI_ERROR_LOGFUNC(_Fmt...) -+#define WAPI_WARN_LOGFUNC(_Fmt...) -+#define WAPI_INFO_LOGFUNC(_Fmt...) -+#define WAPI_STATE_LOGFUNC(_Fmt...) -+#define WAPI_EVENT_LOGFUNC(_Fmt...) -+#define WAPI_TRACE_LOGFUNC(_Fmt...) -+#define WAPI_LOUD_LOGFUNC(_Fmt...) -+#define WAPI_TEMP_LOGFUNC(_Fmt...) -+ -+#define TDLS_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define TDLS_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define TDLS_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define TDLS_STATE_LOGFUNC(_Fmt...) -+#define TDLS_EVENT_LOGFUNC(_Fmt...) -+#define TDLS_TRACE_LOGFUNC(_Fmt...) -+#define TDLS_LOUD_LOGFUNC(_Fmt...) -+#define TDLS_TEMP_LOGFUNC(_Fmt...) -+ -+#define SW1_ERROR_LOGFUNC(_Fmt...) -+#define SW1_WARN_LOGFUNC(_Fmt...) -+#define SW1_INFO_LOGFUNC(_Fmt...) -+#define SW1_STATE_LOGFUNC(_Fmt...) -+#define SW1_EVENT_LOGFUNC(_Fmt...) -+#define SW1_TRACE_LOGFUNC(_Fmt...) -+#define SW1_LOUD_LOGFUNC(_Fmt...) -+#define SW1_TEMP_LOGFUNC(_Fmt...) -+ -+#define SW2_ERROR_LOGFUNC(_Fmt...) -+#define SW2_WARN_LOGFUNC(_Fmt...) -+#define SW2_INFO_LOGFUNC(_Fmt...) -+#define SW2_STATE_LOGFUNC(_Fmt...) -+#define SW2_EVENT_LOGFUNC(_Fmt...) -+#define SW2_TRACE_LOGFUNC(_Fmt...) -+#define SW2_LOUD_LOGFUNC(_Fmt...) -+#define SW2_TEMP_LOGFUNC(_Fmt...) -+ -+#define SW3_ERROR_LOGFUNC(_Fmt...) -+#define SW3_WARN_LOGFUNC(_Fmt...) -+#define SW3_INFO_LOGFUNC(_Fmt...) -+#define SW3_STATE_LOGFUNC(_Fmt...) -+#define SW3_EVENT_LOGFUNC(_Fmt...) -+#define SW3_TRACE_LOGFUNC(_Fmt...) -+#define SW3_LOUD_LOGFUNC(_Fmt...) -+#define SW3_TEMP_LOGFUNC(_Fmt...) -+ -+#define SW4_ERROR_LOGFUNC(_Fmt...) -+#define SW4_WARN_LOGFUNC(_Fmt...) -+#define SW4_INFO_LOGFUNC(_Fmt...) -+#define SW4_STATE_LOGFUNC(_Fmt...) -+#define SW4_EVENT_LOGFUNC(_Fmt...) -+#define SW4_TRACE_LOGFUNC(_Fmt...) -+#define SW4_LOUD_LOGFUNC(_Fmt...) -+#define SW4_TEMP_LOGFUNC(_Fmt...) -+#endif -+ -+#define kalBreakPoint() \ -+do { \ -+ BUG(); \ -+ panic("Oops"); \ -+} while (0) -+ -+#if CFG_ENABLE_AEE_MSG -+#define kalSendAeeException aee_kernel_exception -+#define kalSendAeeWarning aee_kernel_warning -+#define kalSendAeeReminding aee_kernel_reminding -+#else -+#define kalSendAeeException(_module, _desc, ...) -+#define kalSendAeeWarning(_module, _desc, ...) -+#define kalSendAeeReminding(_module, _desc, ...) -+#endif -+ -+#define PRINTF_ARG(...) __VA_ARGS__ -+#define SPRINTF(buf, arg) {buf += sprintf((char *)(buf), PRINTF_ARG arg); } -+ -+#define USEC_TO_SYSTIME(_usec) ((_usec) / USEC_PER_MSEC) -+#define MSEC_TO_SYSTIME(_msec) (_msec) -+ -+#define MSEC_TO_JIFFIES(_msec) msecs_to_jiffies(_msec) -+ -+#define KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE 3000 /* 3s */ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in gl_kal.c */ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalAcquireSpinLock(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, OUT unsigned long *pu4Flags); -+ -+VOID kalReleaseSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, IN UINT_32 u4Flags); -+ -+VOID kalUpdateMACAddress(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucMacAddr); -+ -+VOID kalPacketFree(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket); -+ -+PVOID kalPacketAlloc(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Size, OUT PUINT_8 *ppucData); -+ -+VOID kalOsTimerInitialize(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prTimerHandler); -+ -+BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN OS_SYSTIME rInterval); -+ -+WLAN_STATUS -+kalProcessRxPacket(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN PUINT_8 pucPacketStart, IN UINT_32 u4PacketLen, -+ /* IN PBOOLEAN pfgIsRetain, */ -+ IN BOOLEAN fgIsRetain, IN ENUM_CSUM_RESULT_T aeCSUM[] -+); -+ -+WLAN_STATUS kalRxIndicatePkts(IN P_GLUE_INFO_T prGlueInfo, IN PVOID apvPkts[], IN UINT_8 ucPktNum); -+ -+VOID -+kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus, IN PVOID pvBuf, IN UINT_32 u4BufLen); -+ -+VOID -+kalUpdateReAssocReqInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest); -+ -+VOID kalUpdateReAssocRspInfo(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen); -+ -+#if CFG_TX_FRAGMENT -+BOOLEAN -+kalQueryTxPacketHeader(IN P_GLUE_INFO_T prGlueInfo, -+ IN PVOID pvPacket, OUT PUINT_16 pu2EtherTypeLen, OUT PUINT_8 pucEthDestAddr); -+#endif /* CFG_TX_FRAGMENT */ -+ -+VOID kalSendCompleteAndAwakeQueue(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+VOID kalQueryTxChksumOffloadParam(IN PVOID pvPacket, OUT PUINT_8 pucFlag); -+ -+VOID kalUpdateRxCSUMOffloadParam(IN PVOID pvPacket, IN ENUM_CSUM_RESULT_T eCSUM[] -+); -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+BOOLEAN kalRetrieveNetworkAddress(IN P_GLUE_INFO_T prGlueInfo, IN OUT PARAM_MAC_ADDRESS *prMacAddr); -+ -+VOID -+kalReadyOnChannel(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, -+ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum, IN UINT_32 u4DurationMs); -+ -+VOID -+kalRemainOnChannelExpired(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum); -+ -+VOID -+kalIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen); -+ -+VOID kalIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines in interface - ehpi/sdio.c */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalDevRegRead(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, OUT PUINT_32 pu4Value); -+ -+BOOLEAN kalDevRegWrite(P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, IN UINT_32 u4Value); -+ -+BOOLEAN -+kalDevPortRead(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_16 u2Port, IN UINT_32 u2Len, OUT PUINT_8 pucBuf, IN UINT_32 u2ValidOutBufSize); -+ -+BOOLEAN -+kalDevPortWrite(P_GLUE_INFO_T prGlueInfo, -+ IN UINT_16 u2Port, IN UINT_32 u2Len, IN PUINT_8 pucBuf, IN UINT_32 u2ValidInBufSize); -+ -+BOOLEAN kalDevWriteWithSdioCmd52(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Addr, IN UINT_8 ucData); -+ -+void kalDevLoopbkAuto(IN GLUE_INFO_T *GlueInfo); -+ -+#if CFG_SUPPORT_EXT_CONFIG -+UINT_32 kalReadExtCfg(IN P_GLUE_INFO_T prGlueInfo); -+#endif -+ -+BOOLEAN -+kalQoSFrameClassifierAndPacketInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_NATIVE_PACKET prPacket, -+ OUT PUINT_8 pucPriorityParam, -+ OUT PUINT_32 pu4PacketLen, -+ OUT PUINT_8 pucEthDestAddr, -+ OUT PBOOLEAN pfgIs1X, -+ OUT PBOOLEAN pfgIsPAL, OUT PUINT_8 pucNetworkType, -+ OUT PVOID prGenUse); -+ -+VOID -+kalOidComplete(IN P_GLUE_INFO_T prGlueInfo, -+ IN BOOLEAN fgSetQuery, IN UINT_32 u4SetQueryInfoLen, IN WLAN_STATUS rOidStatus); -+ -+WLAN_STATUS -+kalIoctl(IN P_GLUE_INFO_T prGlueInfo, -+ IN PFN_OID_HANDLER_FUNC pfnOidHandler, -+ IN PVOID pvInfoBuf, -+ IN UINT_32 u4InfoBufLen, -+ IN BOOLEAN fgRead, IN BOOLEAN fgWaitResp, IN BOOLEAN fgCmd, IN BOOLEAN fgIsP2pOid, OUT PUINT_32 pu4QryInfoLen); -+ -+VOID kalHandleAssocInfo(IN P_GLUE_INFO_T prGlueInfo, IN P_EVENT_ASSOC_INFO prAssocInfo); -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+ -+PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength); -+ -+VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf); -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/* Card Removal Check */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsCardRemoved(IN P_GLUE_INFO_T prGlueInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* TX */ -+/*----------------------------------------------------------------------------*/ -+VOID kalFlushPendingTxPackets(IN P_GLUE_INFO_T prGlueInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* Media State Indication */ -+/*----------------------------------------------------------------------------*/ -+ENUM_PARAM_MEDIA_STATE_T kalGetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalSetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicate); -+ -+/*----------------------------------------------------------------------------*/ -+/* OID handling */ -+/*----------------------------------------------------------------------------*/ -+VOID kalOidCmdClearance(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalOidClearance(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalEnqueueCommand(IN P_GLUE_INFO_T prGlueInfo, IN P_QUE_ENTRY_T prQueueEntry); -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+/*----------------------------------------------------------------------------*/ -+/* Bluetooth over Wi-Fi handling */ -+/*----------------------------------------------------------------------------*/ -+VOID kalIndicateBOWEvent(IN P_GLUE_INFO_T prGlueInfo, IN P_AMPC_EVENT prEvent); -+ -+ENUM_BOW_DEVICE_STATE kalGetBowState(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr); -+ -+BOOLEAN kalSetBowState(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_BOW_DEVICE_STATE eBowState, PARAM_MAC_ADDRESS rPeerAddr); -+ -+ENUM_BOW_DEVICE_STATE kalGetBowGlobalState(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_32 kalGetBowFreqInKHz(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_8 kalGetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr); -+ -+VOID kalSetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRole, IN PARAM_MAC_ADDRESS rPeerAddr); -+ -+UINT_8 kalGetBowAvailablePhysicalLinkCount(IN P_GLUE_INFO_T prGlueInfo); -+ -+#if CFG_BOW_SEPARATE_DATA_PATH -+/*----------------------------------------------------------------------------*/ -+/* Bluetooth over Wi-Fi Net Device Init/Uninit */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalInitBowDevice(IN P_GLUE_INFO_T prGlueInfo, IN const char *prDevName); -+ -+BOOLEAN kalUninitBowDevice(IN P_GLUE_INFO_T prGlueInfo); -+#endif /* CFG_BOW_SEPARATE_DATA_PATH */ -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+/*----------------------------------------------------------------------------*/ -+/* Firmware Download Handling */ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetFwStartAddress(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_32 kalGetFwLoadAddress(IN P_GLUE_INFO_T prGlueInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* Security Frame Clearance */ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearSecurityFrames(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalClearSecurityFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+VOID kalSecurityFrameSendComplete(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN WLAN_STATUS rStatus); -+ -+/*----------------------------------------------------------------------------*/ -+/* Management Frame Clearance */ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearMgmtFrames(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalClearMgmtFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+UINT_32 kalGetTxPendingFrameCount(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_32 kalGetTxPendingCmdCount(IN P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Interval); -+ -+BOOLEAN kalCancelTimer(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalScanDone(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN WLAN_STATUS status); -+ -+UINT_32 kalRandomNumber(VOID); -+ -+VOID kalTimeoutHandler(struct timer_list *t); -+ -+VOID kalSetEvent(P_GLUE_INFO_T pr); -+ -+/*----------------------------------------------------------------------------*/ -+/* NVRAM/Registry Service */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsConfigurationExist(IN P_GLUE_INFO_T prGlueInfo); -+ -+P_REG_INFO_T kalGetConfiguration(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID -+kalGetConfigurationVersion(IN P_GLUE_INFO_T prGlueInfo, -+ OUT PUINT_16 pu2Part1CfgOwnVersion, -+ OUT PUINT_16 pu2Part1CfgPeerVersion, -+ OUT PUINT_16 pu2Part2CfgOwnVersion, OUT PUINT_16 pu2Part2CfgPeerVersion); -+ -+BOOLEAN kalCfgDataRead16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, OUT PUINT_16 pu2Data); -+ -+BOOLEAN kalCfgDataWrite16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, IN UINT_16 u2Data); -+ -+/*----------------------------------------------------------------------------*/ -+/* WSC Connection */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalWSCGetActiveState(IN P_GLUE_INFO_T prGlueInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* RSSI Updating */ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalUpdateRSSI(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality); -+ -+/*----------------------------------------------------------------------------*/ -+/* I/O Buffer Pre-allocation */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalInitIOBuffer(VOID); -+ -+VOID kalUninitIOBuffer(VOID); -+ -+PVOID kalAllocateIOBuffer(IN UINT_32 u4AllocSize); -+ -+VOID kalReleaseIOBuffer(IN PVOID pvAddr, IN UINT_32 u4Size); -+ -+VOID -+kalGetChannelList(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_BAND_T eSpecificBand, -+ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList); -+ -+BOOLEAN kalIsAPmode(IN P_GLUE_INFO_T prGlueInfo); -+ -+ULONG kalIOPhyAddrGet(IN ULONG VirtAddr); -+ -+VOID kalDmaBufGet(OUT VOID **VirtAddr, OUT VOID **PhyAddr); -+ -+#if CFG_SUPPORT_802_11W -+/*----------------------------------------------------------------------------*/ -+/* 802.11W */ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetMfpSetting(IN P_GLUE_INFO_T prGlueInfo); -+#endif -+ -+UINT_32 kalWriteToFile(const PUINT_8 pucPath, BOOLEAN fgDoAppend, PUINT_8 pucData, UINT_32 u4Size); -+ -+/*----------------------------------------------------------------------------*/ -+/* NL80211 */ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBuf, IN UINT_32 u4BufLen, IN UINT_8 ucChannelNum, IN INT_32 i4SignalStrength); -+ -+/*----------------------------------------------------------------------------*/ -+/* PNO Support */ -+/*----------------------------------------------------------------------------*/ -+VOID kalSchedScanResults(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalSchedScanStopped(IN P_GLUE_INFO_T prGlueInfo); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+int tx_thread(void *data); -+ -+VOID kalHifAhbKalWakeLockTimeout(IN P_GLUE_INFO_T prGlueInfo); -+VOID kalMetProfilingStart(IN P_GLUE_INFO_T prGlueInfo, IN struct sk_buff *prSkb); -+VOID kalMetProfilingFinish(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+int kalMetInitProcfs(IN P_GLUE_INFO_T prGlueInfo); -+int kalMetRemoveProcfs(void); -+ -+UINT_64 kalGetBootTime(void); -+ -+INT_32 kalReadToFile(const PUINT_8 pucPath, PUINT_8 pucData, UINT_32 u4Size, PUINT_32 pu4ReadSize); -+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG -+BOOLEAN kalIsWakeupByWlan(P_ADAPTER_T prAdapter); -+#endif -+INT_32 kalHaltLock(UINT_32 waitMs); -+INT_32 kalHaltTryLock(VOID); -+VOID kalHaltUnlock(VOID); -+VOID kalSetHalted(BOOLEAN fgHalt); -+BOOLEAN kalIsHalted(VOID); -+ -+INT32 kalPerMonInit(IN P_GLUE_INFO_T prGlueInfo); -+INT32 kalPerMonDisable(IN P_GLUE_INFO_T prGlueInfo); -+INT32 kalPerMonEnable(IN P_GLUE_INFO_T prGlueInfo); -+INT32 kalPerMonStart(IN P_GLUE_INFO_T prGlueInfo); -+INT32 kalPerMonStop(IN P_GLUE_INFO_T prGlueInfo); -+INT32 kalPerMonDestroy(IN P_GLUE_INFO_T prGlueInfo); -+VOID kalPerMonHandler(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+INT32 kalBoostCpu(UINT_32 core_num); -+ -+#endif /* _GL_KAL_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h -new file mode 100644 -index 0000000000000..a4321e7f9a119 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h -@@ -0,0 +1,1270 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_os.h#2 -+*/ -+ -+/*! \file gl_os.h -+ \brief List the external reference to OS for GLUE Layer. -+ -+ In this file we define the data structure - GLUE_INFO_T to store those objects -+ we acquired from OS - e.g. TIMER, SPINLOCK, NET DEVICE ... . And all the -+ external reference (header file, extern func() ..) to OS for GLUE Layer should -+ also list down here. -+*/ -+ -+/* -+** Log: gl_os.h -+** -+** 08 20 2012 yuche.tsai -+** NULL -+** Fix possible KE issue. -+** -+** 08 20 2012 yuche.tsai -+** [ALPS00339327] [Rose][6575JB][BSP Package][Free Test][KE][WIFI]There is no response when you tap the turn off/on -+** button,wait a minutes, the device will reboot automatically and "KE" will pop up. -+** Fix possible KE when netlink operate mgmt frame register. -+ * -+ * 04 12 2012 terry.wu -+ * NULL -+ * Add AEE message support -+ * 1) Show AEE warning(red screen) if SDIO access error occurs -+ -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Enable CFG80211 Support. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 12 13 2011 cm.chang -+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer -+ * Add wake lock if timer timeout value is smaller than 5 seconds -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 16 2011 yuche.tsai -+ * NULL -+ * Avoid using work thread. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 29 2011 terry.wu -+ * NULL -+ * Show DRV_NAME by chip id. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * support concurrent network -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * modify net device relative functions to support multiple H/W queues -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add security check code. -+ * -+ * 02 21 2011 cp.wu -+ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain -+ * simplify logic for checking NVRAM existence only once. -+ * -+ * 02 16 2011 jeffrey.chang -+ * NULL -+ * Add query ipv4 and ipv6 address during early suspend and late resume -+ * -+ * 02 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix kernel API change issue. -+ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is -+ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); -+ * After ALPS 2.3, kfifo_alloc() is changed to -+ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module with structure miss-align -+ * pointer issue -+ * always pre-allio WAPI related structure for align p2p module. -+ * -+ * 02 09 2011 terry.wu -+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules -+ * Halt p2p module init and exit until TxThread finished p2p register and unregister. -+ * -+ * 02 01 2011 cm.chang -+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode -+ * . -+ * -+ * 01 27 2011 cm.chang -+ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default -+ * . -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation -+ * needs such information -+ * fill mac header length information for 802.1x frames. -+ * -+ * 01 11 2011 chinglan.wang -+ * NULL -+ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. Connection establish -+ * successfully. -+ * Use the WPS function to connect AP, the privacy bit always is set to 1. -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues -+ * due to multiple access -+ * use mutex to protect kalIoctl() for thread safe. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * ioctl implementations for P2P Service Discovery -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 09 13 2010 cp.wu -+ * NULL -+ * add waitq for poll() and read(). -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 06 2010 wh.su -+ * NULL -+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * revised implementation of Wi-Fi Direct io controls. -+ * -+ * 08 11 2010 cp.wu -+ * NULL -+ * 1) do not use in-stack variable for beacon updating. (for MAUI porting) -+ * 2) extending scanning result to 64 instead of 48 -+ * -+ * 08 06 2010 cp.wu -+ * NULL -+ * driver hook modifications corresponding to ioctl interface change. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct] add framework for driver hooks -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * add new KAL api -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * modify tx thread and remove some spinlock -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add security frame pending count -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 01 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl to configure scan mode for p2p connection -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add cfg80211 interface, which is to replace WE, for further extension -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * p2p ioctls revised. -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl for controlling p2p scan phase parameters -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement basic wi-fi direct framework -+ * -+ * 05 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * prevent supplicant accessing driver during resume -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic framework for implementating P2P driver hook. -+ * -+ * 05 05 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change variable names for multiple physical link to match with coding convention -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * identify BT Over Wi-Fi Security frame and mark it as 802.1X frame -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) fix firmware download bug -+ * 2) remove query statistics for acelerating firmware download -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * follow Linux's firmware framework, and remove unused kal API -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * supporting power management -+ * -+ * 04 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * pvInformationBuffer and u4InformationBufferLength are no longer in glue -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple -+ * * * * * * * * * * * * * * * * * * * * handler capability -+ * * * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other -+ * * * * * * * * * * * * * * * * * * * * purpose -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * * * * * * are done in adapter layer. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Tag the packet for QoS on Tx path -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * (1)deliver the kalOidComplete status to upper layer -+ * * (2) fix spin lock -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add timeout check in the kalOidComplete -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * emulate NDIS Pending OID facility -+ * -+ * 03 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * adding firmware download related data type -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. -+ * * * * the frequency is used for adhoc connection only -+ * * * * 2) update with SD1 v0.9 CMD/EVENT documentation -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add Bluetooth-over-Wifi frame header check -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\30 2009-10-20 17:38:31 GMT mtk01090 -+** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, -+** and then stop hw. -+** \main\maintrunk.MT5921\29 2009-10-08 10:33:33 GMT mtk01090 -+** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input -+** parameters and pointers. -+** \main\maintrunk.MT5921\28 2009-09-28 20:19:26 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\27 2009-08-18 22:57:12 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\26 2009-07-06 21:42:25 GMT mtk01088 -+** fixed the compiling error at linux -+** \main\maintrunk.MT5921\25 2009-07-06 20:51:46 GMT mtk01088 -+** adding the wapi 1x ether type define -+** \main\maintrunk.MT5921\24 2009-06-23 23:19:18 GMT mtk01090 -+** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support -+** \main\maintrunk.MT5921\23 2009-02-07 15:05:06 GMT mtk01088 -+** add the privacy flag to ingo driver the supplicant selected ap's security -+** \main\maintrunk.MT5921\22 2009-02-05 15:34:09 GMT mtk01088 -+** fixed the compiling error for using bits marco for only one parameter -+** \main\maintrunk.MT5921\21 2009-01-22 13:02:13 GMT mtk01088 -+** data frame is or not 802.1x value share with tid, using the same reserved byte, provide the function to set and get -+** \main\maintrunk.MT5921\20 2008-10-24 12:04:16 GMT mtk01088 -+** move the config.h from precomp.h to here for lint check -+** \main\maintrunk.MT5921\19 2008-09-22 23:19:02 GMT mtk01461 -+** Update driver for code review -+** \main\maintrunk.MT5921\18 2008-09-05 17:25:13 GMT mtk01461 -+** Update Driver for Code Review -+** \main\maintrunk.MT5921\17 2008-08-01 13:32:47 GMT mtk01084 -+** Prevent redundent driver assertion in driver logic when BUS is detached -+** \main\maintrunk.MT5921\16 2008-05-30 14:41:43 GMT mtk01461 -+** Remove WMM Assoc Flag in KAL -+** \main\maintrunk.MT5921\15 2008-05-29 14:16:25 GMT mtk01084 -+** remoev un-used variable -+** \main\maintrunk.MT5921\14 2008-05-03 15:17:14 GMT mtk01461 -+** Add Media Status variable in Glue Layer -+** \main\maintrunk.MT5921\13 2008-04-24 11:58:41 GMT mtk01461 -+** change threshold to 256 -+** \main\maintrunk.MT5921\12 2008-03-11 14:51:05 GMT mtk01461 -+** Remove redundant GL_CONN_INFO_T -+** \main\maintrunk.MT5921\11 2008-01-07 15:07:41 GMT mtk01461 -+** Adjust the netif stop threshold to 150 -+** \main\maintrunk.MT5921\10 2007-11-26 19:43:46 GMT mtk01461 -+** Add OS_TIMESTAMP macro -+** -+** \main\maintrunk.MT5921\9 2007-11-07 18:38:38 GMT mtk01461 -+** Move definition -+** \main\maintrunk.MT5921\8 2007-11-02 01:04:00 GMT mtk01461 -+** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning -+** Revision 1.5 2007/07/12 11:04:28 MTK01084 -+** update macro to delay for ms order -+** -+** Revision 1.4 2007/07/05 07:25:34 MTK01461 -+** Add Linux initial code, modify doc, add 11BB, RF init code -+** -+** Revision 1.3 2007/06/27 02:18:51 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+** Revision 1.2 2007/06/25 06:16:24 MTK01461 -+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API -+** -+*/ -+ -+#ifndef _GL_OS_H -+#define _GL_OS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+/*------------------------------------------------------------------------------ -+ * Flags for LINUX(OS) dependent -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_MAX_WLAN_DEVICES 1 /* number of wlan card will coexist */ -+ -+#define CFG_MAX_TXQ_NUM 4 /* number of tx queue for support multi-queue h/w */ -+ -+#define CFG_USE_SPIN_LOCK_BOTTOM_HALF 0 /* 1: Enable use of SPIN LOCK Bottom Half for LINUX -+ 0: Disable - use SPIN LOCK IRQ SAVE instead */ -+ -+#define CFG_TX_PADDING_SMALL_ETH_PACKET 0 /* 1: Enable - Drop ethernet packet if it < 14 bytes. -+ And pad ethernet packet with dummy 0 if it < 60 bytes. -+ 0: Disable */ -+ -+#define CFG_TX_STOP_NETIF_QUEUE_THRESHOLD 256 /* packets */ -+ -+#define CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD 256 /* packets */ -+#define CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD 128 /* packets */ -+ -+#define ETH_P_1X 0x888E -+#define IPTOS_PREC_OFFSET 5 -+#define USER_PRIORITY_DEFAULT 0 -+ -+#define ETH_WPI_1X 0x88B4 -+ -+#define ETH_HLEN 14 -+#define ETH_TYPE_LEN_OFFSET 12 -+#define ETH_P_IP 0x0800 -+#define ETH_P_1X 0x888E -+#define ETH_P_PRE_1X 0x88C7 -+#define ETH_P_ARP 0x0806 -+ -+#define ARP_PRO_REQ 1 -+#define ARP_PRO_RSP 2 -+ -+#define IPVERSION 4 -+#define IP_HEADER_LEN 20 -+ -+#define IP_PRO_ICMP 0x01 -+#define IP_PRO_UDP 0x11 -+#define IP_PRO_TCP 0x06 -+ -+#define UDP_PORT_DHCPS 0x43 -+#define UDP_PORT_DHCPC 0x44 -+#define UDP_PORT_DNS 0x35 -+ -+#define IPVH_VERSION_OFFSET 4 /* For Little-Endian */ -+#define IPVH_VERSION_MASK 0xF0 -+#define IPTOS_PREC_OFFSET 5 -+#define IPTOS_PREC_MASK 0xE0 -+ -+#define SOURCE_PORT_LEN 2 -+/* NOTE(Kevin): Without IP Option Length */ -+#define LOOK_AHEAD_LEN (ETH_HLEN + IP_HEADER_LEN + SOURCE_PORT_LEN) -+ -+/* 802.2 LLC/SNAP */ -+#define ETH_LLC_OFFSET (ETH_HLEN) -+#define ETH_LLC_LEN 3 -+#define ETH_LLC_DSAP_SNAP 0xAA -+#define ETH_LLC_SSAP_SNAP 0xAA -+#define ETH_LLC_CONTROL_UNNUMBERED_INFORMATION 0x03 -+ -+/* Bluetooth SNAP */ -+#define ETH_SNAP_OFFSET (ETH_HLEN + ETH_LLC_LEN) -+#define ETH_SNAP_LEN 5 -+#define ETH_SNAP_BT_SIG_OUI_0 0x00 -+#define ETH_SNAP_BT_SIG_OUI_1 0x19 -+#define ETH_SNAP_BT_SIG_OUI_2 0x58 -+ -+#define BOW_PROTOCOL_ID_SECURITY_FRAME 0x0003 -+ -+#if defined(MT6620) -+#define CHIP_NAME "MT6620" -+#elif defined(MT6628) -+#define CHIP_NAME "MT6582" -+#endif -+ -+#define DRV_NAME "["CHIP_NAME"]: " -+ -+#define CONFIG_ANDROID 1 -+/* Define if target platform is Android. -+ * It should already be defined in Android kernel source -+ */ -+ -+/* for CFG80211 IE buffering mechanism */ -+#define CFG_CFG80211_IE_BUF_LEN (512) -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include /* constant of kernel version */ -+ -+#include /* bitops.h */ -+ -+#include /* struct timer_list */ -+#include /* jiffies */ -+#include /* udelay and mdelay macro */ -+ -+#if CONFIG_ANDROID -+#include -+#endif -+ -+#include /* IRQT_FALLING */ -+ -+#include /* struct net_device, struct net_device_stats */ -+#include /* for eth_type_trans() function */ -+#include /* struct iw_statistics */ -+#include -+#include /* struct in_device */ -+ -+#include /* struct iphdr */ -+ -+#include /* for memcpy()/memset() function */ -+#include /* for offsetof() macro */ -+ -+#include /* The proc filesystem constants/structures */ -+ -+#include /* for rtnl_lock() and rtnl_unlock() */ -+#include /* kthread_should_stop(), kthread_run() */ -+#include /* for copy_from_user() */ -+#include /* for firmware download */ -+#include -+ -+#include /* for kfifo interface */ -+#include /* for cdev interface */ -+ -+#include /* for firmware download */ -+ -+#if defined(_HIF_SDIO) -+#include -+#include -+#endif -+ -+#include -+ -+#include -+#include -+ -+#include /* readw and writew */ -+ -+#if WIRELESS_EXT > 12 -+#include -+#endif -+ -+#include "version.h" -+#include "config.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#include -+#include -+#endif -+ -+#include -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+#include -+#endif -+ -+#include "gl_typedef.h" -+#include "typedef.h" -+#include "queue.h" -+#include "gl_kal.h" -+#include "hif.h" -+#if CFG_CHIP_RESET_SUPPORT -+#include "gl_rst.h" -+#endif -+ -+#if (CFG_SUPPORT_TDLS == 1) -+#include "tdls_extr.h" -+#endif -+#include "debug.h" -+ -+#include "wlan_lib.h" -+#include "wlan_oid.h" -+ -+#if CFG_ENABLE_AEE_MSG -+#include -+#endif -+ -+extern BOOLEAN fgIsBusAccessFailed; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define GLUE_FLAG_HALT BIT(0) -+#define GLUE_FLAG_INT BIT(1) -+#define GLUE_FLAG_OID BIT(2) -+#define GLUE_FLAG_TIMEOUT BIT(3) -+#define GLUE_FLAG_TXREQ BIT(4) -+#define GLUE_FLAG_SUB_MOD_INIT BIT(5) -+#define GLUE_FLAG_SUB_MOD_EXIT BIT(6) -+#define GLUE_FLAG_SUB_MOD_MULTICAST BIT(7) -+#define GLUE_FLAG_FRAME_FILTER BIT(8) -+#define GLUE_FLAG_FRAME_FILTER_AIS BIT(9) -+#define GLUE_FLAG_HIF_LOOPBK_AUTO BIT(10) -+#define GLUE_FLAG_HALT_BIT (0) -+#define GLUE_FLAG_INT_BIT (1) -+#define GLUE_FLAG_OID_BIT (2) -+#define GLUE_FLAG_TIMEOUT_BIT (3) -+#define GLUE_FLAG_TXREQ_BIT (4) -+#define GLUE_FLAG_SUB_MOD_INIT_BIT (5) -+#define GLUE_FLAG_SUB_MOD_EXIT_BIT (6) -+#define GLUE_FLAG_SUB_MOD_MULTICAST_BIT (7) -+#define GLUE_FLAG_FRAME_FILTER_BIT (8) -+#define GLUE_FLAG_FRAME_FILTER_AIS_BIT (9) -+#define GLUE_FLAG_HIF_LOOPBK_AUTO_BIT (10) -+ -+#define GLUE_BOW_KFIFO_DEPTH (1024) -+/* #define GLUE_BOW_DEVICE_NAME "MT6620 802.11 AMP" */ -+#define GLUE_BOW_DEVICE_NAME "ampc0" -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _GL_WPA_INFO_T { -+ UINT_32 u4WpaVersion; -+ UINT_32 u4KeyMgmt; -+ UINT_32 u4CipherGroup; -+ UINT_32 u4CipherPairwise; -+ UINT_32 u4AuthAlg; -+ BOOLEAN fgPrivacyInvoke; -+#if CFG_SUPPORT_802_11W -+ UINT_32 u4Mfp; -+#endif -+} GL_WPA_INFO_T, *P_GL_WPA_INFO_T; -+ -+typedef enum _ENUM_RSSI_TRIGGER_TYPE { -+ ENUM_RSSI_TRIGGER_NONE, -+ ENUM_RSSI_TRIGGER_GREATER, -+ ENUM_RSSI_TRIGGER_LESS, -+ ENUM_RSSI_TRIGGER_TRIGGERED, -+ ENUM_RSSI_TRIGGER_NUM -+} ENUM_RSSI_TRIGGER_TYPE; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+typedef enum _ENUM_SUB_MODULE_IDX_T { -+ P2P_MODULE = 0, -+ SUB_MODULE_NUM -+} ENUM_SUB_MODULE_IDX_T; -+ -+typedef enum _ENUM_NET_REG_STATE_T { -+ ENUM_NET_REG_STATE_UNREGISTERED, -+ ENUM_NET_REG_STATE_REGISTERING, -+ ENUM_NET_REG_STATE_REGISTERED, -+ ENUM_NET_REG_STATE_UNREGISTERING, -+ ENUM_NET_REG_STATE_NUM -+} ENUM_NET_REG_STATE_T; -+ -+#endif -+ -+typedef struct _GL_IO_REQ_T { -+ QUE_ENTRY_T rQueEntry; -+ /* wait_queue_head_t cmdwait_q; */ -+ BOOLEAN fgRead; -+ BOOLEAN fgWaitResp; -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgIsP2pOid; -+#endif -+ P_ADAPTER_T prAdapter; -+ PFN_OID_HANDLER_FUNC pfnOidHandler; -+ PVOID pvInfoBuf; -+ UINT_32 u4InfoBufLen; -+ PUINT_32 pu4QryInfoLen; -+ WLAN_STATUS rStatus; -+ UINT_32 u4Flag; -+} GL_IO_REQ_T, *P_GL_IO_REQ_T; -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+typedef struct _GL_BOW_INFO { -+ BOOLEAN fgIsRegistered; -+ dev_t u4DeviceNumber; /* dynamic device number */ -+/* struct kfifo *prKfifo; */ /* for buffering indicated events */ -+ struct kfifo rKfifo; /* for buffering indicated events */ -+ spinlock_t rSpinLock; /* spin lock for kfifo */ -+ struct cdev cdev; -+ UINT_32 u4FreqInKHz; /* frequency */ -+ -+ UINT_8 aucRole[CFG_BOW_PHYSICAL_LINK_NUM]; /* 0: Responder, 1: Initiator */ -+ ENUM_BOW_DEVICE_STATE aeState[CFG_BOW_PHYSICAL_LINK_NUM]; -+ PARAM_MAC_ADDRESS arPeerAddr[CFG_BOW_PHYSICAL_LINK_NUM]; -+ -+ wait_queue_head_t outq; -+ -+#if CFG_BOW_SEPARATE_DATA_PATH -+ /* Device handle */ -+ struct net_device *prDevHandler; -+ BOOLEAN fgIsNetRegistered; -+#endif -+ -+} GL_BOW_INFO, *P_GL_BOW_INFO; -+#endif -+ -+#if (CFG_SUPPORT_TDLS == 1) -+typedef struct _TDLS_INFO_LINK_T { -+ /* start time when link is built, end time when link is broken */ -+ unsigned long jiffies_start, jiffies_end; -+ -+ /* the peer MAC */ -+ UINT8 aucPeerMac[6]; -+ -+ /* broken reason */ -+ UINT8 ucReasonCode; -+ -+ /* TRUE: torn down is triggerred by us */ -+ UINT8 fgIsFromUs; -+ -+ /* duplicate count; same reason */ -+ UINT8 ucDupCount; -+ -+ /* HT capability */ -+#define TDLS_INFO_LINK_HT_CAP_SUP 0x01 -+ UINT8 ucHtCap; -+#define TDLS_INFO_LINK_HT_BA_SETUP 0x01 -+#define TDLS_INFO_LINK_HT_BA_SETUP_OK 0x02 -+#define TDLS_INFO_LINK_HT_BA_SETUP_DECLINE 0x04 -+#define TDLS_INFO_LINK_HT_BA_PEER 0x10 -+#define TDLS_INFO_LINK_HT_BA_RSP_OK 0x20 -+#define TDLS_INFO_LINK_HT_BA_RSP_DECLINE 0x40 -+ UINT8 ucHtBa[8]; /* TID0 ~ TID7 */ -+} TDLS_INFO_LINK_T; -+ -+typedef struct _TDLS_INFO_T { -+ /* link history */ -+#define TDLS_LINK_HISTORY_MAX 30 -+ TDLS_INFO_LINK_T rLinkHistory[TDLS_LINK_HISTORY_MAX]; -+ UINT32 u4LinkIdx; -+ -+ /* TRUE: support 20/40 bandwidth in TDLS link */ -+ BOOLEAN fgIs2040Sup; -+ -+ /* total TDLS link count */ -+ INT8 cLinkCnt; -+} TDLS_INFO_T; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+/* -+* type definition of pointer to p2p structure -+*/ -+typedef struct _GL_P2P_INFO_T GL_P2P_INFO_T, *P_GL_P2P_INFO_T; -+ -+struct _GLUE_INFO_T { -+ /* Device handle */ -+ struct net_device *prDevHandler; -+ -+ /* Device Index(index of arWlanDevInfo[]) */ -+ INT_32 i4DevIdx; -+ -+ /* Device statistics */ -+ struct net_device_stats rNetDevStats; -+ -+ /* Wireless statistics struct net_device */ -+ struct iw_statistics rIwStats; -+ -+ /* spinlock to sync power save mechanism */ -+ spinlock_t rSpinLock[SPIN_LOCK_NUM]; -+ -+ /* semaphore for ioctl */ -+ struct semaphore ioctl_sem; -+ -+ UINT_64 u8Cookie; -+ -+ ULONG ulFlag; /* GLUE_FLAG_XXX */ -+ UINT_32 u4PendFlag; -+ /* UINT_32 u4TimeoutFlag; */ -+ UINT_32 u4OidCompleteFlag; -+ UINT_32 u4ReadyFlag; /* check if card is ready */ -+ -+ UINT_32 u4OsMgmtFrameFilter; -+ -+ /* Number of pending frames, also used for debuging if any frame is -+ * missing during the process of unloading Driver. -+ * -+ * NOTE(Kevin): In Linux, we also use this variable as the threshold -+ * for manipulating the netif_stop(wake)_queue() func. -+ */ -+ INT_32 ai4TxPendingFrameNumPerQueue[4][CFG_MAX_TXQ_NUM]; -+ INT_32 i4TxPendingFrameNum; -+ INT_32 i4TxPendingSecurityFrameNum; -+ -+ /* current IO request for kalIoctl */ -+ GL_IO_REQ_T OidEntry; -+ -+ /* registry info */ -+ REG_INFO_T rRegInfo; -+ -+ /* firmware */ -+ struct firmware *prFw; -+ -+ /* Host interface related information */ -+ /* defined in related hif header file */ -+ GL_HIF_INFO_T rHifInfo; -+ -+ /*! \brief wext wpa related information */ -+ GL_WPA_INFO_T rWpaInfo; -+ -+ /* Pointer to ADAPTER_T - main data structure of internal protocol stack */ -+ P_ADAPTER_T prAdapter; -+ -+#ifdef WLAN_INCLUDE_PROC -+ struct proc_dir_entry *pProcRoot; -+#endif /* WLAN_INCLUDE_PROC */ -+ -+ /* Indicated media state */ -+ ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicated; -+ -+ /* Device power state D0~D3 */ -+ PARAM_DEVICE_POWER_STATE ePowerState; -+ -+ struct completion rScanComp; /* indicate scan complete */ -+ struct completion rHaltComp; /* indicate main thread halt complete */ -+ struct completion rPendComp; /* indicate main thread halt complete */ -+#if CFG_ENABLE_WIFI_DIRECT -+ struct completion rSubModComp; /*indicate sub module init or exit complete */ -+#endif -+ WLAN_STATUS rPendStatus; -+ -+ QUE_T rTxQueue; -+ -+ /* OID related */ -+ QUE_T rCmdQueue; -+ /* PVOID pvInformationBuffer; */ -+ /* UINT_32 u4InformationBufferLength; */ -+ /* PVOID pvOidEntry; */ -+ /* PUINT_8 pucIOReqBuff; */ -+ /* QUE_T rIOReqQueue; */ -+ /* QUE_T rFreeIOReqQueue; */ -+ -+ wait_queue_head_t waitq; -+ struct task_struct *main_thread; -+ -+ struct timer_list tickfn; -+ -+#if CFG_SUPPORT_EXT_CONFIG -+ UINT_16 au2ExtCfg[256]; /* NVRAM data buffer */ -+ UINT_32 u4ExtCfgLength; /* 0 means data is NOT valid */ -+#endif -+ -+#if 1 /* CFG_SUPPORT_WAPI */ -+ /* Should be large than the PARAM_WAPI_ASSOC_INFO_T */ -+ UINT_8 aucWapiAssocInfoIEs[42]; -+ UINT_16 u2WapiAssocInfoIESz; -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ GL_BOW_INFO rBowInfo; -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ P_GL_P2P_INFO_T prP2PInfo; -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ /* Wireless statistics struct net_device */ -+ struct iw_statistics rP2pIwStats; -+#endif -+#endif -+ BOOLEAN fgWpsActive; -+ UINT_8 aucWSCIE[500]; /*for probe req */ -+ UINT_16 u2WSCIELen; -+ UINT_8 aucWSCAssocInfoIE[200]; /*for Assoc req */ -+ UINT_16 u2WSCAssocInfoIELen; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ UINT_8 aucHS20AssocInfoIE[200]; /*for Assoc req */ -+ UINT_16 u2HS20AssocInfoIELen; -+ UINT_8 ucHotspotConfig; -+ BOOLEAN fgConnectHS20AP; -+#endif -+ -+ /* NVRAM availability */ -+ BOOLEAN fgNvramAvailable; -+ -+ BOOLEAN fgMcrAccessAllowed; -+ -+ /* MAC Address Overridden by IOCTL */ -+ BOOLEAN fgIsMacAddrOverride; -+ PARAM_MAC_ADDRESS rMacAddrOverride; -+ -+ SET_TXPWR_CTRL_T rTxPwr; -+ -+ /* for cfg80211 scan done indication */ -+ struct cfg80211_scan_request *prScanRequest; -+ -+ /* for cfg80211 scheduled scan */ -+ struct cfg80211_sched_scan_request *prSchedScanRequest; -+ -+ /* to indicate registered or not */ -+ BOOLEAN fgIsRegistered; -+ -+ /* for cfg80211 connected indication */ -+ UINT_32 u4RspIeLength; -+ UINT_8 aucRspIe[CFG_CFG80211_IE_BUF_LEN]; -+ -+ UINT_32 u4ReqIeLength; -+ UINT_8 aucReqIe[CFG_CFG80211_IE_BUF_LEN]; -+ -+ KAL_WAKE_LOCK_T rAhbIsrWakeLock; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ BOOLEAN fgIsDad; -+ UINT_8 aucDADipv4[4]; -+ BOOLEAN fgIs6Dad; -+ UINT_8 aucDADipv6[16]; -+#endif -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ UINT_8 u8MetProfEnable; -+ INT_16 u16MetUdpPort; -+#endif -+ BOOLEAN fgPoorlinkValid; -+ UINT_64 u8Statistic[2]; -+ UINT_64 u8TotalFailCnt; -+ UINT_32 u4LinkspeedThreshold; -+ INT_32 i4RssiThreshold; -+ INT_32 i4RssiCache; -+ UINT_32 u4LinkSpeedCache; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ TDLS_INFO_T rTdlsLink; -+ -+ UINT8 aucTdlsHtPeerMac[6]; -+ IE_HT_CAP_T rTdlsHtCap; /* temp to queue HT capability element */ -+ -+ /* -+ [0~7]: jiffies -+ [8~13]: Peer MAC -+ [14]: Reason Code -+ [15]: From us or peer -+ [16]: Duplicate Count -+ */ -+/* UINT8 aucTdlsDisconHistory[TDLS_DISCON_HISTORY_MAX][20]; */ -+/* UINT32 u4TdlsDisconIdx; */ -+#endif /* CFG_SUPPORT_TDLS */ -+ UINT_32 IsrCnt; -+ UINT_32 IsrPassCnt; -+ UINT_32 TaskIsrCnt; -+ -+ UINT_32 IsrPreCnt; -+ UINT_32 IsrPrePassCnt; -+ UINT_32 TaskPreIsrCnt; -+ -+ UINT_32 IsrAbnormalCnt; -+ UINT_32 IsrSoftWareCnt; -+ UINT_32 IsrTxCnt; -+ UINT_32 IsrRxCnt; -+ UINT_64 u8SkbToDriver; -+ UINT_64 u8SkbFreed; -+}; -+ -+typedef irqreturn_t(*PFN_WLANISR) (int irq, void *dev_id, struct pt_regs *regs); -+ -+typedef void (*PFN_LINUX_TIMER_FUNC) (unsigned long); -+ -+/* generic sub module init/exit handler -+* now, we only have one sub module, p2p -+*/ -+#if CFG_ENABLE_WIFI_DIRECT -+typedef BOOLEAN(*SUB_MODULE_INIT) (P_GLUE_INFO_T prGlueInfo); -+typedef BOOLEAN(*SUB_MODULE_EXIT) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef struct _SUB_MODULE_HANDLER { -+ SUB_MODULE_INIT subModInit; -+ SUB_MODULE_EXIT subModExit; -+ BOOLEAN fgIsInited; -+} SUB_MODULE_HANDLER, *P_SUB_MODULE_HANDLER; -+ -+#endif -+ -+ -+#ifdef CONFIG_NL80211_TESTMODE -+enum TestModeCmdType { -+ /* old test mode command id, compatible with exist testmode command */ -+ TESTMODE_CMD_ID_SW_CMD = 1, -+ TESTMODE_CMD_ID_WAPI = 2, -+ TESTMODE_CMD_ID_HS20 = 3, -+ TESTMODE_CMD_ID_POORLINK = 4, -+ TESTMODE_CMD_ID_STATISTICS = 0x10, -+ TESTMODE_CMD_ID_LINK_DETECT = 0x20, -+ /* old test mode command id, compatible with exist testmode command */ -+ -+ /* all new added test mode command should great than TESTMODE_CMD_ID_NEW_BEGIN */ -+ TESTMODE_CMD_ID_NEW_BEGIN = 100, -+ TESTMODE_CMD_ID_SUSPEND = 101, -+}; -+#if CFG_SUPPORT_HOTSPOT_2_0 -+enum Hs20CmdType { -+ HS20_CMD_ID_SET_BSSID_POOL = 0, -+ NUM_OF_HS20_CMD_ID -+}; -+#endif -+ -+typedef struct _NL80211_DRIVER_TEST_MODE_PARAMS { -+ UINT_32 index; -+ UINT_32 buflen; -+} NL80211_DRIVER_TEST_MODE_PARAMS, *P_NL80211_DRIVER_TEST_MODE_PARAMS; -+ -+/*SW CMD */ -+typedef struct _NL80211_DRIVER_SW_CMD_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_8 set; -+ UINT_32 adr; -+ UINT_32 data; -+} NL80211_DRIVER_SW_CMD_PARAMS, *P_NL80211_DRIVER_SW_CMD_PARAMS; -+ -+typedef struct _NL80211_DRIVER_SUSPEND_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_8 suspend; -+} NL80211_DRIVER_SUSPEND_PARAMS, *P_NL80211_DRIVER_SUSPEND_PARAMS; -+struct iw_encode_exts { -+ __u32 ext_flags; /*!< IW_ENCODE_EXT_* */ -+ __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ -+ __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ -+ __u8 addr[MAC_ADDR_LEN]; /*!< ff:ff:ff:ff:ff:ff for broadcast/multicast -+ * (group) keys or unicast address for -+ * individual keys */ -+ __u16 alg; /*!< IW_ENCODE_ALG_* */ -+ __u16 key_len; -+ __u8 key[32]; -+}; -+ -+/*SET KEY EXT */ -+typedef struct _NL80211_DRIVER_SET_KEY_EXTS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_8 key_index; -+ UINT_8 key_len; -+ struct iw_encode_exts ext; -+} NL80211_DRIVER_SET_KEY_EXTS, *P_NL80211_DRIVER_SET_KEY_EXTS; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ -+struct param_hs20_set_bssid_pool { -+ u8 fgBssidPoolIsEnable; -+ u8 ucNumBssidPool; -+ u8 arBssidPool[8][ETH_ALEN]; -+}; -+ -+struct wpa_driver_hs20_data_s { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ enum Hs20CmdType CmdType; -+ struct param_hs20_set_bssid_pool hs20_set_bssid_pool; -+}; -+ -+#endif /* CFG_SUPPORT_HOTSPOT_2_0 */ -+ -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Macros of SPIN LOCK operations for using in Glue Layer */ -+/*----------------------------------------------------------------------------*/ -+#if CFG_USE_SPIN_LOCK_BOTTOM_HALF -+#define GLUE_SPIN_LOCK_DECLARATION() -+#define GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, rLockCategory) \ -+ { \ -+ if (rLockCategory < SPIN_LOCK_NUM) \ -+ spin_lock_bh(&(prGlueInfo->rSpinLock[rLockCategory])); \ -+ } -+#define GLUE_RELEASE_SPIN_LOCK(prGlueInfo, rLockCategory) \ -+ { \ -+ if (rLockCategory < SPIN_LOCK_NUM) \ -+ spin_unlock_bh(&(prGlueInfo->rSpinLock[rLockCategory])); \ -+ } -+#define GLUE_ACQUIRE_THE_SPIN_LOCK(prLock) \ -+ spin_lock_bh(prLock) -+#define GLUE_RELEASE_THE_SPIN_LOCK(prLock) \ -+ spin_unlock_bh(prLock) -+ -+#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+#define GLUE_SPIN_LOCK_DECLARATION() unsigned long __u4Flags = 0 -+#define GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, rLockCategory) \ -+ { \ -+ if (rLockCategory < SPIN_LOCK_NUM) \ -+ spin_lock_irqsave(&(prGlueInfo)->rSpinLock[rLockCategory], __u4Flags); \ -+ } -+#define GLUE_RELEASE_SPIN_LOCK(prGlueInfo, rLockCategory) \ -+ { \ -+ if (rLockCategory < SPIN_LOCK_NUM) \ -+ spin_unlock_irqrestore(&(prGlueInfo->rSpinLock[rLockCategory]), __u4Flags); \ -+ } -+#define GLUE_ACQUIRE_THE_SPIN_LOCK(prLock) \ -+ spin_lock_irqsave(prLock, __u4Flags) -+#define GLUE_RELEASE_THE_SPIN_LOCK(prLock) \ -+ spin_unlock_irqrestore(prLock, __u4Flags) -+#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros for accessing Reserved Fields of native packet */ -+/*----------------------------------------------------------------------------*/ -+#define GLUE_CB_OFFSET 4 /* For 64-bit platform, avoiding that the cb -+ isoverwrited by "(prQueueEntry)->prNext = -+ (P_QUE_ENTRY_T)NULL;" in QUEUE_INSERT_TAIL */ -+#define GLUE_GET_PKT_QUEUE_ENTRY(_p) \ -+ (&(((struct sk_buff *)(_p))->cb[0])) -+ -+#define GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry) \ -+ ((P_NATIVE_PACKET) ((ULONG)_prQueueEntry - offsetof(struct sk_buff, cb[0]))) -+ -+#define GLUE_SET_PKT_FLAG_802_11(_p) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(7)) -+ -+#define GLUE_SET_PKT_FLAG_1X(_p) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(6)) -+ -+#define GLUE_SET_PKT_FLAG_PAL(_p) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(5)) -+ -+#define GLUE_SET_PKT_FLAG_P2P(_p) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(4)) -+ -+#define GLUE_SET_PKT_TID(_p, _tid) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= (((UINT_8)((_tid) & (BITS(0, 3)))))) -+ -+#define GLUE_SET_PKT_FRAME_LEN(_p, _u2PayloadLen) \ -+ (*((PUINT_16)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+6])) = (UINT_16)(_u2PayloadLen)) -+ -+#define GLUE_GET_PKT_FRAME_LEN(_p) \ -+ (*((PUINT_16)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+6]))) -+ -+#define GLUE_GET_PKT_IS_802_11(_p) \ -+ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(7))) -+ -+#define GLUE_GET_PKT_IS_1X(_p) \ -+ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(6))) -+ -+#define GLUE_GET_PKT_TID(_p) \ -+ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BITS(0, 3))) -+ -+#define GLUE_GET_PKT_IS_PAL(_p) \ -+ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(5))) -+ -+#define GLUE_GET_PKT_IS_P2P(_p) \ -+ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(4))) -+ -+#define GLUE_SET_PKT_HEADER_LEN(_p, _ucMacHeaderLen) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+5])) = (UINT_8)(_ucMacHeaderLen)) -+ -+#define GLUE_GET_PKT_HEADER_LEN(_p) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+5]))) -+ -+#define GLUE_SET_PKT_ARRIVAL_TIME(_p, _rSysTime) \ -+ (*((POS_SYSTIME)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+8])) = (OS_SYSTIME)(_rSysTime)) -+ -+#define GLUE_GET_PKT_ARRIVAL_TIME(_p) \ -+ (*((POS_SYSTIME)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+8]))) -+ -+#define GLUE_SET_PKT_XTIME(_p, _rSysTime) \ -+ (*((UINT_64 *)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+16])) = (UINT_64)(_rSysTime)) -+ -+#define GLUE_GET_PKT_XTIME(_p) \ -+ (*((UINT_64 *)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+16]))) -+ -+/* Check validity of prDev, private data, and pointers */ -+#define GLUE_CHK_DEV(prDev) \ -+ ((prDev && *((P_GLUE_INFO_T *) netdev_priv(prDev))) ? TRUE : FALSE) -+ -+#define GLUE_CHK_PR2(prDev, pr2) \ -+ ((GLUE_CHK_DEV(prDev) && pr2) ? TRUE : FALSE) -+ -+#define GLUE_CHK_PR3(prDev, pr2, pr3) \ -+ ((GLUE_CHK_PR2(prDev, pr2) && pr3) ? TRUE : FALSE) -+ -+#define GLUE_CHK_PR4(prDev, pr2, pr3, pr4) \ -+ ((GLUE_CHK_PR3(prDev, pr2, pr3) && pr4) ? TRUE : FALSE) -+ -+#define GLUE_SET_EVENT(pr) \ -+ kalSetEvent(pr) -+ -+#define GLUE_INC_REF_CNT(_refCount) atomic_inc((atomic_t *)&(_refCount)) -+#define GLUE_DEC_REF_CNT(_refCount) atomic_dec((atomic_t *)&(_refCount)) -+ -+#define DbgPrint(...) -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+#ifdef WLAN_INCLUDE_PROC -+INT_32 procRemoveProcfs(VOID); -+ -+INT_32 procCreateFsEntry(P_GLUE_INFO_T prGlueInfo); -+INT_32 procInitFs(VOID); -+INT_32 procUninitProcFs(VOID); -+ -+#endif /* WLAN_INCLUDE_PROC */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+BOOLEAN glRegisterAmpc(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN glUnregisterAmpc(P_GLUE_INFO_T prGlueInfo); -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ -+VOID wlanSubModRunInit(P_GLUE_INFO_T prGlueInfo); -+ -+VOID wlanSubModRunExit(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN wlanSubModInit(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN wlanSubModExit(P_GLUE_INFO_T prGlueInfo); -+ -+VOID -+wlanSubModRegisterInitExit(SUB_MODULE_INIT rSubModInit, SUB_MODULE_EXIT rSubModExit, ENUM_SUB_MODULE_IDX_T eSubModIdx); -+ -+BOOLEAN wlanExportGlueInfo(P_GLUE_INFO_T *prGlueInfoExpAddr); -+ -+BOOLEAN wlanIsLaunched(VOID); -+ -+VOID wlanUpdateChannelTable(P_GLUE_INFO_T prGlueInfo); -+ -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _GL_OS_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h -new file mode 100644 -index 0000000000000..a27294e335003 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h -@@ -0,0 +1,743 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/os/linux/include/gl_p2p_ioctl.h#9 -+*/ -+ -+/*! \file gl_p2p_ioctl.h -+ \brief This file is for custom ioctls for Wi-Fi Direct only -+*/ -+ -+/* -+** Log: gl_p2p_ioctl.h -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Fix RX SD request under AP mode issue. -+ * -+ * 03 25 2011 wh.su -+ * NULL -+ * Fix P2P IOCTL of multicast address bug, add low power driver stop control. -+ * -+ * 11 22 2011 yuche.tsai -+ * NULL -+ * Update RSSI link quality of P2P Network query method. (Bug fix) -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Add RSSI support for P2P network. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service -+ * discovery version check. -+ * Add support for driver version query & p2p supplicant verseion set. -+ * For new service discovery mechanism sync. -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * . -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 08 16 2011 chinglan.wang -+ * NULL -+ * Add the group id information in the invitation indication. -+ * -+ * 08 09 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Invitation Feature add on. -+ * -+ * 05 04 2011 chinglan.wang -+ * [WCXRP00000698] [MT6620 Wi-Fi][P2P][Driver] Add p2p invitation command for the p2p driver -+ * . -+ * -+ * 03 29 2011 wh.su -+ * [WCXRP00000095] [MT6620 Wi-Fi] [FW] Refine the P2P GO send broadcast protected code -+ * add the set power and get power function sample. -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add Security check related code. -+ * -+ * 03 01 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * fixed the ioctl sumcmd to meet the p2p_supplicant setting. -+ * -+ * 02 23 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * adding the ioctl set int define for p2p parameter. -+ * -+ * 02 22 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * adding the ioctl set int from supplicant, and can used to set the p2p parameters -+ * -+ * 02 17 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * adjust the set wsc ie structure. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * ioctl implementations for P2P Service Discovery -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+ * 12 15 2010 cp.wu -+ * NULL -+ * invoke nicEnableInterrupt() before leaving from wlanAdapterStart() -+ * -+ * 12 07 2010 cp.wu -+ * [WCXRP00000237] [MT6620 Wi-Fi][Wi-Fi Direct][Driver] Add interface for supporting service discovery -+ * define a pair of i/o control for multiplexing layer -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 09 10 2010 george.huang -+ * NULL -+ * update iwpriv LP related -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * add netdev_ops(NDO) for linux kernel 2.6.31 or greater -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Refine a function parameter name. -+ * -+ * 08 19 2010 cp.wu -+ * NULL -+ * add set mac address interface for further possibilities of wpa_supplicant overriding interface address. -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * add wext handlers to link P2P set PS profile/ network address function (TBD) -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * revised implementation of Wi-Fi Direct io controls. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * follow-up with ioctl interface update for Wi-Fi Direct application -+ * -+ * 08 06 2010 cp.wu -+ * NULL -+ * driver hook modifications corresponding to ioctl interface change. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct] add framework for driver hooks -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 01 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl to configure scan mode for p2p connection -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add cfg80211 interface, which is to replace WE, for further extension -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement get scan result. -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement wireless extension ioctls in iw_handler form. -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * p2p ioctls revised. -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl for controlling p2p scan phase parameters -+ * -+*/ -+ -+#ifndef _GL_P2P_IOCTL_H -+#define _GL_P2P_IOCTL_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#include -+#include -+#endif -+ -+#include "wlan_oid.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Device private ioctl calls */ -+/* #define SIOCDEVPRIVATE 0x89F0*/ -+#define IOC_GET_PRIVATE_IOCTL_CMD (SIOCDEVPRIVATE+1) -+ -+/* (WirelessExtension) Private I/O Controls */ -+#define IOC_P2P_CFG_DEVICE (SIOCIWFIRSTPRIV+0) -+#define IOC_P2P_PROVISION_COMPLETE (SIOCIWFIRSTPRIV+2) -+#define IOC_P2P_START_STOP_DISCOVERY (SIOCIWFIRSTPRIV+4) -+#define IOC_P2P_DISCOVERY_RESULTS (SIOCIWFIRSTPRIV+5) -+#define IOC_P2P_WSC_BEACON_PROBE_RSP_IE (SIOCIWFIRSTPRIV+6) -+#define IOC_P2P_GO_WSC_IE IOC_P2P_WSC_BEACON_PROBE_RSP_IE -+#define IOC_P2P_CONNECT_DISCONNECT (SIOCIWFIRSTPRIV+8) -+#define IOC_P2P_PASSWORD_READY (SIOCIWFIRSTPRIV+10) -+/* #define IOC_P2P_SET_PWR_MGMT_PARAM (SIOCIWFIRSTPRIV+12) */ -+#define IOC_P2P_SET_INT (SIOCIWFIRSTPRIV+12) -+#define IOC_P2P_GET_STRUCT (SIOCIWFIRSTPRIV+13) -+#define IOC_P2P_SET_STRUCT (SIOCIWFIRSTPRIV+14) -+#define IOC_P2P_GET_REQ_DEVICE_INFO (SIOCIWFIRSTPRIV+15) -+ -+#define PRIV_CMD_INT_P2P_SET 0 -+ -+/* IOC_P2P_PROVISION_COMPLETE (iw_point . flags) */ -+#define P2P_PROVISIONING_SUCCESS 0 -+#define P2P_PROVISIONING_FAIL 1 -+ -+/* IOC_P2P_START_STOP_DISCOVERY (iw_point . flags) */ -+#define P2P_STOP_DISCOVERY 0 -+#define P2P_START_DISCOVERY 1 -+ -+/* IOC_P2P_CONNECT_DISCONNECT (iw_point . flags) */ -+#define P2P_CONNECT 0 -+#define P2P_DISCONNECT 1 -+ -+/* IOC_P2P_START_STOP_DISCOVERY (scan_type) */ -+#define P2P_SCAN_FULL_AND_FIND 0 -+#define P2P_SCAN_FULL 1 -+#define P2P_SCAN_SEARCH_AND_LISTEN 2 -+#define P2P_LISTEN 3 -+ -+/* IOC_P2P_GET_STRUCT/IOC_P2P_SET_STRUCT */ -+#define P2P_SEND_SD_RESPONSE 0 -+#define P2P_GET_SD_REQUEST 1 -+#define P2P_SEND_SD_REQUEST 2 -+#define P2P_GET_SD_RESPONSE 3 -+#define P2P_TERMINATE_SD_PHASE 4 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Wireless Extension: Private I/O Control */ -+/*----------------------------------------------------------------------------*/ -+typedef struct iw_p2p_cfg_device_type { -+ void __user *ssid; -+ UINT_8 ssid_len; -+ UINT_8 pri_device_type[8]; -+ UINT_8 snd_device_type[8]; -+ void __user *device_name; -+ UINT_8 device_name_len; -+ UINT_8 intend; -+ UINT_8 persistence; -+ UINT_8 sec_mode; -+ UINT_8 ch; -+ UINT_8 ch_width; /* 0: 20 Mhz 1:20/40 Mhz auto */ -+ UINT_8 max_scb; -+} IW_P2P_CFG_DEVICE_TYPE, *P_IW_P2P_CFG_DEVICE_TYPE; -+ -+typedef struct iw_p2p_hostapd_param { -+ UINT_8 cmd; -+ UINT_8 rsv[3]; -+ UINT_8 sta_addr[6]; -+ void __user *data; -+ UINT_16 len; -+} IW_P2P_HOSTAPD_PARAM, *P_IW_P2P_HOSTAPD_PARAM; -+ -+typedef struct iw_p2p_req_device_type { -+ UINT_8 scan_type; /* 0: Full scan + Find -+ * 1: Full scan -+ * 2: Scan (Search +Listen) -+ * 3: Listen -+ * other : reserved -+ */ -+ UINT_8 pri_device_type[8]; -+ void __user *probe_req_ie; -+ UINT_16 probe_req_len; -+ void __user *probe_rsp_ie; -+ UINT_16 probe_rsp_len; -+} IW_P2P_REQ_DEVICE_TYPE, *P_IW_P2P_REQ_DEVICE_TYPE; -+ -+typedef struct iw_p2p_connect_device { -+ UINT_8 sta_addr[6]; -+ UINT_8 p2pRole; /* 0: P2P Device, 1:GC, 2: GO */ -+ UINT_8 needProvision; /* 0: Don't needed provision, 1: doing the wsc provision first */ -+ UINT_8 authPeer; /* 1: auth peer invitation request */ -+ UINT_8 intend_config_method; /* Request Peer Device used config method */ -+} IW_P2P_CONNECT_DEVICE, *P_IW_P2P_CONNECT_DEVICE; -+ -+typedef struct iw_p2p_password_ready { -+ UINT_8 active_config_method; -+ void __user *probe_req_ie; -+ UINT_16 probe_req_len; -+ void __user *probe_rsp_ie; -+ UINT_16 probe_rsp_len; -+} IW_P2P_PASSWORD_READY, *P_IW_P2P_PASSWORD_READY; -+ -+typedef struct iw_p2p_device_req { -+ UINT_8 name[33]; -+ UINT_32 name_len; -+ UINT_8 device_addr[6]; -+ UINT_8 device_type; -+ INT_32 config_method; -+ INT_32 active_config_method; -+} IW_P2P_DEVICE_REQ, *P_IW_P2P_DEVICE_REQ; -+ -+typedef struct iw_p2p_transport_struct { -+ UINT_32 u4CmdId; -+ UINT_32 inBufferLength; -+ UINT_32 outBufferLength; -+ UINT_8 aucBuffer[16]; -+} IW_P2P_TRANSPORT_STRUCT, *P_IW_P2P_TRANSPORT_STRUCT; -+ -+/* For Invitation */ -+typedef struct iw_p2p_ioctl_invitation_struct { -+ UINT_8 aucDeviceID[6]; -+ UINT_8 aucGroupID[6]; /* BSSID */ -+ UINT_8 aucSsid[32]; -+ UINT_32 u4SsidLen; -+ UINT_8 ucReinvoke; -+} IW_P2P_IOCTL_INVITATION_STRUCT, *P_IW_P2P_IOCTL_INVITATION_STRUCT; -+ -+typedef struct iw_p2p_ioctl_abort_invitation { -+ UINT_8 dev_addr[6]; -+} IW_P2P_IOCTL_ABORT_INVITATION, *P_IW_P2P_IOCTL_ABORT_INVITATION; -+ -+typedef struct iw_p2p_ioctl_invitation_indicate { -+ UINT_8 dev_addr[6]; -+ UINT_8 group_bssid[6]; -+ INT_32 config_method; /* peer device supported config method */ -+ UINT_8 dev_name[32]; /* for reinvoke */ -+ UINT_32 name_len; -+ UINT_8 operating_channel; /* for re-invoke, target operating channel */ -+ UINT_8 invitation_type; /* invitation or re-invoke */ -+} IW_P2P_IOCTL_INVITATION_INDICATE, *P_IW_P2P_IOCTL_INVITATION_INDICATE; -+ -+typedef struct iw_p2p_ioctl_invitation_status { -+ UINT_32 status_code; -+} IW_P2P_IOCTL_INVITATION_STATUS, *P_IW_P2P_IOCTL_INVITATION_STATUS; -+ -+/* For Formation */ -+typedef struct iw_p2p_ioctl_start_formation { -+ UINT_8 dev_addr[6]; /* bssid */ -+ UINT_8 role; /* 0: P2P Device, 1:GC, 2: GO */ -+ UINT_8 needProvision; /* 0: Don't needed provision, 1: doing the wsc provision first */ -+ UINT_8 auth; /* 1: auth peer invitation request */ -+ UINT_8 config_method; /* Request Peer Device used config method */ -+} IW_P2P_IOCTL_START_FORMATION, *P_IW_P2P_IOCTL_START_FORMATION; -+ -+/* SET_STRUCT / GET_STRUCT */ -+typedef enum _ENUM_P2P_CMD_ID_T { -+ P2P_CMD_ID_SEND_SD_RESPONSE = 0, /* 0x00 (Set) */ -+ P2P_CMD_ID_GET_SD_REQUEST, /* 0x01 (Get) */ -+ P2P_CMD_ID_SEND_SD_REQUEST, /* 0x02 (Set) */ -+ P2P_CMD_ID_GET_SD_RESPONSE, /* 0x03 (Get) */ -+ P2P_CMD_ID_TERMINATE_SD_PHASE, /* 0x04 (Set) */ -+#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ -+ P2P_CMD_ID_SEC_CHECK, /* 0x05(Set) */ -+#endif -+ P2P_CMD_ID_INVITATION, /* 0x06 (Set) */ -+ P2P_CMD_ID_INVITATION_INDICATE, /* 0x07 (Get) */ -+ P2P_CMD_ID_INVITATION_STATUS, /* 0x08 (Get) */ -+ P2P_CMD_ID_INVITATION_ABORT, /* 0x09 (Set) */ -+ P2P_CMD_ID_START_FORMATION, /* 0x0A (Set) */ -+ P2P_CMD_ID_P2P_VERSION, /* 0x0B (Set/Get) */ -+ P2P_CMD_ID_GET_CH_LIST = 12, /* 0x0C (Get) */ -+ P2P_CMD_ID_GET_OP_CH = 14 /* 0x0E (Get) */ -+} ENUM_P2P_CMD_ID_T, *P_ENUM_P2P_CMD_ID_T; -+ -+/* Service Discovery */ -+typedef struct iw_p2p_cmd_send_sd_response { -+ PARAM_MAC_ADDRESS rReceiverAddr; -+ UINT_8 fgNeedTxDoneIndication; -+ UINT_8 ucSeqNum; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} IW_P2P_CMD_SEND_SD_RESPONSE, *P_IW_P2P_CMD_SEND_SD_RESPONSE; -+ -+typedef struct iw_p2p_cmd_get_sd_request { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} IW_P2P_CMD_GET_SD_REQUEST, *P_IW_P2P_CMD_GET_SD_REQUEST; -+ -+typedef struct iw_p2p_cmd_send_service_discovery_request { -+ PARAM_MAC_ADDRESS rReceiverAddr; -+ UINT_8 fgNeedTxDoneIndication; -+ UINT_8 ucSeqNum; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} IW_P2P_CMD_SEND_SD_REQUEST, *P_IW_P2P_CMD_SEND_SD_REQUEST; -+ -+typedef struct iw_p2p_cmd_get_sd_response { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} IW_P2P_CMD_GET_SD_RESPONSE, *P_IW_P2P_CMD_GET_SD_RESPONSE; -+ -+typedef struct iw_p2p_cmd_terminate_sd_phase { -+ PARAM_MAC_ADDRESS rPeerAddr; -+} IW_P2P_CMD_TERMINATE_SD_PHASE, *P_IW_P2P_CMD_TERMINATE_SD_PHASE; -+ -+typedef struct iw_p2p_version { -+ UINT_32 u4Version; -+} IW_P2P_VERSION, *P_IW_P2P_VERSION; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+extern struct ieee80211_supported_band mtk_band_2ghz; -+extern struct ieee80211_supported_band mtk_band_5ghz; -+extern UINT_32 mtk_cipher_suites[5]; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+int mtk_p2p_cfg80211_change_iface(struct wiphy *wiphy, -+ struct net_device *ndev, -+ enum nl80211_iftype type,/* u32 *flags,*/ struct vif_params *params); -+ -+int mtk_p2p_cfg80211_add_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params); -+ -+int mtk_p2p_cfg80211_get_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, -+ bool pairwise, -+ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *) -+); -+ -+int mtk_p2p_cfg80211_del_key(struct wiphy *wiphy, -+ struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr); -+ -+int -+mtk_p2p_cfg80211_set_default_key(struct wiphy *wiphy, -+ struct net_device *netdev, u8 key_index, bool unicast, bool multicast); -+ -+int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_info *sinfo); -+ -+int mtk_p2p_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed); -+ -+int mtk_p2p_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme); -+ -+int mtk_p2p_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code); -+ -+int mtk_p2p_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params); -+ -+int mtk_p2p_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev); -+ -+int mtk_p2p_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout); -+ -+int mtk_p2p_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params); -+ -+int mtk_p2p_cfg80211_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct ieee80211_channel *chan, unsigned int duration, u64 *cookie); -+ -+int mtk_p2p_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request); -+ -+int mtk_p2p_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); -+ -+int mtk_p2p_cfg80211_set_txpower(struct wiphy *wiphy, -+ struct wireless_dev *wdev, enum nl80211_tx_power_setting type, int mbm); -+ -+int mtk_p2p_cfg80211_get_txpower(struct wiphy *wiphy, struct wireless_dev *wdev, int *dbm); -+ -+int mtk_p2p_cfg80211_deauth(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_deauth_request *req); -+ -+int mtk_p2p_cfg80211_disassoc(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_disassoc_request *req); -+ -+int mtk_p2p_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings); -+ -+int mtk_p2p_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_beacon_data *info); -+ -+int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct cfg80211_mgmt_tx_params *params, -+ u64 *cookie); -+ -+int mtk_p2p_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev); -+ -+int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, struct station_del_parameters *params); -+//int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac); -+ -+int mtk_p2p_cfg80211_set_channel(struct wiphy *wiphy, struct cfg80211_chan_def *chandef); -+ -+void mtk_p2p_cfg80211_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, u16 frame_type, bool reg); -+ -+int -+mtk_p2p_cfg80211_set_bitrate_mask(IN struct wiphy *wiphy, -+ IN struct net_device *dev, -+ IN const u8 *peer, IN const struct cfg80211_bitrate_mask *mask); -+ -+#ifdef CONFIG_NL80211_TESTMODE -+int mtk_p2p_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len); -+int mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+int mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+ -+#if CFG_SUPPORT_WFD -+int mtk_p2p_cfg80211_testmode_wfd_update_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+#endif -+ -+int mtk_p2p_cfg80211_testmode_hotspot_block_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+#else -+#error "Please ENABLE kernel config (CONFIG_NL80211_TESTMODE) to support Wi-Fi Direct" -+#endif -+ -+#endif -+ -+/* I/O control handlers */ -+ -+int -+mtk_p2p_wext_get_priv(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_reconnect(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_auth(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_key(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_mlme_handler(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_powermode(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_get_powermode(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+/* Private Wireless I/O Controls takes use of iw_handler */ -+int -+mtk_p2p_wext_set_local_dev_info(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_provision_complete(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_start_stop_discovery(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_discovery_results(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_wsc_ie(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_connect_disconnect(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_password_ready(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_request_dev_info(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_invitation_indicate(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_invitation_status(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_pm_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_ps_profile(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_network_address(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_int(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+/* Private Wireless I/O Controls for IOC_SET_STRUCT/IOC_GET_STRUCT */ -+int -+mtk_p2p_wext_set_struct(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_get_struct(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+/* IOC_SET_STRUCT/IOC_GET_STRUCT: Service Discovery */ -+int -+mtk_p2p_wext_get_service_discovery_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_get_service_discovery_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_send_service_discovery_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_send_service_discovery_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_terminate_service_discovery_phase(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+int -+mtk_p2p_wext_set_sec_check_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_get_sec_check_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+#endif -+ -+int -+mtk_p2p_wext_set_noa_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_oppps_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_p2p_version(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_get_p2p_version(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+void mtk_p2p_wext_set_Multicastlist(IN P_GLUE_INFO_T prGlueInfo); -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+int -+mtk_p2p_wext_get_rssi(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+struct iw_statistics *mtk_p2p_wext_get_wireless_stats(struct net_device *prDev); -+ -+#endif -+ -+int -+mtk_p2p_wext_set_txpow(IN struct net_device *prDev, -+ IN struct iw_request_info *prIwrInfo, IN OUT union iwreq_data *prTxPow, IN char *pcExtra); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _GL_P2P_IOCTL_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h -new file mode 100644 -index 0000000000000..bf9d8871ef48a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h -@@ -0,0 +1,243 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/os/linux/include/gl_p2p_kal.h#2 -+*/ -+ -+/*! \file gl_p2p_kal.h -+ \brief Declaration of KAL functions for Wi-Fi Direct support -+ - kal*() which is provided by GLUE Layer. -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/* -+** Log: gl_p2p_kal.h -+** -+** 08 30 2012 chinglan.wang -+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only -+** . -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 08 15 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Add group BSSID in invitation request indication. -+ * The BSSID is used for APP to decide the configure method. -+ * -+ * 08 09 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Invitation Feature add on. -+ * -+ * 03 19 2011 terry.wu -+ * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver -+ * create V2.0 p2p driver release based on label "MT6620_WIFI_P2P_DRIVER_V2_0_2100_0319_2011" from main trunk. -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add Security check related code. -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+*/ -+ -+#ifndef _GL_P2P_KAL_H -+#define _GL_P2P_KAL_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "config.h" -+#include "gl_typedef.h" -+#include "gl_os.h" -+#include "wlan_lib.h" -+#include "wlan_oid.h" -+#include "wlan_p2p.h" -+#include "gl_kal.h" -+#include "gl_wext_priv.h" -+#include "nic/p2p.h" -+ -+#if DBG -+extern int allocatedMemSize; -+#endif -+ -+extern BOOLEAN -+wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT unsigned char **ppucDesiredIE); -+ -+#if CFG_SUPPORT_WPS -+extern BOOLEAN -+wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT unsigned char **ppucDesiredIE); -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+BOOLEAN kalP2pFuncGetChannelType(IN ENUM_CHNL_EXT_T rChnlSco, OUT enum nl80211_channel_type *channel_type); -+struct ieee80211_channel *kalP2pFuncGetChannelEntry(IN P_GL_P2P_INFO_T prP2pInfo, IN P_RF_CHANNEL_INFO_T prChannelInfo); -+ -+/* Service Discovery */ -+VOID kalP2PIndicateSDRequest(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum); -+ -+void kalP2PIndicateSDResponse(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum); -+ -+VOID kalP2PIndicateTXDone(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucSeqNum, IN UINT_8 ucStatus); -+ -+/*----------------------------------------------------------------------------*/ -+/* Wi-Fi Direct handling */ -+/*----------------------------------------------------------------------------*/ -+ENUM_PARAM_MEDIA_STATE_T kalP2PGetState(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID -+kalP2PSetState(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_PARAM_MEDIA_STATE_T eState, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucRole); -+ -+VOID -+kalP2PUpdateAssocInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest); -+ -+UINT_32 kalP2PGetFreqInKHz(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_8 kalP2PGetRole(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID -+kalP2PSetRole(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_8 ucResult, IN PUINT_8 pucSSID, IN UINT_8 ucSSIDLen, IN UINT_8 ucRole); -+ -+VOID kalP2PSetCipher(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Cipher); -+ -+BOOLEAN kalP2PGetCipher(IN P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN kalP2PGetTkipCipher(IN P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN kalP2PGetCcmpCipher(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalP2PSetWscMode(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucWscMode); -+ -+UINT_8 kalP2PGetWscMode(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_16 kalP2PCalWSC_IELen(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType); -+ -+VOID kalP2PGenWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer); -+ -+VOID kalP2PUpdateWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer, IN UINT_16 u2BufferLength); -+ -+BOOLEAN kalP2PIndicateFound(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalP2PIndicateConnReq(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucDevName, IN INT_32 u4NameLength, -+ IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucDevType, /* 0: P2P Device / 1: GC / 2: GO */ -+ IN INT_32 i4ConfigMethod, IN INT_32 i4ActiveConfigMethod); -+ -+VOID kalP2PInvitationStatus(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4InvStatus); -+ -+VOID -+kalP2PInvitationIndication(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_P2P_DEVICE_DESC_T prP2pDevDesc, -+ IN PUINT_8 pucSsid, -+ IN UINT_8 ucSsidLen, -+ IN UINT_8 ucOperatingChnl, IN UINT_8 ucInvitationType, IN PUINT_8 pucGroupBssid); -+ -+struct net_device *kalP2PGetDevHdlr(P_GLUE_INFO_T prGlueInfo); -+ -+VOID -+kalGetChnlList(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_BAND_T eSpecificBand, -+ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList); -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+VOID kalP2PIndicateSecCheckRsp(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucRsp, IN UINT_16 u2RspLen); -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+VOID -+kalP2PIndicateChannelReady(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8SeqNum, -+ IN UINT_32 u4ChannelNum, -+ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_32 u4Duration); -+ -+VOID kalP2PIndicateScanDone(IN P_GLUE_INFO_T prGlueInfo, IN BOOLEAN fgIsAbort); -+ -+VOID -+kalP2PIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBuf, -+ IN UINT_32 u4BufLen, IN P_RF_CHANNEL_INFO_T prChannelInfo, IN INT_32 i4SignalStrength); -+ -+VOID kalP2PIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb); -+ -+VOID -+kalP2PIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen); -+ -+VOID kalP2PIndicateChannelExpired(IN P_GLUE_INFO_T prGlueInfo, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo); -+ -+VOID -+kalP2PGCIndicateConnectionStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_P2P_CONNECTION_REQ_INFO_T prP2pConnInfo, -+ IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELen, IN UINT_16 u2StatusReason, -+ IN WLAN_STATUS eStatus); -+ -+VOID kalP2PGOStationUpdate(IN P_GLUE_INFO_T prGlueInfo, IN P_STA_RECORD_T prCliStaRec, IN BOOLEAN fgIsNew); -+ -+INT_32 kalP2PSetBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid, IN BOOLEAN fgIsblock); -+ -+BOOLEAN kalP2PCmpBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid); -+ -+VOID kalP2PSetMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4MaxClient); -+ -+BOOLEAN kalP2PMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4NumClient); -+ -+#endif /* _GL_P2P_KAL_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h -new file mode 100644 -index 0000000000000..e5026e7e6eec5 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h -@@ -0,0 +1,242 @@ -+/* -+** Id: -+//Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/os/linux/include/gl_p2p_os.h#28 -+*/ -+ -+/*! \file gl_p2p_os.h -+ \brief List the external reference to OS for p2p GLUE Layer. -+ -+ In this file we define the data structure - GLUE_INFO_T to store those objects -+ we acquired from OS - e.g. TIMER, SPINLOCK, NET DEVICE ... . And all the -+ external reference (header file, extern func() ..) to OS for GLUE Layer should -+ also list down here. -+*/ -+ -+#ifndef _GL_P2P_OS_H -+#define _GL_P2P_OS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#include -+#endif -+ -+#include "wlan_oid.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+struct _GL_P2P_INFO_T { -+ -+ /* Device handle */ -+ struct net_device *prDevHandler; -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ /* cfg80211 */ -+ struct wireless_dev *prWdev; -+ -+ struct cfg80211_scan_request *prScanRequest; -+ -+ UINT_64 u8Cookie; -+ -+ /* Generation for station list update. */ -+ INT_32 i4Generation; -+ -+ UINT_32 u4OsMgmtFrameFilter; -+ -+#endif -+ -+ /* Device statistics */ -+ struct net_device_stats rNetDevStats; -+ -+ /* glue layer variables */ -+ UINT_32 u4FreqInKHz; /* frequency */ -+ UINT_8 ucRole; /* 0: P2P Device, 1: Group Client, 2: Group Owner */ -+ UINT_8 ucIntent; /* range: 0-15 */ -+ UINT_8 ucScanMode; /* 0: Search & Listen, 1: Scan without probe response */ -+ -+ ENUM_PARAM_MEDIA_STATE_T eState; -+ UINT_32 u4PacketFilter; -+ PARAM_MAC_ADDRESS aucMCAddrList[MAX_NUM_GROUP_ADDR]; -+ -+ /* connection-requested peer information */ -+ UINT_8 aucConnReqDevName[32]; -+ INT_32 u4ConnReqNameLength; -+ PARAM_MAC_ADDRESS rConnReqPeerAddr; -+ PARAM_MAC_ADDRESS rConnReqGroupAddr; /* For invitation group. */ -+ UINT_8 ucConnReqDevType; -+ INT_32 i4ConnReqConfigMethod; -+ INT_32 i4ConnReqActiveConfigMethod; -+ -+ UINT_32 u4CipherPairwise; -+ UINT_8 ucWSCRunning; -+ -+ UINT_8 aucWSCIE[3][400]; /* 0 for beacon, 1 for probe req, 2 for probe response */ -+ UINT_16 u2WSCIELen[3]; -+ -+#if CFG_SUPPORT_WFD -+ UINT_8 aucVenderIE[1024]; /* Save the other IE for prove resp */ -+ UINT_16 u2VenderIELen; -+#endif -+ -+ UINT_8 ucOperatingChnl; -+ UINT_8 ucInvitationType; -+ -+ UINT_32 u4InvStatus; -+ -+ /* For SET_STRUCT/GET_STRUCT */ -+ UINT_8 aucOidBuf[4096]; -+ -+#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ -+ UINT_8 aucSecCheck[256]; -+ UINT_8 aucSecCheckRsp[256]; -+#endif -+ -+ /* Hotspot Client Management */ -+ PARAM_MAC_ADDRESS aucblackMACList[8]; -+ UINT_8 ucMaxClients; -+ -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ UINT_32 u4PsLevel; -+#endif -+}; -+ -+#ifdef CONFIG_NL80211_TESTMODE -+typedef struct _NL80211_DRIVER_TEST_PRE_PARAMS { -+ UINT_16 idx_mode; -+ UINT_16 idx; -+ UINT_32 value; -+} NL80211_DRIVER_TEST_PRE_PARAMS, *P_NL80211_DRIVER_TEST_PRE_PARAMS; -+ -+typedef struct _NL80211_DRIVER_TEST_PARAMS { -+ UINT_32 index; -+ UINT_32 buflen; -+} NL80211_DRIVER_TEST_PARAMS, *P_NL80211_DRIVER_TEST_PARAMS; -+ -+/* P2P Sigma*/ -+typedef struct _NL80211_DRIVER_P2P_SIGMA_PARAMS { -+ NL80211_DRIVER_TEST_PARAMS hdr; -+ UINT_32 idx; -+ UINT_32 value; -+} NL80211_DRIVER_P2P_SIGMA_PARAMS, *P_NL80211_DRIVER_P2P_SIGMA_PARAMS; -+ -+/* Hotspot Client Management */ -+typedef struct _NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS { -+ NL80211_DRIVER_TEST_PARAMS hdr; -+ UINT_8 ucblocked; -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+} NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS, *P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS; -+ -+#if CFG_SUPPORT_WFD -+typedef struct _NL80211_DRIVER_WFD_PARAMS { -+ NL80211_DRIVER_TEST_PARAMS hdr; -+ UINT_32 WfdCmdType; -+ UINT_8 WfdEnable; -+ UINT_8 WfdCoupleSinkStatus; -+ UINT_8 WfdSessionAvailable; -+ UINT_8 WfdSigmaMode; -+ UINT_16 WfdDevInfo; -+ UINT_16 WfdControlPort; -+ UINT_16 WfdMaximumTp; -+ UINT_16 WfdExtendCap; -+ UINT_8 WfdCoupleSinkAddress[MAC_ADDR_LEN]; -+ UINT_8 WfdAssociatedBssid[MAC_ADDR_LEN]; -+ UINT_8 WfdVideoIp[4]; -+ UINT_8 WfdAudioIp[4]; -+ UINT_16 WfdVideoPort; -+ UINT_16 WfdAudioPort; -+ UINT_32 WfdFlag; -+ UINT_32 WfdPolicy; -+ UINT_32 WfdState; -+ UINT_8 WfdSessionInformationIE[24 * 8]; /* Include Subelement ID, length */ -+ UINT_16 WfdSessionInformationIELen; -+ UINT_8 aucReserved1[2]; -+ UINT_8 aucWfdPrimarySinkMac[MAC_ADDR_LEN]; -+ UINT_8 aucWfdSecondarySinkMac[MAC_ADDR_LEN]; -+ UINT_32 WfdAdvanceFlag; -+ /* Group 1 64 bytes */ -+ UINT_8 aucWfdLocalIp[4]; -+ UINT_16 WfdLifetimeAc2; /* Unit is 2 TU */ -+ UINT_16 WfdLifetimeAc3; /* Unit is 2 TU */ -+ UINT_16 WfdCounterThreshold; /* Unit is ms */ -+ UINT_8 aucReserved2[54]; -+ /* Group 3 64 bytes */ -+ UINT_8 aucReserved3[64]; -+ /* Group 3 64 bytes */ -+ UINT_8 aucReserved4[64]; -+} NL80211_DRIVER_WFD_PARAMS, *P_NL80211_DRIVER_WFD_PARAMS; -+#endif -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+BOOLEAN p2pLaunch(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN p2pRemove(P_GLUE_INFO_T prGlueInfo); -+ -+VOID p2pSetMode(IN BOOLEAN fgIsAPMOde); -+ -+BOOLEAN glRegisterP2P(P_GLUE_INFO_T prGlueInfo, const char *prDevName, BOOLEAN fgIsApMode); -+ -+VOID p2pEalySuspendReg(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsEnable); -+ -+BOOLEAN glUnregisterP2P(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN p2pNetRegister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired); -+ -+BOOLEAN p2pNetUnregister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired); -+ -+BOOLEAN p2pStopImmediate(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN p2PFreeInfo(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN glP2pCreateWirelessDevice(P_GLUE_INFO_T prGlueInfo); -+ -+VOID glP2pDestroyWirelessDevice(VOID); -+ -+VOID p2pSetMulticastListWorkQueueWrapper(P_GLUE_INFO_T prGlueInfo); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h -new file mode 100644 -index 0000000000000..f24ceee9e921a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h -@@ -0,0 +1,133 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_rst.h#1 -+*/ -+ -+/*! \file gl_rst.h -+ \brief Declaration of functions and finite state machine for -+ MT6620 Whole-Chip Reset Mechanism -+*/ -+ -+#ifndef _GL_RST_H -+#define _GL_RST_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_typedef.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#if 1 -+typedef INT_32(*wmt_wlan_probe_cb) (VOID); -+typedef INT_32(*wmt_wlan_remove_cb) (VOID); -+typedef INT_32(*wmt_wlan_bus_cnt_get_cb) (VOID); -+typedef INT_32(*wmt_wlan_bus_cnt_clr_cb) (VOID); -+ -+typedef struct _MTK_WCN_WMT_WLAN_CB_INFO { -+ wmt_wlan_probe_cb wlan_probe_cb; -+ wmt_wlan_remove_cb wlan_remove_cb; -+ wmt_wlan_bus_cnt_get_cb wlan_bus_cnt_get_cb; -+ wmt_wlan_bus_cnt_clr_cb wlan_bus_cnt_clr_cb; -+} MTK_WCN_WMT_WLAN_CB_INFO, *P_MTK_WCN_WMT_WLAN_CB_INFO; -+ -+extern INT_32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo); -+extern INT_32 mtk_wcn_wmt_wlan_unreg(VOID); -+#endif -+ -+typedef enum _ENUM_RESET_STATUS_T { -+ RESET_FAIL, -+ RESET_SUCCESS -+} ENUM_RESET_STATUS_T; -+ -+typedef struct _RESET_STRUCT_T { -+ ENUM_RESET_STATUS_T rst_data; -+ struct work_struct rst_work; -+} RESET_STRUCT_T; -+ -+typedef enum _ENUM_WMTRSTMSG_TYPE_T { -+ WMTRSTMSG_RESET_START = 0x0, -+ WMTRSTMSG_RESET_END = 0x1, -+ WMTRSTMSG_RESET_END_FAIL = 0x2, -+ WMTRSTMSG_RESET_MAX, -+ WMTRSTMSG_RESET_INVALID = 0xff -+} ENUM_WMTRSTMSG_TYPE_T, *P_ENUM_WMTRSTMSG_TYPE_T; -+ -+typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T, /* Source driver type */ -+ ENUM_WMTDRV_TYPE_T, /* Destination driver type */ -+ ENUM_WMTMSG_TYPE_T, /* Message type */ -+ void *, /* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client -+ can't touch this buffer after this function return. */ -+ unsigned int /* Buffer size in unit of byte */ -+); -+ -+/******************************************************************************* -+* E X T E R N A L F U N C T I O N S -+******************************************************************************** -+*/ -+#define glDoChipReset() \ -+ do { \ -+ if (!kalStrnCmp(current->comm, "mtk_wmtd", 8)) { \ -+ g_IsNeedDoChipReset = 1; \ -+ DBGLOG(INIT, ERROR, "forbid core dump in mtk_wmtd %s line %d\n", __func__, __LINE__); \ -+ break; \ -+ } \ -+ DBGLOG(INIT, ERROR, "Do core dump and chip reset in %s line %d\n", __func__, __LINE__); \ -+ mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 0x40); \ -+ } while (0) -+ -+#if CFG_CHIP_RESET_SUPPORT -+extern int mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); -+extern int mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); -+extern int wifi_reset_start(void); -+extern int wifi_reset_end(ENUM_RESET_STATUS_T); -+#endif -+extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); -+extern BOOLEAN mtk_wcn_set_connsys_power_off_flag(BOOLEAN value); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern UINT_32 g_IsNeedDoChipReset; -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+VOID glResetInit(VOID); -+ -+VOID glResetUninit(VOID); -+ -+VOID glSendResetRequest(VOID); -+ -+BOOLEAN kalIsResetting(VOID); -+ -+#endif /* _GL_RST_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h -new file mode 100644 -index 0000000000000..3cc57780f2010 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h -@@ -0,0 +1,21 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_sec.h#1 -+*/ -+ -+/*! \file p2p_fsm.h -+ \brief Declaration of functions and finite state machine for P2P Module. -+ -+ Declaration of functions and finite state machine for P2P Module. -+*/ -+ -+#ifndef _GL_SEC_H -+#define _GL_SEC_H -+ -+extern void handle_sec_msg_1(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+extern void handle_sec_msg_2(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+extern void handle_sec_msg_3(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+extern void handle_sec_msg_4(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+extern void handle_sec_msg_5(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+extern void handle_sec_msg_final(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+ -+#endif /* _GL_SEC_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h -new file mode 100644 -index 0000000000000..e9aa3e849eb2e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h -@@ -0,0 +1,298 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_typedef.h#1 -+*/ -+ -+/*! \file gl_typedef.h -+ \brief Definition of basic data type(os dependent). -+ -+ In this file we define the basic data type. -+*/ -+ -+/* -+** Log: gl_typedef.h -+ * -+ * 06 22 2012 cp.wu -+ * [WCXRP00001257] [MT6620][MT5931][MT6628][Driver][Linux] Modify KAL_HZ to align ms accuracy -+ * modify KAL_HZ to (1000) for correct definition. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 02 15 2011 jeffrey.chang -+ * NULL -+ * to support early suspend in android -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\6 2009-08-18 22:57:14 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\5 2008-09-22 23:19:30 GMT mtk01461 -+** Update comment for code review -+** \main\maintrunk.MT5921\4 2008-09-05 17:25:16 GMT mtk01461 -+** Update Driver for Code Review -+** \main\maintrunk.MT5921\3 2007-11-09 11:00:50 GMT mtk01425 -+** 1. Use macro to unify network-to-host and host-to-network related functions -+** Revision 1.3 2007/06/27 02:18:51 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+** Revision 1.2 2007/06/25 06:16:24 MTK01461 -+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API -+** -+*/ -+ -+#ifndef _GL_TYPEDEF_H -+#define _GL_TYPEDEF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Define HZ of timer tick for function kalGetTimeTick() */ -+#define KAL_HZ (1000) -+ -+/* Miscellaneous Equates */ -+#ifndef FALSE -+#define FALSE ((BOOLEAN) 0) -+#define TRUE ((BOOLEAN) 1) -+#endif /* FALSE */ -+ -+#ifndef NULL -+#if defined(__cplusplus) -+#define NULL 0 -+#else -+#define NULL ((void *) 0) -+#endif -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Type definition for void */ -+/*mach/mt_typedefs.h define _TYPEDEFS_H, to avoid compile error*/ -+#ifndef _TYPEDEFS_H -+typedef void VOID; -+#endif -+typedef void *PVOID, **PPVOID; -+ -+/* Type definition for Boolean */ -+typedef unsigned char BOOLEAN, *PBOOLEAN; -+ -+/* Type definition for signed integers */ -+typedef signed char CHAR, *PCHAR, **PPCHAR; -+typedef signed char INT_8, *PINT_8, **PPINT_8; -+typedef signed short INT_16, *PINT_16, **PPINT_16; -+typedef signed int INT_32, *PINT_32, **PPINT_32; -+typedef long LONG, *PLONG, **PPLONG; -+typedef signed long long INT_64, *PINT_64, **PPINT_64; -+ -+/* Type definition for unsigned integers */ -+typedef unsigned char UCHAR, *PUCHAR, **PPUCHAR; -+typedef unsigned char UINT_8, *PUINT_8, **PPUINT_8, *P_UINT_8; -+typedef unsigned short UINT_16, *PUINT_16, **PPUINT_16; -+typedef unsigned int UINT32, *PUINT32; -+typedef unsigned int UINT_32, *PUINT_32, **PPUINT_32; -+typedef unsigned long ULONG, *PULONG, **PPULONG; -+typedef unsigned long long UINT_64, *PUINT_64, **PPUINT_64; -+ -+typedef unsigned int OS_SYSTIME, *POS_SYSTIME, **PPOS_SYSTIME; -+ -+#ifndef _TYPEDEFS_H -+typedef signed char INT8, *PINT8; -+typedef signed short INT16, *PINT16; -+typedef signed int INT32, *PINT32; -+typedef unsigned char UINT8, *PUINT8; -+typedef unsigned short UINT16, *PUINT16; -+typedef unsigned int UINT32, *PUINT32; -+#endif -+ -+/* Type definition of large integer (64bits) union to be comptaible with -+ * Windows definition, so we won't apply our own coding style to these data types. -+ * NOTE: LARGE_INTEGER must NOT be floating variable. -+ * : Check for big-endian compatibility. -+ */ -+typedef union _LARGE_INTEGER { -+ struct { -+ UINT_32 LowPart; -+ INT_32 HighPart; -+ } u; -+ INT_64 QuadPart; -+} LARGE_INTEGER, *PLARGE_INTEGER; -+ -+typedef union _ULARGE_INTEGER { -+ struct { -+ UINT_32 LowPart; -+ UINT_32 HighPart; -+ } u; -+ UINT_64 QuadPart; -+} ULARGE_INTEGER, *PULARGE_INTEGER; -+ -+typedef INT_32(*probe_card) (PVOID pvData); -+typedef VOID(*remove_card) (VOID); -+ -+/* duplicated from wmt_exp.h for better driver isolation */ -+typedef enum _ENUM_WMTDRV_TYPE_T { -+ WMTDRV_TYPE_BT = 0, -+ WMTDRV_TYPE_FM = 1, -+ WMTDRV_TYPE_GPS = 2, -+ WMTDRV_TYPE_WIFI = 3, -+ WMTDRV_TYPE_WMT = 4, -+ WMTDRV_TYPE_STP = 5, -+ WMTDRV_TYPE_SDIO1 = 6, -+ WMTDRV_TYPE_SDIO2 = 7, -+ WMTDRV_TYPE_LPBK = 8, -+ WMTDRV_TYPE_MAX -+} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T; -+ -+typedef enum _ENUM_WMTMSG_TYPE_T { -+ WMTMSG_TYPE_POWER_ON = 0, -+ WMTMSG_TYPE_POWER_OFF = 1, -+ WMTMSG_TYPE_RESET = 2, -+ WMTMSG_TYPE_STP_RDY = 3, -+ WMTMSG_TYPE_HW_FUNC_ON = 4, -+ WMTMSG_TYPE_MAX -+} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T; -+ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define IN /* volatile */ -+#define OUT /* volatile */ -+ -+#define __KAL_ATTRIB_PACKED__ __attribute__((__packed__)) -+#define __KAL_ATTRIB_ALIGN_4__ __aligned(4) -+ -+#ifndef BIT -+#define BIT(n) ((UINT_32) 1U << (n)) -+#endif /* BIT */ -+ -+#ifndef BITS -+/* bits range: for example BITS(16,23) = 0xFF0000 -+ * ==> (BIT(m)-1) = 0x0000FFFF ~(BIT(m)-1) => 0xFFFF0000 -+ * ==> (BIT(n+1)-1) = 0x00FFFFFF -+ */ -+#define BITS(m, n) (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n))) -+#endif /* BIT */ -+ -+/* This macro returns the byte offset of a named field in a known structure -+ type. -+ _type - structure name, -+ _field - field name of the structure */ -+#ifndef OFFSET_OF -+#define OFFSET_OF(_type, _field) ((ULONG)&(((_type *)0)->_field)) -+#endif /* OFFSET_OF */ -+ -+/* This macro returns the base address of an instance of a structure -+ * given the type of the structure and the address of a field within the -+ * containing structure. -+ * _addrOfField - address of current field of the structure, -+ * _type - structure name, -+ * _field - field name of the structure -+ */ -+#ifndef ENTRY_OF -+#define ENTRY_OF(_addrOfField, _type, _field) \ -+ ((_type *)((PINT_8)(_addrOfField) - (PINT_8)OFFSET_OF(_type, _field))) -+#endif /* ENTRY_OF */ -+ -+/* This macro align the input value to the DW boundary. -+ * _value - value need to check -+ */ -+#ifndef ALIGN_4 -+#define ALIGN_4(_value) (((_value) + 3) & ~3u) -+#endif /* ALIGN_4 */ -+ -+/* This macro check the DW alignment of the input value. -+ * _value - value of address need to check -+ */ -+#ifndef IS_ALIGN_4 -+#define IS_ALIGN_4(_value) (((_value) & 0x3) ? FALSE : TRUE) -+#endif /* IS_ALIGN_4 */ -+ -+#ifndef IS_NOT_ALIGN_4 -+#define IS_NOT_ALIGN_4(_value) (((_value) & 0x3) ? TRUE : FALSE) -+#endif /* IS_NOT_ALIGN_4 */ -+ -+/* This macro evaluate the input length in unit of Double Word(4 Bytes). -+ * _value - value in unit of Byte, output will round up to DW boundary. -+ */ -+#ifndef BYTE_TO_DWORD -+#define BYTE_TO_DWORD(_value) ((_value + 3) >> 2) -+#endif /* BYTE_TO_DWORD */ -+ -+/* This macro evaluate the input length in unit of Byte. -+ * _value - value in unit of DW, output is in unit of Byte. -+ */ -+#ifndef DWORD_TO_BYTE -+#define DWORD_TO_BYTE(_value) ((_value) << 2) -+#endif /* DWORD_TO_BYTE */ -+ -+#if 1 /* Little-Endian */ -+#define CONST_NTOHS(_x) ntohs(_x) -+ -+#define CONST_HTONS(_x) htons(_x) -+ -+#define NTOHS(_x) ntohs(_x) -+ -+#define HTONS(_x) htons(_x) -+ -+#define NTOHL(_x) ntohl(_x) -+ -+#define HTONL(_x) htonl(_x) -+ -+#else /* Big-Endian */ -+ -+#define CONST_NTOHS(_x) -+ -+#define CONST_HTONS(_x) -+ -+#define NTOHS(_x) -+ -+#define HTONS(_x) -+ -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _GL_TYPEDEF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h -new file mode 100644 -index 0000000000000..d8d5b0fb67402 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h -@@ -0,0 +1,619 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_vendor.h#1 -+*/ -+ -+/*! \file gl_vendor.h -+ \brief This file is for Portable Driver linux gl_vendor support. -+*/ -+ -+/* -+** Log: gl_vendor.h -+** -+** 10 14 2014 -+** add vendor declaration -+** -+ * -+*/ -+ -+#ifndef _GL_VENDOR_H -+#define _GL_VENDOR_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "gl_os.h" -+ -+#include "wlan_lib.h" -+#include "gl_wext.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define GOOGLE_OUI 0x001A11 -+ -+typedef enum { -+ /* Don't use 0 as a valid subcommand */ -+ ANDROID_NL80211_SUBCMD_UNSPECIFIED, -+ -+ /* Define all vendor startup commands between 0x0 and 0x0FFF */ -+ ANDROID_NL80211_SUBCMD_WIFI_RANGE_START = 0x0001, -+ ANDROID_NL80211_SUBCMD_WIFI_RANGE_END = 0x0FFF, -+ -+ /* Define all GScan related commands between 0x1000 and 0x10FF */ -+ ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000, -+ ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF, -+ -+ /* Define all RTT related commands between 0x1100 and 0x11FF */ -+ ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100, -+ ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF, -+ -+ ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200, -+ ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF, -+ -+ /* Define all Logger related commands between 0x1400 and 0x14FF */ -+ ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400, -+ ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END = 0x14FF, -+ -+ /* Define all wifi offload related commands between 0x1600 and 0x16FF */ -+ ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600, -+ ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x16FF, -+ -+ /* This is reserved for future usage */ -+ -+} ANDROID_VENDOR_SUB_COMMAND; -+ -+typedef enum { -+ WIFI_SUBCMD_GET_CHANNEL_LIST = ANDROID_NL80211_SUBCMD_WIFI_RANGE_START, -+ -+ WIFI_SUBCMD_GET_FEATURE_SET, /* 0x0001 */ -+ WIFI_SUBCMD_GET_FEATURE_SET_MATRIX, /* 0x0002 */ -+ WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, /* 0x0003 */ -+ WIFI_SUBCMD_NODFS_SET, /* 0x0004 */ -+ WIFI_SUBCMD_SET_COUNTRY_CODE, /* 0x0005 */ -+ /* Add more sub commands here */ -+ -+} WIFI_SUB_COMMAND; -+ -+typedef enum { -+ GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START, -+ -+ GSCAN_SUBCMD_SET_CONFIG, /* 0x1001 */ -+ GSCAN_SUBCMD_SET_SCAN_CONFIG, /* 0x1002 */ -+ GSCAN_SUBCMD_ENABLE_GSCAN, /* 0x1003 */ -+ GSCAN_SUBCMD_GET_SCAN_RESULTS, /* 0x1004 */ -+ GSCAN_SUBCMD_SCAN_RESULTS, /* 0x1005 */ -+ -+ GSCAN_SUBCMD_SET_HOTLIST, /* 0x1006 */ -+ -+ GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG, /* 0x1007 */ -+ GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, /* 0x1008 */ -+ /* Add more sub commands here */ -+ -+} GSCAN_SUB_COMMAND; -+ -+typedef enum { -+ RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START, -+ RTT_SUBCMD_CANCEL_CONFIG, -+ RTT_SUBCMD_GETCAPABILITY, -+} RTT_SUB_COMMAND; -+ -+typedef enum { -+ LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START, -+} LSTATS_SUB_COMMAND; -+ -+typedef enum { -+ GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, -+ GSCAN_EVENT_HOTLIST_RESULTS_FOUND, -+ GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, -+ GSCAN_EVENT_FULL_SCAN_RESULTS, -+ RTT_EVENT_COMPLETE, -+ GSCAN_EVENT_COMPLETE_SCAN, -+ GSCAN_EVENT_HOTLIST_RESULTS_LOST -+} WIFI_VENDOR_EVENT; -+ -+typedef enum { -+ WIFI_ATTRIBUTE_BAND, -+ WIFI_ATTRIBUTE_NUM_CHANNELS, -+ WIFI_ATTRIBUTE_CHANNEL_LIST, -+ -+ WIFI_ATTRIBUTE_NUM_FEATURE_SET, -+ WIFI_ATTRIBUTE_FEATURE_SET, -+ WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, -+ WIFI_ATTRIBUTE_NODFS_VALUE, -+ WIFI_ATTRIBUTE_COUNTRY_CODE -+ -+} WIFI_ATTRIBUTE; -+ -+typedef enum { -+ GSCAN_ATTRIBUTE_CAPABILITIES = 1, -+ -+ GSCAN_ATTRIBUTE_NUM_BUCKETS = 10, -+ GSCAN_ATTRIBUTE_BASE_PERIOD, -+ GSCAN_ATTRIBUTE_BUCKETS_BAND, -+ GSCAN_ATTRIBUTE_BUCKET_ID, -+ GSCAN_ATTRIBUTE_BUCKET_PERIOD, -+ GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS, -+ GSCAN_ATTRIBUTE_BUCKET_CHANNELS, -+ GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN, -+ GSCAN_ATTRIBUTE_REPORT_THRESHOLD, -+ GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, -+ -+ GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20, -+ GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, /* indicates no more results */ -+ GSCAN_ATTRIBUTE_FLUSH_FEATURE, /* Flush all the configs */ -+ GSCAN_ENABLE_FULL_SCAN_RESULTS, -+ GSCAN_ATTRIBUTE_REPORT_EVENTS, -+ -+ GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30, -+ GSCAN_ATTRIBUTE_FLUSH_RESULTS, -+ GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */ -+ GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */ -+ GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */ -+ GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event */ -+ -+ GSCAN_ATTRIBUTE_SSID = 40, -+ GSCAN_ATTRIBUTE_BSSID, -+ GSCAN_ATTRIBUTE_CHANNEL, -+ GSCAN_ATTRIBUTE_RSSI, -+ GSCAN_ATTRIBUTE_TIMESTAMP, -+ GSCAN_ATTRIBUTE_RTT, -+ GSCAN_ATTRIBUTE_RTTSD, -+ -+ GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50, -+ GSCAN_ATTRIBUTE_RSSI_LOW, -+ GSCAN_ATTRIBUTE_RSSI_HIGH, -+ GSCAN_ATTRIBUTE_HOTLIST_ELEM, -+ GSCAN_ATTRIBUTE_HOTLIST_FLUSH, -+ -+ GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60, -+ GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, -+ GSCAN_ATTRIBUTE_MIN_BREACHING, -+ GSCAN_ATTRIBUTE_NUM_AP, -+ GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS, -+ GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH -+ -+} GSCAN_ATTRIBUTE; -+ -+typedef enum { -+ RTT_ATTRIBUTE_CAPABILITIES = 1, -+ -+ RTT_ATTRIBUTE_TARGET_CNT = 10, -+ RTT_ATTRIBUTE_TARGET_INFO, -+ RTT_ATTRIBUTE_TARGET_MAC, -+ RTT_ATTRIBUTE_TARGET_TYPE, -+ RTT_ATTRIBUTE_TARGET_PEER, -+ RTT_ATTRIBUTE_TARGET_CHAN, -+ RTT_ATTRIBUTE_TARGET_PERIOD, -+ RTT_ATTRIBUTE_TARGET_NUM_BURST, -+ RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST, -+ RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM, -+ RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR, -+ RTT_ATTRIBUTE_TARGET_LCI, -+ RTT_ATTRIBUTE_TARGET_LCR, -+ RTT_ATTRIBUTE_TARGET_BURST_DURATION, -+ RTT_ATTRIBUTE_TARGET_PREAMBLE, -+ RTT_ATTRIBUTE_TARGET_BW, -+ RTT_ATTRIBUTE_RESULTS_COMPLETE = 30, -+ RTT_ATTRIBUTE_RESULTS_PER_TARGET, -+ RTT_ATTRIBUTE_RESULT_CNT, -+ RTT_ATTRIBUTE_RESULT -+} RTT_ATTRIBUTE; -+ -+typedef enum { -+ LSTATS_ATTRIBUTE_STATS = 2, -+} LSTATS_ATTRIBUTE; -+ -+typedef enum { -+ WIFI_BAND_UNSPECIFIED, -+ WIFI_BAND_BG = 1, /* 2.4 GHz */ -+ WIFI_BAND_A = 2, /* 5 GHz without DFS */ -+ WIFI_BAND_A_DFS = 4, /* 5 GHz DFS only */ -+ WIFI_BAND_A_WITH_DFS = 6, /* 5 GHz with DFS */ -+ WIFI_BAND_ABG = 3, /* 2.4 GHz + 5 GHz; no DFS */ -+ WIFI_BAND_ABG_WITH_DFS = 7, /* 2.4 GHz + 5 GHz with DFS */ -+} WIFI_BAND; -+ -+typedef enum { -+ WIFI_SCAN_BUFFER_FULL, -+ WIFI_SCAN_COMPLETE, -+} WIFI_SCAN_EVENT; -+ -+#define GSCAN_MAX_REPORT_THRESHOLD 1024000 -+#define GSCAN_MAX_CHANNELS 8 -+#define GSCAN_MAX_BUCKETS 8 -+#define MAX_HOTLIST_APS 16 -+#define MAX_SIGNIFICANT_CHANGE_APS 16 -+#define PSCAN_MAX_SCAN_CACHE_SIZE 16 -+#define PSCAN_MAX_AP_CACHE_PER_SCAN 16 -+#define PSCAN_VERSION 1 -+ -+#define MAX_BUFFERED_GSCN_RESULTS 5 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef UINT_64 wifi_timestamp; /* In microseconds (us) */ -+typedef UINT_64 wifi_timespan; /* In nanoseconds (ns) */ -+ -+typedef UINT_8 mac_addr[6]; -+typedef UINT_32 wifi_channel; /* Indicates channel frequency in MHz */ -+typedef INT_32 wifi_rssi; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+typedef struct _PARAM_WIFI_GSCAN_GET_RESULT_PARAMS { -+ UINT_32 get_num; -+ UINT_8 flush; -+} PARAM_WIFI_GSCAN_GET_RESULT_PARAMS, *P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS; -+ -+typedef struct _PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS { -+ UINT_8 ucPscanAct; -+ UINT_8 aucReserved[3]; -+} PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS, *P_PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS; -+ -+typedef struct _PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T { -+ UINT_32 max_scan_cache_size; /* total space allocated for scan (in bytes) */ -+ UINT_32 max_scan_buckets; /* maximum number of channel buckets */ -+ UINT_32 max_ap_cache_per_scan; /* maximum number of APs that can be stored per scan */ -+ UINT_32 max_rssi_sample_size; /* number of RSSI samples used for averaging RSSI */ -+ UINT_32 max_scan_reporting_threshold; /* max possible report_threshold as described */ -+ /* in wifi_scan_cmd_params */ -+ UINT_32 max_hotlist_aps; /* maximum number of entries for hotlist APs */ -+ UINT_32 max_significant_wifi_change_aps; /* maximum number of entries for */ -+ /* significant wifi change APs */ -+ UINT_32 max_bssid_history_entries; /* number of BSSID/RSSI entries that device can hold */ -+} PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T, *P_PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T; -+ -+typedef struct _PARAM_WIFI_GSCAN_CHANNEL_SPEC { -+ UINT_32 channel; /* frequency */ -+ UINT_32 dwellTimeMs; /* dwell time hint */ -+ UINT_32 passive; /* 0 => active, 1 => passive scan; ignored for DFS */ -+ /* Add channel class */ -+} PARAM_WIFI_GSCAN_CHANNEL_SPEC, *P_PARAM_WIFI_GSCAN_CHANNEL_SPEC; -+ -+typedef struct _PARAM_WIFI_GSCAN_BUCKET_SPEC { -+ UINT_32 bucket; /* bucket index, 0 based */ -+ WIFI_BAND band; /* when UNSPECIFIED, use channel list */ -+ UINT_32 period; /* desired period, in millisecond; if this is too */ -+ /* low, the firmware should choose to generate results as */ -+ /* fast as it can instead of failing the command */ -+ /* report_events semantics - -+ * 0 => report only when scan history is % full -+ * 1 => same as 0 + report a scan completion event after scanning this bucket -+ * 2 => same as 1 + forward scan results (beacons/probe responses + IEs) in real time to HAL -+ * 3 => same as 2 + forward scan results (beacons/probe responses + IEs) in real time to -+ supplicant as well (optional) . */ -+ UINT_8 report_events; -+ -+ UINT_32 num_channels; -+ PARAM_WIFI_GSCAN_CHANNEL_SPEC channels[GSCAN_MAX_CHANNELS]; /* channels to scan; -+ these may include DFS channels */ -+} PARAM_WIFI_GSCAN_BUCKET_SPEC, *P_PARAM_WIFI_GSCAN_BUCKET_SPEC; -+ -+typedef struct _PARAM_WIFI_GSCAN_CMD_PARAMS { -+ UINT_32 base_period; /* base timer period in ms */ -+ UINT_32 max_ap_per_scan; /* number of APs to store in each scan in the */ -+ /* BSSID/RSSI history buffer (keep the highest RSSI APs) */ -+ UINT_32 report_threshold; /* in %, when scan buffer is this much full, wake up AP */ -+ UINT_32 num_scans; -+ UINT_32 num_buckets; -+ PARAM_WIFI_GSCAN_BUCKET_SPEC buckets[GSCAN_MAX_BUCKETS]; -+} PARAM_WIFI_GSCAN_CMD_PARAMS, *P_PARAM_WIFI_GSCAN_CMD_PARAMS; -+ -+typedef struct _PARAM_WIFI_GSCAN_RESULT { -+ wifi_timestamp ts; /* time since boot (in microsecond) when the result was */ -+ /* retrieved */ -+ UINT_8 ssid[32 + 1]; /* null terminated */ -+ mac_addr bssid; -+ wifi_channel channel; /* channel frequency in MHz */ -+ wifi_rssi rssi; /* in db */ -+ wifi_timespan rtt; /* in nanoseconds */ -+ wifi_timespan rtt_sd; /* standard deviation in rtt */ -+ UINT_16 beacon_period; /* period advertised in the beacon */ -+ UINT_16 capability; /* capabilities advertised in the beacon */ -+ UINT_32 ie_length; /* size of the ie_data blob */ -+ UINT_8 ie_data[1]; /* blob of all the information elements found in the */ -+ /* beacon; this data should be a packed list of */ -+ /* wifi_information_element objects, one after the other. */ -+ /* other fields */ -+} PARAM_WIFI_GSCAN_RESULT, *P_PARAM_WIFI_GSCAN_RESULT; -+ -+/* Significant wifi change*/ -+/*typedef struct _PARAM_WIFI_CHANGE_RESULT{ -+ mac_addr bssid; // BSSID -+ wifi_channel channel; // channel frequency in MHz -+ UINT_32 num_rssi; // number of rssi samples -+ wifi_rssi rssi[8]; // RSSI history in db -+} PARAM_WIFI_CHANGE_RESULT, *P_PARAM_WIFI_CHANGE_RESULT;*/ -+ -+typedef struct _PARAM_WIFI_CHANGE_RESULT { -+ UINT_16 flags; -+ UINT_16 channel; -+ mac_addr bssid; /* BSSID */ -+ INT_8 rssi[8]; /* RSSI history in db */ -+} PARAM_WIFI_CHANGE_RESULT, *P_PARAM_WIFI_CHANGE_RESULT; -+ -+typedef struct _PARAM_AP_THRESHOLD { -+ mac_addr bssid; /* AP BSSID */ -+ wifi_rssi low; /* low threshold */ -+ wifi_rssi high; /* high threshold */ -+ wifi_channel channel; /* channel hint */ -+} PARAM_AP_THRESHOLD, *P_PARAM_AP_THRESHOLD; -+ -+typedef struct _PARAM_WIFI_BSSID_HOTLIST { -+ UINT_32 lost_ap_sample_size; -+ UINT_32 num_ap; /* number of hotlist APs */ -+ PARAM_AP_THRESHOLD ap[MAX_HOTLIST_APS]; /* hotlist APs */ -+} PARAM_WIFI_BSSID_HOTLIST, *P_PARAM_WIFI_BSSID_HOTLIST; -+ -+typedef struct _PARAM_WIFI_SIGNIFICANT_CHANGE { -+ UINT_16 rssi_sample_size; /* number of samples for averaging RSSI */ -+ UINT_16 lost_ap_sample_size; /* number of samples to confirm AP loss */ -+ UINT_16 min_breaching; /* number of APs breaching threshold */ -+ UINT_16 num_ap; /* max 64 */ -+ PARAM_AP_THRESHOLD ap[MAX_SIGNIFICANT_CHANGE_APS]; -+} PARAM_WIFI_SIGNIFICANT_CHANGE, *P_PARAM_WIFI_SIGNIFICANT_CHANGE; -+ -+/* RTT Capabilities */ -+typedef struct _PARAM_WIFI_RTT_CAPABILITIES { -+ UINT_8 rtt_one_sided_supported; /* if 1-sided rtt data collection is supported */ -+ UINT_8 rtt_ftm_supported; /* if ftm rtt data collection is supported */ -+ UINT_8 lci_support; /* if initiator supports LCI request. Applies to 2-sided RTT */ -+ UINT_8 lcr_support; /* if initiator supports LCR request. Applies to 2-sided RTT */ -+ UINT_8 preamble_support; /* bit mask indicates what preamble is supported by initiator */ -+ UINT_8 bw_support; /* bit mask indicates what BW is supported by initiator */ -+} PARAM_WIFI_RTT_CAPABILITIES, *P_PARAM_WIFI_RTT_CAPABILITIES; -+ -+/* channel operating width */ -+typedef enum { -+ WIFI_CHAN_WIDTH_20 = 0, -+ WIFI_CHAN_WIDTH_40 = 1, -+ WIFI_CHAN_WIDTH_80 = 2, -+ WIFI_CHAN_WIDTH_160 = 3, -+ WIFI_CHAN_WIDTH_80P80 = 4, -+ WIFI_CHAN_WIDTH_5 = 5, -+ WIFI_CHAN_WIDTH_10 = 6, -+ WIFI_CHAN_WIDTH_INVALID = -1 -+} WIFI_CHANNEL_WIDTH; -+ -+/* channel information */ -+typedef struct { -+ WIFI_CHANNEL_WIDTH width; /* channel width (20, 40, 80, 80+80, 160) */ -+ UINT_32 center_freq; /* primary 20 MHz channel */ -+ UINT_32 center_freq0; /* center frequency (MHz) first segment */ -+ UINT_32 center_freq1; /* center frequency (MHz) second segment */ -+} WIFI_CHANNEL_INFO; -+ -+/* channel statistics */ -+typedef struct { -+ WIFI_CHANNEL_INFO channel; /* channel */ -+ UINT_32 on_time; /* msecs the radio is awake (32 bits number accruing over time) */ -+ UINT_32 cca_busy_time; /* msecs the CCA register is busy (32 bits number accruing over time) */ -+} WIFI_CHANNEL_STAT; -+ -+/* radio statistics */ -+typedef struct { -+ UINT_32 radio; /* wifi radio (if multiple radio supported) */ -+ UINT_32 on_time; /* msecs the radio is awake (32 bits number accruing over time) */ -+ UINT_32 tx_time; /* msecs the radio is transmitting (32 bits number accruing over time) */ -+ UINT_32 rx_time; /* msecs the radio is in active receive (32 bits number accruing over time) */ -+ UINT_32 on_time_scan; /* msecs the radio is awake due to all scan (32 bits number accruing over time) */ -+ UINT_32 on_time_nbd; /* msecs the radio is awake due to NAN (32 bits number accruing over time) */ -+ UINT_32 on_time_gscan; /* msecs the radio is awake due to G?scan (32 bits number accruing over time) */ -+ UINT_32 on_time_roam_scan; /* msecs the radio is awake due to roam?scan -+ (32 bits number accruing over time) */ -+ UINT_32 on_time_pno_scan; /* msecs the radio is awake due to PNO scan -+ (32 bits number accruing over time) */ -+ UINT_32 on_time_hs20; /* msecs the radio is awake due to HS2.0 scans and GAS exchange -+ 32 bits number accruing over time) */ -+ UINT_32 num_channels; /* number of channels */ -+ WIFI_CHANNEL_STAT channels[]; /* channel statistics */ -+} WIFI_RADIO_STAT; -+ -+/* wifi rate */ -+typedef struct { -+ UINT_32 preamble:3; /* 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */ -+ UINT_32 nss:2; /* 0:1x1, 1:2x2, 3:3x3, 4:4x4 */ -+ UINT_32 bw:3; /* 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */ -+ UINT_32 rateMcsIdx:8; /* OFDM/CCK rate code would be as per ieee std in the units of 0.5mbps */ -+ /* HT/VHT it would be mcs index */ -+ UINT_32 reserved:16; /* reserved */ -+ UINT_32 bitrate; /* units of 100 Kbps */ -+} WIFI_RATE; -+ -+/* per rate statistics */ -+typedef struct { -+ WIFI_RATE rate; /* rate information */ -+ UINT_32 tx_mpdu; /* number of successfully transmitted data pkts (ACK rcvd) */ -+ UINT_32 rx_mpdu; /* number of received data pkts */ -+ UINT_32 mpdu_lost; /* number of data packet losses (no ACK) */ -+ UINT_32 retries; /* total number of data pkt retries */ -+ UINT_32 retries_short; /* number of short data pkt retries */ -+ UINT_32 retries_long; /* number of long data pkt retries */ -+} WIFI_RATE_STAT; -+ -+/*wifi_interface_link_layer_info*/ -+typedef enum { -+ WIFI_DISCONNECTED = 0, -+ WIFI_AUTHENTICATING = 1, -+ WIFI_ASSOCIATING = 2, -+ WIFI_ASSOCIATED = 3, -+ WIFI_EAPOL_STARTED = 4, /* if done by firmware/driver */ -+ WIFI_EAPOL_COMPLETED = 5, /* if done by firmware/driver */ -+} WIFI_CONNECTION_STATE; -+ -+typedef enum { -+ WIFI_ROAMING_IDLE = 0, -+ WIFI_ROAMING_ACTIVE = 1, -+} WIFI_ROAM_STATE; -+ -+typedef enum { -+ WIFI_INTERFACE_STA = 0, -+ WIFI_INTERFACE_SOFTAP = 1, -+ WIFI_INTERFACE_IBSS = 2, -+ WIFI_INTERFACE_P2P_CLIENT = 3, -+ WIFI_INTERFACE_P2P_GO = 4, -+ WIFI_INTERFACE_NAN = 5, -+ WIFI_INTERFACE_MESH = 6, -+ WIFI_INTERFACE_UNKNOWN = -1 -+} WIFI_INTERFACE_MODE; -+ -+typedef struct { -+ WIFI_INTERFACE_MODE mode; /* interface mode */ -+ u8 mac_addr[6]; /* interface mac address (self) */ -+ WIFI_CONNECTION_STATE state; /* connection state (valid for STA, CLI only) */ -+ WIFI_ROAM_STATE roaming; /* roaming state */ -+ u32 capabilities; /* WIFI_CAPABILITY_XXX (self) */ -+ u8 ssid[33]; /* null terminated SSID */ -+ u8 bssid[6]; /* bssid */ -+ u8 ap_country_str[3]; /* country string advertised by AP */ -+ u8 country_str[3]; /* country string for this association */ -+} WIFI_INTERFACE_LINK_LAYER_INFO; -+ -+/* access categories */ -+typedef enum { -+ WIFI_AC_VO = 0, -+ WIFI_AC_VI = 1, -+ WIFI_AC_BE = 2, -+ WIFI_AC_BK = 3, -+ WIFI_AC_MAX = 4, -+} WIFI_TRAFFIC_AC; -+ -+/* wifi peer type */ -+typedef enum { -+ WIFI_PEER_STA, -+ WIFI_PEER_AP, -+ WIFI_PEER_P2P_GO, -+ WIFI_PEER_P2P_CLIENT, -+ WIFI_PEER_NAN, -+ WIFI_PEER_TDLS, -+ WIFI_PEER_INVALID, -+} WIFI_PEER_TYPE; -+ -+/* per peer statistics */ -+typedef struct { -+ WIFI_PEER_TYPE type; /* peer type (AP, TDLS, GO etc.) */ -+ UINT_8 peer_mac_address[6]; /* mac address */ -+ UINT_32 capabilities; /* peer WIFI_CAPABILITY_XXX */ -+ UINT_32 num_rate; /* number of rates */ -+ WIFI_RATE_STAT rate_stats[]; /* per rate statistics, number of entries = num_rate */ -+} WIFI_PEER_INFO; -+ -+/* per access category statistics */ -+typedef struct { -+ WIFI_TRAFFIC_AC ac; /* access category (VI, VO, BE, BK) */ -+ UINT_32 tx_mpdu; /* number of successfully transmitted unicast data pkts (ACK rcvd) */ -+ UINT_32 rx_mpdu; /* number of received unicast mpdus */ -+ UINT_32 tx_mcast; /* number of successfully transmitted multicast data packets */ -+ /* STA case: implies ACK received from AP for the unicast packet in which mcast pkt was sent */ -+ UINT_32 rx_mcast; /* number of received multicast data packets */ -+ UINT_32 rx_ampdu; /* number of received unicast a-mpdus */ -+ UINT_32 tx_ampdu; /* number of transmitted unicast a-mpdus */ -+ UINT_32 mpdu_lost; /* number of data pkt losses (no ACK) */ -+ UINT_32 retries; /* total number of data pkt retries */ -+ UINT_32 retries_short; /* number of short data pkt retries */ -+ UINT_32 retries_long; /* number of long data pkt retries */ -+ UINT_32 contention_time_min; /* data pkt min contention time (usecs) */ -+ UINT_32 contention_time_max; /* data pkt max contention time (usecs) */ -+ UINT_32 contention_time_avg; /* data pkt avg contention time (usecs) */ -+ UINT_32 contention_num_samples; /* num of data pkts used for contention statistics */ -+} WIFI_WMM_AC_STAT; -+ -+/* interface statistics */ -+typedef struct { -+ /* wifi_interface_handle iface; // wifi interface */ -+ WIFI_INTERFACE_LINK_LAYER_INFO info; /* current state of the interface */ -+ UINT_32 beacon_rx; /* access point beacon received count from connected AP */ -+ UINT_32 mgmt_rx; /* access point mgmt frames received count from connected AP (including Beacon) */ -+ UINT_32 mgmt_action_rx; /* action frames received count */ -+ UINT_32 mgmt_action_tx; /* action frames transmit count */ -+ wifi_rssi rssi_mgmt; /* access Point Beacon and Management frames RSSI (averaged) */ -+ wifi_rssi rssi_data; /* access Point Data Frames RSSI (averaged) from connected AP */ -+ wifi_rssi rssi_ack; /* access Point ACK RSSI (averaged) from connected AP */ -+ WIFI_WMM_AC_STAT ac[WIFI_AC_MAX]; /* per ac data packet statistics */ -+ UINT_32 num_peers; /* number of peers */ -+ WIFI_PEER_INFO peer_info[]; /* per peer statistics */ -+} WIFI_IFACE_STAT; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+int mtk_cfg80211_vendor_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_get_gscan_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_set_scan_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_set_significant_change(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_set_hotlist(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_enable_scan(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_enable_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_get_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_get_rtt_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_llstats_get_info(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_event_complete_scan(struct wiphy *wiphy, struct wireless_dev *wdev, WIFI_SCAN_EVENT complete); -+ -+int mtk_cfg80211_vendor_event_scan_results_available(struct wiphy *wiphy, struct wireless_dev *wdev, UINT_32 num); -+ -+int mtk_cfg80211_vendor_event_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len); -+ -+int mtk_cfg80211_vendor_event_significant_change_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_CHANGE_RESULT pdata, UINT_32 data_len); -+ -+int mtk_cfg80211_vendor_event_hotlist_ap_found(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len); -+ -+int mtk_cfg80211_vendor_event_hotlist_ap_lost(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len); -+ -+#endif /* _GL_VENDOR_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h -new file mode 100644 -index 0000000000000..827ff92b1581f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h -@@ -0,0 +1,357 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_wext.h#1 -+*/ -+ -+/*! \file gl_wext.h -+ \brief This file is for Portable Driver linux wireless extension support. -+*/ -+ -+/* -+** Log: gl_wext.h -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 20 2011 chinglan.wang -+ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. -+ * . -+ * -+ * 09 20 2011 chinglan.wang -+ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. -+ * . -+ * -+ * 01 11 2011 chinglan.wang -+ * NULL -+ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. -+ * Connection establish successfully. -+ * Use the WPS function to connect AP, the privacy bit always is set to 1. . -+ * -+ * 09 27 2010 wh.su -+ * NULL -+ * [WCXRP00000067][MT6620 Wi-Fi][Driver] Support the android+ WAPI function. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\12 2009-10-20 17:38:33 GMT mtk01090 -+** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, -+** and then stop hw. -+** \main\maintrunk.MT5921\11 2009-09-28 20:19:28 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\10 2009-09-03 12:12:35 GMT mtk01088 -+** adding the function declaration -+** \main\maintrunk.MT5921\9 2009-08-18 22:57:17 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\8 2008-08-29 16:59:07 GMT mtk01088 -+** fixed compiling error -+** \main\maintrunk.MT5921\7 2008-08-29 14:13:28 GMT mtk01088 -+** adjust the header file for code refine -+** \main\maintrunk.MT5921\6 2008-03-28 10:40:31 GMT mtk01461 -+** Add set desired rate in Linux STD IOCTL -+** \main\maintrunk.MT5921\5 2008-03-11 14:51:08 GMT mtk01461 -+** Refine private IOCTL functions -+** \main\maintrunk.MT5921\4 2008-02-12 23:45:45 GMT mtk01461 -+** Add Set Frequency & Channel oid support for Linux -+** \main\maintrunk.MT5921\3 2007-11-06 19:36:19 GMT mtk01088 -+** add the WPS related code -+*/ -+ -+#ifndef _GL_WEXT_H -+#define _GL_WEXT_H -+ -+#ifdef WIRELESS_EXT -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define KILO 1000 -+#define RATE_5_5M 11 /* 5.5M */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _PARAM_FIXED_IEs { -+ UINT_8 aucTimestamp[8]; -+ UINT_16 u2BeaconInterval; -+ UINT_16 u2Capabilities; -+} PARAM_FIXED_IEs; -+ -+typedef struct _PARAM_VARIABLE_IE_T { -+ UINT_8 ucElementID; -+ UINT_8 ucLength; -+ UINT_8 aucData[1]; -+} PARAM_VARIABLE_IE_T, *P_PARAM_VARIABLE_IE_T; -+ -+#if WIRELESS_EXT < 18 -+ -+#define SIOCSIWMLME 0x8B16 /* request MLME operation; uses struct iw_mlme */ -+/* MLME requests (SIOCSIWMLME / struct iw_mlme) */ -+#define IW_MLME_DEAUTH 0 -+#define IW_MLME_DISASSOC 1 -+ -+/*! \brief SIOCSIWMLME data */ -+struct iw_mlme { -+ __u16 cmd; /*!< IW_MLME_* */ -+ __u16 reason_code; -+ struct sockaddr addr; -+}; -+ -+#define SIOCSIWAUTH 0x8B32 /* set authentication mode params */ -+#define SIOCGIWAUTH 0x8B33 /* get authentication mode params */ -+/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */ -+#define IW_AUTH_INDEX 0x0FFF -+#define IW_AUTH_FLAGS 0xF000 -+/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095) -+ * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the -+ * parameter that is being set/get to; value will be read/written to -+ * struct iw_param value field) */ -+#define IW_AUTH_WPA_VERSION 0 -+#define IW_AUTH_CIPHER_PAIRWISE 1 -+#define IW_AUTH_CIPHER_GROUP 2 -+#define IW_AUTH_KEY_MGMT 3 -+#define IW_AUTH_TKIP_COUNTERMEASURES 4 -+#define IW_AUTH_DROP_UNENCRYPTED 5 -+#define IW_AUTH_80211_AUTH_ALG 6 -+#define IW_AUTH_WPA_ENABLED 7 -+#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8 -+#define IW_AUTH_ROAMING_CONTROL 9 -+#define IW_AUTH_PRIVACY_INVOKED 10 -+#if CFG_SUPPORT_802_11W -+#define IW_AUTH_MFP 12 -+ -+#define IW_AUTH_MFP_DISABLED 0 /* MFP disabled */ -+#define IW_AUTH_MFP_OPTIONAL 1 /* MFP optional */ -+#define IW_AUTH_MFP_REQUIRED 2 /* MFP required */ -+#endif -+ -+/* IW_AUTH_WPA_VERSION values (bit field) */ -+#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001 -+#define IW_AUTH_WPA_VERSION_WPA 0x00000002 -+#define IW_AUTH_WPA_VERSION_WPA2 0x00000004 -+ -+/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */ -+#define IW_AUTH_CIPHER_NONE 0x00000001 -+#define IW_AUTH_CIPHER_WEP40 0x00000002 -+#define IW_AUTH_CIPHER_TKIP 0x00000004 -+#define IW_AUTH_CIPHER_CCMP 0x00000008 -+#define IW_AUTH_CIPHER_WEP104 0x00000010 -+ -+/* IW_AUTH_KEY_MGMT values (bit field) */ -+#define IW_AUTH_KEY_MGMT_802_1X 1 -+#define IW_AUTH_KEY_MGMT_PSK 2 -+#define IW_AUTH_KEY_MGMT_WPA_NONE 4 -+ -+/* IW_AUTH_80211_AUTH_ALG values (bit field) */ -+#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001 -+#define IW_AUTH_ALG_SHARED_KEY 0x00000002 -+#define IW_AUTH_ALG_LEAP 0x00000004 -+ -+/* IW_AUTH_ROAMING_CONTROL values */ -+#define IW_AUTH_ROAMING_ENABLE 0 /* driver/firmware based roaming */ -+#define IW_AUTH_ROAMING_DISABLE 1 /* user space program used for roaming -+ * control */ -+ -+#define SIOCSIWENCODEEXT 0x8B34 /* set encoding token & mode */ -+#define SIOCGIWENCODEEXT 0x8B35 /* get encoding token & mode */ -+/* SIOCSIWENCODEEXT definitions */ -+#define IW_ENCODE_SEQ_MAX_SIZE 8 -+/* struct iw_encode_ext ->alg */ -+#define IW_ENCODE_ALG_NONE 0 -+#define IW_ENCODE_ALG_WEP 1 -+#define IW_ENCODE_ALG_TKIP 2 -+#define IW_ENCODE_ALG_CCMP 3 -+#if CFG_SUPPORT_802_11W -+#define IW_ENCODE_ALG_AES_CMAC 5 -+#endif -+ -+/* struct iw_encode_ext ->ext_flags */ -+#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001 -+#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002 -+#define IW_ENCODE_EXT_GROUP_KEY 0x00000004 -+#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008 -+ -+struct iw_encode_ext { -+ __u32 ext_flags; /*!< IW_ENCODE_EXT_* */ -+ __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ -+ __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ -+ struct sockaddr addr; /*!< ff:ff:ff:ff:ff:ff for broadcast/multicast -+ * (group) keys or unicast address for -+ * individual keys */ -+ __u16 alg; /*!< IW_ENCODE_ALG_* */ -+ __u16 key_len; -+ __u8 key[0]; -+}; -+ -+#define SIOCSIWPMKSA 0x8B36 /* PMKSA cache operation */ -+#define IW_PMKSA_ADD 1 -+#define IW_PMKSA_REMOVE 2 -+#define IW_PMKSA_FLUSH 3 -+ -+#define IW_PMKID_LEN 16 -+ -+struct iw_pmksa { -+ __u32 cmd; /*!< IW_PMKSA_* */ -+ struct sockaddr bssid; -+ __u8 pmkid[IW_PMKID_LEN]; -+}; -+ -+#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..) -+ * (scan results); This includes id and -+ * length fields. One IWEVGENIE may -+ * contain more than one IE. Scan -+ * results may contain one or more -+ * IWEVGENIE events. */ -+#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure -+ * (struct iw_michaelmicfailure) -+ */ -+#define IWEVASSOCREQIE 0x8C07 /* IEs used in (Re)Association Request. -+ * The data includes id and length -+ * fields and may contain more than one -+ * IE. This event is required in -+ * Managed mode if the driver -+ * generates its own WPA/RSN IE. This -+ * should be sent just before -+ * IWEVREGISTERED event for the -+ * association. */ -+#define IWEVASSOCRESPIE 0x8C08 /* IEs used in (Re)Association -+ * Response. The data includes id and -+ * length fields and may contain more -+ * than one IE. This may be sent -+ * between IWEVASSOCREQIE and -+ * IWEVREGISTERED events for the -+ * association. */ -+#define IWEVPMKIDCAND 0x8C09 /* PMKID candidate for RSN -+ * pre-authentication -+ * (struct iw_pmkid_cand) */ -+ -+#endif /* WIRELESS_EXT < 18 */ -+ -+#if WIRELESS_EXT < 17 -+/* Statistics flags (bitmask in updated) */ -+#define IW_QUAL_QUAL_UPDATED 0x1 /* Value was updated since last read */ -+#define IW_QUAL_LEVEL_UPDATED 0x2 -+#define IW_QUAL_NOISE_UPDATED 0x4 -+#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */ -+#define IW_QUAL_LEVEL_INVALID 0x20 -+#define IW_QUAL_NOISE_INVALID 0x40 -+#endif -+ -+enum { -+ IEEE80211_FILTER_TYPE_BEACON = 1 << 0, -+ IEEE80211_FILTER_TYPE_PROBE_REQ = 1 << 1, -+ IEEE80211_FILTER_TYPE_PROBE_RESP = 1 << 2, -+ IEEE80211_FILTER_TYPE_ASSOC_REQ = 1 << 3, -+ IEEE80211_FILTER_TYPE_ASSOC_RESP = 1 << 4, -+ IEEE80211_FILTER_TYPE_AUTH = 1 << 5, -+ IEEE80211_FILTER_TYPE_DEAUTH = 1 << 6, -+ IEEE80211_FILTER_TYPE_DISASSOC = 1 << 7, -+ IEEE80211_FILTER_TYPE_ALL = 0xFF /* used to check the valid filter bits */ -+}; -+ -+#if CFG_SUPPORT_WAPI -+#define IW_AUTH_WAPI_ENABLED 0x20 -+#define IW_ENCODE_ALG_SMS4 0x20 -+#endif -+ -+#if CFG_SUPPORT_WAPI /* Android+ */ -+#define IW_AUTH_KEY_MGMT_WAPI_PSK 3 -+#define IW_AUTH_KEY_MGMT_WAPI_CERT 4 -+#endif -+#define IW_AUTH_KEY_MGMT_WPS 5 -+ -+#if CFG_SUPPORT_802_11W -+#define IW_AUTH_KEY_MGMT_802_1X_SHA256 7 -+#define IW_AUTH_KEY_MGMT_PSK_SHA256 8 -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern const struct iw_handler_def wext_handler_def; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* wireless extensions' ioctls */ -+int wext_support_ioctl(IN struct net_device *prDev, IN struct ifreq *prIfReq, IN int i4Cmd); -+ -+int -+wext_set_rate(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN struct iw_param *prRate, IN char *pcExtra); -+ -+void -+wext_indicate_wext_event(IN P_GLUE_INFO_T prGlueInfo, -+ IN unsigned int u4Cmd, IN unsigned char *pucData, IN unsigned int u4DataLen); -+ -+struct iw_statistics *wext_get_wireless_stats(struct net_device *prDev); -+ -+BOOLEAN -+wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); -+ -+#if CFG_SUPPORT_WPS -+BOOLEAN -+wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+BOOLEAN wextSrchDesiredHS20IE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); -+ -+BOOLEAN wextSrchDesiredInterworkingIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); -+ -+BOOLEAN wextSrchDesiredAdvProtocolIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); -+ -+BOOLEAN wextSrchDesiredRoamingConsortiumIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); -+#endif -+ -+#if CFG_SUPPORT_WAPI -+BOOLEAN wextSrchDesiredWAPIIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* WIRELESS_EXT */ -+ -+#endif /* _GL_WEXT_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h -new file mode 100644 -index 0000000000000..31933fc6a461e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h -@@ -0,0 +1,402 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_wext_priv.h#3 -+*/ -+ -+/*! \file gl_wext_priv.h -+ \brief This file includes private ioctl support. -+*/ -+ -+/* -+** Log: gl_wext_priv.h -+ * -+ * 01 16 2012 wh.su -+ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl -+ * Adding the template code for set / get band IOCTL (with ICS supplicant_6).. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 01 02 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service -+ * discovery version check. -+ * Add a CMD ID for P2P driver version query. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add security check code. -+ * -+ * 01 27 2011 cm.chang -+ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default -+ * . -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 01 07 2011 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add a new compiling option to control if MCR read/write is permitted -+ * -+ * 12 31 2010 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add some iwpriv commands to support test mode operation -+ * -+ * 11 08 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * add the message check code from mt5921. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * revert changelist #15371, efuse read/write access will be done by RF test approach -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add OID definitions for EFUSE read/write access. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\16 2009-09-29 16:47:23 GMT mtk01090 -+** Remove unused functions -+** \main\maintrunk.MT5921\15 2009-09-28 20:19:31 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\14 2009-05-07 22:26:06 GMT mtk01089 -+** add private IO control for Linux BWCS -+** \main\maintrunk.MT5921\13 2008-08-29 14:55:20 GMT mtk01088 -+** adjust the code to meet coding style -+** \main\maintrunk.MT5921\12 2008-07-16 15:23:45 GMT mtk01104 -+** Support GPIO2 mode -+** \main\maintrunk.MT5921\11 2008-07-14 13:55:58 GMT mtk01104 -+** Support PRIV_CMD_BT_COEXIST -+** \main\maintrunk.MT5921\10 2008-07-09 00:20:24 GMT mtk01461 -+** Add priv oid to support WMM_PS_TEST -+** \main\maintrunk.MT5921\9 2008-05-30 20:27:24 GMT mtk01461 -+** Add POWER_MODE Private IOCTL cmd -+** \main\maintrunk.MT5921\8 2008-04-17 23:06:44 GMT mtk01461 -+** Add iwpriv support for AdHocMode setting -+** \main\maintrunk.MT5921\7 2008-03-31 21:01:24 GMT mtk01461 -+** Add priv IOCTL for VOIP settings -+** \main\maintrunk.MT5921\6 2008-03-31 13:49:47 GMT mtk01461 -+** add priv ioctl arg definition for turning on / off roaming -+** \main\maintrunk.MT5921\5 2008-03-26 15:35:09 GMT mtk01461 -+** Add CSUM offload priv ioctl for Linux -+** \main\maintrunk.MT5921\4 2008-03-11 14:51:11 GMT mtk01461 -+** Refine private IOCTL functions -+** \main\maintrunk.MT5921\3 2007-11-06 19:36:25 GMT mtk01088 -+** add the WPS related code -+*/ -+ -+#ifndef _GL_WEXT_PRIV_H -+#define _GL_WEXT_PRIV_H -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+/* If it is set to 1, iwpriv will support register read/write */ -+#define CFG_SUPPORT_PRIV_MCR_RW 1 -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+extern int set_p2p_mode_handler(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode); -+#if 0 -+extern BOOLEAN fgIsResetting; -+extern BOOLEAN g_u4HaltFlag; -+extern spinlock_t g_p2p_lock; -+extern int g_u4P2PEnding; -+extern int g_u4P2POnOffing; -+#endif -+#endif -+ -+ -+#if (CFG_SUPPORT_TXR_ENC == 1) -+extern VOID rlmCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+#endif /* CFG_SUPPORT_TXR_ENC */ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* New wireless extensions API - SET/GET convention (even ioctl numbers are -+ * root only) -+ */ -+#define IOCTL_SET_INT (SIOCIWFIRSTPRIV + 0) -+#define IOCTL_GET_INT (SIOCIWFIRSTPRIV + 1) -+ -+#define IOCTL_SET_ADDRESS (SIOCIWFIRSTPRIV + 2) -+#define IOCTL_GET_ADDRESS (SIOCIWFIRSTPRIV + 3) -+#define IOCTL_SET_STR (SIOCIWFIRSTPRIV + 4) -+#define IOCTL_GET_STR (SIOCIWFIRSTPRIV + 5) -+#define IOCTL_SET_KEY (SIOCIWFIRSTPRIV + 6) -+#define IOCTL_GET_KEY (SIOCIWFIRSTPRIV + 7) -+#define IOCTL_SET_STRUCT (SIOCIWFIRSTPRIV + 8) -+#define IOCTL_GET_STRUCT (SIOCIWFIRSTPRIV + 9) -+#define IOCTL_SET_STRUCT_FOR_EM (SIOCIWFIRSTPRIV + 11) -+#define IOCTL_SET_INTS (SIOCIWFIRSTPRIV + 12) -+#define IOCTL_GET_INTS (SIOCIWFIRSTPRIV + 13) -+#define IOCTL_SET_STRING (SIOCIWFIRSTPRIV + 14) -+ -+#define PRIV_CMD_REG_DOMAIN 0 -+#define PRIV_CMD_BEACON_PERIOD 1 -+#define PRIV_CMD_ADHOC_MODE 2 -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+#define PRIV_CMD_CSUM_OFFLOAD 3 -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+#define PRIV_CMD_ROAMING 4 -+#define PRIV_CMD_VOIP_DELAY 5 -+#define PRIV_CMD_POWER_MODE 6 -+ -+#define PRIV_CMD_WMM_PS 7 -+#define PRIV_CMD_BT_COEXIST 8 -+#define PRIV_GPIO2_MODE 9 -+ -+#define PRIV_CUSTOM_SET_PTA 10 -+#define PRIV_CUSTOM_CONTINUOUS_POLL 11 -+#define PRIV_CUSTOM_SINGLE_ANTENNA 12 -+#define PRIV_CUSTOM_BWCS_CMD 13 -+#define PRIV_CUSTOM_DISABLE_BEACON_DETECTION 14 /* later */ -+#define PRIV_CMD_OID 15 -+#define PRIV_SEC_MSG_OID 16 -+ -+#define PRIV_CMD_TEST_MODE 17 -+#define PRIV_CMD_TEST_CMD 18 -+#define PRIV_CMD_ACCESS_MCR 19 -+#define PRIV_CMD_SW_CTRL 20 -+ -+#if 1 /* ANTI_PRIVCY */ -+#define PRIV_SEC_CHECK_OID 21 -+#endif -+ -+#define PRIV_CMD_WSC_PROBE_REQ 22 -+ -+#define PRIV_CMD_P2P_VERSION 23 -+ -+#define PRIV_CMD_GET_CH_LIST 24 -+ -+#define PRIV_CMD_SET_TX_POWER 25 -+ -+#define PRIV_CMD_BAND_CONFIG 26 -+ -+#define PRIV_CMD_DUMP_MEM 27 -+ -+#define PRIV_CMD_P2P_MODE 28 -+ -+#define PRIV_CMD_GET_BUILD_DATE_CODE 29 -+ -+#define PRIV_CMD_GET_DEBUG_CODE 30 -+ -+#define PRIV_CMD_OTHER 31 -+ -+#define PRIV_CMD_WFD_DEBUG_CODE 32 -+ -+#define PRIV_CMD_MET_PROFILING 33 -+ -+/* other string command ID */ -+#define PRIV_CMD_OTHER_TDLS 0x00 -+#define PRIV_CMD_OTHER_TAR 0x01 /* TX auto rate */ -+ -+/* 802.3 Objects (Ethernet) */ -+#define OID_802_3_CURRENT_ADDRESS 0x01010102 -+ -+/* IEEE 802.11 OIDs */ -+#define OID_802_11_SUPPORTED_RATES 0x0D01020E -+#define OID_802_11_CONFIGURATION 0x0D010211 -+ -+/* PnP and PM OIDs, NDIS default OIDS */ -+#define OID_PNP_SET_POWER 0xFD010101 -+ -+#define OID_CUSTOM_OID_INTERFACE_VERSION 0xFFA0C000 -+ -+/* MT5921 specific OIDs */ -+#define OID_CUSTOM_BT_COEXIST_CTRL 0xFFA0C580 -+#define OID_CUSTOM_POWER_MANAGEMENT_PROFILE 0xFFA0C581 -+#define OID_CUSTOM_PATTERN_CONFIG 0xFFA0C582 -+#define OID_CUSTOM_BG_SSID_SEARCH_CONFIG 0xFFA0C583 -+#define OID_CUSTOM_VOIP_SETUP 0xFFA0C584 -+#define OID_CUSTOM_ADD_TS 0xFFA0C585 -+#define OID_CUSTOM_DEL_TS 0xFFA0C586 -+#define OID_CUSTOM_SLT 0xFFA0C587 -+#define OID_CUSTOM_ROAMING_EN 0xFFA0C588 -+#define OID_CUSTOM_WMM_PS_TEST 0xFFA0C589 -+#define OID_CUSTOM_COUNTRY_STRING 0xFFA0C58A -+#define OID_CUSTOM_MULTI_DOMAIN_CAPABILITY 0xFFA0C58B -+#define OID_CUSTOM_GPIO2_MODE 0xFFA0C58C -+#define OID_CUSTOM_CONTINUOUS_POLL 0xFFA0C58D -+#define OID_CUSTOM_DISABLE_BEACON_DETECTION 0xFFA0C58E -+ -+/* CR1460, WPS privacy bit check disable */ -+#define OID_CUSTOM_DISABLE_PRIVACY_CHECK 0xFFA0C600 -+ -+/* Precedent OIDs */ -+#define OID_CUSTOM_MCR_RW 0xFFA0C801 -+#define OID_CUSTOM_EEPROM_RW 0xFFA0C803 -+#define OID_CUSTOM_SW_CTRL 0xFFA0C805 -+#define OID_CUSTOM_MEM_DUMP 0xFFA0C807 -+ -+/* RF Test specific OIDs */ -+#define OID_CUSTOM_TEST_MODE 0xFFA0C901 -+#define OID_CUSTOM_TEST_RX_STATUS 0xFFA0C903 -+#define OID_CUSTOM_TEST_TX_STATUS 0xFFA0C905 -+#define OID_CUSTOM_ABORT_TEST_MODE 0xFFA0C906 -+#define OID_CUSTOM_MTK_WIFI_TEST 0xFFA0C911 -+ -+/* BWCS */ -+#define OID_CUSTOM_BWCS_CMD 0xFFA0C931 -+#define OID_CUSTOM_SINGLE_ANTENNA 0xFFA0C932 -+#define OID_CUSTOM_SET_PTA 0xFFA0C933 -+ -+/* NVRAM */ -+#define OID_CUSTOM_MTK_NVRAM_RW 0xFFA0C941 -+#define OID_CUSTOM_CFG_SRC_TYPE 0xFFA0C942 -+#define OID_CUSTOM_EEPROM_TYPE 0xFFA0C943 -+ -+#if CFG_SUPPORT_WAPI -+#define OID_802_11_WAPI_MODE 0xFFA0CA00 -+#define OID_802_11_WAPI_ASSOC_INFO 0xFFA0CA01 -+#define OID_802_11_SET_WAPI_KEY 0xFFA0CA02 -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+#define OID_802_11_WSC_ASSOC_INFO 0xFFA0CB00 -+#endif -+ -+/* Define magic key of test mode (Don't change it for future compatibity) */ -+#define PRIV_CMD_TEST_MAGIC_KEY 2011 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* NIC BBCR configuration entry structure */ -+typedef struct _PRIV_CONFIG_ENTRY { -+ UINT_8 ucOffset; -+ UINT_8 ucValue; -+} PRIV_CONFIG_ENTRY, *PPRIV_CONFIG_ENTRY; -+ -+typedef WLAN_STATUS(*PFN_OID_HANDLER_FUNC_REQ) (IN PVOID prAdapter, -+ IN OUT PVOID pvBuf, IN UINT_32 u4BufLen, OUT PUINT_32 pu4OutInfoLen); -+ -+typedef enum _ENUM_OID_METHOD_T { -+ ENUM_OID_GLUE_ONLY, -+ ENUM_OID_GLUE_EXTENSION, -+ ENUM_OID_DRIVER_CORE -+} ENUM_OID_METHOD_T, *P_ENUM_OID_METHOD_T; -+ -+/* OID set/query processing entry */ -+typedef struct _WLAN_REQ_ENTRY { -+ UINT_32 rOid; /* OID */ -+ PUINT_8 pucOidName; /* OID name text */ -+ BOOLEAN fgQryBufLenChecking; -+ BOOLEAN fgSetBufLenChecking; -+ ENUM_OID_METHOD_T eOidMethod; -+ UINT_32 u4InfoBufLen; -+ PFN_OID_HANDLER_FUNC_REQ pfOidQueryHandler; /* PFN_OID_HANDLER_FUNC */ -+ PFN_OID_HANDLER_FUNC_REQ pfOidSetHandler; /* PFN_OID_HANDLER_FUNC */ -+} WLAN_REQ_ENTRY, *P_WLAN_REQ_ENTRY; -+ -+typedef struct _NDIS_TRANSPORT_STRUCT { -+ UINT_32 ndisOidCmd; -+ UINT_32 inNdisOidlength; -+ UINT_32 outNdisOidLength; -+ UINT_8 ndisOidContent[16]; -+} NDIS_TRANSPORT_STRUCT, *P_NDIS_TRANSPORT_STRUCT; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+int -+priv_set_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); -+ -+int -+priv_get_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); -+ -+int -+priv_set_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); -+ -+int -+priv_get_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); -+ -+int -+priv_set_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); -+ -+int -+priv_get_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); -+ -+UINT_32 CmdStringDecParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen); -+ -+UINT_32 CmdStringMacParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen, OUT UINT_8 *OutMac); -+ -+int -+priv_set_string(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); -+ -+int priv_support_ioctl(IN struct net_device *prDev, IN OUT struct ifreq *prReq, IN int i4Cmd); -+ -+int priv_support_driver_cmd(IN struct net_device *prDev, IN OUT struct ifreq *prReq, IN int i4Cmd); -+ -+INT_32 priv_driver_cmds(IN struct net_device *prNetDev, IN PCHAR pcCommand, IN INT_32 i4TotalLen); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _GL_WEXT_PRIV_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c -new file mode 100644 -index 0000000000000..fba854cfd68e1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c -@@ -0,0 +1,542 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/platform.c#1 -+*/ -+ -+/*! \file "platform.c" -+ \brief This file including the protocol layer privacy function. -+ -+ This file provided the macros and functions library support for the -+ protocol layer security setting from wlan_oid.c and for parse.c and -+ rsn.c and nic_privacy.c -+ -+*/ -+ -+/* -+** Log: platform.c -+ * -+ * 11 14 2011 cm.chang -+ * NULL -+ * Fix compiling warning -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 09 13 2011 jeffrey.chang -+ * [WCXRP00000983] [MT6620][Wi-Fi Driver] invalid pointer casting causes kernel panic during p2p connection -+ * fix the pointer casting -+ * -+ * 06 29 2011 george.huang -+ * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6 -+ * . -+ * -+ * 06 28 2011 george.huang -+ * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6 -+ * remove un-used code -+ * -+ * 05 11 2011 jeffrey.chang -+ * NULL -+ * fix build error -+ * -+ * 05 09 2011 jeffrey.chang -+ * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change -+ * support ARP filter through kernel notifier -+ * -+ * 04 08 2011 pat.lu -+ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver -+ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver -+ * -+ * 03 22 2011 pat.lu -+ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build -+ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * improve portability for awareness of early version of linux kernel and wireless extension. -+ * -+ * 03 18 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * remove early suspend functions -+ * -+ * 03 03 2011 jeffrey.chang -+ * NULL -+ * add the ARP filter callback -+ * -+ * 02 15 2011 jeffrey.chang -+ * NULL -+ * to support early suspend in android -+ * -+ * 02 01 2011 cp.wu -+ * [WCXRP00000413] [MT6620 Wi-Fi][Driver] Merge 1103 changes on NVRAM file path change to DaVinci main trunk and V1.1 -+ * branch -+ * upon Jason Zhang(NVRAM owner)'s change, ALPS has modified its NVRAM storage from /nvram/... to /data/nvram/... -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+** -+*/ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "gl_os.h" -+ -+#ifndef CONFIG_X86 -+#if defined(CONFIG_HAS_EARLY_SUSPEND) -+#include -+#endif -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define WIFI_NVRAM_FILE_NAME "/lib/firmware/mediatek/nvram/WIFI" -+#define WIFI_NVRAM_CUSTOM_NAME "/lib/firmware/mediatek/nvram/WIFI_CUSTOM" -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static int netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr) -+{ -+ UINT_8 ip[4] = { 0 }; -+ UINT_32 u4NumIPv4 = 0; -+/* #ifdef CONFIG_IPV6 */ -+#if 0 -+ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ -+ UINT_32 u4NumIPv6 = 0; -+#endif -+ struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; -+ struct net_device *prDev = ifa->ifa_dev->dev; -+ UINT_32 i; -+ P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ if (prDev == NULL) { -+ DBGLOG(REQ, ERROR, "netdev_event: device is empty.\n"); -+ return NOTIFY_DONE; -+ } -+ DBGLOG(REQ, INFO, "netdev_event, addr=%x, notification=%lx, dev_name=%s\n", -+ ifa->ifa_address, notification, prDev->name); -+ if (!fgIsUnderSuspend) -+ return NOTIFY_DONE; -+ if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) { -+ DBGLOG(REQ, WARN, "netdev_event: not our device\n"); -+ return NOTIFY_DONE; -+ } -+#if 0 /* CFG_SUPPORT_HOTSPOT_2_0 */ -+ { -+ /* printk(KERN_INFO "[netdev_event] IPV4_DAD is unlock now!!\n"); */ -+ prGlueInfo->fgIsDad = FALSE; -+ } -+#endif -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ if (prGlueInfo == NULL) { -+ DBGLOG(REQ, ERROR, "netdev_event: prGlueInfo is empty.\n"); -+ return NOTIFY_DONE; -+ } -+ ASSERT(prGlueInfo); -+ -+ /* <3> get the IPv4 address */ -+ if (!prDev || !(prDev->ip_ptr) || -+ !((struct in_device *)(prDev->ip_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(REQ, INFO, "ip is not available.\n"); -+ return NOTIFY_DONE; -+ } -+ -+ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); -+ DBGLOG(REQ, INFO, "ip is %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); -+ -+ /* todo: traverse between list to find whole sets of IPv4 addresses */ -+ if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0))) -+ u4NumIPv4++; -+/* #ifdef CONFIG_IPV6 */ -+#if 0 -+ if (!prDev || !(prDev->ip6_ptr) || -+ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(REQ, INFO, "ipv6 is not available.\n"); -+ return NOTIFY_DONE; -+ } -+ -+ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); -+ DBGLOG(REQ, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", -+ ip6[0], ip6[1], ip6[2], ip6[3], -+ ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]); -+ -+ /* todo: traverse between list to find whole sets of IPv6 addresses */ -+ if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) -+ /* u4NumIPv6++; */ -+#endif -+ -+ /* here we can compare the dev with other network's netdev to */ -+ /* set the proper arp filter */ -+ /* */ -+ /* IMPORTANT: please make sure if the context can sleep, if the context can't sleep */ -+ /* we should schedule a kernel thread to do this for us */ -+ -+ /* <7> set up the ARP filter */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_32 u4SetInfoLen = 0; -+ UINT_8 aucBuf[32] = { 0 }; -+ UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress); -+ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) aucBuf; -+ P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress; -+ -+/* #ifdef CONFIG_IPV6 */ -+#if 0 -+ prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6; -+#else -+ prParamNetAddrList->u4AddressCount = u4NumIPv4; -+#endif -+ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ for (i = 0; i < u4NumIPv4; i++) { -+ prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */ -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+#if 0 -+ kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip)); -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(ip)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip); -+#else -+ prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress; -+ kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip)); -+ prParamNetAddr = -+ (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS); -+#endif -+ } -+/* #ifdef CONFIG_IPV6 */ -+#if 0 -+ for (i = 0; i < u4NumIPv6; i++) { -+ prParamNetAddr->u2AddressLength = 6; -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6)); -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(ip6)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); -+ } -+#endif -+ ASSERT(u4Len <= sizeof(aucBuf)); -+ -+ DBGLOG(REQ, INFO, "kalIoctl (0x%p, 0x%p)\n", prGlueInfo, prParamNetAddrList); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetNetworkAddress, -+ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, ERROR, "set HW pattern filter fail 0x%x\n", rStatus); -+ } -+ -+ return NOTIFY_DONE; -+ -+} -+ -+/* #if CFG_SUPPORT_HOTSPOT_2_0 */ -+#if 0 -+static int net6dev_event(struct notifier_block *nb, unsigned long notification, void *ptr) -+{ -+ struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; -+ struct net_device *prDev = ifa->idev->dev; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ if (prDev == NULL) { -+ DBGLOG(REQ, INFO, "net6dev_event: device is empty.\n"); -+ return NOTIFY_DONE; -+ } -+ -+ if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) { -+ DBGLOG(REQ, INFO, "net6dev_event: xxx\n"); -+ return NOTIFY_DONE; -+ } -+ -+ if (strncmp(prDev->name, "p2p", 3) == 0) { -+ /* because we store the address of prGlueInfo in p2p's private date of net device */ -+ /* *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prP2PInfo->prDevHandler)) = prGlueInfo; */ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ } else { /* wlan0 */ -+ prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev); -+ } -+ -+ if (prGlueInfo == NULL) { -+ DBGLOG(REQ, INFO, "netdev_event: prGlueInfo is empty.\n"); -+ return NOTIFY_DONE; -+ } -+ /* printk(KERN_INFO "[net6dev_event] IPV6_DAD is unlock now!!\n"); */ -+ prGlueInfo->fgIs6Dad = FALSE; -+ -+ return NOTIFY_DONE; -+} -+#endif -+ -+static struct notifier_block inetaddr_notifier = { -+ .notifier_call = netdev_event, -+}; -+ -+#if 0 /* CFG_SUPPORT_HOTSPOT_2_0 */ -+static struct notifier_block inet6addr_notifier = { -+ .notifier_call = net6dev_event, -+}; -+#endif -+ -+void wlanRegisterNotifier(void) -+{ -+ register_inetaddr_notifier(&inetaddr_notifier); -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ /* register_inet6addr_notifier(&inet6addr_notifier); */ -+#endif -+} -+ -+/* EXPORT_SYMBOL(wlanRegisterNotifier); */ -+ -+void wlanUnregisterNotifier(void) -+{ -+ unregister_inetaddr_notifier(&inetaddr_notifier); -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ /* unregister_inetaddr_notifier(&inet6addr_notifier); */ -+#endif -+} -+ -+/* EXPORT_SYMBOL(wlanUnregisterNotifier); */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Utility function for reading data from files on NVRAM-FS -+* -+* \param[in] -+* filename -+* len -+* offset -+* \param[out] -+* buf -+* \return -+* actual length of data being read -+*/ -+/*----------------------------------------------------------------------------*/ -+static int nvram_read(char *filename, char *buf, ssize_t len, int offset) -+{ -+#if CFG_SUPPORT_NVRAM -+ struct file *fd; -+ int retLen = -1; -+ -+ mm_segment_t old_fs = get_fs(); -+ -+ set_fs(KERNEL_DS); -+ -+ fd = filp_open(filename, O_RDONLY, 0644); -+ -+ if (IS_ERR(fd)) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_read] : failed to open!!\n"); -+ return -1; -+ } -+ -+ do { -+ //if ((fd->f_op == NULL) || (fd->f_op->read == NULL)) { -+ if ( fd->f_op == NULL ) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_read] : file can not be read!!\n"); -+ break; -+ } -+ -+ if (fd->f_pos != offset) { -+ if (fd->f_op->llseek) { -+ if (fd->f_op->llseek(fd, offset, 0) != offset) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_read] : failed to seek!!\n"); -+ break; -+ } -+ } else { -+ fd->f_pos = offset; -+ } -+ } -+ -+ retLen = vfs_read(fd, buf, len, &fd->f_pos); -+ -+ } while (FALSE); -+ -+ filp_close(fd, NULL); -+ -+ set_fs(old_fs); -+ -+ return retLen; -+ -+#else /* !CFG_SUPPORT_NVRAM */ -+ -+ return -EIO; -+ -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Utility function for writing data to files on NVRAM-FS -+* -+* \param[in] -+* filename -+* buf -+* len -+* offset -+* \return -+* actual length of data being written -+*/ -+/*----------------------------------------------------------------------------*/ -+static int nvram_write(char *filename, char *buf, ssize_t len, int offset) -+{ -+#if CFG_SUPPORT_NVRAM -+ struct file *fd; -+ int retLen = -1; -+ -+ mm_segment_t old_fs = get_fs(); -+ -+ set_fs(KERNEL_DS); -+ -+ fd = filp_open(filename, O_WRONLY | O_CREAT, 0644); -+ -+ if (IS_ERR(fd)) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_write] : failed to open!!\n"); -+ return -1; -+ } -+ -+ do { -+ if ((fd->f_op == NULL) || (fd->f_op->write == NULL)) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_write] : file can not be write!!\n"); -+ break; -+ } -+ /* End of if */ -+ if (fd->f_pos != offset) { -+ if (fd->f_op->llseek) { -+ if (fd->f_op->llseek(fd, offset, 0) != offset) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_write] : failed to seek!!\n"); -+ break; -+ } -+ } else { -+ fd->f_pos = offset; -+ } -+ } -+ -+ retLen = vfs_write(fd, buf, len, &fd->f_pos); -+ -+ } while (FALSE); -+ -+ filp_close(fd, NULL); -+ -+ set_fs(old_fs); -+ -+ return retLen; -+ -+#else /* !CFG_SUPPORT_NVRAMS */ -+ -+ return -EIO; -+ -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief API for reading data on NVRAM -+* -+* \param[in] -+* prGlueInfo -+* u4Offset -+* \param[out] -+* pu2Data -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalCfgDataRead16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, OUT PUINT_16 pu2Data) -+{ -+ if (pu2Data == NULL) -+ return FALSE; -+ -+ if (nvram_read(WIFI_NVRAM_FILE_NAME, -+ (char *)pu2Data, sizeof(unsigned short), u4Offset) != sizeof(unsigned short)) { -+ return FALSE; -+ } else { -+ return TRUE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief API for writing data on NVRAM -+* -+* \param[in] -+* prGlueInfo -+* u4Offset -+* u2Data -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalCfgDataWrite16(IN P_GLUE_INFO_T prGlueInfo, UINT_32 u4Offset, UINT_16 u2Data) -+{ -+ if (nvram_write(WIFI_NVRAM_FILE_NAME, -+ (char *)&u2Data, sizeof(unsigned short), u4Offset) != sizeof(unsigned short)) { -+ return FALSE; -+ } else { -+ return TRUE; -+ } -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h -new file mode 100644 -index 0000000000000..9444d415c60e8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h -@@ -0,0 +1,190 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/version.h#1 -+*/ -+ -+/*! \file "version.h" -+ \brief Driver's version definition -+ -+*/ -+ -+/* -+** Log: version.h -+ * -+ * 11 01 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.1.1. -+ * -+ * 08 26 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.9.. -+ * -+ * 08 23 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.8. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * correct typo. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * for building MT6628 Win32 driver environment -+ * -+ * 08 03 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.7. -+ * -+ * 07 24 2011 puff.wen -+ * NULL -+ * [MT5931][Beta 5]Change the version number to v0.2.2.0 -+ * -+ * 06 01 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.6.. -+ * -+ * 05 09 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.5.. -+ * -+ * 04 19 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.4. -+ * -+ * 04 18 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.3. -+ * -+ * 03 25 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.2. -+ * -+ * 03 21 2011 chinglan.wang -+ * NULL -+ * Change the version number to 2.0.0.1. -+ * -+ * 03 18 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.0. -+ * -+ * 02 11 2011 chinglan.wang -+ * NULL -+ * Change to the version 1.2.0.2. -+ * -+ * 02 10 2011 chinglan.wang -+ * NULL -+ * Change the version to 1.2.0.1. -+ * -+ * 02 08 2011 cp.wu -+ * [WCXRP00000427] [MT6620 Wi-Fi][Driver] Modify veresion information to match with release revision number -+ * change version number to v1.2.0.0 for preparing v1.2 software package release. -+ * -+ * 12 10 2010 kevin.huang -+ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check -+ * Add Linux Proc Support -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * [WINDDK] build system changes for MT5931 -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-12-14 14:10:55 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-17 22:41:00 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-13 16:20:33 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:27:13 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _VERSION_H -+#define _VERSION_H -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#ifndef NIC_AUTHOR -+#define NIC_AUTHOR "NIC_AUTHOR" -+#endif -+#ifndef NIC_DESC -+#define NIC_DESC "NIC_DESC" -+#endif -+ -+#ifndef NIC_NAME -+#if defined(MT6620) -+#define NIC_NAME "MT6620" -+#define NIC_DEVICE_ID "MT6620" -+#define NIC_DEVICE_ID_LOW "mt6620" -+#elif defined(MT6628) -+#define NIC_NAME "MT6582" -+#define NIC_DEVICE_ID "MT6582" -+#define NIC_DEVICE_ID_LOW "mt6582" -+#endif -+#endif -+ -+/* NIC driver information */ -+#define NIC_VENDOR "MediaTek Inc." -+#define NIC_VENDOR_OUI {0x00, 0x0C, 0xE7} -+ -+#if defined(MT6620) -+#define NIC_PRODUCT_NAME "MediaTek Inc. MT6620 Wireless LAN Adapter" -+#define NIC_DRIVER_NAME "MediaTek Inc. MT6620 Wireless LAN Adapter Driver" -+#elif defined(MT6628) -+/* #define NIC_PRODUCT_NAME "MediaTek Inc. MT6628 Wireless LAN Adapter" */ -+/* #define NIC_DRIVER_NAME "MediaTek Inc. MT6628 Wireless LAN Adapter Driver" */ -+#define NIC_PRODUCT_NAME "MediaTek Inc. MT6582 Wireless LAN Adapter" -+#define NIC_DRIVER_NAME "MediaTek Inc. MT6582 Wireless LAN Adapter Driver" -+#endif -+ -+/* Define our driver version */ -+#define NIC_DRIVER_MAJOR_VERSION 2 -+#define NIC_DRIVER_MINOR_VERSION 0 -+#define NIC_DRIVER_VERSION (2, 0, 1, 1) -+#define NIC_DRIVER_VERSION_STRING "2.0.1.1" -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _VERSION_H */ -diff --git a/drivers/misc/mediatek/include/mt-plat/aee.h b/drivers/misc/mediatek/include/mt-plat/aee.h -new file mode 100644 -index 0000000000000..d1cf448dafb21 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/aee.h -@@ -0,0 +1,284 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#if !defined(__AEE_H__) -+#define __AEE_H__ -+ -+#include -+#include -+ -+#define AEE_MODULE_NAME_LENGTH 64 -+#define AEE_PROCESS_NAME_LENGTH 256 -+#define AEE_BACKTRACE_LENGTH 3072 -+ -+typedef enum { -+ AE_DEFECT_FATAL, -+ AE_DEFECT_EXCEPTION, -+ AE_DEFECT_WARNING, -+ AE_DEFECT_REMINDING, -+ AE_DEFECT_ATTR_END -+} AE_DEFECT_ATTR; -+ -+typedef enum { -+ AE_KE = 0, /* Fatal Exception */ -+ AE_HWT, -+ AE_REBOOT, -+ AE_NE, -+ AE_JE, -+ AE_SWT, -+ AE_EE, -+ AE_EXP_ERR_END, -+ AE_ANR, /* Error or Warning or Defect */ -+ AE_RESMON, -+ AE_MODEM_WARNING, -+ AE_WTF, -+ AE_WRN_ERR_END, -+ AE_MANUAL, /* Manual Raise */ -+ AE_EXP_CLASS_END, -+ -+ AE_KERNEL_PROBLEM_REPORT = 1000, -+ AE_SYSTEM_JAVA_DEFECT, -+ AE_SYSTEM_NATIVE_DEFECT, -+ AE_MANUAL_MRDUMP_KEY, -+} AE_EXP_CLASS; /* General Program Exception Class */ -+ -+typedef enum { -+ AEE_REBOOT_MODE_NORMAL = 0, -+ AEE_REBOOT_MODE_KERNEL_OOPS, -+ AEE_REBOOT_MODE_KERNEL_PANIC, -+ AEE_REBOOT_MODE_NESTED_EXCEPTION, -+ AEE_REBOOT_MODE_WDT, -+ AEE_REBOOT_MODE_MANUAL_KDUMP, -+} AEE_REBOOT_MODE; -+ -+#define AEE_SZ_SYMBOL_L 140 -+#define AEE_SZ_SYMBOL_S 80 -+struct aee_bt_frame { -+ __u64 pc; -+ __u64 lr; -+ __u32 pad[5]; -+ char pc_symbol[AEE_SZ_SYMBOL_S]; /* Now we use different symbol length for PC &LR */ -+ char lr_symbol[AEE_SZ_SYMBOL_L]; -+}; -+ -+/* aee_process_info struct should strictly small than ipanic_buffer, now 4KB */ -+struct aee_process_info { -+ char process_path[AEE_PROCESS_NAME_LENGTH]; -+ char backtrace[AEE_BACKTRACE_LENGTH]; -+ struct aee_bt_frame ke_frame; -+}; -+ -+struct aee_process_bt { -+ __u32 pid; -+ __u32 nr_entries; -+ struct aee_bt_frame *entries; -+}; -+ -+ -+struct aee_thread_reg { -+ pid_t tid; -+ struct pt_regs regs; -+}; -+ -+struct aee_user_thread_stack { -+ pid_t tid; -+ int StackLength; -+ unsigned char *Userthread_Stack; /*8k stack ,define to char only for match 64bit/32bit*/ -+}; -+ -+struct aee_user_thread_maps { -+ pid_t tid; -+ int Userthread_mapsLength; -+ unsigned char *Userthread_maps; /*8k stack ,define to char only for match 64bit/32bit*/ -+}; -+ -+ -+ -+struct aee_oops { -+ struct list_head list; -+ AE_DEFECT_ATTR attr; -+ AE_EXP_CLASS clazz; -+ -+ char module[AEE_MODULE_NAME_LENGTH]; -+ /* consist with struct aee_process_info */ -+ char process_path[AEE_PROCESS_NAME_LENGTH]; -+ char backtrace[AEE_BACKTRACE_LENGTH]; -+ struct aee_bt_frame ke_frame; -+ -+ char *detail; -+ int detail_len; -+ -+ char *console; -+ int console_len; -+ -+ char *android_main; -+ int android_main_len; -+ char *android_radio; -+ int android_radio_len; -+ char *android_system; -+ int android_system_len; -+ -+ char *userspace_info; -+ int userspace_info_len; -+ -+ char *mmprofile; -+ int mmprofile_len; -+ -+ char *mini_rdump; -+ int mini_rdump_len; -+ -+ -+ struct aee_user_thread_stack userthread_stack; -+ struct aee_thread_reg userthread_reg; -+ struct aee_user_thread_maps userthread_maps; -+ -+ int dump_option; -+}; -+ -+struct aee_kernel_api { -+ void (*kernel_reportAPI)(const AE_DEFECT_ATTR attr, const int db_opt, const char *module, -+ const char *msg); -+ void (*md_exception)(const char *assert_type, const int *log, int log_size, const int *phy, -+ int phy_size, const char *detail, const int db_opt); -+ void (*md32_exception)(const char *assert_type, const int *log, int log_size, -+ const int *phy, int phy_size, const char *detail, const int db_opt); -+ void (*combo_exception)(const char *assert_type, const int *log, int log_size, -+ const int *phy, int phy_size, const char *detail, const int db_opt); -+ void (*scp_exception)(const char *assert_type, const int *log, int log_size, -+ const int *phy, int phy_size, const char *detail, const int db_opt); -+}; -+ -+void aee_sram_printk(const char *fmt, ...); -+int aee_nested_printf(const char *fmt, ...); -+void aee_wdt_irq_info(void); -+void aee_wdt_fiq_info(void *arg, void *regs, void *svc_sp); -+void aee_trigger_kdb(void); -+struct aee_oops *aee_oops_create(AE_DEFECT_ATTR attr, AE_EXP_CLASS clazz, const char *module); -+void aee_oops_set_backtrace(struct aee_oops *oops, const char *backtrace); -+void aee_oops_set_process_path(struct aee_oops *oops, const char *process_path); -+void aee_oops_free(struct aee_oops *oops); -+/* powerkey press,modules use bits */ -+#define AE_WDT_Powerkey_DEVICE_PATH "/dev/kick_powerkey" -+#define WDT_SETBY_DEFAULT (0) -+#define WDT_SETBY_Backlight (1<<0) -+#define WDT_SETBY_Display (1<<1) -+#define WDT_SETBY_SF (1<<2) -+#define WDT_SETBY_PM (1<<3) -+#define WDT_SETBY_WMS_DISABLE_PWK_MONITOR (0xAEEAEE00) -+#define WDT_SETBY_WMS_ENABLE_PWK_MONITOR (0xAEEAEE01) -+#define WDT_PWK_HANG_FORCE_HWT (0xAEE0FFFF) -+ -+/* QHQ RT Monitor */ -+#define AEEIOCTL_RT_MON_Kick _IOR('p', 0x0A, int) -+#define AE_WDT_DEVICE_PATH "/dev/RT_Monitor" -+/* QHQ RT Monitor end */ -+ -+/* DB dump option bits, set relative bit to 1 to include related file in db */ -+#define DB_OPT_DEFAULT (0) -+#define DB_OPT_FTRACE (1<<0) -+#define DB_OPT_PRINTK_TOO_MUCH (1<<1) -+#define DB_OPT_NE_JBT_TRACES (1<<2) -+#define DB_OPT_SWT_JBT_TRACES (1<<3) -+#define DB_OPT_VM_TRACES (1<<4) -+#define DB_OPT_DUMPSYS_ACTIVITY (1<<5) -+#define DB_OPT_DUMPSYS_WINDOW (1<<6) -+#define DB_OPT_DUMPSYS_GFXINFO (1<<7) -+#define DB_OPT_DUMPSYS_SURFACEFLINGER (1<<8) -+#define DB_OPT_DISPLAY_HANG_DUMP (1<<9) -+#define DB_OPT_LOW_MEMORY_KILLER (1<<10) -+#define DB_OPT_PROC_MEM (1<<11) -+#define DB_OPT_FS_IO_LOG (1<<12) -+#define DB_OPT_PROCESS_COREDUMP (1<<13) -+#define DB_OPT_VM_HPROF (1<<14) -+#define DB_OPT_PROCMEM (1<<15) -+#define DB_OPT_DUMPSYS_INPUT (1<<16) -+#define DB_OPT_MMPROFILE_BUFFER (1<<17) -+#define DB_OPT_BINDER_INFO (1<<18) -+#define DB_OPT_WCN_ISSUE_INFO (1<<19) -+#define DB_OPT_DUMMY_DUMP (1<<20) -+#define DB_OPT_PID_MEMORY_INFO (1<<21) -+#define DB_OPT_VM_OOME_HPROF (1<<22) -+#define DB_OPT_PID_SMAPS (1<<23) -+#define DB_OPT_PROC_CMDQ_INFO (1<<24) -+#define DB_OPT_PROC_USKTRK (1<<25) -+#define DB_OPT_SF_RTT_DUMP (1<<26) -+#define DB_OPT_PAGETYPE_INFO (1<<27) -+#define DB_OPT_DUMPSYS_PROCSTATS (1<<28) -+#define DB_OPT_DUMP_DISPLAY (1<<29) -+#define DB_OPT_NATIVE_BACKTRACE (1<<30) -+#define DB_OPT_AARCH64 (1<<31) -+ -+#define aee_kernel_exception(module, msg...) \ -+ aee_kernel_exception_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg) -+#define aee_kernel_warning(module, msg...) \ -+ aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg) -+#define aee_kernel_reminding(module, msg...) \ -+ aee_kernel_reminding_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg) -+#define aee_kernel_dal_show(msg) \ -+ aee_kernel_dal_api(__FILE__, __LINE__, msg) -+ -+#define aed_md_exception(log, log_size, phy, phy_size, detail) \ -+ aed_md_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) -+#define aed_md32_exception(log, log_size, phy, phy_size, detail) \ -+ aed_md32_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) -+#define aed_scp_exception(log, log_size, phy, phy_size, detail) \ -+ aed_scp_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) -+#define aed_combo_exception(log, log_size, phy, phy_size, detail) \ -+ aed_combo_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) -+ -+void aee_kernel_exception_api(const char *file, const int line, const int db_opt, -+ const char *module, const char *msg, ...); -+void aee_kernel_warning_api(const char *file, const int line, const int db_opt, const char *module, -+ const char *msg, ...); -+void aee_kernel_reminding_api(const char *file, const int line, const int db_opt, -+ const char *module, const char *msg, ...); -+void aee_kernel_dal_api(const char *file, const int line, const char *msg); -+ -+void aed_md_exception_api(const int *log, int log_size, const int *phy, int phy_size, -+ const char *detail, const int db_opt); -+void aed_md32_exception_api(const int *log, int log_size, const int *phy, int phy_size, -+ const char *detail, const int db_opt); -+void aed_scp_exception_api(const int *log, int log_size, const int *phy, int phy_size, -+ const char *detail, const int db_opt); -+void aed_combo_exception_api(const int *log, int log_size, const int *phy, int phy_size, -+ const char *detail, const int db_opt); -+ -+void aee_kernel_wdt_kick_Powkey_api(const char *module, int msg); -+int aee_kernel_wdt_kick_api(int kinterval); -+void aee_powerkey_notify_press(unsigned long pressed); -+int aee_kernel_Powerkey_is_press(void); -+ -+void ipanic_recursive_ke(struct pt_regs *regs, struct pt_regs *excp_regs, int cpu); -+ -+/* QHQ RT Monitor */ -+void aee_kernel_RT_Monitor_api(int lParam); -+/* QHQ RT Monitor end */ -+void mt_fiq_printf(const char *fmt, ...); -+void aee_register_api(struct aee_kernel_api *aee_api); -+int aee_in_nested_panic(void); -+void aee_stop_nested_panic(struct pt_regs *regs); -+void aee_wdt_dump_info(void); -+void aee_wdt_printf(const char *fmt, ...); -+ -+void aee_fiq_ipi_cpu_stop(void *arg, void *regs, void *svc_sp); -+ -+#if defined(CONFIG_MTK_AEE_DRAM_CONSOLE) -+void aee_dram_console_reserve_memory(void); -+#else -+static inline void aee_dram_console_reserve_memory(void) -+{ -+} -+#endif -+ -+extern void *aee_excp_regs; /* To store latest exception, in case of stack corruption */ -+#endif /* __AEE_H__ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mrdump.h b/drivers/misc/mediatek/include/mt-plat/mrdump.h -new file mode 100644 -index 0000000000000..b6bdfa2f7617c ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mrdump.h -@@ -0,0 +1,204 @@ -+/* -+ * Copyright (C) 2016 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. -+ */ -+ -+#if !defined(__MRDUMP_H__) -+#define __MRDUMP_H__ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef __aarch64__ -+#define reg_pc pc -+#define reg_lr regs[30] -+#define reg_sp sp -+#define reg_fp regs[29] -+#else -+#define reg_pc ARM_pc -+#define reg_lr ARM_lr -+#define reg_sp ARM_sp -+#define reg_ip ARM_ip -+#define reg_fp ARM_fp -+#endif -+ -+#define MRDUMP_CPU_MAX 16 -+ -+#define MRDUMP_DEV_NULL 0 -+#define MRDUMP_DEV_SDCARD 1 -+#define MRDUMP_DEV_EMMC 2 -+ -+#define MRDUMP_FS_NULL 0 -+#define MRDUMP_FS_VFAT 1 -+#define MRDUMP_FS_EXT4 2 -+ -+#define MRDUMP_GO_DUMP "MRDUMP04" -+ -+typedef uint32_t arm32_gregset_t[18]; -+typedef uint64_t aarch64_gregset_t[34]; -+ -+struct mrdump_crash_record { -+ int reboot_mode; -+ -+ char msg[128]; -+ char backtrace[512]; -+ -+ uint32_t fault_cpu; -+ -+ union { -+ arm32_gregset_t arm32_regs; -+ aarch64_gregset_t aarch64_regs; -+ } cpu_regs[MRDUMP_CPU_MAX]; -+}; -+ -+struct mrdump_machdesc { -+ uint32_t crc; -+ -+ uint32_t output_device; -+ -+ uint32_t nr_cpus; -+ -+ uint64_t page_offset; -+ uint64_t high_memory; -+ -+ uint64_t vmalloc_start; -+ uint64_t vmalloc_end; -+ -+ uint64_t modules_start; -+ uint64_t modules_end; -+ -+ uint64_t phys_offset; -+ uint64_t master_page_table; -+ -+ uint32_t output_fstype; -+ uint32_t output_lbaooo; -+}; -+ -+struct mrdump_control_block { -+ char sig[8]; -+ -+ struct mrdump_machdesc machdesc; -+ struct mrdump_crash_record crash_record; -+}; -+ -+/* NOTE!! any change to this struct should be compatible in aed */ -+struct mrdump_mini_reg_desc { -+ unsigned long reg; /* register value */ -+ unsigned long kstart; /* start kernel addr of memory dump */ -+ unsigned long kend; /* end kernel addr of memory dump */ -+ unsigned long pos; /* next pos to dump */ -+ int valid; /* 1: valid regiser, 0: invalid regiser */ -+ int pad; /* reserved */ -+ loff_t offset; /* offset in buffer */ -+}; -+ -+/* it should always be smaller than MRDUMP_MINI_HEADER_SIZE */ -+struct mrdump_mini_header { -+ struct mrdump_mini_reg_desc reg_desc[ELF_NGREG]; -+}; -+ -+#define MRDUMP_MINI_NR_SECTION 60 -+#define MRDUMP_MINI_SECTION_SIZE (32 * 1024) -+#define NT_IPANIC_MISC 4095 -+#define MRDUMP_MINI_NR_MISC 20 -+ -+struct mrdump_mini_elf_misc { -+ unsigned long vaddr; -+ unsigned long paddr; -+ unsigned long start; -+ unsigned long size; -+}; -+ -+#define NOTE_NAME_SHORT 12 -+#define NOTE_NAME_LONG 20 -+ -+struct mrdump_mini_elf_psinfo { -+ struct elf_note note; -+ char name[NOTE_NAME_SHORT]; -+ struct elf_prpsinfo data; -+}; -+ -+struct mrdump_mini_elf_prstatus { -+ struct elf_note note; -+ char name[NOTE_NAME_SHORT]; -+ struct elf_prstatus data; -+}; -+ -+struct mrdump_mini_elf_note { -+ struct elf_note note; -+ char name[NOTE_NAME_LONG]; -+ struct mrdump_mini_elf_misc data; -+}; -+ -+struct mrdump_mini_elf_header { -+ struct elfhdr ehdr; -+ struct elf_phdr phdrs[MRDUMP_MINI_NR_SECTION]; -+ struct mrdump_mini_elf_psinfo psinfo; -+ struct mrdump_mini_elf_prstatus prstatus[NR_CPUS + 1]; -+ struct mrdump_mini_elf_note misc[MRDUMP_MINI_NR_MISC]; -+}; -+ -+typedef struct mrdump_rsvmem_block { -+ phys_addr_t start_addr; -+ phys_addr_t size; -+} mrdump_rsvmem_block_t; -+ -+ -+#define MRDUMP_MINI_HEADER_SIZE ALIGN(sizeof(struct mrdump_mini_elf_header), PAGE_SIZE) -+#define MRDUMP_MINI_DATA_SIZE (MRDUMP_MINI_NR_SECTION * MRDUMP_MINI_SECTION_SIZE) -+#define MRDUMP_MINI_BUF_SIZE (MRDUMP_MINI_HEADER_SIZE + MRDUMP_MINI_DATA_SIZE) -+ -+#ifdef CONFIG_MTK_RAM_CONSOLE_DRAM_ADDR -+#define MRDUMP_MINI_BUF_PADDR (CONFIG_MTK_RAM_CONSOLE_DRAM_ADDR + 0xf0000) -+#else -+#define MRDUMP_MINI_BUF_PADDR 0 -+#endif -+ -+int mrdump_init(void); -+void __mrdump_create_oops_dump(AEE_REBOOT_MODE reboot_mode, struct pt_regs *regs, const char *msg, -+ ...); -+#if defined(CONFIG_MTK_AEE_IPANIC) -+void mrdump_rsvmem(void); -+#else -+static inline void mrdump_rsvmem(void) -+{ -+} -+#endif -+ -+#if defined(CONFIG_MTK_AEE_MRDUMP) -+void aee_kdump_reboot(AEE_REBOOT_MODE, const char *msg, ...); -+#else -+static inline void aee_kdump_reboot(AEE_REBOOT_MODE reboot_mode, const char *msg, ...) -+{ -+} -+#endif -+ -+typedef int (*mrdump_write)(void *buf, int off, int len, int encrypt); -+#if defined(CONFIG_MTK_AEE_IPANIC) -+int mrdump_mini_create_oops_dump(AEE_REBOOT_MODE reboot_mode, mrdump_write write, -+ loff_t sd_offset, const char *msg, va_list ap); -+void mrdump_mini_reserve_memory(void); -+#else -+static inline int mrdump_mini_create_oops_dump(AEE_REBOOT_MODE reboot_mode, mrdump_write write, -+ loff_t sd_offset, const char *msg, va_list ap) -+{ -+ return 0; -+} -+ -+static inline void mrdump_mini_reserve_memory(void) -+{ -+} -+#endif -+ -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h b/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h -new file mode 100644 -index 0000000000000..1b60f007d0fdf ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h -@@ -0,0 +1,295 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+ -+#ifndef _MT8167_THERMAL_H -+#define _MT8167_THERMAL_H -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "sync_write.h" -+ -+extern void __iomem *thermal_base; -+extern void __iomem *auxadc_ts_base; -+extern void __iomem *apmixed_base; -+extern void __iomem *pericfg_base; -+extern int auxadc_ts_phy_base; -+extern int apmixed_phy_base; -+ -+#define THERM_CTRL_BASE_2 thermal_base -+#define AUXADC_BASE_2 auxadc_ts_base -+#define PERICFG_BASE pericfg_base -+#define APMIXED_BASE_2 apmixed_base -+ -+#define MT6752_EVB_BUILD_PASS /*Jerry fix build error FIX_ME*/ -+ -+/******************************************************************************* -+* AUXADC Register Definition -+******************************************************************************/ -+/*AUXADC_BASE: 0xF1001000 from Vincent Liang 2014.5.8*/ -+ -+#define AUXADC_CON0_V (AUXADC_BASE_2 + 0x000) /*yes, 0x11003000*/ -+#define AUXADC_CON1_V (AUXADC_BASE_2 + 0x004) -+#define AUXADC_CON1_SET_V (AUXADC_BASE_2 + 0x008) -+#define AUXADC_CON1_CLR_V (AUXADC_BASE_2 + 0x00C) -+#define AUXADC_CON2_V (AUXADC_BASE_2 + 0x010) -+/*#define AUXADC_CON3_V (AUXADC_BASE_2 + 0x014)*/ -+#define AUXADC_DAT0_V (AUXADC_BASE_2 + 0x014) -+#define AUXADC_DAT1_V (AUXADC_BASE_2 + 0x018) -+#define AUXADC_DAT2_V (AUXADC_BASE_2 + 0x01C) -+#define AUXADC_DAT3_V (AUXADC_BASE_2 + 0x020) -+#define AUXADC_DAT4_V (AUXADC_BASE_2 + 0x024) -+#define AUXADC_DAT5_V (AUXADC_BASE_2 + 0x028) -+#define AUXADC_DAT6_V (AUXADC_BASE_2 + 0x02C) -+#define AUXADC_DAT7_V (AUXADC_BASE_2 + 0x030) -+#define AUXADC_DAT8_V (AUXADC_BASE_2 + 0x034) -+#define AUXADC_DAT9_V (AUXADC_BASE_2 + 0x038) -+#define AUXADC_DAT10_V (AUXADC_BASE_2 + 0x03C) -+#define AUXADC_DAT11_V (AUXADC_BASE_2 + 0x040) -+#define AUXADC_MISC_V (AUXADC_BASE_2 + 0x094) -+ -+#define AUXADC_CON0_P (auxadc_ts_phy_base + 0x000) -+#define AUXADC_CON1_P (auxadc_ts_phy_base + 0x004) -+#define AUXADC_CON1_SET_P (auxadc_ts_phy_base + 0x008) -+#define AUXADC_CON1_CLR_P (auxadc_ts_phy_base + 0x00C) -+#define AUXADC_CON2_P (auxadc_ts_phy_base + 0x010) -+/*#define AUXADC_CON3_P (auxadc_ts_phy_base + 0x014)*/ -+#define AUXADC_DAT0_P (auxadc_ts_phy_base + 0x014) -+#define AUXADC_DAT1_P (auxadc_ts_phy_base + 0x018) -+#define AUXADC_DAT2_P (auxadc_ts_phy_base + 0x01C) -+#define AUXADC_DAT3_P (auxadc_ts_phy_base + 0x020) -+#define AUXADC_DAT4_P (auxadc_ts_phy_base + 0x024) -+#define AUXADC_DAT5_P (auxadc_ts_phy_base + 0x028) -+#define AUXADC_DAT6_P (auxadc_ts_phy_base + 0x02C) -+#define AUXADC_DAT7_P (auxadc_ts_phy_base + 0x030) -+#define AUXADC_DAT8_P (auxadc_ts_phy_base + 0x034) -+#define AUXADC_DAT9_P (auxadc_ts_phy_base + 0x038) -+#define AUXADC_DAT10_P (auxadc_ts_phy_base + 0x03C) -+#define AUXADC_DAT11_P (auxadc_ts_phy_base + 0x040) -+ -+#define AUXADC_MISC_P (auxadc_ts_phy_base + 0x094) -+ -+/******************************************************************************* -+* Peripheral Configuration Register Definition -+******************************************************************************/ -+/*#define PERICFG_BASE (0x10002000)*/ -+#define PERI_GLOBALCON_RST0 (pericfg_base + 0x000) /*yes, 0x10002000*/ -+/******************************************************************************* -+ * APMixedSys Configuration Register Definition -+ ******************************************************************************/ -+#define TS_CON0 (APMIXED_BASE_2 + 0x600) /*yes 0x10209000*/ -+#define TS_CON1 (APMIXED_BASE_2 + 0x604) -+#define TS_CON0_TM (APMIXED_BASE_2 + 0x600) /* yes 0x10209000 */ -+#define TS_CON1_TM (APMIXED_BASE_2 + 0x604) -+#define TS_CON0_P (apmixed_phy_base + 0x600) -+#define TS_CON1_P (apmixed_phy_base + 0x604) -+ -+/******************************************************************************* -+ * Thermal Controller Register Definition -+ ******************************************************************************/ -+#define TEMPMONCTL0 (THERM_CTRL_BASE_2 + 0x000) /*yes 0x1100B000*/ -+#define TEMPMONCTL1 (THERM_CTRL_BASE_2 + 0x004) -+#define TEMPMONCTL2 (THERM_CTRL_BASE_2 + 0x008) -+#define TEMPMONINT (THERM_CTRL_BASE_2 + 0x00C) -+#define TEMPMONINTSTS (THERM_CTRL_BASE_2 + 0x010) -+#define TEMPMONIDET0 (THERM_CTRL_BASE_2 + 0x014) -+#define TEMPMONIDET1 (THERM_CTRL_BASE_2 + 0x018) -+#define TEMPMONIDET2 (THERM_CTRL_BASE_2 + 0x01C) -+#define TEMPH2NTHRE (THERM_CTRL_BASE_2 + 0x024) -+#define TEMPHTHRE (THERM_CTRL_BASE_2 + 0x028) -+#define TEMPCTHRE (THERM_CTRL_BASE_2 + 0x02C) -+#define TEMPOFFSETH (THERM_CTRL_BASE_2 + 0x030) -+#define TEMPOFFSETL (THERM_CTRL_BASE_2 + 0x034) -+#define TEMPMSRCTL0 (THERM_CTRL_BASE_2 + 0x038) -+#define TEMPMSRCTL1 (THERM_CTRL_BASE_2 + 0x03C) -+#define TEMPAHBPOLL (THERM_CTRL_BASE_2 + 0x040) -+#define TEMPAHBTO (THERM_CTRL_BASE_2 + 0x044) -+#define TEMPADCPNP0 (THERM_CTRL_BASE_2 + 0x048) -+#define TEMPADCPNP1 (THERM_CTRL_BASE_2 + 0x04C) -+#define TEMPADCPNP2 (THERM_CTRL_BASE_2 + 0x050) -+#define TEMPADCPNP3 (THERM_CTRL_BASE_2 + 0x0B4) -+ -+#define TEMPADCMUX (THERM_CTRL_BASE_2 + 0x054) -+#define TEMPADCEXT (THERM_CTRL_BASE_2 + 0x058) -+#define TEMPADCEXT1 (THERM_CTRL_BASE_2 + 0x05C) -+#define TEMPADCEN (THERM_CTRL_BASE_2 + 0x060) -+#define TEMPPNPMUXADDR (THERM_CTRL_BASE_2 + 0x064) -+#define TEMPADCMUXADDR (THERM_CTRL_BASE_2 + 0x068) -+#define TEMPADCEXTADDR (THERM_CTRL_BASE_2 + 0x06C) -+#define TEMPADCEXT1ADDR (THERM_CTRL_BASE_2 + 0x070) -+#define TEMPADCENADDR (THERM_CTRL_BASE_2 + 0x074) -+#define TEMPADCVALIDADDR (THERM_CTRL_BASE_2 + 0x078) -+#define TEMPADCVOLTADDR (THERM_CTRL_BASE_2 + 0x07C) -+#define TEMPRDCTRL (THERM_CTRL_BASE_2 + 0x080) -+#define TEMPADCVALIDMASK (THERM_CTRL_BASE_2 + 0x084) -+#define TEMPADCVOLTAGESHIFT (THERM_CTRL_BASE_2 + 0x088) -+#define TEMPADCWRITECTRL (THERM_CTRL_BASE_2 + 0x08C) -+#define TEMPMSR0 (THERM_CTRL_BASE_2 + 0x090) -+#define TEMPMSR1 (THERM_CTRL_BASE_2 + 0x094) -+#define TEMPMSR2 (THERM_CTRL_BASE_2 + 0x098) -+#define TEMPMSR3 (THERM_CTRL_BASE_2 + 0x0B8) -+ -+#define TEMPIMMD0 (THERM_CTRL_BASE_2 + 0x0A0) -+#define TEMPIMMD1 (THERM_CTRL_BASE_2 + 0x0A4) -+#define TEMPIMMD2 (THERM_CTRL_BASE_2 + 0x0A8) -+#define TEMPIMMD3 (THERM_CTRL_BASE_2 + 0x0BC) -+ -+ -+#define TEMPPROTCTL (THERM_CTRL_BASE_2 + 0x0C0) -+#define TEMPPROTTA (THERM_CTRL_BASE_2 + 0x0C4) -+#define TEMPPROTTB (THERM_CTRL_BASE_2 + 0x0C8) -+#define TEMPPROTTC (THERM_CTRL_BASE_2 + 0x0CC) -+ -+#define TEMPSPARE0 (THERM_CTRL_BASE_2 + 0x0F0) -+#define TEMPSPARE1 (THERM_CTRL_BASE_2 + 0x0F4) -+#define TEMPSPARE2 (THERM_CTRL_BASE_2 + 0x0F8) -+#define TEMPSPARE3 (THERM_CTRL_BASE_2 + 0x0FC) -+ -+#define PTPCORESEL (THERM_CTRL_BASE_2 + 0x400) -+#define THERMINTST (THERM_CTRL_BASE_2 + 0x404) -+#define PTPODINTST (THERM_CTRL_BASE_2 + 0x408) -+#define THSTAGE0ST (THERM_CTRL_BASE_2 + 0x40C) -+#define THSTAGE1ST (THERM_CTRL_BASE_2 + 0x410) -+#define THSTAGE2ST (THERM_CTRL_BASE_2 + 0x414) -+#define THAHBST0 (THERM_CTRL_BASE_2 + 0x418) -+#define THAHBST1 (THERM_CTRL_BASE_2 + 0x41C) /*Only for DE debug*/ -+#define PTPSPARE0 (THERM_CTRL_BASE_2 + 0x420) -+#define PTPSPARE1 (THERM_CTRL_BASE_2 + 0x424) -+#define PTPSPARE2 (THERM_CTRL_BASE_2 + 0x428) -+#define PTPSPARE3 (THERM_CTRL_BASE_2 + 0x42C) -+#define THSLPEVEB (THERM_CTRL_BASE_2 + 0x430) -+ -+ -+#define PTPSPARE0_P (thermal_phy_base + 0x420) -+#define PTPSPARE1_P (thermal_phy_base + 0x424) -+#define PTPSPARE2_P (thermal_phy_base + 0x428) -+#define PTPSPARE3_P (thermal_phy_base + 0x42C) -+ -+/******************************************************************************* -+ * Thermal Controller Register Mask Definition -+ ******************************************************************************/ -+#define THERMAL_ENABLE_SEN0 0x1 -+#define THERMAL_ENABLE_SEN1 0x2 -+#define THERMAL_ENABLE_SEN2 0x4 -+#define THERMAL_MONCTL0_MASK 0x00000007 -+ -+#define THERMAL_PUNT_MASK 0x00000FFF -+#define THERMAL_FSINTVL_MASK 0x03FF0000 -+#define THERMAL_SPINTVL_MASK 0x000003FF -+#define THERMAL_MON_INT_MASK 0x0007FFFF -+ -+#define THERMAL_MON_CINTSTS0 0x000001 -+#define THERMAL_MON_HINTSTS0 0x000002 -+#define THERMAL_MON_LOINTSTS0 0x000004 -+#define THERMAL_MON_HOINTSTS0 0x000008 -+#define THERMAL_MON_NHINTSTS0 0x000010 -+#define THERMAL_MON_CINTSTS1 0x000020 -+#define THERMAL_MON_HINTSTS1 0x000040 -+#define THERMAL_MON_LOINTSTS1 0x000080 -+#define THERMAL_MON_HOINTSTS1 0x000100 -+#define THERMAL_MON_NHINTSTS1 0x000200 -+#define THERMAL_MON_CINTSTS2 0x000400 -+#define THERMAL_MON_HINTSTS2 0x000800 -+#define THERMAL_MON_LOINTSTS2 0x001000 -+#define THERMAL_MON_HOINTSTS2 0x002000 -+#define THERMAL_MON_NHINTSTS2 0x004000 -+#define THERMAL_MON_TOINTSTS 0x008000 -+#define THERMAL_MON_IMMDINTSTS0 0x010000 -+#define THERMAL_MON_IMMDINTSTS1 0x020000 -+#define THERMAL_MON_IMMDINTSTS2 0x040000 -+#define THERMAL_MON_FILTINTSTS0 0x080000 -+#define THERMAL_MON_FILTINTSTS1 0x100000 -+#define THERMAL_MON_FILTINTSTS2 0x200000 -+ -+ -+#define THERMAL_tri_SPM_State0 0x20000000 -+#define THERMAL_tri_SPM_State1 0x40000000 -+#define THERMAL_tri_SPM_State2 0x80000000 -+ -+ -+#define THERMAL_MSRCTL0_MASK 0x00000007 -+#define THERMAL_MSRCTL1_MASK 0x00000038 -+#define THERMAL_MSRCTL2_MASK 0x000001C0 -+ -+enum thermal_sensor_name { -+ THERMAL_SENSOR1 = 0,/*TS_MCU1*/ -+ THERMAL_SENSOR_NUM -+}; -+ -+enum thermal_bank_name { -+ THERMAL_BANK0 = 0, /*CPU (TS_MCU1) (TS1)*/ -+ THERMAL_BANK_NUM -+}; -+ -+struct TS_SVS { -+ unsigned int ts_MTS; -+ unsigned int ts_BTS; -+}; -+ -+struct mtk_gpu_power_info { -+ unsigned int gpufreq_khz; -+ unsigned int gpufreq_power; -+}; -+ -+/* svs driver need this function */ -+extern void get_thermal_slope_intercept(struct TS_SVS *ts_info, enum thermal_bank_name ts_bank); -+ -+/* mtk_thermal_platform.c need this */ -+extern void set_taklking_flag(bool flag); -+ -+#define THERMAL_WRAP_WR32(val, addr) mt_reg_sync_writel((val), ((void *)addr)) -+ -+enum MTK_THERMAL_SENSOR_CPU_ID_MET { -+ MTK_THERMAL_SENSOR_TS1 = 0, -+ MTK_THERMAL_SENSOR_TS2, -+ MTK_THERMAL_SENSOR_TS3, -+ MTK_THERMAL_SENSOR_TS4, -+ MTK_THERMAL_SENSOR_TSABB, -+ -+ ATM_CPU_LIMIT, -+ ATM_GPU_LIMIT, -+ -+ MTK_THERMAL_SENSOR_CPU_COUNT -+}; -+ -+extern int tscpu_get_cpu_temp_met(enum MTK_THERMAL_SENSOR_CPU_ID_MET id); -+extern int mtk_gpufreq_register(struct mtk_gpu_power_info *freqs, int num); -+ -+typedef void (*met_thermalsampler_funcMET)(void); -+void mt_thermalsampler_registerCB(met_thermalsampler_funcMET pCB); -+ -+void tscpu_start_thermal(void); -+void tscpu_stop_thermal(void); -+void tscpu_cancel_thermal_timer(void); -+void tscpu_start_thermal_timer(void); -+int mtkts_bts_get_hw_temp(void); -+ -+extern int get_immediate_ts1_wrap(void); -+extern int get_immediate_ts2_wrap(void); -+extern int get_immediate_ts3_wrap(void); -+ -+extern int is_cpu_power_unlimit(void); /* in mtk_ts_cpu.c */ -+extern int is_cpu_power_min(void); /* in mtk_ts_cpu.c */ -+extern int get_cpu_target_tj(void); -+extern int get_cpu_target_offset(void); -+ -+extern int mtktscpu_debug_log; -+ -+#endif -+ -diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h -new file mode 100644 -index 0000000000000..142a007805b95 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h -@@ -0,0 +1,159 @@ -+/* -+ * Copyright (C) 2011 MediaTek, Inc. -+ * -+ * Author: Holmes Chiou -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef __MT_FREQHOPPING_H__ -+#define __MT_FREQHOPPING_H__ -+ -+#define MT_FHPLL_MAX 6 -+#define MT_SSC_NR_PREDEFINE_SETTING 10 /* TODO: is 10 a good number ? */ -+ -+#define MEMPLL_SSC 0 -+#define MAINPLL_SSC 1 -+ -+#define FHTAG "[FH]" -+ -+#define VERBOSE_DEBUG 0 -+ -+#if VERBOSE_DEBUG -+#define FH_MSG(fmt, args...) \ -+ pr_debug(FHTAG""fmt" <- %s(): L<%d> PID<%s><%d>\n", ##args, __func__, __LINE__, current->comm, current->pid) -+#else -+ -+#if 1 /* log level is 6 xlog */ -+#define FH_MSG(fmt, args...) pr_debug(fmt, ##args) -+#else /* log level is 4 (printk) */ -+#define FH_MSG(fmt, args...) printk(FHTAG""fmt"\n", ##args) -+#endif -+ -+#endif -+ -+/* not support at mt2701 yet */ -+/* DRAMC */ -+#define FULLY_VERSION_FHCTL 0 -+ -+enum FH_FH_STATUS { -+ FH_FH_DISABLE = 0, -+ FH_FH_ENABLE_SSC, -+ FH_FH_ENABLE_DFH, -+ FH_FH_ENABLE_DVFS, -+}; -+ -+enum FH_PLL_STATUS { -+ FH_PLL_DISABLE = 0, -+ FH_PLL_ENABLE = 1 -+}; -+ -+/* TODO: FREQ_MODIFIED should not be here */ -+/* FH_PLL_STATUS_FREQ_MODIFIED = 3 */ -+ -+ -+enum FH_CMD { -+ FH_CMD_ENABLE = 1, -+ FH_CMD_DISABLE, -+ FH_CMD_ENABLE_USR_DEFINED, -+ FH_CMD_DISABLE_USR_DEFINED, -+ FH_CMD_INTERNAL_MAX_CMD, -+/* TODO: do we need these cmds ? -+ * FH_CMD_PLL_ENABLE, -+ * FH_CMD_PLL_DISABLE, -+ * FH_CMD_EXT_ALL_FULL_RANGE_CMD, -+ * FH_CMD_EXT_ALL_HALF_RANGE_CMD, -+ * FH_CMD_EXT_DISABLE_ALL_CMD, -+ * FH_CMD_EXT_DESIGNATED_PLL_FULL_RANGE_CMD, -+ * FH_CMD_EXT_DESIGNATED_PLL_AND_SETTING_CMD -+*/ -+}; -+ -+/* -+ * enum FH_OPCODE{ -+ * FH_OPCODE_ENABLE_WITH_ID = 1, -+ * FH_OPCODE_ENABLE_WITHOUT_ID, -+ * FH_OPCODE_DISABLE, -+ * }; -+*/ -+ -+enum FH_PLL_ID { -+ MT658X_FH_MINIMUMM_PLL = 0, -+ MT658X_FH_ARM_PLL = MT658X_FH_MINIMUMM_PLL, -+ MT658X_FH_MAIN_PLL = 1, -+ MT658X_FH_MEM_PLL = 2, -+ MT658X_FH_MSDC_PLL = 3, -+ MT658X_FH_MM_PLL = 4, /* MT658X_FH_TVD_PLL = 4, */ -+ MT658X_FH_VENC_PLL = 5, /* MT658X_FH_LVDS_PLL = 5, */ -+ /* 8127 FHCTL MB */ -+ MT658X_FH_TVD_PLL = 6, /* MT658X_FH_TVD_PLL = 6, */ -+ MT658X_FH_MAXIMUMM_PLL = MT658X_FH_TVD_PLL, -+ /* 8127 FHCTL ME */ -+ MT658X_FH_PLL_TOTAL_NUM -+}; -+ -+/* keep track the status of each PLL */ -+/* TODO: do we need another "uint mode" for Dynamic FH */ -+typedef struct { -+ unsigned int fh_status; -+ unsigned int pll_status; -+ unsigned int setting_id; -+ unsigned int curr_freq; -+ unsigned int user_defined; -+} fh_pll_t; -+ -+ -+/* Record the owner of enable freq hopping <==TBD */ -+struct freqhopping_pll { -+ union { -+ int mt_pll[MT_FHPLL_MAX]; -+ struct { -+ int mt_arm_fhpll; -+ int mt_main_fhpll; -+ int mt_mem_fhpll; -+ int mt_msdc_fhpll; -+ int mt_mm_fhpll; -+ int mt_venc_fhpll; -+ }; -+ }; -+}; -+ -+struct freqhopping_ssc { -+ unsigned int freq; -+ unsigned int dt; -+ unsigned int df; -+ unsigned int upbnd; -+ unsigned int lowbnd; -+ unsigned int dds; -+}; -+ -+struct freqhopping_ioctl { -+ unsigned int pll_id; -+ struct freqhopping_ssc ssc_setting; /* used only when user-define */ -+ int result; -+}; -+ -+int freqhopping_config(unsigned int pll_id, unsigned long vco_freq, unsigned int enable); -+void mt_freqhopping_init(void); -+void mt_freqhopping_pll_init(void); -+int mt_h2l_mempll(void); -+int mt_l2h_mempll(void); -+int mt_h2l_dvfs_mempll(void); -+int mt_l2h_dvfs_mempll(void); -+int mt_dfs_armpll(unsigned int current_freq, unsigned int target_freq); -+int mt_is_support_DFS_mode(void); -+void mt_fh_popod_save(void); -+void mt_fh_popod_restore(void); -+int mt_fh_dram_overclock(int clk); -+int mt_fh_get_dramc(void); -+unsigned int mt_get_emi_freq(void); -+ -+#endif /* !__MT_FREQHOPPING_H__ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h -new file mode 100644 -index 0000000000000..0c049db9aa977 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h -@@ -0,0 +1,37 @@ -+/* -+ * Copyright (c) 2015 MediaTek Inc. -+ * -+ * 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. -+ */ -+ -+#include -+ -+#define STA_POWER_DOWN 0 -+#define STA_POWER_ON 1 -+ -+/* -+ * 1. for CPU MTCMOS: CPU0, CPU1, CPU2, CPU3, DBG0, CPU4, CPU5, CPU6, CPU7, DBG1, CPUSYS1 -+ * 2. call spm_mtcmos_cpu_lock/unlock() before/after any operations -+ */ -+extern int spm_mtcmos_cpu_init(void); -+extern void spm_mtcmos_cpu_lock(unsigned long *flags); -+extern void spm_mtcmos_cpu_unlock(unsigned long *flags); -+extern int spm_mtcmos_ctrl_cpu(unsigned int cpu, int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu0(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu1(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu2(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu3(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu4(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu5(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu6(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu7(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpusys0(int state, int chkWfiBeforePdn); -+extern bool spm_cpusys0_can_power_down(void); -diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h -new file mode 100644 -index 0000000000000..28176b3cd9af1 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h -@@ -0,0 +1,40 @@ -+/* -+ * Copyright (c) 2015 MediaTek Inc. -+ * -+ * 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. -+ */ -+ -+#ifndef __MTK_BOOT_SHARE_PAGE_H__ -+#define __MTK_BOOT_SHARE_PAGE_H__ -+ -+#define BOOT_SHARE_BASE (0xC0002000) /* address in linux kernel */ -+#define BOOT_SHARE_SIZE (0x1000) /* page size 4K bytes */ -+ -+#define BOOT_SHARE_MAGIC (0x4545544D) /* MTEE */ -+ -+/* Memory map & defines for boot share page */ -+/* -+ * Note: -+ * 1. BOOT_SHARE_XXXXX_OFST is the address offset related to BOOT_SHARE_BASE -+ */ -+#define BOOT_SHARE_MAGIC1_OFST (0) -+#define BOOT_SHARE_MAGIC1_SIZE (4) -+ -+#define BOOT_SHARE_DEV_INFO_OFST (BOOT_SHARE_MAGIC1_OFST+BOOT_SHARE_MAGIC1_SIZE) -+#define BOOT_SHARE_DEV_INFO_SIZE (16) -+ -+#define BOOT_SHARE_HOTPLUG_OFST (1008) /* 16 bytes for hotplug/jump-reg */ -+#define BOOT_SHARE_HOTPLUG_SIZE (32) -+ -+#define BOOT_SHARE_MAGIC2_OFST (4092) -+#define BOOT_SHARE_MAGIC2_SIZE (4) -+ -+#endif /* __MTK_BOOT_SHARE_PAGE_H__ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h -new file mode 100644 -index 0000000000000..eefdaad4aaa5d ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h -@@ -0,0 +1,301 @@ -+/* -+ * Copyright (C) 2016 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. -+ */ -+ -+#ifndef _MT8127_THERMAL_H -+#define _MT8127_THERMAL_H -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "mt-plat/sync_write.h" -+#include -+ -+/* #include */ -+/* #include "../../../../../thermal/mt8127/inc/mt_gpufreq.h" */ -+ -+#if 1 -+extern void __iomem *thermal_base; -+extern void __iomem *auxadc_ts_base; -+extern void __iomem *pericfg_base; -+extern void __iomem *apmixed_ts_base; -+ -+extern int mtktscpu_limited_dmips; -+ -+void __attribute__ ((weak)) mt_gpufreq_thermal_protect(unsigned int limited_power) { -+} -+ -+unsigned int __attribute__ ((weak)) mt_gpufreq_get_cur_freq(void) { -+ return 0; -+} -+ -+u32 __attribute__ ((weak)) get_devinfo_with_index(u32 index) { -+ return 0; -+} -+ -+extern int IMM_GetOneChannelValue(int dwChannel, int data[4], int *rawdata); -+extern int IMM_IsAdcInitReady(void); -+extern int PMIC_IMM_GetOneChannelValue(int dwChannel, int deCount, int trimd); -+extern int thermal_phy_base; -+extern int auxadc_ts_phy_base; -+extern int apmixed_phy_base; -+extern int pericfg_phy_base; -+ -+/* extern int last_abb_t; */ -+/* extern int last_CPU2_t; */ -+extern int get_immediate_temp2_wrap(void); -+extern void mtkts_dump_cali_info(void); -+extern u32 get_devinfo_with_index(u32 index); -+extern int bts_cur_temp; -+ -+#define THERM_CTRL_BASE_2 thermal_base -+#define AUXADC_BASE_2 auxadc_ts_base -+#define PERICFG_BASE_2 pericfg_base -+#define APMIXED_BASE_2 apmixed_ts_base -+#endif -+ -+/******************************************************************************* -+ * AUXADC Register Definition -+ ******************************************************************************/ -+#define AUXADC_CON0_V (AUXADC_BASE_2 + 0x000) /* yes, 0x11001000 */ -+#define AUXADC_CON1_V (AUXADC_BASE_2 + 0x004) -+#define AUXADC_CON1_SET_V (AUXADC_BASE_2 + 0x008) -+#define AUXADC_CON1_CLR_V (AUXADC_BASE_2 + 0x00C) -+#define AUXADC_CON2_V (AUXADC_BASE_2 + 0x010) -+#define AUXADC_DAT0_V (AUXADC_BASE_2 + 0x014) -+#define AUXADC_DAT1_V (AUXADC_BASE_2 + 0x018) -+#define AUXADC_DAT2_V (AUXADC_BASE_2 + 0x01C) -+#define AUXADC_DAT3_V (AUXADC_BASE_2 + 0x020) -+#define AUXADC_DAT4_V (AUXADC_BASE_2 + 0x024) -+#define AUXADC_DAT5_V (AUXADC_BASE_2 + 0x028) -+#define AUXADC_DAT6_V (AUXADC_BASE_2 + 0x02C) -+#define AUXADC_DAT7_V (AUXADC_BASE_2 + 0x030) -+#define AUXADC_DAT8_V (AUXADC_BASE_2 + 0x034) -+#define AUXADC_DAT9_V (AUXADC_BASE_2 + 0x038) -+#define AUXADC_DAT10_V (AUXADC_BASE_2 + 0x03C) -+#define AUXADC_DAT11_V (AUXADC_BASE_2 + 0x040) -+#define AUXADC_MISC_V (AUXADC_BASE_2 + 0x094) -+#define AUXADC_CON0_P (auxadc_ts_phy_base + 0x000) -+#define AUXADC_CON1_P (auxadc_ts_phy_base + 0x004) -+#define AUXADC_CON1_SET_P (auxadc_ts_phy_base + 0x008) -+#define AUXADC_CON1_CLR_P (auxadc_ts_phy_base + 0x00C) -+#define AUXADC_CON2_P (auxadc_ts_phy_base + 0x010) -+#define AUXADC_DAT0_P (auxadc_ts_phy_base + 0x014) -+#define AUXADC_DAT1_P (auxadc_ts_phy_base + 0x018) -+#define AUXADC_DAT2_P (auxadc_ts_phy_base + 0x01C) -+#define AUXADC_DAT3_P (auxadc_ts_phy_base + 0x020) -+#define AUXADC_DAT4_P (auxadc_ts_phy_base + 0x024) -+#define AUXADC_DAT5_P (auxadc_ts_phy_base + 0x028) -+#define AUXADC_DAT6_P (auxadc_ts_phy_base + 0x02C) -+#define AUXADC_DAT7_P (auxadc_ts_phy_base + 0x030) -+#define AUXADC_DAT8_P (auxadc_ts_phy_base + 0x034) -+#define AUXADC_DAT9_P (auxadc_ts_phy_base + 0x038) -+#define AUXADC_DAT10_P (auxadc_ts_phy_base + 0x03C) -+#define AUXADC_DAT11_P (auxadc_ts_phy_base + 0x040) -+#define AUXADC_MISC_P (auxadc_ts_phy_base + 0x094) -+ -+/******************************************************************************* -+ * Peripheral Configuration Register Definition -+ ******************************************************************************/ -+#define PERI_GLOBALCON_RST0 (PERICFG_BASE_2 + 0x000) /* yes, 0x10003000 */ -+ -+/******************************************************************************* -+ * APMixedSys Configuration Register Definition -+ ******************************************************************************/ -+#define TS_CON0 (APMIXED_BASE_2 + 0x600) /* yes 0x10209000 */ -+#define TS_CON1 (APMIXED_BASE_2 + 0x604) -+/******************************************************************************* -+ * Thermal Controller Register Definition -+ ******************************************************************************/ -+#define TEMPMONCTL0 (THERM_CTRL_BASE_2 + 0x000) /* yes 0x1100B000 */ -+#define TEMPMONCTL1 (THERM_CTRL_BASE_2 + 0x004) -+#define TEMPMONCTL2 (THERM_CTRL_BASE_2 + 0x008) -+#define TEMPMONINT (THERM_CTRL_BASE_2 + 0x00C) -+#define TEMPMONINTSTS (THERM_CTRL_BASE_2 + 0x010) -+#define TEMPMONIDET0 (THERM_CTRL_BASE_2 + 0x014) -+#define TEMPMONIDET1 (THERM_CTRL_BASE_2 + 0x018) -+#define TEMPMONIDET2 (THERM_CTRL_BASE_2 + 0x01C) -+#define TEMPH2NTHRE (THERM_CTRL_BASE_2 + 0x024) -+#define TEMPHTHRE (THERM_CTRL_BASE_2 + 0x028) -+#define TEMPCTHRE (THERM_CTRL_BASE_2 + 0x02C) -+#define TEMPOFFSETH (THERM_CTRL_BASE_2 + 0x030) -+#define TEMPOFFSETL (THERM_CTRL_BASE_2 + 0x034) -+#define TEMPMSRCTL0 (THERM_CTRL_BASE_2 + 0x038) -+#define TEMPMSRCTL1 (THERM_CTRL_BASE_2 + 0x03C) -+#define TEMPAHBPOLL (THERM_CTRL_BASE_2 + 0x040) -+#define TEMPAHBTO (THERM_CTRL_BASE_2 + 0x044) -+#define TEMPADCPNP0 (THERM_CTRL_BASE_2 + 0x048) -+#define TEMPADCPNP1 (THERM_CTRL_BASE_2 + 0x04C) -+#define TEMPADCPNP2 (THERM_CTRL_BASE_2 + 0x050) -+#define TEMPADCPNP3 (THERM_CTRL_BASE_2 + 0x0B4) -+ -+#define TEMPADCMUX (THERM_CTRL_BASE_2 + 0x054) -+#define TEMPADCEXT (THERM_CTRL_BASE_2 + 0x058) -+#define TEMPADCEXT1 (THERM_CTRL_BASE_2 + 0x05C) -+#define TEMPADCEN (THERM_CTRL_BASE_2 + 0x060) -+#define TEMPPNPMUXADDR (THERM_CTRL_BASE_2 + 0x064) -+#define TEMPADCMUXADDR (THERM_CTRL_BASE_2 + 0x068) -+#define TEMPADCEXTADDR (THERM_CTRL_BASE_2 + 0x06C) -+#define TEMPADCEXT1ADDR (THERM_CTRL_BASE_2 + 0x070) -+#define TEMPADCENADDR (THERM_CTRL_BASE_2 + 0x074) -+#define TEMPADCVALIDADDR (THERM_CTRL_BASE_2 + 0x078) -+#define TEMPADCVOLTADDR (THERM_CTRL_BASE_2 + 0x07C) -+#define TEMPRDCTRL (THERM_CTRL_BASE_2 + 0x080) -+#define TEMPADCVALIDMASK (THERM_CTRL_BASE_2 + 0x084) -+#define TEMPADCVOLTAGESHIFT (THERM_CTRL_BASE_2 + 0x088) -+#define TEMPADCWRITECTRL (THERM_CTRL_BASE_2 + 0x08C) -+#define TEMPMSR0 (THERM_CTRL_BASE_2 + 0x090) -+#define TEMPMSR1 (THERM_CTRL_BASE_2 + 0x094) -+#define TEMPMSR2 (THERM_CTRL_BASE_2 + 0x098) -+#define TEMPMSR3 (THERM_CTRL_BASE_2 + 0x0B8) -+ -+#define TEMPIMMD0 (THERM_CTRL_BASE_2 + 0x0A0) -+#define TEMPIMMD1 (THERM_CTRL_BASE_2 + 0x0A4) -+#define TEMPIMMD2 (THERM_CTRL_BASE_2 + 0x0A8) -+ -+#define TEMPPROTCTL (THERM_CTRL_BASE_2 + 0x0C0) -+#define TEMPPROTTA (THERM_CTRL_BASE_2 + 0x0C4) -+#define TEMPPROTTB (THERM_CTRL_BASE_2 + 0x0C8) -+#define TEMPPROTTC (THERM_CTRL_BASE_2 + 0x0CC) -+ -+#define TEMPSPARE0 (THERM_CTRL_BASE_2 + 0x0F0) -+#define TEMPSPARE1 (THERM_CTRL_BASE_2 + 0x0F4) -+#define TEMPSPARE2 (THERM_CTRL_BASE_2 + 0x0F8) -+#define TEMPSPARE3 (THERM_CTRL_BASE_2 + 0x0FC) -+ -+#define PTPCORESEL (THERM_CTRL_BASE_2 + 0x400) -+#define THERMINTST (THERM_CTRL_BASE_2 + 0x404) -+#define PTPODINTST (THERM_CTRL_BASE_2 + 0x408) -+#define THSTAGE0ST (THERM_CTRL_BASE_2 + 0x40C) -+#define THSTAGE1ST (THERM_CTRL_BASE_2 + 0x410) -+#define THSTAGE2ST (THERM_CTRL_BASE_2 + 0x414) -+#define THAHBST0 (THERM_CTRL_BASE_2 + 0x418) -+#define THAHBST1 (THERM_CTRL_BASE_2 + 0x41C) /* Only for DE debug */ -+#define PTPSPARE0 (THERM_CTRL_BASE_2 + 0x420) -+#define PTPSPARE1 (THERM_CTRL_BASE_2 + 0x424) -+#define PTPSPARE2 (THERM_CTRL_BASE_2 + 0x428) -+#define PTPSPARE3 (THERM_CTRL_BASE_2 + 0x42C) -+#define THSLPEVEB (THERM_CTRL_BASE_2 + 0x430) -+ -+/******************************************************************************* -+ * Thermal Controller Register Mask Definition -+ ******************************************************************************/ -+#define THERMAL_ENABLE_SEN0 0x1 -+#define THERMAL_ENABLE_SEN1 0x2 -+#define THERMAL_ENABLE_SEN2 0x4 -+#define THERMAL_MONCTL0_MASK 0x00000007 -+ -+#define THERMAL_PUNT_MASK 0x00000FFF -+#define THERMAL_FSINTVL_MASK 0x03FF0000 -+#define THERMAL_SPINTVL_MASK 0x000003FF -+#define THERMAL_MON_INT_MASK 0x0007FFFF -+ -+#define THERMAL_MON_CINTSTS0 0x000001 -+#define THERMAL_MON_HINTSTS0 0x000002 -+#define THERMAL_MON_LOINTSTS0 0x000004 -+#define THERMAL_MON_HOINTSTS0 0x000008 -+#define THERMAL_MON_NHINTSTS0 0x000010 -+#define THERMAL_MON_CINTSTS1 0x000020 -+#define THERMAL_MON_HINTSTS1 0x000040 -+#define THERMAL_MON_LOINTSTS1 0x000080 -+#define THERMAL_MON_HOINTSTS1 0x000100 -+#define THERMAL_MON_NHINTSTS1 0x000200 -+#define THERMAL_MON_CINTSTS2 0x000400 -+#define THERMAL_MON_HINTSTS2 0x000800 -+#define THERMAL_MON_LOINTSTS2 0x001000 -+#define THERMAL_MON_HOINTSTS2 0x002000 -+#define THERMAL_MON_NHINTSTS2 0x004000 -+#define THERMAL_MON_TOINTSTS 0x008000 -+#define THERMAL_MON_IMMDINTSTS0 0x010000 -+#define THERMAL_MON_IMMDINTSTS1 0x020000 -+#define THERMAL_MON_IMMDINTSTS2 0x040000 -+#define THERMAL_MON_FILTINTSTS0 0x080000 -+#define THERMAL_MON_FILTINTSTS1 0x100000 -+#define THERMAL_MON_FILTINTSTS2 0x200000 -+ -+ -+#define THERMAL_tri_SPM_State0 0x20000000 -+#define THERMAL_tri_SPM_State1 0x40000000 -+#define THERMAL_tri_SPM_State2 0x80000000 -+ -+ -+#define THERMAL_MSRCTL0_MASK 0x00000007 -+#define THERMAL_MSRCTL1_MASK 0x00000038 -+#define THERMAL_MSRCTL2_MASK 0x000001C0 -+ -+/* extern int thermal_one_shot_handler(int times); */ -+ -+typedef enum { -+ THERMAL_SENSOR1 = 0, /* TS1 */ -+ THERMAL_SENSOR_NUM -+} thermal_sensor_name; -+ -+struct TS_PTPOD { -+ unsigned int ts_MTS; -+ unsigned int ts_BTS; -+}; -+ -+extern void get_thermal_slope_intercept(struct TS_PTPOD *ts_info); -+extern void set_taklking_flag(bool flag); -+extern int tscpu_get_cpu_temp(void); -+ -+/*5 thermal sensors*/ -+typedef enum { -+ MTK_THERMAL_SENSOR_TS1 = 0, -+ ATM_CPU_LIMIT, -+ ATM_GPU_LIMIT, -+ MTK_THERMAL_SENSOR_CPU_COUNT -+} MTK_THERMAL_SENSOR_CPU_ID_MET; -+ -+struct mtk_cpu_power_info { -+ unsigned int cpufreq_khz; -+ unsigned int cpufreq_ncpu; -+ unsigned int cpufreq_power; -+}; -+extern int mtk_cpufreq_register(struct mtk_cpu_power_info *freqs, int num); -+ -+extern int tscpu_get_cpu_temp_met(MTK_THERMAL_SENSOR_CPU_ID_MET id); -+ -+ -+typedef void (*met_thermalsampler_funcMET) (void); -+void mt_thermalsampler_registerCB(met_thermalsampler_funcMET pCB); -+ -+void tscpu_start_thermal(void); -+void tscpu_stop_thermal(void); -+void tscpu_cancel_thermal_timer(void); -+void tscpu_start_thermal_timer(void); -+int mtkts_AP_get_hw_temp(void); -+ -+extern int amddulthro_backoff(int level); -+/* extern int IMM_GetOneChannelValue(int dwChannel, int data[4], int *rawdata); */ -+/* extern int IMM_IsAdcInitReady(void); */ -+extern int get_immediate_temp2_wrap(void); -+extern void mtkts_dump_cali_info(void); -+extern unsigned int read_dram_temperature(void); -+extern int mtk_thermal_get_cpu_load_sum(void); -+ -+/********************************** -+ * Power table struct for thermal -+ **********************************/ -+struct mt_gpufreq_power_table_info { -+ unsigned int gpufreq_khz; -+ unsigned int gpufreq_volt; -+ unsigned int gpufreq_power; -+}; -+ -+extern int mtk_gpufreq_register(struct mt_gpufreq_power_table_info *freqs, int num); -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mt_sched.h b/drivers/misc/mediatek/include/mt-plat/mt_sched.h -new file mode 100644 -index 0000000000000..71206f0805482 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt_sched.h -@@ -0,0 +1,34 @@ -+/* -+* Copyright (C) 2016 MediaTek Inc. -+* -+* 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. -+* -+* 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 http://www.gnu.org/licenses/gpl-2.0.html for more details. -+*/ -+ -+#ifdef CONFIG_MTK_SCHED_RQAVG_US -+/* -+ * @cpu: cpu id -+ * @reset: reset the statistic start time after this time query -+ * @use_maxfreq: caculate cpu loading with max cpu max frequency -+ * return: cpu loading as percentage (0~100) -+ */ -+extern unsigned int sched_get_percpu_load(int cpu, bool reset, bool use_maxfreq); -+ -+/* -+ * return: heavy task(loading>90%) number in the system -+ */ -+extern unsigned int sched_get_nr_heavy_task(void); -+ -+/* -+ * @threshold: heavy task loading threshold (0~1023) -+ * return: heavy task(loading>threshold) number in the system -+ */ -+extern unsigned int sched_get_nr_heavy_task_by_threshold(unsigned int threshold); -+#endif /* CONFIG_MTK_SCHED_RQAVG_US */ -+ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_io.h b/drivers/misc/mediatek/include/mt-plat/mtk_io.h -new file mode 100644 -index 0000000000000..de17db505d3e5 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_io.h -@@ -0,0 +1,23 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef __MT_IO_H__ -+#define __MT_IO_H__ -+ -+/* only for arm64 */ -+#ifdef CONFIG_ARM64 -+#define IOMEM(a) ((void __force __iomem *)((a))) -+#endif -+ -+#endif /* !__MT_IO_H__ */ -+ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h b/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h -new file mode 100644 -index 0000000000000..d679c5a1ce738 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h -@@ -0,0 +1,62 @@ -+/* -+ * Copyright (C) 2016 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef __MTK_LPAE_H__ -+#define __MTK_LPAE_H__ -+#ifdef CONFIG_MTK_LM_MODE -+ -+#include -+ -+#define INTERAL_MAPPING_OFFSET (0x40000000) -+#define INTERAL_MAPPING_LIMIT (INTERAL_MAPPING_OFFSET + 0x80000000) -+ -+#define MT_OVERFLOW_ADDR_START 0x100000000ULL -+ -+unsigned int __attribute__((weak)) enable_4G(void) -+{ -+ return 0; -+} -+ -+/* For HW modules which support 33-bit address setting */ -+#define CROSS_OVERFLOW_ADDR_TRANSFER(phy_addr, size, ret) \ -+ do { \ -+ ret = 0; \ -+ if (enable_4G()) {\ -+ if (((phys_addr_t)phy_addr < MT_OVERFLOW_ADDR_START)\ -+ && (((phys_addr_t)phy_addr + size) >= MT_OVERFLOW_ADDR_START)) \ -+ ret = MT_OVERFLOW_ADDR_START - phy_addr; \ -+ } \ -+ } while (0) \ -+ -+/* For SPM and MD32 only in ROME */ -+#define MAPPING_DRAM_ACCESS_ADDR(phy_addr) \ -+ do { \ -+ if (enable_4G()) {\ -+ if (phy_addr >= INTERAL_MAPPING_OFFSET && phy_addr < INTERAL_MAPPING_LIMIT) \ -+ phy_addr += INTERAL_MAPPING_OFFSET; \ -+ } \ -+ } while (0)\ -+ -+#else /* !CONFIG_ARM_LPAE */ -+ -+#define CROSS_OVERFLOW_ADDR_TRANSFER(phy_addr, size, ret) -+#define MAPPING_DRAM_ACCESS_ADDR(phy_addr) -+#define MT_OVERFLOW_ADDR_START 0 -+ -+static inline unsigned int enable_4G(void) -+{ -+ return 0; -+} -+ -+#endif -+#endif /*!__MTK_LPAE_H__ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h b/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h -new file mode 100644 -index 0000000000000..7baafc4329bfc ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h -@@ -0,0 +1,42 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef _MTK_MDM_MONITOR_H -+#define _MTK_MDM_MONITOR_H -+ -+struct md_info { -+ char *attribute; -+ int value; -+ char *unit; -+ int invalid_value; -+ int index; -+}; -+ -+extern -+int mtk_mdm_get_md_info(struct md_info **p_inf, int *size); -+ -+extern -+int mtk_mdm_start_query(void); -+ -+extern -+int mtk_mdm_stop_query(void); -+ -+extern -+int mtk_mdm_set_signal_period(int second); -+ -+extern -+int mtk_mdm_set_md1_signal_period(int second); -+ -+extern -+int mtk_mdm_set_md2_signal_period(int second); -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h b/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h -new file mode 100644 -index 0000000000000..8f20f38b75d6c ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h -@@ -0,0 +1,28 @@ -+/* -+ * Copyright (C) 2016 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef __MTK_PLATFORM_DEBUG_H__ -+#define __MTK_PLATFORM_DEBUG_H__ -+ -+#ifdef CONFIG_MTK_PLAT_SRAM_FLAG -+/* plat_sram_flag */ -+extern int set_sram_flag_lastpc_valid(void); -+extern int set_sram_flag_dfd_valid(void); -+extern int set_sram_flag_etb_user(unsigned int etb_id, unsigned int user_id); -+#endif -+ -+#ifdef CONFIG_MTK_DFD_INTERNAL_DUMP -+extern int dfd_setup(void); -+#endif -+ -+#endif /* __MTK_PLATFORM_DEBUG_H__ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h b/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h -new file mode 100644 -index 0000000000000..3a94a1bbcd241 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h -@@ -0,0 +1,162 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef __MTK_RAM_CONSOLE_H__ -+#define __MTK_RAM_CONSOLE_H__ -+ -+#include -+#include -+ -+typedef enum { -+ AEE_FIQ_STEP_FIQ_ISR_BASE = 1, -+ AEE_FIQ_STEP_WDT_FIQ_INFO = 4, -+ AEE_FIQ_STEP_WDT_FIQ_STACK, -+ AEE_FIQ_STEP_WDT_FIQ_LOOP, -+ AEE_FIQ_STEP_WDT_FIQ_DONE, -+ AEE_FIQ_STEP_WDT_IRQ_INFO = 8, -+ AEE_FIQ_STEP_WDT_IRQ_KICK, -+ AEE_FIQ_STEP_WDT_IRQ_SMP_STOP, -+ AEE_FIQ_STEP_WDT_IRQ_TIME, -+ AEE_FIQ_STEP_WDT_IRQ_STACK, -+ AEE_FIQ_STEP_WDT_IRQ_GIC, -+ AEE_FIQ_STEP_WDT_IRQ_LOCALTIMER, -+ AEE_FIQ_STEP_WDT_IRQ_IDLE, -+ AEE_FIQ_STEP_WDT_IRQ_SCHED, -+ AEE_FIQ_STEP_WDT_IRQ_DONE, -+ AEE_FIQ_STEP_KE_WDT_INFO = 20, -+ AEE_FIQ_STEP_KE_WDT_PERCPU, -+ AEE_FIQ_STEP_KE_WDT_LOG, -+ AEE_FIQ_STEP_KE_SCHED_DEBUG, -+ AEE_FIQ_STEP_KE_EINT_DEBUG, -+ AEE_FIQ_STEP_KE_WDT_DONE, -+ AEE_FIQ_STEP_KE_IPANIC_DIE = 32, -+ AEE_FIQ_STEP_KE_IPANIC_START, -+ AEE_FIQ_STEP_KE_IPANIC_OOP_HEADER, -+ AEE_FIQ_STEP_KE_IPANIC_DETAIL, -+ AEE_FIQ_STEP_KE_IPANIC_CONSOLE, -+ AEE_FIQ_STEP_KE_IPANIC_USERSPACE, -+ AEE_FIQ_STEP_KE_IPANIC_ANDROID, -+ AEE_FIQ_STEP_KE_IPANIC_MMPROFILE, -+ AEE_FIQ_STEP_KE_IPANIC_HEADER, -+ AEE_FIQ_STEP_KE_IPANIC_DONE, -+ AEE_FIQ_STEP_KE_NESTED_PANIC = 64, -+} AEE_FIQ_STEP_NUM; -+ -+#ifdef CONFIG_MTK_RAM_CONSOLE -+extern int aee_rr_curr_fiq_step(void); -+extern void aee_rr_rec_fiq_step(u8 i); -+extern void aee_rr_rec_reboot_mode(u8 mode); -+extern void aee_rr_rec_kdump_params(void *params); -+extern void aee_rr_rec_last_irq_enter(int cpu, int irq, u64 j); -+extern void aee_rr_rec_last_irq_exit(int cpu, int irq, u64 j); -+extern void aee_rr_rec_last_sched_jiffies(int cpu, u64 j, const char *comm); -+extern void aee_sram_fiq_log(const char *msg); -+extern void ram_console_write(struct console *console, const char *s, unsigned int count); -+extern void aee_sram_fiq_save_bin(const char *buffer, size_t len); -+extern void aee_rr_rec_hotplug_footprint(int cpu, u8 fp); -+extern void aee_rr_rec_hotplug_cpu_event(u8 val); -+extern void aee_rr_rec_hotplug_cb_index(u8 val); -+extern void aee_rr_rec_hotplug_cb_fp(unsigned long val); -+#ifdef CONFIG_MTK_EMMC_SUPPORT -+extern void last_kmsg_store_to_emmc(void); -+#endif -+ -+#else -+static inline void aee_rr_rec_hotplug_footprint(int cpu, u8 fp) -+{ -+} -+static inline void aee_rr_rec_hotplug_cpu_event(u8 val) -+{ -+} -+static inline void aee_rr_rec_hotplug_cb_index(u8 val) -+{ -+} -+static inline void aee_rr_rec_hotplug_cb_fp(unsigned long val) -+{ -+} -+static inline int aee_rr_curr_fiq_step(void) -+{ -+ return 0; -+} -+ -+static inline void aee_rr_rec_fiq_step(u8 i) -+{ -+} -+ -+static inline unsigned int aee_rr_curr_exp_type(void) -+{ -+ return 0; -+} -+ -+static inline void aee_rr_rec_exp_type(unsigned int type) -+{ -+} -+ -+static inline void aee_rr_rec_reboot_mode(u8 mode) -+{ -+} -+ -+static inline void aee_rr_rec_kdump_params(void *params) -+{ -+} -+ -+static inline void aee_rr_rec_last_irq_enter(int cpu, int irq, u64 j) -+{ -+} -+ -+static inline void aee_rr_rec_last_irq_exit(int cpu, int irq, u64 j) -+{ -+} -+ -+static inline void aee_rr_rec_last_sched_jiffies(int cpu, u64 j, const char *comm) -+{ -+} -+ -+static inline void aee_sram_fiq_log(const char *msg) -+{ -+} -+ -+static inline void ram_console_write(struct console *console, const char *s, unsigned int count) -+{ -+} -+ -+static inline void aee_sram_fiq_save_bin(unsigned char *buffer, size_t len) -+{ -+} -+ -+#ifdef CONFIG_MTK_EMMC_SUPPORT -+static inline void last_kmsg_store_to_emmc(void) -+{ -+} -+#endif -+ -+#endif /* CONFIG_MTK_RAM_CONSOLE */ -+ -+#ifdef CONFIG_MTK_AEE_IPANIC -+extern int ipanic_kmsg_write(unsigned int part, const char *buf, size_t size); -+extern int ipanic_kmsg_get_next(int *count, u64 *id, enum pstore_type_id *type, struct timespec *time, -+ char **buf, struct pstore_info *psi); -+#else -+static inline int ipanic_kmsg_write(unsigned int part, const char *buf, size_t size) -+{ -+ return 0; -+} -+ -+static inline int ipanic_kmsg_get_next(int *count, u64 *id, enum pstore_type_id *type, struct timespec *time, -+ char **buf, struct pstore_info *psi) -+{ -+ return 0; -+} -+#endif /* CONFIG_MTK_AEE_IPANIC */ -+ -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h b/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h -new file mode 100644 -index 0000000000000..2181e99895934 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h -@@ -0,0 +1,85 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef MTK_RTC_H -+#define MTK_RTC_H -+ -+#include -+#include -+#include -+ -+typedef enum { -+ RTC_GPIO_USER_WIFI = 8, -+ RTC_GPIO_USER_GPS = 9, -+ RTC_GPIO_USER_BT = 10, -+ RTC_GPIO_USER_FM = 11, -+ RTC_GPIO_USER_PMIC = 12, -+} rtc_gpio_user_t; -+ -+#ifdef CONFIG_MTK_RTC -+ -+/* -+ * NOTE: -+ * 1. RTC_GPIO always exports 32K enabled by some user even if the phone is powered off -+ */ -+ -+extern unsigned long rtc_read_hw_time(void); -+extern void rtc_gpio_enable_32k(rtc_gpio_user_t user); -+extern void rtc_gpio_disable_32k(rtc_gpio_user_t user); -+extern bool rtc_gpio_32k_status(void); -+ -+/* for AUDIOPLL (deprecated) */ -+extern void rtc_enable_abb_32k(void); -+extern void rtc_disable_abb_32k(void); -+ -+/* NOTE: used in Sleep driver to workaround Vrtc-Vore level shifter issue */ -+extern void rtc_enable_writeif(void); -+extern void rtc_disable_writeif(void); -+ -+extern void rtc_mark_recovery(void); -+#if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING) -+extern void rtc_mark_kpoc(void); -+#endif/*if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING)*/ -+extern void rtc_mark_fast(void); -+extern u16 rtc_rdwr_uart_bits(u16 *val); -+extern void rtc_bbpu_power_down(void); -+extern void rtc_read_pwron_alarm(struct rtc_wkalrm *alm); -+extern int get_rtc_spare_fg_value(void); -+extern int set_rtc_spare_fg_value(int val); -+extern void rtc_irq_handler(void); -+extern bool crystal_exist_status(void); -+extern void mt_power_off(void); -+#else/*ifdef CONFIG_MTK_RTC*/ -+#define rtc_read_hw_time() ({ 0; }) -+#define rtc_gpio_enable_32k(user) do {} while (0) -+#define rtc_gpio_disable_32k(user) do {} while (0) -+#define rtc_gpio_32k_status() do {} while (0) -+#define rtc_enable_abb_32k() do {} while (0) -+#define rtc_disable_abb_32k() do {} while (0) -+#define rtc_enable_writeif() do {} while (0) -+#define rtc_disable_writeif() do {} while (0) -+#define rtc_mark_recovery() do {} while (0) -+#if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING) -+#define rtc_mark_kpoc() do {} while (0) -+#endif/*if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING)*/ -+#define rtc_mark_fast() do {} while (0) -+#define rtc_rdwr_uart_bits(val) ({ 0; }) -+#define rtc_bbpu_power_down() do {} while (0) -+#define rtc_read_pwron_alarm(alm) do {} while (0) -+#define get_rtc_spare_fg_value() ({ 0; }) -+#define set_rtc_spare_fg_value(val) ({ 0; }) -+#define rtc_irq_handler() do {} while (0) -+#define crystal_exist_status() do {} while (0) -+__weak void mt_power_off(void); -+#endif/*ifdef CONFIG_MTK_RTC*/ -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h -new file mode 100644 -index 0000000000000..eac6bc713c985 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h -@@ -0,0 +1,69 @@ -+/* -+ * Copyright (c) 2009 Travis Geiselbrecht -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining -+ * a copy of this software and associated documentation files -+ * (the "Software"), to deal in the Software without restriction, -+ * including without limitation the rights to use, copy, modify, merge, -+ * publish, distribute, sublicense, and/or sell copies of the Software, -+ * and to permit persons to whom the Software is furnished to do so, -+ * subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#ifndef _MTK_THERMAL_EXT_CONTROL_H -+#define _MTK_THERMAL_EXT_CONTROL_H -+ -+#define THERMAL_MD32_IPI_MSG_BASE 0x1F00 -+#define THERMAL_AP_IPI_MSG_BASE 0x2F00 -+ -+typedef enum { -+ THERMAL_AP_IPI_MSG_SET_TZ_THRESHOLD = THERMAL_AP_IPI_MSG_BASE, -+ THERMAL_AP_IPI_MSG_MD32_START, -+ -+ THERMAL_MD32_IPI_MSG_READY = THERMAL_MD32_IPI_MSG_BASE, -+ THERMAL_MD32_IPI_MSG_MD32_START_ACK, -+ THERMAL_MD32_IPI_MSG_REACH_THRESHOLD, -+} thermal_ipi_msg_id; -+ -+typedef enum { -+/* MTK_THERMAL_EXT_SENSOR_CPU = 0, */ -+ MTK_THERMAL_EXT_SENSOR_ABB = 0, -+ MTK_THERMAL_EXT_SENSOR_PMIC, -+ MTK_THERMAL_EXT_SENSOR_BATTERY, -+ MTK_THERMAL_EXT_SENSOR_COUNT -+} MTK_THERMAL_EXT_SENSOR_ID; -+ -+typedef struct { -+ int id; /* id of this tz */ -+ int polling_delay; /* polling delay of this tz */ -+ long high_trip_point; /* high threshold of this tz */ -+ long low_trip_point; /* low threshold of this tz */ -+} thermal_zone_data; -+ -+typedef struct { -+ int id; /* id of this tz */ -+ long high_trip_point; /* high threshold of this tz */ -+ long low_trip_point; /* low threshold of this tz */ -+ long temperature; /* Current temperature gotten from TS */ -+} thermal_zone_status; -+ -+typedef struct { -+ short id; -+ union { -+ thermal_zone_data tz; -+ thermal_zone_status tz_status; -+ } data; -+} thermal_ipi_msg; -+ -+#endif /* _MTK_THERMAL_EXT_CONTROL_H */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h -new file mode 100644 -index 0000000000000..7903b49dc419c ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h -@@ -0,0 +1,102 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef _MTK_THERMAL_MONITOR_H -+#define _MTK_THERMAL_MONITOR_H -+ -+#include -+ -+/* -+ * MTK_THERMAL_WRAPPER_BYPASS = 1 (use original Linux Thermal API) -+ * MTK_THERMAL_WRAPPER_BYPASS = 0 (use MTK Thermal API Monitor) -+ */ -+#define MTK_THERMAL_WRAPPER_BYPASS 0 -+ -+#if MTK_THERMAL_WRAPPER_BYPASS -+/* Original LTF API */ -+#define mtk_thermal_zone_device_register thermal_zone_device_register -+#define mtk_thermal_zone_device_unregister thermal_zone_device_unregister -+#define mtk_thermal_cooling_device_unregister thermal_cooling_device_unregister -+#define mtk_thermal_cooling_device_register thermal_cooling_device_register -+#define mtk_thermal_zone_bind_cooling_device thermal_zone_bind_cooling_device -+ -+#else -+ -+struct thermal_cooling_device_ops_extra { -+ int (*set_cur_temp)(struct thermal_cooling_device *, unsigned long); -+}; -+ -+extern -+struct thermal_zone_device *mtk_thermal_zone_device_register_wrapper -+(char *type, int trips, void *devdata, const struct thermal_zone_device_ops *ops, -+int tc1, int tc2, int passive_delay, int polling_delay); -+ -+extern -+void mtk_thermal_zone_device_unregister_wrapper(struct thermal_zone_device *tz); -+ -+extern -+struct thermal_cooling_device *mtk_thermal_cooling_device_register_wrapper -+(char *type, void *devdata, const struct thermal_cooling_device_ops *ops); -+ -+extern -+struct thermal_cooling_device *mtk_thermal_cooling_device_register_wrapper_extra -+(char *type, void *devdata, const struct thermal_cooling_device_ops *ops, -+const struct thermal_cooling_device_ops_extra *ops_ext); -+ -+extern -+int mtk_thermal_cooling_device_add_exit_point -+(struct thermal_cooling_device *cdev, int exit_point); -+ -+extern -+void mtk_thermal_cooling_device_unregister_wrapper(struct thermal_cooling_device *cdev); -+ -+extern int mtk_thermal_zone_bind_cooling_device_wrapper -+(struct thermal_zone_device *tz, int trip, struct thermal_cooling_device *cdev); -+ -+extern int mtk_thermal_zone_bind_trigger_trip(struct thermal_zone_device *tz, int trip, int mode); -+#define mtk_thermal_zone_device_register mtk_thermal_zone_device_register_wrapper -+#define mtk_thermal_zone_device_unregister mtk_thermal_zone_device_unregister_wrapper -+#define mtk_thermal_cooling_device_unregister mtk_thermal_cooling_device_unregister_wrapper -+#define mtk_thermal_cooling_device_register mtk_thermal_cooling_device_register_wrapper -+#define mtk_thermal_zone_bind_cooling_device mtk_thermal_zone_bind_cooling_device_wrapper -+ -+#endif -+ -+typedef enum { -+ MTK_THERMAL_SENSOR_CPU = 0, -+ MTK_THERMAL_SENSOR_ABB, -+ MTK_THERMAL_SENSOR_PMIC, -+ MTK_THERMAL_SENSOR_BATTERY, -+ MTK_THERMAL_SENSOR_MD1, -+ MTK_THERMAL_SENSOR_MD2, -+ MTK_THERMAL_SENSOR_WIFI, -+ MTK_THERMAL_SENSOR_BATTERY2, -+ MTK_THERMAL_SENSOR_BUCK, -+ MTK_THERMAL_SENSOR_AP, -+ MTK_THERMAL_SENSOR_PCB1, -+ MTK_THERMAL_SENSOR_PCB2, -+ MTK_THERMAL_SENSOR_SKIN, -+ MTK_THERMAL_SENSOR_XTAL, -+ MTK_THERMAL_SENSOR_MD_PA, -+ -+ MTK_THERMAL_SENSOR_COUNT -+} MTK_THERMAL_SENSOR_ID; -+ -+extern int mtk_thermal_get_temp(MTK_THERMAL_SENSOR_ID id); -+extern struct proc_dir_entry *mtk_thermal_get_proc_drv_therm_dir_entry(void); -+ -+/* This API function is implemented in mediatek/kernel/drivers/leds/leds.c */ -+extern int setMaxbrightness(int max_level, int enable); -+ -+extern void machine_power_off(void); -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h -new file mode 100644 -index 0000000000000..305574031196a ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h -@@ -0,0 +1,114 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef _MTK_THERMAL_PLATFORM_H -+#define _MTK_THERMAL_PLATFORM_H -+ -+#include -+#include -+ -+extern -+int mtk_thermal_get_cpu_info(int *nocores, int **cpufreq, int **cpuloading); -+ -+extern -+int mtk_thermal_get_gpu_info(int *nocores, int **gpufreq, int **gpuloading); -+ -+extern -+int mtk_thermal_get_batt_info(int *batt_voltage, int *batt_current, int *batt_temp); -+ -+extern -+int mtk_thermal_get_extra_info(int *no_extra_attr, -+ char ***attr_names, int **attr_values, char ***attr_unit); -+ -+extern -+int mtk_thermal_force_get_batt_temp(void); -+ -+ -+enum { -+ MTK_THERMAL_SCEN_CALL = 0x1 -+}; -+ -+extern -+unsigned int mtk_thermal_set_user_scenarios(unsigned int mask); -+ -+extern -+unsigned int mtk_thermal_clear_user_scenarios(unsigned int mask); -+ -+ -+#if defined(CONFIG_MTK_SMART_BATTERY) -+/* global variable from battery driver... */ -+extern kal_bool gFG_Is_Charging; -+#endif -+ -+extern int force_get_tbat(void); -+#endif /* _MTK_THERMAL_PLATFORM_H */ -+ -+ -+typedef enum { -+ TA_DAEMON_CMD_GET_INIT_FLAG = 0, -+ TA_DAEMON_CMD_SET_DAEMON_PID, -+ TA_DAEMON_CMD_NOTIFY_DAEMON, -+ TA_DAEMON_CMD_NOTIFY_DAEMON_CATMINIT, -+ TA_DAEMON_CMD_SET_TTJ, -+ TA_DAEMON_CMD_GET_TPCB, -+ -+ TA_DAEMON_CMD_TO_KERNEL_NUMBER -+} TA_DAEMON_CTRL_CMD_TO_KERNEL; /*must sync userspace/kernel: TA_DAEMON_CTRL_CMD_FROM_USER*/ -+ -+#define TAD_NL_MSG_T_HDR_LEN 12 -+#define TAD_NL_MSG_MAX_LEN 2048 -+ -+struct tad_nl_msg_t { -+ unsigned int tad_cmd; -+ unsigned int tad_data_len; -+ unsigned int tad_ret_data_len; -+ char tad_data[TAD_NL_MSG_MAX_LEN]; -+}; -+ -+enum { -+ TA_CATMPLUS = 1, -+ TA_CONTINUOUS = 2, -+ TA_CATMPLUS_TTJ = 3 -+}; -+ -+ -+struct cATM_params_t { -+ int CATM_ON; -+ int K_TT; -+ int K_SUM_TT_LOW; -+ int K_SUM_TT_HIGH; -+ int MIN_SUM_TT; -+ int MAX_SUM_TT; -+ int MIN_TTJ; -+ int CATMP_STEADY_TTJ_DELTA; -+}; -+struct continuetm_params_t { -+ int STEADY_TARGET_TJ; -+ int MAX_TARGET_TJ; -+ int TRIP_TPCB; -+ int STEADY_TARGET_TPCB; -+}; -+ -+ -+struct CATM_T { -+ struct cATM_params_t t_catm_par; -+ struct continuetm_params_t t_continuetm_par; -+}; -+extern struct CATM_T thermal_atm_t; -+int wakeup_ta_algo(int flow_state); -+int ta_get_ttj(void); -+ -+extern int mtk_thermal_get_tpcb_target(void); -+extern int tsatm_thermal_get_catm_type(void); -+ -+ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h -new file mode 100644 -index 0000000000000..1c23a9f4a862e ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h -@@ -0,0 +1,47 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#undef TRACE_SYSTEM -+#define TRACE_SYSTEM thermal -+ -+#if !defined(_MTK_THERMAL_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) -+#define _MTK_THERMAL_TRACE_H -+ -+#include -+ -+TRACE_EVENT(cooling_device_state, -+ TP_PROTO(int device, unsigned long state), -+ TP_ARGS(device, state), TP_STRUCT__entry(__field(int, device) -+ __field(unsigned long, state) -+ ), -+ TP_fast_assign(__entry->device = device; -+ __entry->state = state;), -+ TP_printk("cooling_device=%d, state=%lu\n", __entry->device, __entry->state) -+); -+ -+TRACE_EVENT(thermal_zone_state, -+ TP_PROTO(int device, int state), -+ TP_ARGS(device, state), TP_STRUCT__entry(__field(int, device) -+ __field(int, state) -+ ), -+ TP_fast_assign(__entry->device = device; -+ __entry->state = state;), -+ TP_printk("thermal_zone=%d, state=%d\n", __entry->device, __entry->state) -+); -+#endif /* _MTK_THERMAL_TRACE_H */ -+ -+/* This part must be outside protection */ -+#undef TRACE_INCLUDE_PATH -+#define TRACE_INCLUDE_PATH . -+#define TRACE_INCLUDE_FILE mach/mtk_thermal_trace -+#include -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h -new file mode 100644 -index 0000000000000..dfcef3d952fc7 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h -@@ -0,0 +1,241 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef _TYPEDEFS_H -+#define _TYPEDEFS_H -+ -+#include -+ -+/* --------------------------------------------------------------------------- */ -+/* Basic Type Definitions */ -+/* --------------------------------------------------------------------------- */ -+ -+typedef volatile unsigned char *P_kal_uint8; -+typedef volatile unsigned short *P_kal_uint16; -+typedef volatile unsigned int *P_kal_uint32; -+ -+typedef long LONG; -+typedef unsigned char UBYTE; -+typedef short SHORT; -+ -+typedef signed char kal_int8; -+typedef signed short kal_int16; -+typedef signed int kal_int32; -+typedef long long kal_int64; -+typedef unsigned char kal_uint8; -+typedef unsigned short kal_uint16; -+typedef unsigned int kal_uint32; -+typedef unsigned long long kal_uint64; -+typedef char kal_char; -+ -+typedef unsigned int *UINT32P; -+typedef volatile unsigned short *UINT16P; -+typedef volatile unsigned char *UINT8P; -+typedef unsigned char *U8P; -+ -+typedef volatile unsigned char *P_U8; -+typedef volatile signed char *P_S8; -+typedef volatile unsigned short *P_U16; -+typedef volatile signed short *P_S16; -+typedef volatile unsigned int *P_U32; -+typedef volatile signed int *P_S32; -+typedef unsigned long long *P_U64; -+typedef signed long long *P_S64; -+ -+typedef unsigned char U8; -+typedef signed char S8; -+typedef unsigned short U16; -+typedef signed short S16; -+typedef unsigned int U32; -+typedef signed int S32; -+typedef unsigned long long U64; -+typedef signed long long S64; -+/* typedef unsigned char bool; */ -+ -+typedef unsigned char UINT8; -+typedef unsigned short UINT16; -+typedef unsigned int UINT32; -+typedef unsigned short USHORT; -+typedef signed char INT8; -+typedef signed short INT16; -+typedef signed int INT32; -+typedef unsigned int DWORD; -+typedef void VOID; -+typedef unsigned char BYTE; -+typedef float FLOAT; -+ -+typedef char *LPCSTR; -+typedef short *LPWSTR; -+ -+ -+/* --------------------------------------------------------------------------- */ -+/* Constants */ -+/* --------------------------------------------------------------------------- */ -+ -+#ifndef FALSE -+#define FALSE (0) -+#endif -+ -+#ifndef TRUE -+#define TRUE (1) -+#endif -+ -+#ifndef NULL -+#define NULL (0) -+#endif -+ -+/* enum boolean {false, true}; */ -+enum { RX, TX, NONE }; -+ -+#ifndef BOOL -+typedef unsigned char BOOL; -+#endif -+ -+#ifndef BATTERY_BOOL -+#define BATTERY_BOOL -+typedef enum { -+ KAL_FALSE = 0, -+ KAL_TRUE = 1, -+} kal_bool; -+#endif -+ -+/* --------------------------------------------------------------------------- */ -+/* Type Casting */ -+/* --------------------------------------------------------------------------- */ -+ -+#define AS_INT32(x) (*(INT32 *)((void *)x)) -+#define AS_INT16(x) (*(INT16 *)((void *)x)) -+#define AS_INT8(x) (*(INT8 *)((void *)x)) -+ -+#define AS_UINT32(x) (*(UINT32 *)((void *)x)) -+#define AS_UINT16(x) (*(UINT16 *)((void *)x)) -+#define AS_UINT8(x) (*(UINT8 *)((void *)x)) -+ -+ -+/* --------------------------------------------------------------------------- */ -+/* Register Manipulations */ -+/* --------------------------------------------------------------------------- */ -+ -+#define READ_REGISTER_UINT32(reg) \ -+ (*(volatile UINT32 * const)(reg)) -+ -+#define WRITE_REGISTER_UINT32(reg, val) \ -+ ((*(volatile UINT32 * const)(reg)) = (val)) -+ -+#define READ_REGISTER_UINT16(reg) \ -+ ((*(volatile UINT16 * const)(reg))) -+ -+#define WRITE_REGISTER_UINT16(reg, val) \ -+ ((*(volatile UINT16 * const)(reg)) = (val)) -+ -+#define READ_REGISTER_UINT8(reg) \ -+ ((*(volatile UINT8 * const)(reg))) -+ -+#define WRITE_REGISTER_UINT8(reg, val) \ -+ ((*(volatile UINT8 * const)(reg)) = (val)) -+ -+#define INREG8(x) READ_REGISTER_UINT8((UINT8 *)((void *)(x))) -+#define OUTREG8(x, y) WRITE_REGISTER_UINT8((UINT8 *)((void *)(x)), (UINT8)(y)) -+#define SETREG8(x, y) OUTREG8(x, INREG8(x)|(y)) -+#define CLRREG8(x, y) OUTREG8(x, INREG8(x)&~(y)) -+#define MASKREG8(x, y, z) OUTREG8(x, (INREG8(x)&~(y))|(z)) -+ -+#define INREG16(x) READ_REGISTER_UINT16((UINT16 *)((void *)(x))) -+#define OUTREG16(x, y) WRITE_REGISTER_UINT16((UINT16 *)((void *)(x)), (UINT16)(y)) -+#define SETREG16(x, y) OUTREG16(x, INREG16(x)|(y)) -+#define CLRREG16(x, y) OUTREG16(x, INREG16(x)&~(y)) -+#define MASKREG16(x, y, z) OUTREG16(x, (INREG16(x)&~(y))|(z)) -+ -+#define INREG32(x) READ_REGISTER_UINT32((UINT32 *)((void *)(x))) -+#define OUTREG32(x, y) WRITE_REGISTER_UINT32((UINT32 *)((void *)(x)), (UINT32)(y)) -+#define SETREG32(x, y) OUTREG32(x, INREG32(x)|(y)) -+#define CLRREG32(x, y) OUTREG32(x, INREG32(x)&~(y)) -+#define MASKREG32(x, y, z) OUTREG32(x, (INREG32(x)&~(y))|(z)) -+ -+ -+#define DRV_Reg8(addr) INREG8(addr) -+#define DRV_WriteReg8(addr, data) OUTREG8(addr, data) -+#define DRV_SetReg8(addr, data) SETREG8(addr, data) -+#define DRV_ClrReg8(addr, data) CLRREG8(addr, data) -+ -+#define DRV_Reg16(addr) INREG16(addr) -+#define DRV_WriteReg16(addr, data) OUTREG16(addr, data) -+#define DRV_SetReg16(addr, data) SETREG16(addr, data) -+#define DRV_ClrReg16(addr, data) CLRREG16(addr, data) -+ -+#define DRV_Reg32(addr) INREG32(addr) -+#define DRV_WriteReg32(addr, data) OUTREG32(addr, data) -+#define DRV_SetReg32(addr, data) SETREG32(addr, data) -+#define DRV_ClrReg32(addr, data) CLRREG32(addr, data) -+ -+/* !!! DEPRECATED, WILL BE REMOVED LATER !!! */ -+#define DRV_Reg(addr) DRV_Reg16(addr) -+#define DRV_WriteReg(addr, data) DRV_WriteReg16(addr, data) -+#define DRV_SetReg(addr, data) DRV_SetReg16(addr, data) -+#define DRV_ClrReg(addr, data) DRV_ClrReg16(addr, data) -+ -+ -+/* --------------------------------------------------------------------------- */ -+/* Compiler Time Deduction Macros */ -+/* --------------------------------------------------------------------------- */ -+ -+ -+ -+/* --------------------------------------------------------------------------- */ -+/* Assertions */ -+/* --------------------------------------------------------------------------- */ -+ -+/* -+*#ifndef ASSERT -+*#define ASSERT(expr) BUG_ON(!(expr)) -+*#endif -+* -+*#ifndef NOT_IMPLEMENTED -+*#define NOT_IMPLEMENTED() BUG_ON(1) -+*#endif -+*/ -+#define STATIC_ASSERT(pred) STATIC_ASSERT_X(pred, __LINE__) -+#define STATIC_ASSERT_X(pred, line) STATIC_ASSERT_XX(pred, line) -+#define STATIC_ASSERT_XX(pred, line) \ -+extern char assertion_failed_at_##line[(pred) ? 1 : -1] -+ -+/* --------------------------------------------------------------------------- */ -+/* Resolve Compiler Warnings */ -+/* --------------------------------------------------------------------------- */ -+ -+#define NOT_REFERENCED(x) { (x) = (x); } -+ -+ -+/* --------------------------------------------------------------------------- */ -+/* Utilities */ -+/* --------------------------------------------------------------------------- */ -+ -+#define MAXIMUM(A, B) (((A) > (B))?(A):(B)) -+#define MINIMUM(A, B) (((A) < (B))?(A):(B)) -+ -+#define ARY_SIZE(x) (sizeof((x)) / sizeof((x[0]))) -+#define DVT_DELAYMACRO(u4Num) \ -+{ \ -+ UINT32 u4Count = 0; \ -+ for (u4Count = 0; u4Count < u4Num; u4Count++) \ -+ ; \ -+} \ -+ -+#define A68351B 0 -+#define B68351B 1 -+#define B68351D 2 -+#define B68351E 3 -+#define UNKNOWN_IC_VERSION 0xFF -+ -+ -+#endif /* _TYPEDEFS_H */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h b/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h -new file mode 100644 -index 0000000000000..0a4fda1916540 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h -@@ -0,0 +1,185 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+/*! \file -+ * \brief Declaration of library functions -+ * -+ * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _MTK_WCN_CMB_STUB_H_ -+#define _MTK_WCN_CMB_STUB_H_ -+ -+#include -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* Audio GPIO naming style for 73/75/77 */ -+/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_0 1 */ -+/* Audio GPIO naming style for 89/8135 */ -+/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_1 1 */ -+/* Audio GPIO naming style for 6592 */ -+/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_2 1 */ -+/* Audio GPIO naming style for 6595 */ -+#define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_3 1 -+#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 1 -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum { -+ CMB_STUB_AIF_0 = 0, /* 0000: BT_PCM_OFF & FM analog (line in/out) */ -+ CMB_STUB_AIF_1 = 1, /* 0001: BT_PCM_ON & FM analog (in/out) */ -+ CMB_STUB_AIF_2 = 2, /* 0010: BT_PCM_OFF & FM digital (I2S) */ -+ CMB_STUB_AIF_3 = 3, /* 0011: BT_PCM_ON & FM digital (I2S) (invalid in 73evb & 1.2 phone configuration) */ -+ CMB_STUB_AIF_4 = 4, /* 0100: BT_I2S & FM disable in special projects, e.g. protea*/ -+ CMB_STUB_AIF_MAX = 5, -+} CMB_STUB_AIF_X; -+ -+/*COMBO_CHIP_AUDIO_PIN_CTRL*/ -+typedef enum { -+ CMB_STUB_AIF_CTRL_DIS = 0, -+ CMB_STUB_AIF_CTRL_EN = 1, -+ CMB_STUB_AIF_CTRL_MAX = 2, -+} CMB_STUB_AIF_CTRL; -+ -+typedef enum { -+ COMBO_FUNC_TYPE_BT = 0, -+ COMBO_FUNC_TYPE_FM = 1, -+ COMBO_FUNC_TYPE_GPS = 2, -+ COMBO_FUNC_TYPE_WIFI = 3, -+ COMBO_FUNC_TYPE_WMT = 4, -+ COMBO_FUNC_TYPE_STP = 5, -+ COMBO_FUNC_TYPE_NUM = 6 -+} COMBO_FUNC_TYPE; -+ -+typedef enum { -+ COMBO_IF_UART = 0, -+ COMBO_IF_MSDC = 1, -+ COMBO_IF_BTIF = 2, -+ COMBO_IF_MAX, -+} COMBO_IF; -+ -+typedef void (*wmt_bgf_eirq_cb) (void); -+typedef int (*wmt_aif_ctrl_cb) (CMB_STUB_AIF_X, CMB_STUB_AIF_CTRL); -+typedef void (*wmt_func_ctrl_cb) (unsigned int, unsigned int); -+typedef signed long (*wmt_thermal_query_cb) (void); -+typedef int (*wmt_deep_idle_ctrl_cb) (unsigned int); -+typedef int (*wmt_func_do_reset) (unsigned int); -+ -+/* for DVFS driver do 1v autok */ -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+typedef unsigned int (*wmt_get_drv_status)(unsigned int); -+#endif -+ -+typedef void (*msdc_sdio_irq_handler_t) (void *); /* external irq handler */ -+typedef void (*pm_callback_t) (pm_message_t state, void *data); -+ -+struct sdio_ops { -+ void (*sdio_request_eirq)(msdc_sdio_irq_handler_t irq_handler, void *data); -+ void (*sdio_enable_eirq)(void); -+ void (*sdio_disable_eirq)(void); -+ void (*sdio_register_pm)(pm_callback_t pm_cb, void *data); -+}; -+ -+typedef struct _CMB_STUB_CB_ { -+ unsigned int size; /* structure size */ -+ /*wmt_bgf_eirq_cb bgf_eirq_cb; *//* remove bgf_eirq_cb from stub. handle it in platform */ -+ wmt_aif_ctrl_cb aif_ctrl_cb; -+ wmt_func_ctrl_cb func_ctrl_cb; -+ wmt_thermal_query_cb thermal_query_cb; -+ wmt_deep_idle_ctrl_cb deep_idle_ctrl_cb; -+ wmt_func_do_reset wmt_do_reset_cb; -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+ wmt_get_drv_status get_drv_status_cb; -+#endif -+} CMB_STUB_CB, *P_CMB_STUB_CB; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+extern struct sdio_ops mt_sdio_ops[4]; -+ -+extern int mtk_wcn_cmb_stub_reg(P_CMB_STUB_CB p_stub_cb); -+extern int mtk_wcn_cmb_stub_unreg(void); -+ -+extern int mtk_wcn_cmb_stub_aif_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl); -+ -+static inline int mtk_wcn_cmb_stub_audio_ctrl(CMB_STUB_AIF_X state) -+{ -+/* return mtk_wcn_cmb_stub_aif_ctrl(state, 1); */ -+ return 0; -+} -+ -+extern int mt_combo_plt_enter_deep_idle(COMBO_IF src); -+extern int mt_combo_plt_exit_deep_idle(COMBO_IF src); -+ -+/* Use new mtk_wcn_stub APIs instead of old mt_combo ones for kernel to control -+ * function on/off. -+ */ -+extern void mtk_wcn_cmb_stub_func_ctrl(unsigned int type, unsigned int on); -+extern int mtk_wcn_cmb_stub_query_ctrl(void); -+extern int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on); -+extern int mtk_wcn_sdio_irq_flag_set(int falg); -+ -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+extern int mtk_wcn_cmb_stub_1vautok_for_dvfs(void); -+#endif -+ -+extern int mtk_wcn_wmt_chipid_query(void); -+extern void mtk_wcn_wmt_set_chipid(int chipid); -+ -+/* mtk_uart_pdn_enable -- request uart port enter/exit deep idle mode, this API is defined in uart driver -+ * -+ * @ port - uart port name, Eg: "ttyMT0", "ttyMT1", "ttyMT2" -+ * @ enable - "1", enable deep idle; "0", disable deep idle -+ * -+ * Return 0 if success, else -1 -+ */ -+extern unsigned int mtk_uart_pdn_enable(char *port, int enable); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _MTK_WCN_CMB_STUB_H_ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/rt-regmap.h b/drivers/misc/mediatek/include/mt-plat/rt-regmap.h -new file mode 100644 -index 0000000000000..9a45e23005cad ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/rt-regmap.h -@@ -0,0 +1,291 @@ -+/* drivers/misc/mediatek/include/mt-plat/rt-regmap.h -+ * Header of Richtek regmap with debugfs Driver -+ * -+ * Copyright (C) 2014 Richtek Technology Corp. -+ * Jeff Chang -+ * -+ * 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. -+ */ -+ -+#ifndef MISC_MEDIATEK_RT_REGMAP_H -+#define MISC_MEDIATEK_RT_REGMAP_H -+ -+#include -+#include -+ -+/* #define RT_REGMAP_VERSION "1.1.11_G" */ -+ -+enum rt_access_mode { -+ RT_1BYTE_MODE = 1, -+ RT_2BYTE_MODE = 2, -+ RT_4BYTE_MODE = 4, -+}; -+ -+/* start : the start address of group -+ * end : the end address of group -+ * mode : access mode (1,2,4 bytes) -+ */ -+struct rt_access_group { -+ u32 start; -+ u32 end; -+ enum rt_access_mode mode; -+}; -+ -+/* rt_reg_type -+ * RT_NORMAL : Write data without mask -+ * Read from cache -+ * RT_WBITS : Write data with mask -+ * Read from cache -+ * RT_VOLATILE : Write data to chip directly -+ * Read data from chip -+ * RT_RESERVE : Reserve registers (Write/Read as RT_NORMAL) -+ */ -+ -+#define RT_REG_TYPE_MASK (0x03) -+#define RT_NORMAL (0x00) -+#define RT_WBITS (0x01) -+#define RT_VOLATILE (0x02) -+#define RT_RESERVE (0x03) -+ -+/* RT_WR_ONCE : write once will check write data and cache data, -+ * if write data = cache data, data will not be writen. -+ */ -+#define RT_WR_ONCE (0x08) -+#define RT_NORMAL_WR_ONCE (RT_NORMAL|RT_WR_ONCE) -+#define RT_WBITS_WR_ONCE (RT_WBITS|RT_WR_ONCE) -+ -+enum rt_data_format { -+ RT_LITTLE_ENDIAN, -+ RT_BIG_ENDIAN, -+}; -+ -+/* rt_regmap_mode -+ * 0 0 0 0 0 0 0 0 -+ * | | | | | | -+ * | | | |__| byte_mode -+ * | |__| || -+ * | || Cache_mode -+ * | Block_mode -+ * Debug_mode -+ */ -+ -+#define RT_BYTE_MODE_MASK (0x01) -+/* 1 byte for each register*/ -+#define RT_SINGLE_BYTE (0 << 0) -+/* multi bytes for each regiseter*/ -+#define RT_MULTI_BYTE (1 << 0) -+ -+#define RT_CACHE_MODE_MASK (0x06) -+/* write to cache and chip synchronously */ -+#define RT_CACHE_WR_THROUGH (0 << 1) -+/* write to cache and chip asynchronously */ -+#define RT_CACHE_WR_BACK (1 << 1) -+/* disable cache */ -+#define RT_CACHE_DISABLE (2 << 1) -+ -+#define RT_IO_BLK_MODE_MASK (0x18) -+/* pass through all write function */ -+#define RT_IO_PASS_THROUGH (0 << 3) -+/* block all write function */ -+#define RT_IO_BLK_ALL (1 << 3) -+/* block cache write function */ -+#define RT_IO_BLK_CACHE (2 << 3) -+/* block chip write function */ -+#define RT_IO_BLK_CHIP (3 << 3) -+ -+#define DBG_MODE_MASK (0x20) -+/* create general debugfs for register map */ -+#define RT_DBG_GENERAL (0 << 5) -+/* create node for each regisetr map by register address*/ -+#define RT_DBG_SPECIAL (1 << 5) -+ -+ -+/* struct rt_register -+ * -+ * Ricktek register map structure for store mapping data -+ * @addr: register address. -+ * @name: register name. -+ * @size: register byte size. -+ * @reg_type: register R/W type ( RT_NORMAL, RT_WBITS, RT_VOLATILE, RT_RESERVE) -+ * @wbit_mask: register writeable bits mask; -+ * @cache_data: cache data for store cache value. -+ */ -+struct rt_register { -+ u32 addr; -+ const char *name; -+ unsigned int size; -+ unsigned char reg_type; -+ unsigned char *wbit_mask; -+ unsigned char *cache_data; -+}; -+ -+/* Declare a rt_register by RT_REG_DECL -+ * @_addr: regisetr address. -+ * @_reg_length: register data length. -+ * @_reg_type: register type (rt_reg_type). -+ * @_mask: register writealbe mask. -+ */ -+#define RT_REG_DECL(_addr, _reg_length, _reg_type, _mask_...) \ -+ static unsigned char rt_writable_mask_##_addr[_reg_length] = _mask_;\ -+ static struct rt_register rt_register_##_addr = { \ -+ .addr = _addr, \ -+ .size = _reg_length,\ -+ .reg_type = _reg_type,\ -+ .wbit_mask = rt_writable_mask_##_addr,\ -+ } -+ -+/* Declare a rt_register by RT_NAMED_REG_DECL -+ * @_name: a name for a rt_register. -+ */ -+#define RT_NAMED_REG_DECL(_addr, _name, _reg_length, _reg_type, _mask_...) \ -+ static unsigned char rt_writable_mask_##_addr[_reg_length] = _mask_;\ -+ static struct rt_register rt_register_##_addr = { \ -+ .addr = _addr, \ -+ .name = _name, \ -+ .size = _reg_length,\ -+ .reg_type = _reg_type,\ -+ .wbit_mask = rt_writable_mask_##_addr,\ -+ } -+ -+#define RT_REG(_addr) (&rt_register_##_addr) -+ -+/* rt_regmap_properties -+ * @name: the name of debug node. -+ * @aliases: alisis name of rt_regmap_device. -+ * @register_num: the number of rt_register_map registers. -+ * @rm: rt_regiseter_map pointer array. -+ * @group: register map access group. -+ * @rt_format: default is little endian. -+ * @rt_regmap_mode: rt_regmap_device mode. -+ * @io_log_en: enable/disable io log -+ */ -+struct rt_regmap_properties { -+ const char *name; -+ const char *aliases; -+ int register_num; -+ struct rt_register **rm; -+ struct rt_access_group *group; -+ enum rt_data_format rt_format; -+ unsigned char rt_regmap_mode; -+ unsigned char io_log_en:1; -+}; -+ -+/* A passing struct for rt_regmap_reg_read and rt_regmap_reg_write function -+ * reg: regmap addr. -+ * mask: mask for update bits. -+ * rt_data: register value. -+ */ -+struct rt_reg_data { -+ u32 reg; -+ u32 mask; -+ union { -+ u32 data_u32; -+ u16 data_u16; -+ u8 data_u8; -+ u8 data[4]; -+ } rt_data; -+}; -+ -+struct rt_regmap_device; -+ -+struct rt_debug_st { -+ void *info; -+ int id; -+}; -+ -+/* basic chip read/write function */ -+struct rt_regmap_fops { -+ int (*read_device)(void *client, u32 addr, int leng, void *dst); -+ int (*write_device)(void *client, u32 addr, int leng, const void *src); -+}; -+ -+/* with slave address */ -+extern struct rt_regmap_device* -+ rt_regmap_device_register_ex(struct rt_regmap_properties *props, -+ struct rt_regmap_fops *rops, -+ struct device *parent, -+ void *client, int slv_addr, void *drvdata); -+ -+static inline struct rt_regmap_device* -+ rt_regmap_device_register(struct rt_regmap_properties *props, -+ struct rt_regmap_fops *rops, -+ struct device *parent, -+ struct i2c_client *client, void *drvdata) -+{ -+ return rt_regmap_device_register_ex(props, rops, parent, -+ client, client->addr, drvdata); -+} -+ -+extern void rt_regmap_device_unregister(struct rt_regmap_device *rd); -+ -+extern int rt_regmap_cache_init(struct rt_regmap_device *rd); -+ -+extern int rt_regmap_cache_reload(struct rt_regmap_device *rd); -+ -+extern int rt_regmap_block_write(struct rt_regmap_device *rd, u32 reg, -+ int bytes, const void *rc); -+extern int rt_asyn_regmap_block_write(struct rt_regmap_device *rd, u32 reg, -+ int bytes, const void *rc); -+extern int rt_regmap_block_read(struct rt_regmap_device *rd, u32 reg, -+ int bytes, void *dst); -+ -+extern int _rt_regmap_reg_read(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd); -+extern int _rt_regmap_reg_write(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd); -+extern int _rt_asyn_regmap_reg_write(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd); -+extern int _rt_regmap_update_bits(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd); -+ -+static inline int rt_regmap_reg_read(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd, u32 reg) -+{ -+ rrd->reg = reg; -+ return _rt_regmap_reg_read(rd, rrd); -+}; -+ -+static inline int rt_regmap_reg_write(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd, u32 reg, const u32 data) -+{ -+ rrd->reg = reg; -+ rrd->rt_data.data_u32 = data; -+ return _rt_regmap_reg_write(rd, rrd); -+}; -+ -+static inline int rt_asyn_regmap_reg_write(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd, u32 reg, const u32 data) -+{ -+ rrd->reg = reg; -+ rrd->rt_data.data_u32 = data; -+ return _rt_asyn_regmap_reg_write(rd, rrd); -+}; -+ -+static inline int rt_regmap_update_bits(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd, u32 reg, u32 mask, u32 data) -+{ -+ rrd->reg = reg; -+ rrd->mask = mask; -+ rrd->rt_data.data_u32 = data; -+ return _rt_regmap_update_bits(rd, rrd); -+} -+ -+extern void rt_regmap_cache_backup(struct rt_regmap_device *rd); -+ -+extern void rt_regmap_cache_sync(struct rt_regmap_device *rd); -+extern void rt_regmap_cache_write_back(struct rt_regmap_device *rd, u32 reg); -+ -+extern int rt_is_reg_readable(struct rt_regmap_device *rd, u32 reg); -+extern int rt_is_reg_volatile(struct rt_regmap_device *rd, u32 reg); -+extern int rt_get_regsize(struct rt_regmap_device *rd, u32 reg); -+extern void rt_cache_getlasterror(struct rt_regmap_device *rd, char *buf); -+extern void rt_cache_clrlasterror(struct rt_regmap_device *rd); -+ -+extern int rt_regmap_add_debugfs(struct rt_regmap_device *rd, const char *name, -+ umode_t mode, void *data, const struct file_operations *fops); -+ -+#define to_rt_regmap_device(obj) container_of(obj, struct rt_regmap_device, dev) -+ -+#endif /*MISC_MEDIATEK_RT_REGMAP_H*/ -diff --git a/drivers/misc/mediatek/include/mt-plat/sync_write.h b/drivers/misc/mediatek/include/mt-plat/sync_write.h -new file mode 100644 -index 0000000000000..f9e5fe4c23e17 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/sync_write.h -@@ -0,0 +1,88 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef _MT_SYNC_WRITE_H -+#define _MT_SYNC_WRITE_H -+ -+#if defined(__KERNEL__) -+ -+#include -+#include -+ -+/* -+ * Define macros. -+ */ -+#define mt_reg_sync_writel(v, a) \ -+ do { \ -+ __raw_writel((v), (void __force __iomem *)((a))); \ -+ mb(); \ -+ } while (0) -+ -+#define mt_reg_sync_writew(v, a) \ -+ do { \ -+ __raw_writew((v), (void __force __iomem *)((a))); \ -+ mb(); \ -+ } while (0) -+ -+#define mt_reg_sync_writeb(v, a) \ -+ do { \ -+ __raw_writeb((v), (void __force __iomem *)((a))); \ -+ mb(); \ -+ } while (0) -+ -+#ifdef CONFIG_64BIT -+#define mt_reg_sync_writeq(v, a) \ -+ do { \ -+ __raw_writeq((v), (void __force __iomem *)((a))); \ -+ mb(); \ -+ } while (0) -+#endif -+ -+#else /* __KERNEL__ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define mt_reg_sync_writel(v, a) mt65xx_reg_sync_writel(v, a) -+#define mt_reg_sync_writew(v, a) mt65xx_reg_sync_writew(v, a) -+#define mt_reg_sync_writeb(v, a) mt65xx_reg_sync_writeb(v, a) -+ -+#define mb() \ -+ { \ -+ __asm__ __volatile__ ("dsb" : : : "memory"); \ -+ } -+ -+#define mt65xx_reg_sync_writel(v, a) \ -+ do { \ -+ *(volatile unsigned int *)(a) = (v); \ -+ mb(); \ -+ } while (0) -+ -+#define mt65xx_reg_sync_writew(v, a) \ -+ do { \ -+ *(volatile unsigned short *)(a) = (v); \ -+ mb(); \ -+ } while (0) -+ -+#define mt65xx_reg_sync_writeb(v, a) \ -+ do { \ -+ *(volatile unsigned char *)(a) = (v); \ -+ mb(); \ -+ } while (0) -+ -+#endif /* __KERNEL__ */ -+ -+#endif /* !_MT_SYNC_WRITE_H */ -diff --git a/drivers/misc/mediatek/include/mt-plat/wakelock.h b/drivers/misc/mediatek/include/mt-plat/wakelock.h -new file mode 100644 -index 0000000000000..f4a698a228803 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/wakelock.h -@@ -0,0 +1,67 @@ -+/* include/linux/wakelock.h -+ * -+ * Copyright (C) 2007-2012 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef _LINUX_WAKELOCK_H -+#define _LINUX_WAKELOCK_H -+ -+#include -+#include -+ -+/* A wake_lock prevents the system from entering suspend or other low power -+ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock -+ * prevents a full system suspend. -+ */ -+ -+enum { -+ WAKE_LOCK_SUSPEND, /* Prevent suspend */ -+ WAKE_LOCK_TYPE_COUNT -+}; -+ -+struct wake_lock { -+ struct wakeup_source ws; -+}; -+ -+static inline void wake_lock_init(struct wake_lock *lock, int type, -+ const char *name) -+{ -+ wakeup_source_init(&lock->ws, name); -+} -+ -+static inline void wake_lock_destroy(struct wake_lock *lock) -+{ -+ wakeup_source_trash(&lock->ws); -+} -+ -+static inline void wake_lock(struct wake_lock *lock) -+{ -+ __pm_stay_awake(&lock->ws); -+} -+ -+static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) -+{ -+ __pm_wakeup_event(&lock->ws, jiffies_to_msecs(timeout)); -+} -+ -+static inline void wake_unlock(struct wake_lock *lock) -+{ -+ __pm_relax(&lock->ws); -+} -+ -+static inline int wake_lock_active(struct wake_lock *lock) -+{ -+ return lock->ws.active; -+} -+ -+#endif diff --git a/patch/kernel/archive/mt7623-4.19/0002-r2-wifi-add-dt.patch b/patch/kernel/archive/mt7623-4.19/0002-r2-wifi-add-dt.patch deleted file mode 100644 index 6973812817e5..000000000000 --- a/patch/kernel/archive/mt7623-4.19/0002-r2-wifi-add-dt.patch +++ /dev/null @@ -1,842 +0,0 @@ -From 83ffbaceffed1cd47a6f67fb20e39737dfb2d01a Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 28 Aug 2018 18:14:56 +0200 -Subject: [PATCH] [wifi] adding wifi-related changes outside driver-directory - ---- - arch/arm/boot/dts/mt7623.dtsi | 41 +- - arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 42 ++ - drivers/soc/mediatek/mtk-pmic-wrap.c | 12 + - drivers/watchdog/mtk_wdt.c | 377 +++++++++++++++++- - include/linux/wakelock.h | 67 ++++ - include/net/genetlink.h | 44 ++ - include/soc/mediatek/pmic_wrap.h | 19 + - include/uapi/linux/genetlink.h | 1 + - 8 files changed, 588 insertions(+), 15 deletions(-) - create mode 100644 include/linux/wakelock.h - create mode 100644 include/soc/mediatek/pmic_wrap.h - -diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi -index 04228cf9ddbbc..af6b6228f8a80 100644 ---- a/arch/arm/boot/dts/mt7623.dtsi -+++ b/arch/arm/boot/dts/mt7623.dtsi -@@ -266,6 +266,8 @@ - compatible = "mediatek,mt7623-wdt", - "mediatek,mt6589-wdt"; - reg = <0 0x10007000 0 0x100>; -+ interrupts = ; -+ #reset-cells = <1>; - }; - - timer: timer@10008000 { -@@ -494,13 +496,26 @@ - "mediatek,mtk-btif"; - reg = <0 0x1100c000 0 0x1000>; - interrupts = ; -- clocks = <&pericfg CLK_PERI_BTIF>; -- clock-names = "main"; -+ clocks = <&pericfg CLK_PERI_BTIF>, <&pericfg CLK_PERI_AP_DMA>; -+ clock-names = "main", "apdmac"; - reg-shift = <2>; - reg-io-width = <4>; - status = "disabled"; - }; - -+ btif_tx: btif_tx@11000780 { -+ compatible = "mediatek,btif_tx"; -+ reg = <0 0x11000780 0 0x80>; -+ interrupts = ; -+ status = "okay"; -+ }; -+ btif_rx: btif_rx@11000800 { -+ compatible = "mediatek,btif_rx"; -+ reg = <0 0x11000800 0 0x80>; -+ interrupts = ; -+ status = "okay"; -+ }; -+ - nandc: nfi@1100d000 { - compatible = "mediatek,mt7623-nfc", - "mediatek,mt2701-nfc"; -@@ -683,6 +698,28 @@ - status = "disabled"; - }; - -+ consys: consys@18070000 { -+ compatible = "mediatek,mt7623-consys"; -+ reg = <0 0x18070000 0 0x0200>, /*CONN_MCU_CONFIG_BASE */ -+ <0 0x10001000 0 0x1600>; /*TOPCKGEN_BASE */ -+ clocks = <&infracfg CLK_INFRA_CONNMCU>; -+ clock-names = "consysbus"; -+ power-domains = <&scpsys MT2701_POWER_DOMAIN_CONN>; -+ interrupts = , /* BGF_EINT */ -+ ; /* WDT_EINT */ -+ resets = <&watchdog MT2701_TOPRGU_CONN_MCU_RST>; -+ reset-names = "connsys"; -+ status="disabled"; -+ }; -+ wifi:wifi@180f0000 { -+ compatible = "mediatek,mt7623-wifi", -+ "mediatek,wifi"; -+ reg = <0 0x180f0000 0 0x005c>; -+ interrupts = ; -+ clocks = <&pericfg CLK_PERI_AP_DMA>; -+ clock-names = "wifi-dma"; -+ }; -+ - hifsys: syscon@1a000000 { - compatible = "mediatek,mt7623-hifsys", - "mediatek,mt2701-hifsys", -diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -index 2b760f90f38c8..465fb887b2ca6 100644 ---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -@@ -84,6 +84,18 @@ - }; - }; - -+ reserved-memory { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ consys-reserve-memory { -+ compatible = "mediatek,consys-reserve-memory"; -+ no-map; -+ size = <0 0x100000>; -+ alignment = <0 0x100000>; -+ }; -+ }; -+ - leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; -@@ -259,6 +271,36 @@ - }; - }; - -+&pio { -+ consys_pins_default: consys_pins_default { -+ adie { -+ pinmux = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ bias-disable; -+ }; -+ }; -+}; -+&consys { -+ mediatek,pwrap-regmap = <&pwrap>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&consys_pins_default>; -+ vcn18-supply = <&mt6323_vcn18_reg>; -+ vcn28-supply = <&mt6323_vcn28_reg>; -+ vcn33_bt-supply = <&mt6323_vcn33_bt_reg>; -+ vcn33_wifi-supply = <&mt6323_vcn33_wifi_reg>; -+ status = "okay"; -+}; -+ - &pcie { - pinctrl-names = "default"; - pinctrl-0 = <&pcie_default>; -diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c -index 4e931fdf4d091..6600396ee2993 100644 ---- a/drivers/soc/mediatek/mtk-pmic-wrap.c -+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c -@@ -1530,6 +1530,18 @@ static const struct of_device_id of_pwrap_match_tbl[] = { - }; - MODULE_DEVICE_TABLE(of, of_pwrap_match_tbl); - -+struct regmap *pwrap_node_to_regmap(struct device_node *np) -+{ -+ struct platform_device *pdev; -+ struct pmic_wrapper *wrp; -+ pdev = of_find_device_by_node(np); -+ if (!pdev) -+ return ERR_PTR(-ENODEV); -+ wrp = platform_get_drvdata(pdev); -+ return wrp->regmap; -+} -+EXPORT_SYMBOL_GPL(pwrap_node_to_regmap); -+ - static int pwrap_probe(struct platform_device *pdev) - { - int ret, irq; -diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c -index 4baf64f21aa11..6a361f808aed1 100644 ---- a/drivers/watchdog/mtk_wdt.c -+++ b/drivers/watchdog/mtk_wdt.c -@@ -1,4 +1,3 @@ --// SPDX-License-Identifier: GPL-2.0+ - /* - * Mediatek Watchdog Driver - * -@@ -6,20 +5,51 @@ - * - * Matthias Brugger - * -+ * 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. -+ * - * Based on sunxi_wdt.c - */ - - #include - #include - #include -+#include - #include - #include - #include -+#include -+#include -+#include - #include -+#include - #include -+#ifdef CONFIG_FIQ_GLUE -+#include -+#include -+#endif - #include - #include -+#include -+#include - #include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_MT6397_MISC -+#include -+#endif - - #define WDT_MAX_TIMEOUT 31 - #define WDT_MIN_TIMEOUT 1 -@@ -38,37 +68,167 @@ - #define WDT_MODE_EXRST_EN (1 << 2) - #define WDT_MODE_IRQ_EN (1 << 3) - #define WDT_MODE_AUTO_START (1 << 4) -+#define WDT_MODE_IRQ_LVL (1 << 5) - #define WDT_MODE_DUAL_EN (1 << 6) - #define WDT_MODE_KEY 0x22000000 - -+#define WDT_STATUS 0x0c -+#define WDT_NONRST_REG 0x20 -+#define WDT_NONRST_REG2 0x24 -+ - #define WDT_SWRST 0x14 - #define WDT_SWRST_KEY 0x1209 - -+#define WDT_SWSYSRST 0x18 -+#define WDT_SWSYSRST_KEY 0x88000000 -+ -+#define WDT_REQ_MODE 0x30 -+#define WDT_REQ_MODE_KEY 0x33000000 -+#define WDT_REQ_IRQ_EN 0x34 -+#define WDT_REQ_IRQ_KEY 0x44000000 -+#define WDT_REQ_MODE_DEBUG_EN 0x80000 -+ -+ - #define DRV_NAME "mtk-wdt" --#define DRV_VERSION "1.0" -+#define DRV_VERSION "2.0" - - static bool nowayout = WATCHDOG_NOWAYOUT; --static unsigned int timeout; -+static unsigned int timeout = WDT_MAX_TIMEOUT; -+ -+struct toprgu_reset { -+ spinlock_t lock; -+ void __iomem *toprgu_swrst_base; -+ int regofs; -+ struct reset_controller_dev rcdev; -+}; - - struct mtk_wdt_dev { - struct watchdog_device wdt_dev; - void __iomem *wdt_base; -+ int wdt_irq_id; -+ struct notifier_block restart_handler; -+ struct toprgu_reset reset_controller; - }; - --static int mtk_wdt_restart(struct watchdog_device *wdt_dev, -- unsigned long action, void *data) -+static void __iomem *toprgu_base; -+static struct watchdog_device *wdt_dev; -+ -+static int toprgu_reset_assert(struct reset_controller_dev *rcdev, -+ unsigned long id) - { -- struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev); -+ unsigned int tmp; -+ unsigned long flags; -+ struct toprgu_reset *data = container_of(rcdev, struct toprgu_reset, rcdev); -+ -+ spin_lock_irqsave(&data->lock, flags); -+ -+ tmp = __raw_readl(data->toprgu_swrst_base + data->regofs); -+ tmp |= BIT(id); -+ tmp |= WDT_SWSYSRST_KEY; -+ writel(tmp, data->toprgu_swrst_base + data->regofs); -+ -+ spin_unlock_irqrestore(&data->lock, flags); -+ -+ return 0; -+} -+ -+static int toprgu_reset_deassert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ unsigned int tmp; -+ unsigned long flags; -+ struct toprgu_reset *data = container_of(rcdev, struct toprgu_reset, rcdev); -+ -+ spin_lock_irqsave(&data->lock, flags); -+ -+ tmp = __raw_readl(data->toprgu_swrst_base + data->regofs); -+ tmp &= ~BIT(id); -+ tmp |= WDT_SWSYSRST_KEY; -+ writel(tmp, data->toprgu_swrst_base + data->regofs); -+ -+ spin_unlock_irqrestore(&data->lock, flags); -+ -+ return 0; -+} -+ -+static int toprgu_reset(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ int ret; -+ -+ ret = toprgu_reset_assert(rcdev, id); -+ if (ret) -+ return ret; -+ -+ return toprgu_reset_deassert(rcdev, id); -+} -+ -+static struct reset_control_ops toprgu_reset_ops = { -+ .assert = toprgu_reset_assert, -+ .deassert = toprgu_reset_deassert, -+ .reset = toprgu_reset, -+}; -+ -+static void toprgu_register_reset_controller(struct platform_device *pdev, int regofs) -+{ -+ int ret; -+ struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev); -+ -+ spin_lock_init(&mtk_wdt->reset_controller.lock); -+ -+ mtk_wdt->reset_controller.toprgu_swrst_base = mtk_wdt->wdt_base; -+ mtk_wdt->reset_controller.regofs = regofs; -+ mtk_wdt->reset_controller.rcdev.owner = THIS_MODULE; -+ mtk_wdt->reset_controller.rcdev.nr_resets = 15; -+ mtk_wdt->reset_controller.rcdev.ops = &toprgu_reset_ops; -+ mtk_wdt->reset_controller.rcdev.of_node = pdev->dev.of_node; -+ -+ ret = reset_controller_register(&mtk_wdt->reset_controller.rcdev); -+ if (ret) -+ pr_err("could not register toprgu reset controller: %d\n", ret); -+} -+ -+static int mtk_reset_handler(struct notifier_block *this, unsigned long mode, -+ void *cmd) -+{ -+ struct mtk_wdt_dev *mtk_wdt; - void __iomem *wdt_base; -+ u32 reg; - -+ mtk_wdt = container_of(this, struct mtk_wdt_dev, restart_handler); - wdt_base = mtk_wdt->wdt_base; - -- while (1) { -- writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST); -- mdelay(5); -+ /* WDT_STATUS will be cleared to zero after writing to WDT_MODE, so we backup it in WDT_NONRST_REG, -+ * and then print it out in mtk_wdt_probe() after reset -+ */ -+ writel(__raw_readl(wdt_base + WDT_STATUS), wdt_base + WDT_NONRST_REG); -+ -+ reg = ioread32(wdt_base + WDT_MODE); -+ reg &= ~(WDT_MODE_DUAL_EN | WDT_MODE_IRQ_EN | WDT_MODE_EN); -+ reg |= WDT_MODE_KEY; -+ iowrite32(reg, wdt_base + WDT_MODE); -+ -+ if (cmd && !strcmp(cmd, "rpmbpk")) { -+ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 0), wdt_base + WDT_NONRST_REG2); -+ } else if (cmd && !strcmp(cmd, "recovery")) { -+ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 1), wdt_base + WDT_NONRST_REG2); -+ #ifdef CONFIG_MT6397_MISC -+ mtk_misc_mark_recovery(); -+ #endif -+ } else if (cmd && !strcmp(cmd, "bootloader")) { -+ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 2), wdt_base + WDT_NONRST_REG2); -+ #ifdef CONFIG_MT6397_MISC -+ mtk_misc_mark_fast(); -+ #endif - } - -- return 0; -+ if (!arm_pm_restart) { -+ while (1) { -+ writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST); -+ mdelay(5); -+ } -+ } -+ return NOTIFY_DONE; - } - - static int mtk_wdt_ping(struct watchdog_device *wdt_dev) -@@ -77,6 +237,7 @@ static int mtk_wdt_ping(struct watchdog_device *wdt_dev) - void __iomem *wdt_base = mtk_wdt->wdt_base; - - iowrite32(WDT_RST_RELOAD, wdt_base + WDT_RST); -+ printk_deferred("[WDK]: kick Ex WDT\n"); - - return 0; - } -@@ -128,7 +289,8 @@ static int mtk_wdt_start(struct watchdog_device *wdt_dev) - return ret; - - reg = ioread32(wdt_base + WDT_MODE); -- reg &= ~(WDT_MODE_IRQ_EN | WDT_MODE_DUAL_EN); -+ reg |= (WDT_MODE_DUAL_EN | WDT_MODE_IRQ_EN | WDT_MODE_EXRST_EN); -+ reg &= ~(WDT_MODE_IRQ_LVL | WDT_MODE_EXT_POL_HIGH); - reg |= (WDT_MODE_EN | WDT_MODE_KEY); - iowrite32(reg, wdt_base + WDT_MODE); - -@@ -148,13 +310,56 @@ static const struct watchdog_ops mtk_wdt_ops = { - .stop = mtk_wdt_stop, - .ping = mtk_wdt_ping, - .set_timeout = mtk_wdt_set_timeout, -- .restart = mtk_wdt_restart, - }; - -+#ifdef CONFIG_FIQ_GLUE -+static void wdt_fiq(void *arg, void *regs, void *svc_sp) -+{ -+ unsigned int wdt_mode_val; -+ void __iomem *wdt_base = ((struct mtk_wdt_dev *)arg)->wdt_base; -+ -+ wdt_mode_val = __raw_readl(wdt_base + WDT_STATUS); -+ writel(wdt_mode_val, wdt_base + WDT_NONRST_REG); -+ -+ aee_wdt_fiq_info(arg, regs, svc_sp); -+} -+#else -+static void wdt_report_info(void) -+{ -+ struct task_struct *task; -+ -+ task = &init_task; -+ pr_debug("Qwdt: -- watchdog time out\n"); -+ -+ for_each_process(task) { -+ if (task->state == 0) { -+ pr_debug("PID: %d, name: %s\n backtrace:\n", task->pid, task->comm); -+ show_stack(task, NULL); -+ pr_debug("\n"); -+ } -+ } -+ -+ pr_debug("backtrace of current task:\n"); -+ show_stack(NULL, NULL); -+ pr_debug("Qwdt: -- watchdog time out\n"); -+} -+ -+static irqreturn_t mtk_wdt_isr(int irq, void *dev_id) -+{ -+ pr_err("fwq mtk_wdt_isr\n"); -+ -+ wdt_report_info(); -+ BUG(); -+ -+ return IRQ_HANDLED; -+} -+#endif -+ - static int mtk_wdt_probe(struct platform_device *pdev) - { - struct mtk_wdt_dev *mtk_wdt; - struct resource *res; -+ unsigned int tmp; - int err; - - mtk_wdt = devm_kzalloc(&pdev->dev, sizeof(*mtk_wdt), GFP_KERNEL); -@@ -165,9 +370,32 @@ static int mtk_wdt_probe(struct platform_device *pdev) - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mtk_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res); -+ - if (IS_ERR(mtk_wdt->wdt_base)) - return PTR_ERR(mtk_wdt->wdt_base); - -+ pr_err("MTK_WDT_NONRST_REG(%x)\n", __raw_readl(mtk_wdt->wdt_base + WDT_NONRST_REG)); -+ -+ mtk_wdt->wdt_irq_id = irq_of_parse_and_map(pdev->dev.of_node, 0); -+ if (!mtk_wdt->wdt_irq_id) { -+ pr_err("RGU get IRQ ID failed\n"); -+ return -ENODEV; -+ } -+ -+#ifndef CONFIG_FIQ_GLUE -+ err = request_irq(mtk_wdt->wdt_irq_id, (irq_handler_t)mtk_wdt_isr, IRQF_TRIGGER_NONE, DRV_NAME, mtk_wdt); -+#else -+ mtk_wdt->wdt_irq_id = get_hardware_irq(mtk_wdt->wdt_irq_id); -+ err = request_fiq(mtk_wdt->wdt_irq_id, wdt_fiq, IRQF_TRIGGER_FALLING, mtk_wdt); -+#endif -+ if (err != 0) { -+ pr_err("mtk_wdt_probe : failed to request irq (%d)\n", err); -+ return err; -+ } -+ -+ toprgu_base = mtk_wdt->wdt_base; -+ wdt_dev = &mtk_wdt->wdt_dev; -+ - mtk_wdt->wdt_dev.info = &mtk_wdt_info; - mtk_wdt->wdt_dev.ops = &mtk_wdt_ops; - mtk_wdt->wdt_dev.timeout = WDT_MAX_TIMEOUT; -@@ -177,7 +405,6 @@ static int mtk_wdt_probe(struct platform_device *pdev) - - watchdog_init_timeout(&mtk_wdt->wdt_dev, timeout, &pdev->dev); - watchdog_set_nowayout(&mtk_wdt->wdt_dev, nowayout); -- watchdog_set_restart_priority(&mtk_wdt->wdt_dev, 128); - - watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt); - -@@ -187,9 +414,40 @@ static int mtk_wdt_probe(struct platform_device *pdev) - if (unlikely(err)) - return err; - -+ mtk_wdt->restart_handler.notifier_call = mtk_reset_handler; -+ mtk_wdt->restart_handler.priority = 128; -+ -+ if (arm_pm_restart) { -+ dev_info(&pdev->dev, "register restart_handler on reboot_notifier_list for psci reset\n"); -+ err = register_reboot_notifier(&mtk_wdt->restart_handler); -+ if (err != 0) -+ dev_warn(&pdev->dev, -+ "cannot register reboot notifier (err=%d)\n", err); -+ } else { -+ err = register_restart_handler(&mtk_wdt->restart_handler); -+ if (err) -+ dev_warn(&pdev->dev, -+ "cannot register restart handler (err=%d)\n", err); -+ } -+ - dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n", - mtk_wdt->wdt_dev.timeout, nowayout); - -+ writel(WDT_REQ_MODE_KEY | (__raw_readl(mtk_wdt->wdt_base + WDT_REQ_MODE) & -+ (~WDT_REQ_MODE_DEBUG_EN)), mtk_wdt->wdt_base + WDT_REQ_MODE); -+ -+ toprgu_register_reset_controller(pdev, WDT_SWSYSRST); -+ -+ /* enable scpsys thermal and thermal_controller request, and set to reset directly mode */ -+ tmp = ioread32(mtk_wdt->wdt_base + WDT_REQ_MODE) | (1 << 18) | (1 << 0); -+ tmp |= WDT_REQ_MODE_KEY; -+ iowrite32(tmp, mtk_wdt->wdt_base + WDT_REQ_MODE); -+ -+ tmp = ioread32(mtk_wdt->wdt_base + WDT_REQ_IRQ_EN); -+ tmp &= ~((1 << 18) | (1 << 0)); -+ tmp |= WDT_REQ_IRQ_KEY; -+ iowrite32(tmp, mtk_wdt->wdt_base + WDT_REQ_IRQ_EN); -+ - return 0; - } - -@@ -205,8 +463,12 @@ static int mtk_wdt_remove(struct platform_device *pdev) - { - struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev); - -+ unregister_restart_handler(&mtk_wdt->restart_handler); -+ - watchdog_unregister_device(&mtk_wdt->wdt_dev); - -+ reset_controller_unregister(&mtk_wdt->reset_controller.rcdev); -+ - return 0; - } - -@@ -258,6 +520,95 @@ static struct platform_driver mtk_wdt_driver = { - - module_platform_driver(mtk_wdt_driver); - -+static int wk_proc_cmd_read(struct seq_file *s, void *v) -+{ -+ unsigned int enabled = 1; -+ -+ if (!(ioread32(toprgu_base + WDT_MODE) & WDT_MODE_EN)) -+ enabled = 0; -+ -+ seq_printf(s, "enabled timeout\n%-4d %-8d\n", enabled, wdt_dev->timeout); -+ -+ return 0; -+} -+ -+static int wk_proc_cmd_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, wk_proc_cmd_read, NULL); -+} -+ -+static ssize_t wk_proc_cmd_write(struct file *file, const char *buf, size_t count, loff_t *data) -+{ -+ int ret; -+ int enable; -+ int timeout; -+ char wk_cmd_buf[256]; -+ -+ if (count == 0) -+ return -1; -+ -+ if (count > 255) -+ count = 255; -+ -+ ret = copy_from_user(wk_cmd_buf, buf, count); -+ if (ret < 0) -+ return -1; -+ -+ wk_cmd_buf[count] = '\0'; -+ -+ pr_debug("Write %s\n", wk_cmd_buf); -+ -+ ret = sscanf(wk_cmd_buf, "%d %d", &enable, &timeout); -+ if (ret != 2) -+ pr_debug("%s: expect 2 numbers\n", __func__); -+ -+ pr_debug("[WDK] enable=%d timeout=%d\n", enable, timeout); -+ -+ if (timeout > 20 && timeout <= WDT_MAX_TIMEOUT) { -+ wdt_dev->timeout = timeout; -+ mtk_wdt_set_timeout(wdt_dev, wdt_dev->timeout); -+ } else { -+ pr_err("[WDK] The timeout(%d) should bigger than 20 and not bigger than %d\n", -+ timeout, WDT_MAX_TIMEOUT); -+ -+ } -+ -+ if (enable == 1) { -+ mtk_wdt_start(wdt_dev); -+ set_bit(WDOG_ACTIVE, &wdt_dev->status); -+ pr_err("[WDK] enable wdt\n"); -+ } else if (enable == 0) { -+ mtk_wdt_stop(wdt_dev); -+ clear_bit(WDOG_ACTIVE, &wdt_dev->status); -+ pr_err("[WDK] disable wdt\n"); -+ } -+ -+ return count; -+} -+ -+static const struct file_operations wk_proc_cmd_fops = { -+ .owner = THIS_MODULE, -+ .open = wk_proc_cmd_open, -+ .read = seq_read, -+ .write = wk_proc_cmd_write, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+static int __init wk_proc_init(void) -+{ -+ struct proc_dir_entry *de = proc_create("wdk", 0660, NULL, &wk_proc_cmd_fops); -+ -+ if (!de) -+ pr_err("[wk_proc_init]: create /proc/wdk failed\n"); -+ -+ pr_debug("[WDK] Initialize proc\n"); -+ -+ return 0; -+} -+ -+late_initcall(wk_proc_init); -+ - module_param(timeout, uint, 0); - MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds"); - -diff --git a/include/linux/wakelock.h b/include/linux/wakelock.h -new file mode 100644 -index 0000000000000..f4a698a228803 ---- /dev/null -+++ b/include/linux/wakelock.h -@@ -0,0 +1,67 @@ -+/* include/linux/wakelock.h -+ * -+ * Copyright (C) 2007-2012 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef _LINUX_WAKELOCK_H -+#define _LINUX_WAKELOCK_H -+ -+#include -+#include -+ -+/* A wake_lock prevents the system from entering suspend or other low power -+ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock -+ * prevents a full system suspend. -+ */ -+ -+enum { -+ WAKE_LOCK_SUSPEND, /* Prevent suspend */ -+ WAKE_LOCK_TYPE_COUNT -+}; -+ -+struct wake_lock { -+ struct wakeup_source ws; -+}; -+ -+static inline void wake_lock_init(struct wake_lock *lock, int type, -+ const char *name) -+{ -+ wakeup_source_init(&lock->ws, name); -+} -+ -+static inline void wake_lock_destroy(struct wake_lock *lock) -+{ -+ wakeup_source_trash(&lock->ws); -+} -+ -+static inline void wake_lock(struct wake_lock *lock) -+{ -+ __pm_stay_awake(&lock->ws); -+} -+ -+static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) -+{ -+ __pm_wakeup_event(&lock->ws, jiffies_to_msecs(timeout)); -+} -+ -+static inline void wake_unlock(struct wake_lock *lock) -+{ -+ __pm_relax(&lock->ws); -+} -+ -+static inline int wake_lock_active(struct wake_lock *lock) -+{ -+ return lock->ws.active; -+} -+ -+#endif -diff --git a/include/net/genetlink.h b/include/net/genetlink.h -index decf6012a4016..6471da92334ad 100644 ---- a/include/net/genetlink.h -+++ b/include/net/genetlink.h -@@ -144,6 +144,50 @@ struct genl_ops { - }; - - int genl_register_family(struct genl_family *family); -+ -+/** -+ * genl_register_family_with_ops - register a generic netlink family with ops -+ * @family: generic netlink family -+ * @ops: operations to be registered -+ * @n_ops: number of elements to register -+ * -+ * Registers the specified family and operations from the specified table. -+ * Only one family may be registered with the same family name or identifier. -+ * -+ * The family id may equal GENL_ID_GENERATE causing an unique id to -+ * be automatically generated and assigned. -+ * -+ * Either a doit or dumpit callback must be specified for every registered -+ * operation or the function will fail. Only one operation structure per -+ * command identifier may be registered. -+ * -+ * See include/net/genetlink.h for more documenation on the operations -+ * structure. -+ * -+ * Return 0 on success or a negative error code. -+ */ -+static inline int -+_genl_register_family_with_ops_grps(struct genl_family *family, -+ const struct genl_ops *ops, size_t n_ops, -+ const struct genl_multicast_group *mcgrps, -+ size_t n_mcgrps) -+{ -+ family->module = THIS_MODULE; -+ family->ops = ops; -+ family->n_ops = n_ops; -+ family->mcgrps = mcgrps; -+ family->n_mcgrps = n_mcgrps; -+ return genl_register_family(family); -+} -+#define genl_register_family_with_ops(family, ops) \ -+ _genl_register_family_with_ops_grps((family), \ -+ (ops), ARRAY_SIZE(ops), \ -+ NULL, 0) -+#define genl_register_family_with_ops_groups(family, ops, grps) \ -+ _genl_register_family_with_ops_grps((family), \ -+ (ops), ARRAY_SIZE(ops), \ -+ (grps), ARRAY_SIZE(grps)) -+ - int genl_unregister_family(const struct genl_family *family); - void genl_notify(const struct genl_family *family, struct sk_buff *skb, - struct genl_info *info, u32 group, gfp_t flags); -diff --git a/include/soc/mediatek/pmic_wrap.h b/include/soc/mediatek/pmic_wrap.h -new file mode 100644 -index 0000000000000..5b5c85272c58b ---- /dev/null -+++ b/include/soc/mediatek/pmic_wrap.h -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * 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. -+ */ -+ -+#ifndef __SOC_MEDIATEK_PMIC_WRAP_H -+#define __SOC_MEDIATEK_PMIC_WRAP_H -+ -+extern struct regmap *pwrap_node_to_regmap(struct device_node *np); -+ -+#endif /* __SOC_MEDIATEK_PMIC_WRAP_H */ -diff --git a/include/uapi/linux/genetlink.h b/include/uapi/linux/genetlink.h -index 877f7fa954666..6a176b3d43f9b 100644 ---- a/include/uapi/linux/genetlink.h -+++ b/include/uapi/linux/genetlink.h -@@ -27,6 +27,7 @@ struct genlmsghdr { - /* - * List of reserved static generic netlink identifiers: - */ -+#define GENL_ID_GENERATE 0 - #define GENL_ID_CTRL NLMSG_MIN_TYPE - #define GENL_ID_VFS_DQUOT (NLMSG_MIN_TYPE + 1) - #define GENL_ID_PMCRAID (NLMSG_MIN_TYPE + 2) diff --git a/patch/kernel/archive/mt7623-4.19/0003-r2-gcc8-nic_rx.patch b/patch/kernel/archive/mt7623-4.19/0003-r2-gcc8-nic_rx.patch deleted file mode 100644 index 7e4a636d2fc5..000000000000 --- a/patch/kernel/archive/mt7623-4.19/0003-r2-gcc8-nic_rx.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 203a5a7727a80ab519ea00181a909e415c5567ab Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Wed, 29 Aug 2018 19:17:00 +0200 -Subject: [PATCH] [gcc] gcc8-fixes by Dominik Koch + nic_rx-patch from - https://bugs.linaro.org/show_bug.cgi?id=3823 - ---- - .../misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c | 10 ++++++---- - .../misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c | 2 +- - .../connectivity/wlan/gen2/os/linux/include/gl_kal.h | 2 +- - 3 files changed, 8 insertions(+), 6 deletions(-) - -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c -index ba4840414da85..65823023cec0e 100644 ---- a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c -@@ -2061,7 +2061,6 @@ VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb - case EVENT_ID_BT_OVER_WIFI: - #if CFG_ENABLE_BT_OVER_WIFI - { -- UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)]; - P_EVENT_BT_OVER_WIFI prEventBtOverWifi; - P_AMPC_EVENT prBowEvent; - P_BOW_LINK_CONNECTED prBowLinkConnected; -@@ -2069,11 +2068,11 @@ VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb - - prEventBtOverWifi = (P_EVENT_BT_OVER_WIFI) (prEvent->aucBuffer); - -- /* construct event header */ -- prBowEvent = (P_AMPC_EVENT) aucTmp; -- - if (prEventBtOverWifi->ucLinkStatus == 0) { - /* Connection */ -+ UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_CONNECTED)]; -+ /* construct event header */ -+ prBowEvent = (P_AMPC_EVENT) aucTmp; - prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED; - prBowEvent->rHeader.ucSeqNumber = 0; - prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED); -@@ -2086,6 +2085,9 @@ VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb - kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent); - } else { - /* Disconnection */ -+ UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)]; -+ /* construct event header */ -+ prBowEvent = (P_AMPC_EVENT) aucTmp; - prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED; - prBowEvent->rHeader.ucSeqNumber = 0; - prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED); -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c -index dd00859d46082..ad7107b1d9a44 100644 ---- a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c -@@ -5021,7 +5021,7 @@ VOID qmHandleRxArpPackets(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) - if (prBssInfo && prBssInfo->prStaRecOfAP && prBssInfo->prStaRecOfAP->aucMacAddr) { - if (EQUAL_MAC_ADDR(&(pucData[ETH_TYPE_LEN_OFFSET + 10]), /* source hardware address */ - prBssInfo->prStaRecOfAP->aucMacAddr)) { -- strncpy(apIp, &(pucData[ETH_TYPE_LEN_OFFSET + 16]), sizeof(apIp)); /* src ip address */ -+ memcpy(apIp, &(pucData[ETH_TYPE_LEN_OFFSET + 16]), sizeof(apIp)); /* src ip address */ - DBGLOG(INIT, TRACE, "get arp response from AP %d.%d.%d.%d\n", - apIp[0], apIp[1], apIp[2], apIp[3]); - } -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h -index 1406905095e64..b1386918c08de 100644 ---- a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h -@@ -852,7 +852,7 @@ struct KAL_HALT_CTRL_T { - - /* string operation */ - #define kalStrCpy(dest, src) strcpy(dest, src) --#define kalStrnCpy(dest, src, n) strncpy(dest, src, n) -+#define kalStrnCpy(dest, src, n) memcpy(dest, src, n) - #define kalStrCmp(ct, cs) strcmp(ct, cs) - #define kalStrnCmp(ct, cs, n) strncmp(ct, cs, n) - #define kalStrChr(s, c) strchr(s, c) diff --git a/patch/kernel/archive/mt7623-4.19/0004-r2-power-off-and-rtc.patch.broken b/patch/kernel/archive/mt7623-4.19/0004-r2-power-off-and-rtc.patch.broken deleted file mode 100644 index 287a26531a3d..000000000000 --- a/patch/kernel/archive/mt7623-4.19/0004-r2-power-off-and-rtc.patch.broken +++ /dev/null @@ -1,715 +0,0 @@ -From 981dbf745c8c80300707ee2a5c1e25189b51a2e6 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 23 Oct 2018 12:09:37 +0200 -Subject: [PATCH] [poweroff] add power-off patch from jofri - ---- - .../devicetree/bindings/mfd/mt6397.txt | 10 +- - .../bindings/power/reset/mt6323-poweroff.txt | 20 +++ - .../devicetree/bindings/rtc/rtc-mt6397.txt | 29 ++++ - MAINTAINERS | 7 + - arch/arm/boot/dts/mt6323.dtsi | 46 +++++- - arch/arm/configs/mt7623n_evb_fwu_defconfig | 4 +- - drivers/mfd/mt6397-core.c | 40 +++-- - drivers/power/reset/Kconfig | 10 ++ - drivers/power/reset/Makefile | 1 + - drivers/power/reset/mt6323-poweroff.c | 97 ++++++++++++ - drivers/rtc/rtc-mt6397.c | 147 ++++-------------- - include/linux/mfd/mt6397/core.h | 2 + - include/linux/mfd/mt6397/rtc.h | 71 +++++++++ - 13 files changed, 356 insertions(+), 128 deletions(-) - create mode 100644 Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt - create mode 100644 Documentation/devicetree/bindings/rtc/rtc-mt6397.txt - create mode 100644 drivers/power/reset/mt6323-poweroff.c - create mode 100644 include/linux/mfd/mt6397/rtc.h - -diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt -index 0ebd08af777d4..44acb98277168 100644 ---- a/Documentation/devicetree/bindings/mfd/mt6397.txt -+++ b/Documentation/devicetree/bindings/mfd/mt6397.txt -@@ -8,6 +8,7 @@ MT6397/MT6323 is a multifunction device with the following sub modules: - - Clock - - LED - - Keys -+- Power controller - - It is interfaced to host controller using SPI interface by a proprietary hardware - called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap. -@@ -22,8 +23,10 @@ compatible: "mediatek,mt6397" or "mediatek,mt6323" - Optional subnodes: - - - rtc -- Required properties: -+ Required properties: Should be one of follows -+ - compatible: "mediatek,mt6323-rtc" - - compatible: "mediatek,mt6397-rtc" -+ For details, see Documentation/devicetree/bindings/rtc/rtc-mt6397.txt - - regulators - Required properties: - - compatible: "mediatek,mt6397-regulator" -@@ -46,6 +49,11 @@ Optional subnodes: - - compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys" - see Documentation/devicetree/bindings/input/mtk-pmic-keys.txt - -+- power-controller -+ Required properties: -+ - compatible: "mediatek,mt6323-pwrc" -+ For details, see Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt -+ - Example: - pwrap: pwrap@1000f000 { - compatible = "mediatek,mt8135-pwrap"; -diff --git a/Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt b/Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt -new file mode 100644 -index 0000000000000..6f7c5905a6529 ---- /dev/null -+++ b/Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt -@@ -0,0 +1,20 @@ -+Device Tree Bindings for Power Controller on MediaTek PMIC -+ -+The power controller which could be found on PMIC is responsible for externally -+powering off or on the remote MediaTek SoC through the circuit BBPU. -+ -+Required properties: -+- compatible: Should be one of follows -+ "mediatek,mt6323-pwrc": for MT6323 PMIC -+ -+Example: -+ -+ pmic { -+ compatible = "mediatek,mt6323"; -+ -+ ... -+ -+ power-controller { -+ compatible = "mediatek,mt6323-pwrc"; -+ }; -+ } -diff --git a/Documentation/devicetree/bindings/rtc/rtc-mt6397.txt b/Documentation/devicetree/bindings/rtc/rtc-mt6397.txt -new file mode 100644 -index 0000000000000..6e97248e89306 ---- /dev/null -+++ b/Documentation/devicetree/bindings/rtc/rtc-mt6397.txt -@@ -0,0 +1,29 @@ -+Device-Tree bindings for MediaTek PMIC based RTC -+ -+MediaTek PMIC based RTC is an independent function of MediaTek PMIC that works -+as a type of multi-function device (MFD). The RTC can be configured and set up -+with PMIC wrapper bus which is a common resource shared with the other -+functions found on the same PMIC. -+ -+For MediaTek PMIC MFD bindings, see: -+Documentation/devicetree/bindings/mfd/mt6397.txt -+ -+For MediaTek PMIC wrapper bus bindings, see: -+Documentation/devicetree/bindings/soc/mediatek/pwrap.txt -+ -+Required properties: -+- compatible: Should be one of follows -+ "mediatek,mt6323-rtc": for MT6323 PMIC -+ "mediatek,mt6397-rtc": for MT6397 PMIC -+ -+Example: -+ -+ pmic { -+ compatible = "mediatek,mt6323"; -+ -+ ... -+ -+ rtc { -+ compatible = "mediatek,mt6323-rtc"; -+ }; -+ }; -diff --git a/MAINTAINERS b/MAINTAINERS -index b2f710eee67a7..ed4733bbd124f 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -9227,6 +9227,13 @@ S: Maintained - F: drivers/net/dsa/mt7530.* - F: net/dsa/tag_mtk.c - -+MEDIATEK BOARD LEVEL SHUTDOWN DRIVERS -+M: Sean Wang -+L: linux-pm@vger.kernel.org -+S: Maintained -+F: Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt -+F: drivers/power/reset/mt6323-poweroff.c -+ - MEDIATEK JPEG DRIVER - M: Rick Chang - M: Bin Liu -diff --git a/arch/arm/boot/dts/mt6323.dtsi b/arch/arm/boot/dts/mt6323.dtsi -index ba397407c1dd0..871de0bb349bd 100644 ---- a/arch/arm/boot/dts/mt6323.dtsi -+++ b/arch/arm/boot/dts/mt6323.dtsi -@@ -18,7 +18,24 @@ - compatible = "mediatek,mt6323-led"; - #address-cells = <1>; - #size-cells = <0>; -- status = "disabled"; -+ -+ led@0 { -+ reg = <0>; -+ label = "bpi-r2:isink:green"; -+ default-state = "off"; -+ }; -+ -+ led@1 { -+ reg = <1>; -+ label = "bpi-r2:isink:red"; -+ default-state = "off"; -+ }; -+ -+ led@2 { -+ reg = <2>; -+ label = "bpi-r2:isink:blue"; -+ default-state = "off"; -+ }; - }; - - mt6323regulator: mt6323regulator{ -@@ -238,5 +255,32 @@ - regulator-enable-ramp-delay = <216>; - }; - }; -+ -+ mt6323keys: mt6323keys { -+ compatible = "mediatek,mt6323-keys"; -+ mediatek,long-press-mode = <1>; -+ power-off-time-sec = <0>; -+ -+ power { -+ linux,keycodes = <116>; -+ wakeup-source; -+ }; -+ -+ home { -+ linux,keycodes = <114>; -+ }; -+ }; -+ -+ codec: mt6397codec { -+ compatible = "mediatek,mt6397-codec"; -+ }; -+ -+ power-controller { -+ compatible = "mediatek,mt6323-pwrc"; -+ }; -+ -+ rtc { -+ compatible = "mediatek,mt6323-rtc"; -+ }; - }; - }; -diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c -index 77b64bd64df36..e0012e2624734 100644 ---- a/drivers/mfd/mt6397-core.c -+++ b/drivers/mfd/mt6397-core.c -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 2014 MediaTek Inc. -+ * Copyright (c) 2014-2018 MediaTek Inc. - * Author: Flora Fu, MediaTek - * - * This program is free software; you can redistribute it and/or modify -@@ -13,6 +13,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -23,24 +24,27 @@ - #include - #include - -+#define MT6323_RTC_BASE 0x8000 -+#define MT6323_RTC_SIZE 0x40 -+ - #define MT6397_RTC_BASE 0xe000 - #define MT6397_RTC_SIZE 0x3e - -+#define MT6323_PWRC_BASE 0x8000 -+#define MT6323_PWRC_SIZE 0x40 -+ - #define MT6323_CID_CODE 0x23 - #define MT6391_CID_CODE 0x91 - #define MT6397_CID_CODE 0x97 - -+static const struct resource mt6323_rtc_resources[] = { -+ DEFINE_RES_MEM(MT6323_RTC_BASE, MT6323_RTC_SIZE), -+ DEFINE_RES_IRQ(MT6323_IRQ_STATUS_RTC), -+}; -+ - static const struct resource mt6397_rtc_resources[] = { -- { -- .start = MT6397_RTC_BASE, -- .end = MT6397_RTC_BASE + MT6397_RTC_SIZE, -- .flags = IORESOURCE_MEM, -- }, -- { -- .start = MT6397_IRQ_RTC, -- .end = MT6397_IRQ_RTC, -- .flags = IORESOURCE_IRQ, -- }, -+ DEFINE_RES_MEM(MT6397_RTC_BASE, MT6397_RTC_SIZE), -+ DEFINE_RES_IRQ(MT6397_IRQ_RTC), - }; - - static const struct resource mt6323_keys_resources[] = { -@@ -53,8 +57,17 @@ static const struct resource mt6397_keys_resources[] = { - DEFINE_RES_IRQ(MT6397_IRQ_HOMEKEY), - }; - -+static const struct resource mt6323_pwrc_resources[] = { -+ DEFINE_RES_MEM(MT6323_PWRC_BASE, MT6323_PWRC_SIZE), -+}; -+ - static const struct mfd_cell mt6323_devs[] = { - { -+ .name = "mt6323-rtc", -+ .num_resources = ARRAY_SIZE(mt6323_rtc_resources), -+ .resources = mt6323_rtc_resources, -+ .of_compatible = "mediatek,mt6323-rtc", -+ }, { - .name = "mt6323-regulator", - .of_compatible = "mediatek,mt6323-regulator" - }, { -@@ -65,6 +78,11 @@ static const struct mfd_cell mt6323_devs[] = { - .num_resources = ARRAY_SIZE(mt6323_keys_resources), - .resources = mt6323_keys_resources, - .of_compatible = "mediatek,mt6323-keys" -+ }, { -+ .name = "mt6323-pwrc", -+ .num_resources = ARRAY_SIZE(mt6323_pwrc_resources), -+ .resources = mt6323_pwrc_resources, -+ .of_compatible = "mediatek,mt6323-pwrc" - }, - }; - -diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig -index 6533aa560aa1f..3d0c050c51601 100644 ---- a/drivers/power/reset/Kconfig -+++ b/drivers/power/reset/Kconfig -@@ -139,6 +139,16 @@ config POWER_RESET_LTC2952 - This driver supports an external powerdown trigger and board power - down via the LTC2952. Bindings are made in the device tree. - -+config POWER_RESET_MT6323 -+ bool "MediaTek MT6323 power-off driver" -+ depends on MFD_MT6397 -+ help -+ The power-off driver is responsible for externally shutdown down -+ the power of a remote MediaTek SoC MT6323 is connected to through -+ controlling a tiny circuit BBPU inside MT6323 RTC. -+ -+ Say Y if you have a board where MT6323 could be found. -+ - config POWER_RESET_QNAP - bool "QNAP power-off driver" - depends on OF_GPIO && PLAT_ORION -diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile -index 0aebee954ac1b..94eaceb01d665 100644 ---- a/drivers/power/reset/Makefile -+++ b/drivers/power/reset/Makefile -@@ -11,6 +11,7 @@ obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o - obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o - obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o - obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o -+obj-$(CONFIG_POWER_RESET_MT6323) += mt6323-poweroff.o - obj-$(CONFIG_POWER_RESET_QCOM_PON) += qcom-pon.o - obj-$(CONFIG_POWER_RESET_OCELOT_RESET) += ocelot-reset.o - obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o -diff --git a/drivers/power/reset/mt6323-poweroff.c b/drivers/power/reset/mt6323-poweroff.c -new file mode 100644 -index 0000000000000..c195766f75704 ---- /dev/null -+++ b/drivers/power/reset/mt6323-poweroff.c -@@ -0,0 +1,97 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Power off through MediaTek PMIC -+ * -+ * Copyright (C) 2018 MediaTek Inc. -+ * -+ * Author: Sean Wang -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct mt6323_pwrc { -+ struct device *dev; -+ struct regmap *regmap; -+ u32 base; -+}; -+ -+static struct mt6323_pwrc *mt_pwrc; -+ -+static void mt6323_do_pwroff(void) -+{ -+ struct mt6323_pwrc *pwrc = mt_pwrc; -+ unsigned int val; -+ int ret; -+ -+ regmap_write(pwrc->regmap, pwrc->base + RTC_BBPU, RTC_BBPU_KEY); -+ regmap_write(pwrc->regmap, pwrc->base + RTC_WRTGR, 1); -+ -+ ret = regmap_read_poll_timeout(pwrc->regmap, -+ pwrc->base + RTC_BBPU, val, -+ !(val & RTC_BBPU_CBUSY), -+ MTK_RTC_POLL_DELAY_US, -+ MTK_RTC_POLL_TIMEOUT); -+ if (ret) -+ dev_err(pwrc->dev, "failed to write BBPU: %d\n", ret); -+ -+ /* Wait some time until system down, otherwise, notice with a warn */ -+ mdelay(1000); -+ -+ WARN_ONCE(1, "Unable to power off system\n"); -+} -+ -+static int mt6323_pwrc_probe(struct platform_device *pdev) -+{ -+ struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent); -+ struct mt6323_pwrc *pwrc; -+ struct resource *res; -+ -+ pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL); -+ if (!pwrc) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ pwrc->base = res->start; -+ pwrc->regmap = mt6397_chip->regmap; -+ pwrc->dev = &pdev->dev; -+ mt_pwrc = pwrc; -+ -+ pm_power_off = &mt6323_do_pwroff; -+ -+ return 0; -+} -+ -+static int mt6323_pwrc_remove(struct platform_device *pdev) -+{ -+ if (pm_power_off == &mt6323_do_pwroff) -+ pm_power_off = NULL; -+ -+ return 0; -+} -+ -+static const struct of_device_id mt6323_pwrc_dt_match[] = { -+ { .compatible = "mediatek,mt6323-pwrc" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mt6323_pwrc_dt_match); -+ -+static struct platform_driver mt6323_pwrc_driver = { -+ .probe = mt6323_pwrc_probe, -+ .remove = mt6323_pwrc_remove, -+ .driver = { -+ .name = "mt6323-pwrc", -+ .of_match_table = mt6323_pwrc_dt_match, -+ }, -+}; -+ -+module_platform_driver(mt6323_pwrc_driver); -+ -+MODULE_DESCRIPTION("Poweroff driver for MT6323 PMIC"); -+MODULE_AUTHOR("Sean Wang "); -+MODULE_LICENSE("GPL v2"); -diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c -index 385f8303bb412..66e949df8d6a1 100644 ---- a/drivers/rtc/rtc-mt6397.c -+++ b/drivers/rtc/rtc-mt6397.c -@@ -1,80 +1,26 @@ -+// SPDX-License-Identifier: GPL-2.0 - /* --* Copyright (c) 2014-2015 MediaTek Inc. --* Author: Tianping.Fang --* --* 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. --* --* 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. --*/ -- --#include --#include -+ * MediaTek PMIC RTC driver -+ * -+ * Copyright (C) 2014-2018 MediaTek Inc. -+ * -+ * Author: Tianping.Fang -+ * Sean Wang -+ */ -+ -+#include -+#include -+#include - #include -+#include -+#include -+#include - #include - #include --#include --#include --#include --#include --#include --#include -- --#define RTC_BBPU 0x0000 --#define RTC_BBPU_CBUSY BIT(6) -- --#define RTC_WRTGR 0x003c -- --#define RTC_IRQ_STA 0x0002 --#define RTC_IRQ_STA_AL BIT(0) --#define RTC_IRQ_STA_LP BIT(3) -- --#define RTC_IRQ_EN 0x0004 --#define RTC_IRQ_EN_AL BIT(0) --#define RTC_IRQ_EN_ONESHOT BIT(2) --#define RTC_IRQ_EN_LP BIT(3) --#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL) -- --#define RTC_AL_MASK 0x0008 --#define RTC_AL_MASK_DOW BIT(4) -- --#define RTC_TC_SEC 0x000a --/* Min, Hour, Dom... register offset to RTC_TC_SEC */ --#define RTC_OFFSET_SEC 0 --#define RTC_OFFSET_MIN 1 --#define RTC_OFFSET_HOUR 2 --#define RTC_OFFSET_DOM 3 --#define RTC_OFFSET_DOW 4 --#define RTC_OFFSET_MTH 5 --#define RTC_OFFSET_YEAR 6 --#define RTC_OFFSET_COUNT 7 -- --#define RTC_AL_SEC 0x0018 -- --#define RTC_PDN2 0x002e --#define RTC_PDN2_PWRON_ALARM BIT(4) -- --#define RTC_MIN_YEAR 1968 --#define RTC_BASE_YEAR 1900 --#define RTC_NUM_YEARS 128 --#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR) -- --struct mt6397_rtc { -- struct device *dev; -- struct rtc_device *rtc_dev; -- struct mutex lock; -- struct regmap *regmap; -- int irq; -- u32 addr_base; --}; -+#include - - static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc) - { -- unsigned long timeout = jiffies + HZ; - int ret; - u32 data; - -@@ -82,19 +28,13 @@ static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc) - if (ret < 0) - return ret; - -- while (1) { -- ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_BBPU, -- &data); -- if (ret < 0) -- break; -- if (!(data & RTC_BBPU_CBUSY)) -- break; -- if (time_after(jiffies, timeout)) { -- ret = -ETIMEDOUT; -- break; -- } -- cpu_relax(); -- } -+ ret = regmap_read_poll_timeout(rtc->regmap, -+ rtc->addr_base + RTC_BBPU, data, -+ !(data & RTC_BBPU_CBUSY), -+ MTK_RTC_POLL_DELAY_US, -+ MTK_RTC_POLL_TIMEOUT); -+ if (ret < 0) -+ dev_err(rtc->dev, "failed to write WRTGE: %d\n", ret); - - return ret; - } -@@ -332,44 +272,25 @@ static int mtk_rtc_probe(struct platform_device *pdev) - - platform_set_drvdata(pdev, rtc); - -- ret = request_threaded_irq(rtc->irq, NULL, -- mtk_rtc_irq_handler_thread, -- IRQF_ONESHOT | IRQF_TRIGGER_HIGH, -- "mt6397-rtc", rtc); -+ ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, -+ mtk_rtc_irq_handler_thread, -+ IRQF_ONESHOT | IRQF_TRIGGER_HIGH, -+ "mt6397-rtc", rtc); - if (ret) { - dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", - rtc->irq, ret); -- goto out_dispose_irq; -+ return ret; - } - - device_init_wakeup(&pdev->dev, 1); - -- rtc->rtc_dev = rtc_device_register("mt6397-rtc", &pdev->dev, -- &mtk_rtc_ops, THIS_MODULE); -- if (IS_ERR(rtc->rtc_dev)) { -- dev_err(&pdev->dev, "register rtc device failed\n"); -- ret = PTR_ERR(rtc->rtc_dev); -- goto out_free_irq; -- } -- -- return 0; -+ rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); -+ if (IS_ERR(rtc->rtc_dev)) -+ return PTR_ERR(rtc->rtc_dev); - --out_free_irq: -- free_irq(rtc->irq, rtc->rtc_dev); --out_dispose_irq: -- irq_dispose_mapping(rtc->irq); -- return ret; --} -+ rtc->rtc_dev->ops = &mtk_rtc_ops; - --static int mtk_rtc_remove(struct platform_device *pdev) --{ -- struct mt6397_rtc *rtc = platform_get_drvdata(pdev); -- -- rtc_device_unregister(rtc->rtc_dev); -- free_irq(rtc->irq, rtc->rtc_dev); -- irq_dispose_mapping(rtc->irq); -- -- return 0; -+ return rtc_register_device(rtc->rtc_dev); - } - - #ifdef CONFIG_PM_SLEEP -@@ -398,6 +319,7 @@ static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_rtc_suspend, - mt6397_rtc_resume); - - static const struct of_device_id mt6397_rtc_of_match[] = { -+ { .compatible = "mediatek,mt6323-rtc", }, - { .compatible = "mediatek,mt6397-rtc", }, - { } - }; -@@ -410,7 +332,6 @@ static struct platform_driver mtk_rtc_driver = { - .pm = &mt6397_pm_ops, - }, - .probe = mtk_rtc_probe, -- .remove = mtk_rtc_remove, - }; - - module_platform_driver(mtk_rtc_driver); -diff --git a/include/linux/mfd/mt6397/core.h b/include/linux/mfd/mt6397/core.h -index d678f526e4986..0425c68cc1877 100644 ---- a/include/linux/mfd/mt6397/core.h -+++ b/include/linux/mfd/mt6397/core.h -@@ -15,6 +15,8 @@ - #ifndef __MFD_MT6397_CORE_H__ - #define __MFD_MT6397_CORE_H__ - -+#include -+ - enum mt6397_irq_numbers { - MT6397_IRQ_SPKL_AB = 0, - MT6397_IRQ_SPKR_AB, -diff --git a/include/linux/mfd/mt6397/rtc.h b/include/linux/mfd/mt6397/rtc.h -new file mode 100644 -index 0000000000000..ac932c93da8f2 ---- /dev/null -+++ b/include/linux/mfd/mt6397/rtc.h -@@ -0,0 +1,71 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2014-2018 MediaTek Inc. -+ * -+ * Author: Tianping.Fang -+ * Sean Wang -+ */ -+ -+#ifndef _LINUX_MFD_MT6397_RTC_H_ -+#define _LINUX_MFD_MT6397_RTC_H_ -+ -+#include -+#include -+#include -+#include -+ -+#define RTC_BBPU 0x0000 -+#define RTC_BBPU_CBUSY BIT(6) -+#define RTC_BBPU_KEY (0x43 << 8) -+ -+#define RTC_WRTGR 0x003c -+ -+#define RTC_IRQ_STA 0x0002 -+#define RTC_IRQ_STA_AL BIT(0) -+#define RTC_IRQ_STA_LP BIT(3) -+ -+#define RTC_IRQ_EN 0x0004 -+#define RTC_IRQ_EN_AL BIT(0) -+#define RTC_IRQ_EN_ONESHOT BIT(2) -+#define RTC_IRQ_EN_LP BIT(3) -+#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL) -+ -+#define RTC_AL_MASK 0x0008 -+#define RTC_AL_MASK_DOW BIT(4) -+ -+#define RTC_TC_SEC 0x000a -+/* Min, Hour, Dom... register offset to RTC_TC_SEC */ -+#define RTC_OFFSET_SEC 0 -+#define RTC_OFFSET_MIN 1 -+#define RTC_OFFSET_HOUR 2 -+#define RTC_OFFSET_DOM 3 -+#define RTC_OFFSET_DOW 4 -+#define RTC_OFFSET_MTH 5 -+#define RTC_OFFSET_YEAR 6 -+#define RTC_OFFSET_COUNT 7 -+ -+#define RTC_AL_SEC 0x0018 -+ -+#define RTC_PDN2 0x002e -+#define RTC_PDN2_PWRON_ALARM BIT(4) -+ -+#define RTC_MIN_YEAR 1968 -+#define RTC_BASE_YEAR 1900 -+#define RTC_NUM_YEARS 128 -+#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR) -+ -+#define MTK_RTC_POLL_DELAY_US 10 -+#define MTK_RTC_POLL_TIMEOUT (jiffies_to_usecs(HZ)) -+ -+struct mt6397_rtc { -+ struct device *dev; -+ struct rtc_device *rtc_dev; -+ -+ /* Protect register access from multiple tasks */ -+ struct mutex lock; -+ struct regmap *regmap; -+ int irq; -+ u32 addr_base; -+}; -+ -+#endif /* _LINUX_MFD_MT6397_RTC_H_ */ diff --git a/patch/kernel/archive/mt7623-4.19/aufs4.19-20181029.patch b/patch/kernel/archive/mt7623-4.19/aufs4.19-20181029.patch deleted file mode 100644 index f11b030b2cc2..000000000000 --- a/patch/kernel/archive/mt7623-4.19/aufs4.19-20181029.patch +++ /dev/null @@ -1,39290 +0,0 @@ -diff --git a/Documentation/ABI/testing/debugfs-aufs b/Documentation/ABI/testing/debugfs-aufs -new file mode 100644 -index 000000000..4a6694194 ---- /dev/null -+++ b/Documentation/ABI/testing/debugfs-aufs -@@ -0,0 +1,55 @@ -+What: /debug/aufs/si_/ -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ Under /debug/aufs, a directory named si_ is created -+ per aufs mount, where is a unique id generated -+ internally. -+ -+What: /debug/aufs/si_/plink -+Date: Apr 2013 -+Contact: J. R. Okajima -+Description: -+ It has three lines and shows the information about the -+ pseudo-link. The first line is a single number -+ representing a number of buckets. The second line is a -+ number of pseudo-links per buckets (separated by a -+ blank). The last line is a single number representing a -+ total number of psedo-links. -+ When the aufs mount option 'noplink' is specified, it -+ will show "1\n0\n0\n". -+ -+What: /debug/aufs/si_/xib -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ It shows the consumed blocks by xib (External Inode Number -+ Bitmap), its block size and file size. -+ When the aufs mount option 'noxino' is specified, it -+ will be empty. About XINO files, see the aufs manual. -+ -+What: /debug/aufs/si_/xi0, xi1 ... xiN and xiN-N -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ It shows the consumed blocks by xino (External Inode Number -+ Translation Table), its link count, block size and file -+ size. -+ Due to the file size limit, there may exist multiple -+ xino files per branch. In this case, "-N" is added to -+ the filename and it corresponds to the index of the -+ internal xino array. "-0" is omitted. -+ When the aufs mount option 'noxino' is specified, Those -+ entries won't exist. About XINO files, see the aufs -+ manual. -+ -+What: /debug/aufs/si_/xigen -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ It shows the consumed blocks by xigen (External Inode -+ Generation Table), its block size and file size. -+ If CONFIG_AUFS_EXPORT is disabled, this entry will not -+ be created. -+ When the aufs mount option 'noxino' is specified, it -+ will be empty. About XINO files, see the aufs manual. -diff --git a/Documentation/ABI/testing/sysfs-aufs b/Documentation/ABI/testing/sysfs-aufs -new file mode 100644 -index 000000000..82f951849 ---- /dev/null -+++ b/Documentation/ABI/testing/sysfs-aufs -@@ -0,0 +1,31 @@ -+What: /sys/fs/aufs/si_/ -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ Under /sys/fs/aufs, a directory named si_ is created -+ per aufs mount, where is a unique id generated -+ internally. -+ -+What: /sys/fs/aufs/si_/br0, br1 ... brN -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ It shows the abolute path of a member directory (which -+ is called branch) in aufs, and its permission. -+ -+What: /sys/fs/aufs/si_/brid0, brid1 ... bridN -+Date: July 2013 -+Contact: J. R. Okajima -+Description: -+ It shows the id of a member directory (which is called -+ branch) in aufs. -+ -+What: /sys/fs/aufs/si_/xi_path -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ It shows the abolute path of XINO (External Inode Number -+ Bitmap, Translation Table and Generation Table) file -+ even if it is the default path. -+ When the aufs mount option 'noxino' is specified, it -+ will be empty. About XINO files, see the aufs manual. -diff --git a/Documentation/filesystems/aufs/README b/Documentation/filesystems/aufs/README -new file mode 100644 -index 000000000..79eb50ae0 ---- /dev/null -+++ b/Documentation/filesystems/aufs/README -@@ -0,0 +1,394 @@ -+ -+Aufs4 -- advanced multi layered unification filesystem version 4.x -+http://aufs.sf.net -+Junjiro R. Okajima -+ -+ -+0. Introduction -+---------------------------------------- -+In the early days, aufs was entirely re-designed and re-implemented -+Unionfs Version 1.x series. Adding many original ideas, approaches, -+improvements and implementations, it becomes totally different from -+Unionfs while keeping the basic features. -+Recently, Unionfs Version 2.x series begin taking some of the same -+approaches to aufs1's. -+Unionfs is being developed by Professor Erez Zadok at Stony Brook -+University and his team. -+ -+Aufs4 supports linux-4.0 and later, and for linux-3.x series try aufs3. -+If you want older kernel version support, try aufs2-2.6.git or -+aufs2-standalone.git repository, aufs1 from CVS on SourceForge. -+ -+Note: it becomes clear that "Aufs was rejected. Let's give it up." -+ According to Christoph Hellwig, linux rejects all union-type -+ filesystems but UnionMount. -+ -+ -+PS. Al Viro seems have a plan to merge aufs as well as overlayfs and -+ UnionMount, and he pointed out an issue around a directory mutex -+ lock and aufs addressed it. But it is still unsure whether aufs will -+ be merged (or any other union solution). -+ -+ -+ -+1. Features -+---------------------------------------- -+- unite several directories into a single virtual filesystem. The member -+ directory is called as a branch. -+- you can specify the permission flags to the branch, which are 'readonly', -+ 'readwrite' and 'whiteout-able.' -+- by upper writable branch, internal copyup and whiteout, files/dirs on -+ readonly branch are modifiable logically. -+- dynamic branch manipulation, add, del. -+- etc... -+ -+Also there are many enhancements in aufs, such as: -+- test only the highest one for the directory permission (dirperm1) -+- copyup on open (coo=) -+- 'move' policy for copy-up between two writable branches, after -+ checking free space. -+- xattr, acl -+- readdir(3) in userspace. -+- keep inode number by external inode number table -+- keep the timestamps of file/dir in internal copyup operation -+- seekable directory, supporting NFS readdir. -+- whiteout is hardlinked in order to reduce the consumption of inodes -+ on branch -+- do not copyup, nor create a whiteout when it is unnecessary -+- revert a single systemcall when an error occurs in aufs -+- remount interface instead of ioctl -+- maintain /etc/mtab by an external command, /sbin/mount.aufs. -+- loopback mounted filesystem as a branch -+- kernel thread for removing the dir who has a plenty of whiteouts -+- support copyup sparse file (a file which has a 'hole' in it) -+- default permission flags for branches -+- selectable permission flags for ro branch, whether whiteout can -+ exist or not -+- export via NFS. -+- support /fs/aufs and /aufs. -+- support multiple writable branches, some policies to select one -+ among multiple writable branches. -+- a new semantics for link(2) and rename(2) to support multiple -+ writable branches. -+- no glibc changes are required. -+- pseudo hardlink (hardlink over branches) -+- allow a direct access manually to a file on branch, e.g. bypassing aufs. -+ including NFS or remote filesystem branch. -+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX. -+- and more... -+ -+Currently these features are dropped temporary from aufs4. -+See design/08plan.txt in detail. -+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs -+ (robr) -+- statistics of aufs thread (/sys/fs/aufs/stat) -+ -+Features or just an idea in the future (see also design/*.txt), -+- reorder the branch index without del/re-add. -+- permanent xino files for NFSD -+- an option for refreshing the opened files after add/del branches -+- light version, without branch manipulation. (unnecessary?) -+- copyup in userspace -+- inotify in userspace -+- readv/writev -+ -+ -+2. Download -+---------------------------------------- -+There are three GIT trees for aufs4, aufs4-linux.git, -+aufs4-standalone.git, and aufs-util.git. Note that there is no "4" in -+"aufs-util.git." -+While the aufs-util is always necessary, you need either of aufs4-linux -+or aufs4-standalone. -+ -+The aufs4-linux tree includes the whole linux mainline GIT tree, -+git://git.kernel.org/.../torvalds/linux.git. -+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot -+build aufs4 as an external kernel module. -+Several extra patches are not included in this tree. Only -+aufs4-standalone tree contains them. They are described in the later -+section "Configuration and Compilation." -+ -+On the other hand, the aufs4-standalone tree has only aufs source files -+and necessary patches, and you can select CONFIG_AUFS_FS=m. -+But you need to apply all aufs patches manually. -+ -+You will find GIT branches whose name is in form of "aufs4.x" where "x" -+represents the linux kernel version, "linux-4.x". For instance, -+"aufs4.0" is for linux-4.0. For latest "linux-4.x-rcN", use -+"aufs4.x-rcN" branch. -+ -+o aufs4-linux tree -+$ git clone --reference /your/linux/git/tree \ -+ git://github.com/sfjro/aufs4-linux.git aufs4-linux.git -+- if you don't have linux GIT tree, then remove "--reference ..." -+$ cd aufs4-linux.git -+$ git checkout origin/aufs4.0 -+ -+Or You may want to directly git-pull aufs into your linux GIT tree, and -+leave the patch-work to GIT. -+$ cd /your/linux/git/tree -+$ git remote add aufs4 git://github.com/sfjro/aufs4-linux.git -+$ git fetch aufs4 -+$ git checkout -b my4.0 v4.0 -+$ (add your local change...) -+$ git pull aufs4 aufs4.0 -+- now you have v4.0 + your_changes + aufs4.0 in you my4.0 branch. -+- you may need to solve some conflicts between your_changes and -+ aufs4.0. in this case, git-rerere is recommended so that you can -+ solve the similar conflicts automatically when you upgrade to 4.1 or -+ later in the future. -+ -+o aufs4-standalone tree -+$ git clone git://github.com/sfjro/aufs4-standalone.git aufs4-standalone.git -+$ cd aufs4-standalone.git -+$ git checkout origin/aufs4.0 -+ -+o aufs-util tree -+$ git clone git://git.code.sf.net/p/aufs/aufs-util aufs-util.git -+- note that the public aufs-util.git is on SourceForge instead of -+ GitHUB. -+$ cd aufs-util.git -+$ git checkout origin/aufs4.0 -+ -+Note: The 4.x-rcN branch is to be used with `rc' kernel versions ONLY. -+The minor version number, 'x' in '4.x', of aufs may not always -+follow the minor version number of the kernel. -+Because changes in the kernel that cause the use of a new -+minor version number do not always require changes to aufs-util. -+ -+Since aufs-util has its own minor version number, you may not be -+able to find a GIT branch in aufs-util for your kernel's -+exact minor version number. -+In this case, you should git-checkout the branch for the -+nearest lower number. -+ -+For (an unreleased) example: -+If you are using "linux-4.10" and the "aufs4.10" branch -+does not exist in aufs-util repository, then "aufs4.9", "aufs4.8" -+or something numerically smaller is the branch for your kernel. -+ -+Also you can view all branches by -+ $ git branch -a -+ -+ -+3. Configuration and Compilation -+---------------------------------------- -+Make sure you have git-checkout'ed the correct branch. -+ -+For aufs4-linux tree, -+- enable CONFIG_AUFS_FS. -+- set other aufs configurations if necessary. -+ -+For aufs4-standalone tree, -+There are several ways to build. -+ -+1. -+- apply ./aufs4-kbuild.patch to your kernel source files. -+- apply ./aufs4-base.patch too. -+- apply ./aufs4-mmap.patch too. -+- apply ./aufs4-standalone.patch too, if you have a plan to set -+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs4-standalone.patch. -+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your -+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild. -+- enable CONFIG_AUFS_FS, you can select either -+ =m or =y. -+- and build your kernel as usual. -+- install the built kernel. -+ Note: Since linux-3.9, every filesystem module requires an alias -+ "fs-". You should make sure that "fs-aufs" is listed in your -+ modules.aliases file if you set CONFIG_AUFS_FS=m. -+- install the header files too by "make headers_install" to the -+ directory where you specify. By default, it is $PWD/usr. -+ "make help" shows a brief note for headers_install. -+- and reboot your system. -+ -+2. -+- module only (CONFIG_AUFS_FS=m). -+- apply ./aufs4-base.patch to your kernel source files. -+- apply ./aufs4-mmap.patch too. -+- apply ./aufs4-standalone.patch too. -+- build your kernel, don't forget "make headers_install", and reboot. -+- edit ./config.mk and set other aufs configurations if necessary. -+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes -+ every aufs configurations. -+- build the module by simple "make". -+ Note: Since linux-3.9, every filesystem module requires an alias -+ "fs-". You should make sure that "fs-aufs" is listed in your -+ modules.aliases file. -+- you can specify ${KDIR} make variable which points to your kernel -+ source tree. -+- install the files -+ + run "make install" to install the aufs module, or copy the built -+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply). -+ + run "make install_headers" (instead of headers_install) to install -+ the modified aufs header file (you can specify DESTDIR which is -+ available in aufs standalone version's Makefile only), or copy -+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever -+ you like manually. By default, the target directory is $PWD/usr. -+- no need to apply aufs4-kbuild.patch, nor copying source files to your -+ kernel source tree. -+ -+Note: The header file aufs_type.h is necessary to build aufs-util -+ as well as "make headers_install" in the kernel source tree. -+ headers_install is subject to be forgotten, but it is essentially -+ necessary, not only for building aufs-util. -+ You may not meet problems without headers_install in some older -+ version though. -+ -+And then, -+- read README in aufs-util, build and install it -+- note that your distribution may contain an obsoleted version of -+ aufs_type.h in /usr/include/linux or something. When you build aufs -+ utilities, make sure that your compiler refers the correct aufs header -+ file which is built by "make headers_install." -+- if you want to use readdir(3) in userspace or pathconf(3) wrapper, -+ then run "make install_ulib" too. And refer to the aufs manual in -+ detail. -+ -+There several other patches in aufs4-standalone.git. They are all -+optional. When you meet some problems, they will help you. -+- aufs4-loopback.patch -+ Supports a nested loopback mount in a branch-fs. This patch is -+ unnecessary until aufs produces a message like "you may want to try -+ another patch for loopback file". -+- vfs-ino.patch -+ Modifies a system global kernel internal function get_next_ino() in -+ order to stop assigning 0 for an inode-number. Not directly related to -+ aufs, but recommended generally. -+- tmpfs-idr.patch -+ Keeps the tmpfs inode number as the lowest value. Effective to reduce -+ the size of aufs XINO files for tmpfs branch. Also it prevents the -+ duplication of inode number, which is important for backup tools and -+ other utilities. When you find aufs XINO files for tmpfs branch -+ growing too much, try this patch. -+- lockdep-debug.patch -+ Because aufs is not only an ordinary filesystem (callee of VFS), but -+ also a caller of VFS functions for branch filesystems, subclassing of -+ the internal locks for LOCKDEP is necessary. LOCKDEP is a debugging -+ feature of linux kernel. If you enable CONFIG_LOCKDEP, then you will -+ need to apply this debug patch to expand several constant values. -+ If don't know what LOCKDEP, then you don't have apply this patch. -+ -+ -+4. Usage -+---------------------------------------- -+At first, make sure aufs-util are installed, and please read the aufs -+manual, aufs.5 in aufs-util.git tree. -+$ man -l aufs.5 -+ -+And then, -+$ mkdir /tmp/rw /tmp/aufs -+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs -+ -+Here is another example. The result is equivalent. -+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs -+ Or -+# mount -t aufs -o br:/tmp/rw none /tmp/aufs -+# mount -o remount,append:${HOME} /tmp/aufs -+ -+Then, you can see whole tree of your home dir through /tmp/aufs. If -+you modify a file under /tmp/aufs, the one on your home directory is -+not affected, instead the same named file will be newly created under -+/tmp/rw. And all of your modification to a file will be applied to -+the one under /tmp/rw. This is called the file based Copy on Write -+(COW) method. -+Aufs mount options are described in aufs.5. -+If you run chroot or something and make your aufs as a root directory, -+then you need to customize the shutdown script. See the aufs manual in -+detail. -+ -+Additionally, there are some sample usages of aufs which are a -+diskless system with network booting, and LiveCD over NFS. -+See sample dir in CVS tree on SourceForge. -+ -+ -+5. Contact -+---------------------------------------- -+When you have any problems or strange behaviour in aufs, please let me -+know with: -+- /proc/mounts (instead of the output of mount(8)) -+- /sys/module/aufs/* -+- /sys/fs/aufs/* (if you have them) -+- /debug/aufs/* (if you have them) -+- linux kernel version -+ if your kernel is not plain, for example modified by distributor, -+ the url where i can download its source is necessary too. -+- aufs version which was printed at loading the module or booting the -+ system, instead of the date you downloaded. -+- configuration (define/undefine CONFIG_AUFS_xxx) -+- kernel configuration or /proc/config.gz (if you have it) -+- behaviour which you think to be incorrect -+- actual operation, reproducible one is better -+- mailto: aufs-users at lists.sourceforge.net -+ -+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches, -+and Feature Requests) on SourceForge. Please join and write to -+aufs-users ML. -+ -+ -+6. Acknowledgements -+---------------------------------------- -+Thanks to everyone who have tried and are using aufs, whoever -+have reported a bug or any feedback. -+ -+Especially donators: -+Tomas Matejicek(slax.org) made a donation (much more than once). -+ Since Apr 2010, Tomas M (the author of Slax and Linux Live -+ scripts) is making "doubling" donations. -+ Unfortunately I cannot list all of the donators, but I really -+ appreciate. -+ It ends Aug 2010, but the ordinary donation URL is still available. -+ -+Dai Itasaka made a donation (2007/8). -+Chuck Smith made a donation (2008/4, 10 and 12). -+Henk Schoneveld made a donation (2008/9). -+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10). -+Francois Dupoux made a donation (2008/11). -+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public -+ aufs2 GIT tree (2009/2). -+William Grant made a donation (2009/3). -+Patrick Lane made a donation (2009/4). -+The Mail Archive (mail-archive.com) made donations (2009/5). -+Nippy Networks (Ed Wildgoose) made a donation (2009/7). -+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11). -+Pavel Pronskiy made a donation (2011/2). -+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy -+ Networks (Ed Wildgoose) made a donation for hardware (2011/3). -+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and -+11). -+Sam Liddicott made a donation (2011/9). -+Era Scarecrow made a donation (2013/4). -+Bor Ratajc made a donation (2013/4). -+Alessandro Gorreta made a donation (2013/4). -+POIRETTE Marc made a donation (2013/4). -+Alessandro Gorreta made a donation (2013/4). -+lauri kasvandik made a donation (2013/5). -+"pemasu from Finland" made a donation (2013/7). -+The Parted Magic Project made a donation (2013/9 and 11). -+Pavel Barta made a donation (2013/10). -+Nikolay Pertsev made a donation (2014/5). -+James B made a donation (2014/7 and 2015/7). -+Stefano Di Biase made a donation (2014/8). -+Daniel Epellei made a donation (2015/1). -+OmegaPhil made a donation (2016/1, 2018/4). -+Tomasz Szewczyk made a donation (2016/4). -+James Burry made a donation (2016/12). -+Carsten Rose made a donation (2018/9). -+ -+Thank you very much. -+Donations are always, including future donations, very important and -+helpful for me to keep on developing aufs. -+ -+ -+7. -+---------------------------------------- -+If you are an experienced user, no explanation is needed. Aufs is -+just a linux filesystem. -+ -+ -+Enjoy! -+ -+# Local variables: ; -+# mode: text; -+# End: ; -diff --git a/Documentation/filesystems/aufs/design/01intro.txt b/Documentation/filesystems/aufs/design/01intro.txt -new file mode 100644 -index 000000000..aa1052982 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/01intro.txt -@@ -0,0 +1,171 @@ -+ -+# Copyright (C) 2005-2018 Junjiro R. Okajima -+# -+# 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, see . -+ -+Introduction -+---------------------------------------- -+ -+aufs [ei ju: ef es] | /ey-yoo-ef-es/ | [a u f s] -+1. abbrev. for "advanced multi-layered unification filesystem". -+2. abbrev. for "another unionfs". -+3. abbrev. for "auf das" in German which means "on the" in English. -+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E). -+ But "Filesystem aufs Filesystem" is hard to understand. -+4. abbrev. for "African Urban Fashion Show". -+ -+AUFS is a filesystem with features: -+- multi layered stackable unification filesystem, the member directory -+ is called as a branch. -+- branch permission and attribute, 'readonly', 'real-readonly', -+ 'readwrite', 'whiteout-able', 'link-able whiteout', etc. and their -+ combination. -+- internal "file copy-on-write". -+- logical deletion, whiteout. -+- dynamic branch manipulation, adding, deleting and changing permission. -+- allow bypassing aufs, user's direct branch access. -+- external inode number translation table and bitmap which maintains the -+ persistent aufs inode number. -+- seekable directory, including NFS readdir. -+- file mapping, mmap and sharing pages. -+- pseudo-link, hardlink over branches. -+- loopback mounted filesystem as a branch. -+- several policies to select one among multiple writable branches. -+- revert a single systemcall when an error occurs in aufs. -+- and more... -+ -+ -+Multi Layered Stackable Unification Filesystem -+---------------------------------------------------------------------- -+Most people already knows what it is. -+It is a filesystem which unifies several directories and provides a -+merged single directory. When users access a file, the access will be -+passed/re-directed/converted (sorry, I am not sure which English word is -+correct) to the real file on the member filesystem. The member -+filesystem is called 'lower filesystem' or 'branch' and has a mode -+'readonly' and 'readwrite.' And the deletion for a file on the lower -+readonly branch is handled by creating 'whiteout' on the upper writable -+branch. -+ -+On LKML, there have been discussions about UnionMount (Jan Blunck, -+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took -+different approaches to implement the merged-view. -+The former tries putting it into VFS, and the latter implements as a -+separate filesystem. -+(If I misunderstand about these implementations, please let me know and -+I shall correct it. Because it is a long time ago when I read their -+source files last time). -+ -+UnionMount's approach will be able to small, but may be hard to share -+branches between several UnionMount since the whiteout in it is -+implemented in the inode on branch filesystem and always -+shared. According to Bharata's post, readdir does not seems to be -+finished yet. -+There are several missing features known in this implementations such as -+- for users, the inode number may change silently. eg. copy-up. -+- link(2) may break by copy-up. -+- read(2) may get an obsoleted filedata (fstat(2) too). -+- fcntl(F_SETLK) may be broken by copy-up. -+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after -+ open(O_RDWR). -+ -+In linux-3.18, "overlay" filesystem (formerly known as "overlayfs") was -+merged into mainline. This is another implementation of UnionMount as a -+separated filesystem. All the limitations and known problems which -+UnionMount are equally inherited to "overlay" filesystem. -+ -+Unionfs has a longer history. When I started implementing a stackable -+filesystem (Aug 2005), it already existed. It has virtual super_block, -+inode, dentry and file objects and they have an array pointing lower -+same kind objects. After contributing many patches for Unionfs, I -+re-started my project AUFS (Jun 2006). -+ -+In AUFS, the structure of filesystem resembles to Unionfs, but I -+implemented my own ideas, approaches and enhancements and it became -+totally different one. -+ -+Comparing DM snapshot and fs based implementation -+- the number of bytes to be copied between devices is much smaller. -+- the type of filesystem must be one and only. -+- the fs must be writable, no readonly fs, even for the lower original -+ device. so the compression fs will not be usable. but if we use -+ loopback mount, we may address this issue. -+ for instance, -+ mount /cdrom/squashfs.img /sq -+ losetup /sq/ext2.img -+ losetup /somewhere/cow -+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..." -+- it will be difficult (or needs more operations) to extract the -+ difference between the original device and COW. -+- DM snapshot-merge may help a lot when users try merging. in the -+ fs-layer union, users will use rsync(1). -+ -+You may want to read my old paper "Filesystems in LiveCD" -+(http://aufs.sourceforge.net/aufs2/report/sq/sq.pdf). -+ -+ -+Several characters/aspects/persona of aufs -+---------------------------------------------------------------------- -+ -+Aufs has several characters, aspects or persona. -+1. a filesystem, callee of VFS helper -+2. sub-VFS, caller of VFS helper for branches -+3. a virtual filesystem which maintains persistent inode number -+4. reader/writer of files on branches such like an application -+ -+1. Callee of VFS Helper -+As an ordinary linux filesystem, aufs is a callee of VFS. For instance, -+unlink(2) from an application reaches sys_unlink() kernel function and -+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it -+calls filesystem specific unlink operation. Actually aufs implements the -+unlink operation but it behaves like a redirector. -+ -+2. Caller of VFS Helper for Branches -+aufs_unlink() passes the unlink request to the branch filesystem as if -+it were called from VFS. So the called unlink operation of the branch -+filesystem acts as usual. As a caller of VFS helper, aufs should handle -+every necessary pre/post operation for the branch filesystem. -+- acquire the lock for the parent dir on a branch -+- lookup in a branch -+- revalidate dentry on a branch -+- mnt_want_write() for a branch -+- vfs_unlink() for a branch -+- mnt_drop_write() for a branch -+- release the lock on a branch -+ -+3. Persistent Inode Number -+One of the most important issue for a filesystem is to maintain inode -+numbers. This is particularly important to support exporting a -+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a -+backend block device for its own. But some storage is necessary to -+keep and maintain the inode numbers. It may be a large space and may not -+suit to keep in memory. Aufs rents some space from its first writable -+branch filesystem (by default) and creates file(s) on it. These files -+are created by aufs internally and removed soon (currently) keeping -+opened. -+Note: Because these files are removed, they are totally gone after -+ unmounting aufs. It means the inode numbers are not persistent -+ across unmount or reboot. I have a plan to make them really -+ persistent which will be important for aufs on NFS server. -+ -+4. Read/Write Files Internally (copy-on-write) -+Because a branch can be readonly, when you write a file on it, aufs will -+"copy-up" it to the upper writable branch internally. And then write the -+originally requested thing to the file. Generally kernel doesn't -+open/read/write file actively. In aufs, even a single write may cause a -+internal "file copy". This behaviour is very similar to cp(1) command. -+ -+Some people may think it is better to pass such work to user space -+helper, instead of doing in kernel space. Actually I am still thinking -+about it. But currently I have implemented it in kernel space. -diff --git a/Documentation/filesystems/aufs/design/02struct.txt b/Documentation/filesystems/aufs/design/02struct.txt -new file mode 100644 -index 000000000..f5fb6a8ad ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/02struct.txt -@@ -0,0 +1,258 @@ -+ -+# Copyright (C) 2005-2018 Junjiro R. Okajima -+# -+# 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, see . -+ -+Basic Aufs Internal Structure -+ -+Superblock/Inode/Dentry/File Objects -+---------------------------------------------------------------------- -+As like an ordinary filesystem, aufs has its own -+superblock/inode/dentry/file objects. All these objects have a -+dynamically allocated array and store the same kind of pointers to the -+lower filesystem, branch. -+For example, when you build a union with one readwrite branch and one -+readonly, mounted /au, /rw and /ro respectively. -+- /au = /rw + /ro -+- /ro/fileA exists but /rw/fileA -+ -+Aufs lookup operation finds /ro/fileA and gets dentry for that. These -+pointers are stored in a aufs dentry. The array in aufs dentry will be, -+- [0] = NULL (because /rw/fileA doesn't exist) -+- [1] = /ro/fileA -+ -+This style of an array is essentially same to the aufs -+superblock/inode/dentry/file objects. -+ -+Because aufs supports manipulating branches, ie. add/delete/change -+branches dynamically, these objects has its own generation. When -+branches are changed, the generation in aufs superblock is -+incremented. And a generation in other object are compared when it is -+accessed. When a generation in other objects are obsoleted, aufs -+refreshes the internal array. -+ -+ -+Superblock -+---------------------------------------------------------------------- -+Additionally aufs superblock has some data for policies to select one -+among multiple writable branches, XIB files, pseudo-links and kobject. -+See below in detail. -+About the policies which supports copy-down a directory, see -+wbr_policy.txt too. -+ -+ -+Branch and XINO(External Inode Number Translation Table) -+---------------------------------------------------------------------- -+Every branch has its own xino (external inode number translation table) -+file. The xino file is created and unlinked by aufs internally. When two -+members of a union exist on the same filesystem, they share the single -+xino file. -+The struct of a xino file is simple, just a sequence of aufs inode -+numbers which is indexed by the lower inode number. -+In the above sample, assume the inode number of /ro/fileA is i111 and -+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as -+4(8) bytes at 111 * 4(8) bytes offset in the xino file. -+ -+When the inode numbers are not contiguous, the xino file will be sparse -+which has a hole in it and doesn't consume as much disk space as it -+might appear. If your branch filesystem consumes disk space for such -+holes, then you should specify 'xino=' option at mounting aufs. -+ -+Aufs has a mount option to free the disk blocks for such holes in XINO -+files on tmpfs or ramdisk. But it is not so effective actually. If you -+meet a problem of disk shortage due to XINO files, then you should try -+"tmpfs-ino.patch" (and "vfs-ino.patch" too) in aufs4-standalone.git. -+The patch localizes the assignment inumbers per tmpfs-mount and avoid -+the holes in XINO files. -+ -+Also a writable branch has three kinds of "whiteout bases". All these -+are existed when the branch is joined to aufs, and their names are -+whiteout-ed doubly, so that users will never see their names in aufs -+hierarchy. -+1. a regular file which will be hardlinked to all whiteouts. -+2. a directory to store a pseudo-link. -+3. a directory to store an "orphan"-ed file temporary. -+ -+1. Whiteout Base -+ When you remove a file on a readonly branch, aufs handles it as a -+ logical deletion and creates a whiteout on the upper writable branch -+ as a hardlink of this file in order not to consume inode on the -+ writable branch. -+2. Pseudo-link Dir -+ See below, Pseudo-link. -+3. Step-Parent Dir -+ When "fileC" exists on the lower readonly branch only and it is -+ opened and removed with its parent dir, and then user writes -+ something into it, then aufs copies-up fileC to this -+ directory. Because there is no other dir to store fileC. After -+ creating a file under this dir, the file is unlinked. -+ -+Because aufs supports manipulating branches, ie. add/delete/change -+dynamically, a branch has its own id. When the branch order changes, -+aufs finds the new index by searching the branch id. -+ -+ -+Pseudo-link -+---------------------------------------------------------------------- -+Assume "fileA" exists on the lower readonly branch only and it is -+hardlinked to "fileB" on the branch. When you write something to fileA, -+aufs copies-up it to the upper writable branch. Additionally aufs -+creates a hardlink under the Pseudo-link Directory of the writable -+branch. The inode of a pseudo-link is kept in aufs super_block as a -+simple list. If fileB is read after unlinking fileA, aufs returns -+filedata from the pseudo-link instead of the lower readonly -+branch. Because the pseudo-link is based upon the inode, to keep the -+inode number by xino (see above) is essentially necessary. -+ -+All the hardlinks under the Pseudo-link Directory of the writable branch -+should be restored in a proper location later. Aufs provides a utility -+to do this. The userspace helpers executed at remounting and unmounting -+aufs by default. -+During this utility is running, it puts aufs into the pseudo-link -+maintenance mode. In this mode, only the process which began the -+maintenance mode (and its child processes) is allowed to operate in -+aufs. Some other processes which are not related to the pseudo-link will -+be allowed to run too, but the rest have to return an error or wait -+until the maintenance mode ends. If a process already acquires an inode -+mutex (in VFS), it has to return an error. -+ -+ -+XIB(external inode number bitmap) -+---------------------------------------------------------------------- -+Addition to the xino file per a branch, aufs has an external inode number -+bitmap in a superblock object. It is also an internal file such like a -+xino file. -+It is a simple bitmap to mark whether the aufs inode number is in-use or -+not. -+To reduce the file I/O, aufs prepares a single memory page to cache xib. -+ -+As well as XINO files, aufs has a feature to truncate/refresh XIB to -+reduce the number of consumed disk blocks for these files. -+ -+ -+Virtual or Vertical Dir, and Readdir in Userspace -+---------------------------------------------------------------------- -+In order to support multiple layers (branches), aufs readdir operation -+constructs a virtual dir block on memory. For readdir, aufs calls -+vfs_readdir() internally for each dir on branches, merges their entries -+with eliminating the whiteout-ed ones, and sets it to file (dir) -+object. So the file object has its entry list until it is closed. The -+entry list will be updated when the file position is zero and becomes -+obsoleted. This decision is made in aufs automatically. -+ -+The dynamically allocated memory block for the name of entries has a -+unit of 512 bytes (by default) and stores the names contiguously (no -+padding). Another block for each entry is handled by kmem_cache too. -+During building dir blocks, aufs creates hash list and judging whether -+the entry is whiteouted by its upper branch or already listed. -+The merged result is cached in the corresponding inode object and -+maintained by a customizable life-time option. -+ -+Some people may call it can be a security hole or invite DoS attack -+since the opened and once readdir-ed dir (file object) holds its entry -+list and becomes a pressure for system memory. But I'd say it is similar -+to files under /proc or /sys. The virtual files in them also holds a -+memory page (generally) while they are opened. When an idea to reduce -+memory for them is introduced, it will be applied to aufs too. -+For those who really hate this situation, I've developed readdir(3) -+library which operates this merging in userspace. You just need to set -+LD_PRELOAD environment variable, and aufs will not consume no memory in -+kernel space for readdir(3). -+ -+ -+Workqueue -+---------------------------------------------------------------------- -+Aufs sometimes requires privilege access to a branch. For instance, -+in copy-up/down operation. When a user process is going to make changes -+to a file which exists in the lower readonly branch only, and the mode -+of one of ancestor directories may not be writable by a user -+process. Here aufs copy-up the file with its ancestors and they may -+require privilege to set its owner/group/mode/etc. -+This is a typical case of a application character of aufs (see -+Introduction). -+ -+Aufs uses workqueue synchronously for this case. It creates its own -+workqueue. The workqueue is a kernel thread and has privilege. Aufs -+passes the request to call mkdir or write (for example), and wait for -+its completion. This approach solves a problem of a signal handler -+simply. -+If aufs didn't adopt the workqueue and changed the privilege of the -+process, then the process may receive the unexpected SIGXFSZ or other -+signals. -+ -+Also aufs uses the system global workqueue ("events" kernel thread) too -+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a -+whiteout base and etc. This is unrelated to a privilege. -+Most of aufs operation tries acquiring a rw_semaphore for aufs -+superblock at the beginning, at the same time waits for the completion -+of all queued asynchronous tasks. -+ -+ -+Whiteout -+---------------------------------------------------------------------- -+The whiteout in aufs is very similar to Unionfs's. That is represented -+by its filename. UnionMount takes an approach of a file mode, but I am -+afraid several utilities (find(1) or something) will have to support it. -+ -+Basically the whiteout represents "logical deletion" which stops aufs to -+lookup further, but also it represents "dir is opaque" which also stop -+further lookup. -+ -+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively. -+In order to make several functions in a single systemcall to be -+revertible, aufs adopts an approach to rename a directory to a temporary -+unique whiteouted name. -+For example, in rename(2) dir where the target dir already existed, aufs -+renames the target dir to a temporary unique whiteouted name before the -+actual rename on a branch, and then handles other actions (make it opaque, -+update the attributes, etc). If an error happens in these actions, aufs -+simply renames the whiteouted name back and returns an error. If all are -+succeeded, aufs registers a function to remove the whiteouted unique -+temporary name completely and asynchronously to the system global -+workqueue. -+ -+ -+Copy-up -+---------------------------------------------------------------------- -+It is a well-known feature or concept. -+When user modifies a file on a readonly branch, aufs operate "copy-up" -+internally and makes change to the new file on the upper writable branch. -+When the trigger systemcall does not update the timestamps of the parent -+dir, aufs reverts it after copy-up. -+ -+ -+Move-down (aufs3.9 and later) -+---------------------------------------------------------------------- -+"Copy-up" is one of the essential feature in aufs. It copies a file from -+the lower readonly branch to the upper writable branch when a user -+changes something about the file. -+"Move-down" is an opposite action of copy-up. Basically this action is -+ran manually instead of automatically and internally. -+For desgin and implementation, aufs has to consider these issues. -+- whiteout for the file may exist on the lower branch. -+- ancestor directories may not exist on the lower branch. -+- diropq for the ancestor directories may exist on the upper branch. -+- free space on the lower branch will reduce. -+- another access to the file may happen during moving-down, including -+ UDBA (see "Revalidate Dentry and UDBA"). -+- the file should not be hard-linked nor pseudo-linked. they should be -+ handled by auplink utility later. -+ -+Sometimes users want to move-down a file from the upper writable branch -+to the lower readonly or writable branch. For instance, -+- the free space of the upper writable branch is going to run out. -+- create a new intermediate branch between the upper and lower branch. -+- etc. -+ -+For this purpose, use "aumvdown" command in aufs-util.git. -diff --git a/Documentation/filesystems/aufs/design/03atomic_open.txt b/Documentation/filesystems/aufs/design/03atomic_open.txt -new file mode 100644 -index 000000000..1b0699f8b ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/03atomic_open.txt -@@ -0,0 +1,85 @@ -+ -+# Copyright (C) 2015-2018 Junjiro R. Okajima -+# -+# 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, see . -+ -+Support for a branch who has its ->atomic_open() -+---------------------------------------------------------------------- -+The filesystems who implement its ->atomic_open() are not majority. For -+example NFSv4 does, and aufs should call NFSv4 ->atomic_open, -+particularly for open(O_CREAT|O_EXCL, 0400) case. Other than -+->atomic_open(), NFSv4 returns an error for this open(2). While I am not -+sure whether all filesystems who have ->atomic_open() behave like this, -+but NFSv4 surely returns the error. -+ -+In order to support ->atomic_open() for aufs, there are a few -+approaches. -+ -+A. Introduce aufs_atomic_open() -+ - calls one of VFS:do_last(), lookup_open() or atomic_open() for -+ branch fs. -+B. Introduce aufs_atomic_open() calling create, open and chmod. this is -+ an aufs user Pip Cet's approach -+ - calls aufs_create(), VFS finish_open() and notify_change(). -+ - pass fake-mode to finish_open(), and then correct the mode by -+ notify_change(). -+C. Extend aufs_open() to call branch fs's ->atomic_open() -+ - no aufs_atomic_open(). -+ - aufs_lookup() registers the TID to an aufs internal object. -+ - aufs_create() does nothing when the matching TID is registered, but -+ registers the mode. -+ - aufs_open() calls branch fs's ->atomic_open() when the matching -+ TID is registered. -+D. Extend aufs_open() to re-try branch fs's ->open() with superuser's -+ credential -+ - no aufs_atomic_open(). -+ - aufs_create() registers the TID to an internal object. this info -+ represents "this process created this file just now." -+ - when aufs gets EACCES from branch fs's ->open(), then confirm the -+ registered TID and re-try open() with superuser's credential. -+ -+Pros and cons for each approach. -+ -+A. -+ - straightforward but highly depends upon VFS internal. -+ - the atomic behavaiour is kept. -+ - some of parameters such as nameidata are hard to reproduce for -+ branch fs. -+ - large overhead. -+B. -+ - easy to implement. -+ - the atomic behavaiour is lost. -+C. -+ - the atomic behavaiour is kept. -+ - dirty and tricky. -+ - VFS checks whether the file is created correctly after calling -+ ->create(), which means this approach doesn't work. -+D. -+ - easy to implement. -+ - the atomic behavaiour is lost. -+ - to open a file with superuser's credential and give it to a user -+ process is a bad idea, since the file object keeps the credential -+ in it. It may affect LSM or something. This approach doesn't work -+ either. -+ -+The approach A is ideal, but it hard to implement. So here is a -+variation of A, which is to be implemented. -+ -+A-1. Introduce aufs_atomic_open() -+ - calls branch fs ->atomic_open() if exists. otherwise calls -+ vfs_create() and finish_open(). -+ - the demerit is that the several checks after branch fs -+ ->atomic_open() are lost. in the ordinary case, the checks are -+ done by VFS:do_last(), lookup_open() and atomic_open(). some can -+ be implemented in aufs, but not all I am afraid. -diff --git a/Documentation/filesystems/aufs/design/03lookup.txt b/Documentation/filesystems/aufs/design/03lookup.txt -new file mode 100644 -index 000000000..80ae63bce ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/03lookup.txt -@@ -0,0 +1,113 @@ -+ -+# Copyright (C) 2005-2018 Junjiro R. Okajima -+# -+# 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, see . -+ -+Lookup in a Branch -+---------------------------------------------------------------------- -+Since aufs has a character of sub-VFS (see Introduction), it operates -+lookup for branches as VFS does. It may be a heavy work. But almost all -+lookup operation in aufs is the simplest case, ie. lookup only an entry -+directly connected to its parent. Digging down the directory hierarchy -+is unnecessary. VFS has a function lookup_one_len() for that use, and -+aufs calls it. -+ -+When a branch is a remote filesystem, aufs basically relies upon its -+->d_revalidate(), also aufs forces the hardest revalidate tests for -+them. -+For d_revalidate, aufs implements three levels of revalidate tests. See -+"Revalidate Dentry and UDBA" in detail. -+ -+ -+Test Only the Highest One for the Directory Permission (dirperm1 option) -+---------------------------------------------------------------------- -+Let's try case study. -+- aufs has two branches, upper readwrite and lower readonly. -+ /au = /rw + /ro -+- "dirA" exists under /ro, but /rw. and its mode is 0700. -+- user invoked "chmod a+rx /au/dirA" -+- the internal copy-up is activated and "/rw/dirA" is created and its -+ permission bits are set to world readable. -+- then "/au/dirA" becomes world readable? -+ -+In this case, /ro/dirA is still 0700 since it exists in readonly branch, -+or it may be a natively readonly filesystem. If aufs respects the lower -+branch, it should not respond readdir request from other users. But user -+allowed it by chmod. Should really aufs rejects showing the entries -+under /ro/dirA? -+ -+To be honest, I don't have a good solution for this case. So aufs -+implements 'dirperm1' and 'nodirperm1' mount options, and leave it to -+users. -+When dirperm1 is specified, aufs checks only the highest one for the -+directory permission, and shows the entries. Otherwise, as usual, checks -+every dir existing on all branches and rejects the request. -+ -+As a side effect, dirperm1 option improves the performance of aufs -+because the number of permission check is reduced when the number of -+branch is many. -+ -+ -+Revalidate Dentry and UDBA (User's Direct Branch Access) -+---------------------------------------------------------------------- -+Generally VFS helpers re-validate a dentry as a part of lookup. -+0. digging down the directory hierarchy. -+1. lock the parent dir by its i_mutex. -+2. lookup the final (child) entry. -+3. revalidate it. -+4. call the actual operation (create, unlink, etc.) -+5. unlock the parent dir -+ -+If the filesystem implements its ->d_revalidate() (step 3), then it is -+called. Actually aufs implements it and checks the dentry on a branch is -+still valid. -+But it is not enough. Because aufs has to release the lock for the -+parent dir on a branch at the end of ->lookup() (step 2) and -+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still -+held by VFS. -+If the file on a branch is changed directly, eg. bypassing aufs, after -+aufs released the lock, then the subsequent operation may cause -+something unpleasant result. -+ -+This situation is a result of VFS architecture, ->lookup() and -+->d_revalidate() is separated. But I never say it is wrong. It is a good -+design from VFS's point of view. It is just not suitable for sub-VFS -+character in aufs. -+ -+Aufs supports such case by three level of revalidation which is -+selectable by user. -+1. Simple Revalidate -+ Addition to the native flow in VFS's, confirm the child-parent -+ relationship on the branch just after locking the parent dir on the -+ branch in the "actual operation" (step 4). When this validation -+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still -+ checks the validation of the dentry on branches. -+2. Monitor Changes Internally by Inotify/Fsnotify -+ Addition to above, in the "actual operation" (step 4) aufs re-lookup -+ the dentry on the branch, and returns EBUSY if it finds different -+ dentry. -+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches -+ during it is in cache. When the event is notified, aufs registers a -+ function to kernel 'events' thread by schedule_work(). And the -+ function sets some special status to the cached aufs dentry and inode -+ private data. If they are not cached, then aufs has nothing to -+ do. When the same file is accessed through aufs (step 0-3) later, -+ aufs will detect the status and refresh all necessary data. -+ In this mode, aufs has to ignore the event which is fired by aufs -+ itself. -+3. No Extra Validation -+ This is the simplest test and doesn't add any additional revalidation -+ test, and skip the revalidation in step 4. It is useful and improves -+ aufs performance when system surely hide the aufs branches from user, -+ by over-mounting something (or another method). -diff --git a/Documentation/filesystems/aufs/design/04branch.txt b/Documentation/filesystems/aufs/design/04branch.txt -new file mode 100644 -index 000000000..0c1289737 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/04branch.txt -@@ -0,0 +1,74 @@ -+ -+# Copyright (C) 2005-2018 Junjiro R. Okajima -+# -+# 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, see . -+ -+Branch Manipulation -+ -+Since aufs supports dynamic branch manipulation, ie. add/remove a branch -+and changing its permission/attribute, there are a lot of works to do. -+ -+ -+Add a Branch -+---------------------------------------------------------------------- -+o Confirm the adding dir exists outside of aufs, including loopback -+ mount, and its various attributes. -+o Initialize the xino file and whiteout bases if necessary. -+ See struct.txt. -+ -+o Check the owner/group/mode of the directory -+ When the owner/group/mode of the adding directory differs from the -+ existing branch, aufs issues a warning because it may impose a -+ security risk. -+ For example, when a upper writable branch has a world writable empty -+ top directory, a malicious user can create any files on the writable -+ branch directly, like copy-up and modify manually. If something like -+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper -+ writable branch, and the writable branch is world-writable, then a -+ malicious guy may create /etc/passwd on the writable branch directly -+ and the infected file will be valid in aufs. -+ I am afraid it can be a security issue, but aufs can do nothing except -+ producing a warning. -+ -+ -+Delete a Branch -+---------------------------------------------------------------------- -+o Confirm the deleting branch is not busy -+ To be general, there is one merit to adopt "remount" interface to -+ manipulate branches. It is to discard caches. At deleting a branch, -+ aufs checks the still cached (and connected) dentries and inodes. If -+ there are any, then they are all in-use. An inode without its -+ corresponding dentry can be alive alone (for example, inotify/fsnotify case). -+ -+ For the cached one, aufs checks whether the same named entry exists on -+ other branches. -+ If the cached one is a directory, because aufs provides a merged view -+ to users, as long as one dir is left on any branch aufs can show the -+ dir to users. In this case, the branch can be removed from aufs. -+ Otherwise aufs rejects deleting the branch. -+ -+ If any file on the deleting branch is opened by aufs, then aufs -+ rejects deleting. -+ -+ -+Modify the Permission of a Branch -+---------------------------------------------------------------------- -+o Re-initialize or remove the xino file and whiteout bases if necessary. -+ See struct.txt. -+ -+o rw --> ro: Confirm the modifying branch is not busy -+ Aufs rejects the request if any of these conditions are true. -+ - a file on the branch is mmap-ed. -+ - a regular file on the branch is opened for write and there is no -+ same named entry on the upper branch. -diff --git a/Documentation/filesystems/aufs/design/05wbr_policy.txt b/Documentation/filesystems/aufs/design/05wbr_policy.txt -new file mode 100644 -index 000000000..cc5b7979c ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/05wbr_policy.txt -@@ -0,0 +1,64 @@ -+ -+# Copyright (C) 2005-2018 Junjiro R. Okajima -+# -+# 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, see . -+ -+Policies to Select One among Multiple Writable Branches -+---------------------------------------------------------------------- -+When the number of writable branch is more than one, aufs has to decide -+the target branch for file creation or copy-up. By default, the highest -+writable branch which has the parent (or ancestor) dir of the target -+file is chosen (top-down-parent policy). -+By user's request, aufs implements some other policies to select the -+writable branch, for file creation several policies, round-robin, -+most-free-space, and other policies. For copy-up, top-down-parent, -+bottom-up-parent, bottom-up and others. -+ -+As expected, the round-robin policy selects the branch in circular. When -+you have two writable branches and creates 10 new files, 5 files will be -+created for each branch. mkdir(2) systemcall is an exception. When you -+create 10 new directories, all will be created on the same branch. -+And the most-free-space policy selects the one which has most free -+space among the writable branches. The amount of free space will be -+checked by aufs internally, and users can specify its time interval. -+ -+The policies for copy-up is more simple, -+top-down-parent is equivalent to the same named on in create policy, -+bottom-up-parent selects the writable branch where the parent dir -+exists and the nearest upper one from the copyup-source, -+bottom-up selects the nearest upper writable branch from the -+copyup-source, regardless the existence of the parent dir. -+ -+There are some rules or exceptions to apply these policies. -+- If there is a readonly branch above the policy-selected branch and -+ the parent dir is marked as opaque (a variation of whiteout), or the -+ target (creating) file is whiteout-ed on the upper readonly branch, -+ then the result of the policy is ignored and the target file will be -+ created on the nearest upper writable branch than the readonly branch. -+- If there is a writable branch above the policy-selected branch and -+ the parent dir is marked as opaque or the target file is whiteouted -+ on the branch, then the result of the policy is ignored and the target -+ file will be created on the highest one among the upper writable -+ branches who has diropq or whiteout. In case of whiteout, aufs removes -+ it as usual. -+- link(2) and rename(2) systemcalls are exceptions in every policy. -+ They try selecting the branch where the source exists as possible -+ since copyup a large file will take long time. If it can't be, -+ ie. the branch where the source exists is readonly, then they will -+ follow the copyup policy. -+- There is an exception for rename(2) when the target exists. -+ If the rename target exists, aufs compares the index of the branches -+ where the source and the target exists and selects the higher -+ one. If the selected branch is readonly, then aufs follows the -+ copyup policy. -diff --git a/Documentation/filesystems/aufs/design/06dirren.dot b/Documentation/filesystems/aufs/design/06dirren.dot -new file mode 100644 -index 000000000..2d62bb6dd ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/06dirren.dot -@@ -0,0 +1,31 @@ -+ -+// to view this graph, run dot(1) command in GRAPHVIZ. -+ -+digraph G { -+node [shape=box]; -+whinfo [label="detailed info file\n(lower_brid_root-hinum, h_inum, namelen, old name)"]; -+ -+node [shape=oval]; -+ -+aufs_rename -> whinfo [label="store/remove"]; -+ -+node [shape=oval]; -+inode_list [label="h_inum list in branch\ncache"]; -+ -+node [shape=box]; -+whinode [label="h_inum list file"]; -+ -+node [shape=oval]; -+brmgmt [label="br_add/del/mod/umount"]; -+ -+brmgmt -> inode_list [label="create/remove"]; -+brmgmt -> whinode [label="load/store"]; -+ -+inode_list -> whinode [style=dashed,dir=both]; -+ -+aufs_rename -> inode_list [label="add/del"]; -+ -+aufs_lookup -> inode_list [label="search"]; -+ -+aufs_lookup -> whinfo [label="load/remove"]; -+} -diff --git a/Documentation/filesystems/aufs/design/06dirren.txt b/Documentation/filesystems/aufs/design/06dirren.txt -new file mode 100644 -index 000000000..1f3cb86d9 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/06dirren.txt -@@ -0,0 +1,102 @@ -+ -+# Copyright (C) 2017-2018 Junjiro R. Okajima -+# -+# 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, see . -+ -+Special handling for renaming a directory (DIRREN) -+---------------------------------------------------------------------- -+First, let's assume we have a simple usecase. -+ -+- /u = /rw + /ro -+- /rw/dirA exists -+- /ro/dirA and /ro/dirA/file exist too -+- there is no dirB on both branches -+- a user issues rename("dirA", "dirB") -+ -+Now, what should aufs behave against this rename(2)? -+There are a few possible cases. -+ -+A. returns EROFS. -+ since dirA exists on a readonly branch which cannot be renamed. -+B. returns EXDEV. -+ it is possible to copy-up dirA (only the dir itself), but the child -+ entries ("file" in this case) should not be. it must be a bad -+ approach to copy-up recursively. -+C. returns a success. -+ even the branch /ro is readonly, aufs tries renaming it. Obviously it -+ is a violation of aufs' policy. -+D. construct an extra information which indicates that /ro/dirA should -+ be handled as the name of dirB. -+ overlayfs has a similar feature called REDIRECT. -+ -+Until now, aufs implements the case B only which returns EXDEV, and -+expects the userspace application behaves like mv(1) which tries -+issueing rename(2) recursively. -+ -+A new aufs feature called DIRREN is introduced which implements the case -+D. There are several "extra information" added. -+ -+1. detailed info per renamed directory -+ path: /rw/dirB/$AUFS_WH_DR_INFO_PFX. -+2. the inode-number list of directories on a branch -+ path: /rw/dirB/$AUFS_WH_DR_BRHINO -+ -+The filename of "detailed info per directory" represents the lower -+branch, and its format is -+- a type of the branch id -+ one of these. -+ + uuid (not implemented yet) -+ + fsid -+ + dev -+- the inode-number of the branch root dir -+ -+And it contains these info in a single regular file. -+- magic number -+- branch's inode-number of the logically renamed dir -+- the name of the before-renamed dir -+ -+The "detailed info per directory" file is created in aufs rename(2), and -+loaded in any lookup. -+The info is considered in lookup for the matching case only. Here -+"matching" means that the root of branch (in the info filename) is same -+to the current looking-up branch. After looking-up the before-renamed -+name, the inode-number is compared. And the matched dentry is used. -+ -+The "inode-number list of directories" is a regular file which contains -+simply the inode-numbers on the branch. The file is created or updated -+in removing the branch, and loaded in adding the branch. Its lifetime is -+equal to the branch. -+The list is refered in lookup, and when the current target inode is -+found in the list, the aufs tries loading the "detailed info per -+directory" and get the changed and valid name of the dir. -+ -+Theoretically these "extra informaiton" may be able to be put into XATTR -+in the dir inode. But aufs doesn't choose this way because -+1. XATTR may not be supported by the branch (or its configuration) -+2. XATTR may have its size limit. -+3. XATTR may be less easy to convert than a regular file, when the -+ format of the info is changed in the future. -+At the same time, I agree that the regular file approach is much slower -+than XATTR approach. So, in the future, aufs may take the XATTR or other -+better approach. -+ -+This DIRREN feature is enabled by aufs configuration, and is activated -+by a new mount option. -+ -+For the more complicated case, there is a work with UDBA option, which -+is to dected the direct access to the branches (by-passing aufs) and to -+maintain the cashes in aufs. Since a single cached aufs dentry may -+contains two names, before- and after-rename, the name comparision in -+UDBA handler may not work correctly. In this case, the behaviour will be -+equivalen to udba=reval case. -diff --git a/Documentation/filesystems/aufs/design/06fhsm.txt b/Documentation/filesystems/aufs/design/06fhsm.txt -new file mode 100644 -index 000000000..ddfebecdf ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/06fhsm.txt -@@ -0,0 +1,120 @@ -+ -+# Copyright (C) 2011-2018 Junjiro R. Okajima -+# -+# 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 St, Fifth Floor, Boston, MA 02110-1301 USA -+ -+ -+File-based Hierarchical Storage Management (FHSM) -+---------------------------------------------------------------------- -+Hierarchical Storage Management (or HSM) is a well-known feature in the -+storage world. Aufs provides this feature as file-based with multiple -+writable branches, based upon the principle of "Colder, the Lower". -+Here the word "colder" means that the less used files, and "lower" means -+that the position in the order of the stacked branches vertically. -+These multiple writable branches are prioritized, ie. the topmost one -+should be the fastest drive and be used heavily. -+ -+o Characters in aufs FHSM story -+- aufs itself and a new branch attribute. -+- a new ioctl interface to move-down and to establish a connection with -+ the daemon ("move-down" is a converse of "copy-up"). -+- userspace tool and daemon. -+ -+The userspace daemon establishes a connection with aufs and waits for -+the notification. The notified information is very similar to struct -+statfs containing the number of consumed blocks and inodes. -+When the consumed blocks/inodes of a branch exceeds the user-specified -+upper watermark, the daemon activates its move-down process until the -+consumed blocks/inodes reaches the user-specified lower watermark. -+ -+The actual move-down is done by aufs based upon the request from -+user-space since we need to maintain the inode number and the internal -+pointer arrays in aufs. -+ -+Currently aufs FHSM handles the regular files only. Additionally they -+must not be hard-linked nor pseudo-linked. -+ -+ -+o Cowork of aufs and the user-space daemon -+ During the userspace daemon established the connection, aufs sends a -+ small notification to it whenever aufs writes something into the -+ writable branch. But it may cost high since aufs issues statfs(2) -+ internally. So user can specify a new option to cache the -+ info. Actually the notification is controlled by these factors. -+ + the specified cache time. -+ + classified as "force" by aufs internally. -+ Until the specified time expires, aufs doesn't send the info -+ except the forced cases. When aufs decide forcing, the info is always -+ notified to userspace. -+ For example, the number of free inodes is generally large enough and -+ the shortage of it happens rarely. So aufs doesn't force the -+ notification when creating a new file, directory and others. This is -+ the typical case which aufs doesn't force. -+ When aufs writes the actual filedata and the files consumes any of new -+ blocks, the aufs forces notifying. -+ -+ -+o Interfaces in aufs -+- New branch attribute. -+ + fhsm -+ Specifies that the branch is managed by FHSM feature. In other word, -+ participant in the FHSM. -+ When nofhsm is set to the branch, it will not be the source/target -+ branch of the move-down operation. This attribute is set -+ independently from coo and moo attributes, and if you want full -+ FHSM, you should specify them as well. -+- New mount option. -+ + fhsm_sec -+ Specifies a second to suppress many less important info to be -+ notified. -+- New ioctl. -+ + AUFS_CTL_FHSM_FD -+ create a new file descriptor which userspace can read the notification -+ (a subset of struct statfs) from aufs. -+- Module parameter 'brs' -+ It has to be set to 1. Otherwise the new mount option 'fhsm' will not -+ be set. -+- mount helpers /sbin/mount.aufs and /sbin/umount.aufs -+ When there are two or more branches with fhsm attributes, -+ /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs -+ terminates it. As a result of remounting and branch-manipulation, the -+ number of branches with fhsm attribute can be one. In this case, -+ /sbin/mount.aufs will terminate the user-space daemon. -+ -+ -+Finally the operation is done as these steps in kernel-space. -+- make sure that, -+ + no one else is using the file. -+ + the file is not hard-linked. -+ + the file is not pseudo-linked. -+ + the file is a regular file. -+ + the parent dir is not opaqued. -+- find the target writable branch. -+- make sure the file is not whiteout-ed by the upper (than the target) -+ branch. -+- make the parent dir on the target branch. -+- mutex lock the inode on the branch. -+- unlink the whiteout on the target branch (if exists). -+- lookup and create the whiteout-ed temporary name on the target branch. -+- copy the file as the whiteout-ed temporary name on the target branch. -+- rename the whiteout-ed temporary name to the original name. -+- unlink the file on the source branch. -+- maintain the internal pointer array and the external inode number -+ table (XINO). -+- maintain the timestamps and other attributes of the parent dir and the -+ file. -+ -+And of course, in every step, an error may happen. So the operation -+should restore the original file state after an error happens. -diff --git a/Documentation/filesystems/aufs/design/06mmap.txt b/Documentation/filesystems/aufs/design/06mmap.txt -new file mode 100644 -index 000000000..9a0a096b1 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/06mmap.txt -@@ -0,0 +1,72 @@ -+ -+# Copyright (C) 2005-2018 Junjiro R. Okajima -+# -+# 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, see . -+ -+mmap(2) -- File Memory Mapping -+---------------------------------------------------------------------- -+In aufs, the file-mapped pages are handled by a branch fs directly, no -+interaction with aufs. It means aufs_mmap() calls the branch fs's -+->mmap(). -+This approach is simple and good, but there is one problem. -+Under /proc, several entries show the mmapped files by its path (with -+device and inode number), and the printed path will be the path on the -+branch fs's instead of virtual aufs's. -+This is not a problem in most cases, but some utilities lsof(1) (and its -+user) may expect the path on aufs. -+ -+To address this issue, aufs adds a new member called vm_prfile in struct -+vm_area_struct (and struct vm_region). The original vm_file points to -+the file on the branch fs in order to handle everything correctly as -+usual. The new vm_prfile points to a virtual file in aufs, and the -+show-functions in procfs refers to vm_prfile if it is set. -+Also we need to maintain several other places where touching vm_file -+such like -+- fork()/clone() copies vma and the reference count of vm_file is -+ incremented. -+- merging vma maintains the ref count too. -+ -+This is not a good approach. It just fakes the printed path. But it -+leaves all behaviour around f_mapping unchanged. This is surely an -+advantage. -+Actually aufs had adopted another complicated approach which calls -+generic_file_mmap() and handles struct vm_operations_struct. In this -+approach, aufs met a hard problem and I could not solve it without -+switching the approach. -+ -+There may be one more another approach which is -+- bind-mount the branch-root onto the aufs-root internally -+- grab the new vfsmount (ie. struct mount) -+- lazy-umount the branch-root internally -+- in open(2) the aufs-file, open the branch-file with the hidden -+ vfsmount (instead of the original branch's vfsmount) -+- ideally this "bind-mount and lazy-umount" should be done atomically, -+ but it may be possible from userspace by the mount helper. -+ -+Adding the internal hidden vfsmount and using it in opening a file, the -+file path under /proc will be printed correctly. This approach looks -+smarter, but is not possible I am afraid. -+- aufs-root may be bind-mount later. when it happens, another hidden -+ vfsmount will be required. -+- it is hard to get the chance to bind-mount and lazy-umount -+ + in kernel-space, FS can have vfsmount in open(2) via -+ file->f_path, and aufs can know its vfsmount. But several locks are -+ already acquired, and if aufs tries to bind-mount and lazy-umount -+ here, then it may cause a deadlock. -+ + in user-space, bind-mount doesn't invoke the mount helper. -+- since /proc shows dev and ino, aufs has to give vma these info. it -+ means a new member vm_prinode will be necessary. this is essentially -+ equivalent to vm_prfile described above. -+ -+I have to give up this "looks-smater" approach. -diff --git a/Documentation/filesystems/aufs/design/06xattr.txt b/Documentation/filesystems/aufs/design/06xattr.txt -new file mode 100644 -index 000000000..be441e8d3 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/06xattr.txt -@@ -0,0 +1,96 @@ -+ -+# Copyright (C) 2014-2018 Junjiro R. Okajima -+# -+# 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 St, Fifth Floor, Boston, MA 02110-1301 USA -+ -+ -+Listing XATTR/EA and getting the value -+---------------------------------------------------------------------- -+For the inode standard attributes (owner, group, timestamps, etc.), aufs -+shows the values from the topmost existing file. This behaviour is good -+for the non-dir entries since the bahaviour exactly matches the shown -+information. But for the directories, aufs considers all the same named -+entries on the lower branches. Which means, if one of the lower entry -+rejects readdir call, then aufs returns an error even if the topmost -+entry allows it. This behaviour is necessary to respect the branch fs's -+security, but can make users confused since the user-visible standard -+attributes don't match the behaviour. -+To address this issue, aufs has a mount option called dirperm1 which -+checks the permission for the topmost entry only, and ignores the lower -+entry's permission. -+ -+A similar issue can happen around XATTR. -+getxattr(2) and listxattr(2) families behave as if dirperm1 option is -+always set. Otherwise these very unpleasant situation would happen. -+- listxattr(2) may return the duplicated entries. -+- users may not be able to remove or reset the XATTR forever, -+ -+ -+XATTR/EA support in the internal (copy,move)-(up,down) -+---------------------------------------------------------------------- -+Generally the extended attributes of inode are categorized as these. -+- "security" for LSM and capability. -+- "system" for posix ACL, 'acl' mount option is required for the branch -+ fs generally. -+- "trusted" for userspace, CAP_SYS_ADMIN is required. -+- "user" for userspace, 'user_xattr' mount option is required for the -+ branch fs generally. -+ -+Moreover there are some other categories. Aufs handles these rather -+unpopular categories as the ordinary ones, ie. there is no special -+condition nor exception. -+ -+In copy-up, the support for XATTR on the dst branch may differ from the -+src branch. In this case, the copy-up operation will get an error and -+the original user operation which triggered the copy-up will fail. It -+can happen that even all copy-up will fail. -+When both of src and dst branches support XATTR and if an error occurs -+during copying XATTR, then the copy-up should fail obviously. That is a -+good reason and aufs should return an error to userspace. But when only -+the src branch support that XATTR, aufs should not return an error. -+For example, the src branch supports ACL but the dst branch doesn't -+because the dst branch may natively un-support it or temporary -+un-support it due to "noacl" mount option. Of course, the dst branch fs -+may NOT return an error even if the XATTR is not supported. It is -+totally up to the branch fs. -+ -+Anyway when the aufs internal copy-up gets an error from the dst branch -+fs, then aufs tries removing the just copied entry and returns the error -+to the userspace. The worst case of this situation will be all copy-up -+will fail. -+ -+For the copy-up operation, there two basic approaches. -+- copy the specified XATTR only (by category above), and return the -+ error unconditionally if it happens. -+- copy all XATTR, and ignore the error on the specified category only. -+ -+In order to support XATTR and to implement the correct behaviour, aufs -+chooses the latter approach and introduces some new branch attributes, -+"icexsec", "icexsys", "icextr", "icexusr", and "icexoth". -+They correspond to the XATTR namespaces (see above). Additionally, to be -+convenient, "icex" is also provided which means all "icex*" attributes -+are set (here the word "icex" stands for "ignore copy-error on XATTR"). -+ -+The meaning of these attributes is to ignore the error from setting -+XATTR on that branch. -+Note that aufs tries copying all XATTR unconditionally, and ignores the -+error from the dst branch according to the specified attributes. -+ -+Some XATTR may have its default value. The default value may come from -+the parent dir or the environment. If the default value is set at the -+file creating-time, it will be overwritten by copy-up. -+Some contradiction may happen I am afraid. -+Do we need another attribute to stop copying XATTR? I am unsure. For -+now, aufs implements the branch attributes to ignore the error. -diff --git a/Documentation/filesystems/aufs/design/07export.txt b/Documentation/filesystems/aufs/design/07export.txt -new file mode 100644 -index 000000000..bb700cb18 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/07export.txt -@@ -0,0 +1,58 @@ -+ -+# Copyright (C) 2005-2018 Junjiro R. Okajima -+# -+# 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, see . -+ -+Export Aufs via NFS -+---------------------------------------------------------------------- -+Here is an approach. -+- like xino/xib, add a new file 'xigen' which stores aufs inode -+ generation. -+- iget_locked(): initialize aufs inode generation for a new inode, and -+ store it in xigen file. -+- destroy_inode(): increment aufs inode generation and store it in xigen -+ file. it is necessary even if it is not unlinked, because any data of -+ inode may be changed by UDBA. -+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise -+ build file handle by -+ + branch id (4 bytes) -+ + superblock generation (4 bytes) -+ + inode number (4 or 8 bytes) -+ + parent dir inode number (4 or 8 bytes) -+ + inode generation (4 bytes)) -+ + return value of exportfs_encode_fh() for the parent on a branch (4 -+ bytes) -+ + file handle for a branch (by exportfs_encode_fh()) -+- fh_to_dentry(): -+ + find the index of a branch from its id in handle, and check it is -+ still exist in aufs. -+ + 1st level: get the inode number from handle and search it in cache. -+ + 2nd level: if not found in cache, get the parent inode number from -+ the handle and search it in cache. and then open the found parent -+ dir, find the matching inode number by vfs_readdir() and get its -+ name, and call lookup_one_len() for the target dentry. -+ + 3rd level: if the parent dir is not cached, call -+ exportfs_decode_fh() for a branch and get the parent on a branch, -+ build a pathname of it, convert it a pathname in aufs, call -+ path_lookup(). now aufs gets a parent dir dentry, then handle it as -+ the 2nd level. -+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount -+ for every branch, but not itself. to get this, (currently) aufs -+ searches in current->nsproxy->mnt_ns list. it may not be a good -+ idea, but I didn't get other approach. -+ + test the generation of the gotten inode. -+- every inode operation: they may get EBUSY due to UDBA. in this case, -+ convert it into ESTALE for NFSD. -+- readdir(): call lockdep_on/off() because filldir in NFSD calls -+ lookup_one_len(), vfs_getattr(), encode_fh() and others. -diff --git a/Documentation/filesystems/aufs/design/08shwh.txt b/Documentation/filesystems/aufs/design/08shwh.txt -new file mode 100644 -index 000000000..1dad573f6 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/08shwh.txt -@@ -0,0 +1,52 @@ -+ -+# Copyright (C) 2005-2018 Junjiro R. Okajima -+# -+# 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, see . -+ -+Show Whiteout Mode (shwh) -+---------------------------------------------------------------------- -+Generally aufs hides the name of whiteouts. But in some cases, to show -+them is very useful for users. For instance, creating a new middle layer -+(branch) by merging existing layers. -+ -+(borrowing aufs1 HOW-TO from a user, Michael Towers) -+When you have three branches, -+- Bottom: 'system', squashfs (underlying base system), read-only -+- Middle: 'mods', squashfs, read-only -+- Top: 'overlay', ram (tmpfs), read-write -+ -+The top layer is loaded at boot time and saved at shutdown, to preserve -+the changes made to the system during the session. -+When larger changes have been made, or smaller changes have accumulated, -+the size of the saved top layer data grows. At this point, it would be -+nice to be able to merge the two overlay branches ('mods' and 'overlay') -+and rewrite the 'mods' squashfs, clearing the top layer and thus -+restoring save and load speed. -+ -+This merging is simplified by the use of another aufs mount, of just the -+two overlay branches using the 'shwh' option. -+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \ -+ aufs /livesys/merge_union -+ -+A merged view of these two branches is then available at -+/livesys/merge_union, and the new feature is that the whiteouts are -+visible! -+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable -+writing to all branches. Also the default mode for all branches is 'ro'. -+It is now possible to save the combined contents of the two overlay -+branches to a new squashfs, e.g.: -+# mksquashfs /livesys/merge_union /path/to/newmods.squash -+ -+This new squashfs archive can be stored on the boot device and the -+initramfs will use it to replace the old one at the next boot. -diff --git a/Documentation/filesystems/aufs/design/10dynop.txt b/Documentation/filesystems/aufs/design/10dynop.txt -new file mode 100644 -index 000000000..710313c08 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/10dynop.txt -@@ -0,0 +1,47 @@ -+ -+# Copyright (C) 2010-2018 Junjiro R. Okajima -+# -+# 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, see . -+ -+Dynamically customizable FS operations -+---------------------------------------------------------------------- -+Generally FS operations (struct inode_operations, struct -+address_space_operations, struct file_operations, etc.) are defined as -+"static const", but it never means that FS have only one set of -+operation. Some FS have multiple sets of them. For instance, ext2 has -+three sets, one for XIP, for NOBH, and for normal. -+Since aufs overrides and redirects these operations, sometimes aufs has -+to change its behaviour according to the branch FS type. More importantly -+VFS acts differently if a function (member in the struct) is set or -+not. It means aufs should have several sets of operations and select one -+among them according to the branch FS definition. -+ -+In order to solve this problem and not to affect the behaviour of VFS, -+aufs defines these operations dynamically. For instance, aufs defines -+dummy direct_IO function for struct address_space_operations, but it may -+not be set to the address_space_operations actually. When the branch FS -+doesn't have it, aufs doesn't set it to its address_space_operations -+while the function definition itself is still alive. So the behaviour -+itself will not change, and it will return an error when direct_IO is -+not set. -+ -+The lifetime of these dynamically generated operation object is -+maintained by aufs branch object. When the branch is removed from aufs, -+the reference counter of the object is decremented. When it reaches -+zero, the dynamically generated operation object will be freed. -+ -+This approach is designed to support AIO (io_submit), Direct I/O and -+XIP (DAX) mainly. -+Currently this approach is applied to address_space_operations for -+regular files only. -diff --git a/MAINTAINERS b/MAINTAINERS -index b2f710eee..d21161917 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -2605,6 +2605,19 @@ F: include/linux/audit.h - F: include/uapi/linux/audit.h - F: kernel/audit* - -+AUFS (advanced multi layered unification filesystem) FILESYSTEM -+M: "J. R. Okajima" -+L: linux-unionfs@vger.kernel.org -+L: aufs-users@lists.sourceforge.net (members only) -+W: http://aufs.sourceforge.net -+T: git://github.com/sfjro/aufs4-linux.git -+S: Supported -+F: Documentation/filesystems/aufs/ -+F: Documentation/ABI/testing/debugfs-aufs -+F: Documentation/ABI/testing/sysfs-aufs -+F: fs/aufs/ -+F: include/uapi/linux/aufs_type.h -+ - AUXILIARY DISPLAY DRIVERS - M: Miguel Ojeda Sandonis - S: Maintained -diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index ea9debf59..9e534a36c 100644 ---- a/drivers/block/loop.c -+++ b/drivers/block/loop.c -@@ -739,6 +739,24 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, - return error; - } - -+/* -+ * for AUFS -+ * no get/put for file. -+ */ -+struct file *loop_backing_file(struct super_block *sb) -+{ -+ struct file *ret; -+ struct loop_device *l; -+ -+ ret = NULL; -+ if (MAJOR(sb->s_dev) == LOOP_MAJOR) { -+ l = sb->s_bdev->bd_disk->private_data; -+ ret = l->lo_backing_file; -+ } -+ return ret; -+} -+EXPORT_SYMBOL_GPL(loop_backing_file); -+ - /* loop sysfs attributes */ - - static ssize_t loop_attr_show(struct device *dev, char *page, -diff --git a/fs/Kconfig b/fs/Kconfig -index ac474a61b..284cee954 100644 ---- a/fs/Kconfig -+++ b/fs/Kconfig -@@ -255,6 +255,7 @@ source "fs/pstore/Kconfig" - source "fs/sysv/Kconfig" - source "fs/ufs/Kconfig" - source "fs/exofs/Kconfig" -+source "fs/aufs/Kconfig" - - endif # MISC_FILESYSTEMS - -diff --git a/fs/Makefile b/fs/Makefile -index 293733f61..12d19d0de 100644 ---- a/fs/Makefile -+++ b/fs/Makefile -@@ -128,3 +128,4 @@ obj-y += exofs/ # Multiple modules - obj-$(CONFIG_CEPH_FS) += ceph/ - obj-$(CONFIG_PSTORE) += pstore/ - obj-$(CONFIG_EFIVAR_FS) += efivarfs/ -+obj-$(CONFIG_AUFS_FS) += aufs/ -diff --git a/fs/aufs/Kconfig b/fs/aufs/Kconfig -new file mode 100644 -index 000000000..9f4364257 ---- /dev/null -+++ b/fs/aufs/Kconfig -@@ -0,0 +1,199 @@ -+# SPDX-License-Identifier: GPL-2.0 -+config AUFS_FS -+ tristate "Aufs (Advanced multi layered unification filesystem) support" -+ help -+ Aufs is a stackable unification filesystem such as Unionfs, -+ which unifies several directories and provides a merged single -+ directory. -+ In the early days, aufs was entirely re-designed and -+ re-implemented Unionfs Version 1.x series. Introducing many -+ original ideas, approaches and improvements, it becomes totally -+ different from Unionfs while keeping the basic features. -+ -+if AUFS_FS -+choice -+ prompt "Maximum number of branches" -+ default AUFS_BRANCH_MAX_127 -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+config AUFS_BRANCH_MAX_127 -+ bool "127" -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+config AUFS_BRANCH_MAX_511 -+ bool "511" -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+config AUFS_BRANCH_MAX_1023 -+ bool "1023" -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+config AUFS_BRANCH_MAX_32767 -+ bool "32767" -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+endchoice -+ -+config AUFS_SBILIST -+ bool -+ depends on AUFS_MAGIC_SYSRQ || PROC_FS -+ default y -+ help -+ Automatic configuration for internal use. -+ When aufs supports Magic SysRq or /proc, enabled automatically. -+ -+config AUFS_HNOTIFY -+ bool "Detect direct branch access (bypassing aufs)" -+ help -+ If you want to modify files on branches directly, eg. bypassing aufs, -+ and want aufs to detect the changes of them fully, then enable this -+ option and use 'udba=notify' mount option. -+ Currently there is only one available configuration, "fsnotify". -+ It will have a negative impact to the performance. -+ See detail in aufs.5. -+ -+choice -+ prompt "method" if AUFS_HNOTIFY -+ default AUFS_HFSNOTIFY -+config AUFS_HFSNOTIFY -+ bool "fsnotify" -+ select FSNOTIFY -+endchoice -+ -+config AUFS_EXPORT -+ bool "NFS-exportable aufs" -+ depends on EXPORTFS -+ help -+ If you want to export your mounted aufs via NFS, then enable this -+ option. There are several requirements for this configuration. -+ See detail in aufs.5. -+ -+config AUFS_INO_T_64 -+ bool -+ depends on AUFS_EXPORT -+ depends on 64BIT && !(ALPHA || S390) -+ default y -+ help -+ Automatic configuration for internal use. -+ /* typedef unsigned long/int __kernel_ino_t */ -+ /* alpha and s390x are int */ -+ -+config AUFS_XATTR -+ bool "support for XATTR/EA (including Security Labels)" -+ help -+ If your branch fs supports XATTR/EA and you want to make them -+ available in aufs too, then enable this opsion and specify the -+ branch attributes for EA. -+ See detail in aufs.5. -+ -+config AUFS_FHSM -+ bool "File-based Hierarchical Storage Management" -+ help -+ Hierarchical Storage Management (or HSM) is a well-known feature -+ in the storage world. Aufs provides this feature as file-based. -+ with multiple branches. -+ These multiple branches are prioritized, ie. the topmost one -+ should be the fastest drive and be used heavily. -+ -+config AUFS_RDU -+ bool "Readdir in userspace" -+ help -+ Aufs has two methods to provide a merged view for a directory, -+ by a user-space library and by kernel-space natively. The latter -+ is always enabled but sometimes large and slow. -+ If you enable this option, install the library in aufs2-util -+ package, and set some environment variables for your readdir(3), -+ then the work will be handled in user-space which generally -+ shows better performance in most cases. -+ See detail in aufs.5. -+ -+config AUFS_DIRREN -+ bool "Workaround for rename(2)-ing a directory" -+ help -+ By default, aufs returns EXDEV error in renameing a dir who has -+ his child on the lower branch, since it is a bad idea to issue -+ rename(2) internally for every lower branch. But user may not -+ accept this behaviour. So here is a workaround to allow such -+ rename(2) and store some extra infromation on the writable -+ branch. Obviously this costs high (and I don't like it). -+ To use this feature, you need to enable this configuration AND -+ to specify the mount option `dirren.' -+ See details in aufs.5 and the design documents. -+ -+config AUFS_SHWH -+ bool "Show whiteouts" -+ help -+ If you want to make the whiteouts in aufs visible, then enable -+ this option and specify 'shwh' mount option. Although it may -+ sounds like philosophy or something, but in technically it -+ simply shows the name of whiteout with keeping its behaviour. -+ -+config AUFS_BR_RAMFS -+ bool "Ramfs (initramfs/rootfs) as an aufs branch" -+ help -+ If you want to use ramfs as an aufs branch fs, then enable this -+ option. Generally tmpfs is recommended. -+ Aufs prohibited them to be a branch fs by default, because -+ initramfs becomes unusable after switch_root or something -+ generally. If you sets initramfs as an aufs branch and boot your -+ system by switch_root, you will meet a problem easily since the -+ files in initramfs may be inaccessible. -+ Unless you are going to use ramfs as an aufs branch fs without -+ switch_root or something, leave it N. -+ -+config AUFS_BR_FUSE -+ bool "Fuse fs as an aufs branch" -+ depends on FUSE_FS -+ select AUFS_POLL -+ help -+ If you want to use fuse-based userspace filesystem as an aufs -+ branch fs, then enable this option. -+ It implements the internal poll(2) operation which is -+ implemented by fuse only (curretnly). -+ -+config AUFS_POLL -+ bool -+ help -+ Automatic configuration for internal use. -+ -+config AUFS_BR_HFSPLUS -+ bool "Hfsplus as an aufs branch" -+ depends on HFSPLUS_FS -+ default y -+ help -+ If you want to use hfsplus fs as an aufs branch fs, then enable -+ this option. This option introduces a small overhead at -+ copying-up a file on hfsplus. -+ -+config AUFS_BDEV_LOOP -+ bool -+ depends on BLK_DEV_LOOP -+ default y -+ help -+ Automatic configuration for internal use. -+ Convert =[ym] into =y. -+ -+config AUFS_DEBUG -+ bool "Debug aufs" -+ help -+ Enable this to compile aufs internal debug code. -+ It will have a negative impact to the performance. -+ -+config AUFS_MAGIC_SYSRQ -+ bool -+ depends on AUFS_DEBUG && MAGIC_SYSRQ -+ default y -+ help -+ Automatic configuration for internal use. -+ When aufs supports Magic SysRq, enabled automatically. -+endif -diff --git a/fs/aufs/Makefile b/fs/aufs/Makefile -new file mode 100644 -index 000000000..2c819a649 ---- /dev/null -+++ b/fs/aufs/Makefile -@@ -0,0 +1,46 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+include ${src}/magic.mk -+ifeq (${CONFIG_AUFS_FS},m) -+include ${src}/conf.mk -+endif -+-include ${src}/priv_def.mk -+ -+# cf. include/linux/kernel.h -+# enable pr_debug -+ccflags-y += -DDEBUG -+# sparse requires the full pathname -+ifdef M -+ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h -+else -+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h -+endif -+ -+obj-$(CONFIG_AUFS_FS) += aufs.o -+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \ -+ wkq.o vfsub.o dcsub.o \ -+ cpup.o whout.o wbr_policy.o \ -+ dinfo.o dentry.o \ -+ dynop.o \ -+ finfo.o file.o f_op.o \ -+ dir.o vdir.o \ -+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \ -+ mvdown.o ioctl.o -+ -+# all are boolean -+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o -+aufs-$(CONFIG_SYSFS) += sysfs.o -+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o -+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o -+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o -+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o -+aufs-$(CONFIG_AUFS_EXPORT) += export.o -+aufs-$(CONFIG_AUFS_XATTR) += xattr.o -+aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o -+aufs-$(CONFIG_AUFS_DIRREN) += dirren.o -+aufs-$(CONFIG_AUFS_FHSM) += fhsm.o -+aufs-$(CONFIG_AUFS_POLL) += poll.o -+aufs-$(CONFIG_AUFS_RDU) += rdu.o -+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o -+aufs-$(CONFIG_AUFS_DEBUG) += debug.o -+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o -diff --git a/fs/aufs/aufs.h b/fs/aufs/aufs.h -new file mode 100644 -index 000000000..245691743 ---- /dev/null -+++ b/fs/aufs/aufs.h -@@ -0,0 +1,62 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * all header files -+ */ -+ -+#ifndef __AUFS_H__ -+#define __AUFS_H__ -+ -+#ifdef __KERNEL__ -+ -+#define AuStub(type, name, body, ...) \ -+ static inline type name(__VA_ARGS__) { body; } -+ -+#define AuStubVoid(name, ...) \ -+ AuStub(void, name, , __VA_ARGS__) -+#define AuStubInt0(name, ...) \ -+ AuStub(int, name, return 0, __VA_ARGS__) -+ -+#include "debug.h" -+ -+#include "branch.h" -+#include "cpup.h" -+#include "dcsub.h" -+#include "dbgaufs.h" -+#include "dentry.h" -+#include "dir.h" -+#include "dirren.h" -+#include "dynop.h" -+#include "file.h" -+#include "fstype.h" -+#include "hbl.h" -+#include "inode.h" -+#include "lcnt.h" -+#include "loop.h" -+#include "module.h" -+#include "opts.h" -+#include "rwsem.h" -+#include "super.h" -+#include "sysaufs.h" -+#include "vfsub.h" -+#include "whout.h" -+#include "wkq.h" -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_H__ */ -diff --git a/fs/aufs/branch.c b/fs/aufs/branch.c -new file mode 100644 -index 000000000..2fc6dc1e3 ---- /dev/null -+++ b/fs/aufs/branch.c -@@ -0,0 +1,1422 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * branch management -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+/* -+ * free a single branch -+ */ -+static void au_br_do_free(struct au_branch *br) -+{ -+ int i; -+ struct au_wbr *wbr; -+ struct au_dykey **key; -+ -+ au_hnotify_fin_br(br); -+ /* always, regardless the mount option */ -+ au_dr_hino_free(&br->br_dirren); -+ au_xino_put(br); -+ -+ AuLCntZero(au_lcnt_read(&br->br_nfiles, /*do_rev*/0)); -+ au_lcnt_fin(&br->br_nfiles, /*do_sync*/0); -+ AuLCntZero(au_lcnt_read(&br->br_count, /*do_rev*/0)); -+ au_lcnt_fin(&br->br_count, /*do_sync*/0); -+ -+ wbr = br->br_wbr; -+ if (wbr) { -+ for (i = 0; i < AuBrWh_Last; i++) -+ dput(wbr->wbr_wh[i]); -+ AuDebugOn(atomic_read(&wbr->wbr_wh_running)); -+ AuRwDestroy(&wbr->wbr_wh_rwsem); -+ } -+ -+ if (br->br_fhsm) { -+ au_br_fhsm_fin(br->br_fhsm); -+ kfree(br->br_fhsm); -+ } -+ -+ key = br->br_dykey; -+ for (i = 0; i < AuBrDynOp; i++, key++) -+ if (*key) -+ au_dy_put(*key); -+ else -+ break; -+ -+ /* recursive lock, s_umount of branch's */ -+ /* synchronize_rcu(); */ /* why? */ -+ lockdep_off(); -+ path_put(&br->br_path); -+ lockdep_on(); -+ kfree(wbr); -+ au_lcnt_wait_for_fin(&br->br_nfiles); -+ au_lcnt_wait_for_fin(&br->br_count); -+ /* I don't know why, but percpu_refcount requires this */ -+ /* synchronize_rcu(); */ -+ kfree(br); -+} -+ -+/* -+ * frees all branches -+ */ -+void au_br_free(struct au_sbinfo *sbinfo) -+{ -+ aufs_bindex_t bmax; -+ struct au_branch **br; -+ -+ AuRwMustWriteLock(&sbinfo->si_rwsem); -+ -+ bmax = sbinfo->si_bbot + 1; -+ br = sbinfo->si_branch; -+ while (bmax--) -+ au_br_do_free(*br++); -+} -+ -+/* -+ * find the index of a branch which is specified by @br_id. -+ */ -+int au_br_index(struct super_block *sb, aufs_bindex_t br_id) -+{ -+ aufs_bindex_t bindex, bbot; -+ -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) -+ if (au_sbr_id(sb, bindex) == br_id) -+ return bindex; -+ return -1; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * add a branch -+ */ -+ -+static int test_overlap(struct super_block *sb, struct dentry *h_adding, -+ struct dentry *h_root) -+{ -+ if (unlikely(h_adding == h_root -+ || au_test_loopback_overlap(sb, h_adding))) -+ return 1; -+ if (h_adding->d_sb != h_root->d_sb) -+ return 0; -+ return au_test_subdir(h_adding, h_root) -+ || au_test_subdir(h_root, h_adding); -+} -+ -+/* -+ * returns a newly allocated branch. @new_nbranch is a number of branches -+ * after adding a branch. -+ */ -+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch, -+ int perm) -+{ -+ struct au_branch *add_branch; -+ struct dentry *root; -+ struct inode *inode; -+ int err; -+ -+ err = -ENOMEM; -+ add_branch = kzalloc(sizeof(*add_branch), GFP_NOFS); -+ if (unlikely(!add_branch)) -+ goto out; -+ add_branch->br_xino = au_xino_alloc(/*nfile*/1); -+ if (unlikely(!add_branch->br_xino)) -+ goto out_br; -+ err = au_hnotify_init_br(add_branch, perm); -+ if (unlikely(err)) -+ goto out_xino; -+ -+ if (au_br_writable(perm)) { -+ /* may be freed separately at changing the branch permission */ -+ add_branch->br_wbr = kzalloc(sizeof(*add_branch->br_wbr), -+ GFP_NOFS); -+ if (unlikely(!add_branch->br_wbr)) -+ goto out_hnotify; -+ } -+ -+ if (au_br_fhsm(perm)) { -+ err = au_fhsm_br_alloc(add_branch); -+ if (unlikely(err)) -+ goto out_wbr; -+ } -+ -+ root = sb->s_root; -+ err = au_sbr_realloc(au_sbi(sb), new_nbranch, /*may_shrink*/0); -+ if (!err) -+ err = au_di_realloc(au_di(root), new_nbranch, /*may_shrink*/0); -+ if (!err) { -+ inode = d_inode(root); -+ err = au_hinode_realloc(au_ii(inode), new_nbranch, -+ /*may_shrink*/0); -+ } -+ if (!err) -+ return add_branch; /* success */ -+ -+out_wbr: -+ kfree(add_branch->br_wbr); -+out_hnotify: -+ au_hnotify_fin_br(add_branch); -+out_xino: -+ au_xino_put(add_branch); -+out_br: -+ kfree(add_branch); -+out: -+ return ERR_PTR(err); -+} -+ -+/* -+ * test if the branch permission is legal or not. -+ */ -+static int test_br(struct inode *inode, int brperm, char *path) -+{ -+ int err; -+ -+ err = (au_br_writable(brperm) && IS_RDONLY(inode)); -+ if (!err) -+ goto out; -+ -+ err = -EINVAL; -+ pr_err("write permission for readonly mount or inode, %s\n", path); -+ -+out: -+ return err; -+} -+ -+/* -+ * returns: -+ * 0: success, the caller will add it -+ * plus: success, it is already unified, the caller should ignore it -+ * minus: error -+ */ -+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount) -+{ -+ int err; -+ aufs_bindex_t bbot, bindex; -+ struct dentry *root, *h_dentry; -+ struct inode *inode, *h_inode; -+ -+ root = sb->s_root; -+ bbot = au_sbbot(sb); -+ if (unlikely(bbot >= 0 -+ && au_find_dbindex(root, add->path.dentry) >= 0)) { -+ err = 1; -+ if (!remount) { -+ err = -EINVAL; -+ pr_err("%s duplicated\n", add->pathname); -+ } -+ goto out; -+ } -+ -+ err = -ENOSPC; /* -E2BIG; */ -+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex -+ || AUFS_BRANCH_MAX - 1 <= bbot)) { -+ pr_err("number of branches exceeded %s\n", add->pathname); -+ goto out; -+ } -+ -+ err = -EDOM; -+ if (unlikely(add->bindex < 0 || bbot + 1 < add->bindex)) { -+ pr_err("bad index %d\n", add->bindex); -+ goto out; -+ } -+ -+ inode = d_inode(add->path.dentry); -+ err = -ENOENT; -+ if (unlikely(!inode->i_nlink)) { -+ pr_err("no existence %s\n", add->pathname); -+ goto out; -+ } -+ -+ err = -EINVAL; -+ if (unlikely(inode->i_sb == sb)) { -+ pr_err("%s must be outside\n", add->pathname); -+ goto out; -+ } -+ -+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) { -+ pr_err("unsupported filesystem, %s (%s)\n", -+ add->pathname, au_sbtype(inode->i_sb)); -+ goto out; -+ } -+ -+ if (unlikely(inode->i_sb->s_stack_depth)) { -+ pr_err("already stacked, %s (%s)\n", -+ add->pathname, au_sbtype(inode->i_sb)); -+ goto out; -+ } -+ -+ err = test_br(d_inode(add->path.dentry), add->perm, add->pathname); -+ if (unlikely(err)) -+ goto out; -+ -+ if (bbot < 0) -+ return 0; /* success */ -+ -+ err = -EINVAL; -+ for (bindex = 0; bindex <= bbot; bindex++) -+ if (unlikely(test_overlap(sb, add->path.dentry, -+ au_h_dptr(root, bindex)))) { -+ pr_err("%s is overlapped\n", add->pathname); -+ goto out; -+ } -+ -+ err = 0; -+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) { -+ h_dentry = au_h_dptr(root, 0); -+ h_inode = d_inode(h_dentry); -+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO) -+ || !uid_eq(h_inode->i_uid, inode->i_uid) -+ || !gid_eq(h_inode->i_gid, inode->i_gid)) -+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n", -+ add->pathname, -+ i_uid_read(inode), i_gid_read(inode), -+ (inode->i_mode & S_IALLUGO), -+ i_uid_read(h_inode), i_gid_read(h_inode), -+ (h_inode->i_mode & S_IALLUGO)); -+ } -+ -+out: -+ return err; -+} -+ -+/* -+ * initialize or clean the whiteouts for an adding branch -+ */ -+static int au_br_init_wh(struct super_block *sb, struct au_branch *br, -+ int new_perm) -+{ -+ int err, old_perm; -+ aufs_bindex_t bindex; -+ struct inode *h_inode; -+ struct au_wbr *wbr; -+ struct au_hinode *hdir; -+ struct dentry *h_dentry; -+ -+ err = vfsub_mnt_want_write(au_br_mnt(br)); -+ if (unlikely(err)) -+ goto out; -+ -+ wbr = br->br_wbr; -+ old_perm = br->br_perm; -+ br->br_perm = new_perm; -+ hdir = NULL; -+ h_inode = NULL; -+ bindex = au_br_index(sb, br->br_id); -+ if (0 <= bindex) { -+ hdir = au_hi(d_inode(sb->s_root), bindex); -+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT); -+ } else { -+ h_dentry = au_br_dentry(br); -+ h_inode = d_inode(h_dentry); -+ inode_lock_nested(h_inode, AuLsc_I_PARENT); -+ } -+ if (!wbr) -+ err = au_wh_init(br, sb); -+ else { -+ wbr_wh_write_lock(wbr); -+ err = au_wh_init(br, sb); -+ wbr_wh_write_unlock(wbr); -+ } -+ if (hdir) -+ au_hn_inode_unlock(hdir); -+ else -+ inode_unlock(h_inode); -+ vfsub_mnt_drop_write(au_br_mnt(br)); -+ br->br_perm = old_perm; -+ -+ if (!err && wbr && !au_br_writable(new_perm)) { -+ kfree(wbr); -+ br->br_wbr = NULL; -+ } -+ -+out: -+ return err; -+} -+ -+static int au_wbr_init(struct au_branch *br, struct super_block *sb, -+ int perm) -+{ -+ int err; -+ struct kstatfs kst; -+ struct au_wbr *wbr; -+ -+ wbr = br->br_wbr; -+ au_rw_init(&wbr->wbr_wh_rwsem); -+ atomic_set(&wbr->wbr_wh_running, 0); -+ -+ /* -+ * a limit for rmdir/rename a dir -+ * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h -+ */ -+ err = vfs_statfs(&br->br_path, &kst); -+ if (unlikely(err)) -+ goto out; -+ err = -EINVAL; -+ if (kst.f_namelen >= NAME_MAX) -+ err = au_br_init_wh(sb, br, perm); -+ else -+ pr_err("%pd(%s), unsupported namelen %ld\n", -+ au_br_dentry(br), -+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen); -+ -+out: -+ return err; -+} -+ -+/* initialize a new branch */ -+static int au_br_init(struct au_branch *br, struct super_block *sb, -+ struct au_opt_add *add) -+{ -+ int err; -+ struct au_branch *brbase; -+ struct file *xf; -+ struct inode *h_inode; -+ -+ err = 0; -+ br->br_perm = add->perm; -+ br->br_path = add->path; /* set first, path_get() later */ -+ spin_lock_init(&br->br_dykey_lock); -+ au_lcnt_init(&br->br_nfiles, /*release*/NULL); -+ au_lcnt_init(&br->br_count, /*release*/NULL); -+ br->br_id = au_new_br_id(sb); -+ AuDebugOn(br->br_id < 0); -+ -+ /* always, regardless the given option */ -+ err = au_dr_br_init(sb, br, &add->path); -+ if (unlikely(err)) -+ goto out_err; -+ -+ if (au_br_writable(add->perm)) { -+ err = au_wbr_init(br, sb, add->perm); -+ if (unlikely(err)) -+ goto out_err; -+ } -+ -+ if (au_opt_test(au_mntflags(sb), XINO)) { -+ brbase = au_sbr(sb, 0); -+ xf = au_xino_file(brbase->br_xino, /*idx*/-1); -+ AuDebugOn(!xf); -+ h_inode = d_inode(add->path.dentry); -+ err = au_xino_init_br(sb, br, h_inode->i_ino, &xf->f_path); -+ if (unlikely(err)) { -+ AuDebugOn(au_xino_file(br->br_xino, /*idx*/-1)); -+ goto out_err; -+ } -+ } -+ -+ sysaufs_br_init(br); -+ path_get(&br->br_path); -+ goto out; /* success */ -+ -+out_err: -+ memset(&br->br_path, 0, sizeof(br->br_path)); -+out: -+ return err; -+} -+ -+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex, -+ struct au_branch *br, aufs_bindex_t bbot, -+ aufs_bindex_t amount) -+{ -+ struct au_branch **brp; -+ -+ AuRwMustWriteLock(&sbinfo->si_rwsem); -+ -+ brp = sbinfo->si_branch + bindex; -+ memmove(brp + 1, brp, sizeof(*brp) * amount); -+ *brp = br; -+ sbinfo->si_bbot++; -+ if (unlikely(bbot < 0)) -+ sbinfo->si_bbot = 0; -+} -+ -+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex, -+ aufs_bindex_t bbot, aufs_bindex_t amount) -+{ -+ struct au_hdentry *hdp; -+ -+ AuRwMustWriteLock(&dinfo->di_rwsem); -+ -+ hdp = au_hdentry(dinfo, bindex); -+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount); -+ au_h_dentry_init(hdp); -+ dinfo->di_bbot++; -+ if (unlikely(bbot < 0)) -+ dinfo->di_btop = 0; -+} -+ -+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex, -+ aufs_bindex_t bbot, aufs_bindex_t amount) -+{ -+ struct au_hinode *hip; -+ -+ AuRwMustWriteLock(&iinfo->ii_rwsem); -+ -+ hip = au_hinode(iinfo, bindex); -+ memmove(hip + 1, hip, sizeof(*hip) * amount); -+ au_hinode_init(hip); -+ iinfo->ii_bbot++; -+ if (unlikely(bbot < 0)) -+ iinfo->ii_btop = 0; -+} -+ -+static void au_br_do_add(struct super_block *sb, struct au_branch *br, -+ aufs_bindex_t bindex) -+{ -+ struct dentry *root, *h_dentry; -+ struct inode *root_inode, *h_inode; -+ aufs_bindex_t bbot, amount; -+ -+ root = sb->s_root; -+ root_inode = d_inode(root); -+ bbot = au_sbbot(sb); -+ amount = bbot + 1 - bindex; -+ h_dentry = au_br_dentry(br); -+ au_sbilist_lock(); -+ au_br_do_add_brp(au_sbi(sb), bindex, br, bbot, amount); -+ au_br_do_add_hdp(au_di(root), bindex, bbot, amount); -+ au_br_do_add_hip(au_ii(root_inode), bindex, bbot, amount); -+ au_set_h_dptr(root, bindex, dget(h_dentry)); -+ h_inode = d_inode(h_dentry); -+ au_set_h_iptr(root_inode, bindex, au_igrab(h_inode), /*flags*/0); -+ au_sbilist_unlock(); -+} -+ -+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount) -+{ -+ int err; -+ aufs_bindex_t bbot, add_bindex; -+ struct dentry *root, *h_dentry; -+ struct inode *root_inode; -+ struct au_branch *add_branch; -+ -+ root = sb->s_root; -+ root_inode = d_inode(root); -+ IMustLock(root_inode); -+ IiMustWriteLock(root_inode); -+ err = test_add(sb, add, remount); -+ if (unlikely(err < 0)) -+ goto out; -+ if (err) { -+ err = 0; -+ goto out; /* success */ -+ } -+ -+ bbot = au_sbbot(sb); -+ add_branch = au_br_alloc(sb, bbot + 2, add->perm); -+ err = PTR_ERR(add_branch); -+ if (IS_ERR(add_branch)) -+ goto out; -+ -+ err = au_br_init(add_branch, sb, add); -+ if (unlikely(err)) { -+ au_br_do_free(add_branch); -+ goto out; -+ } -+ -+ add_bindex = add->bindex; -+ sysaufs_brs_del(sb, add_bindex); /* remove successors */ -+ au_br_do_add(sb, add_branch, add_bindex); -+ sysaufs_brs_add(sb, add_bindex); /* append successors */ -+ dbgaufs_brs_add(sb, add_bindex, /*topdown*/0); /* rename successors */ -+ -+ h_dentry = add->path.dentry; -+ if (!add_bindex) { -+ au_cpup_attr_all(root_inode, /*force*/1); -+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes; -+ } else -+ au_add_nlink(root_inode, d_inode(h_dentry)); -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static unsigned long long au_farray_cb(struct super_block *sb, void *a, -+ unsigned long long max __maybe_unused, -+ void *arg) -+{ -+ unsigned long long n; -+ struct file **p, *f; -+ struct hlist_bl_head *files; -+ struct hlist_bl_node *pos; -+ struct au_finfo *finfo; -+ -+ n = 0; -+ p = a; -+ files = &au_sbi(sb)->si_files; -+ hlist_bl_lock(files); -+ hlist_bl_for_each_entry(finfo, pos, files, fi_hlist) { -+ f = finfo->fi_file; -+ if (file_count(f) -+ && !special_file(file_inode(f)->i_mode)) { -+ get_file(f); -+ *p++ = f; -+ n++; -+ AuDebugOn(n > max); -+ } -+ } -+ hlist_bl_unlock(files); -+ -+ return n; -+} -+ -+static struct file **au_farray_alloc(struct super_block *sb, -+ unsigned long long *max) -+{ -+ struct au_sbinfo *sbi; -+ -+ sbi = au_sbi(sb); -+ *max = au_lcnt_read(&sbi->si_nfiles, /*do_rev*/1); -+ return au_array_alloc(max, au_farray_cb, sb, /*arg*/NULL); -+} -+ -+static void au_farray_free(struct file **a, unsigned long long max) -+{ -+ unsigned long long ull; -+ -+ for (ull = 0; ull < max; ull++) -+ if (a[ull]) -+ fput(a[ull]); -+ kvfree(a); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * delete a branch -+ */ -+ -+/* to show the line number, do not make it inlined function */ -+#define AuVerbose(do_info, fmt, ...) do { \ -+ if (do_info) \ -+ pr_info(fmt, ##__VA_ARGS__); \ -+} while (0) -+ -+static int au_test_ibusy(struct inode *inode, aufs_bindex_t btop, -+ aufs_bindex_t bbot) -+{ -+ return (inode && !S_ISDIR(inode->i_mode)) || btop == bbot; -+} -+ -+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t btop, -+ aufs_bindex_t bbot) -+{ -+ return au_test_ibusy(d_inode(dentry), btop, bbot); -+} -+ -+/* -+ * test if the branch is deletable or not. -+ */ -+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex, -+ unsigned int sigen, const unsigned int verbose) -+{ -+ int err, i, j, ndentry; -+ aufs_bindex_t btop, bbot; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry *d; -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_dcsub_pages(&dpages, root, NULL, NULL); -+ if (unlikely(err)) -+ goto out_dpages; -+ -+ for (i = 0; !err && i < dpages.ndpage; i++) { -+ dpage = dpages.dpages + i; -+ ndentry = dpage->ndentry; -+ for (j = 0; !err && j < ndentry; j++) { -+ d = dpage->dentries[j]; -+ AuDebugOn(au_dcount(d) <= 0); -+ if (!au_digen_test(d, sigen)) { -+ di_read_lock_child(d, AuLock_IR); -+ if (unlikely(au_dbrange_test(d))) { -+ di_read_unlock(d, AuLock_IR); -+ continue; -+ } -+ } else { -+ di_write_lock_child(d); -+ if (unlikely(au_dbrange_test(d))) { -+ di_write_unlock(d); -+ continue; -+ } -+ err = au_reval_dpath(d, sigen); -+ if (!err) -+ di_downgrade_lock(d, AuLock_IR); -+ else { -+ di_write_unlock(d); -+ break; -+ } -+ } -+ -+ /* AuDbgDentry(d); */ -+ btop = au_dbtop(d); -+ bbot = au_dbbot(d); -+ if (btop <= bindex -+ && bindex <= bbot -+ && au_h_dptr(d, bindex) -+ && au_test_dbusy(d, btop, bbot)) { -+ err = -EBUSY; -+ AuVerbose(verbose, "busy %pd\n", d); -+ AuDbgDentry(d); -+ } -+ di_read_unlock(d, AuLock_IR); -+ } -+ } -+ -+out_dpages: -+ au_dpages_free(&dpages); -+out: -+ return err; -+} -+ -+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex, -+ unsigned int sigen, const unsigned int verbose) -+{ -+ int err; -+ unsigned long long max, ull; -+ struct inode *i, **array; -+ aufs_bindex_t btop, bbot; -+ -+ array = au_iarray_alloc(sb, &max); -+ err = PTR_ERR(array); -+ if (IS_ERR(array)) -+ goto out; -+ -+ err = 0; -+ AuDbg("b%d\n", bindex); -+ for (ull = 0; !err && ull < max; ull++) { -+ i = array[ull]; -+ if (unlikely(!i)) -+ break; -+ if (i->i_ino == AUFS_ROOT_INO) -+ continue; -+ -+ /* AuDbgInode(i); */ -+ if (au_iigen(i, NULL) == sigen) -+ ii_read_lock_child(i); -+ else { -+ ii_write_lock_child(i); -+ err = au_refresh_hinode_self(i); -+ au_iigen_dec(i); -+ if (!err) -+ ii_downgrade_lock(i); -+ else { -+ ii_write_unlock(i); -+ break; -+ } -+ } -+ -+ btop = au_ibtop(i); -+ bbot = au_ibbot(i); -+ if (btop <= bindex -+ && bindex <= bbot -+ && au_h_iptr(i, bindex) -+ && au_test_ibusy(i, btop, bbot)) { -+ err = -EBUSY; -+ AuVerbose(verbose, "busy i%lu\n", i->i_ino); -+ AuDbgInode(i); -+ } -+ ii_read_unlock(i); -+ } -+ au_iarray_free(array, max); -+ -+out: -+ return err; -+} -+ -+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex, -+ const unsigned int verbose) -+{ -+ int err; -+ unsigned int sigen; -+ -+ sigen = au_sigen(root->d_sb); -+ DiMustNoWaiters(root); -+ IiMustNoWaiters(d_inode(root)); -+ di_write_unlock(root); -+ err = test_dentry_busy(root, bindex, sigen, verbose); -+ if (!err) -+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose); -+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */ -+ -+ return err; -+} -+ -+static int test_dir_busy(struct file *file, aufs_bindex_t br_id, -+ struct file **to_free, int *idx) -+{ -+ int err; -+ unsigned char matched, root; -+ aufs_bindex_t bindex, bbot; -+ struct au_fidir *fidir; -+ struct au_hfile *hfile; -+ -+ err = 0; -+ root = IS_ROOT(file->f_path.dentry); -+ if (root) { -+ get_file(file); -+ to_free[*idx] = file; -+ (*idx)++; -+ goto out; -+ } -+ -+ matched = 0; -+ fidir = au_fi(file)->fi_hdir; -+ AuDebugOn(!fidir); -+ bbot = au_fbbot_dir(file); -+ for (bindex = au_fbtop(file); bindex <= bbot; bindex++) { -+ hfile = fidir->fd_hfile + bindex; -+ if (!hfile->hf_file) -+ continue; -+ -+ if (hfile->hf_br->br_id == br_id) { -+ matched = 1; -+ break; -+ } -+ } -+ if (matched) -+ err = -EBUSY; -+ -+out: -+ return err; -+} -+ -+static int test_file_busy(struct super_block *sb, aufs_bindex_t br_id, -+ struct file **to_free, int opened) -+{ -+ int err, idx; -+ unsigned long long ull, max; -+ aufs_bindex_t btop; -+ struct file *file, **array; -+ struct dentry *root; -+ struct au_hfile *hfile; -+ -+ array = au_farray_alloc(sb, &max); -+ err = PTR_ERR(array); -+ if (IS_ERR(array)) -+ goto out; -+ -+ err = 0; -+ idx = 0; -+ root = sb->s_root; -+ di_write_unlock(root); -+ for (ull = 0; ull < max; ull++) { -+ file = array[ull]; -+ if (unlikely(!file)) -+ break; -+ -+ /* AuDbg("%pD\n", file); */ -+ fi_read_lock(file); -+ btop = au_fbtop(file); -+ if (!d_is_dir(file->f_path.dentry)) { -+ hfile = &au_fi(file)->fi_htop; -+ if (hfile->hf_br->br_id == br_id) -+ err = -EBUSY; -+ } else -+ err = test_dir_busy(file, br_id, to_free, &idx); -+ fi_read_unlock(file); -+ if (unlikely(err)) -+ break; -+ } -+ di_write_lock_child(root); -+ au_farray_free(array, max); -+ AuDebugOn(idx > opened); -+ -+out: -+ return err; -+} -+ -+static void br_del_file(struct file **to_free, unsigned long long opened, -+ aufs_bindex_t br_id) -+{ -+ unsigned long long ull; -+ aufs_bindex_t bindex, btop, bbot, bfound; -+ struct file *file; -+ struct au_fidir *fidir; -+ struct au_hfile *hfile; -+ -+ for (ull = 0; ull < opened; ull++) { -+ file = to_free[ull]; -+ if (unlikely(!file)) -+ break; -+ -+ /* AuDbg("%pD\n", file); */ -+ AuDebugOn(!d_is_dir(file->f_path.dentry)); -+ bfound = -1; -+ fidir = au_fi(file)->fi_hdir; -+ AuDebugOn(!fidir); -+ fi_write_lock(file); -+ btop = au_fbtop(file); -+ bbot = au_fbbot_dir(file); -+ for (bindex = btop; bindex <= bbot; bindex++) { -+ hfile = fidir->fd_hfile + bindex; -+ if (!hfile->hf_file) -+ continue; -+ -+ if (hfile->hf_br->br_id == br_id) { -+ bfound = bindex; -+ break; -+ } -+ } -+ AuDebugOn(bfound < 0); -+ au_set_h_fptr(file, bfound, NULL); -+ if (bfound == btop) { -+ for (btop++; btop <= bbot; btop++) -+ if (au_hf_dir(file, btop)) { -+ au_set_fbtop(file, btop); -+ break; -+ } -+ } -+ fi_write_unlock(file); -+ } -+} -+ -+static void au_br_do_del_brp(struct au_sbinfo *sbinfo, -+ const aufs_bindex_t bindex, -+ const aufs_bindex_t bbot) -+{ -+ struct au_branch **brp, **p; -+ -+ AuRwMustWriteLock(&sbinfo->si_rwsem); -+ -+ brp = sbinfo->si_branch + bindex; -+ if (bindex < bbot) -+ memmove(brp, brp + 1, sizeof(*brp) * (bbot - bindex)); -+ sbinfo->si_branch[0 + bbot] = NULL; -+ sbinfo->si_bbot--; -+ -+ p = au_krealloc(sbinfo->si_branch, sizeof(*p) * bbot, AuGFP_SBILIST, -+ /*may_shrink*/1); -+ if (p) -+ sbinfo->si_branch = p; -+ /* harmless error */ -+} -+ -+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex, -+ const aufs_bindex_t bbot) -+{ -+ struct au_hdentry *hdp, *p; -+ -+ AuRwMustWriteLock(&dinfo->di_rwsem); -+ -+ hdp = au_hdentry(dinfo, bindex); -+ if (bindex < bbot) -+ memmove(hdp, hdp + 1, sizeof(*hdp) * (bbot - bindex)); -+ /* au_h_dentry_init(au_hdentry(dinfo, bbot); */ -+ dinfo->di_bbot--; -+ -+ p = au_krealloc(dinfo->di_hdentry, sizeof(*p) * bbot, AuGFP_SBILIST, -+ /*may_shrink*/1); -+ if (p) -+ dinfo->di_hdentry = p; -+ /* harmless error */ -+} -+ -+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex, -+ const aufs_bindex_t bbot) -+{ -+ struct au_hinode *hip, *p; -+ -+ AuRwMustWriteLock(&iinfo->ii_rwsem); -+ -+ hip = au_hinode(iinfo, bindex); -+ if (bindex < bbot) -+ memmove(hip, hip + 1, sizeof(*hip) * (bbot - bindex)); -+ /* au_hinode_init(au_hinode(iinfo, bbot)); */ -+ iinfo->ii_bbot--; -+ -+ p = au_krealloc(iinfo->ii_hinode, sizeof(*p) * bbot, AuGFP_SBILIST, -+ /*may_shrink*/1); -+ if (p) -+ iinfo->ii_hinode = p; -+ /* harmless error */ -+} -+ -+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex, -+ struct au_branch *br) -+{ -+ aufs_bindex_t bbot; -+ struct au_sbinfo *sbinfo; -+ struct dentry *root, *h_root; -+ struct inode *inode, *h_inode; -+ struct au_hinode *hinode; -+ -+ SiMustWriteLock(sb); -+ -+ root = sb->s_root; -+ inode = d_inode(root); -+ sbinfo = au_sbi(sb); -+ bbot = sbinfo->si_bbot; -+ -+ h_root = au_h_dptr(root, bindex); -+ hinode = au_hi(inode, bindex); -+ h_inode = au_igrab(hinode->hi_inode); -+ au_hiput(hinode); -+ -+ au_sbilist_lock(); -+ au_br_do_del_brp(sbinfo, bindex, bbot); -+ au_br_do_del_hdp(au_di(root), bindex, bbot); -+ au_br_do_del_hip(au_ii(inode), bindex, bbot); -+ au_sbilist_unlock(); -+ -+ /* ignore an error */ -+ au_dr_br_fin(sb, br); /* always, regardless the mount option */ -+ -+ dput(h_root); -+ iput(h_inode); -+ au_br_do_free(br); -+} -+ -+static unsigned long long empty_cb(struct super_block *sb, void *array, -+ unsigned long long max, void *arg) -+{ -+ return max; -+} -+ -+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount) -+{ -+ int err, rerr, i; -+ unsigned long long opened; -+ unsigned int mnt_flags; -+ aufs_bindex_t bindex, bbot, br_id; -+ unsigned char do_wh, verbose; -+ struct au_branch *br; -+ struct au_wbr *wbr; -+ struct dentry *root; -+ struct file **to_free; -+ -+ err = 0; -+ opened = 0; -+ to_free = NULL; -+ root = sb->s_root; -+ bindex = au_find_dbindex(root, del->h_path.dentry); -+ if (bindex < 0) { -+ if (remount) -+ goto out; /* success */ -+ err = -ENOENT; -+ pr_err("%s no such branch\n", del->pathname); -+ goto out; -+ } -+ AuDbg("bindex b%d\n", bindex); -+ -+ err = -EBUSY; -+ mnt_flags = au_mntflags(sb); -+ verbose = !!au_opt_test(mnt_flags, VERBOSE); -+ bbot = au_sbbot(sb); -+ if (unlikely(!bbot)) { -+ AuVerbose(verbose, "no more branches left\n"); -+ goto out; -+ } -+ -+ br = au_sbr(sb, bindex); -+ AuDebugOn(!path_equal(&br->br_path, &del->h_path)); -+ if (unlikely(au_lcnt_read(&br->br_count, /*do_rev*/1))) { -+ AuVerbose(verbose, "br %pd2 is busy now\n", del->h_path.dentry); -+ goto out; -+ } -+ -+ br_id = br->br_id; -+ opened = au_lcnt_read(&br->br_nfiles, /*do_rev*/1); -+ if (unlikely(opened)) { -+ to_free = au_array_alloc(&opened, empty_cb, sb, NULL); -+ err = PTR_ERR(to_free); -+ if (IS_ERR(to_free)) -+ goto out; -+ -+ err = test_file_busy(sb, br_id, to_free, opened); -+ if (unlikely(err)) { -+ AuVerbose(verbose, "%llu file(s) opened\n", opened); -+ goto out; -+ } -+ } -+ -+ wbr = br->br_wbr; -+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph); -+ if (do_wh) { -+ /* instead of WbrWhMustWriteLock(wbr) */ -+ SiMustWriteLock(sb); -+ for (i = 0; i < AuBrWh_Last; i++) { -+ dput(wbr->wbr_wh[i]); -+ wbr->wbr_wh[i] = NULL; -+ } -+ } -+ -+ err = test_children_busy(root, bindex, verbose); -+ if (unlikely(err)) { -+ if (do_wh) -+ goto out_wh; -+ goto out; -+ } -+ -+ err = 0; -+ if (to_free) { -+ /* -+ * now we confirmed the branch is deletable. -+ * let's free the remaining opened dirs on the branch. -+ */ -+ di_write_unlock(root); -+ br_del_file(to_free, opened, br_id); -+ di_write_lock_child(root); -+ } -+ -+ sysaufs_brs_del(sb, bindex); /* remove successors */ -+ dbgaufs_xino_del(br); /* remove one */ -+ au_br_do_del(sb, bindex, br); -+ sysaufs_brs_add(sb, bindex); /* append successors */ -+ dbgaufs_brs_add(sb, bindex, /*topdown*/1); /* rename successors */ -+ -+ if (!bindex) { -+ au_cpup_attr_all(d_inode(root), /*force*/1); -+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes; -+ } else -+ au_sub_nlink(d_inode(root), d_inode(del->h_path.dentry)); -+ if (au_opt_test(mnt_flags, PLINK)) -+ au_plink_half_refresh(sb, br_id); -+ -+ goto out; /* success */ -+ -+out_wh: -+ /* revert */ -+ rerr = au_br_init_wh(sb, br, br->br_perm); -+ if (rerr) -+ pr_warn("failed re-creating base whiteout, %s. (%d)\n", -+ del->pathname, rerr); -+out: -+ if (to_free) -+ au_farray_free(to_free, opened); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg) -+{ -+ int err; -+ aufs_bindex_t btop, bbot; -+ struct aufs_ibusy ibusy; -+ struct inode *inode, *h_inode; -+ -+ err = -EPERM; -+ if (unlikely(!capable(CAP_SYS_ADMIN))) -+ goto out; -+ -+ err = copy_from_user(&ibusy, arg, sizeof(ibusy)); -+ if (!err) -+ err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ goto out; -+ } -+ -+ err = -EINVAL; -+ si_read_lock(sb, AuLock_FLUSH); -+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbbot(sb))) -+ goto out_unlock; -+ -+ err = 0; -+ ibusy.h_ino = 0; /* invalid */ -+ inode = ilookup(sb, ibusy.ino); -+ if (!inode -+ || inode->i_ino == AUFS_ROOT_INO -+ || au_is_bad_inode(inode)) -+ goto out_unlock; -+ -+ ii_read_lock_child(inode); -+ btop = au_ibtop(inode); -+ bbot = au_ibbot(inode); -+ if (btop <= ibusy.bindex && ibusy.bindex <= bbot) { -+ h_inode = au_h_iptr(inode, ibusy.bindex); -+ if (h_inode && au_test_ibusy(inode, btop, bbot)) -+ ibusy.h_ino = h_inode->i_ino; -+ } -+ ii_read_unlock(inode); -+ iput(inode); -+ -+out_unlock: -+ si_read_unlock(sb); -+ if (!err) { -+ err = __put_user(ibusy.h_ino, &arg->h_ino); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ } -+ } -+out: -+ return err; -+} -+ -+long au_ibusy_ioctl(struct file *file, unsigned long arg) -+{ -+ return au_ibusy(file->f_path.dentry->d_sb, (void __user *)arg); -+} -+ -+#ifdef CONFIG_COMPAT -+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg) -+{ -+ return au_ibusy(file->f_path.dentry->d_sb, compat_ptr(arg)); -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * change a branch permission -+ */ -+ -+static void au_warn_ima(void) -+{ -+#ifdef CONFIG_IMA -+ /* since it doesn't support mark_files_ro() */ -+ AuWarn1("RW -> RO makes IMA to produce wrong message\n"); -+#endif -+} -+ -+static int do_need_sigen_inc(int a, int b) -+{ -+ return au_br_whable(a) && !au_br_whable(b); -+} -+ -+static int need_sigen_inc(int old, int new) -+{ -+ return do_need_sigen_inc(old, new) -+ || do_need_sigen_inc(new, old); -+} -+ -+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ int err, do_warn; -+ unsigned int mnt_flags; -+ unsigned long long ull, max; -+ aufs_bindex_t br_id; -+ unsigned char verbose, writer; -+ struct file *file, *hf, **array; -+ struct au_hfile *hfile; -+ -+ mnt_flags = au_mntflags(sb); -+ verbose = !!au_opt_test(mnt_flags, VERBOSE); -+ -+ array = au_farray_alloc(sb, &max); -+ err = PTR_ERR(array); -+ if (IS_ERR(array)) -+ goto out; -+ -+ do_warn = 0; -+ br_id = au_sbr_id(sb, bindex); -+ for (ull = 0; ull < max; ull++) { -+ file = array[ull]; -+ if (unlikely(!file)) -+ break; -+ -+ /* AuDbg("%pD\n", file); */ -+ fi_read_lock(file); -+ if (unlikely(au_test_mmapped(file))) { -+ err = -EBUSY; -+ AuVerbose(verbose, "mmapped %pD\n", file); -+ AuDbgFile(file); -+ FiMustNoWaiters(file); -+ fi_read_unlock(file); -+ goto out_array; -+ } -+ -+ hfile = &au_fi(file)->fi_htop; -+ hf = hfile->hf_file; -+ if (!d_is_reg(file->f_path.dentry) -+ || !(file->f_mode & FMODE_WRITE) -+ || hfile->hf_br->br_id != br_id -+ || !(hf->f_mode & FMODE_WRITE)) -+ array[ull] = NULL; -+ else { -+ do_warn = 1; -+ get_file(file); -+ } -+ -+ FiMustNoWaiters(file); -+ fi_read_unlock(file); -+ fput(file); -+ } -+ -+ err = 0; -+ if (do_warn) -+ au_warn_ima(); -+ -+ for (ull = 0; ull < max; ull++) { -+ file = array[ull]; -+ if (!file) -+ continue; -+ -+ /* todo: already flushed? */ -+ /* -+ * fs/super.c:mark_files_ro() is gone, but aufs keeps its -+ * approach which resets f_mode and calls mnt_drop_write() and -+ * file_release_write() for each file, because the branch -+ * attribute in aufs world is totally different from the native -+ * fs rw/ro mode. -+ */ -+ /* fi_read_lock(file); */ -+ hfile = &au_fi(file)->fi_htop; -+ hf = hfile->hf_file; -+ /* fi_read_unlock(file); */ -+ spin_lock(&hf->f_lock); -+ writer = !!(hf->f_mode & FMODE_WRITER); -+ hf->f_mode &= ~(FMODE_WRITE | FMODE_WRITER); -+ spin_unlock(&hf->f_lock); -+ if (writer) { -+ put_write_access(file_inode(hf)); -+ __mnt_drop_write(hf->f_path.mnt); -+ } -+ } -+ -+out_array: -+ au_farray_free(array, max); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, -+ int *do_refresh) -+{ -+ int err, rerr; -+ aufs_bindex_t bindex; -+ struct dentry *root; -+ struct au_branch *br; -+ struct au_br_fhsm *bf; -+ -+ root = sb->s_root; -+ bindex = au_find_dbindex(root, mod->h_root); -+ if (bindex < 0) { -+ if (remount) -+ return 0; /* success */ -+ err = -ENOENT; -+ pr_err("%s no such branch\n", mod->path); -+ goto out; -+ } -+ AuDbg("bindex b%d\n", bindex); -+ -+ err = test_br(d_inode(mod->h_root), mod->perm, mod->path); -+ if (unlikely(err)) -+ goto out; -+ -+ br = au_sbr(sb, bindex); -+ AuDebugOn(mod->h_root != au_br_dentry(br)); -+ if (br->br_perm == mod->perm) -+ return 0; /* success */ -+ -+ /* pre-allocate for non-fhsm --> fhsm */ -+ bf = NULL; -+ if (!au_br_fhsm(br->br_perm) && au_br_fhsm(mod->perm)) { -+ err = au_fhsm_br_alloc(br); -+ if (unlikely(err)) -+ goto out; -+ bf = br->br_fhsm; -+ br->br_fhsm = NULL; -+ } -+ -+ if (au_br_writable(br->br_perm)) { -+ /* remove whiteout base */ -+ err = au_br_init_wh(sb, br, mod->perm); -+ if (unlikely(err)) -+ goto out_bf; -+ -+ if (!au_br_writable(mod->perm)) { -+ /* rw --> ro, file might be mmapped */ -+ DiMustNoWaiters(root); -+ IiMustNoWaiters(d_inode(root)); -+ di_write_unlock(root); -+ err = au_br_mod_files_ro(sb, bindex); -+ /* aufs_write_lock() calls ..._child() */ -+ di_write_lock_child(root); -+ -+ if (unlikely(err)) { -+ rerr = -ENOMEM; -+ br->br_wbr = kzalloc(sizeof(*br->br_wbr), -+ GFP_NOFS); -+ if (br->br_wbr) -+ rerr = au_wbr_init(br, sb, br->br_perm); -+ if (unlikely(rerr)) { -+ AuIOErr("nested error %d (%d)\n", -+ rerr, err); -+ br->br_perm = mod->perm; -+ } -+ } -+ } -+ } else if (au_br_writable(mod->perm)) { -+ /* ro --> rw */ -+ err = -ENOMEM; -+ br->br_wbr = kzalloc(sizeof(*br->br_wbr), GFP_NOFS); -+ if (br->br_wbr) { -+ err = au_wbr_init(br, sb, mod->perm); -+ if (unlikely(err)) { -+ kfree(br->br_wbr); -+ br->br_wbr = NULL; -+ } -+ } -+ } -+ if (unlikely(err)) -+ goto out_bf; -+ -+ if (au_br_fhsm(br->br_perm)) { -+ if (!au_br_fhsm(mod->perm)) { -+ /* fhsm --> non-fhsm */ -+ au_br_fhsm_fin(br->br_fhsm); -+ kfree(br->br_fhsm); -+ br->br_fhsm = NULL; -+ } -+ } else if (au_br_fhsm(mod->perm)) -+ /* non-fhsm --> fhsm */ -+ br->br_fhsm = bf; -+ -+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm); -+ br->br_perm = mod->perm; -+ goto out; /* success */ -+ -+out_bf: -+ kfree(bf); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs) -+{ -+ int err; -+ struct kstatfs kstfs; -+ -+ err = vfs_statfs(&br->br_path, &kstfs); -+ if (!err) { -+ stfs->f_blocks = kstfs.f_blocks; -+ stfs->f_bavail = kstfs.f_bavail; -+ stfs->f_files = kstfs.f_files; -+ stfs->f_ffree = kstfs.f_ffree; -+ } -+ -+ return err; -+} -diff --git a/fs/aufs/branch.h b/fs/aufs/branch.h -new file mode 100644 -index 000000000..2b0f58bb9 ---- /dev/null -+++ b/fs/aufs/branch.h -@@ -0,0 +1,367 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * branch filesystems and xino for them -+ */ -+ -+#ifndef __AUFS_BRANCH_H__ -+#define __AUFS_BRANCH_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include "dirren.h" -+#include "dynop.h" -+#include "lcnt.h" -+#include "rwsem.h" -+#include "super.h" -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* a xino file */ -+struct au_xino { -+ struct file **xi_file; -+ unsigned int xi_nfile; -+ -+ struct { -+ spinlock_t spin; -+ ino_t *array; -+ int total; -+ /* reserved for future use */ -+ /* unsigned long *bitmap; */ -+ wait_queue_head_t wqh; -+ } xi_nondir; -+ -+ struct mutex xi_mtx; /* protects xi_file array */ -+ /* reserved for future use */ -+ /* wait_queue_head_t xi_wq; */ -+ /* atomic_t xi_pending; */ -+ -+ atomic_t xi_truncating; -+ -+ struct kref xi_kref; -+}; -+ -+/* File-based Hierarchical Storage Management */ -+struct au_br_fhsm { -+#ifdef CONFIG_AUFS_FHSM -+ struct mutex bf_lock; -+ unsigned long bf_jiffy; -+ struct aufs_stfs bf_stfs; -+ int bf_readable; -+#endif -+}; -+ -+/* members for writable branch only */ -+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last}; -+struct au_wbr { -+ struct au_rwsem wbr_wh_rwsem; -+ struct dentry *wbr_wh[AuBrWh_Last]; -+ atomic_t wbr_wh_running; -+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */ -+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */ -+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */ -+ -+ /* mfs mode */ -+ unsigned long long wbr_bytes; -+}; -+ -+/* ext2 has 3 types of operations at least, ext3 has 4 */ -+#define AuBrDynOp (AuDyLast * 4) -+ -+#ifdef CONFIG_AUFS_HFSNOTIFY -+/* support for asynchronous destruction */ -+struct au_br_hfsnotify { -+ struct fsnotify_group *hfsn_group; -+}; -+#endif -+ -+/* sysfs entries */ -+struct au_brsysfs { -+ char name[16]; -+ struct attribute attr; -+}; -+ -+enum { -+ AuBrSysfs_BR, -+ AuBrSysfs_BRID, -+ AuBrSysfs_Last -+}; -+ -+/* protected by superblock rwsem */ -+struct au_branch { -+ struct au_xino *br_xino; -+ -+ aufs_bindex_t br_id; -+ -+ int br_perm; -+ struct path br_path; -+ spinlock_t br_dykey_lock; -+ struct au_dykey *br_dykey[AuBrDynOp]; -+ au_lcnt_t br_nfiles; /* opened files */ -+ au_lcnt_t br_count; /* in-use for other */ -+ -+ struct au_wbr *br_wbr; -+ struct au_br_fhsm *br_fhsm; -+ -+#ifdef CONFIG_AUFS_HFSNOTIFY -+ struct au_br_hfsnotify *br_hfsn; -+#endif -+ -+#ifdef CONFIG_SYSFS -+ /* entries under sysfs per mount-point */ -+ struct au_brsysfs br_sysfs[AuBrSysfs_Last]; -+#endif -+ -+#ifdef CONFIG_DEBUG_FS -+ struct dentry *br_dbgaufs; /* xino */ -+#endif -+ -+ struct au_dr_br br_dirren; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct vfsmount *au_br_mnt(struct au_branch *br) -+{ -+ return br->br_path.mnt; -+} -+ -+static inline struct dentry *au_br_dentry(struct au_branch *br) -+{ -+ return br->br_path.dentry; -+} -+ -+static inline struct super_block *au_br_sb(struct au_branch *br) -+{ -+ return au_br_mnt(br)->mnt_sb; -+} -+ -+static inline int au_br_rdonly(struct au_branch *br) -+{ -+ return (sb_rdonly(au_br_sb(br)) -+ || !au_br_writable(br->br_perm)) -+ ? -EROFS : 0; -+} -+ -+static inline int au_br_hnotifyable(int brperm __maybe_unused) -+{ -+#ifdef CONFIG_AUFS_HNOTIFY -+ return !(brperm & AuBrPerm_RR); -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_br_test_oflag(int oflag, struct au_branch *br) -+{ -+ int err, exec_flag; -+ -+ err = 0; -+ exec_flag = oflag & __FMODE_EXEC; -+ if (unlikely(exec_flag && path_noexec(&br->br_path))) -+ err = -EACCES; -+ -+ return err; -+} -+ -+static inline void au_xino_get(struct au_branch *br) -+{ -+ struct au_xino *xi; -+ -+ xi = br->br_xino; -+ if (xi) -+ kref_get(&xi->xi_kref); -+} -+ -+static inline int au_xino_count(struct au_branch *br) -+{ -+ int v; -+ struct au_xino *xi; -+ -+ v = 0; -+ xi = br->br_xino; -+ if (xi) -+ v = kref_read(&xi->xi_kref); -+ -+ return v; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* branch.c */ -+struct au_sbinfo; -+void au_br_free(struct au_sbinfo *sinfo); -+int au_br_index(struct super_block *sb, aufs_bindex_t br_id); -+struct au_opt_add; -+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount); -+struct au_opt_del; -+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount); -+long au_ibusy_ioctl(struct file *file, unsigned long arg); -+#ifdef CONFIG_COMPAT -+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg); -+#endif -+struct au_opt_mod; -+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, -+ int *do_refresh); -+struct aufs_stfs; -+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs); -+ -+/* xino.c */ -+static const loff_t au_loff_max = LLONG_MAX; -+ -+aufs_bindex_t au_xi_root(struct super_block *sb, struct dentry *dentry); -+struct file *au_xino_create(struct super_block *sb, char *fpath, int silent); -+struct file *au_xino_create2(struct super_block *sb, struct path *base, -+ struct file *copy_src); -+struct au_xi_new { -+ struct au_xino *xi; /* switch between xino and xigen */ -+ int idx; -+ struct path *base; -+ struct file *copy_src; -+}; -+struct file *au_xi_new(struct super_block *sb, struct au_xi_new *xinew); -+ -+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ ino_t *ino); -+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ ino_t ino); -+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *buf, size_t size, -+ loff_t *pos); -+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos); -+ -+int au_xib_trunc(struct super_block *sb); -+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex, int idx_begin); -+ -+struct au_xino *au_xino_alloc(unsigned int nfile); -+int au_xino_put(struct au_branch *br); -+struct file *au_xino_file1(struct au_xino *xi); -+ -+struct au_opt_xino; -+void au_xino_clr(struct super_block *sb); -+int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt, int remount); -+struct file *au_xino_def(struct super_block *sb); -+int au_xino_init_br(struct super_block *sb, struct au_branch *br, ino_t hino, -+ struct path *base); -+ -+ino_t au_xino_new_ino(struct super_block *sb); -+void au_xino_delete_inode(struct inode *inode, const int unlinked); -+ -+void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex, -+ ino_t h_ino, int idx); -+int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ int *idx); -+ -+int au_xino_path(struct seq_file *seq, struct file *file); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* @idx is signed to accept -1 meaning the first file */ -+static inline struct file *au_xino_file(struct au_xino *xi, int idx) -+{ -+ struct file *file; -+ -+ file = NULL; -+ if (!xi) -+ goto out; -+ -+ if (idx >= 0) { -+ if (idx < xi->xi_nfile) -+ file = xi->xi_file[idx]; -+ } else -+ file = au_xino_file1(xi); -+ -+out: -+ return file; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* Superblock to branch */ -+static inline -+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ return au_sbr(sb, bindex)->br_id; -+} -+ -+static inline -+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ return au_br_mnt(au_sbr(sb, bindex)); -+} -+ -+static inline -+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ return au_br_sb(au_sbr(sb, bindex)); -+} -+ -+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ return au_sbr(sb, bindex)->br_perm; -+} -+ -+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ return au_br_whable(au_sbr_perm(sb, bindex)); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define wbr_wh_read_lock(wbr) au_rw_read_lock(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_write_lock(wbr) au_rw_write_lock(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_read_trylock(wbr) au_rw_read_trylock(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_write_trylock(wbr) au_rw_write_trylock(&(wbr)->wbr_wh_rwsem) -+/* -+#define wbr_wh_read_trylock_nested(wbr) \ -+ au_rw_read_trylock_nested(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_write_trylock_nested(wbr) \ -+ au_rw_write_trylock_nested(&(wbr)->wbr_wh_rwsem) -+*/ -+ -+#define wbr_wh_read_unlock(wbr) au_rw_read_unlock(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_write_unlock(wbr) au_rw_write_unlock(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_downgrade_lock(wbr) au_rw_dgrade_lock(&(wbr)->wbr_wh_rwsem) -+ -+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&(wbr)->wbr_wh_rwsem) -+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&(wbr)->wbr_wh_rwsem) -+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&(wbr)->wbr_wh_rwsem) -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_FHSM -+static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm) -+{ -+ mutex_init(&brfhsm->bf_lock); -+ brfhsm->bf_jiffy = 0; -+ brfhsm->bf_readable = 0; -+} -+ -+static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm) -+{ -+ mutex_destroy(&brfhsm->bf_lock); -+} -+#else -+AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm) -+AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm) -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_BRANCH_H__ */ -diff --git a/fs/aufs/conf.mk b/fs/aufs/conf.mk -new file mode 100644 -index 000000000..12782f8e0 ---- /dev/null -+++ b/fs/aufs/conf.mk -@@ -0,0 +1,40 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS} -+ -+define AuConf -+ifdef ${1} -+AuConfStr += ${1}=${${1}} -+endif -+endef -+ -+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \ -+ SBILIST \ -+ HNOTIFY HFSNOTIFY \ -+ EXPORT INO_T_64 \ -+ XATTR \ -+ FHSM \ -+ RDU \ -+ DIRREN \ -+ SHWH \ -+ BR_RAMFS \ -+ BR_FUSE POLL \ -+ BR_HFSPLUS \ -+ BDEV_LOOP \ -+ DEBUG MAGIC_SYSRQ -+$(foreach i, ${AuConfAll}, \ -+ $(eval $(call AuConf,CONFIG_AUFS_${i}))) -+ -+AuConfName = ${obj}/conf.str -+${AuConfName}.tmp: FORCE -+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@ -+${AuConfName}: ${AuConfName}.tmp -+ @diff -q $< $@ > /dev/null 2>&1 || { \ -+ echo ' GEN ' $@; \ -+ cp -p $< $@; \ -+ } -+FORCE: -+clean-files += ${AuConfName} ${AuConfName}.tmp -+${obj}/sysfs.o: ${AuConfName} -+ -+-include ${srctree}/${src}/conf_priv.mk -diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c -new file mode 100644 -index 000000000..a1ef90f08 ---- /dev/null -+++ b/fs/aufs/cpup.c -@@ -0,0 +1,1444 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * copy-up functions, see wbr_policy.c for copy-down -+ */ -+ -+#include -+#include -+#include -+#include "aufs.h" -+ -+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags) -+{ -+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE -+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT; -+ -+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags)); -+ -+ dst->i_flags |= iflags & ~mask; -+ if (au_test_fs_notime(dst->i_sb)) -+ dst->i_flags |= S_NOATIME | S_NOCMTIME; -+} -+ -+void au_cpup_attr_timesizes(struct inode *inode) -+{ -+ struct inode *h_inode; -+ -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ fsstack_copy_attr_times(inode, h_inode); -+ fsstack_copy_inode_size(inode, h_inode); -+} -+ -+void au_cpup_attr_nlink(struct inode *inode, int force) -+{ -+ struct inode *h_inode; -+ struct super_block *sb; -+ aufs_bindex_t bindex, bbot; -+ -+ sb = inode->i_sb; -+ bindex = au_ibtop(inode); -+ h_inode = au_h_iptr(inode, bindex); -+ if (!force -+ && !S_ISDIR(h_inode->i_mode) -+ && au_opt_test(au_mntflags(sb), PLINK) -+ && au_plink_test(inode)) -+ return; -+ -+ /* -+ * 0 can happen in revalidating. -+ * h_inode->i_mutex may not be held here, but it is harmless since once -+ * i_nlink reaches 0, it will never become positive except O_TMPFILE -+ * case. -+ * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause -+ * the incorrect link count. -+ */ -+ set_nlink(inode, h_inode->i_nlink); -+ -+ /* -+ * fewer nlink makes find(1) noisy, but larger nlink doesn't. -+ * it may includes whplink directory. -+ */ -+ if (S_ISDIR(h_inode->i_mode)) { -+ bbot = au_ibbot(inode); -+ for (bindex++; bindex <= bbot; bindex++) { -+ h_inode = au_h_iptr(inode, bindex); -+ if (h_inode) -+ au_add_nlink(inode, h_inode); -+ } -+ } -+} -+ -+void au_cpup_attr_changeable(struct inode *inode) -+{ -+ struct inode *h_inode; -+ -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ inode->i_mode = h_inode->i_mode; -+ inode->i_uid = h_inode->i_uid; -+ inode->i_gid = h_inode->i_gid; -+ au_cpup_attr_timesizes(inode); -+ au_cpup_attr_flags(inode, h_inode->i_flags); -+} -+ -+void au_cpup_igen(struct inode *inode, struct inode *h_inode) -+{ -+ struct au_iinfo *iinfo = au_ii(inode); -+ -+ IiMustWriteLock(inode); -+ -+ iinfo->ii_higen = h_inode->i_generation; -+ iinfo->ii_hsb1 = h_inode->i_sb; -+} -+ -+void au_cpup_attr_all(struct inode *inode, int force) -+{ -+ struct inode *h_inode; -+ -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ au_cpup_attr_changeable(inode); -+ if (inode->i_nlink > 0) -+ au_cpup_attr_nlink(inode, force); -+ inode->i_rdev = h_inode->i_rdev; -+ inode->i_blkbits = h_inode->i_blkbits; -+ au_cpup_igen(inode, h_inode); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */ -+ -+/* keep the timestamps of the parent dir when cpup */ -+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, -+ struct path *h_path) -+{ -+ struct inode *h_inode; -+ -+ dt->dt_dentry = dentry; -+ dt->dt_h_path = *h_path; -+ h_inode = d_inode(h_path->dentry); -+ dt->dt_atime = h_inode->i_atime; -+ dt->dt_mtime = h_inode->i_mtime; -+ /* smp_mb(); */ -+} -+ -+void au_dtime_revert(struct au_dtime *dt) -+{ -+ struct iattr attr; -+ int err; -+ -+ attr.ia_atime = dt->dt_atime; -+ attr.ia_mtime = dt->dt_mtime; -+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET -+ | ATTR_ATIME | ATTR_ATIME_SET; -+ -+ /* no delegation since this is a directory */ -+ err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL); -+ if (unlikely(err)) -+ pr_warn("restoring timestamps failed(%d). ignored\n", err); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* internal use only */ -+struct au_cpup_reg_attr { -+ int valid; -+ struct kstat st; -+ unsigned int iflags; /* inode->i_flags */ -+}; -+ -+static noinline_for_stack -+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src, -+ struct au_cpup_reg_attr *h_src_attr) -+{ -+ int err, sbits, icex; -+ unsigned int mnt_flags; -+ unsigned char verbose; -+ struct iattr ia; -+ struct path h_path; -+ struct inode *h_isrc, *h_idst; -+ struct kstat *h_st; -+ struct au_branch *br; -+ -+ h_path.dentry = au_h_dptr(dst, bindex); -+ h_idst = d_inode(h_path.dentry); -+ br = au_sbr(dst->d_sb, bindex); -+ h_path.mnt = au_br_mnt(br); -+ h_isrc = d_inode(h_src); -+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID -+ | ATTR_ATIME | ATTR_MTIME -+ | ATTR_ATIME_SET | ATTR_MTIME_SET; -+ if (h_src_attr && h_src_attr->valid) { -+ h_st = &h_src_attr->st; -+ ia.ia_uid = h_st->uid; -+ ia.ia_gid = h_st->gid; -+ ia.ia_atime = h_st->atime; -+ ia.ia_mtime = h_st->mtime; -+ if (h_idst->i_mode != h_st->mode -+ && !S_ISLNK(h_idst->i_mode)) { -+ ia.ia_valid |= ATTR_MODE; -+ ia.ia_mode = h_st->mode; -+ } -+ sbits = !!(h_st->mode & (S_ISUID | S_ISGID)); -+ au_cpup_attr_flags(h_idst, h_src_attr->iflags); -+ } else { -+ ia.ia_uid = h_isrc->i_uid; -+ ia.ia_gid = h_isrc->i_gid; -+ ia.ia_atime = h_isrc->i_atime; -+ ia.ia_mtime = h_isrc->i_mtime; -+ if (h_idst->i_mode != h_isrc->i_mode -+ && !S_ISLNK(h_idst->i_mode)) { -+ ia.ia_valid |= ATTR_MODE; -+ ia.ia_mode = h_isrc->i_mode; -+ } -+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID)); -+ au_cpup_attr_flags(h_idst, h_isrc->i_flags); -+ } -+ /* no delegation since it is just created */ -+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL); -+ -+ /* is this nfs only? */ -+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) { -+ ia.ia_valid = ATTR_FORCE | ATTR_MODE; -+ ia.ia_mode = h_isrc->i_mode; -+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL); -+ } -+ -+ icex = br->br_perm & AuBrAttr_ICEX; -+ if (!err) { -+ mnt_flags = au_mntflags(dst->d_sb); -+ verbose = !!au_opt_test(mnt_flags, VERBOSE); -+ err = au_cpup_xattr(h_path.dentry, h_src, icex, verbose); -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len, -+ char *buf, unsigned long blksize) -+{ -+ int err; -+ size_t sz, rbytes, wbytes; -+ unsigned char all_zero; -+ char *p, *zp; -+ struct inode *h_inode; -+ /* reduce stack usage */ -+ struct iattr *ia; -+ -+ zp = page_address(ZERO_PAGE(0)); -+ if (unlikely(!zp)) -+ return -ENOMEM; /* possible? */ -+ -+ err = 0; -+ all_zero = 0; -+ while (len) { -+ AuDbg("len %lld\n", len); -+ sz = blksize; -+ if (len < blksize) -+ sz = len; -+ -+ rbytes = 0; -+ /* todo: signal_pending? */ -+ while (!rbytes || err == -EAGAIN || err == -EINTR) { -+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos); -+ err = rbytes; -+ } -+ if (unlikely(err < 0)) -+ break; -+ -+ all_zero = 0; -+ if (len >= rbytes && rbytes == blksize) -+ all_zero = !memcmp(buf, zp, rbytes); -+ if (!all_zero) { -+ wbytes = rbytes; -+ p = buf; -+ while (wbytes) { -+ size_t b; -+ -+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos); -+ err = b; -+ /* todo: signal_pending? */ -+ if (unlikely(err == -EAGAIN || err == -EINTR)) -+ continue; -+ if (unlikely(err < 0)) -+ break; -+ wbytes -= b; -+ p += b; -+ } -+ if (unlikely(err < 0)) -+ break; -+ } else { -+ loff_t res; -+ -+ AuLabel(hole); -+ res = vfsub_llseek(dst, rbytes, SEEK_CUR); -+ err = res; -+ if (unlikely(res < 0)) -+ break; -+ } -+ len -= rbytes; -+ err = 0; -+ } -+ -+ /* the last block may be a hole */ -+ if (!err && all_zero) { -+ AuLabel(last hole); -+ -+ err = 1; -+ if (au_test_nfs(dst->f_path.dentry->d_sb)) { -+ /* nfs requires this step to make last hole */ -+ /* is this only nfs? */ -+ do { -+ /* todo: signal_pending? */ -+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos); -+ } while (err == -EAGAIN || err == -EINTR); -+ if (err == 1) -+ dst->f_pos--; -+ } -+ -+ if (err == 1) { -+ ia = (void *)buf; -+ ia->ia_size = dst->f_pos; -+ ia->ia_valid = ATTR_SIZE | ATTR_FILE; -+ ia->ia_file = dst; -+ h_inode = file_inode(dst); -+ inode_lock_nested(h_inode, AuLsc_I_CHILD2); -+ /* no delegation since it is just created */ -+ err = vfsub_notify_change(&dst->f_path, ia, -+ /*delegated*/NULL); -+ inode_unlock(h_inode); -+ } -+ } -+ -+ return err; -+} -+ -+int au_copy_file(struct file *dst, struct file *src, loff_t len) -+{ -+ int err; -+ unsigned long blksize; -+ unsigned char do_kfree; -+ char *buf; -+ -+ err = -ENOMEM; -+ blksize = dst->f_path.dentry->d_sb->s_blocksize; -+ if (!blksize || PAGE_SIZE < blksize) -+ blksize = PAGE_SIZE; -+ AuDbg("blksize %lu\n", blksize); -+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *)); -+ if (do_kfree) -+ buf = kmalloc(blksize, GFP_NOFS); -+ else -+ buf = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!buf)) -+ goto out; -+ -+ if (len > (1 << 22)) -+ AuDbg("copying a large file %lld\n", (long long)len); -+ -+ src->f_pos = 0; -+ dst->f_pos = 0; -+ err = au_do_copy_file(dst, src, len, buf, blksize); -+ if (do_kfree) -+ kfree(buf); -+ else -+ free_page((unsigned long)buf); -+ -+out: -+ return err; -+} -+ -+static int au_do_copy(struct file *dst, struct file *src, loff_t len) -+{ -+ int err; -+ struct super_block *h_src_sb; -+ struct inode *h_src_inode; -+ -+ h_src_inode = file_inode(src); -+ h_src_sb = h_src_inode->i_sb; -+ -+ /* XFS acquires inode_lock */ -+ if (!au_test_xfs(h_src_sb)) -+ err = au_copy_file(dst, src, len); -+ else { -+ inode_unlock_shared(h_src_inode); -+ err = au_copy_file(dst, src, len); -+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD); -+ } -+ -+ return err; -+} -+ -+static int au_clone_or_copy(struct file *dst, struct file *src, loff_t len) -+{ -+ int err; -+ struct super_block *h_src_sb; -+ struct inode *h_src_inode; -+ -+ h_src_inode = file_inode(src); -+ h_src_sb = h_src_inode->i_sb; -+ if (h_src_sb != file_inode(dst)->i_sb -+ || !dst->f_op->clone_file_range) { -+ err = au_do_copy(dst, src, len); -+ goto out; -+ } -+ -+ if (!au_test_nfs(h_src_sb)) { -+ inode_unlock_shared(h_src_inode); -+ err = vfsub_clone_file_range(src, dst, len); -+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD); -+ } else -+ err = vfsub_clone_file_range(src, dst, len); -+ /* older XFS has a condition in cloning */ -+ if (unlikely(err != -EOPNOTSUPP)) -+ goto out; -+ -+ /* the backend fs on NFS may not support cloning */ -+ err = au_do_copy(dst, src, len); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * to support a sparse file which is opened with O_APPEND, -+ * we need to close the file. -+ */ -+static int au_cp_regular(struct au_cp_generic *cpg) -+{ -+ int err, i; -+ enum { SRC, DST }; -+ struct { -+ aufs_bindex_t bindex; -+ unsigned int flags; -+ struct dentry *dentry; -+ int force_wr; -+ struct file *file; -+ void *label; -+ } *f, file[] = { -+ { -+ .bindex = cpg->bsrc, -+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE, -+ .label = &&out -+ }, -+ { -+ .bindex = cpg->bdst, -+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE, -+ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST), -+ .label = &&out_src -+ } -+ }; -+ struct au_branch *br; -+ struct super_block *sb, *h_src_sb; -+ struct inode *h_src_inode; -+ struct task_struct *tsk = current; -+ -+ /* bsrc branch can be ro/rw. */ -+ sb = cpg->dentry->d_sb; -+ f = file; -+ for (i = 0; i < 2; i++, f++) { -+ f->dentry = au_h_dptr(cpg->dentry, f->bindex); -+ f->file = au_h_open(cpg->dentry, f->bindex, f->flags, -+ /*file*/NULL, f->force_wr); -+ err = PTR_ERR(f->file); -+ if (IS_ERR(f->file)) -+ goto *f->label; -+ } -+ -+ /* try stopping to update while we copyup */ -+ h_src_inode = d_inode(file[SRC].dentry); -+ h_src_sb = h_src_inode->i_sb; -+ if (!au_test_nfs(h_src_sb)) -+ IMustLock(h_src_inode); -+ err = au_clone_or_copy(file[DST].file, file[SRC].file, cpg->len); -+ -+ /* i wonder if we had O_NO_DELAY_FPUT flag */ -+ if (tsk->flags & PF_KTHREAD) -+ __fput_sync(file[DST].file); -+ else { -+ /* it happened actually */ -+ fput(file[DST].file); -+ /* -+ * too bad. -+ * we have to call both since we don't know which place the file -+ * was added to. -+ */ -+ task_work_run(); -+ flush_delayed_fput(); -+ } -+ br = au_sbr(sb, file[DST].bindex); -+ au_lcnt_dec(&br->br_nfiles); -+ -+out_src: -+ fput(file[SRC].file); -+ br = au_sbr(sb, file[SRC].bindex); -+ au_lcnt_dec(&br->br_nfiles); -+out: -+ return err; -+} -+ -+static int au_do_cpup_regular(struct au_cp_generic *cpg, -+ struct au_cpup_reg_attr *h_src_attr) -+{ -+ int err, rerr; -+ loff_t l; -+ struct path h_path; -+ struct inode *h_src_inode, *h_dst_inode; -+ -+ err = 0; -+ h_src_inode = au_h_iptr(d_inode(cpg->dentry), cpg->bsrc); -+ l = i_size_read(h_src_inode); -+ if (cpg->len == -1 || l < cpg->len) -+ cpg->len = l; -+ if (cpg->len) { -+ /* try stopping to update while we are referencing */ -+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD); -+ au_pin_hdir_unlock(cpg->pin); -+ -+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc); -+ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc); -+ h_src_attr->iflags = h_src_inode->i_flags; -+ if (!au_test_nfs(h_src_inode->i_sb)) -+ err = vfsub_getattr(&h_path, &h_src_attr->st); -+ else { -+ inode_unlock_shared(h_src_inode); -+ err = vfsub_getattr(&h_path, &h_src_attr->st); -+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD); -+ } -+ if (unlikely(err)) { -+ inode_unlock_shared(h_src_inode); -+ goto out; -+ } -+ h_src_attr->valid = 1; -+ if (!au_test_nfs(h_src_inode->i_sb)) { -+ err = au_cp_regular(cpg); -+ inode_unlock_shared(h_src_inode); -+ } else { -+ inode_unlock_shared(h_src_inode); -+ err = au_cp_regular(cpg); -+ } -+ rerr = au_pin_hdir_relock(cpg->pin); -+ if (!err && rerr) -+ err = rerr; -+ } -+ if (!err && (h_src_inode->i_state & I_LINKABLE)) { -+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst); -+ h_dst_inode = d_inode(h_path.dentry); -+ spin_lock(&h_dst_inode->i_lock); -+ h_dst_inode->i_state |= I_LINKABLE; -+ spin_unlock(&h_dst_inode->i_lock); -+ } -+ -+out: -+ return err; -+} -+ -+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src, -+ struct inode *h_dir) -+{ -+ int err, symlen; -+ mm_segment_t old_fs; -+ union { -+ char *k; -+ char __user *u; -+ } sym; -+ -+ err = -ENOMEM; -+ sym.k = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!sym.k)) -+ goto out; -+ -+ /* unnecessary to support mmap_sem since symlink is not mmap-able */ -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ symlen = vfs_readlink(h_src, sym.u, PATH_MAX); -+ err = symlen; -+ set_fs(old_fs); -+ -+ if (symlen > 0) { -+ sym.k[symlen] = 0; -+ err = vfsub_symlink(h_dir, h_path, sym.k); -+ } -+ free_page((unsigned long)sym.k); -+ -+out: -+ return err; -+} -+ -+/* -+ * regardless 'acl' option, reset all ACL. -+ * All ACL will be copied up later from the original entry on the lower branch. -+ */ -+static int au_reset_acl(struct inode *h_dir, struct path *h_path, umode_t mode) -+{ -+ int err; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ -+ h_dentry = h_path->dentry; -+ h_inode = d_inode(h_dentry); -+ /* forget_all_cached_acls(h_inode)); */ -+ err = vfsub_removexattr(h_dentry, XATTR_NAME_POSIX_ACL_ACCESS); -+ AuTraceErr(err); -+ if (err == -EOPNOTSUPP) -+ err = 0; -+ if (!err) -+ err = vfsub_acl_chmod(h_inode, mode); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_do_cpup_dir(struct au_cp_generic *cpg, struct dentry *dst_parent, -+ struct inode *h_dir, struct path *h_path) -+{ -+ int err; -+ struct inode *dir, *inode; -+ -+ err = vfsub_removexattr(h_path->dentry, XATTR_NAME_POSIX_ACL_DEFAULT); -+ AuTraceErr(err); -+ if (err == -EOPNOTSUPP) -+ err = 0; -+ if (unlikely(err)) -+ goto out; -+ -+ /* -+ * strange behaviour from the users view, -+ * particularly setattr case -+ */ -+ dir = d_inode(dst_parent); -+ if (au_ibtop(dir) == cpg->bdst) -+ au_cpup_attr_nlink(dir, /*force*/1); -+ inode = d_inode(cpg->dentry); -+ au_cpup_attr_nlink(inode, /*force*/1); -+ -+out: -+ return err; -+} -+ -+static noinline_for_stack -+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent, -+ struct au_cpup_reg_attr *h_src_attr) -+{ -+ int err; -+ umode_t mode; -+ unsigned int mnt_flags; -+ unsigned char isdir, isreg, force; -+ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME); -+ struct au_dtime dt; -+ struct path h_path; -+ struct dentry *h_src, *h_dst, *h_parent; -+ struct inode *h_inode, *h_dir; -+ struct super_block *sb; -+ -+ /* bsrc branch can be ro/rw. */ -+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc); -+ h_inode = d_inode(h_src); -+ AuDebugOn(h_inode != au_h_iptr(d_inode(cpg->dentry), cpg->bsrc)); -+ -+ /* try stopping to be referenced while we are creating */ -+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst); -+ if (au_ftest_cpup(cpg->flags, RENAME)) -+ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX, -+ AUFS_WH_PFX_LEN)); -+ h_parent = h_dst->d_parent; /* dir inode is locked */ -+ h_dir = d_inode(h_parent); -+ IMustLock(h_dir); -+ AuDebugOn(h_parent != h_dst->d_parent); -+ -+ sb = cpg->dentry->d_sb; -+ h_path.mnt = au_sbr_mnt(sb, cpg->bdst); -+ if (do_dt) { -+ h_path.dentry = h_parent; -+ au_dtime_store(&dt, dst_parent, &h_path); -+ } -+ h_path.dentry = h_dst; -+ -+ isreg = 0; -+ isdir = 0; -+ mode = h_inode->i_mode; -+ switch (mode & S_IFMT) { -+ case S_IFREG: -+ isreg = 1; -+ err = vfsub_create(h_dir, &h_path, 0600, /*want_excl*/true); -+ if (!err) -+ err = au_do_cpup_regular(cpg, h_src_attr); -+ break; -+ case S_IFDIR: -+ isdir = 1; -+ err = vfsub_mkdir(h_dir, &h_path, mode); -+ if (!err) -+ err = au_do_cpup_dir(cpg, dst_parent, h_dir, &h_path); -+ break; -+ case S_IFLNK: -+ err = au_do_cpup_symlink(&h_path, h_src, h_dir); -+ break; -+ case S_IFCHR: -+ case S_IFBLK: -+ AuDebugOn(!capable(CAP_MKNOD)); -+ /*FALLTHROUGH*/ -+ case S_IFIFO: -+ case S_IFSOCK: -+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev); -+ break; -+ default: -+ AuIOErr("Unknown inode type 0%o\n", mode); -+ err = -EIO; -+ } -+ if (!err) -+ err = au_reset_acl(h_dir, &h_path, mode); -+ -+ mnt_flags = au_mntflags(sb); -+ if (!au_opt_test(mnt_flags, UDBA_NONE) -+ && !isdir -+ && au_opt_test(mnt_flags, XINO) -+ && (h_inode->i_nlink == 1 -+ || (h_inode->i_state & I_LINKABLE)) -+ /* todo: unnecessary? */ -+ /* && d_inode(cpg->dentry)->i_nlink == 1 */ -+ && cpg->bdst < cpg->bsrc -+ && !au_ftest_cpup(cpg->flags, KEEPLINO)) -+ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0); -+ /* ignore this error */ -+ -+ if (!err) { -+ force = 0; -+ if (isreg) { -+ force = !!cpg->len; -+ if (cpg->len == -1) -+ force = !!i_size_read(h_inode); -+ } -+ au_fhsm_wrote(sb, cpg->bdst, force); -+ } -+ -+ if (do_dt) -+ au_dtime_revert(&dt); -+ return err; -+} -+ -+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path) -+{ -+ int err; -+ struct dentry *dentry, *h_dentry, *h_parent, *parent; -+ struct inode *h_dir; -+ aufs_bindex_t bdst; -+ -+ dentry = cpg->dentry; -+ bdst = cpg->bdst; -+ h_dentry = au_h_dptr(dentry, bdst); -+ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) { -+ dget(h_dentry); -+ au_set_h_dptr(dentry, bdst, NULL); -+ err = au_lkup_neg(dentry, bdst, /*wh*/0); -+ if (!err) -+ h_path->dentry = dget(au_h_dptr(dentry, bdst)); -+ au_set_h_dptr(dentry, bdst, h_dentry); -+ } else { -+ err = 0; -+ parent = dget_parent(dentry); -+ h_parent = au_h_dptr(parent, bdst); -+ dput(parent); -+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent); -+ if (IS_ERR(h_path->dentry)) -+ err = PTR_ERR(h_path->dentry); -+ } -+ if (unlikely(err)) -+ goto out; -+ -+ h_parent = h_dentry->d_parent; /* dir inode is locked */ -+ h_dir = d_inode(h_parent); -+ IMustLock(h_dir); -+ AuDbg("%pd %pd\n", h_dentry, h_path->dentry); -+ /* no delegation since it is just created */ -+ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL, -+ /*flags*/0); -+ dput(h_path->dentry); -+ -+out: -+ return err; -+} -+ -+/* -+ * copyup the @dentry from @bsrc to @bdst. -+ * the caller must set the both of lower dentries. -+ * @len is for truncating when it is -1 copyup the entire file. -+ * in link/rename cases, @dst_parent may be different from the real one. -+ * basic->bsrc can be larger than basic->bdst. -+ * aufs doesn't touch the credential so -+ * security_inode_copy_up{,_xattr}() are unnecessary. -+ */ -+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent) -+{ -+ int err, rerr; -+ aufs_bindex_t old_ibtop; -+ unsigned char isdir, plink; -+ struct dentry *h_src, *h_dst, *h_parent; -+ struct inode *dst_inode, *h_dir, *inode, *delegated, *src_inode; -+ struct super_block *sb; -+ struct au_branch *br; -+ /* to reduce stack size */ -+ struct { -+ struct au_dtime dt; -+ struct path h_path; -+ struct au_cpup_reg_attr h_src_attr; -+ } *a; -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ a->h_src_attr.valid = 0; -+ -+ sb = cpg->dentry->d_sb; -+ br = au_sbr(sb, cpg->bdst); -+ a->h_path.mnt = au_br_mnt(br); -+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst); -+ h_parent = h_dst->d_parent; /* dir inode is locked */ -+ h_dir = d_inode(h_parent); -+ IMustLock(h_dir); -+ -+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc); -+ inode = d_inode(cpg->dentry); -+ -+ if (!dst_parent) -+ dst_parent = dget_parent(cpg->dentry); -+ else -+ dget(dst_parent); -+ -+ plink = !!au_opt_test(au_mntflags(sb), PLINK); -+ dst_inode = au_h_iptr(inode, cpg->bdst); -+ if (dst_inode) { -+ if (unlikely(!plink)) { -+ err = -EIO; -+ AuIOErr("hi%lu(i%lu) exists on b%d " -+ "but plink is disabled\n", -+ dst_inode->i_ino, inode->i_ino, cpg->bdst); -+ goto out_parent; -+ } -+ -+ if (dst_inode->i_nlink) { -+ const int do_dt = au_ftest_cpup(cpg->flags, DTIME); -+ -+ h_src = au_plink_lkup(inode, cpg->bdst); -+ err = PTR_ERR(h_src); -+ if (IS_ERR(h_src)) -+ goto out_parent; -+ if (unlikely(d_is_negative(h_src))) { -+ err = -EIO; -+ AuIOErr("i%lu exists on b%d " -+ "but not pseudo-linked\n", -+ inode->i_ino, cpg->bdst); -+ dput(h_src); -+ goto out_parent; -+ } -+ -+ if (do_dt) { -+ a->h_path.dentry = h_parent; -+ au_dtime_store(&a->dt, dst_parent, &a->h_path); -+ } -+ -+ a->h_path.dentry = h_dst; -+ delegated = NULL; -+ err = vfsub_link(h_src, h_dir, &a->h_path, &delegated); -+ if (!err && au_ftest_cpup(cpg->flags, RENAME)) -+ err = au_do_ren_after_cpup(cpg, &a->h_path); -+ if (do_dt) -+ au_dtime_revert(&a->dt); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ dput(h_src); -+ goto out_parent; -+ } else -+ /* todo: cpup_wh_file? */ -+ /* udba work */ -+ au_update_ibrange(inode, /*do_put_zero*/1); -+ } -+ -+ isdir = S_ISDIR(inode->i_mode); -+ old_ibtop = au_ibtop(inode); -+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr); -+ if (unlikely(err)) -+ goto out_rev; -+ dst_inode = d_inode(h_dst); -+ inode_lock_nested(dst_inode, AuLsc_I_CHILD2); -+ /* todo: necessary? */ -+ /* au_pin_hdir_unlock(cpg->pin); */ -+ -+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr); -+ if (unlikely(err)) { -+ /* todo: necessary? */ -+ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */ -+ inode_unlock(dst_inode); -+ goto out_rev; -+ } -+ -+ if (cpg->bdst < old_ibtop) { -+ if (S_ISREG(inode->i_mode)) { -+ err = au_dy_iaop(inode, cpg->bdst, dst_inode); -+ if (unlikely(err)) { -+ /* ignore an error */ -+ /* au_pin_hdir_relock(cpg->pin); */ -+ inode_unlock(dst_inode); -+ goto out_rev; -+ } -+ } -+ au_set_ibtop(inode, cpg->bdst); -+ } else -+ au_set_ibbot(inode, cpg->bdst); -+ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode), -+ au_hi_flags(inode, isdir)); -+ -+ /* todo: necessary? */ -+ /* err = au_pin_hdir_relock(cpg->pin); */ -+ inode_unlock(dst_inode); -+ if (unlikely(err)) -+ goto out_rev; -+ -+ src_inode = d_inode(h_src); -+ if (!isdir -+ && (src_inode->i_nlink > 1 -+ || src_inode->i_state & I_LINKABLE) -+ && plink) -+ au_plink_append(inode, cpg->bdst, h_dst); -+ -+ if (au_ftest_cpup(cpg->flags, RENAME)) { -+ a->h_path.dentry = h_dst; -+ err = au_do_ren_after_cpup(cpg, &a->h_path); -+ } -+ if (!err) -+ goto out_parent; /* success */ -+ -+ /* revert */ -+out_rev: -+ a->h_path.dentry = h_parent; -+ au_dtime_store(&a->dt, dst_parent, &a->h_path); -+ a->h_path.dentry = h_dst; -+ rerr = 0; -+ if (d_is_positive(h_dst)) { -+ if (!isdir) { -+ /* no delegation since it is just created */ -+ rerr = vfsub_unlink(h_dir, &a->h_path, -+ /*delegated*/NULL, /*force*/0); -+ } else -+ rerr = vfsub_rmdir(h_dir, &a->h_path); -+ } -+ au_dtime_revert(&a->dt); -+ if (rerr) { -+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr); -+ err = -EIO; -+ } -+out_parent: -+ dput(dst_parent); -+ kfree(a); -+out: -+ return err; -+} -+ -+#if 0 /* reserved */ -+struct au_cpup_single_args { -+ int *errp; -+ struct au_cp_generic *cpg; -+ struct dentry *dst_parent; -+}; -+ -+static void au_call_cpup_single(void *args) -+{ -+ struct au_cpup_single_args *a = args; -+ -+ au_pin_hdir_acquire_nest(a->cpg->pin); -+ *a->errp = au_cpup_single(a->cpg, a->dst_parent); -+ au_pin_hdir_release(a->cpg->pin); -+} -+#endif -+ -+/* -+ * prevent SIGXFSZ in copy-up. -+ * testing CAP_MKNOD is for generic fs, -+ * but CAP_FSETID is for xfs only, currently. -+ */ -+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode) -+{ -+ int do_sio; -+ struct super_block *sb; -+ struct inode *h_dir; -+ -+ do_sio = 0; -+ sb = au_pinned_parent(pin)->d_sb; -+ if (!au_wkq_test() -+ && (!au_sbi(sb)->si_plink_maint_pid -+ || au_plink_maint(sb, AuLock_NOPLM))) { -+ switch (mode & S_IFMT) { -+ case S_IFREG: -+ /* no condition about RLIMIT_FSIZE and the file size */ -+ do_sio = 1; -+ break; -+ case S_IFCHR: -+ case S_IFBLK: -+ do_sio = !capable(CAP_MKNOD); -+ break; -+ } -+ if (!do_sio) -+ do_sio = ((mode & (S_ISUID | S_ISGID)) -+ && !capable(CAP_FSETID)); -+ /* this workaround may be removed in the future */ -+ if (!do_sio) { -+ h_dir = au_pinned_h_dir(pin); -+ do_sio = h_dir->i_mode & S_ISVTX; -+ } -+ } -+ -+ return do_sio; -+} -+ -+#if 0 /* reserved */ -+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent) -+{ -+ int err, wkq_err; -+ struct dentry *h_dentry; -+ -+ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc); -+ if (!au_cpup_sio_test(pin, d_inode(h_dentry)->i_mode)) -+ err = au_cpup_single(cpg, dst_parent); -+ else { -+ struct au_cpup_single_args args = { -+ .errp = &err, -+ .cpg = cpg, -+ .dst_parent = dst_parent -+ }; -+ wkq_err = au_wkq_wait(au_call_cpup_single, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ return err; -+} -+#endif -+ -+/* -+ * copyup the @dentry from the first active lower branch to @bdst, -+ * using au_cpup_single(). -+ */ -+static int au_cpup_simple(struct au_cp_generic *cpg) -+{ -+ int err; -+ unsigned int flags_orig; -+ struct dentry *dentry; -+ -+ AuDebugOn(cpg->bsrc < 0); -+ -+ dentry = cpg->dentry; -+ DiMustWriteLock(dentry); -+ -+ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1); -+ if (!err) { -+ flags_orig = cpg->flags; -+ au_fset_cpup(cpg->flags, RENAME); -+ err = au_cpup_single(cpg, NULL); -+ cpg->flags = flags_orig; -+ if (!err) -+ return 0; /* success */ -+ -+ /* revert */ -+ au_set_h_dptr(dentry, cpg->bdst, NULL); -+ au_set_dbtop(dentry, cpg->bsrc); -+ } -+ -+ return err; -+} -+ -+struct au_cpup_simple_args { -+ int *errp; -+ struct au_cp_generic *cpg; -+}; -+ -+static void au_call_cpup_simple(void *args) -+{ -+ struct au_cpup_simple_args *a = args; -+ -+ au_pin_hdir_acquire_nest(a->cpg->pin); -+ *a->errp = au_cpup_simple(a->cpg); -+ au_pin_hdir_release(a->cpg->pin); -+} -+ -+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg) -+{ -+ int err, wkq_err; -+ struct dentry *dentry, *parent; -+ struct file *h_file; -+ struct inode *h_dir; -+ -+ dentry = cpg->dentry; -+ h_file = NULL; -+ if (au_ftest_cpup(cpg->flags, HOPEN)) { -+ AuDebugOn(cpg->bsrc < 0); -+ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ } -+ -+ parent = dget_parent(dentry); -+ h_dir = au_h_iptr(d_inode(parent), cpg->bdst); -+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE) -+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode)) -+ err = au_cpup_simple(cpg); -+ else { -+ struct au_cpup_simple_args args = { -+ .errp = &err, -+ .cpg = cpg -+ }; -+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ dput(parent); -+ if (h_file) -+ au_h_open_post(dentry, cpg->bsrc, h_file); -+ -+out: -+ return err; -+} -+ -+int au_sio_cpup_simple(struct au_cp_generic *cpg) -+{ -+ aufs_bindex_t bsrc, bbot; -+ struct dentry *dentry, *h_dentry; -+ -+ if (cpg->bsrc < 0) { -+ dentry = cpg->dentry; -+ bbot = au_dbbot(dentry); -+ for (bsrc = cpg->bdst + 1; bsrc <= bbot; bsrc++) { -+ h_dentry = au_h_dptr(dentry, bsrc); -+ if (h_dentry) { -+ AuDebugOn(d_is_negative(h_dentry)); -+ break; -+ } -+ } -+ AuDebugOn(bsrc > bbot); -+ cpg->bsrc = bsrc; -+ } -+ AuDebugOn(cpg->bsrc <= cpg->bdst); -+ return au_do_sio_cpup_simple(cpg); -+} -+ -+int au_sio_cpdown_simple(struct au_cp_generic *cpg) -+{ -+ AuDebugOn(cpg->bdst <= cpg->bsrc); -+ return au_do_sio_cpup_simple(cpg); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * copyup the deleted file for writing. -+ */ -+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry, -+ struct file *file) -+{ -+ int err; -+ unsigned int flags_orig; -+ aufs_bindex_t bsrc_orig; -+ struct au_dinfo *dinfo; -+ struct { -+ struct au_hdentry *hd; -+ struct dentry *h_dentry; -+ } hdst, hsrc; -+ -+ dinfo = au_di(cpg->dentry); -+ AuRwMustWriteLock(&dinfo->di_rwsem); -+ -+ bsrc_orig = cpg->bsrc; -+ cpg->bsrc = dinfo->di_btop; -+ hdst.hd = au_hdentry(dinfo, cpg->bdst); -+ hdst.h_dentry = hdst.hd->hd_dentry; -+ hdst.hd->hd_dentry = wh_dentry; -+ dinfo->di_btop = cpg->bdst; -+ -+ hsrc.h_dentry = NULL; -+ if (file) { -+ hsrc.hd = au_hdentry(dinfo, cpg->bsrc); -+ hsrc.h_dentry = hsrc.hd->hd_dentry; -+ hsrc.hd->hd_dentry = au_hf_top(file)->f_path.dentry; -+ } -+ flags_orig = cpg->flags; -+ cpg->flags = !AuCpup_DTIME; -+ err = au_cpup_single(cpg, /*h_parent*/NULL); -+ cpg->flags = flags_orig; -+ if (file) { -+ if (!err) -+ err = au_reopen_nondir(file); -+ hsrc.hd->hd_dentry = hsrc.h_dentry; -+ } -+ hdst.hd->hd_dentry = hdst.h_dentry; -+ dinfo->di_btop = cpg->bsrc; -+ cpg->bsrc = bsrc_orig; -+ -+ return err; -+} -+ -+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file) -+{ -+ int err; -+ aufs_bindex_t bdst; -+ struct au_dtime dt; -+ struct dentry *dentry, *parent, *h_parent, *wh_dentry; -+ struct au_branch *br; -+ struct path h_path; -+ -+ dentry = cpg->dentry; -+ bdst = cpg->bdst; -+ br = au_sbr(dentry->d_sb, bdst); -+ parent = dget_parent(dentry); -+ h_parent = au_h_dptr(parent, bdst); -+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out; -+ -+ h_path.dentry = h_parent; -+ h_path.mnt = au_br_mnt(br); -+ au_dtime_store(&dt, parent, &h_path); -+ err = au_do_cpup_wh(cpg, wh_dentry, file); -+ if (unlikely(err)) -+ goto out_wh; -+ -+ dget(wh_dentry); -+ h_path.dentry = wh_dentry; -+ if (!d_is_dir(wh_dentry)) { -+ /* no delegation since it is just created */ -+ err = vfsub_unlink(d_inode(h_parent), &h_path, -+ /*delegated*/NULL, /*force*/0); -+ } else -+ err = vfsub_rmdir(d_inode(h_parent), &h_path); -+ if (unlikely(err)) { -+ AuIOErr("failed remove copied-up tmp file %pd(%d)\n", -+ wh_dentry, err); -+ err = -EIO; -+ } -+ au_dtime_revert(&dt); -+ au_set_hi_wh(d_inode(dentry), bdst, wh_dentry); -+ -+out_wh: -+ dput(wh_dentry); -+out: -+ dput(parent); -+ return err; -+} -+ -+struct au_cpup_wh_args { -+ int *errp; -+ struct au_cp_generic *cpg; -+ struct file *file; -+}; -+ -+static void au_call_cpup_wh(void *args) -+{ -+ struct au_cpup_wh_args *a = args; -+ -+ au_pin_hdir_acquire_nest(a->cpg->pin); -+ *a->errp = au_cpup_wh(a->cpg, a->file); -+ au_pin_hdir_release(a->cpg->pin); -+} -+ -+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file) -+{ -+ int err, wkq_err; -+ aufs_bindex_t bdst; -+ struct dentry *dentry, *parent, *h_orph, *h_parent; -+ struct inode *dir, *h_dir, *h_tmpdir; -+ struct au_wbr *wbr; -+ struct au_pin wh_pin, *pin_orig; -+ -+ dentry = cpg->dentry; -+ bdst = cpg->bdst; -+ parent = dget_parent(dentry); -+ dir = d_inode(parent); -+ h_orph = NULL; -+ h_parent = NULL; -+ h_dir = au_igrab(au_h_iptr(dir, bdst)); -+ h_tmpdir = h_dir; -+ pin_orig = NULL; -+ if (!h_dir->i_nlink) { -+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr; -+ h_orph = wbr->wbr_orph; -+ -+ h_parent = dget(au_h_dptr(parent, bdst)); -+ au_set_h_dptr(parent, bdst, dget(h_orph)); -+ h_tmpdir = d_inode(h_orph); -+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0); -+ -+ inode_lock_nested(h_tmpdir, AuLsc_I_PARENT3); -+ /* todo: au_h_open_pre()? */ -+ -+ pin_orig = cpg->pin; -+ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT, -+ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED); -+ cpg->pin = &wh_pin; -+ } -+ -+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE) -+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode)) -+ err = au_cpup_wh(cpg, file); -+ else { -+ struct au_cpup_wh_args args = { -+ .errp = &err, -+ .cpg = cpg, -+ .file = file -+ }; -+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ if (h_orph) { -+ inode_unlock(h_tmpdir); -+ /* todo: au_h_open_post()? */ -+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0); -+ au_set_h_dptr(parent, bdst, h_parent); -+ AuDebugOn(!pin_orig); -+ cpg->pin = pin_orig; -+ } -+ iput(h_dir); -+ dput(parent); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * generic routine for both of copy-up and copy-down. -+ */ -+/* cf. revalidate function in file.c */ -+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, -+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, -+ struct au_pin *pin, -+ struct dentry *h_parent, void *arg), -+ void *arg) -+{ -+ int err; -+ struct au_pin pin; -+ struct dentry *d, *parent, *h_parent, *real_parent, *h_dentry; -+ -+ err = 0; -+ parent = dget_parent(dentry); -+ if (IS_ROOT(parent)) -+ goto out; -+ -+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2, -+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE); -+ -+ /* do not use au_dpage */ -+ real_parent = parent; -+ while (1) { -+ dput(parent); -+ parent = dget_parent(dentry); -+ h_parent = au_h_dptr(parent, bdst); -+ if (h_parent) -+ goto out; /* success */ -+ -+ /* find top dir which is necessary to cpup */ -+ do { -+ d = parent; -+ dput(parent); -+ parent = dget_parent(d); -+ di_read_lock_parent3(parent, !AuLock_IR); -+ h_parent = au_h_dptr(parent, bdst); -+ di_read_unlock(parent, !AuLock_IR); -+ } while (!h_parent); -+ -+ if (d != real_parent) -+ di_write_lock_child3(d); -+ -+ /* somebody else might create while we were sleeping */ -+ h_dentry = au_h_dptr(d, bdst); -+ if (!h_dentry || d_is_negative(h_dentry)) { -+ if (h_dentry) -+ au_update_dbtop(d); -+ -+ au_pin_set_dentry(&pin, d); -+ err = au_do_pin(&pin); -+ if (!err) { -+ err = cp(d, bdst, &pin, h_parent, arg); -+ au_unpin(&pin); -+ } -+ } -+ -+ if (d != real_parent) -+ di_write_unlock(d); -+ if (unlikely(err)) -+ break; -+ } -+ -+out: -+ dput(parent); -+ return err; -+} -+ -+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst, -+ struct au_pin *pin, -+ struct dentry *h_parent __maybe_unused, -+ void *arg __maybe_unused) -+{ -+ struct au_cp_generic cpg = { -+ .dentry = dentry, -+ .bdst = bdst, -+ .bsrc = -1, -+ .len = 0, -+ .pin = pin, -+ .flags = AuCpup_DTIME -+ }; -+ return au_sio_cpup_simple(&cpg); -+} -+ -+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) -+{ -+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL); -+} -+ -+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) -+{ -+ int err; -+ struct dentry *parent; -+ struct inode *dir; -+ -+ parent = dget_parent(dentry); -+ dir = d_inode(parent); -+ err = 0; -+ if (au_h_iptr(dir, bdst)) -+ goto out; -+ -+ di_read_unlock(parent, AuLock_IR); -+ di_write_lock_parent(parent); -+ /* someone else might change our inode while we were sleeping */ -+ if (!au_h_iptr(dir, bdst)) -+ err = au_cpup_dirs(dentry, bdst); -+ di_downgrade_lock(parent, AuLock_IR); -+ -+out: -+ dput(parent); -+ return err; -+} -diff --git a/fs/aufs/cpup.h b/fs/aufs/cpup.h -new file mode 100644 -index 000000000..0faad688b ---- /dev/null -+++ b/fs/aufs/cpup.h -@@ -0,0 +1,100 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * copy-up/down functions -+ */ -+ -+#ifndef __AUFS_CPUP_H__ -+#define __AUFS_CPUP_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+struct inode; -+struct file; -+struct au_pin; -+ -+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags); -+void au_cpup_attr_timesizes(struct inode *inode); -+void au_cpup_attr_nlink(struct inode *inode, int force); -+void au_cpup_attr_changeable(struct inode *inode); -+void au_cpup_igen(struct inode *inode, struct inode *h_inode); -+void au_cpup_attr_all(struct inode *inode, int force); -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_cp_generic { -+ struct dentry *dentry; -+ aufs_bindex_t bdst, bsrc; -+ loff_t len; -+ struct au_pin *pin; -+ unsigned int flags; -+}; -+ -+/* cpup flags */ -+#define AuCpup_DTIME 1 /* do dtime_store/revert */ -+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino, -+ for link(2) */ -+#define AuCpup_RENAME (1 << 2) /* rename after cpup */ -+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in -+ cpup */ -+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the -+ existing entry */ -+#define AuCpup_RWDST (1 << 5) /* force write target even if -+ the branch is marked as RO */ -+ -+#ifndef CONFIG_AUFS_BR_HFSPLUS -+#undef AuCpup_HOPEN -+#define AuCpup_HOPEN 0 -+#endif -+ -+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name) -+#define au_fset_cpup(flags, name) \ -+ do { (flags) |= AuCpup_##name; } while (0) -+#define au_fclr_cpup(flags, name) \ -+ do { (flags) &= ~AuCpup_##name; } while (0) -+ -+int au_copy_file(struct file *dst, struct file *src, loff_t len); -+int au_sio_cpup_simple(struct au_cp_generic *cpg); -+int au_sio_cpdown_simple(struct au_cp_generic *cpg); -+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file); -+ -+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, -+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, -+ struct au_pin *pin, -+ struct dentry *h_parent, void *arg), -+ void *arg); -+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); -+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* keep timestamps when copyup */ -+struct au_dtime { -+ struct dentry *dt_dentry; -+ struct path dt_h_path; -+ struct timespec64 dt_atime, dt_mtime; -+}; -+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, -+ struct path *h_path); -+void au_dtime_revert(struct au_dtime *dt); -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_CPUP_H__ */ -diff --git a/fs/aufs/dbgaufs.c b/fs/aufs/dbgaufs.c -new file mode 100644 -index 000000000..13872925a ---- /dev/null -+++ b/fs/aufs/dbgaufs.c -@@ -0,0 +1,519 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * debugfs interface -+ */ -+ -+#include -+#include "aufs.h" -+ -+#ifndef CONFIG_SYSFS -+#error DEBUG_FS depends upon SYSFS -+#endif -+ -+static struct dentry *dbgaufs; -+static const mode_t dbgaufs_mode = 0444; -+ -+/* 20 is max digits length of ulong 64 */ -+struct dbgaufs_arg { -+ int n; -+ char a[20 * 4]; -+}; -+ -+/* -+ * common function for all XINO files -+ */ -+static int dbgaufs_xi_release(struct inode *inode __maybe_unused, -+ struct file *file) -+{ -+ kfree(file->private_data); -+ return 0; -+} -+ -+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt, -+ int cnt) -+{ -+ int err; -+ struct kstat st; -+ struct dbgaufs_arg *p; -+ -+ err = -ENOMEM; -+ p = kmalloc(sizeof(*p), GFP_NOFS); -+ if (unlikely(!p)) -+ goto out; -+ -+ err = 0; -+ p->n = 0; -+ file->private_data = p; -+ if (!xf) -+ goto out; -+ -+ err = vfsub_getattr(&xf->f_path, &st); -+ if (!err) { -+ if (do_fcnt) -+ p->n = snprintf -+ (p->a, sizeof(p->a), "%d, %llux%u %lld\n", -+ cnt, st.blocks, st.blksize, -+ (long long)st.size); -+ else -+ p->n = snprintf(p->a, sizeof(p->a), "%llux%u %lld\n", -+ st.blocks, st.blksize, -+ (long long)st.size); -+ AuDebugOn(p->n >= sizeof(p->a)); -+ } else { -+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err); -+ err = 0; -+ } -+ -+out: -+ return err; -+} -+ -+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ struct dbgaufs_arg *p; -+ -+ p = file->private_data; -+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct dbgaufs_plink_arg { -+ int n; -+ char a[]; -+}; -+ -+static int dbgaufs_plink_release(struct inode *inode __maybe_unused, -+ struct file *file) -+{ -+ free_page((unsigned long)file->private_data); -+ return 0; -+} -+ -+static int dbgaufs_plink_open(struct inode *inode, struct file *file) -+{ -+ int err, i, limit; -+ unsigned long n, sum; -+ struct dbgaufs_plink_arg *p; -+ struct au_sbinfo *sbinfo; -+ struct super_block *sb; -+ struct hlist_bl_head *hbl; -+ -+ err = -ENOMEM; -+ p = (void *)get_zeroed_page(GFP_NOFS); -+ if (unlikely(!p)) -+ goto out; -+ -+ err = -EFBIG; -+ sbinfo = inode->i_private; -+ sb = sbinfo->si_sb; -+ si_noflush_read_lock(sb); -+ if (au_opt_test(au_mntflags(sb), PLINK)) { -+ limit = PAGE_SIZE - sizeof(p->n); -+ -+ /* the number of buckets */ -+ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH); -+ p->n += n; -+ limit -= n; -+ -+ sum = 0; -+ for (i = 0, hbl = sbinfo->si_plink; i < AuPlink_NHASH; -+ i++, hbl++) { -+ n = au_hbl_count(hbl); -+ sum += n; -+ -+ n = snprintf(p->a + p->n, limit, "%lu ", n); -+ p->n += n; -+ limit -= n; -+ if (unlikely(limit <= 0)) -+ goto out_free; -+ } -+ p->a[p->n - 1] = '\n'; -+ -+ /* the sum of plinks */ -+ n = snprintf(p->a + p->n, limit, "%lu\n", sum); -+ p->n += n; -+ limit -= n; -+ if (unlikely(limit <= 0)) -+ goto out_free; -+ } else { -+#define str "1\n0\n0\n" -+ p->n = sizeof(str) - 1; -+ strcpy(p->a, str); -+#undef str -+ } -+ si_read_unlock(sb); -+ -+ err = 0; -+ file->private_data = p; -+ goto out; /* success */ -+ -+out_free: -+ free_page((unsigned long)p); -+out: -+ return err; -+} -+ -+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ struct dbgaufs_plink_arg *p; -+ -+ p = file->private_data; -+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n); -+} -+ -+static const struct file_operations dbgaufs_plink_fop = { -+ .owner = THIS_MODULE, -+ .open = dbgaufs_plink_open, -+ .release = dbgaufs_plink_release, -+ .read = dbgaufs_plink_read -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int dbgaufs_xib_open(struct inode *inode, struct file *file) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ struct super_block *sb; -+ -+ sbinfo = inode->i_private; -+ sb = sbinfo->si_sb; -+ si_noflush_read_lock(sb); -+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0, /*cnt*/0); -+ si_read_unlock(sb); -+ return err; -+} -+ -+static const struct file_operations dbgaufs_xib_fop = { -+ .owner = THIS_MODULE, -+ .open = dbgaufs_xib_open, -+ .release = dbgaufs_xi_release, -+ .read = dbgaufs_xi_read -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define DbgaufsXi_PREFIX "xi" -+ -+static int dbgaufs_xino_open(struct inode *inode, struct file *file) -+{ -+ int err, idx; -+ long l; -+ aufs_bindex_t bindex; -+ char *p, a[sizeof(DbgaufsXi_PREFIX) + 8]; -+ struct au_sbinfo *sbinfo; -+ struct super_block *sb; -+ struct au_xino *xi; -+ struct file *xf; -+ struct qstr *name; -+ struct au_branch *br; -+ -+ err = -ENOENT; -+ name = &file->f_path.dentry->d_name; -+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX) -+ || memcmp(name->name, DbgaufsXi_PREFIX, -+ sizeof(DbgaufsXi_PREFIX) - 1))) -+ goto out; -+ -+ AuDebugOn(name->len >= sizeof(a)); -+ memcpy(a, name->name, name->len); -+ a[name->len] = '\0'; -+ p = strchr(a, '-'); -+ if (p) -+ *p = '\0'; -+ err = kstrtol(a + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l); -+ if (unlikely(err)) -+ goto out; -+ bindex = l; -+ idx = 0; -+ if (p) { -+ err = kstrtol(p + 1, 10, &l); -+ if (unlikely(err)) -+ goto out; -+ idx = l; -+ } -+ -+ err = -ENOENT; -+ sbinfo = inode->i_private; -+ sb = sbinfo->si_sb; -+ si_noflush_read_lock(sb); -+ if (unlikely(bindex < 0 || bindex > au_sbbot(sb))) -+ goto out_si; -+ br = au_sbr(sb, bindex); -+ xi = br->br_xino; -+ if (unlikely(idx >= xi->xi_nfile)) -+ goto out_si; -+ xf = au_xino_file(xi, idx); -+ if (xf) -+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1, -+ au_xino_count(br)); -+ -+out_si: -+ si_read_unlock(sb); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static const struct file_operations dbgaufs_xino_fop = { -+ .owner = THIS_MODULE, -+ .open = dbgaufs_xino_open, -+ .release = dbgaufs_xi_release, -+ .read = dbgaufs_xi_read -+}; -+ -+void dbgaufs_xino_del(struct au_branch *br) -+{ -+ struct dentry *dbgaufs; -+ -+ dbgaufs = br->br_dbgaufs; -+ if (!dbgaufs) -+ return; -+ -+ br->br_dbgaufs = NULL; -+ /* debugfs acquires the parent i_mutex */ -+ lockdep_off(); -+ debugfs_remove(dbgaufs); -+ lockdep_on(); -+} -+ -+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ aufs_bindex_t bbot; -+ struct au_branch *br; -+ -+ if (!au_sbi(sb)->si_dbgaufs) -+ return; -+ -+ bbot = au_sbbot(sb); -+ for (; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ dbgaufs_xino_del(br); -+ } -+} -+ -+static void dbgaufs_br_do_add(struct super_block *sb, aufs_bindex_t bindex, -+ unsigned int idx, struct dentry *parent, -+ struct au_sbinfo *sbinfo) -+{ -+ struct au_branch *br; -+ struct dentry *d; -+ /* "xi" bindex(5) "-" idx(2) NULL */ -+ char name[sizeof(DbgaufsXi_PREFIX) + 8]; -+ -+ if (!idx) -+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex); -+ else -+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d-%u", -+ bindex, idx); -+ br = au_sbr(sb, bindex); -+ if (br->br_dbgaufs) { -+ struct qstr qstr = QSTR_INIT(name, strlen(name)); -+ -+ if (!au_qstreq(&br->br_dbgaufs->d_name, &qstr)) { -+ /* debugfs acquires the parent i_mutex */ -+ lockdep_off(); -+ d = debugfs_rename(parent, br->br_dbgaufs, parent, -+ name); -+ lockdep_on(); -+ if (unlikely(!d)) -+ pr_warn("failed renaming %pd/%s, ignored.\n", -+ parent, name); -+ } -+ } else { -+ lockdep_off(); -+ br->br_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent, -+ sbinfo, &dbgaufs_xino_fop); -+ lockdep_on(); -+ if (unlikely(!br->br_dbgaufs)) -+ pr_warn("failed creating %pd/%s, ignored.\n", -+ parent, name); -+ } -+} -+ -+static void dbgaufs_br_add(struct super_block *sb, aufs_bindex_t bindex, -+ struct dentry *parent, struct au_sbinfo *sbinfo) -+{ -+ struct au_branch *br; -+ struct au_xino *xi; -+ unsigned int u; -+ -+ br = au_sbr(sb, bindex); -+ xi = br->br_xino; -+ for (u = 0; u < xi->xi_nfile; u++) -+ dbgaufs_br_do_add(sb, bindex, u, parent, sbinfo); -+} -+ -+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex, int topdown) -+{ -+ struct au_sbinfo *sbinfo; -+ struct dentry *parent; -+ aufs_bindex_t bbot; -+ -+ if (!au_opt_test(au_mntflags(sb), XINO)) -+ return; -+ -+ sbinfo = au_sbi(sb); -+ parent = sbinfo->si_dbgaufs; -+ if (!parent) -+ return; -+ -+ bbot = au_sbbot(sb); -+ if (topdown) -+ for (; bindex <= bbot; bindex++) -+ dbgaufs_br_add(sb, bindex, parent, sbinfo); -+ else -+ for (; bbot >= bindex; bbot--) -+ dbgaufs_br_add(sb, bbot, parent, sbinfo); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_EXPORT -+static int dbgaufs_xigen_open(struct inode *inode, struct file *file) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ struct super_block *sb; -+ -+ sbinfo = inode->i_private; -+ sb = sbinfo->si_sb; -+ si_noflush_read_lock(sb); -+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0, /*cnt*/0); -+ si_read_unlock(sb); -+ return err; -+} -+ -+static const struct file_operations dbgaufs_xigen_fop = { -+ .owner = THIS_MODULE, -+ .open = dbgaufs_xigen_open, -+ .release = dbgaufs_xi_release, -+ .read = dbgaufs_xi_read -+}; -+ -+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo) -+{ -+ int err; -+ -+ /* -+ * This function is a dynamic '__init' function actually, -+ * so the tiny check for si_rwsem is unnecessary. -+ */ -+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ -+ -+ err = -EIO; -+ sbinfo->si_dbgaufs_xigen = debugfs_create_file -+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, -+ &dbgaufs_xigen_fop); -+ if (sbinfo->si_dbgaufs_xigen) -+ err = 0; -+ -+ return err; -+} -+#else -+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo) -+{ -+ return 0; -+} -+#endif /* CONFIG_AUFS_EXPORT */ -+ -+/* ---------------------------------------------------------------------- */ -+ -+void dbgaufs_si_fin(struct au_sbinfo *sbinfo) -+{ -+ /* -+ * This function is a dynamic '__fin' function actually, -+ * so the tiny check for si_rwsem is unnecessary. -+ */ -+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ -+ -+ debugfs_remove_recursive(sbinfo->si_dbgaufs); -+ sbinfo->si_dbgaufs = NULL; -+} -+ -+int dbgaufs_si_init(struct au_sbinfo *sbinfo) -+{ -+ int err; -+ char name[SysaufsSiNameLen]; -+ -+ /* -+ * This function is a dynamic '__init' function actually, -+ * so the tiny check for si_rwsem is unnecessary. -+ */ -+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ -+ -+ err = -ENOENT; -+ if (!dbgaufs) { -+ AuErr1("/debug/aufs is uninitialized\n"); -+ goto out; -+ } -+ -+ err = -EIO; -+ sysaufs_name(sbinfo, name); -+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs); -+ if (unlikely(!sbinfo->si_dbgaufs)) -+ goto out; -+ -+ /* regardless plink/noplink option */ -+ sbinfo->si_dbgaufs_plink = debugfs_create_file -+ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, -+ &dbgaufs_plink_fop); -+ if (unlikely(!sbinfo->si_dbgaufs_plink)) -+ goto out_dir; -+ -+ /* regardless xino/noxino option */ -+ sbinfo->si_dbgaufs_xib = debugfs_create_file -+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, -+ &dbgaufs_xib_fop); -+ if (unlikely(!sbinfo->si_dbgaufs_xib)) -+ goto out_dir; -+ -+ err = dbgaufs_xigen_init(sbinfo); -+ if (!err) -+ goto out; /* success */ -+ -+out_dir: -+ dbgaufs_si_fin(sbinfo); -+out: -+ if (unlikely(err)) -+ pr_err("debugfs/aufs failed\n"); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void dbgaufs_fin(void) -+{ -+ debugfs_remove(dbgaufs); -+} -+ -+int __init dbgaufs_init(void) -+{ -+ int err; -+ -+ err = -EIO; -+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL); -+ if (dbgaufs) -+ err = 0; -+ return err; -+} -diff --git a/fs/aufs/dbgaufs.h b/fs/aufs/dbgaufs.h -new file mode 100644 -index 000000000..59d7b9d08 ---- /dev/null -+++ b/fs/aufs/dbgaufs.h -@@ -0,0 +1,53 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * debugfs interface -+ */ -+ -+#ifndef __DBGAUFS_H__ -+#define __DBGAUFS_H__ -+ -+#ifdef __KERNEL__ -+ -+struct super_block; -+struct au_sbinfo; -+struct au_branch; -+ -+#ifdef CONFIG_DEBUG_FS -+/* dbgaufs.c */ -+void dbgaufs_xino_del(struct au_branch *br); -+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex); -+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex, int topdown); -+void dbgaufs_si_fin(struct au_sbinfo *sbinfo); -+int dbgaufs_si_init(struct au_sbinfo *sbinfo); -+void dbgaufs_fin(void); -+int __init dbgaufs_init(void); -+#else -+AuStubVoid(dbgaufs_xino_del, struct au_branch *br) -+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex) -+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex, -+ int topdown) -+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo) -+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo) -+AuStubVoid(dbgaufs_fin, void) -+AuStubInt0(__init dbgaufs_init, void) -+#endif /* CONFIG_DEBUG_FS */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __DBGAUFS_H__ */ -diff --git a/fs/aufs/dcsub.c b/fs/aufs/dcsub.c -new file mode 100644 -index 000000000..b30828810 ---- /dev/null -+++ b/fs/aufs/dcsub.c -@@ -0,0 +1,225 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * sub-routines for dentry cache -+ */ -+ -+#include "aufs.h" -+ -+static void au_dpage_free(struct au_dpage *dpage) -+{ -+ int i; -+ struct dentry **p; -+ -+ p = dpage->dentries; -+ for (i = 0; i < dpage->ndentry; i++) -+ dput(*p++); -+ free_page((unsigned long)dpage->dentries); -+} -+ -+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp) -+{ -+ int err; -+ void *p; -+ -+ err = -ENOMEM; -+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp); -+ if (unlikely(!dpages->dpages)) -+ goto out; -+ -+ p = (void *)__get_free_page(gfp); -+ if (unlikely(!p)) -+ goto out_dpages; -+ -+ dpages->dpages[0].ndentry = 0; -+ dpages->dpages[0].dentries = p; -+ dpages->ndpage = 1; -+ return 0; /* success */ -+ -+out_dpages: -+ kfree(dpages->dpages); -+out: -+ return err; -+} -+ -+void au_dpages_free(struct au_dcsub_pages *dpages) -+{ -+ int i; -+ struct au_dpage *p; -+ -+ p = dpages->dpages; -+ for (i = 0; i < dpages->ndpage; i++) -+ au_dpage_free(p++); -+ kfree(dpages->dpages); -+} -+ -+static int au_dpages_append(struct au_dcsub_pages *dpages, -+ struct dentry *dentry, gfp_t gfp) -+{ -+ int err, sz; -+ struct au_dpage *dpage; -+ void *p; -+ -+ dpage = dpages->dpages + dpages->ndpage - 1; -+ sz = PAGE_SIZE / sizeof(dentry); -+ if (unlikely(dpage->ndentry >= sz)) { -+ AuLabel(new dpage); -+ err = -ENOMEM; -+ sz = dpages->ndpage * sizeof(*dpages->dpages); -+ p = au_kzrealloc(dpages->dpages, sz, -+ sz + sizeof(*dpages->dpages), gfp, -+ /*may_shrink*/0); -+ if (unlikely(!p)) -+ goto out; -+ -+ dpages->dpages = p; -+ dpage = dpages->dpages + dpages->ndpage; -+ p = (void *)__get_free_page(gfp); -+ if (unlikely(!p)) -+ goto out; -+ -+ dpage->ndentry = 0; -+ dpage->dentries = p; -+ dpages->ndpage++; -+ } -+ -+ AuDebugOn(au_dcount(dentry) <= 0); -+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry); -+ return 0; /* success */ -+ -+out: -+ return err; -+} -+ -+/* todo: BAD approach */ -+/* copied from linux/fs/dcache.c */ -+enum d_walk_ret { -+ D_WALK_CONTINUE, -+ D_WALK_QUIT, -+ D_WALK_NORETRY, -+ D_WALK_SKIP, -+}; -+ -+extern void d_walk(struct dentry *parent, void *data, -+ enum d_walk_ret (*enter)(void *, struct dentry *)); -+ -+struct ac_dpages_arg { -+ int err; -+ struct au_dcsub_pages *dpages; -+ struct super_block *sb; -+ au_dpages_test test; -+ void *arg; -+}; -+ -+static enum d_walk_ret au_call_dpages_append(void *_arg, struct dentry *dentry) -+{ -+ enum d_walk_ret ret; -+ struct ac_dpages_arg *arg = _arg; -+ -+ ret = D_WALK_CONTINUE; -+ if (dentry->d_sb == arg->sb -+ && !IS_ROOT(dentry) -+ && au_dcount(dentry) > 0 -+ && au_di(dentry) -+ && (!arg->test || arg->test(dentry, arg->arg))) { -+ arg->err = au_dpages_append(arg->dpages, dentry, GFP_ATOMIC); -+ if (unlikely(arg->err)) -+ ret = D_WALK_QUIT; -+ } -+ -+ return ret; -+} -+ -+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, -+ au_dpages_test test, void *arg) -+{ -+ struct ac_dpages_arg args = { -+ .err = 0, -+ .dpages = dpages, -+ .sb = root->d_sb, -+ .test = test, -+ .arg = arg -+ }; -+ -+ d_walk(root, &args, au_call_dpages_append); -+ -+ return args.err; -+} -+ -+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, -+ int do_include, au_dpages_test test, void *arg) -+{ -+ int err; -+ -+ err = 0; -+ write_seqlock(&rename_lock); -+ spin_lock(&dentry->d_lock); -+ if (do_include -+ && au_dcount(dentry) > 0 -+ && (!test || test(dentry, arg))) -+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); -+ spin_unlock(&dentry->d_lock); -+ if (unlikely(err)) -+ goto out; -+ -+ /* -+ * RCU for vfsmount is unnecessary since this is a traverse in a single -+ * mount -+ */ -+ while (!IS_ROOT(dentry)) { -+ dentry = dentry->d_parent; /* rename_lock is locked */ -+ spin_lock(&dentry->d_lock); -+ if (au_dcount(dentry) > 0 -+ && (!test || test(dentry, arg))) -+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); -+ spin_unlock(&dentry->d_lock); -+ if (unlikely(err)) -+ break; -+ } -+ -+out: -+ write_sequnlock(&rename_lock); -+ return err; -+} -+ -+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg) -+{ -+ return au_di(dentry) && dentry->d_sb == arg; -+} -+ -+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages, -+ struct dentry *dentry, int do_include) -+{ -+ return au_dcsub_pages_rev(dpages, dentry, do_include, -+ au_dcsub_dpages_aufs, dentry->d_sb); -+} -+ -+int au_test_subdir(struct dentry *d1, struct dentry *d2) -+{ -+ struct path path[2] = { -+ { -+ .dentry = d1 -+ }, -+ { -+ .dentry = d2 -+ } -+ }; -+ -+ return path_is_under(path + 0, path + 1); -+} -diff --git a/fs/aufs/dcsub.h b/fs/aufs/dcsub.h -new file mode 100644 -index 000000000..c610133de ---- /dev/null -+++ b/fs/aufs/dcsub.h -@@ -0,0 +1,137 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * sub-routines for dentry cache -+ */ -+ -+#ifndef __AUFS_DCSUB_H__ -+#define __AUFS_DCSUB_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+ -+struct au_dpage { -+ int ndentry; -+ struct dentry **dentries; -+}; -+ -+struct au_dcsub_pages { -+ int ndpage; -+ struct au_dpage *dpages; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* dcsub.c */ -+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp); -+void au_dpages_free(struct au_dcsub_pages *dpages); -+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg); -+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, -+ au_dpages_test test, void *arg); -+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, -+ int do_include, au_dpages_test test, void *arg); -+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages, -+ struct dentry *dentry, int do_include); -+int au_test_subdir(struct dentry *d1, struct dentry *d2); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * todo: in linux-3.13, several similar (but faster) helpers are added to -+ * include/linux/dcache.h. Try them (in the future). -+ */ -+ -+static inline int au_d_hashed_positive(struct dentry *d) -+{ -+ int err; -+ struct inode *inode = d_inode(d); -+ -+ err = 0; -+ if (unlikely(d_unhashed(d) -+ || d_is_negative(d) -+ || !inode->i_nlink)) -+ err = -ENOENT; -+ return err; -+} -+ -+static inline int au_d_linkable(struct dentry *d) -+{ -+ int err; -+ struct inode *inode = d_inode(d); -+ -+ err = au_d_hashed_positive(d); -+ if (err -+ && d_is_positive(d) -+ && (inode->i_state & I_LINKABLE)) -+ err = 0; -+ return err; -+} -+ -+static inline int au_d_alive(struct dentry *d) -+{ -+ int err; -+ struct inode *inode; -+ -+ err = 0; -+ if (!IS_ROOT(d)) -+ err = au_d_hashed_positive(d); -+ else { -+ inode = d_inode(d); -+ if (unlikely(d_unlinked(d) -+ || d_is_negative(d) -+ || !inode->i_nlink)) -+ err = -ENOENT; -+ } -+ return err; -+} -+ -+static inline int au_alive_dir(struct dentry *d) -+{ -+ int err; -+ -+ err = au_d_alive(d); -+ if (unlikely(err || IS_DEADDIR(d_inode(d)))) -+ err = -ENOENT; -+ return err; -+} -+ -+static inline int au_qstreq(struct qstr *a, struct qstr *b) -+{ -+ return a->len == b->len -+ && !memcmp(a->name, b->name, a->len); -+} -+ -+/* -+ * by the commit -+ * 360f547 2015-01-25 dcache: let the dentry count go down to zero without -+ * taking d_lock -+ * the type of d_lockref.count became int, but the inlined function d_count() -+ * still returns unsigned int. -+ * I don't know why. Maybe it is for every d_count() users? -+ * Anyway au_dcount() lives on. -+ */ -+static inline int au_dcount(struct dentry *d) -+{ -+ return (int)d_count(d); -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DCSUB_H__ */ -diff --git a/fs/aufs/debug.c b/fs/aufs/debug.c -new file mode 100644 -index 000000000..51b978b0e ---- /dev/null -+++ b/fs/aufs/debug.c -@@ -0,0 +1,440 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * debug print functions -+ */ -+ -+#include "aufs.h" -+ -+/* Returns 0, or -errno. arg is in kp->arg. */ -+static int param_atomic_t_set(const char *val, const struct kernel_param *kp) -+{ -+ int err, n; -+ -+ err = kstrtoint(val, 0, &n); -+ if (!err) { -+ if (n > 0) -+ au_debug_on(); -+ else -+ au_debug_off(); -+ } -+ return err; -+} -+ -+/* Returns length written or -errno. Buffer is 4k (ie. be short!) */ -+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp) -+{ -+ atomic_t *a; -+ -+ a = kp->arg; -+ return sprintf(buffer, "%d", atomic_read(a)); -+} -+ -+static struct kernel_param_ops param_ops_atomic_t = { -+ .set = param_atomic_t_set, -+ .get = param_atomic_t_get -+ /* void (*free)(void *arg) */ -+}; -+ -+atomic_t aufs_debug = ATOMIC_INIT(0); -+MODULE_PARM_DESC(debug, "debug print"); -+module_param_named(debug, aufs_debug, atomic_t, 0664); -+ -+DEFINE_MUTEX(au_dbg_mtx); /* just to serialize the dbg msgs */ -+char *au_plevel = KERN_DEBUG; -+#define dpri(fmt, ...) do { \ -+ if ((au_plevel \ -+ && strcmp(au_plevel, KERN_DEBUG)) \ -+ || au_debug_test()) \ -+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \ -+} while (0) -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_dpri_whlist(struct au_nhash *whlist) -+{ -+ unsigned long ul, n; -+ struct hlist_head *head; -+ struct au_vdir_wh *pos; -+ -+ n = whlist->nh_num; -+ head = whlist->nh_head; -+ for (ul = 0; ul < n; ul++) { -+ hlist_for_each_entry(pos, head, wh_hash) -+ dpri("b%d, %.*s, %d\n", -+ pos->wh_bindex, -+ pos->wh_str.len, pos->wh_str.name, -+ pos->wh_str.len); -+ head++; -+ } -+} -+ -+void au_dpri_vdir(struct au_vdir *vdir) -+{ -+ unsigned long ul; -+ union au_vdir_deblk_p p; -+ unsigned char *o; -+ -+ if (!vdir || IS_ERR(vdir)) { -+ dpri("err %ld\n", PTR_ERR(vdir)); -+ return; -+ } -+ -+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %llu\n", -+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk, -+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version); -+ for (ul = 0; ul < vdir->vd_nblk; ul++) { -+ p.deblk = vdir->vd_deblk[ul]; -+ o = p.deblk; -+ dpri("[%lu]: %p\n", ul, o); -+ } -+} -+ -+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn, -+ struct dentry *wh) -+{ -+ char *n = NULL; -+ int l = 0; -+ -+ if (!inode || IS_ERR(inode)) { -+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode)); -+ return -1; -+ } -+ -+ /* the type of i_blocks depends upon CONFIG_LBDAF */ -+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long) -+ && sizeof(inode->i_blocks) != sizeof(u64)); -+ if (wh) { -+ n = (void *)wh->d_name.name; -+ l = wh->d_name.len; -+ } -+ -+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu," -+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n", -+ bindex, inode, -+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??", -+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode, -+ i_size_read(inode), (unsigned long long)inode->i_blocks, -+ hn, (long long)timespec64_to_ns(&inode->i_ctime) & 0x0ffff, -+ inode->i_mapping ? inode->i_mapping->nrpages : 0, -+ inode->i_state, inode->i_flags, inode_peek_iversion(inode), -+ inode->i_generation, -+ l ? ", wh " : "", l, n); -+ return 0; -+} -+ -+void au_dpri_inode(struct inode *inode) -+{ -+ struct au_iinfo *iinfo; -+ struct au_hinode *hi; -+ aufs_bindex_t bindex; -+ int err, hn; -+ -+ err = do_pri_inode(-1, inode, -1, NULL); -+ if (err || !au_test_aufs(inode->i_sb) || au_is_bad_inode(inode)) -+ return; -+ -+ iinfo = au_ii(inode); -+ dpri("i-1: btop %d, bbot %d, gen %d\n", -+ iinfo->ii_btop, iinfo->ii_bbot, au_iigen(inode, NULL)); -+ if (iinfo->ii_btop < 0) -+ return; -+ hn = 0; -+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot; bindex++) { -+ hi = au_hinode(iinfo, bindex); -+ hn = !!au_hn(hi); -+ do_pri_inode(bindex, hi->hi_inode, hn, hi->hi_whdentry); -+ } -+} -+ -+void au_dpri_dalias(struct inode *inode) -+{ -+ struct dentry *d; -+ -+ spin_lock(&inode->i_lock); -+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) -+ au_dpri_dentry(d); -+ spin_unlock(&inode->i_lock); -+} -+ -+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry) -+{ -+ struct dentry *wh = NULL; -+ int hn; -+ struct inode *inode; -+ struct au_iinfo *iinfo; -+ struct au_hinode *hi; -+ -+ if (!dentry || IS_ERR(dentry)) { -+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry)); -+ return -1; -+ } -+ /* do not call dget_parent() here */ -+ /* note: access d_xxx without d_lock */ -+ dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n", -+ bindex, dentry, dentry, -+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??", -+ au_dcount(dentry), dentry->d_flags, -+ d_unhashed(dentry) ? "un" : ""); -+ hn = -1; -+ inode = NULL; -+ if (d_is_positive(dentry)) -+ inode = d_inode(dentry); -+ if (inode -+ && au_test_aufs(dentry->d_sb) -+ && bindex >= 0 -+ && !au_is_bad_inode(inode)) { -+ iinfo = au_ii(inode); -+ hi = au_hinode(iinfo, bindex); -+ hn = !!au_hn(hi); -+ wh = hi->hi_whdentry; -+ } -+ do_pri_inode(bindex, inode, hn, wh); -+ return 0; -+} -+ -+void au_dpri_dentry(struct dentry *dentry) -+{ -+ struct au_dinfo *dinfo; -+ aufs_bindex_t bindex; -+ int err; -+ -+ err = do_pri_dentry(-1, dentry); -+ if (err || !au_test_aufs(dentry->d_sb)) -+ return; -+ -+ dinfo = au_di(dentry); -+ if (!dinfo) -+ return; -+ dpri("d-1: btop %d, bbot %d, bwh %d, bdiropq %d, gen %d, tmp %d\n", -+ dinfo->di_btop, dinfo->di_bbot, -+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry), -+ dinfo->di_tmpfile); -+ if (dinfo->di_btop < 0) -+ return; -+ for (bindex = dinfo->di_btop; bindex <= dinfo->di_bbot; bindex++) -+ do_pri_dentry(bindex, au_hdentry(dinfo, bindex)->hd_dentry); -+} -+ -+static int do_pri_file(aufs_bindex_t bindex, struct file *file) -+{ -+ char a[32]; -+ -+ if (!file || IS_ERR(file)) { -+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file)); -+ return -1; -+ } -+ a[0] = 0; -+ if (bindex < 0 -+ && !IS_ERR_OR_NULL(file->f_path.dentry) -+ && au_test_aufs(file->f_path.dentry->d_sb) -+ && au_fi(file)) -+ snprintf(a, sizeof(a), ", gen %d, mmapped %d", -+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped)); -+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n", -+ bindex, file->f_mode, file->f_flags, (long)file_count(file), -+ file->f_version, file->f_pos, a); -+ if (!IS_ERR_OR_NULL(file->f_path.dentry)) -+ do_pri_dentry(bindex, file->f_path.dentry); -+ return 0; -+} -+ -+void au_dpri_file(struct file *file) -+{ -+ struct au_finfo *finfo; -+ struct au_fidir *fidir; -+ struct au_hfile *hfile; -+ aufs_bindex_t bindex; -+ int err; -+ -+ err = do_pri_file(-1, file); -+ if (err -+ || IS_ERR_OR_NULL(file->f_path.dentry) -+ || !au_test_aufs(file->f_path.dentry->d_sb)) -+ return; -+ -+ finfo = au_fi(file); -+ if (!finfo) -+ return; -+ if (finfo->fi_btop < 0) -+ return; -+ fidir = finfo->fi_hdir; -+ if (!fidir) -+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file); -+ else -+ for (bindex = finfo->fi_btop; -+ bindex >= 0 && bindex <= fidir->fd_bbot; -+ bindex++) { -+ hfile = fidir->fd_hfile + bindex; -+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL); -+ } -+} -+ -+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br) -+{ -+ struct vfsmount *mnt; -+ struct super_block *sb; -+ -+ if (!br || IS_ERR(br)) -+ goto out; -+ mnt = au_br_mnt(br); -+ if (!mnt || IS_ERR(mnt)) -+ goto out; -+ sb = mnt->mnt_sb; -+ if (!sb || IS_ERR(sb)) -+ goto out; -+ -+ dpri("s%d: {perm 0x%x, id %d, wbr %p}, " -+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, " -+ "xino %d\n", -+ bindex, br->br_perm, br->br_id, br->br_wbr, -+ au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev), -+ sb->s_flags, sb->s_count, -+ atomic_read(&sb->s_active), -+ !!au_xino_file(br->br_xino, /*idx*/-1)); -+ return 0; -+ -+out: -+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br)); -+ return -1; -+} -+ -+void au_dpri_sb(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ aufs_bindex_t bindex; -+ int err; -+ /* to reduce stack size */ -+ struct { -+ struct vfsmount mnt; -+ struct au_branch fake; -+ } *a; -+ -+ /* this function can be called from magic sysrq */ -+ a = kzalloc(sizeof(*a), GFP_ATOMIC); -+ if (unlikely(!a)) { -+ dpri("no memory\n"); -+ return; -+ } -+ -+ a->mnt.mnt_sb = sb; -+ a->fake.br_path.mnt = &a->mnt; -+ err = do_pri_br(-1, &a->fake); -+ kfree(a); -+ dpri("dev 0x%x\n", sb->s_dev); -+ if (err || !au_test_aufs(sb)) -+ return; -+ -+ sbinfo = au_sbi(sb); -+ if (!sbinfo) -+ return; -+ dpri("nw %d, gen %u, kobj %d\n", -+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation, -+ kref_read(&sbinfo->si_kobj.kref)); -+ for (bindex = 0; bindex <= sbinfo->si_bbot; bindex++) -+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line) -+{ -+ struct inode *h_inode, *inode = d_inode(dentry); -+ struct dentry *h_dentry; -+ aufs_bindex_t bindex, bbot, bi; -+ -+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */) -+ return; -+ -+ bbot = au_dbbot(dentry); -+ bi = au_ibbot(inode); -+ if (bi < bbot) -+ bbot = bi; -+ bindex = au_dbtop(dentry); -+ bi = au_ibtop(inode); -+ if (bi > bindex) -+ bindex = bi; -+ -+ for (; bindex <= bbot; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ h_inode = au_h_iptr(inode, bindex); -+ if (unlikely(h_inode != d_inode(h_dentry))) { -+ au_debug_on(); -+ AuDbg("b%d, %s:%d\n", bindex, func, line); -+ AuDbgDentry(dentry); -+ AuDbgInode(inode); -+ au_debug_off(); -+ BUG(); -+ } -+ } -+} -+ -+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen) -+{ -+ int err, i, j; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry **dentries; -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ AuDebugOn(err); -+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1); -+ AuDebugOn(err); -+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) { -+ dpage = dpages.dpages + i; -+ dentries = dpage->dentries; -+ for (j = dpage->ndentry - 1; !err && j >= 0; j--) -+ AuDebugOn(au_digen_test(dentries[j], sigen)); -+ } -+ au_dpages_free(&dpages); -+} -+ -+void au_dbg_verify_kthread(void) -+{ -+ if (au_wkq_test()) { -+ au_dbg_blocked(); -+ /* -+ * It may be recursive, but udba=notify between two aufs mounts, -+ * where a single ro branch is shared, is not a problem. -+ */ -+ /* WARN_ON(1); */ -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int __init au_debug_init(void) -+{ -+ aufs_bindex_t bindex; -+ struct au_vdir_destr destr; -+ -+ bindex = -1; -+ AuDebugOn(bindex >= 0); -+ -+ destr.len = -1; -+ AuDebugOn(destr.len < NAME_MAX); -+ -+#ifdef CONFIG_4KSTACKS -+ pr_warn("CONFIG_4KSTACKS is defined.\n"); -+#endif -+ -+ return 0; -+} -diff --git a/fs/aufs/debug.h b/fs/aufs/debug.h -new file mode 100644 -index 000000000..b80bb5a9a ---- /dev/null -+++ b/fs/aufs/debug.h -@@ -0,0 +1,226 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * debug print functions -+ */ -+ -+#ifndef __AUFS_DEBUG_H__ -+#define __AUFS_DEBUG_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_AUFS_DEBUG -+#define AuDebugOn(a) BUG_ON(a) -+ -+/* module parameter */ -+extern atomic_t aufs_debug; -+static inline void au_debug_on(void) -+{ -+ atomic_inc(&aufs_debug); -+} -+static inline void au_debug_off(void) -+{ -+ atomic_dec_if_positive(&aufs_debug); -+} -+ -+static inline int au_debug_test(void) -+{ -+ return atomic_read(&aufs_debug) > 0; -+} -+#else -+#define AuDebugOn(a) do {} while (0) -+AuStubVoid(au_debug_on, void) -+AuStubVoid(au_debug_off, void) -+AuStubInt0(au_debug_test, void) -+#endif /* CONFIG_AUFS_DEBUG */ -+ -+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t) -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* debug print */ -+ -+#define AuDbg(fmt, ...) do { \ -+ if (au_debug_test()) \ -+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \ -+} while (0) -+#define AuLabel(l) AuDbg(#l "\n") -+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__) -+#define AuWarn1(fmt, ...) do { \ -+ static unsigned char _c; \ -+ if (!_c++) \ -+ pr_warn(fmt, ##__VA_ARGS__); \ -+} while (0) -+ -+#define AuErr1(fmt, ...) do { \ -+ static unsigned char _c; \ -+ if (!_c++) \ -+ pr_err(fmt, ##__VA_ARGS__); \ -+} while (0) -+ -+#define AuIOErr1(fmt, ...) do { \ -+ static unsigned char _c; \ -+ if (!_c++) \ -+ AuIOErr(fmt, ##__VA_ARGS__); \ -+} while (0) -+ -+#define AuUnsupportMsg "This operation is not supported." \ -+ " Please report this application to aufs-users ML." -+#define AuUnsupport(fmt, ...) do { \ -+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \ -+ dump_stack(); \ -+} while (0) -+ -+#define AuTraceErr(e) do { \ -+ if (unlikely((e) < 0)) \ -+ AuDbg("err %d\n", (int)(e)); \ -+} while (0) -+ -+#define AuTraceErrPtr(p) do { \ -+ if (IS_ERR(p)) \ -+ AuDbg("err %ld\n", PTR_ERR(p)); \ -+} while (0) -+ -+/* dirty macros for debug print, use with "%.*s" and caution */ -+#define AuLNPair(qstr) (qstr)->len, (qstr)->name -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct dentry; -+#ifdef CONFIG_AUFS_DEBUG -+extern struct mutex au_dbg_mtx; -+extern char *au_plevel; -+struct au_nhash; -+void au_dpri_whlist(struct au_nhash *whlist); -+struct au_vdir; -+void au_dpri_vdir(struct au_vdir *vdir); -+struct inode; -+void au_dpri_inode(struct inode *inode); -+void au_dpri_dalias(struct inode *inode); -+void au_dpri_dentry(struct dentry *dentry); -+struct file; -+void au_dpri_file(struct file *filp); -+struct super_block; -+void au_dpri_sb(struct super_block *sb); -+ -+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__) -+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line); -+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen); -+void au_dbg_verify_kthread(void); -+ -+int __init au_debug_init(void); -+ -+#define AuDbgWhlist(w) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#w "\n"); \ -+ au_dpri_whlist(w); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgVdir(v) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#v "\n"); \ -+ au_dpri_vdir(v); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgInode(i) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#i "\n"); \ -+ au_dpri_inode(i); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgDAlias(i) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#i "\n"); \ -+ au_dpri_dalias(i); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgDentry(d) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#d "\n"); \ -+ au_dpri_dentry(d); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgFile(f) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#f "\n"); \ -+ au_dpri_file(f); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgSb(sb) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#sb "\n"); \ -+ au_dpri_sb(sb); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgSym(addr) do { \ -+ char sym[KSYM_SYMBOL_LEN]; \ -+ sprint_symbol(sym, (unsigned long)addr); \ -+ AuDbg("%s\n", sym); \ -+} while (0) -+#else -+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry) -+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen) -+AuStubVoid(au_dbg_verify_kthread, void) -+AuStubInt0(__init au_debug_init, void) -+ -+#define AuDbgWhlist(w) do {} while (0) -+#define AuDbgVdir(v) do {} while (0) -+#define AuDbgInode(i) do {} while (0) -+#define AuDbgDAlias(i) do {} while (0) -+#define AuDbgDentry(d) do {} while (0) -+#define AuDbgFile(f) do {} while (0) -+#define AuDbgSb(sb) do {} while (0) -+#define AuDbgSym(addr) do {} while (0) -+#endif /* CONFIG_AUFS_DEBUG */ -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_MAGIC_SYSRQ -+int __init au_sysrq_init(void); -+void au_sysrq_fin(void); -+ -+#ifdef CONFIG_HW_CONSOLE -+#define au_dbg_blocked() do { \ -+ WARN_ON(1); \ -+ handle_sysrq('w'); \ -+} while (0) -+#else -+AuStubVoid(au_dbg_blocked, void) -+#endif -+ -+#else -+AuStubInt0(__init au_sysrq_init, void) -+AuStubVoid(au_sysrq_fin, void) -+AuStubVoid(au_dbg_blocked, void) -+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DEBUG_H__ */ -diff --git a/fs/aufs/dentry.c b/fs/aufs/dentry.c -new file mode 100644 -index 000000000..79761eae9 ---- /dev/null -+++ b/fs/aufs/dentry.c -@@ -0,0 +1,1153 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * lookup and dentry operations -+ */ -+ -+#include -+#include "aufs.h" -+ -+/* -+ * returns positive/negative dentry, NULL or an error. -+ * NULL means whiteout-ed or not-found. -+ */ -+static struct dentry* -+au_do_lookup(struct dentry *h_parent, struct dentry *dentry, -+ aufs_bindex_t bindex, struct au_do_lookup_args *args) -+{ -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ struct au_branch *br; -+ int wh_found, opq; -+ unsigned char wh_able; -+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG); -+ const unsigned char ignore_perm = !!au_ftest_lkup(args->flags, -+ IGNORE_PERM); -+ -+ wh_found = 0; -+ br = au_sbr(dentry->d_sb, bindex); -+ wh_able = !!au_br_whable(br->br_perm); -+ if (wh_able) -+ wh_found = au_wh_test(h_parent, &args->whname, ignore_perm); -+ h_dentry = ERR_PTR(wh_found); -+ if (!wh_found) -+ goto real_lookup; -+ if (unlikely(wh_found < 0)) -+ goto out; -+ -+ /* We found a whiteout */ -+ /* au_set_dbbot(dentry, bindex); */ -+ au_set_dbwh(dentry, bindex); -+ if (!allow_neg) -+ return NULL; /* success */ -+ -+real_lookup: -+ if (!ignore_perm) -+ h_dentry = vfsub_lkup_one(args->name, h_parent); -+ else -+ h_dentry = au_sio_lkup_one(args->name, h_parent); -+ if (IS_ERR(h_dentry)) { -+ if (PTR_ERR(h_dentry) == -ENAMETOOLONG -+ && !allow_neg) -+ h_dentry = NULL; -+ goto out; -+ } -+ -+ h_inode = d_inode(h_dentry); -+ if (d_is_negative(h_dentry)) { -+ if (!allow_neg) -+ goto out_neg; -+ } else if (wh_found -+ || (args->type && args->type != (h_inode->i_mode & S_IFMT))) -+ goto out_neg; -+ else if (au_ftest_lkup(args->flags, DIRREN) -+ /* && h_inode */ -+ && !au_dr_lkup_h_ino(args, bindex, h_inode->i_ino)) { -+ AuDbg("b%d %pd ignored hi%llu\n", bindex, h_dentry, -+ (unsigned long long)h_inode->i_ino); -+ goto out_neg; -+ } -+ -+ if (au_dbbot(dentry) <= bindex) -+ au_set_dbbot(dentry, bindex); -+ if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry)) -+ au_set_dbtop(dentry, bindex); -+ au_set_h_dptr(dentry, bindex, h_dentry); -+ -+ if (!d_is_dir(h_dentry) -+ || !wh_able -+ || (d_really_is_positive(dentry) && !d_is_dir(dentry))) -+ goto out; /* success */ -+ -+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD); -+ opq = au_diropq_test(h_dentry); -+ inode_unlock_shared(h_inode); -+ if (opq > 0) -+ au_set_dbdiropq(dentry, bindex); -+ else if (unlikely(opq < 0)) { -+ au_set_h_dptr(dentry, bindex, NULL); -+ h_dentry = ERR_PTR(opq); -+ } -+ goto out; -+ -+out_neg: -+ dput(h_dentry); -+ h_dentry = NULL; -+out: -+ return h_dentry; -+} -+ -+static int au_test_shwh(struct super_block *sb, const struct qstr *name) -+{ -+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH) -+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))) -+ return -EPERM; -+ return 0; -+} -+ -+/* -+ * returns the number of lower positive dentries, -+ * otherwise an error. -+ * can be called at unlinking with @type is zero. -+ */ -+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop, -+ unsigned int flags) -+{ -+ int npositive, err; -+ aufs_bindex_t bindex, btail, bdiropq; -+ unsigned char isdir, dirperm1, dirren; -+ struct au_do_lookup_args args = { -+ .flags = flags, -+ .name = &dentry->d_name -+ }; -+ struct dentry *parent; -+ struct super_block *sb; -+ -+ sb = dentry->d_sb; -+ err = au_test_shwh(sb, args.name); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_wh_name_alloc(&args.whname, args.name); -+ if (unlikely(err)) -+ goto out; -+ -+ isdir = !!d_is_dir(dentry); -+ dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1); -+ dirren = !!au_opt_test(au_mntflags(sb), DIRREN); -+ if (dirren) -+ au_fset_lkup(args.flags, DIRREN); -+ -+ npositive = 0; -+ parent = dget_parent(dentry); -+ btail = au_dbtaildir(parent); -+ for (bindex = btop; bindex <= btail; bindex++) { -+ struct dentry *h_parent, *h_dentry; -+ struct inode *h_inode, *h_dir; -+ struct au_branch *br; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry) { -+ if (d_is_positive(h_dentry)) -+ npositive++; -+ break; -+ } -+ h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || !d_is_dir(h_parent)) -+ continue; -+ -+ if (dirren) { -+ /* if the inum matches, then use the prepared name */ -+ err = au_dr_lkup_name(&args, bindex); -+ if (unlikely(err)) -+ goto out_parent; -+ } -+ -+ h_dir = d_inode(h_parent); -+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT); -+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &args); -+ inode_unlock_shared(h_dir); -+ err = PTR_ERR(h_dentry); -+ if (IS_ERR(h_dentry)) -+ goto out_parent; -+ if (h_dentry) -+ au_fclr_lkup(args.flags, ALLOW_NEG); -+ if (dirperm1) -+ au_fset_lkup(args.flags, IGNORE_PERM); -+ -+ if (au_dbwh(dentry) == bindex) -+ break; -+ if (!h_dentry) -+ continue; -+ if (d_is_negative(h_dentry)) -+ continue; -+ h_inode = d_inode(h_dentry); -+ npositive++; -+ if (!args.type) -+ args.type = h_inode->i_mode & S_IFMT; -+ if (args.type != S_IFDIR) -+ break; -+ else if (isdir) { -+ /* the type of lower may be different */ -+ bdiropq = au_dbdiropq(dentry); -+ if (bdiropq >= 0 && bdiropq <= bindex) -+ break; -+ } -+ br = au_sbr(sb, bindex); -+ if (dirren -+ && au_dr_hino_test_add(&br->br_dirren, h_inode->i_ino, -+ /*add_ent*/NULL)) { -+ /* prepare next name to lookup */ -+ err = au_dr_lkup(&args, dentry, bindex); -+ if (unlikely(err)) -+ goto out_parent; -+ } -+ } -+ -+ if (npositive) { -+ AuLabel(positive); -+ au_update_dbtop(dentry); -+ } -+ err = npositive; -+ if (unlikely(!au_opt_test(au_mntflags(sb), UDBA_NONE) -+ && au_dbtop(dentry) < 0)) { -+ err = -EIO; -+ AuIOErr("both of real entry and whiteout found, %pd, err %d\n", -+ dentry, err); -+ } -+ -+out_parent: -+ dput(parent); -+ kfree(args.whname.name); -+ if (dirren) -+ au_dr_lkup_fin(&args); -+out: -+ return err; -+} -+ -+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent) -+{ -+ struct dentry *dentry; -+ int wkq_err; -+ -+ if (!au_test_h_perm_sio(d_inode(parent), MAY_EXEC)) -+ dentry = vfsub_lkup_one(name, parent); -+ else { -+ struct vfsub_lkup_one_args args = { -+ .errp = &dentry, -+ .name = name, -+ .parent = parent -+ }; -+ -+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args); -+ if (unlikely(wkq_err)) -+ dentry = ERR_PTR(wkq_err); -+ } -+ -+ return dentry; -+} -+ -+/* -+ * lookup @dentry on @bindex which should be negative. -+ */ -+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh) -+{ -+ int err; -+ struct dentry *parent, *h_parent, *h_dentry; -+ struct au_branch *br; -+ -+ parent = dget_parent(dentry); -+ h_parent = au_h_dptr(parent, bindex); -+ br = au_sbr(dentry->d_sb, bindex); -+ if (wh) -+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name); -+ else -+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent); -+ err = PTR_ERR(h_dentry); -+ if (IS_ERR(h_dentry)) -+ goto out; -+ if (unlikely(d_is_positive(h_dentry))) { -+ err = -EIO; -+ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex); -+ dput(h_dentry); -+ goto out; -+ } -+ -+ err = 0; -+ if (bindex < au_dbtop(dentry)) -+ au_set_dbtop(dentry, bindex); -+ if (au_dbbot(dentry) < bindex) -+ au_set_dbbot(dentry, bindex); -+ au_set_h_dptr(dentry, bindex, h_dentry); -+ -+out: -+ dput(parent); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* subset of struct inode */ -+struct au_iattr { -+ unsigned long i_ino; -+ /* unsigned int i_nlink; */ -+ kuid_t i_uid; -+ kgid_t i_gid; -+ u64 i_version; -+/* -+ loff_t i_size; -+ blkcnt_t i_blocks; -+*/ -+ umode_t i_mode; -+}; -+ -+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode) -+{ -+ ia->i_ino = h_inode->i_ino; -+ /* ia->i_nlink = h_inode->i_nlink; */ -+ ia->i_uid = h_inode->i_uid; -+ ia->i_gid = h_inode->i_gid; -+ ia->i_version = inode_query_iversion(h_inode); -+/* -+ ia->i_size = h_inode->i_size; -+ ia->i_blocks = h_inode->i_blocks; -+*/ -+ ia->i_mode = (h_inode->i_mode & S_IFMT); -+} -+ -+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode) -+{ -+ return ia->i_ino != h_inode->i_ino -+ /* || ia->i_nlink != h_inode->i_nlink */ -+ || !uid_eq(ia->i_uid, h_inode->i_uid) -+ || !gid_eq(ia->i_gid, h_inode->i_gid) -+ || !inode_eq_iversion(h_inode, ia->i_version) -+/* -+ || ia->i_size != h_inode->i_size -+ || ia->i_blocks != h_inode->i_blocks -+*/ -+ || ia->i_mode != (h_inode->i_mode & S_IFMT); -+} -+ -+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent, -+ struct au_branch *br) -+{ -+ int err; -+ struct au_iattr ia; -+ struct inode *h_inode; -+ struct dentry *h_d; -+ struct super_block *h_sb; -+ -+ err = 0; -+ memset(&ia, -1, sizeof(ia)); -+ h_sb = h_dentry->d_sb; -+ h_inode = NULL; -+ if (d_is_positive(h_dentry)) { -+ h_inode = d_inode(h_dentry); -+ au_iattr_save(&ia, h_inode); -+ } else if (au_test_nfs(h_sb) || au_test_fuse(h_sb)) -+ /* nfs d_revalidate may return 0 for negative dentry */ -+ /* fuse d_revalidate always return 0 for negative dentry */ -+ goto out; -+ -+ /* main purpose is namei.c:cached_lookup() and d_revalidate */ -+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent); -+ err = PTR_ERR(h_d); -+ if (IS_ERR(h_d)) -+ goto out; -+ -+ err = 0; -+ if (unlikely(h_d != h_dentry -+ || d_inode(h_d) != h_inode -+ || (h_inode && au_iattr_test(&ia, h_inode)))) -+ err = au_busy_or_stale(); -+ dput(h_d); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir, -+ struct dentry *h_parent, struct au_branch *br) -+{ -+ int err; -+ -+ err = 0; -+ if (udba == AuOpt_UDBA_REVAL -+ && !au_test_fs_remote(h_dentry->d_sb)) { -+ IMustLock(h_dir); -+ err = (d_inode(h_dentry->d_parent) != h_dir); -+ } else if (udba != AuOpt_UDBA_NONE) -+ err = au_h_verify_dentry(h_dentry, h_parent, br); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent) -+{ -+ int err; -+ aufs_bindex_t new_bindex, bindex, bbot, bwh, bdiropq; -+ struct au_hdentry tmp, *p, *q; -+ struct au_dinfo *dinfo; -+ struct super_block *sb; -+ -+ DiMustWriteLock(dentry); -+ -+ sb = dentry->d_sb; -+ dinfo = au_di(dentry); -+ bbot = dinfo->di_bbot; -+ bwh = dinfo->di_bwh; -+ bdiropq = dinfo->di_bdiropq; -+ bindex = dinfo->di_btop; -+ p = au_hdentry(dinfo, bindex); -+ for (; bindex <= bbot; bindex++, p++) { -+ if (!p->hd_dentry) -+ continue; -+ -+ new_bindex = au_br_index(sb, p->hd_id); -+ if (new_bindex == bindex) -+ continue; -+ -+ if (dinfo->di_bwh == bindex) -+ bwh = new_bindex; -+ if (dinfo->di_bdiropq == bindex) -+ bdiropq = new_bindex; -+ if (new_bindex < 0) { -+ au_hdput(p); -+ p->hd_dentry = NULL; -+ continue; -+ } -+ -+ /* swap two lower dentries, and loop again */ -+ q = au_hdentry(dinfo, new_bindex); -+ tmp = *q; -+ *q = *p; -+ *p = tmp; -+ if (tmp.hd_dentry) { -+ bindex--; -+ p--; -+ } -+ } -+ -+ dinfo->di_bwh = -1; -+ if (bwh >= 0 && bwh <= au_sbbot(sb) && au_sbr_whable(sb, bwh)) -+ dinfo->di_bwh = bwh; -+ -+ dinfo->di_bdiropq = -1; -+ if (bdiropq >= 0 -+ && bdiropq <= au_sbbot(sb) -+ && au_sbr_whable(sb, bdiropq)) -+ dinfo->di_bdiropq = bdiropq; -+ -+ err = -EIO; -+ dinfo->di_btop = -1; -+ dinfo->di_bbot = -1; -+ bbot = au_dbbot(parent); -+ bindex = 0; -+ p = au_hdentry(dinfo, bindex); -+ for (; bindex <= bbot; bindex++, p++) -+ if (p->hd_dentry) { -+ dinfo->di_btop = bindex; -+ break; -+ } -+ -+ if (dinfo->di_btop >= 0) { -+ bindex = bbot; -+ p = au_hdentry(dinfo, bindex); -+ for (; bindex >= 0; bindex--, p--) -+ if (p->hd_dentry) { -+ dinfo->di_bbot = bindex; -+ err = 0; -+ break; -+ } -+ } -+ -+ return err; -+} -+ -+static void au_do_hide(struct dentry *dentry) -+{ -+ struct inode *inode; -+ -+ if (d_really_is_positive(dentry)) { -+ inode = d_inode(dentry); -+ if (!d_is_dir(dentry)) { -+ if (inode->i_nlink && !d_unhashed(dentry)) -+ drop_nlink(inode); -+ } else { -+ clear_nlink(inode); -+ /* stop next lookup */ -+ inode->i_flags |= S_DEAD; -+ } -+ smp_mb(); /* necessary? */ -+ } -+ d_drop(dentry); -+} -+ -+static int au_hide_children(struct dentry *parent) -+{ -+ int err, i, j, ndentry; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry *dentry; -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_dcsub_pages(&dpages, parent, NULL, NULL); -+ if (unlikely(err)) -+ goto out_dpages; -+ -+ /* in reverse order */ -+ for (i = dpages.ndpage - 1; i >= 0; i--) { -+ dpage = dpages.dpages + i; -+ ndentry = dpage->ndentry; -+ for (j = ndentry - 1; j >= 0; j--) { -+ dentry = dpage->dentries[j]; -+ if (dentry != parent) -+ au_do_hide(dentry); -+ } -+ } -+ -+out_dpages: -+ au_dpages_free(&dpages); -+out: -+ return err; -+} -+ -+static void au_hide(struct dentry *dentry) -+{ -+ int err; -+ -+ AuDbgDentry(dentry); -+ if (d_is_dir(dentry)) { -+ /* shrink_dcache_parent(dentry); */ -+ err = au_hide_children(dentry); -+ if (unlikely(err)) -+ AuIOErr("%pd, failed hiding children, ignored %d\n", -+ dentry, err); -+ } -+ au_do_hide(dentry); -+} -+ -+/* -+ * By adding a dirty branch, a cached dentry may be affected in various ways. -+ * -+ * a dirty branch is added -+ * - on the top of layers -+ * - in the middle of layers -+ * - to the bottom of layers -+ * -+ * on the added branch there exists -+ * - a whiteout -+ * - a diropq -+ * - a same named entry -+ * + exist -+ * * negative --> positive -+ * * positive --> positive -+ * - type is unchanged -+ * - type is changed -+ * + doesn't exist -+ * * negative --> negative -+ * * positive --> negative (rejected by au_br_del() for non-dir case) -+ * - none -+ */ -+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo, -+ struct au_dinfo *tmp) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct { -+ struct dentry *dentry; -+ struct inode *inode; -+ mode_t mode; -+ } orig_h, tmp_h = { -+ .dentry = NULL -+ }; -+ struct au_hdentry *hd; -+ struct inode *inode, *h_inode; -+ struct dentry *h_dentry; -+ -+ err = 0; -+ AuDebugOn(dinfo->di_btop < 0); -+ orig_h.mode = 0; -+ orig_h.dentry = au_hdentry(dinfo, dinfo->di_btop)->hd_dentry; -+ orig_h.inode = NULL; -+ if (d_is_positive(orig_h.dentry)) { -+ orig_h.inode = d_inode(orig_h.dentry); -+ orig_h.mode = orig_h.inode->i_mode & S_IFMT; -+ } -+ if (tmp->di_btop >= 0) { -+ tmp_h.dentry = au_hdentry(tmp, tmp->di_btop)->hd_dentry; -+ if (d_is_positive(tmp_h.dentry)) { -+ tmp_h.inode = d_inode(tmp_h.dentry); -+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT; -+ } -+ } -+ -+ inode = NULL; -+ if (d_really_is_positive(dentry)) -+ inode = d_inode(dentry); -+ if (!orig_h.inode) { -+ AuDbg("negative originally\n"); -+ if (inode) { -+ au_hide(dentry); -+ goto out; -+ } -+ AuDebugOn(inode); -+ AuDebugOn(dinfo->di_btop != dinfo->di_bbot); -+ AuDebugOn(dinfo->di_bdiropq != -1); -+ -+ if (!tmp_h.inode) { -+ AuDbg("negative --> negative\n"); -+ /* should have only one negative lower */ -+ if (tmp->di_btop >= 0 -+ && tmp->di_btop < dinfo->di_btop) { -+ AuDebugOn(tmp->di_btop != tmp->di_bbot); -+ AuDebugOn(dinfo->di_btop != dinfo->di_bbot); -+ au_set_h_dptr(dentry, dinfo->di_btop, NULL); -+ au_di_cp(dinfo, tmp); -+ hd = au_hdentry(tmp, tmp->di_btop); -+ au_set_h_dptr(dentry, tmp->di_btop, -+ dget(hd->hd_dentry)); -+ } -+ au_dbg_verify_dinode(dentry); -+ } else { -+ AuDbg("negative --> positive\n"); -+ /* -+ * similar to the behaviour of creating with bypassing -+ * aufs. -+ * unhash it in order to force an error in the -+ * succeeding create operation. -+ * we should not set S_DEAD here. -+ */ -+ d_drop(dentry); -+ /* au_di_swap(tmp, dinfo); */ -+ au_dbg_verify_dinode(dentry); -+ } -+ } else { -+ AuDbg("positive originally\n"); -+ /* inode may be NULL */ -+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode); -+ if (!tmp_h.inode) { -+ AuDbg("positive --> negative\n"); -+ /* or bypassing aufs */ -+ au_hide(dentry); -+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_btop) -+ dinfo->di_bwh = tmp->di_bwh; -+ if (inode) -+ err = au_refresh_hinode_self(inode); -+ au_dbg_verify_dinode(dentry); -+ } else if (orig_h.mode == tmp_h.mode) { -+ AuDbg("positive --> positive, same type\n"); -+ if (!S_ISDIR(orig_h.mode) -+ && dinfo->di_btop > tmp->di_btop) { -+ /* -+ * similar to the behaviour of removing and -+ * creating. -+ */ -+ au_hide(dentry); -+ if (inode) -+ err = au_refresh_hinode_self(inode); -+ au_dbg_verify_dinode(dentry); -+ } else { -+ /* fill empty slots */ -+ if (dinfo->di_btop > tmp->di_btop) -+ dinfo->di_btop = tmp->di_btop; -+ if (dinfo->di_bbot < tmp->di_bbot) -+ dinfo->di_bbot = tmp->di_bbot; -+ dinfo->di_bwh = tmp->di_bwh; -+ dinfo->di_bdiropq = tmp->di_bdiropq; -+ bbot = dinfo->di_bbot; -+ bindex = tmp->di_btop; -+ hd = au_hdentry(tmp, bindex); -+ for (; bindex <= bbot; bindex++, hd++) { -+ if (au_h_dptr(dentry, bindex)) -+ continue; -+ h_dentry = hd->hd_dentry; -+ if (!h_dentry) -+ continue; -+ AuDebugOn(d_is_negative(h_dentry)); -+ h_inode = d_inode(h_dentry); -+ AuDebugOn(orig_h.mode -+ != (h_inode->i_mode -+ & S_IFMT)); -+ au_set_h_dptr(dentry, bindex, -+ dget(h_dentry)); -+ } -+ if (inode) -+ err = au_refresh_hinode(inode, dentry); -+ au_dbg_verify_dinode(dentry); -+ } -+ } else { -+ AuDbg("positive --> positive, different type\n"); -+ /* similar to the behaviour of removing and creating */ -+ au_hide(dentry); -+ if (inode) -+ err = au_refresh_hinode_self(inode); -+ au_dbg_verify_dinode(dentry); -+ } -+ } -+ -+out: -+ return err; -+} -+ -+void au_refresh_dop(struct dentry *dentry, int force_reval) -+{ -+ const struct dentry_operations *dop -+ = force_reval ? &aufs_dop : dentry->d_sb->s_d_op; -+ static const unsigned int mask -+ = DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE; -+ -+ BUILD_BUG_ON(sizeof(mask) != sizeof(dentry->d_flags)); -+ -+ if (dentry->d_op == dop) -+ return; -+ -+ AuDbg("%pd\n", dentry); -+ spin_lock(&dentry->d_lock); -+ if (dop == &aufs_dop) -+ dentry->d_flags |= mask; -+ else -+ dentry->d_flags &= ~mask; -+ dentry->d_op = dop; -+ spin_unlock(&dentry->d_lock); -+} -+ -+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent) -+{ -+ int err, ebrange, nbr; -+ unsigned int sigen; -+ struct au_dinfo *dinfo, *tmp; -+ struct super_block *sb; -+ struct inode *inode; -+ -+ DiMustWriteLock(dentry); -+ AuDebugOn(IS_ROOT(dentry)); -+ AuDebugOn(d_really_is_negative(parent)); -+ -+ sb = dentry->d_sb; -+ sigen = au_sigen(sb); -+ err = au_digen_test(parent, sigen); -+ if (unlikely(err)) -+ goto out; -+ -+ nbr = au_sbbot(sb) + 1; -+ dinfo = au_di(dentry); -+ err = au_di_realloc(dinfo, nbr, /*may_shrink*/0); -+ if (unlikely(err)) -+ goto out; -+ ebrange = au_dbrange_test(dentry); -+ if (!ebrange) -+ ebrange = au_do_refresh_hdentry(dentry, parent); -+ -+ if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) { -+ AuDebugOn(au_dbtop(dentry) < 0 && au_dbbot(dentry) >= 0); -+ if (d_really_is_positive(dentry)) { -+ inode = d_inode(dentry); -+ err = au_refresh_hinode_self(inode); -+ } -+ au_dbg_verify_dinode(dentry); -+ if (!err) -+ goto out_dgen; /* success */ -+ goto out; -+ } -+ -+ /* temporary dinfo */ -+ AuDbgDentry(dentry); -+ err = -ENOMEM; -+ tmp = au_di_alloc(sb, AuLsc_DI_TMP); -+ if (unlikely(!tmp)) -+ goto out; -+ au_di_swap(tmp, dinfo); -+ /* returns the number of positive dentries */ -+ /* -+ * if current working dir is removed, it returns an error. -+ * but the dentry is legal. -+ */ -+ err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG); -+ AuDbgDentry(dentry); -+ au_di_swap(tmp, dinfo); -+ if (err == -ENOENT) -+ err = 0; -+ if (err >= 0) { -+ /* compare/refresh by dinfo */ -+ AuDbgDentry(dentry); -+ err = au_refresh_by_dinfo(dentry, dinfo, tmp); -+ au_dbg_verify_dinode(dentry); -+ AuTraceErr(err); -+ } -+ au_di_realloc(dinfo, nbr, /*may_shrink*/1); /* harmless if err */ -+ au_rw_write_unlock(&tmp->di_rwsem); -+ au_di_free(tmp); -+ if (unlikely(err)) -+ goto out; -+ -+out_dgen: -+ au_update_digen(dentry); -+out: -+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) { -+ AuIOErr("failed refreshing %pd, %d\n", dentry, err); -+ AuDbgDentry(dentry); -+ } -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags, -+ struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ int err, valid; -+ -+ err = 0; -+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE)) -+ goto out; -+ -+ AuDbg("b%d\n", bindex); -+ /* -+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs, -+ * due to whiteout and branch permission. -+ */ -+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE -+ | LOOKUP_FOLLOW | LOOKUP_EXCL); -+ /* it may return tri-state */ -+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags); -+ -+ if (unlikely(valid < 0)) -+ err = valid; -+ else if (!valid) -+ err = -EINVAL; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* todo: remove this */ -+static int h_d_revalidate(struct dentry *dentry, struct inode *inode, -+ unsigned int flags, int do_udba, int dirren) -+{ -+ int err; -+ umode_t mode, h_mode; -+ aufs_bindex_t bindex, btail, btop, ibs, ibe; -+ unsigned char plus, unhashed, is_root, h_plus, h_nfs, tmpfile; -+ struct inode *h_inode, *h_cached_inode; -+ struct dentry *h_dentry; -+ struct qstr *name, *h_name; -+ -+ err = 0; -+ plus = 0; -+ mode = 0; -+ ibs = -1; -+ ibe = -1; -+ unhashed = !!d_unhashed(dentry); -+ is_root = !!IS_ROOT(dentry); -+ name = &dentry->d_name; -+ tmpfile = au_di(dentry)->di_tmpfile; -+ -+ /* -+ * Theoretically, REVAL test should be unnecessary in case of -+ * {FS,I}NOTIFY. -+ * But {fs,i}notify doesn't fire some necessary events, -+ * IN_ATTRIB for atime/nlink/pageio -+ * Let's do REVAL test too. -+ */ -+ if (do_udba && inode) { -+ mode = (inode->i_mode & S_IFMT); -+ plus = (inode->i_nlink > 0); -+ ibs = au_ibtop(inode); -+ ibe = au_ibbot(inode); -+ } -+ -+ btop = au_dbtop(dentry); -+ btail = btop; -+ if (inode && S_ISDIR(inode->i_mode)) -+ btail = au_dbtaildir(dentry); -+ for (bindex = btop; bindex <= btail; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ -+ AuDbg("b%d, %pd\n", bindex, h_dentry); -+ h_nfs = !!au_test_nfs(h_dentry->d_sb); -+ spin_lock(&h_dentry->d_lock); -+ h_name = &h_dentry->d_name; -+ if (unlikely(do_udba -+ && !is_root -+ && ((!h_nfs -+ && (unhashed != !!d_unhashed(h_dentry) -+ || (!tmpfile && !dirren -+ && !au_qstreq(name, h_name)) -+ )) -+ || (h_nfs -+ && !(flags & LOOKUP_OPEN) -+ && (h_dentry->d_flags -+ & DCACHE_NFSFS_RENAMED))) -+ )) { -+ int h_unhashed; -+ -+ h_unhashed = d_unhashed(h_dentry); -+ spin_unlock(&h_dentry->d_lock); -+ AuDbg("unhash 0x%x 0x%x, %pd %pd\n", -+ unhashed, h_unhashed, dentry, h_dentry); -+ goto err; -+ } -+ spin_unlock(&h_dentry->d_lock); -+ -+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex); -+ if (unlikely(err)) -+ /* do not goto err, to keep the errno */ -+ break; -+ -+ /* todo: plink too? */ -+ if (!do_udba) -+ continue; -+ -+ /* UDBA tests */ -+ if (unlikely(!!inode != d_is_positive(h_dentry))) -+ goto err; -+ -+ h_inode = NULL; -+ if (d_is_positive(h_dentry)) -+ h_inode = d_inode(h_dentry); -+ h_plus = plus; -+ h_mode = mode; -+ h_cached_inode = h_inode; -+ if (h_inode) { -+ h_mode = (h_inode->i_mode & S_IFMT); -+ h_plus = (h_inode->i_nlink > 0); -+ } -+ if (inode && ibs <= bindex && bindex <= ibe) -+ h_cached_inode = au_h_iptr(inode, bindex); -+ -+ if (!h_nfs) { -+ if (unlikely(plus != h_plus && !tmpfile)) -+ goto err; -+ } else { -+ if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED) -+ && !is_root -+ && !IS_ROOT(h_dentry) -+ && unhashed != d_unhashed(h_dentry))) -+ goto err; -+ } -+ if (unlikely(mode != h_mode -+ || h_cached_inode != h_inode)) -+ goto err; -+ continue; -+ -+err: -+ err = -EINVAL; -+ break; -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+/* todo: consolidate with do_refresh() and au_reval_for_attr() */ -+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen) -+{ -+ int err; -+ struct dentry *parent; -+ -+ if (!au_digen_test(dentry, sigen)) -+ return 0; -+ -+ parent = dget_parent(dentry); -+ di_read_lock_parent(parent, AuLock_IR); -+ AuDebugOn(au_digen_test(parent, sigen)); -+ au_dbg_verify_gen(parent, sigen); -+ err = au_refresh_dentry(dentry, parent); -+ di_read_unlock(parent, AuLock_IR); -+ dput(parent); -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_reval_dpath(struct dentry *dentry, unsigned int sigen) -+{ -+ int err; -+ struct dentry *d, *parent; -+ -+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR)) -+ return simple_reval_dpath(dentry, sigen); -+ -+ /* slow loop, keep it simple and stupid */ -+ /* cf: au_cpup_dirs() */ -+ err = 0; -+ parent = NULL; -+ while (au_digen_test(dentry, sigen)) { -+ d = dentry; -+ while (1) { -+ dput(parent); -+ parent = dget_parent(d); -+ if (!au_digen_test(parent, sigen)) -+ break; -+ d = parent; -+ } -+ -+ if (d != dentry) -+ di_write_lock_child2(d); -+ -+ /* someone might update our dentry while we were sleeping */ -+ if (au_digen_test(d, sigen)) { -+ /* -+ * todo: consolidate with simple_reval_dpath(), -+ * do_refresh() and au_reval_for_attr(). -+ */ -+ di_read_lock_parent(parent, AuLock_IR); -+ err = au_refresh_dentry(d, parent); -+ di_read_unlock(parent, AuLock_IR); -+ } -+ -+ if (d != dentry) -+ di_write_unlock(d); -+ dput(parent); -+ if (unlikely(err)) -+ break; -+ } -+ -+ return err; -+} -+ -+/* -+ * if valid returns 1, otherwise 0. -+ */ -+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags) -+{ -+ int valid, err; -+ unsigned int sigen; -+ unsigned char do_udba, dirren; -+ struct super_block *sb; -+ struct inode *inode; -+ -+ /* todo: support rcu-walk? */ -+ if (flags & LOOKUP_RCU) -+ return -ECHILD; -+ -+ valid = 0; -+ if (unlikely(!au_di(dentry))) -+ goto out; -+ -+ valid = 1; -+ sb = dentry->d_sb; -+ /* -+ * todo: very ugly -+ * i_mutex of parent dir may be held, -+ * but we should not return 'invalid' due to busy. -+ */ -+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM); -+ if (unlikely(err)) { -+ valid = err; -+ AuTraceErr(err); -+ goto out; -+ } -+ inode = NULL; -+ if (d_really_is_positive(dentry)) -+ inode = d_inode(dentry); -+ if (unlikely(inode && au_is_bad_inode(inode))) { -+ err = -EINVAL; -+ AuTraceErr(err); -+ goto out_dgrade; -+ } -+ if (unlikely(au_dbrange_test(dentry))) { -+ err = -EINVAL; -+ AuTraceErr(err); -+ goto out_dgrade; -+ } -+ -+ sigen = au_sigen(sb); -+ if (au_digen_test(dentry, sigen)) { -+ AuDebugOn(IS_ROOT(dentry)); -+ err = au_reval_dpath(dentry, sigen); -+ if (unlikely(err)) { -+ AuTraceErr(err); -+ goto out_dgrade; -+ } -+ } -+ di_downgrade_lock(dentry, AuLock_IR); -+ -+ err = -EINVAL; -+ if (!(flags & (LOOKUP_OPEN | LOOKUP_EMPTY)) -+ && inode -+ && !(inode->i_state && I_LINKABLE) -+ && (IS_DEADDIR(inode) || !inode->i_nlink)) { -+ AuTraceErr(err); -+ goto out_inval; -+ } -+ -+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE); -+ if (do_udba && inode) { -+ aufs_bindex_t btop = au_ibtop(inode); -+ struct inode *h_inode; -+ -+ if (btop >= 0) { -+ h_inode = au_h_iptr(inode, btop); -+ if (h_inode && au_test_higen(inode, h_inode)) { -+ AuTraceErr(err); -+ goto out_inval; -+ } -+ } -+ } -+ -+ dirren = !!au_opt_test(au_mntflags(sb), DIRREN); -+ err = h_d_revalidate(dentry, inode, flags, do_udba, dirren); -+ if (unlikely(!err && do_udba && au_dbtop(dentry) < 0)) { -+ err = -EIO; -+ AuDbg("both of real entry and whiteout found, %p, err %d\n", -+ dentry, err); -+ } -+ goto out_inval; -+ -+out_dgrade: -+ di_downgrade_lock(dentry, AuLock_IR); -+out_inval: -+ aufs_read_unlock(dentry, AuLock_IR); -+ AuTraceErr(err); -+ valid = !err; -+out: -+ if (!valid) { -+ AuDbg("%pd invalid, %d\n", dentry, valid); -+ d_drop(dentry); -+ } -+ return valid; -+} -+ -+static void aufs_d_release(struct dentry *dentry) -+{ -+ if (au_di(dentry)) { -+ au_di_fin(dentry); -+ au_hn_di_reinit(dentry); -+ } -+} -+ -+const struct dentry_operations aufs_dop = { -+ .d_revalidate = aufs_d_revalidate, -+ .d_weak_revalidate = aufs_d_revalidate, -+ .d_release = aufs_d_release -+}; -+ -+/* aufs_dop without d_revalidate */ -+const struct dentry_operations aufs_dop_noreval = { -+ .d_release = aufs_d_release -+}; -diff --git a/fs/aufs/dentry.h b/fs/aufs/dentry.h -new file mode 100644 -index 000000000..adc2ac997 ---- /dev/null -+++ b/fs/aufs/dentry.h -@@ -0,0 +1,267 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * lookup and dentry operations -+ */ -+ -+#ifndef __AUFS_DENTRY_H__ -+#define __AUFS_DENTRY_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include "dirren.h" -+#include "rwsem.h" -+ -+struct au_hdentry { -+ struct dentry *hd_dentry; -+ aufs_bindex_t hd_id; -+}; -+ -+struct au_dinfo { -+ atomic_t di_generation; -+ -+ struct au_rwsem di_rwsem; -+ aufs_bindex_t di_btop, di_bbot, di_bwh, di_bdiropq; -+ unsigned char di_tmpfile; /* to allow the different name */ -+ struct au_hdentry *di_hdentry; -+} ____cacheline_aligned_in_smp; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* flags for au_lkup_dentry() */ -+#define AuLkup_ALLOW_NEG 1 -+#define AuLkup_IGNORE_PERM (1 << 1) -+#define AuLkup_DIRREN (1 << 2) -+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name) -+#define au_fset_lkup(flags, name) \ -+ do { (flags) |= AuLkup_##name; } while (0) -+#define au_fclr_lkup(flags, name) \ -+ do { (flags) &= ~AuLkup_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_DIRREN -+#undef AuLkup_DIRREN -+#define AuLkup_DIRREN 0 -+#endif -+ -+struct au_do_lookup_args { -+ unsigned int flags; -+ mode_t type; -+ struct qstr whname, *name; -+ struct au_dr_lookup dirren; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* dentry.c */ -+extern const struct dentry_operations aufs_dop, aufs_dop_noreval; -+struct au_branch; -+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent); -+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir, -+ struct dentry *h_parent, struct au_branch *br); -+ -+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop, -+ unsigned int flags); -+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh); -+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent); -+int au_reval_dpath(struct dentry *dentry, unsigned int sigen); -+void au_refresh_dop(struct dentry *dentry, int force_reval); -+ -+/* dinfo.c */ -+void au_di_init_once(void *_di); -+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc); -+void au_di_free(struct au_dinfo *dinfo); -+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b); -+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src); -+int au_di_init(struct dentry *dentry); -+void au_di_fin(struct dentry *dentry); -+int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink); -+ -+void di_read_lock(struct dentry *d, int flags, unsigned int lsc); -+void di_read_unlock(struct dentry *d, int flags); -+void di_downgrade_lock(struct dentry *d, int flags); -+void di_write_lock(struct dentry *d, unsigned int lsc); -+void di_write_unlock(struct dentry *d); -+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir); -+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir); -+void di_write_unlock2(struct dentry *d1, struct dentry *d2); -+ -+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex); -+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex); -+aufs_bindex_t au_dbtail(struct dentry *dentry); -+aufs_bindex_t au_dbtaildir(struct dentry *dentry); -+ -+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_dentry); -+int au_digen_test(struct dentry *dentry, unsigned int sigen); -+int au_dbrange_test(struct dentry *dentry); -+void au_update_digen(struct dentry *dentry); -+void au_update_dbrange(struct dentry *dentry, int do_put_zero); -+void au_update_dbtop(struct dentry *dentry); -+void au_update_dbbot(struct dentry *dentry); -+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct au_dinfo *au_di(struct dentry *dentry) -+{ -+ return dentry->d_fsdata; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* lock subclass for dinfo */ -+enum { -+ AuLsc_DI_CHILD, /* child first */ -+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */ -+ AuLsc_DI_CHILD3, /* copyup dirs */ -+ AuLsc_DI_PARENT, -+ AuLsc_DI_PARENT2, -+ AuLsc_DI_PARENT3, -+ AuLsc_DI_TMP /* temp for replacing dinfo */ -+}; -+ -+/* -+ * di_read_lock_child, di_write_lock_child, -+ * di_read_lock_child2, di_write_lock_child2, -+ * di_read_lock_child3, di_write_lock_child3, -+ * di_read_lock_parent, di_write_lock_parent, -+ * di_read_lock_parent2, di_write_lock_parent2, -+ * di_read_lock_parent3, di_write_lock_parent3, -+ */ -+#define AuReadLockFunc(name, lsc) \ -+static inline void di_read_lock_##name(struct dentry *d, int flags) \ -+{ di_read_lock(d, flags, AuLsc_DI_##lsc); } -+ -+#define AuWriteLockFunc(name, lsc) \ -+static inline void di_write_lock_##name(struct dentry *d) \ -+{ di_write_lock(d, AuLsc_DI_##lsc); } -+ -+#define AuRWLockFuncs(name, lsc) \ -+ AuReadLockFunc(name, lsc) \ -+ AuWriteLockFunc(name, lsc) -+ -+AuRWLockFuncs(child, CHILD); -+AuRWLockFuncs(child2, CHILD2); -+AuRWLockFuncs(child3, CHILD3); -+AuRWLockFuncs(parent, PARENT); -+AuRWLockFuncs(parent2, PARENT2); -+AuRWLockFuncs(parent3, PARENT3); -+ -+#undef AuReadLockFunc -+#undef AuWriteLockFunc -+#undef AuRWLockFuncs -+ -+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem) -+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem) -+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem) -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* todo: memory barrier? */ -+static inline unsigned int au_digen(struct dentry *d) -+{ -+ return atomic_read(&au_di(d)->di_generation); -+} -+ -+static inline void au_h_dentry_init(struct au_hdentry *hdentry) -+{ -+ hdentry->hd_dentry = NULL; -+} -+ -+static inline struct au_hdentry *au_hdentry(struct au_dinfo *di, -+ aufs_bindex_t bindex) -+{ -+ return di->di_hdentry + bindex; -+} -+ -+static inline void au_hdput(struct au_hdentry *hd) -+{ -+ if (hd) -+ dput(hd->hd_dentry); -+} -+ -+static inline aufs_bindex_t au_dbtop(struct dentry *dentry) -+{ -+ DiMustAnyLock(dentry); -+ return au_di(dentry)->di_btop; -+} -+ -+static inline aufs_bindex_t au_dbbot(struct dentry *dentry) -+{ -+ DiMustAnyLock(dentry); -+ return au_di(dentry)->di_bbot; -+} -+ -+static inline aufs_bindex_t au_dbwh(struct dentry *dentry) -+{ -+ DiMustAnyLock(dentry); -+ return au_di(dentry)->di_bwh; -+} -+ -+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry) -+{ -+ DiMustAnyLock(dentry); -+ return au_di(dentry)->di_bdiropq; -+} -+ -+/* todo: hard/soft set? */ -+static inline void au_set_dbtop(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ DiMustWriteLock(dentry); -+ au_di(dentry)->di_btop = bindex; -+} -+ -+static inline void au_set_dbbot(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ DiMustWriteLock(dentry); -+ au_di(dentry)->di_bbot = bindex; -+} -+ -+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ DiMustWriteLock(dentry); -+ /* dbwh can be outside of btop - bbot range */ -+ au_di(dentry)->di_bwh = bindex; -+} -+ -+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ DiMustWriteLock(dentry); -+ au_di(dentry)->di_bdiropq = bindex; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_HNOTIFY -+static inline void au_digen_dec(struct dentry *d) -+{ -+ atomic_dec(&au_di(d)->di_generation); -+} -+ -+static inline void au_hn_di_reinit(struct dentry *dentry) -+{ -+ dentry->d_fsdata = NULL; -+} -+#else -+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused) -+#endif /* CONFIG_AUFS_HNOTIFY */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DENTRY_H__ */ -diff --git a/fs/aufs/dinfo.c b/fs/aufs/dinfo.c -new file mode 100644 -index 000000000..7e56fe742 ---- /dev/null -+++ b/fs/aufs/dinfo.c -@@ -0,0 +1,554 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * dentry private data -+ */ -+ -+#include "aufs.h" -+ -+void au_di_init_once(void *_dinfo) -+{ -+ struct au_dinfo *dinfo = _dinfo; -+ -+ au_rw_init(&dinfo->di_rwsem); -+} -+ -+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc) -+{ -+ struct au_dinfo *dinfo; -+ int nbr, i; -+ -+ dinfo = au_cache_alloc_dinfo(); -+ if (unlikely(!dinfo)) -+ goto out; -+ -+ nbr = au_sbbot(sb) + 1; -+ if (nbr <= 0) -+ nbr = 1; -+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS); -+ if (dinfo->di_hdentry) { -+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc); -+ dinfo->di_btop = -1; -+ dinfo->di_bbot = -1; -+ dinfo->di_bwh = -1; -+ dinfo->di_bdiropq = -1; -+ dinfo->di_tmpfile = 0; -+ for (i = 0; i < nbr; i++) -+ dinfo->di_hdentry[i].hd_id = -1; -+ goto out; -+ } -+ -+ au_cache_free_dinfo(dinfo); -+ dinfo = NULL; -+ -+out: -+ return dinfo; -+} -+ -+void au_di_free(struct au_dinfo *dinfo) -+{ -+ struct au_hdentry *p; -+ aufs_bindex_t bbot, bindex; -+ -+ /* dentry may not be revalidated */ -+ bindex = dinfo->di_btop; -+ if (bindex >= 0) { -+ bbot = dinfo->di_bbot; -+ p = au_hdentry(dinfo, bindex); -+ while (bindex++ <= bbot) -+ au_hdput(p++); -+ } -+ kfree(dinfo->di_hdentry); -+ au_cache_free_dinfo(dinfo); -+} -+ -+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b) -+{ -+ struct au_hdentry *p; -+ aufs_bindex_t bi; -+ -+ AuRwMustWriteLock(&a->di_rwsem); -+ AuRwMustWriteLock(&b->di_rwsem); -+ -+#define DiSwap(v, name) \ -+ do { \ -+ v = a->di_##name; \ -+ a->di_##name = b->di_##name; \ -+ b->di_##name = v; \ -+ } while (0) -+ -+ DiSwap(p, hdentry); -+ DiSwap(bi, btop); -+ DiSwap(bi, bbot); -+ DiSwap(bi, bwh); -+ DiSwap(bi, bdiropq); -+ /* smp_mb(); */ -+ -+#undef DiSwap -+} -+ -+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src) -+{ -+ AuRwMustWriteLock(&dst->di_rwsem); -+ AuRwMustWriteLock(&src->di_rwsem); -+ -+ dst->di_btop = src->di_btop; -+ dst->di_bbot = src->di_bbot; -+ dst->di_bwh = src->di_bwh; -+ dst->di_bdiropq = src->di_bdiropq; -+ /* smp_mb(); */ -+} -+ -+int au_di_init(struct dentry *dentry) -+{ -+ int err; -+ struct super_block *sb; -+ struct au_dinfo *dinfo; -+ -+ err = 0; -+ sb = dentry->d_sb; -+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD); -+ if (dinfo) { -+ atomic_set(&dinfo->di_generation, au_sigen(sb)); -+ /* smp_mb(); */ /* atomic_set */ -+ dentry->d_fsdata = dinfo; -+ } else -+ err = -ENOMEM; -+ -+ return err; -+} -+ -+void au_di_fin(struct dentry *dentry) -+{ -+ struct au_dinfo *dinfo; -+ -+ dinfo = au_di(dentry); -+ AuRwDestroy(&dinfo->di_rwsem); -+ au_di_free(dinfo); -+} -+ -+int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink) -+{ -+ int err, sz; -+ struct au_hdentry *hdp; -+ -+ AuRwMustWriteLock(&dinfo->di_rwsem); -+ -+ err = -ENOMEM; -+ sz = sizeof(*hdp) * (dinfo->di_bbot + 1); -+ if (!sz) -+ sz = sizeof(*hdp); -+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS, -+ may_shrink); -+ if (hdp) { -+ dinfo->di_hdentry = hdp; -+ err = 0; -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void do_ii_write_lock(struct inode *inode, unsigned int lsc) -+{ -+ switch (lsc) { -+ case AuLsc_DI_CHILD: -+ ii_write_lock_child(inode); -+ break; -+ case AuLsc_DI_CHILD2: -+ ii_write_lock_child2(inode); -+ break; -+ case AuLsc_DI_CHILD3: -+ ii_write_lock_child3(inode); -+ break; -+ case AuLsc_DI_PARENT: -+ ii_write_lock_parent(inode); -+ break; -+ case AuLsc_DI_PARENT2: -+ ii_write_lock_parent2(inode); -+ break; -+ case AuLsc_DI_PARENT3: -+ ii_write_lock_parent3(inode); -+ break; -+ default: -+ BUG(); -+ } -+} -+ -+static void do_ii_read_lock(struct inode *inode, unsigned int lsc) -+{ -+ switch (lsc) { -+ case AuLsc_DI_CHILD: -+ ii_read_lock_child(inode); -+ break; -+ case AuLsc_DI_CHILD2: -+ ii_read_lock_child2(inode); -+ break; -+ case AuLsc_DI_CHILD3: -+ ii_read_lock_child3(inode); -+ break; -+ case AuLsc_DI_PARENT: -+ ii_read_lock_parent(inode); -+ break; -+ case AuLsc_DI_PARENT2: -+ ii_read_lock_parent2(inode); -+ break; -+ case AuLsc_DI_PARENT3: -+ ii_read_lock_parent3(inode); -+ break; -+ default: -+ BUG(); -+ } -+} -+ -+void di_read_lock(struct dentry *d, int flags, unsigned int lsc) -+{ -+ struct inode *inode; -+ -+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc); -+ if (d_really_is_positive(d)) { -+ inode = d_inode(d); -+ if (au_ftest_lock(flags, IW)) -+ do_ii_write_lock(inode, lsc); -+ else if (au_ftest_lock(flags, IR)) -+ do_ii_read_lock(inode, lsc); -+ } -+} -+ -+void di_read_unlock(struct dentry *d, int flags) -+{ -+ struct inode *inode; -+ -+ if (d_really_is_positive(d)) { -+ inode = d_inode(d); -+ if (au_ftest_lock(flags, IW)) { -+ au_dbg_verify_dinode(d); -+ ii_write_unlock(inode); -+ } else if (au_ftest_lock(flags, IR)) { -+ au_dbg_verify_dinode(d); -+ ii_read_unlock(inode); -+ } -+ } -+ au_rw_read_unlock(&au_di(d)->di_rwsem); -+} -+ -+void di_downgrade_lock(struct dentry *d, int flags) -+{ -+ if (d_really_is_positive(d) && au_ftest_lock(flags, IR)) -+ ii_downgrade_lock(d_inode(d)); -+ au_rw_dgrade_lock(&au_di(d)->di_rwsem); -+} -+ -+void di_write_lock(struct dentry *d, unsigned int lsc) -+{ -+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc); -+ if (d_really_is_positive(d)) -+ do_ii_write_lock(d_inode(d), lsc); -+} -+ -+void di_write_unlock(struct dentry *d) -+{ -+ au_dbg_verify_dinode(d); -+ if (d_really_is_positive(d)) -+ ii_write_unlock(d_inode(d)); -+ au_rw_write_unlock(&au_di(d)->di_rwsem); -+} -+ -+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir) -+{ -+ AuDebugOn(d1 == d2 -+ || d_inode(d1) == d_inode(d2) -+ || d1->d_sb != d2->d_sb); -+ -+ if ((isdir && au_test_subdir(d1, d2)) -+ || d1 < d2) { -+ di_write_lock_child(d1); -+ di_write_lock_child2(d2); -+ } else { -+ di_write_lock_child(d2); -+ di_write_lock_child2(d1); -+ } -+} -+ -+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir) -+{ -+ AuDebugOn(d1 == d2 -+ || d_inode(d1) == d_inode(d2) -+ || d1->d_sb != d2->d_sb); -+ -+ if ((isdir && au_test_subdir(d1, d2)) -+ || d1 < d2) { -+ di_write_lock_parent(d1); -+ di_write_lock_parent2(d2); -+ } else { -+ di_write_lock_parent(d2); -+ di_write_lock_parent2(d1); -+ } -+} -+ -+void di_write_unlock2(struct dentry *d1, struct dentry *d2) -+{ -+ di_write_unlock(d1); -+ if (d_inode(d1) == d_inode(d2)) -+ au_rw_write_unlock(&au_di(d2)->di_rwsem); -+ else -+ di_write_unlock(d2); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ struct dentry *d; -+ -+ DiMustAnyLock(dentry); -+ -+ if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry)) -+ return NULL; -+ AuDebugOn(bindex < 0); -+ d = au_hdentry(au_di(dentry), bindex)->hd_dentry; -+ AuDebugOn(d && au_dcount(d) <= 0); -+ return d; -+} -+ -+/* -+ * extended version of au_h_dptr(). -+ * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or -+ * error. -+ */ -+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ struct dentry *h_dentry; -+ struct inode *inode, *h_inode; -+ -+ AuDebugOn(d_really_is_negative(dentry)); -+ -+ h_dentry = NULL; -+ if (au_dbtop(dentry) <= bindex -+ && bindex <= au_dbbot(dentry)) -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry && !au_d_linkable(h_dentry)) { -+ dget(h_dentry); -+ goto out; /* success */ -+ } -+ -+ inode = d_inode(dentry); -+ AuDebugOn(bindex < au_ibtop(inode)); -+ AuDebugOn(au_ibbot(inode) < bindex); -+ h_inode = au_h_iptr(inode, bindex); -+ h_dentry = d_find_alias(h_inode); -+ if (h_dentry) { -+ if (!IS_ERR(h_dentry)) { -+ if (!au_d_linkable(h_dentry)) -+ goto out; /* success */ -+ dput(h_dentry); -+ } else -+ goto out; -+ } -+ -+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) { -+ h_dentry = au_plink_lkup(inode, bindex); -+ AuDebugOn(!h_dentry); -+ if (!IS_ERR(h_dentry)) { -+ if (!au_d_hashed_positive(h_dentry)) -+ goto out; /* success */ -+ dput(h_dentry); -+ h_dentry = NULL; -+ } -+ } -+ -+out: -+ AuDbgDentry(h_dentry); -+ return h_dentry; -+} -+ -+aufs_bindex_t au_dbtail(struct dentry *dentry) -+{ -+ aufs_bindex_t bbot, bwh; -+ -+ bbot = au_dbbot(dentry); -+ if (0 <= bbot) { -+ bwh = au_dbwh(dentry); -+ if (!bwh) -+ return bwh; -+ if (0 < bwh && bwh < bbot) -+ return bwh - 1; -+ } -+ return bbot; -+} -+ -+aufs_bindex_t au_dbtaildir(struct dentry *dentry) -+{ -+ aufs_bindex_t bbot, bopq; -+ -+ bbot = au_dbtail(dentry); -+ if (0 <= bbot) { -+ bopq = au_dbdiropq(dentry); -+ if (0 <= bopq && bopq < bbot) -+ bbot = bopq; -+ } -+ return bbot; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_dentry) -+{ -+ struct au_dinfo *dinfo; -+ struct au_hdentry *hd; -+ struct au_branch *br; -+ -+ DiMustWriteLock(dentry); -+ -+ dinfo = au_di(dentry); -+ hd = au_hdentry(dinfo, bindex); -+ au_hdput(hd); -+ hd->hd_dentry = h_dentry; -+ if (h_dentry) { -+ br = au_sbr(dentry->d_sb, bindex); -+ hd->hd_id = br->br_id; -+ } -+} -+ -+int au_dbrange_test(struct dentry *dentry) -+{ -+ int err; -+ aufs_bindex_t btop, bbot; -+ -+ err = 0; -+ btop = au_dbtop(dentry); -+ bbot = au_dbbot(dentry); -+ if (btop >= 0) -+ AuDebugOn(bbot < 0 && btop > bbot); -+ else { -+ err = -EIO; -+ AuDebugOn(bbot >= 0); -+ } -+ -+ return err; -+} -+ -+int au_digen_test(struct dentry *dentry, unsigned int sigen) -+{ -+ int err; -+ -+ err = 0; -+ if (unlikely(au_digen(dentry) != sigen -+ || au_iigen_test(d_inode(dentry), sigen))) -+ err = -EIO; -+ -+ return err; -+} -+ -+void au_update_digen(struct dentry *dentry) -+{ -+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb)); -+ /* smp_mb(); */ /* atomic_set */ -+} -+ -+void au_update_dbrange(struct dentry *dentry, int do_put_zero) -+{ -+ struct au_dinfo *dinfo; -+ struct dentry *h_d; -+ struct au_hdentry *hdp; -+ aufs_bindex_t bindex, bbot; -+ -+ DiMustWriteLock(dentry); -+ -+ dinfo = au_di(dentry); -+ if (!dinfo || dinfo->di_btop < 0) -+ return; -+ -+ if (do_put_zero) { -+ bbot = dinfo->di_bbot; -+ bindex = dinfo->di_btop; -+ hdp = au_hdentry(dinfo, bindex); -+ for (; bindex <= bbot; bindex++, hdp++) { -+ h_d = hdp->hd_dentry; -+ if (h_d && d_is_negative(h_d)) -+ au_set_h_dptr(dentry, bindex, NULL); -+ } -+ } -+ -+ dinfo->di_btop = 0; -+ hdp = au_hdentry(dinfo, dinfo->di_btop); -+ for (; dinfo->di_btop <= dinfo->di_bbot; dinfo->di_btop++, hdp++) -+ if (hdp->hd_dentry) -+ break; -+ if (dinfo->di_btop > dinfo->di_bbot) { -+ dinfo->di_btop = -1; -+ dinfo->di_bbot = -1; -+ return; -+ } -+ -+ hdp = au_hdentry(dinfo, dinfo->di_bbot); -+ for (; dinfo->di_bbot >= 0; dinfo->di_bbot--, hdp--) -+ if (hdp->hd_dentry) -+ break; -+ AuDebugOn(dinfo->di_btop > dinfo->di_bbot || dinfo->di_bbot < 0); -+} -+ -+void au_update_dbtop(struct dentry *dentry) -+{ -+ aufs_bindex_t bindex, bbot; -+ struct dentry *h_dentry; -+ -+ bbot = au_dbbot(dentry); -+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ if (d_is_positive(h_dentry)) { -+ au_set_dbtop(dentry, bindex); -+ return; -+ } -+ au_set_h_dptr(dentry, bindex, NULL); -+ } -+} -+ -+void au_update_dbbot(struct dentry *dentry) -+{ -+ aufs_bindex_t bindex, btop; -+ struct dentry *h_dentry; -+ -+ btop = au_dbtop(dentry); -+ for (bindex = au_dbbot(dentry); bindex >= btop; bindex--) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ if (d_is_positive(h_dentry)) { -+ au_set_dbbot(dentry, bindex); -+ return; -+ } -+ au_set_h_dptr(dentry, bindex, NULL); -+ } -+} -+ -+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry) -+{ -+ aufs_bindex_t bindex, bbot; -+ -+ bbot = au_dbbot(dentry); -+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) -+ if (au_h_dptr(dentry, bindex) == h_dentry) -+ return bindex; -+ return -1; -+} -diff --git a/fs/aufs/dir.c b/fs/aufs/dir.c -new file mode 100644 -index 000000000..48e067fe6 ---- /dev/null -+++ b/fs/aufs/dir.c -@@ -0,0 +1,762 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * directory operations -+ */ -+ -+#include -+#include "aufs.h" -+ -+void au_add_nlink(struct inode *dir, struct inode *h_dir) -+{ -+ unsigned int nlink; -+ -+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); -+ -+ nlink = dir->i_nlink; -+ nlink += h_dir->i_nlink - 2; -+ if (h_dir->i_nlink < 2) -+ nlink += 2; -+ smp_mb(); /* for i_nlink */ -+ /* 0 can happen in revaliding */ -+ set_nlink(dir, nlink); -+} -+ -+void au_sub_nlink(struct inode *dir, struct inode *h_dir) -+{ -+ unsigned int nlink; -+ -+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); -+ -+ nlink = dir->i_nlink; -+ nlink -= h_dir->i_nlink - 2; -+ if (h_dir->i_nlink < 2) -+ nlink -= 2; -+ smp_mb(); /* for i_nlink */ -+ /* nlink == 0 means the branch-fs is broken */ -+ set_nlink(dir, nlink); -+} -+ -+loff_t au_dir_size(struct file *file, struct dentry *dentry) -+{ -+ loff_t sz; -+ aufs_bindex_t bindex, bbot; -+ struct file *h_file; -+ struct dentry *h_dentry; -+ -+ sz = 0; -+ if (file) { -+ AuDebugOn(!d_is_dir(file->f_path.dentry)); -+ -+ bbot = au_fbbot_dir(file); -+ for (bindex = au_fbtop(file); -+ bindex <= bbot && sz < KMALLOC_MAX_SIZE; -+ bindex++) { -+ h_file = au_hf_dir(file, bindex); -+ if (h_file && file_inode(h_file)) -+ sz += vfsub_f_size_read(h_file); -+ } -+ } else { -+ AuDebugOn(!dentry); -+ AuDebugOn(!d_is_dir(dentry)); -+ -+ bbot = au_dbtaildir(dentry); -+ for (bindex = au_dbtop(dentry); -+ bindex <= bbot && sz < KMALLOC_MAX_SIZE; -+ bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry && d_is_positive(h_dentry)) -+ sz += i_size_read(d_inode(h_dentry)); -+ } -+ } -+ if (sz < KMALLOC_MAX_SIZE) -+ sz = roundup_pow_of_two(sz); -+ if (sz > KMALLOC_MAX_SIZE) -+ sz = KMALLOC_MAX_SIZE; -+ else if (sz < NAME_MAX) { -+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX); -+ sz = AUFS_RDBLK_DEF; -+ } -+ return sz; -+} -+ -+struct au_dir_ts_arg { -+ struct dentry *dentry; -+ aufs_bindex_t brid; -+}; -+ -+static void au_do_dir_ts(void *arg) -+{ -+ struct au_dir_ts_arg *a = arg; -+ struct au_dtime dt; -+ struct path h_path; -+ struct inode *dir, *h_dir; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_hinode *hdir; -+ int err; -+ aufs_bindex_t btop, bindex; -+ -+ sb = a->dentry->d_sb; -+ if (d_really_is_negative(a->dentry)) -+ goto out; -+ /* no dir->i_mutex lock */ -+ aufs_read_lock(a->dentry, AuLock_DW); /* noflush */ -+ -+ dir = d_inode(a->dentry); -+ btop = au_ibtop(dir); -+ bindex = au_br_index(sb, a->brid); -+ if (bindex < btop) -+ goto out_unlock; -+ -+ br = au_sbr(sb, bindex); -+ h_path.dentry = au_h_dptr(a->dentry, bindex); -+ if (!h_path.dentry) -+ goto out_unlock; -+ h_path.mnt = au_br_mnt(br); -+ au_dtime_store(&dt, a->dentry, &h_path); -+ -+ br = au_sbr(sb, btop); -+ if (!au_br_writable(br->br_perm)) -+ goto out_unlock; -+ h_path.dentry = au_h_dptr(a->dentry, btop); -+ h_path.mnt = au_br_mnt(br); -+ err = vfsub_mnt_want_write(h_path.mnt); -+ if (err) -+ goto out_unlock; -+ hdir = au_hi(dir, btop); -+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT); -+ h_dir = au_h_iptr(dir, btop); -+ if (h_dir->i_nlink -+ && timespec64_compare(&h_dir->i_mtime, &dt.dt_mtime) < 0) { -+ dt.dt_h_path = h_path; -+ au_dtime_revert(&dt); -+ } -+ au_hn_inode_unlock(hdir); -+ vfsub_mnt_drop_write(h_path.mnt); -+ au_cpup_attr_timesizes(dir); -+ -+out_unlock: -+ aufs_read_unlock(a->dentry, AuLock_DW); -+out: -+ dput(a->dentry); -+ au_nwt_done(&au_sbi(sb)->si_nowait); -+ kfree(arg); -+} -+ -+void au_dir_ts(struct inode *dir, aufs_bindex_t bindex) -+{ -+ int perm, wkq_err; -+ aufs_bindex_t btop; -+ struct au_dir_ts_arg *arg; -+ struct dentry *dentry; -+ struct super_block *sb; -+ -+ IMustLock(dir); -+ -+ dentry = d_find_any_alias(dir); -+ AuDebugOn(!dentry); -+ sb = dentry->d_sb; -+ btop = au_ibtop(dir); -+ if (btop == bindex) { -+ au_cpup_attr_timesizes(dir); -+ goto out; -+ } -+ -+ perm = au_sbr_perm(sb, btop); -+ if (!au_br_writable(perm)) -+ goto out; -+ -+ arg = kmalloc(sizeof(*arg), GFP_NOFS); -+ if (!arg) -+ goto out; -+ -+ arg->dentry = dget(dentry); /* will be dput-ted by au_do_dir_ts() */ -+ arg->brid = au_sbr_id(sb, bindex); -+ wkq_err = au_wkq_nowait(au_do_dir_ts, arg, sb, /*flags*/0); -+ if (unlikely(wkq_err)) { -+ pr_err("wkq %d\n", wkq_err); -+ dput(dentry); -+ kfree(arg); -+ } -+ -+out: -+ dput(dentry); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int reopen_dir(struct file *file) -+{ -+ int err; -+ unsigned int flags; -+ aufs_bindex_t bindex, btail, btop; -+ struct dentry *dentry, *h_dentry; -+ struct file *h_file; -+ -+ /* open all lower dirs */ -+ dentry = file->f_path.dentry; -+ btop = au_dbtop(dentry); -+ for (bindex = au_fbtop(file); bindex < btop; bindex++) -+ au_set_h_fptr(file, bindex, NULL); -+ au_set_fbtop(file, btop); -+ -+ btail = au_dbtaildir(dentry); -+ for (bindex = au_fbbot_dir(file); btail < bindex; bindex--) -+ au_set_h_fptr(file, bindex, NULL); -+ au_set_fbbot_dir(file, btail); -+ -+ flags = vfsub_file_flags(file); -+ for (bindex = btop; bindex <= btail; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ h_file = au_hf_dir(file, bindex); -+ if (h_file) -+ continue; -+ -+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; /* close all? */ -+ au_set_h_fptr(file, bindex, h_file); -+ } -+ au_update_figen(file); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ err = 0; -+ -+out: -+ return err; -+} -+ -+static int do_open_dir(struct file *file, int flags, struct file *h_file) -+{ -+ int err; -+ aufs_bindex_t bindex, btail; -+ struct dentry *dentry, *h_dentry; -+ struct vfsmount *mnt; -+ -+ FiMustWriteLock(file); -+ AuDebugOn(h_file); -+ -+ err = 0; -+ mnt = file->f_path.mnt; -+ dentry = file->f_path.dentry; -+ file->f_version = inode_query_iversion(d_inode(dentry)); -+ bindex = au_dbtop(dentry); -+ au_set_fbtop(file, bindex); -+ btail = au_dbtaildir(dentry); -+ au_set_fbbot_dir(file, btail); -+ for (; !err && bindex <= btail; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ -+ err = vfsub_test_mntns(mnt, h_dentry->d_sb); -+ if (unlikely(err)) -+ break; -+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0); -+ if (IS_ERR(h_file)) { -+ err = PTR_ERR(h_file); -+ break; -+ } -+ au_set_h_fptr(file, bindex, h_file); -+ } -+ au_update_figen(file); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ if (!err) -+ return 0; /* success */ -+ -+ /* close all */ -+ for (bindex = au_fbtop(file); bindex <= btail; bindex++) -+ au_set_h_fptr(file, bindex, NULL); -+ au_set_fbtop(file, -1); -+ au_set_fbbot_dir(file, -1); -+ -+ return err; -+} -+ -+static int aufs_open_dir(struct inode *inode __maybe_unused, -+ struct file *file) -+{ -+ int err; -+ struct super_block *sb; -+ struct au_fidir *fidir; -+ -+ err = -ENOMEM; -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ fidir = au_fidir_alloc(sb); -+ if (fidir) { -+ struct au_do_open_args args = { -+ .open = do_open_dir, -+ .fidir = fidir -+ }; -+ err = au_do_open(file, &args); -+ if (unlikely(err)) -+ kfree(fidir); -+ } -+ si_read_unlock(sb); -+ return err; -+} -+ -+static int aufs_release_dir(struct inode *inode __maybe_unused, -+ struct file *file) -+{ -+ struct au_vdir *vdir_cache; -+ struct au_finfo *finfo; -+ struct au_fidir *fidir; -+ struct au_hfile *hf; -+ aufs_bindex_t bindex, bbot; -+ -+ finfo = au_fi(file); -+ fidir = finfo->fi_hdir; -+ if (fidir) { -+ au_hbl_del(&finfo->fi_hlist, -+ &au_sbi(file->f_path.dentry->d_sb)->si_files); -+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */ -+ if (vdir_cache) -+ au_vdir_free(vdir_cache); -+ -+ bindex = finfo->fi_btop; -+ if (bindex >= 0) { -+ hf = fidir->fd_hfile + bindex; -+ /* -+ * calls fput() instead of filp_close(), -+ * since no dnotify or lock for the lower file. -+ */ -+ bbot = fidir->fd_bbot; -+ for (; bindex <= bbot; bindex++, hf++) -+ if (hf->hf_file) -+ au_hfput(hf, /*execed*/0); -+ } -+ kfree(fidir); -+ finfo->fi_hdir = NULL; -+ } -+ au_finfo_fin(file); -+ return 0; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_do_flush_dir(struct file *file, fl_owner_t id) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct file *h_file; -+ -+ err = 0; -+ bbot = au_fbbot_dir(file); -+ for (bindex = au_fbtop(file); !err && bindex <= bbot; bindex++) { -+ h_file = au_hf_dir(file, bindex); -+ if (h_file) -+ err = vfsub_flush(h_file, id); -+ } -+ return err; -+} -+ -+static int aufs_flush_dir(struct file *file, fl_owner_t id) -+{ -+ return au_do_flush(file, id, au_do_flush_dir); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync) -+{ -+ int err; -+ aufs_bindex_t bbot, bindex; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ err = 0; -+ sb = dentry->d_sb; -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ bbot = au_dbbot(dentry); -+ for (bindex = au_dbtop(dentry); !err && bindex <= bbot; bindex++) { -+ struct path h_path; -+ -+ if (au_test_ro(sb, bindex, inode)) -+ continue; -+ h_path.dentry = au_h_dptr(dentry, bindex); -+ if (!h_path.dentry) -+ continue; -+ -+ h_path.mnt = au_sbr_mnt(sb, bindex); -+ err = vfsub_fsync(NULL, &h_path, datasync); -+ } -+ -+ return err; -+} -+ -+static int au_do_fsync_dir(struct file *file, int datasync) -+{ -+ int err; -+ aufs_bindex_t bbot, bindex; -+ struct file *h_file; -+ struct super_block *sb; -+ struct inode *inode; -+ -+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*fi_lsc*/0); -+ if (unlikely(err)) -+ goto out; -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ bbot = au_fbbot_dir(file); -+ for (bindex = au_fbtop(file); !err && bindex <= bbot; bindex++) { -+ h_file = au_hf_dir(file, bindex); -+ if (!h_file || au_test_ro(sb, bindex, inode)) -+ continue; -+ -+ err = vfsub_fsync(h_file, &h_file->f_path, datasync); -+ } -+ -+out: -+ return err; -+} -+ -+/* -+ * @file may be NULL -+ */ -+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end, -+ int datasync) -+{ -+ int err; -+ struct dentry *dentry; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ err = 0; -+ dentry = file->f_path.dentry; -+ inode = d_inode(dentry); -+ inode_lock(inode); -+ sb = dentry->d_sb; -+ si_noflush_read_lock(sb); -+ if (file) -+ err = au_do_fsync_dir(file, datasync); -+ else { -+ di_write_lock_child(dentry); -+ err = au_do_fsync_dir_no_file(dentry, datasync); -+ } -+ au_cpup_attr_timesizes(inode); -+ di_write_unlock(dentry); -+ if (file) -+ fi_write_unlock(file); -+ -+ si_read_unlock(sb); -+ inode_unlock(inode); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int aufs_iterate_shared(struct file *file, struct dir_context *ctx) -+{ -+ int err; -+ struct dentry *dentry; -+ struct inode *inode, *h_inode; -+ struct super_block *sb; -+ -+ AuDbg("%pD, ctx{%ps, %llu}\n", file, ctx->actor, ctx->pos); -+ -+ dentry = file->f_path.dentry; -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ -+ sb = dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*fi_lsc*/0); -+ if (unlikely(err)) -+ goto out; -+ err = au_alive_dir(dentry); -+ if (!err) -+ err = au_vdir_init(file); -+ di_downgrade_lock(dentry, AuLock_IR); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ if (!au_test_nfsd()) { -+ err = au_vdir_fill_de(file, ctx); -+ fsstack_copy_attr_atime(inode, h_inode); -+ } else { -+ /* -+ * nfsd filldir may call lookup_one_len(), vfs_getattr(), -+ * encode_fh() and others. -+ */ -+ atomic_inc(&h_inode->i_count); -+ di_read_unlock(dentry, AuLock_IR); -+ si_read_unlock(sb); -+ err = au_vdir_fill_de(file, ctx); -+ fsstack_copy_attr_atime(inode, h_inode); -+ fi_write_unlock(file); -+ iput(h_inode); -+ -+ AuTraceErr(err); -+ return err; -+ } -+ -+out_unlock: -+ di_read_unlock(dentry, AuLock_IR); -+ fi_write_unlock(file); -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define AuTestEmpty_WHONLY 1 -+#define AuTestEmpty_CALLED (1 << 1) -+#define AuTestEmpty_SHWH (1 << 2) -+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name) -+#define au_fset_testempty(flags, name) \ -+ do { (flags) |= AuTestEmpty_##name; } while (0) -+#define au_fclr_testempty(flags, name) \ -+ do { (flags) &= ~AuTestEmpty_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_SHWH -+#undef AuTestEmpty_SHWH -+#define AuTestEmpty_SHWH 0 -+#endif -+ -+struct test_empty_arg { -+ struct dir_context ctx; -+ struct au_nhash *whlist; -+ unsigned int flags; -+ int err; -+ aufs_bindex_t bindex; -+}; -+ -+static int test_empty_cb(struct dir_context *ctx, const char *__name, -+ int namelen, loff_t offset __maybe_unused, u64 ino, -+ unsigned int d_type) -+{ -+ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg, -+ ctx); -+ char *name = (void *)__name; -+ -+ arg->err = 0; -+ au_fset_testempty(arg->flags, CALLED); -+ /* smp_mb(); */ -+ if (name[0] == '.' -+ && (namelen == 1 || (name[1] == '.' && namelen == 2))) -+ goto out; /* success */ -+ -+ if (namelen <= AUFS_WH_PFX_LEN -+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { -+ if (au_ftest_testempty(arg->flags, WHONLY) -+ && !au_nhash_test_known_wh(arg->whlist, name, namelen)) -+ arg->err = -ENOTEMPTY; -+ goto out; -+ } -+ -+ name += AUFS_WH_PFX_LEN; -+ namelen -= AUFS_WH_PFX_LEN; -+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen)) -+ arg->err = au_nhash_append_wh -+ (arg->whlist, name, namelen, ino, d_type, arg->bindex, -+ au_ftest_testempty(arg->flags, SHWH)); -+ -+out: -+ /* smp_mb(); */ -+ AuTraceErr(arg->err); -+ return arg->err; -+} -+ -+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg) -+{ -+ int err; -+ struct file *h_file; -+ struct au_branch *br; -+ -+ h_file = au_h_open(dentry, arg->bindex, -+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE, -+ /*file*/NULL, /*force_wr*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = 0; -+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE) -+ && !file_inode(h_file)->i_nlink) -+ goto out_put; -+ -+ do { -+ arg->err = 0; -+ au_fclr_testempty(arg->flags, CALLED); -+ /* smp_mb(); */ -+ err = vfsub_iterate_dir(h_file, &arg->ctx); -+ if (err >= 0) -+ err = arg->err; -+ } while (!err && au_ftest_testempty(arg->flags, CALLED)); -+ -+out_put: -+ fput(h_file); -+ br = au_sbr(dentry->d_sb, arg->bindex); -+ au_lcnt_dec(&br->br_nfiles); -+out: -+ return err; -+} -+ -+struct do_test_empty_args { -+ int *errp; -+ struct dentry *dentry; -+ struct test_empty_arg *arg; -+}; -+ -+static void call_do_test_empty(void *args) -+{ -+ struct do_test_empty_args *a = args; -+ *a->errp = do_test_empty(a->dentry, a->arg); -+} -+ -+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg) -+{ -+ int err, wkq_err; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ -+ h_dentry = au_h_dptr(dentry, arg->bindex); -+ h_inode = d_inode(h_dentry); -+ /* todo: i_mode changes anytime? */ -+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD); -+ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ); -+ inode_unlock_shared(h_inode); -+ if (!err) -+ err = do_test_empty(dentry, arg); -+ else { -+ struct do_test_empty_args args = { -+ .errp = &err, -+ .dentry = dentry, -+ .arg = arg -+ }; -+ unsigned int flags = arg->flags; -+ -+ wkq_err = au_wkq_wait(call_do_test_empty, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ arg->flags = flags; -+ } -+ -+ return err; -+} -+ -+int au_test_empty_lower(struct dentry *dentry) -+{ -+ int err; -+ unsigned int rdhash; -+ aufs_bindex_t bindex, btop, btail; -+ struct au_nhash whlist; -+ struct test_empty_arg arg = { -+ .ctx = { -+ .actor = test_empty_cb -+ } -+ }; -+ int (*test_empty)(struct dentry *dentry, struct test_empty_arg *arg); -+ -+ SiMustAnyLock(dentry->d_sb); -+ -+ rdhash = au_sbi(dentry->d_sb)->si_rdhash; -+ if (!rdhash) -+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry)); -+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ -+ arg.flags = 0; -+ arg.whlist = &whlist; -+ btop = au_dbtop(dentry); -+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)) -+ au_fset_testempty(arg.flags, SHWH); -+ test_empty = do_test_empty; -+ if (au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)) -+ test_empty = sio_test_empty; -+ arg.bindex = btop; -+ err = test_empty(dentry, &arg); -+ if (unlikely(err)) -+ goto out_whlist; -+ -+ au_fset_testempty(arg.flags, WHONLY); -+ btail = au_dbtaildir(dentry); -+ for (bindex = btop + 1; !err && bindex <= btail; bindex++) { -+ struct dentry *h_dentry; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry && d_is_positive(h_dentry)) { -+ arg.bindex = bindex; -+ err = test_empty(dentry, &arg); -+ } -+ } -+ -+out_whlist: -+ au_nhash_wh_free(&whlist); -+out: -+ return err; -+} -+ -+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist) -+{ -+ int err; -+ struct test_empty_arg arg = { -+ .ctx = { -+ .actor = test_empty_cb -+ } -+ }; -+ aufs_bindex_t bindex, btail; -+ -+ err = 0; -+ arg.whlist = whlist; -+ arg.flags = AuTestEmpty_WHONLY; -+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)) -+ au_fset_testempty(arg.flags, SHWH); -+ btail = au_dbtaildir(dentry); -+ for (bindex = au_dbtop(dentry); !err && bindex <= btail; bindex++) { -+ struct dentry *h_dentry; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry && d_is_positive(h_dentry)) { -+ arg.bindex = bindex; -+ err = sio_test_empty(dentry, &arg); -+ } -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+const struct file_operations aufs_dir_fop = { -+ .owner = THIS_MODULE, -+ .llseek = default_llseek, -+ .read = generic_read_dir, -+ .iterate_shared = aufs_iterate_shared, -+ .unlocked_ioctl = aufs_ioctl_dir, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = aufs_compat_ioctl_dir, -+#endif -+ .open = aufs_open_dir, -+ .release = aufs_release_dir, -+ .flush = aufs_flush_dir, -+ .fsync = aufs_fsync_dir -+}; -diff --git a/fs/aufs/dir.h b/fs/aufs/dir.h -new file mode 100644 -index 000000000..e7acabe09 ---- /dev/null -+++ b/fs/aufs/dir.h -@@ -0,0 +1,132 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * directory operations -+ */ -+ -+#ifndef __AUFS_DIR_H__ -+#define __AUFS_DIR_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* need to be faster and smaller */ -+ -+struct au_nhash { -+ unsigned int nh_num; -+ struct hlist_head *nh_head; -+}; -+ -+struct au_vdir_destr { -+ unsigned char len; -+ unsigned char name[0]; -+} __packed; -+ -+struct au_vdir_dehstr { -+ struct hlist_node hash; -+ struct au_vdir_destr *str; -+} ____cacheline_aligned_in_smp; -+ -+struct au_vdir_de { -+ ino_t de_ino; -+ unsigned char de_type; -+ /* caution: packed */ -+ struct au_vdir_destr de_str; -+} __packed; -+ -+struct au_vdir_wh { -+ struct hlist_node wh_hash; -+#ifdef CONFIG_AUFS_SHWH -+ ino_t wh_ino; -+ aufs_bindex_t wh_bindex; -+ unsigned char wh_type; -+#else -+ aufs_bindex_t wh_bindex; -+#endif -+ /* caution: packed */ -+ struct au_vdir_destr wh_str; -+} __packed; -+ -+union au_vdir_deblk_p { -+ unsigned char *deblk; -+ struct au_vdir_de *de; -+}; -+ -+struct au_vdir { -+ unsigned char **vd_deblk; -+ unsigned long vd_nblk; -+ struct { -+ unsigned long ul; -+ union au_vdir_deblk_p p; -+ } vd_last; -+ -+ u64 vd_version; -+ unsigned int vd_deblk_sz; -+ unsigned long vd_jiffy; -+} ____cacheline_aligned_in_smp; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* dir.c */ -+extern const struct file_operations aufs_dir_fop; -+void au_add_nlink(struct inode *dir, struct inode *h_dir); -+void au_sub_nlink(struct inode *dir, struct inode *h_dir); -+loff_t au_dir_size(struct file *file, struct dentry *dentry); -+void au_dir_ts(struct inode *dir, aufs_bindex_t bsrc); -+int au_test_empty_lower(struct dentry *dentry); -+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist); -+ -+/* vdir.c */ -+unsigned int au_rdhash_est(loff_t sz); -+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp); -+void au_nhash_wh_free(struct au_nhash *whlist); -+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, -+ int limit); -+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen); -+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino, -+ unsigned int d_type, aufs_bindex_t bindex, -+ unsigned char shwh); -+void au_vdir_free(struct au_vdir *vdir); -+int au_vdir_init(struct file *file); -+int au_vdir_fill_de(struct file *file, struct dir_context *ctx); -+ -+/* ioctl.c */ -+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg); -+ -+#ifdef CONFIG_AUFS_RDU -+/* rdu.c */ -+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -+#ifdef CONFIG_COMPAT -+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, -+ unsigned long arg); -+#endif -+#else -+AuStub(long, au_rdu_ioctl, return -EINVAL, struct file *file, -+ unsigned int cmd, unsigned long arg) -+#ifdef CONFIG_COMPAT -+AuStub(long, au_rdu_compat_ioctl, return -EINVAL, struct file *file, -+ unsigned int cmd, unsigned long arg) -+#endif -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DIR_H__ */ -diff --git a/fs/aufs/dirren.c b/fs/aufs/dirren.c -new file mode 100644 -index 000000000..85c77ad80 ---- /dev/null -+++ b/fs/aufs/dirren.c -@@ -0,0 +1,1316 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2017-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * special handling in renaming a directory -+ * in order to support looking-up the before-renamed name on the lower readonly -+ * branches -+ */ -+ -+#include -+#include "aufs.h" -+ -+static void au_dr_hino_del(struct au_dr_br *dr, struct au_dr_hino *ent) -+{ -+ int idx; -+ -+ idx = au_dr_ihash(ent->dr_h_ino); -+ au_hbl_del(&ent->dr_hnode, dr->dr_h_ino + idx); -+} -+ -+static int au_dr_hino_test_empty(struct au_dr_br *dr) -+{ -+ int ret, i; -+ struct hlist_bl_head *hbl; -+ -+ ret = 1; -+ for (i = 0; ret && i < AuDirren_NHASH; i++) { -+ hbl = dr->dr_h_ino + i; -+ hlist_bl_lock(hbl); -+ ret &= hlist_bl_empty(hbl); -+ hlist_bl_unlock(hbl); -+ } -+ -+ return ret; -+} -+ -+static struct au_dr_hino *au_dr_hino_find(struct au_dr_br *dr, ino_t ino) -+{ -+ struct au_dr_hino *found, *ent; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ int idx; -+ -+ found = NULL; -+ idx = au_dr_ihash(ino); -+ hbl = dr->dr_h_ino + idx; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(ent, pos, hbl, dr_hnode) -+ if (ent->dr_h_ino == ino) { -+ found = ent; -+ break; -+ } -+ hlist_bl_unlock(hbl); -+ -+ return found; -+} -+ -+int au_dr_hino_test_add(struct au_dr_br *dr, ino_t ino, -+ struct au_dr_hino *add_ent) -+{ -+ int found, idx; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ struct au_dr_hino *ent; -+ -+ found = 0; -+ idx = au_dr_ihash(ino); -+ hbl = dr->dr_h_ino + idx; -+#if 0 -+ { -+ struct hlist_bl_node *tmp; -+ -+ hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode) -+ AuDbg("hi%llu\n", (unsigned long long)ent->dr_h_ino); -+ } -+#endif -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(ent, pos, hbl, dr_hnode) -+ if (ent->dr_h_ino == ino) { -+ found = 1; -+ break; -+ } -+ if (!found && add_ent) -+ hlist_bl_add_head(&add_ent->dr_hnode, hbl); -+ hlist_bl_unlock(hbl); -+ -+ if (!found && add_ent) -+ AuDbg("i%llu added\n", (unsigned long long)add_ent->dr_h_ino); -+ -+ return found; -+} -+ -+void au_dr_hino_free(struct au_dr_br *dr) -+{ -+ int i; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos, *tmp; -+ struct au_dr_hino *ent; -+ -+ /* SiMustWriteLock(sb); */ -+ -+ for (i = 0; i < AuDirren_NHASH; i++) { -+ hbl = dr->dr_h_ino + i; -+ /* no spinlock since sbinfo must be write-locked */ -+ hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode) -+ kfree(ent); -+ INIT_HLIST_BL_HEAD(hbl); -+ } -+} -+ -+/* returns the number of inodes or an error */ -+static int au_dr_hino_store(struct super_block *sb, struct au_branch *br, -+ struct file *hinofile) -+{ -+ int err, i; -+ ssize_t ssz; -+ loff_t pos, oldsize; -+ __be64 u64; -+ struct inode *hinoinode; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *n1, *n2; -+ struct au_dr_hino *ent; -+ -+ SiMustWriteLock(sb); -+ AuDebugOn(!au_br_writable(br->br_perm)); -+ -+ hinoinode = file_inode(hinofile); -+ oldsize = i_size_read(hinoinode); -+ -+ err = 0; -+ pos = 0; -+ hbl = br->br_dirren.dr_h_ino; -+ for (i = 0; !err && i < AuDirren_NHASH; i++, hbl++) { -+ /* no bit-lock since sbinfo must be write-locked */ -+ hlist_bl_for_each_entry_safe(ent, n1, n2, hbl, dr_hnode) { -+ AuDbg("hi%llu, %pD2\n", -+ (unsigned long long)ent->dr_h_ino, hinofile); -+ u64 = cpu_to_be64(ent->dr_h_ino); -+ ssz = vfsub_write_k(hinofile, &u64, sizeof(u64), &pos); -+ if (ssz == sizeof(u64)) -+ continue; -+ -+ /* write error */ -+ pr_err("ssz %zd, %pD2\n", ssz, hinofile); -+ err = -ENOSPC; -+ if (ssz < 0) -+ err = ssz; -+ break; -+ } -+ } -+ /* regardless the error */ -+ if (pos < oldsize) { -+ err = vfsub_trunc(&hinofile->f_path, pos, /*attr*/0, hinofile); -+ AuTraceErr(err); -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_dr_hino_load(struct au_dr_br *dr, struct file *hinofile) -+{ -+ int err, hidx; -+ ssize_t ssz; -+ size_t sz, n; -+ loff_t pos; -+ uint64_t u64; -+ struct au_dr_hino *ent; -+ struct inode *hinoinode; -+ struct hlist_bl_head *hbl; -+ -+ err = 0; -+ pos = 0; -+ hbl = dr->dr_h_ino; -+ hinoinode = file_inode(hinofile); -+ sz = i_size_read(hinoinode); -+ AuDebugOn(sz % sizeof(u64)); -+ n = sz / sizeof(u64); -+ while (n--) { -+ ssz = vfsub_read_k(hinofile, &u64, sizeof(u64), &pos); -+ if (unlikely(ssz != sizeof(u64))) { -+ pr_err("ssz %zd, %pD2\n", ssz, hinofile); -+ err = -EINVAL; -+ if (ssz < 0) -+ err = ssz; -+ goto out_free; -+ } -+ -+ ent = kmalloc(sizeof(*ent), GFP_NOFS); -+ if (!ent) { -+ err = -ENOMEM; -+ AuTraceErr(err); -+ goto out_free; -+ } -+ ent->dr_h_ino = be64_to_cpu((__force __be64)u64); -+ AuDbg("hi%llu, %pD2\n", -+ (unsigned long long)ent->dr_h_ino, hinofile); -+ hidx = au_dr_ihash(ent->dr_h_ino); -+ au_hbl_add(&ent->dr_hnode, hbl + hidx); -+ } -+ goto out; /* success */ -+ -+out_free: -+ au_dr_hino_free(dr); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * @bindex/@br is a switch to distinguish whether suspending hnotify or not. -+ * @path is a switch to distinguish load and store. -+ */ -+static int au_dr_hino(struct super_block *sb, aufs_bindex_t bindex, -+ struct au_branch *br, const struct path *path) -+{ -+ int err, flags; -+ unsigned char load, suspend; -+ struct file *hinofile; -+ struct au_hinode *hdir; -+ struct inode *dir, *delegated; -+ struct path hinopath; -+ struct qstr hinoname = QSTR_INIT(AUFS_WH_DR_BRHINO, -+ sizeof(AUFS_WH_DR_BRHINO) - 1); -+ -+ AuDebugOn(bindex < 0 && !br); -+ AuDebugOn(bindex >= 0 && br); -+ -+ err = -EINVAL; -+ suspend = !br; -+ if (suspend) -+ br = au_sbr(sb, bindex); -+ load = !!path; -+ if (!load) { -+ path = &br->br_path; -+ AuDebugOn(!au_br_writable(br->br_perm)); -+ if (unlikely(!au_br_writable(br->br_perm))) -+ goto out; -+ } -+ -+ hdir = NULL; -+ if (suspend) { -+ dir = d_inode(sb->s_root); -+ hdir = au_hinode(au_ii(dir), bindex); -+ dir = hdir->hi_inode; -+ au_hn_inode_lock_nested(hdir, AuLsc_I_CHILD); -+ } else { -+ dir = d_inode(path->dentry); -+ inode_lock_nested(dir, AuLsc_I_CHILD); -+ } -+ hinopath.dentry = vfsub_lkup_one(&hinoname, path->dentry); -+ err = PTR_ERR(hinopath.dentry); -+ if (IS_ERR(hinopath.dentry)) -+ goto out_unlock; -+ -+ err = 0; -+ flags = O_RDONLY; -+ if (load) { -+ if (d_is_negative(hinopath.dentry)) -+ goto out_dput; /* success */ -+ } else { -+ if (au_dr_hino_test_empty(&br->br_dirren)) { -+ if (d_is_positive(hinopath.dentry)) { -+ delegated = NULL; -+ err = vfsub_unlink(dir, &hinopath, &delegated, -+ /*force*/0); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ pr_err("ignored err %d, %pd2\n", -+ err, hinopath.dentry); -+ if (unlikely(err == -EWOULDBLOCK)) -+ iput(delegated); -+ err = 0; -+ } -+ goto out_dput; -+ } else if (!d_is_positive(hinopath.dentry)) { -+ err = vfsub_create(dir, &hinopath, 0600, -+ /*want_excl*/false); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out_dput; -+ } -+ flags = O_WRONLY; -+ } -+ hinopath.mnt = path->mnt; -+ hinofile = vfsub_dentry_open(&hinopath, flags); -+ if (suspend) -+ au_hn_inode_unlock(hdir); -+ else -+ inode_unlock(dir); -+ dput(hinopath.dentry); -+ AuTraceErrPtr(hinofile); -+ if (IS_ERR(hinofile)) { -+ err = PTR_ERR(hinofile); -+ goto out; -+ } -+ -+ if (load) -+ err = au_dr_hino_load(&br->br_dirren, hinofile); -+ else -+ err = au_dr_hino_store(sb, br, hinofile); -+ fput(hinofile); -+ goto out; -+ -+out_dput: -+ dput(hinopath.dentry); -+out_unlock: -+ if (suspend) -+ au_hn_inode_unlock(hdir); -+ else -+ inode_unlock(dir); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_dr_brid_init(struct au_dr_brid *brid, const struct path *path) -+{ -+ int err; -+ struct kstatfs kstfs; -+ dev_t dev; -+ struct dentry *dentry; -+ struct super_block *sb; -+ -+ err = vfs_statfs((void *)path, &kstfs); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out; -+ -+ /* todo: support for UUID */ -+ -+ if (kstfs.f_fsid.val[0] || kstfs.f_fsid.val[1]) { -+ brid->type = AuBrid_FSID; -+ brid->fsid = kstfs.f_fsid; -+ } else { -+ dentry = path->dentry; -+ sb = dentry->d_sb; -+ dev = sb->s_dev; -+ if (dev) { -+ brid->type = AuBrid_DEV; -+ brid->dev = dev; -+ } -+ } -+ -+out: -+ return err; -+} -+ -+int au_dr_br_init(struct super_block *sb, struct au_branch *br, -+ const struct path *path) -+{ -+ int err, i; -+ struct au_dr_br *dr; -+ struct hlist_bl_head *hbl; -+ -+ dr = &br->br_dirren; -+ hbl = dr->dr_h_ino; -+ for (i = 0; i < AuDirren_NHASH; i++, hbl++) -+ INIT_HLIST_BL_HEAD(hbl); -+ -+ err = au_dr_brid_init(&dr->dr_brid, path); -+ if (unlikely(err)) -+ goto out; -+ -+ if (au_opt_test(au_mntflags(sb), DIRREN)) -+ err = au_dr_hino(sb, /*bindex*/-1, br, path); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_dr_br_fin(struct super_block *sb, struct au_branch *br) -+{ -+ int err; -+ -+ err = 0; -+ if (au_br_writable(br->br_perm)) -+ err = au_dr_hino(sb, /*bindex*/-1, br, /*path*/NULL); -+ if (!err) -+ au_dr_hino_free(&br->br_dirren); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_brid_str(struct au_dr_brid *brid, struct inode *h_inode, -+ char *buf, size_t sz) -+{ -+ int err; -+ unsigned int major, minor; -+ char *p; -+ -+ p = buf; -+ err = snprintf(p, sz, "%d_", brid->type); -+ AuDebugOn(err > sz); -+ p += err; -+ sz -= err; -+ switch (brid->type) { -+ case AuBrid_Unset: -+ return -EINVAL; -+ case AuBrid_UUID: -+ err = snprintf(p, sz, "%pU", brid->uuid.b); -+ break; -+ case AuBrid_FSID: -+ err = snprintf(p, sz, "%08x-%08x", -+ brid->fsid.val[0], brid->fsid.val[1]); -+ break; -+ case AuBrid_DEV: -+ major = MAJOR(brid->dev); -+ minor = MINOR(brid->dev); -+ if (major <= 0xff && minor <= 0xff) -+ err = snprintf(p, sz, "%02x%02x", major, minor); -+ else -+ err = snprintf(p, sz, "%03x:%05x", major, minor); -+ break; -+ } -+ AuDebugOn(err > sz); -+ p += err; -+ sz -= err; -+ err = snprintf(p, sz, "_%llu", (unsigned long long)h_inode->i_ino); -+ AuDebugOn(err > sz); -+ p += err; -+ sz -= err; -+ -+ return p - buf; -+} -+ -+static int au_drinfo_name(struct au_branch *br, char *name, int len) -+{ -+ int rlen; -+ struct dentry *br_dentry; -+ struct inode *br_inode; -+ -+ br_dentry = au_br_dentry(br); -+ br_inode = d_inode(br_dentry); -+ rlen = au_brid_str(&br->br_dirren.dr_brid, br_inode, name, len); -+ AuDebugOn(rlen >= AUFS_DIRREN_ENV_VAL_SZ); -+ AuDebugOn(rlen > len); -+ -+ return rlen; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * from the given @h_dentry, construct drinfo at @*fdata. -+ * when the size of @*fdata is not enough, reallocate and return new @fdata and -+ * @allocated. -+ */ -+static int au_drinfo_construct(struct au_drinfo_fdata **fdata, -+ struct dentry *h_dentry, -+ unsigned char *allocated) -+{ -+ int err, v; -+ struct au_drinfo_fdata *f, *p; -+ struct au_drinfo *drinfo; -+ struct inode *h_inode; -+ struct qstr *qname; -+ -+ err = 0; -+ f = *fdata; -+ h_inode = d_inode(h_dentry); -+ qname = &h_dentry->d_name; -+ drinfo = &f->drinfo; -+ drinfo->ino = (__force uint64_t)cpu_to_be64(h_inode->i_ino); -+ drinfo->oldnamelen = qname->len; -+ if (*allocated < sizeof(*f) + qname->len) { -+ v = roundup_pow_of_two(*allocated + qname->len); -+ p = au_krealloc(f, v, GFP_NOFS, /*may_shrink*/0); -+ if (unlikely(!p)) { -+ err = -ENOMEM; -+ AuTraceErr(err); -+ goto out; -+ } -+ f = p; -+ *fdata = f; -+ *allocated = v; -+ drinfo = &f->drinfo; -+ } -+ memcpy(drinfo->oldname, qname->name, qname->len); -+ AuDbg("i%llu, %.*s\n", -+ be64_to_cpu((__force __be64)drinfo->ino), drinfo->oldnamelen, -+ drinfo->oldname); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* callers have to free the return value */ -+static struct au_drinfo *au_drinfo_read_k(struct file *file, ino_t h_ino) -+{ -+ struct au_drinfo *ret, *drinfo; -+ struct au_drinfo_fdata fdata; -+ int len; -+ loff_t pos; -+ ssize_t ssz; -+ -+ ret = ERR_PTR(-EIO); -+ pos = 0; -+ ssz = vfsub_read_k(file, &fdata, sizeof(fdata), &pos); -+ if (unlikely(ssz != sizeof(fdata))) { -+ AuIOErr("ssz %zd, %u, %pD2\n", -+ ssz, (unsigned int)sizeof(fdata), file); -+ goto out; -+ } -+ -+ fdata.magic = ntohl((__force __be32)fdata.magic); -+ switch (fdata.magic) { -+ case AUFS_DRINFO_MAGIC_V1: -+ break; -+ default: -+ AuIOErr("magic-num 0x%x, 0x%x, %pD2\n", -+ fdata.magic, AUFS_DRINFO_MAGIC_V1, file); -+ goto out; -+ } -+ -+ drinfo = &fdata.drinfo; -+ len = drinfo->oldnamelen; -+ if (!len) { -+ AuIOErr("broken drinfo %pD2\n", file); -+ goto out; -+ } -+ -+ ret = NULL; -+ drinfo->ino = be64_to_cpu((__force __be64)drinfo->ino); -+ if (unlikely(h_ino && drinfo->ino != h_ino)) { -+ AuDbg("ignored i%llu, i%llu, %pD2\n", -+ (unsigned long long)drinfo->ino, -+ (unsigned long long)h_ino, file); -+ goto out; /* success */ -+ } -+ -+ ret = kmalloc(sizeof(*ret) + len, GFP_NOFS); -+ if (unlikely(!ret)) { -+ ret = ERR_PTR(-ENOMEM); -+ AuTraceErrPtr(ret); -+ goto out; -+ } -+ -+ *ret = *drinfo; -+ ssz = vfsub_read_k(file, (void *)ret->oldname, len, &pos); -+ if (unlikely(ssz != len)) { -+ kfree(ret); -+ ret = ERR_PTR(-EIO); -+ AuIOErr("ssz %zd, %u, %pD2\n", ssz, len, file); -+ goto out; -+ } -+ -+ AuDbg("oldname %.*s\n", ret->oldnamelen, ret->oldname); -+ -+out: -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* in order to be revertible */ -+struct au_drinfo_rev_elm { -+ int created; -+ struct dentry *info_dentry; -+ struct au_drinfo *info_last; -+}; -+ -+struct au_drinfo_rev { -+ unsigned char already; -+ aufs_bindex_t nelm; -+ struct au_drinfo_rev_elm elm[0]; -+}; -+ -+/* todo: isn't it too large? */ -+struct au_drinfo_store { -+ struct path h_ppath; -+ struct dentry *h_dentry; -+ struct au_drinfo_fdata *fdata; -+ char *infoname; /* inside of whname, just after PFX */ -+ char whname[sizeof(AUFS_WH_DR_INFO_PFX) + AUFS_DIRREN_ENV_VAL_SZ]; -+ aufs_bindex_t btgt, btail; -+ unsigned char no_sio, -+ allocated, /* current size of *fdata */ -+ infonamelen, /* room size for p */ -+ whnamelen, /* length of the generated name */ -+ renameback; /* renamed back */ -+}; -+ -+/* on rename(2) error, the caller should revert it using @elm */ -+static int au_drinfo_do_store(struct au_drinfo_store *w, -+ struct au_drinfo_rev_elm *elm) -+{ -+ int err, len; -+ ssize_t ssz; -+ loff_t pos; -+ struct path infopath = { -+ .mnt = w->h_ppath.mnt -+ }; -+ struct inode *h_dir, *h_inode, *delegated; -+ struct file *infofile; -+ struct qstr *qname; -+ -+ AuDebugOn(elm -+ && memcmp(elm, page_address(ZERO_PAGE(0)), sizeof(*elm))); -+ -+ infopath.dentry = vfsub_lookup_one_len(w->whname, w->h_ppath.dentry, -+ w->whnamelen); -+ AuTraceErrPtr(infopath.dentry); -+ if (IS_ERR(infopath.dentry)) { -+ err = PTR_ERR(infopath.dentry); -+ goto out; -+ } -+ -+ err = 0; -+ h_dir = d_inode(w->h_ppath.dentry); -+ if (elm && d_is_negative(infopath.dentry)) { -+ err = vfsub_create(h_dir, &infopath, 0600, /*want_excl*/true); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out_dput; -+ elm->created = 1; -+ elm->info_dentry = dget(infopath.dentry); -+ } -+ -+ infofile = vfsub_dentry_open(&infopath, O_RDWR); -+ AuTraceErrPtr(infofile); -+ if (IS_ERR(infofile)) { -+ err = PTR_ERR(infofile); -+ goto out_dput; -+ } -+ -+ h_inode = d_inode(infopath.dentry); -+ if (elm && i_size_read(h_inode)) { -+ h_inode = d_inode(w->h_dentry); -+ elm->info_last = au_drinfo_read_k(infofile, h_inode->i_ino); -+ AuTraceErrPtr(elm->info_last); -+ if (IS_ERR(elm->info_last)) { -+ err = PTR_ERR(elm->info_last); -+ elm->info_last = NULL; -+ AuDebugOn(elm->info_dentry); -+ goto out_fput; -+ } -+ } -+ -+ if (elm && w->renameback) { -+ delegated = NULL; -+ err = vfsub_unlink(h_dir, &infopath, &delegated, /*force*/0); -+ AuTraceErr(err); -+ if (unlikely(err == -EWOULDBLOCK)) -+ iput(delegated); -+ goto out_fput; -+ } -+ -+ pos = 0; -+ qname = &w->h_dentry->d_name; -+ len = sizeof(*w->fdata) + qname->len; -+ if (!elm) -+ len = sizeof(*w->fdata) + w->fdata->drinfo.oldnamelen; -+ ssz = vfsub_write_k(infofile, w->fdata, len, &pos); -+ if (ssz == len) { -+ AuDbg("hi%llu, %.*s\n", w->fdata->drinfo.ino, -+ w->fdata->drinfo.oldnamelen, w->fdata->drinfo.oldname); -+ goto out_fput; /* success */ -+ } else { -+ err = -EIO; -+ if (ssz < 0) -+ err = ssz; -+ /* the caller should revert it using @elm */ -+ } -+ -+out_fput: -+ fput(infofile); -+out_dput: -+ dput(infopath.dentry); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+struct au_call_drinfo_do_store_args { -+ int *errp; -+ struct au_drinfo_store *w; -+ struct au_drinfo_rev_elm *elm; -+}; -+ -+static void au_call_drinfo_do_store(void *args) -+{ -+ struct au_call_drinfo_do_store_args *a = args; -+ -+ *a->errp = au_drinfo_do_store(a->w, a->elm); -+} -+ -+static int au_drinfo_store_sio(struct au_drinfo_store *w, -+ struct au_drinfo_rev_elm *elm) -+{ -+ int err, wkq_err; -+ -+ if (w->no_sio) -+ err = au_drinfo_do_store(w, elm); -+ else { -+ struct au_call_drinfo_do_store_args a = { -+ .errp = &err, -+ .w = w, -+ .elm = elm -+ }; -+ wkq_err = au_wkq_wait(au_call_drinfo_do_store, &a); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ AuTraceErr(err); -+ -+ return err; -+} -+ -+static int au_drinfo_store_work_init(struct au_drinfo_store *w, -+ aufs_bindex_t btgt) -+{ -+ int err; -+ -+ memset(w, 0, sizeof(*w)); -+ w->allocated = roundup_pow_of_two(sizeof(*w->fdata) + 40); -+ strcpy(w->whname, AUFS_WH_DR_INFO_PFX); -+ w->infoname = w->whname + sizeof(AUFS_WH_DR_INFO_PFX) - 1; -+ w->infonamelen = sizeof(w->whname) - sizeof(AUFS_WH_DR_INFO_PFX); -+ w->btgt = btgt; -+ w->no_sio = !!uid_eq(current_fsuid(), GLOBAL_ROOT_UID); -+ -+ err = -ENOMEM; -+ w->fdata = kcalloc(1, w->allocated, GFP_NOFS); -+ if (unlikely(!w->fdata)) { -+ AuTraceErr(err); -+ goto out; -+ } -+ w->fdata->magic = (__force uint32_t)htonl(AUFS_DRINFO_MAGIC_V1); -+ err = 0; -+ -+out: -+ return err; -+} -+ -+static void au_drinfo_store_work_fin(struct au_drinfo_store *w) -+{ -+ kfree(w->fdata); -+} -+ -+static void au_drinfo_store_rev(struct au_drinfo_rev *rev, -+ struct au_drinfo_store *w) -+{ -+ struct au_drinfo_rev_elm *elm; -+ struct inode *h_dir, *delegated; -+ int err, nelm; -+ struct path infopath = { -+ .mnt = w->h_ppath.mnt -+ }; -+ -+ h_dir = d_inode(w->h_ppath.dentry); -+ IMustLock(h_dir); -+ -+ err = 0; -+ elm = rev->elm; -+ for (nelm = rev->nelm; nelm > 0; nelm--, elm++) { -+ AuDebugOn(elm->created && elm->info_last); -+ if (elm->created) { -+ AuDbg("here\n"); -+ delegated = NULL; -+ infopath.dentry = elm->info_dentry; -+ err = vfsub_unlink(h_dir, &infopath, &delegated, -+ !w->no_sio); -+ AuTraceErr(err); -+ if (unlikely(err == -EWOULDBLOCK)) -+ iput(delegated); -+ dput(elm->info_dentry); -+ } else if (elm->info_last) { -+ AuDbg("here\n"); -+ w->fdata->drinfo = *elm->info_last; -+ memcpy(w->fdata->drinfo.oldname, -+ elm->info_last->oldname, -+ elm->info_last->oldnamelen); -+ err = au_drinfo_store_sio(w, /*elm*/NULL); -+ kfree(elm->info_last); -+ } -+ if (unlikely(err)) -+ AuIOErr("%d, %s\n", err, w->whname); -+ /* go on even if err */ -+ } -+} -+ -+/* caller has to call au_dr_rename_fin() later */ -+static int au_drinfo_store(struct dentry *dentry, aufs_bindex_t btgt, -+ struct qstr *dst_name, void *_rev) -+{ -+ int err, sz, nelm; -+ aufs_bindex_t bindex, btail; -+ struct au_drinfo_store work; -+ struct au_drinfo_rev *rev, **p; -+ struct au_drinfo_rev_elm *elm; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_hinode *hdir; -+ -+ err = au_drinfo_store_work_init(&work, btgt); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out; -+ -+ err = -ENOMEM; -+ btail = au_dbtaildir(dentry); -+ nelm = btail - btgt; -+ sz = sizeof(*rev) + sizeof(*elm) * nelm; -+ rev = kcalloc(1, sz, GFP_NOFS); -+ if (unlikely(!rev)) { -+ AuTraceErr(err); -+ goto out_args; -+ } -+ rev->nelm = nelm; -+ elm = rev->elm; -+ p = _rev; -+ *p = rev; -+ -+ err = 0; -+ sb = dentry->d_sb; -+ work.h_ppath.dentry = au_h_dptr(dentry, btgt); -+ work.h_ppath.mnt = au_sbr_mnt(sb, btgt); -+ hdir = au_hi(d_inode(dentry), btgt); -+ au_hn_inode_lock_nested(hdir, AuLsc_I_CHILD); -+ for (bindex = btgt + 1; bindex <= btail; bindex++, elm++) { -+ work.h_dentry = au_h_dptr(dentry, bindex); -+ if (!work.h_dentry) -+ continue; -+ -+ err = au_drinfo_construct(&work.fdata, work.h_dentry, -+ &work.allocated); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ break; -+ -+ work.renameback = au_qstreq(&work.h_dentry->d_name, dst_name); -+ br = au_sbr(sb, bindex); -+ work.whnamelen = sizeof(AUFS_WH_DR_INFO_PFX) - 1; -+ work.whnamelen += au_drinfo_name(br, work.infoname, -+ work.infonamelen); -+ AuDbg("whname %.*s, i%llu, %.*s\n", -+ work.whnamelen, work.whname, -+ be64_to_cpu((__force __be64)work.fdata->drinfo.ino), -+ work.fdata->drinfo.oldnamelen, -+ work.fdata->drinfo.oldname); -+ -+ err = au_drinfo_store_sio(&work, elm); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ break; -+ } -+ if (unlikely(err)) { -+ /* revert all drinfo */ -+ au_drinfo_store_rev(rev, &work); -+ kfree(rev); -+ *p = NULL; -+ } -+ au_hn_inode_unlock(hdir); -+ -+out_args: -+ au_drinfo_store_work_fin(&work); -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_dr_rename(struct dentry *src, aufs_bindex_t bindex, -+ struct qstr *dst_name, void *_rev) -+{ -+ int err, already; -+ ino_t ino; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_dr_br *dr; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ struct au_dr_hino *ent; -+ struct au_drinfo_rev *rev, **p; -+ -+ AuDbg("bindex %d\n", bindex); -+ -+ err = -ENOMEM; -+ ent = kmalloc(sizeof(*ent), GFP_NOFS); -+ if (unlikely(!ent)) -+ goto out; -+ -+ sb = src->d_sb; -+ br = au_sbr(sb, bindex); -+ dr = &br->br_dirren; -+ h_dentry = au_h_dptr(src, bindex); -+ h_inode = d_inode(h_dentry); -+ ino = h_inode->i_ino; -+ ent->dr_h_ino = ino; -+ already = au_dr_hino_test_add(dr, ino, ent); -+ AuDbg("b%d, hi%llu, already %d\n", -+ bindex, (unsigned long long)ino, already); -+ -+ err = au_drinfo_store(src, bindex, dst_name, _rev); -+ AuTraceErr(err); -+ if (!err) { -+ p = _rev; -+ rev = *p; -+ rev->already = already; -+ goto out; /* success */ -+ } -+ -+ /* revert */ -+ if (!already) -+ au_dr_hino_del(dr, ent); -+ kfree(ent); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *_rev) -+{ -+ struct au_drinfo_rev *rev; -+ struct au_drinfo_rev_elm *elm; -+ int nelm; -+ -+ rev = _rev; -+ elm = rev->elm; -+ for (nelm = rev->nelm; nelm > 0; nelm--, elm++) { -+ dput(elm->info_dentry); -+ kfree(elm->info_last); -+ } -+ kfree(rev); -+} -+ -+void au_dr_rename_rev(struct dentry *src, aufs_bindex_t btgt, void *_rev) -+{ -+ int err; -+ struct au_drinfo_store work; -+ struct au_drinfo_rev *rev = _rev; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct inode *h_inode; -+ struct au_dr_br *dr; -+ struct au_dr_hino *ent; -+ -+ err = au_drinfo_store_work_init(&work, btgt); -+ if (unlikely(err)) -+ goto out; -+ -+ sb = src->d_sb; -+ br = au_sbr(sb, btgt); -+ work.h_ppath.dentry = au_h_dptr(src, btgt); -+ work.h_ppath.mnt = au_br_mnt(br); -+ au_drinfo_store_rev(rev, &work); -+ au_drinfo_store_work_fin(&work); -+ if (rev->already) -+ goto out; -+ -+ dr = &br->br_dirren; -+ h_inode = d_inode(work.h_ppath.dentry); -+ ent = au_dr_hino_find(dr, h_inode->i_ino); -+ BUG_ON(!ent); -+ au_dr_hino_del(dr, ent); -+ kfree(ent); -+ -+out: -+ kfree(rev); -+ if (unlikely(err)) -+ pr_err("failed to remove dirren info\n"); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct au_drinfo *au_drinfo_do_load(struct path *h_ppath, -+ char *whname, int whnamelen, -+ struct dentry **info_dentry) -+{ -+ struct au_drinfo *drinfo; -+ struct file *f; -+ struct inode *h_dir; -+ struct path infopath; -+ int unlocked; -+ -+ AuDbg("%pd/%.*s\n", h_ppath->dentry, whnamelen, whname); -+ -+ *info_dentry = NULL; -+ drinfo = NULL; -+ unlocked = 0; -+ h_dir = d_inode(h_ppath->dentry); -+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT); -+ infopath.dentry = vfsub_lookup_one_len(whname, h_ppath->dentry, -+ whnamelen); -+ if (IS_ERR(infopath.dentry)) { -+ drinfo = (void *)infopath.dentry; -+ goto out; -+ } -+ -+ if (d_is_negative(infopath.dentry)) -+ goto out_dput; /* success */ -+ -+ infopath.mnt = h_ppath->mnt; -+ f = vfsub_dentry_open(&infopath, O_RDONLY); -+ inode_unlock_shared(h_dir); -+ unlocked = 1; -+ if (IS_ERR(f)) { -+ drinfo = (void *)f; -+ goto out_dput; -+ } -+ -+ drinfo = au_drinfo_read_k(f, /*h_ino*/0); -+ if (IS_ERR_OR_NULL(drinfo)) -+ goto out_fput; -+ -+ AuDbg("oldname %.*s\n", drinfo->oldnamelen, drinfo->oldname); -+ *info_dentry = dget(infopath.dentry); /* keep it alive */ -+ -+out_fput: -+ fput(f); -+out_dput: -+ dput(infopath.dentry); -+out: -+ if (!unlocked) -+ inode_unlock_shared(h_dir); -+ AuTraceErrPtr(drinfo); -+ return drinfo; -+} -+ -+struct au_drinfo_do_load_args { -+ struct au_drinfo **drinfop; -+ struct path *h_ppath; -+ char *whname; -+ int whnamelen; -+ struct dentry **info_dentry; -+}; -+ -+static void au_call_drinfo_do_load(void *args) -+{ -+ struct au_drinfo_do_load_args *a = args; -+ -+ *a->drinfop = au_drinfo_do_load(a->h_ppath, a->whname, a->whnamelen, -+ a->info_dentry); -+} -+ -+struct au_drinfo_load { -+ struct path h_ppath; -+ struct qstr *qname; -+ unsigned char no_sio; -+ -+ aufs_bindex_t ninfo; -+ struct au_drinfo **drinfo; -+}; -+ -+static int au_drinfo_load(struct au_drinfo_load *w, aufs_bindex_t bindex, -+ struct au_branch *br) -+{ -+ int err, wkq_err, whnamelen, e; -+ char whname[sizeof(AUFS_WH_DR_INFO_PFX) + AUFS_DIRREN_ENV_VAL_SZ] -+ = AUFS_WH_DR_INFO_PFX; -+ struct au_drinfo *drinfo; -+ struct qstr oldname; -+ struct inode *h_dir, *delegated; -+ struct dentry *info_dentry; -+ struct path infopath; -+ -+ whnamelen = sizeof(AUFS_WH_DR_INFO_PFX) - 1; -+ whnamelen += au_drinfo_name(br, whname + whnamelen, -+ sizeof(whname) - whnamelen); -+ if (w->no_sio) -+ drinfo = au_drinfo_do_load(&w->h_ppath, whname, whnamelen, -+ &info_dentry); -+ else { -+ struct au_drinfo_do_load_args args = { -+ .drinfop = &drinfo, -+ .h_ppath = &w->h_ppath, -+ .whname = whname, -+ .whnamelen = whnamelen, -+ .info_dentry = &info_dentry -+ }; -+ wkq_err = au_wkq_wait(au_call_drinfo_do_load, &args); -+ if (unlikely(wkq_err)) -+ drinfo = ERR_PTR(wkq_err); -+ } -+ err = PTR_ERR(drinfo); -+ if (IS_ERR_OR_NULL(drinfo)) -+ goto out; -+ -+ err = 0; -+ oldname.len = drinfo->oldnamelen; -+ oldname.name = drinfo->oldname; -+ if (au_qstreq(w->qname, &oldname)) { -+ /* the name is renamed back */ -+ kfree(drinfo); -+ drinfo = NULL; -+ -+ infopath.dentry = info_dentry; -+ infopath.mnt = w->h_ppath.mnt; -+ h_dir = d_inode(w->h_ppath.dentry); -+ delegated = NULL; -+ inode_lock_nested(h_dir, AuLsc_I_PARENT); -+ e = vfsub_unlink(h_dir, &infopath, &delegated, !w->no_sio); -+ inode_unlock(h_dir); -+ if (unlikely(e)) -+ AuIOErr("ignored %d, %pd2\n", e, &infopath.dentry); -+ if (unlikely(e == -EWOULDBLOCK)) -+ iput(delegated); -+ } -+ kfree(w->drinfo[bindex]); -+ w->drinfo[bindex] = drinfo; -+ dput(info_dentry); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_dr_lkup_free(struct au_drinfo **drinfo, int n) -+{ -+ struct au_drinfo **p = drinfo; -+ -+ while (n-- > 0) -+ kfree(*drinfo++); -+ kfree(p); -+} -+ -+int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry, -+ aufs_bindex_t btgt) -+{ -+ int err, ninfo; -+ struct au_drinfo_load w; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ struct inode *h_dir; -+ struct au_dr_hino *ent; -+ struct super_block *sb; -+ -+ AuDbg("%.*s, name %.*s, whname %.*s, b%d\n", -+ AuLNPair(&dentry->d_name), AuLNPair(&lkup->dirren.dr_name), -+ AuLNPair(&lkup->whname), btgt); -+ -+ sb = dentry->d_sb; -+ bbot = au_sbbot(sb); -+ w.ninfo = bbot + 1; -+ if (!lkup->dirren.drinfo) { -+ lkup->dirren.drinfo = kcalloc(w.ninfo, -+ sizeof(*lkup->dirren.drinfo), -+ GFP_NOFS); -+ if (unlikely(!lkup->dirren.drinfo)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ lkup->dirren.ninfo = w.ninfo; -+ } -+ w.drinfo = lkup->dirren.drinfo; -+ w.no_sio = !!uid_eq(current_fsuid(), GLOBAL_ROOT_UID); -+ w.h_ppath.dentry = au_h_dptr(dentry, btgt); -+ AuDebugOn(!w.h_ppath.dentry); -+ w.h_ppath.mnt = au_sbr_mnt(sb, btgt); -+ w.qname = &dentry->d_name; -+ -+ ninfo = 0; -+ for (bindex = btgt + 1; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ err = au_drinfo_load(&w, bindex, br); -+ if (unlikely(err)) -+ goto out_free; -+ if (w.drinfo[bindex]) -+ ninfo++; -+ } -+ if (!ninfo) { -+ br = au_sbr(sb, btgt); -+ h_dir = d_inode(w.h_ppath.dentry); -+ ent = au_dr_hino_find(&br->br_dirren, h_dir->i_ino); -+ AuDebugOn(!ent); -+ au_dr_hino_del(&br->br_dirren, ent); -+ kfree(ent); -+ } -+ goto out; /* success */ -+ -+out_free: -+ au_dr_lkup_free(lkup->dirren.drinfo, lkup->dirren.ninfo); -+ lkup->dirren.ninfo = 0; -+ lkup->dirren.drinfo = NULL; -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_dr_lkup_fin(struct au_do_lookup_args *lkup) -+{ -+ au_dr_lkup_free(lkup->dirren.drinfo, lkup->dirren.ninfo); -+} -+ -+int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt) -+{ -+ int err; -+ struct au_drinfo *drinfo; -+ -+ err = 0; -+ if (!lkup->dirren.drinfo) -+ goto out; -+ AuDebugOn(lkup->dirren.ninfo < btgt + 1); -+ drinfo = lkup->dirren.drinfo[btgt + 1]; -+ if (!drinfo) -+ goto out; -+ -+ kfree(lkup->whname.name); -+ lkup->whname.name = NULL; -+ lkup->dirren.dr_name.len = drinfo->oldnamelen; -+ lkup->dirren.dr_name.name = drinfo->oldname; -+ lkup->name = &lkup->dirren.dr_name; -+ err = au_wh_name_alloc(&lkup->whname, lkup->name); -+ if (!err) -+ AuDbg("name %.*s, whname %.*s, b%d\n", -+ AuLNPair(lkup->name), AuLNPair(&lkup->whname), -+ btgt); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex, -+ ino_t h_ino) -+{ -+ int match; -+ struct au_drinfo *drinfo; -+ -+ match = 1; -+ if (!lkup->dirren.drinfo) -+ goto out; -+ AuDebugOn(lkup->dirren.ninfo < bindex + 1); -+ drinfo = lkup->dirren.drinfo[bindex + 1]; -+ if (!drinfo) -+ goto out; -+ -+ match = (drinfo->ino == h_ino); -+ AuDbg("match %d\n", match); -+ -+out: -+ return match; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_dr_opt_set(struct super_block *sb) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ err = 0; -+ bbot = au_sbbot(sb); -+ for (bindex = 0; !err && bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ err = au_dr_hino(sb, bindex, /*br*/NULL, &br->br_path); -+ } -+ -+ return err; -+} -+ -+int au_dr_opt_flush(struct super_block *sb) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ err = 0; -+ bbot = au_sbbot(sb); -+ for (bindex = 0; !err && bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_writable(br->br_perm)) -+ err = au_dr_hino(sb, bindex, /*br*/NULL, /*path*/NULL); -+ } -+ -+ return err; -+} -+ -+int au_dr_opt_clr(struct super_block *sb, int no_flush) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ err = 0; -+ if (!no_flush) { -+ err = au_dr_opt_flush(sb); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ au_dr_hino_free(&br->br_dirren); -+ } -+ -+out: -+ return err; -+} -diff --git a/fs/aufs/dirren.h b/fs/aufs/dirren.h -new file mode 100644 -index 000000000..f5139a30c ---- /dev/null -+++ b/fs/aufs/dirren.h -@@ -0,0 +1,140 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2017-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * renamed dir info -+ */ -+ -+#ifndef __AUFS_DIRREN_H__ -+#define __AUFS_DIRREN_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include "hbl.h" -+ -+#define AuDirren_NHASH 100 -+ -+#ifdef CONFIG_AUFS_DIRREN -+enum au_brid_type { -+ AuBrid_Unset, -+ AuBrid_UUID, -+ AuBrid_FSID, -+ AuBrid_DEV -+}; -+ -+struct au_dr_brid { -+ enum au_brid_type type; -+ union { -+ uuid_t uuid; /* unimplemented yet */ -+ fsid_t fsid; -+ dev_t dev; -+ }; -+}; -+ -+/* 20 is the max digits length of ulong 64 */ -+/* brid-type "_" uuid "_" inum */ -+#define AUFS_DIRREN_FNAME_SZ (1 + 1 + UUID_STRING_LEN + 20) -+#define AUFS_DIRREN_ENV_VAL_SZ (AUFS_DIRREN_FNAME_SZ + 1 + 20) -+ -+struct au_dr_hino { -+ struct hlist_bl_node dr_hnode; -+ ino_t dr_h_ino; -+}; -+ -+struct au_dr_br { -+ struct hlist_bl_head dr_h_ino[AuDirren_NHASH]; -+ struct au_dr_brid dr_brid; -+}; -+ -+struct au_dr_lookup { -+ /* dr_name is pointed by struct au_do_lookup_args.name */ -+ struct qstr dr_name; /* subset of dr_info */ -+ aufs_bindex_t ninfo; -+ struct au_drinfo **drinfo; -+}; -+#else -+struct au_dr_hino; -+/* empty */ -+struct au_dr_br { }; -+struct au_dr_lookup { }; -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_branch; -+struct au_do_lookup_args; -+struct au_hinode; -+#ifdef CONFIG_AUFS_DIRREN -+int au_dr_hino_test_add(struct au_dr_br *dr, ino_t h_ino, -+ struct au_dr_hino *add_ent); -+void au_dr_hino_free(struct au_dr_br *dr); -+int au_dr_br_init(struct super_block *sb, struct au_branch *br, -+ const struct path *path); -+int au_dr_br_fin(struct super_block *sb, struct au_branch *br); -+int au_dr_rename(struct dentry *src, aufs_bindex_t bindex, -+ struct qstr *dst_name, void *_rev); -+void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *rev); -+void au_dr_rename_rev(struct dentry *src, aufs_bindex_t bindex, void *rev); -+int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry, -+ aufs_bindex_t bindex); -+int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt); -+int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex, -+ ino_t h_ino); -+void au_dr_lkup_fin(struct au_do_lookup_args *lkup); -+int au_dr_opt_set(struct super_block *sb); -+int au_dr_opt_flush(struct super_block *sb); -+int au_dr_opt_clr(struct super_block *sb, int no_flush); -+#else -+AuStubInt0(au_dr_hino_test_add, struct au_dr_br *dr, ino_t h_ino, -+ struct au_dr_hino *add_ent); -+AuStubVoid(au_dr_hino_free, struct au_dr_br *dr); -+AuStubInt0(au_dr_br_init, struct super_block *sb, struct au_branch *br, -+ const struct path *path); -+AuStubInt0(au_dr_br_fin, struct super_block *sb, struct au_branch *br); -+AuStubInt0(au_dr_rename, struct dentry *src, aufs_bindex_t bindex, -+ struct qstr *dst_name, void *_rev); -+AuStubVoid(au_dr_rename_fin, struct dentry *src, aufs_bindex_t btgt, void *rev); -+AuStubVoid(au_dr_rename_rev, struct dentry *src, aufs_bindex_t bindex, -+ void *rev); -+AuStubInt0(au_dr_lkup, struct au_do_lookup_args *lkup, struct dentry *dentry, -+ aufs_bindex_t bindex); -+AuStubInt0(au_dr_lkup_name, struct au_do_lookup_args *lkup, aufs_bindex_t btgt); -+AuStubInt0(au_dr_lkup_h_ino, struct au_do_lookup_args *lkup, -+ aufs_bindex_t bindex, ino_t h_ino); -+AuStubVoid(au_dr_lkup_fin, struct au_do_lookup_args *lkup); -+AuStubInt0(au_dr_opt_set, struct super_block *sb); -+AuStubInt0(au_dr_opt_flush, struct super_block *sb); -+AuStubInt0(au_dr_opt_clr, struct super_block *sb, int no_flush); -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_DIRREN -+static inline int au_dr_ihash(ino_t h_ino) -+{ -+ return h_ino % AuDirren_NHASH; -+} -+#else -+AuStubInt0(au_dr_ihash, ino_t h_ino); -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DIRREN_H__ */ -diff --git a/fs/aufs/dynop.c b/fs/aufs/dynop.c -new file mode 100644 -index 000000000..f2ff9f3ab ---- /dev/null -+++ b/fs/aufs/dynop.c -@@ -0,0 +1,370 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2010-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * dynamically customizable operations for regular files -+ */ -+ -+#include "aufs.h" -+ -+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop) -+ -+/* -+ * How large will these lists be? -+ * Usually just a few elements, 20-30 at most for each, I guess. -+ */ -+static struct hlist_bl_head dynop[AuDyLast]; -+ -+static struct au_dykey *dy_gfind_get(struct hlist_bl_head *hbl, -+ const void *h_op) -+{ -+ struct au_dykey *key, *tmp; -+ struct hlist_bl_node *pos; -+ -+ key = NULL; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(tmp, pos, hbl, dk_hnode) -+ if (tmp->dk_op.dy_hop == h_op) { -+ key = tmp; -+ kref_get(&key->dk_kref); -+ break; -+ } -+ hlist_bl_unlock(hbl); -+ -+ return key; -+} -+ -+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key) -+{ -+ struct au_dykey **k, *found; -+ const void *h_op = key->dk_op.dy_hop; -+ int i; -+ -+ found = NULL; -+ k = br->br_dykey; -+ for (i = 0; i < AuBrDynOp; i++) -+ if (k[i]) { -+ if (k[i]->dk_op.dy_hop == h_op) { -+ found = k[i]; -+ break; -+ } -+ } else -+ break; -+ if (!found) { -+ spin_lock(&br->br_dykey_lock); -+ for (; i < AuBrDynOp; i++) -+ if (k[i]) { -+ if (k[i]->dk_op.dy_hop == h_op) { -+ found = k[i]; -+ break; -+ } -+ } else { -+ k[i] = key; -+ break; -+ } -+ spin_unlock(&br->br_dykey_lock); -+ BUG_ON(i == AuBrDynOp); /* expand the array */ -+ } -+ -+ return found; -+} -+ -+/* kref_get() if @key is already added */ -+static struct au_dykey *dy_gadd(struct hlist_bl_head *hbl, struct au_dykey *key) -+{ -+ struct au_dykey *tmp, *found; -+ struct hlist_bl_node *pos; -+ const void *h_op = key->dk_op.dy_hop; -+ -+ found = NULL; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(tmp, pos, hbl, dk_hnode) -+ if (tmp->dk_op.dy_hop == h_op) { -+ kref_get(&tmp->dk_kref); -+ found = tmp; -+ break; -+ } -+ if (!found) -+ hlist_bl_add_head(&key->dk_hnode, hbl); -+ hlist_bl_unlock(hbl); -+ -+ if (!found) -+ DyPrSym(key); -+ return found; -+} -+ -+static void dy_free_rcu(struct rcu_head *rcu) -+{ -+ struct au_dykey *key; -+ -+ key = container_of(rcu, struct au_dykey, dk_rcu); -+ DyPrSym(key); -+ kfree(key); -+} -+ -+static void dy_free(struct kref *kref) -+{ -+ struct au_dykey *key; -+ struct hlist_bl_head *hbl; -+ -+ key = container_of(kref, struct au_dykey, dk_kref); -+ hbl = dynop + key->dk_op.dy_type; -+ au_hbl_del(&key->dk_hnode, hbl); -+ call_rcu(&key->dk_rcu, dy_free_rcu); -+} -+ -+void au_dy_put(struct au_dykey *key) -+{ -+ kref_put(&key->dk_kref, dy_free); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *)) -+ -+#ifdef CONFIG_AUFS_DEBUG -+#define DyDbgDeclare(cnt) unsigned int cnt = 0 -+#define DyDbgInc(cnt) do { cnt++; } while (0) -+#else -+#define DyDbgDeclare(cnt) do {} while (0) -+#define DyDbgInc(cnt) do {} while (0) -+#endif -+ -+#define DySet(func, dst, src, h_op, h_sb) do { \ -+ DyDbgInc(cnt); \ -+ if (h_op->func) { \ -+ if (src.func) \ -+ dst.func = src.func; \ -+ else \ -+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \ -+ } \ -+} while (0) -+ -+#define DySetForce(func, dst, src) do { \ -+ AuDebugOn(!src.func); \ -+ DyDbgInc(cnt); \ -+ dst.func = src.func; \ -+} while (0) -+ -+#define DySetAop(func) \ -+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb) -+#define DySetAopForce(func) \ -+ DySetForce(func, dyaop->da_op, aufs_aop) -+ -+static void dy_aop(struct au_dykey *key, const void *h_op, -+ struct super_block *h_sb __maybe_unused) -+{ -+ struct au_dyaop *dyaop = (void *)key; -+ const struct address_space_operations *h_aop = h_op; -+ DyDbgDeclare(cnt); -+ -+ AuDbg("%s\n", au_sbtype(h_sb)); -+ -+ DySetAop(writepage); -+ DySetAopForce(readpage); /* force */ -+ DySetAop(writepages); -+ DySetAop(set_page_dirty); -+ DySetAop(readpages); -+ DySetAop(write_begin); -+ DySetAop(write_end); -+ DySetAop(bmap); -+ DySetAop(invalidatepage); -+ DySetAop(releasepage); -+ DySetAop(freepage); -+ /* this one will be changed according to an aufs mount option */ -+ DySetAop(direct_IO); -+ DySetAop(migratepage); -+ DySetAop(isolate_page); -+ DySetAop(putback_page); -+ DySetAop(launder_page); -+ DySetAop(is_partially_uptodate); -+ DySetAop(is_dirty_writeback); -+ DySetAop(error_remove_page); -+ DySetAop(swap_activate); -+ DySetAop(swap_deactivate); -+ -+ DyDbgSize(cnt, *h_aop); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void dy_bug(struct kref *kref) -+{ -+ BUG(); -+} -+ -+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br) -+{ -+ struct au_dykey *key, *old; -+ struct hlist_bl_head *hbl; -+ struct op { -+ unsigned int sz; -+ void (*set)(struct au_dykey *key, const void *h_op, -+ struct super_block *h_sb __maybe_unused); -+ }; -+ static const struct op a[] = { -+ [AuDy_AOP] = { -+ .sz = sizeof(struct au_dyaop), -+ .set = dy_aop -+ } -+ }; -+ const struct op *p; -+ -+ hbl = dynop + op->dy_type; -+ key = dy_gfind_get(hbl, op->dy_hop); -+ if (key) -+ goto out_add; /* success */ -+ -+ p = a + op->dy_type; -+ key = kzalloc(p->sz, GFP_NOFS); -+ if (unlikely(!key)) { -+ key = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ -+ key->dk_op.dy_hop = op->dy_hop; -+ kref_init(&key->dk_kref); -+ p->set(key, op->dy_hop, au_br_sb(br)); -+ old = dy_gadd(hbl, key); -+ if (old) { -+ kfree(key); -+ key = old; -+ } -+ -+out_add: -+ old = dy_bradd(br, key); -+ if (old) -+ /* its ref-count should never be zero here */ -+ kref_put(&key->dk_kref, dy_bug); -+out: -+ return key; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * Aufs prohibits O_DIRECT by default even if the branch supports it. -+ * This behaviour is necessary to return an error from open(O_DIRECT) instead -+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes -+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error. -+ * See the aufs manual in detail. -+ */ -+static void dy_adx(struct au_dyaop *dyaop, int do_dx) -+{ -+ if (!do_dx) -+ dyaop->da_op.direct_IO = NULL; -+ else -+ dyaop->da_op.direct_IO = aufs_aop.direct_IO; -+} -+ -+static struct au_dyaop *dy_aget(struct au_branch *br, -+ const struct address_space_operations *h_aop, -+ int do_dx) -+{ -+ struct au_dyaop *dyaop; -+ struct au_dynop op; -+ -+ op.dy_type = AuDy_AOP; -+ op.dy_haop = h_aop; -+ dyaop = (void *)dy_get(&op, br); -+ if (IS_ERR(dyaop)) -+ goto out; -+ dy_adx(dyaop, do_dx); -+ -+out: -+ return dyaop; -+} -+ -+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex, -+ struct inode *h_inode) -+{ -+ int err, do_dx; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_dyaop *dyaop; -+ -+ AuDebugOn(!S_ISREG(h_inode->i_mode)); -+ IiMustWriteLock(inode); -+ -+ sb = inode->i_sb; -+ br = au_sbr(sb, bindex); -+ do_dx = !!au_opt_test(au_mntflags(sb), DIO); -+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx); -+ err = PTR_ERR(dyaop); -+ if (IS_ERR(dyaop)) -+ /* unnecessary to call dy_fput() */ -+ goto out; -+ -+ err = 0; -+ inode->i_mapping->a_ops = &dyaop->da_op; -+ -+out: -+ return err; -+} -+ -+/* -+ * Is it safe to replace a_ops during the inode/file is in operation? -+ * Yes, I hope so. -+ */ -+int au_dy_irefresh(struct inode *inode) -+{ -+ int err; -+ aufs_bindex_t btop; -+ struct inode *h_inode; -+ -+ err = 0; -+ if (S_ISREG(inode->i_mode)) { -+ btop = au_ibtop(inode); -+ h_inode = au_h_iptr(inode, btop); -+ err = au_dy_iaop(inode, btop, h_inode); -+ } -+ return err; -+} -+ -+void au_dy_arefresh(int do_dx) -+{ -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ struct au_dykey *key; -+ -+ hbl = dynop + AuDy_AOP; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(key, pos, hbl, dk_hnode) -+ dy_adx((void *)key, do_dx); -+ hlist_bl_unlock(hbl); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void __init au_dy_init(void) -+{ -+ int i; -+ -+ /* make sure that 'struct au_dykey *' can be any type */ -+ BUILD_BUG_ON(offsetof(struct au_dyaop, da_key)); -+ -+ for (i = 0; i < AuDyLast; i++) -+ INIT_HLIST_BL_HEAD(dynop + i); -+} -+ -+void au_dy_fin(void) -+{ -+ int i; -+ -+ for (i = 0; i < AuDyLast; i++) -+ WARN_ON(!hlist_bl_empty(dynop + i)); -+} -diff --git a/fs/aufs/dynop.h b/fs/aufs/dynop.h -new file mode 100644 -index 000000000..d4015351e ---- /dev/null -+++ b/fs/aufs/dynop.h -@@ -0,0 +1,75 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2010-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * dynamically customizable operations (for regular files only) -+ */ -+ -+#ifndef __AUFS_DYNOP_H__ -+#define __AUFS_DYNOP_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+ -+enum {AuDy_AOP, AuDyLast}; -+ -+struct au_dynop { -+ int dy_type; -+ union { -+ const void *dy_hop; -+ const struct address_space_operations *dy_haop; -+ }; -+}; -+ -+struct au_dykey { -+ union { -+ struct hlist_bl_node dk_hnode; -+ struct rcu_head dk_rcu; -+ }; -+ struct au_dynop dk_op; -+ -+ /* -+ * during I am in the branch local array, kref is gotten. when the -+ * branch is removed, kref is put. -+ */ -+ struct kref dk_kref; -+}; -+ -+/* stop unioning since their sizes are very different from each other */ -+struct au_dyaop { -+ struct au_dykey da_key; -+ struct address_space_operations da_op; /* not const */ -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* dynop.c */ -+struct au_branch; -+void au_dy_put(struct au_dykey *key); -+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex, -+ struct inode *h_inode); -+int au_dy_irefresh(struct inode *inode); -+void au_dy_arefresh(int do_dio); -+ -+void __init au_dy_init(void); -+void au_dy_fin(void); -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DYNOP_H__ */ -diff --git a/fs/aufs/export.c b/fs/aufs/export.c -new file mode 100644 -index 000000000..0358fbec3 ---- /dev/null -+++ b/fs/aufs/export.c -@@ -0,0 +1,838 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * export via nfs -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+union conv { -+#ifdef CONFIG_AUFS_INO_T_64 -+ __u32 a[2]; -+#else -+ __u32 a[1]; -+#endif -+ ino_t ino; -+}; -+ -+static ino_t decode_ino(__u32 *a) -+{ -+ union conv u; -+ -+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a)); -+ u.a[0] = a[0]; -+#ifdef CONFIG_AUFS_INO_T_64 -+ u.a[1] = a[1]; -+#endif -+ return u.ino; -+} -+ -+static void encode_ino(__u32 *a, ino_t ino) -+{ -+ union conv u; -+ -+ u.ino = ino; -+ a[0] = u.a[0]; -+#ifdef CONFIG_AUFS_INO_T_64 -+ a[1] = u.a[1]; -+#endif -+} -+ -+/* NFS file handle */ -+enum { -+ Fh_br_id, -+ Fh_sigen, -+#ifdef CONFIG_AUFS_INO_T_64 -+ /* support 64bit inode number */ -+ Fh_ino1, -+ Fh_ino2, -+ Fh_dir_ino1, -+ Fh_dir_ino2, -+#else -+ Fh_ino1, -+ Fh_dir_ino1, -+#endif -+ Fh_igen, -+ Fh_h_type, -+ Fh_tail, -+ -+ Fh_ino = Fh_ino1, -+ Fh_dir_ino = Fh_dir_ino1 -+}; -+ -+static int au_test_anon(struct dentry *dentry) -+{ -+ /* note: read d_flags without d_lock */ -+ return !!(dentry->d_flags & DCACHE_DISCONNECTED); -+} -+ -+int au_test_nfsd(void) -+{ -+ int ret; -+ struct task_struct *tsk = current; -+ char comm[sizeof(tsk->comm)]; -+ -+ ret = 0; -+ if (tsk->flags & PF_KTHREAD) { -+ get_task_comm(comm, tsk); -+ ret = !strcmp(comm, "nfsd"); -+ } -+ -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* inode generation external table */ -+ -+void au_xigen_inc(struct inode *inode) -+{ -+ loff_t pos; -+ ssize_t sz; -+ __u32 igen; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ -+ sb = inode->i_sb; -+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO)); -+ -+ sbinfo = au_sbi(sb); -+ pos = inode->i_ino; -+ pos *= sizeof(igen); -+ igen = inode->i_generation + 1; -+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen, -+ sizeof(igen), &pos); -+ if (sz == sizeof(igen)) -+ return; /* success */ -+ -+ if (unlikely(sz >= 0)) -+ AuIOErr("xigen error (%zd)\n", sz); -+} -+ -+int au_xigen_new(struct inode *inode) -+{ -+ int err; -+ loff_t pos; -+ ssize_t sz; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ -+ err = 0; -+ /* todo: dirty, at mount time */ -+ if (inode->i_ino == AUFS_ROOT_INO) -+ goto out; -+ sb = inode->i_sb; -+ SiMustAnyLock(sb); -+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) -+ goto out; -+ -+ err = -EFBIG; -+ pos = inode->i_ino; -+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) { -+ AuIOErr1("too large i%lld\n", pos); -+ goto out; -+ } -+ pos *= sizeof(inode->i_generation); -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ file = sbinfo->si_xigen; -+ BUG_ON(!file); -+ -+ if (vfsub_f_size_read(file) -+ < pos + sizeof(inode->i_generation)) { -+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next); -+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation, -+ sizeof(inode->i_generation), &pos); -+ } else -+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation, -+ sizeof(inode->i_generation), &pos); -+ if (sz == sizeof(inode->i_generation)) -+ goto out; /* success */ -+ -+ err = sz; -+ if (unlikely(sz >= 0)) { -+ err = -EIO; -+ AuIOErr("xigen error (%zd)\n", sz); -+ } -+ -+out: -+ return err; -+} -+ -+int au_xigen_set(struct super_block *sb, struct path *path) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ file = au_xino_create2(sb, path, sbinfo->si_xigen); -+ err = PTR_ERR(file); -+ if (IS_ERR(file)) -+ goto out; -+ err = 0; -+ if (sbinfo->si_xigen) -+ fput(sbinfo->si_xigen); -+ sbinfo->si_xigen = file; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_xigen_clr(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ if (sbinfo->si_xigen) { -+ fput(sbinfo->si_xigen); -+ sbinfo->si_xigen = NULL; -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino, -+ ino_t dir_ino) -+{ -+ struct dentry *dentry, *d; -+ struct inode *inode; -+ unsigned int sigen; -+ -+ dentry = NULL; -+ inode = ilookup(sb, ino); -+ if (!inode) -+ goto out; -+ -+ dentry = ERR_PTR(-ESTALE); -+ sigen = au_sigen(sb); -+ if (unlikely(au_is_bad_inode(inode) -+ || IS_DEADDIR(inode) -+ || sigen != au_iigen(inode, NULL))) -+ goto out_iput; -+ -+ dentry = NULL; -+ if (!dir_ino || S_ISDIR(inode->i_mode)) -+ dentry = d_find_alias(inode); -+ else { -+ spin_lock(&inode->i_lock); -+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) { -+ spin_lock(&d->d_lock); -+ if (!au_test_anon(d) -+ && d_inode(d->d_parent)->i_ino == dir_ino) { -+ dentry = dget_dlock(d); -+ spin_unlock(&d->d_lock); -+ break; -+ } -+ spin_unlock(&d->d_lock); -+ } -+ spin_unlock(&inode->i_lock); -+ } -+ if (unlikely(dentry && au_digen_test(dentry, sigen))) { -+ /* need to refresh */ -+ dput(dentry); -+ dentry = NULL; -+ } -+ -+out_iput: -+ iput(inode); -+out: -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* todo: dirty? */ -+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */ -+ -+struct au_compare_mnt_args { -+ /* input */ -+ struct super_block *sb; -+ -+ /* output */ -+ struct vfsmount *mnt; -+}; -+ -+static int au_compare_mnt(struct vfsmount *mnt, void *arg) -+{ -+ struct au_compare_mnt_args *a = arg; -+ -+ if (mnt->mnt_sb != a->sb) -+ return 0; -+ a->mnt = mntget(mnt); -+ return 1; -+} -+ -+static struct vfsmount *au_mnt_get(struct super_block *sb) -+{ -+ int err; -+ struct path root; -+ struct au_compare_mnt_args args = { -+ .sb = sb -+ }; -+ -+ get_fs_root(current->fs, &root); -+ rcu_read_lock(); -+ err = iterate_mounts(au_compare_mnt, &args, root.mnt); -+ rcu_read_unlock(); -+ path_put(&root); -+ AuDebugOn(!err); -+ AuDebugOn(!args.mnt); -+ return args.mnt; -+} -+ -+struct au_nfsd_si_lock { -+ unsigned int sigen; -+ aufs_bindex_t bindex, br_id; -+ unsigned char force_lock; -+}; -+ -+static int si_nfsd_read_lock(struct super_block *sb, -+ struct au_nfsd_si_lock *nsi_lock) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ -+ si_read_lock(sb, AuLock_FLUSH); -+ -+ /* branch id may be wrapped around */ -+ err = 0; -+ bindex = au_br_index(sb, nsi_lock->br_id); -+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb)) -+ goto out; /* success */ -+ -+ err = -ESTALE; -+ bindex = -1; -+ if (!nsi_lock->force_lock) -+ si_read_unlock(sb); -+ -+out: -+ nsi_lock->bindex = bindex; -+ return err; -+} -+ -+struct find_name_by_ino { -+ struct dir_context ctx; -+ int called, found; -+ ino_t ino; -+ char *name; -+ int namelen; -+}; -+ -+static int -+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen, -+ loff_t offset, u64 ino, unsigned int d_type) -+{ -+ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino, -+ ctx); -+ -+ a->called++; -+ if (a->ino != ino) -+ return 0; -+ -+ memcpy(a->name, name, namelen); -+ a->namelen = namelen; -+ a->found = 1; -+ return 1; -+} -+ -+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino, -+ struct au_nfsd_si_lock *nsi_lock) -+{ -+ struct dentry *dentry, *parent; -+ struct file *file; -+ struct inode *dir; -+ struct find_name_by_ino arg = { -+ .ctx = { -+ .actor = find_name_by_ino -+ } -+ }; -+ int err; -+ -+ parent = path->dentry; -+ if (nsi_lock) -+ si_read_unlock(parent->d_sb); -+ file = vfsub_dentry_open(path, au_dir_roflags); -+ dentry = (void *)file; -+ if (IS_ERR(file)) -+ goto out; -+ -+ dentry = ERR_PTR(-ENOMEM); -+ arg.name = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!arg.name)) -+ goto out_file; -+ arg.ino = ino; -+ arg.found = 0; -+ do { -+ arg.called = 0; -+ /* smp_mb(); */ -+ err = vfsub_iterate_dir(file, &arg.ctx); -+ } while (!err && !arg.found && arg.called); -+ dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_name; -+ /* instead of ENOENT */ -+ dentry = ERR_PTR(-ESTALE); -+ if (!arg.found) -+ goto out_name; -+ -+ /* do not call vfsub_lkup_one() */ -+ dir = d_inode(parent); -+ dentry = vfsub_lookup_one_len_unlocked(arg.name, parent, arg.namelen); -+ AuTraceErrPtr(dentry); -+ if (IS_ERR(dentry)) -+ goto out_name; -+ AuDebugOn(au_test_anon(dentry)); -+ if (unlikely(d_really_is_negative(dentry))) { -+ dput(dentry); -+ dentry = ERR_PTR(-ENOENT); -+ } -+ -+out_name: -+ free_page((unsigned long)arg.name); -+out_file: -+ fput(file); -+out: -+ if (unlikely(nsi_lock -+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0)) -+ if (!IS_ERR(dentry)) { -+ dput(dentry); -+ dentry = ERR_PTR(-ESTALE); -+ } -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino, -+ ino_t dir_ino, -+ struct au_nfsd_si_lock *nsi_lock) -+{ -+ struct dentry *dentry; -+ struct path path; -+ -+ if (dir_ino != AUFS_ROOT_INO) { -+ path.dentry = decode_by_ino(sb, dir_ino, 0); -+ dentry = path.dentry; -+ if (!path.dentry || IS_ERR(path.dentry)) -+ goto out; -+ AuDebugOn(au_test_anon(path.dentry)); -+ } else -+ path.dentry = dget(sb->s_root); -+ -+ path.mnt = au_mnt_get(sb); -+ dentry = au_lkup_by_ino(&path, ino, nsi_lock); -+ path_put(&path); -+ -+out: -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int h_acceptable(void *expv, struct dentry *dentry) -+{ -+ return 1; -+} -+ -+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath, -+ char *buf, int len, struct super_block *sb) -+{ -+ char *p; -+ int n; -+ struct path path; -+ -+ p = d_path(h_rootpath, buf, len); -+ if (IS_ERR(p)) -+ goto out; -+ n = strlen(p); -+ -+ path.mnt = h_rootpath->mnt; -+ path.dentry = h_parent; -+ p = d_path(&path, buf, len); -+ if (IS_ERR(p)) -+ goto out; -+ if (n != 1) -+ p += n; -+ -+ path.mnt = au_mnt_get(sb); -+ path.dentry = sb->s_root; -+ p = d_path(&path, buf, len - strlen(p)); -+ mntput(path.mnt); -+ if (IS_ERR(p)) -+ goto out; -+ if (n != 1) -+ p[strlen(p)] = '/'; -+ -+out: -+ AuTraceErrPtr(p); -+ return p; -+} -+ -+static -+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh, -+ int fh_len, struct au_nfsd_si_lock *nsi_lock) -+{ -+ struct dentry *dentry, *h_parent, *root; -+ struct super_block *h_sb; -+ char *pathname, *p; -+ struct vfsmount *h_mnt; -+ struct au_branch *br; -+ int err; -+ struct path path; -+ -+ br = au_sbr(sb, nsi_lock->bindex); -+ h_mnt = au_br_mnt(br); -+ h_sb = h_mnt->mnt_sb; -+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */ -+ lockdep_off(); -+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail), -+ fh_len - Fh_tail, fh[Fh_h_type], -+ h_acceptable, /*context*/NULL); -+ lockdep_on(); -+ dentry = h_parent; -+ if (unlikely(!h_parent || IS_ERR(h_parent))) { -+ AuWarn1("%s decode_fh failed, %ld\n", -+ au_sbtype(h_sb), PTR_ERR(h_parent)); -+ goto out; -+ } -+ dentry = NULL; -+ if (unlikely(au_test_anon(h_parent))) { -+ AuWarn1("%s decode_fh returned a disconnected dentry\n", -+ au_sbtype(h_sb)); -+ goto out_h_parent; -+ } -+ -+ dentry = ERR_PTR(-ENOMEM); -+ pathname = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!pathname)) -+ goto out_h_parent; -+ -+ root = sb->s_root; -+ path.mnt = h_mnt; -+ di_read_lock_parent(root, !AuLock_IR); -+ path.dentry = au_h_dptr(root, nsi_lock->bindex); -+ di_read_unlock(root, !AuLock_IR); -+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb); -+ dentry = (void *)p; -+ if (IS_ERR(p)) -+ goto out_pathname; -+ -+ si_read_unlock(sb); -+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path); -+ dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_relock; -+ -+ dentry = ERR_PTR(-ENOENT); -+ AuDebugOn(au_test_anon(path.dentry)); -+ if (unlikely(d_really_is_negative(path.dentry))) -+ goto out_path; -+ -+ if (ino != d_inode(path.dentry)->i_ino) -+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL); -+ else -+ dentry = dget(path.dentry); -+ -+out_path: -+ path_put(&path); -+out_relock: -+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0)) -+ if (!IS_ERR(dentry)) { -+ dput(dentry); -+ dentry = ERR_PTR(-ESTALE); -+ } -+out_pathname: -+ free_page((unsigned long)pathname); -+out_h_parent: -+ dput(h_parent); -+out: -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct dentry * -+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, -+ int fh_type) -+{ -+ struct dentry *dentry; -+ __u32 *fh = fid->raw; -+ struct au_branch *br; -+ ino_t ino, dir_ino; -+ struct au_nfsd_si_lock nsi_lock = { -+ .force_lock = 0 -+ }; -+ -+ dentry = ERR_PTR(-ESTALE); -+ /* it should never happen, but the file handle is unreliable */ -+ if (unlikely(fh_len < Fh_tail)) -+ goto out; -+ nsi_lock.sigen = fh[Fh_sigen]; -+ nsi_lock.br_id = fh[Fh_br_id]; -+ -+ /* branch id may be wrapped around */ -+ br = NULL; -+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock))) -+ goto out; -+ nsi_lock.force_lock = 1; -+ -+ /* is this inode still cached? */ -+ ino = decode_ino(fh + Fh_ino); -+ /* it should never happen */ -+ if (unlikely(ino == AUFS_ROOT_INO)) -+ goto out_unlock; -+ -+ dir_ino = decode_ino(fh + Fh_dir_ino); -+ dentry = decode_by_ino(sb, ino, dir_ino); -+ if (IS_ERR(dentry)) -+ goto out_unlock; -+ if (dentry) -+ goto accept; -+ -+ /* is the parent dir cached? */ -+ br = au_sbr(sb, nsi_lock.bindex); -+ au_lcnt_inc(&br->br_nfiles); -+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock); -+ if (IS_ERR(dentry)) -+ goto out_unlock; -+ if (dentry) -+ goto accept; -+ -+ /* lookup path */ -+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock); -+ if (IS_ERR(dentry)) -+ goto out_unlock; -+ if (unlikely(!dentry)) -+ /* todo?: make it ESTALE */ -+ goto out_unlock; -+ -+accept: -+ if (!au_digen_test(dentry, au_sigen(sb)) -+ && d_inode(dentry)->i_generation == fh[Fh_igen]) -+ goto out_unlock; /* success */ -+ -+ dput(dentry); -+ dentry = ERR_PTR(-ESTALE); -+out_unlock: -+ if (br) -+ au_lcnt_dec(&br->br_nfiles); -+ si_read_unlock(sb); -+out: -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+#if 0 /* reserved for future use */ -+/* support subtreecheck option */ -+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid, -+ int fh_len, int fh_type) -+{ -+ struct dentry *parent; -+ __u32 *fh = fid->raw; -+ ino_t dir_ino; -+ -+ dir_ino = decode_ino(fh + Fh_dir_ino); -+ parent = decode_by_ino(sb, dir_ino, 0); -+ if (IS_ERR(parent)) -+ goto out; -+ if (!parent) -+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]), -+ dir_ino, fh, fh_len); -+ -+out: -+ AuTraceErrPtr(parent); -+ return parent; -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len, -+ struct inode *dir) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct super_block *sb, *h_sb; -+ struct dentry *dentry, *parent, *h_parent; -+ struct inode *h_dir; -+ struct au_branch *br; -+ -+ err = -ENOSPC; -+ if (unlikely(*max_len <= Fh_tail)) { -+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len); -+ goto out; -+ } -+ -+ err = FILEID_ROOT; -+ if (inode->i_ino == AUFS_ROOT_INO) { -+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO); -+ goto out; -+ } -+ -+ h_parent = NULL; -+ sb = inode->i_sb; -+ err = si_read_lock(sb, AuLock_FLUSH); -+ if (unlikely(err)) -+ goto out; -+ -+#ifdef CONFIG_AUFS_DEBUG -+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) -+ AuWarn1("NFS-exporting requires xino\n"); -+#endif -+ err = -EIO; -+ parent = NULL; -+ ii_read_lock_child(inode); -+ bindex = au_ibtop(inode); -+ if (!dir) { -+ dentry = d_find_any_alias(inode); -+ if (unlikely(!dentry)) -+ goto out_unlock; -+ AuDebugOn(au_test_anon(dentry)); -+ parent = dget_parent(dentry); -+ dput(dentry); -+ if (unlikely(!parent)) -+ goto out_unlock; -+ if (d_really_is_positive(parent)) -+ dir = d_inode(parent); -+ } -+ -+ ii_read_lock_parent(dir); -+ h_dir = au_h_iptr(dir, bindex); -+ ii_read_unlock(dir); -+ if (unlikely(!h_dir)) -+ goto out_parent; -+ h_parent = d_find_any_alias(h_dir); -+ if (unlikely(!h_parent)) -+ goto out_hparent; -+ -+ err = -EPERM; -+ br = au_sbr(sb, bindex); -+ h_sb = au_br_sb(br); -+ if (unlikely(!h_sb->s_export_op)) { -+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb)); -+ goto out_hparent; -+ } -+ -+ fh[Fh_br_id] = br->br_id; -+ fh[Fh_sigen] = au_sigen(sb); -+ encode_ino(fh + Fh_ino, inode->i_ino); -+ encode_ino(fh + Fh_dir_ino, dir->i_ino); -+ fh[Fh_igen] = inode->i_generation; -+ -+ *max_len -= Fh_tail; -+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail), -+ max_len, -+ /*connectable or subtreecheck*/0); -+ err = fh[Fh_h_type]; -+ *max_len += Fh_tail; -+ /* todo: macros? */ -+ if (err != FILEID_INVALID) -+ err = 99; -+ else -+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb)); -+ -+out_hparent: -+ dput(h_parent); -+out_parent: -+ dput(parent); -+out_unlock: -+ ii_read_unlock(inode); -+ si_read_unlock(sb); -+out: -+ if (unlikely(err < 0)) -+ err = FILEID_INVALID; -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int aufs_commit_metadata(struct inode *inode) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct super_block *sb; -+ struct inode *h_inode; -+ int (*f)(struct inode *inode); -+ -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ ii_write_lock_child(inode); -+ bindex = au_ibtop(inode); -+ AuDebugOn(bindex < 0); -+ h_inode = au_h_iptr(inode, bindex); -+ -+ f = h_inode->i_sb->s_export_op->commit_metadata; -+ if (f) -+ err = f(h_inode); -+ else { -+ struct writeback_control wbc = { -+ .sync_mode = WB_SYNC_ALL, -+ .nr_to_write = 0 /* metadata only */ -+ }; -+ -+ err = sync_inode(h_inode, &wbc); -+ } -+ -+ au_cpup_attr_timesizes(inode); -+ ii_write_unlock(inode); -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct export_operations aufs_export_op = { -+ .fh_to_dentry = aufs_fh_to_dentry, -+ /* .fh_to_parent = aufs_fh_to_parent, */ -+ .encode_fh = aufs_encode_fh, -+ .commit_metadata = aufs_commit_metadata -+}; -+ -+void au_export_init(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ __u32 u; -+ -+ BUILD_BUG_ON_MSG(IS_BUILTIN(CONFIG_AUFS_FS) -+ && IS_MODULE(CONFIG_EXPORTFS), -+ AUFS_NAME ": unsupported configuration " -+ "CONFIG_EXPORTFS=m and CONFIG_AUFS_FS=y"); -+ -+ sb->s_export_op = &aufs_export_op; -+ sbinfo = au_sbi(sb); -+ sbinfo->si_xigen = NULL; -+ get_random_bytes(&u, sizeof(u)); -+ BUILD_BUG_ON(sizeof(u) != sizeof(int)); -+ atomic_set(&sbinfo->si_xigen_next, u); -+} -diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c -new file mode 100644 -index 000000000..0733ae8ac ---- /dev/null -+++ b/fs/aufs/f_op.c -@@ -0,0 +1,819 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * file and vm operations -+ */ -+ -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+int au_do_open_nondir(struct file *file, int flags, struct file *h_file) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct dentry *dentry, *h_dentry; -+ struct au_finfo *finfo; -+ struct inode *h_inode; -+ -+ FiMustWriteLock(file); -+ -+ err = 0; -+ dentry = file->f_path.dentry; -+ AuDebugOn(IS_ERR_OR_NULL(dentry)); -+ finfo = au_fi(file); -+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop)); -+ atomic_set(&finfo->fi_mmapped, 0); -+ bindex = au_dbtop(dentry); -+ if (!h_file) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb); -+ if (unlikely(err)) -+ goto out; -+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0); -+ if (IS_ERR(h_file)) { -+ err = PTR_ERR(h_file); -+ goto out; -+ } -+ } else { -+ h_dentry = h_file->f_path.dentry; -+ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb); -+ if (unlikely(err)) -+ goto out; -+ /* br ref is already inc-ed */ -+ } -+ -+ if ((flags & __O_TMPFILE) -+ && !(flags & O_EXCL)) { -+ h_inode = file_inode(h_file); -+ spin_lock(&h_inode->i_lock); -+ h_inode->i_state |= I_LINKABLE; -+ spin_unlock(&h_inode->i_lock); -+ } -+ au_set_fbtop(file, bindex); -+ au_set_h_fptr(file, bindex, h_file); -+ au_update_figen(file); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ -+out: -+ return err; -+} -+ -+static int aufs_open_nondir(struct inode *inode __maybe_unused, -+ struct file *file) -+{ -+ int err; -+ struct super_block *sb; -+ struct au_do_open_args args = { -+ .open = au_do_open_nondir -+ }; -+ -+ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n", -+ file, vfsub_file_flags(file), file->f_mode); -+ -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ err = au_do_open(file, &args); -+ si_read_unlock(sb); -+ return err; -+} -+ -+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file) -+{ -+ struct au_finfo *finfo; -+ aufs_bindex_t bindex; -+ -+ finfo = au_fi(file); -+ au_hbl_del(&finfo->fi_hlist, -+ &au_sbi(file->f_path.dentry->d_sb)->si_files); -+ bindex = finfo->fi_btop; -+ if (bindex >= 0) -+ au_set_h_fptr(file, bindex, NULL); -+ -+ au_finfo_fin(file); -+ return 0; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_do_flush_nondir(struct file *file, fl_owner_t id) -+{ -+ int err; -+ struct file *h_file; -+ -+ err = 0; -+ h_file = au_hf_top(file); -+ if (h_file) -+ err = vfsub_flush(h_file, id); -+ return err; -+} -+ -+static int aufs_flush_nondir(struct file *file, fl_owner_t id) -+{ -+ return au_do_flush(file, id, au_do_flush_nondir); -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * read and write functions acquire [fdi]_rwsem once, but release before -+ * mmap_sem. This is because to stop a race condition between mmap(2). -+ * Releasing these aufs-rwsem should be safe, no branch-management (by keeping -+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in -+ * read functions after [fdi]_rwsem are released, but it should be harmless. -+ */ -+ -+/* Callers should call au_read_post() or fput() in the end */ -+struct file *au_read_pre(struct file *file, int keep_fi, unsigned int lsc) -+{ -+ struct file *h_file; -+ int err; -+ -+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0, lsc); -+ if (!err) { -+ di_read_unlock(file->f_path.dentry, AuLock_IR); -+ h_file = au_hf_top(file); -+ get_file(h_file); -+ if (!keep_fi) -+ fi_read_unlock(file); -+ } else -+ h_file = ERR_PTR(err); -+ -+ return h_file; -+} -+ -+static void au_read_post(struct inode *inode, struct file *h_file) -+{ -+ /* update without lock, I don't think it a problem */ -+ fsstack_copy_attr_atime(inode, file_inode(h_file)); -+ fput(h_file); -+} -+ -+struct au_write_pre { -+ /* input */ -+ unsigned int lsc; -+ -+ /* output */ -+ blkcnt_t blks; -+ aufs_bindex_t btop; -+}; -+ -+/* -+ * return with iinfo is write-locked -+ * callers should call au_write_post() or iinfo_write_unlock() + fput() in the -+ * end -+ */ -+static struct file *au_write_pre(struct file *file, int do_ready, -+ struct au_write_pre *wpre) -+{ -+ struct file *h_file; -+ struct dentry *dentry; -+ int err; -+ unsigned int lsc; -+ struct au_pin pin; -+ -+ lsc = 0; -+ if (wpre) -+ lsc = wpre->lsc; -+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, lsc); -+ h_file = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ -+ dentry = file->f_path.dentry; -+ if (do_ready) { -+ err = au_ready_to_write(file, -1, &pin); -+ if (unlikely(err)) { -+ h_file = ERR_PTR(err); -+ di_write_unlock(dentry); -+ goto out_fi; -+ } -+ } -+ -+ di_downgrade_lock(dentry, /*flags*/0); -+ if (wpre) -+ wpre->btop = au_fbtop(file); -+ h_file = au_hf_top(file); -+ get_file(h_file); -+ if (wpre) -+ wpre->blks = file_inode(h_file)->i_blocks; -+ if (do_ready) -+ au_unpin(&pin); -+ di_read_unlock(dentry, /*flags*/0); -+ -+out_fi: -+ fi_write_unlock(file); -+out: -+ return h_file; -+} -+ -+static void au_write_post(struct inode *inode, struct file *h_file, -+ struct au_write_pre *wpre, ssize_t written) -+{ -+ struct inode *h_inode; -+ -+ au_cpup_attr_timesizes(inode); -+ AuDebugOn(au_ibtop(inode) != wpre->btop); -+ h_inode = file_inode(h_file); -+ inode->i_mode = h_inode->i_mode; -+ ii_write_unlock(inode); -+ /* AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks); */ -+ if (written > 0) -+ au_fhsm_wrote(inode->i_sb, wpre->btop, -+ /*force*/h_inode->i_blocks > wpre->blks); -+ fput(h_file); -+} -+ -+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ struct inode *inode; -+ struct file *h_file; -+ struct super_block *sb; -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ /* filedata may be obsoleted by concurrent copyup, but no problem */ -+ err = vfsub_read_u(h_file, buf, count, ppos); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ au_read_post(inode, h_file); -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* -+ * todo: very ugly -+ * it locks both of i_mutex and si_rwsem for read in safe. -+ * if the plink maintenance mode continues forever (that is the problem), -+ * may loop forever. -+ */ -+static void au_mtx_and_read_lock(struct inode *inode) -+{ -+ int err; -+ struct super_block *sb = inode->i_sb; -+ -+ while (1) { -+ inode_lock(inode); -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (!err) -+ break; -+ inode_unlock(inode); -+ si_read_lock(sb, AuLock_NOPLMW); -+ si_read_unlock(sb); -+ } -+} -+ -+static ssize_t aufs_write(struct file *file, const char __user *ubuf, -+ size_t count, loff_t *ppos) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ char __user *buf = (char __user *)ubuf; -+ -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ wpre.lsc = 0; -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = vfsub_write_u(h_file, buf, count, ppos); -+ au_write_post(inode, h_file, &wpre, err); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+ return err; -+} -+ -+static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio, -+ struct iov_iter *iov_iter) -+{ -+ ssize_t err; -+ struct file *file; -+ ssize_t (*iter)(struct kiocb *, struct iov_iter *); -+ -+ err = security_file_permission(h_file, rw); -+ if (unlikely(err)) -+ goto out; -+ -+ err = -ENOSYS; -+ iter = NULL; -+ if (rw == MAY_READ) -+ iter = h_file->f_op->read_iter; -+ else if (rw == MAY_WRITE) -+ iter = h_file->f_op->write_iter; -+ -+ file = kio->ki_filp; -+ kio->ki_filp = h_file; -+ if (iter) { -+ lockdep_off(); -+ err = iter(kio, iov_iter); -+ lockdep_on(); -+ } else -+ /* currently there is no such fs */ -+ WARN_ON_ONCE(1); -+ kio->ki_filp = file; -+ -+out: -+ return err; -+} -+ -+static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter) -+{ -+ ssize_t err; -+ struct file *file, *h_file; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ file = kio->ki_filp; -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/1, /*lsc*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ if (au_test_loopback_kthread()) { -+ au_warn_loopback(h_file->f_path.dentry->d_sb); -+ if (file->f_mapping != h_file->f_mapping) { -+ file->f_mapping = h_file->f_mapping; -+ smp_mb(); /* unnecessary? */ -+ } -+ } -+ fi_read_unlock(file); -+ -+ err = au_do_iter(h_file, MAY_READ, kio, iov_iter); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ au_read_post(inode, h_file); -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *file, *h_file; -+ -+ file = kio->ki_filp; -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ wpre.lsc = 0; -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter); -+ au_write_post(inode, h_file, &wpre, err); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+ return err; -+} -+ -+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags) -+{ -+ ssize_t err; -+ struct file *h_file; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ au_read_post(inode, h_file); -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+static ssize_t -+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos, -+ size_t len, unsigned int flags) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ wpre.lsc = 0; -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags); -+ au_write_post(inode, h_file, &wpre, err); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+ return err; -+} -+ -+static long aufs_fallocate(struct file *file, int mode, loff_t offset, -+ loff_t len) -+{ -+ long err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ wpre.lsc = 0; -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_fallocate(h_file, mode, offset, len); -+ lockdep_on(); -+ au_write_post(inode, h_file, &wpre, /*written*/1); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+ return err; -+} -+ -+static ssize_t aufs_copy_file_range(struct file *src, loff_t src_pos, -+ struct file *dst, loff_t dst_pos, -+ size_t len, unsigned int flags) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ enum { SRC, DST }; -+ struct { -+ struct inode *inode; -+ struct file *h_file; -+ struct super_block *h_sb; -+ } a[2]; -+#define a_src a[SRC] -+#define a_dst a[DST] -+ -+ err = -EINVAL; -+ a_src.inode = file_inode(src); -+ if (unlikely(!S_ISREG(a_src.inode->i_mode))) -+ goto out; -+ a_dst.inode = file_inode(dst); -+ if (unlikely(!S_ISREG(a_dst.inode->i_mode))) -+ goto out; -+ -+ au_mtx_and_read_lock(a_dst.inode); -+ /* -+ * in order to match the order in di_write_lock2_{child,parent}(), -+ * use f_path.dentry for this comparison. -+ */ -+ if (src->f_path.dentry < dst->f_path.dentry) { -+ a_src.h_file = au_read_pre(src, /*keep_fi*/1, AuLsc_FI_1); -+ err = PTR_ERR(a_src.h_file); -+ if (IS_ERR(a_src.h_file)) -+ goto out_si; -+ -+ wpre.lsc = AuLsc_FI_2; -+ a_dst.h_file = au_write_pre(dst, /*do_ready*/1, &wpre); -+ err = PTR_ERR(a_dst.h_file); -+ if (IS_ERR(a_dst.h_file)) { -+ au_read_post(a_src.inode, a_src.h_file); -+ goto out_si; -+ } -+ } else { -+ wpre.lsc = AuLsc_FI_1; -+ a_dst.h_file = au_write_pre(dst, /*do_ready*/1, &wpre); -+ err = PTR_ERR(a_dst.h_file); -+ if (IS_ERR(a_dst.h_file)) -+ goto out_si; -+ -+ a_src.h_file = au_read_pre(src, /*keep_fi*/1, AuLsc_FI_2); -+ err = PTR_ERR(a_src.h_file); -+ if (IS_ERR(a_src.h_file)) { -+ au_write_post(a_dst.inode, a_dst.h_file, &wpre, -+ /*written*/0); -+ goto out_si; -+ } -+ } -+ -+ err = -EXDEV; -+ a_src.h_sb = file_inode(a_src.h_file)->i_sb; -+ a_dst.h_sb = file_inode(a_dst.h_file)->i_sb; -+ if (unlikely(a_src.h_sb != a_dst.h_sb)) { -+ AuDbgFile(src); -+ AuDbgFile(dst); -+ goto out_file; -+ } -+ -+ err = vfsub_copy_file_range(a_src.h_file, src_pos, a_dst.h_file, -+ dst_pos, len, flags); -+ -+out_file: -+ au_write_post(a_dst.inode, a_dst.h_file, &wpre, err); -+ fi_read_unlock(src); -+ au_read_post(a_src.inode, a_src.h_file); -+out_si: -+ si_read_unlock(a_dst.inode->i_sb); -+ inode_unlock(a_dst.inode); -+out: -+ return err; -+#undef a_src -+#undef a_dst -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * The locking order around current->mmap_sem. -+ * - in most and regular cases -+ * file I/O syscall -- aufs_read() or something -+ * -- si_rwsem for read -- mmap_sem -+ * (Note that [fdi]i_rwsem are released before mmap_sem). -+ * - in mmap case -+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem -+ * This AB-BA order is definitely bad, but is not a problem since "si_rwsem for -+ * read" allows multiple processes to acquire it and [fdi]i_rwsem are not held -+ * in file I/O. Aufs needs to stop lockdep in aufs_mmap() though. -+ * It means that when aufs acquires si_rwsem for write, the process should never -+ * acquire mmap_sem. -+ * -+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a -+ * problem either since any directory is not able to be mmap-ed. -+ * The similar scenario is applied to aufs_readlink() too. -+ */ -+ -+#if 0 /* stop calling security_file_mmap() */ -+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */ -+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b) -+ -+static unsigned long au_arch_prot_conv(unsigned long flags) -+{ -+ /* currently ppc64 only */ -+#ifdef CONFIG_PPC64 -+ /* cf. linux/arch/powerpc/include/asm/mman.h */ -+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO); -+ return AuConv_VM_PROT(flags, SAO); -+#else -+ AuDebugOn(arch_calc_vm_prot_bits(-1)); -+ return 0; -+#endif -+} -+ -+static unsigned long au_prot_conv(unsigned long flags) -+{ -+ return AuConv_VM_PROT(flags, READ) -+ | AuConv_VM_PROT(flags, WRITE) -+ | AuConv_VM_PROT(flags, EXEC) -+ | au_arch_prot_conv(flags); -+} -+ -+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */ -+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b) -+ -+static unsigned long au_flag_conv(unsigned long flags) -+{ -+ return AuConv_VM_MAP(flags, GROWSDOWN) -+ | AuConv_VM_MAP(flags, DENYWRITE) -+ | AuConv_VM_MAP(flags, LOCKED); -+} -+#endif -+ -+static int aufs_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ int err; -+ const unsigned char wlock -+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED); -+ struct super_block *sb; -+ struct file *h_file; -+ struct inode *inode; -+ -+ AuDbgVmRegion(file, vma); -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ lockdep_off(); -+ si_read_lock(sb, AuLock_NOPLMW); -+ -+ h_file = au_write_pre(file, wlock, /*wpre*/NULL); -+ lockdep_on(); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = 0; -+ au_set_mmapped(file); -+ au_vm_file_reset(vma, h_file); -+ /* -+ * we cannot call security_mmap_file() here since it may acquire -+ * mmap_sem or i_mutex. -+ * -+ * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags), -+ * au_flag_conv(vma->vm_flags)); -+ */ -+ if (!err) -+ err = call_mmap(h_file, vma); -+ if (!err) { -+ au_vm_prfile_set(vma, file); -+ fsstack_copy_attr_atime(inode, file_inode(h_file)); -+ goto out_fput; /* success */ -+ } -+ au_unset_mmapped(file); -+ au_vm_file_reset(vma, file); -+ -+out_fput: -+ lockdep_off(); -+ ii_write_unlock(inode); -+ lockdep_on(); -+ fput(h_file); -+out: -+ lockdep_off(); -+ si_read_unlock(sb); -+ lockdep_on(); -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end, -+ int datasync) -+{ -+ int err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ -+ err = 0; /* -EBADF; */ /* posix? */ -+ if (unlikely(!(file->f_mode & FMODE_WRITE))) -+ goto out; -+ -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ wpre.lsc = 0; -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out_unlock; -+ -+ err = vfsub_fsync(h_file, &h_file->f_path, datasync); -+ au_write_post(inode, h_file, &wpre, /*written*/0); -+ -+out_unlock: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+out: -+ return err; -+} -+ -+static int aufs_fasync(int fd, struct file *file, int flag) -+{ -+ int err; -+ struct file *h_file; -+ struct super_block *sb; -+ -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ if (h_file->f_op->fasync) -+ err = h_file->f_op->fasync(fd, h_file, flag); -+ fput(h_file); /* instead of au_read_post() */ -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+static int aufs_setfl(struct file *file, unsigned long arg) -+{ -+ int err; -+ struct file *h_file; -+ struct super_block *sb; -+ -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ /* stop calling h_file->fasync */ -+ arg |= vfsub_file_flags(file) & FASYNC; -+ err = setfl(/*unused fd*/-1, h_file, arg); -+ fput(h_file); /* instead of au_read_post() */ -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* no one supports this operation, currently */ -+#if 0 -+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset, -+ size_t len, loff_t *pos, int more) -+{ -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+const struct file_operations aufs_file_fop = { -+ .owner = THIS_MODULE, -+ -+ .llseek = default_llseek, -+ -+ .read = aufs_read, -+ .write = aufs_write, -+ .read_iter = aufs_read_iter, -+ .write_iter = aufs_write_iter, -+ -+#ifdef CONFIG_AUFS_POLL -+ .poll = aufs_poll, -+#endif -+ .unlocked_ioctl = aufs_ioctl_nondir, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = aufs_compat_ioctl_nondir, -+#endif -+ .mmap = aufs_mmap, -+ .open = aufs_open_nondir, -+ .flush = aufs_flush_nondir, -+ .release = aufs_release_nondir, -+ .fsync = aufs_fsync_nondir, -+ .fasync = aufs_fasync, -+ /* .sendpage = aufs_sendpage, */ -+ .setfl = aufs_setfl, -+ .splice_write = aufs_splice_write, -+ .splice_read = aufs_splice_read, -+#if 0 -+ .aio_splice_write = aufs_aio_splice_write, -+ .aio_splice_read = aufs_aio_splice_read, -+#endif -+ .fallocate = aufs_fallocate, -+ .copy_file_range = aufs_copy_file_range -+}; -diff --git a/fs/aufs/fhsm.c b/fs/aufs/fhsm.c -new file mode 100644 -index 000000000..fdb91f6eb ---- /dev/null -+++ b/fs/aufs/fhsm.c -@@ -0,0 +1,427 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2011-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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 St, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+/* -+ * File-based Hierarchy Storage Management -+ */ -+ -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+static aufs_bindex_t au_fhsm_bottom(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ SiMustAnyLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ AuDebugOn(!fhsm); -+ return fhsm->fhsm_bottom; -+} -+ -+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ AuDebugOn(!fhsm); -+ fhsm->fhsm_bottom = bindex; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_fhsm_test_jiffy(struct au_sbinfo *sbinfo, struct au_branch *br) -+{ -+ struct au_br_fhsm *bf; -+ -+ bf = br->br_fhsm; -+ MtxMustLock(&bf->bf_lock); -+ -+ return !bf->bf_readable -+ || time_after(jiffies, -+ bf->bf_jiffy + sbinfo->si_fhsm.fhsm_expire); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_fhsm_notify(struct super_block *sb, int val) -+{ -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ SiMustAnyLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ if (au_fhsm_pid(fhsm) -+ && atomic_read(&fhsm->fhsm_readable) != -1) { -+ atomic_set(&fhsm->fhsm_readable, val); -+ if (val) -+ wake_up(&fhsm->fhsm_wqh); -+ } -+} -+ -+static int au_fhsm_stfs(struct super_block *sb, aufs_bindex_t bindex, -+ struct aufs_stfs *rstfs, int do_lock, int do_notify) -+{ -+ int err; -+ struct au_branch *br; -+ struct au_br_fhsm *bf; -+ -+ br = au_sbr(sb, bindex); -+ AuDebugOn(au_br_rdonly(br)); -+ bf = br->br_fhsm; -+ AuDebugOn(!bf); -+ -+ if (do_lock) -+ mutex_lock(&bf->bf_lock); -+ else -+ MtxMustLock(&bf->bf_lock); -+ -+ /* sb->s_root for NFS is unreliable */ -+ err = au_br_stfs(br, &bf->bf_stfs); -+ if (unlikely(err)) { -+ AuErr1("FHSM failed (%d), b%d, ignored.\n", bindex, err); -+ goto out; -+ } -+ -+ bf->bf_jiffy = jiffies; -+ bf->bf_readable = 1; -+ if (do_notify) -+ au_fhsm_notify(sb, /*val*/1); -+ if (rstfs) -+ *rstfs = bf->bf_stfs; -+ -+out: -+ if (do_lock) -+ mutex_unlock(&bf->bf_lock); -+ au_fhsm_notify(sb, /*val*/1); -+ -+ return err; -+} -+ -+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ struct au_branch *br; -+ struct au_br_fhsm *bf; -+ -+ AuDbg("b%d, force %d\n", bindex, force); -+ SiMustAnyLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ if (!au_ftest_si(sbinfo, FHSM) -+ || fhsm->fhsm_bottom == bindex) -+ return; -+ -+ br = au_sbr(sb, bindex); -+ bf = br->br_fhsm; -+ AuDebugOn(!bf); -+ mutex_lock(&bf->bf_lock); -+ if (force -+ || au_fhsm_pid(fhsm) -+ || au_fhsm_test_jiffy(sbinfo, br)) -+ err = au_fhsm_stfs(sb, bindex, /*rstfs*/NULL, /*do_lock*/0, -+ /*do_notify*/1); -+ mutex_unlock(&bf->bf_lock); -+} -+ -+void au_fhsm_wrote_all(struct super_block *sb, int force) -+{ -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ /* exclude the bottom */ -+ bbot = au_fhsm_bottom(sb); -+ for (bindex = 0; bindex < bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_fhsm(br->br_perm)) -+ au_fhsm_wrote(sb, bindex, force); -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static __poll_t au_fhsm_poll(struct file *file, struct poll_table_struct *wait) -+{ -+ __poll_t mask; -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ mask = 0; -+ sbinfo = file->private_data; -+ fhsm = &sbinfo->si_fhsm; -+ poll_wait(file, &fhsm->fhsm_wqh, wait); -+ if (atomic_read(&fhsm->fhsm_readable)) -+ mask = EPOLLIN /* | EPOLLRDNORM */; -+ -+ if (!mask) -+ AuDbg("mask 0x%x\n", mask); -+ return mask; -+} -+ -+static int au_fhsm_do_read_one(struct aufs_stbr __user *stbr, -+ struct aufs_stfs *stfs, __s16 brid) -+{ -+ int err; -+ -+ err = copy_to_user(&stbr->stfs, stfs, sizeof(*stfs)); -+ if (!err) -+ err = __put_user(brid, &stbr->brid); -+ if (unlikely(err)) -+ err = -EFAULT; -+ -+ return err; -+} -+ -+static ssize_t au_fhsm_do_read(struct super_block *sb, -+ struct aufs_stbr __user *stbr, size_t count) -+{ -+ ssize_t err; -+ int nstbr; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ struct au_br_fhsm *bf; -+ -+ /* except the bottom branch */ -+ err = 0; -+ nstbr = 0; -+ bbot = au_fhsm_bottom(sb); -+ for (bindex = 0; !err && bindex < bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (!au_br_fhsm(br->br_perm)) -+ continue; -+ -+ bf = br->br_fhsm; -+ mutex_lock(&bf->bf_lock); -+ if (bf->bf_readable) { -+ err = -EFAULT; -+ if (count >= sizeof(*stbr)) -+ err = au_fhsm_do_read_one(stbr++, &bf->bf_stfs, -+ br->br_id); -+ if (!err) { -+ bf->bf_readable = 0; -+ count -= sizeof(*stbr); -+ nstbr++; -+ } -+ } -+ mutex_unlock(&bf->bf_lock); -+ } -+ if (!err) -+ err = sizeof(*stbr) * nstbr; -+ -+ return err; -+} -+ -+static ssize_t au_fhsm_read(struct file *file, char __user *buf, size_t count, -+ loff_t *pos) -+{ -+ ssize_t err; -+ int readable; -+ aufs_bindex_t nfhsm, bindex, bbot; -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ struct au_branch *br; -+ struct super_block *sb; -+ -+ err = 0; -+ sbinfo = file->private_data; -+ fhsm = &sbinfo->si_fhsm; -+need_data: -+ spin_lock_irq(&fhsm->fhsm_wqh.lock); -+ if (!atomic_read(&fhsm->fhsm_readable)) { -+ if (vfsub_file_flags(file) & O_NONBLOCK) -+ err = -EAGAIN; -+ else -+ err = wait_event_interruptible_locked_irq -+ (fhsm->fhsm_wqh, -+ atomic_read(&fhsm->fhsm_readable)); -+ } -+ spin_unlock_irq(&fhsm->fhsm_wqh.lock); -+ if (unlikely(err)) -+ goto out; -+ -+ /* sb may already be dead */ -+ au_rw_read_lock(&sbinfo->si_rwsem); -+ readable = atomic_read(&fhsm->fhsm_readable); -+ if (readable > 0) { -+ sb = sbinfo->si_sb; -+ AuDebugOn(!sb); -+ /* exclude the bottom branch */ -+ nfhsm = 0; -+ bbot = au_fhsm_bottom(sb); -+ for (bindex = 0; bindex < bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_fhsm(br->br_perm)) -+ nfhsm++; -+ } -+ err = -EMSGSIZE; -+ if (nfhsm * sizeof(struct aufs_stbr) <= count) { -+ atomic_set(&fhsm->fhsm_readable, 0); -+ err = au_fhsm_do_read(sbinfo->si_sb, (void __user *)buf, -+ count); -+ } -+ } -+ au_rw_read_unlock(&sbinfo->si_rwsem); -+ if (!readable) -+ goto need_data; -+ -+out: -+ return err; -+} -+ -+static int au_fhsm_release(struct inode *inode, struct file *file) -+{ -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ /* sb may already be dead */ -+ sbinfo = file->private_data; -+ fhsm = &sbinfo->si_fhsm; -+ spin_lock(&fhsm->fhsm_spin); -+ fhsm->fhsm_pid = 0; -+ spin_unlock(&fhsm->fhsm_spin); -+ kobject_put(&sbinfo->si_kobj); -+ -+ return 0; -+} -+ -+static const struct file_operations au_fhsm_fops = { -+ .owner = THIS_MODULE, -+ .llseek = noop_llseek, -+ .read = au_fhsm_read, -+ .poll = au_fhsm_poll, -+ .release = au_fhsm_release -+}; -+ -+int au_fhsm_fd(struct super_block *sb, int oflags) -+{ -+ int err, fd; -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ err = -EPERM; -+ if (unlikely(!capable(CAP_SYS_ADMIN))) -+ goto out; -+ -+ err = -EINVAL; -+ if (unlikely(oflags & ~(O_CLOEXEC | O_NONBLOCK))) -+ goto out; -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ spin_lock(&fhsm->fhsm_spin); -+ if (!fhsm->fhsm_pid) -+ fhsm->fhsm_pid = current->pid; -+ else -+ err = -EBUSY; -+ spin_unlock(&fhsm->fhsm_spin); -+ if (unlikely(err)) -+ goto out; -+ -+ oflags |= O_RDONLY; -+ /* oflags |= FMODE_NONOTIFY; */ -+ fd = anon_inode_getfd("[aufs_fhsm]", &au_fhsm_fops, sbinfo, oflags); -+ err = fd; -+ if (unlikely(fd < 0)) -+ goto out_pid; -+ -+ /* succeed regardless 'fhsm' status */ -+ kobject_get(&sbinfo->si_kobj); -+ si_noflush_read_lock(sb); -+ if (au_ftest_si(sbinfo, FHSM)) -+ au_fhsm_wrote_all(sb, /*force*/0); -+ si_read_unlock(sb); -+ goto out; /* success */ -+ -+out_pid: -+ spin_lock(&fhsm->fhsm_spin); -+ fhsm->fhsm_pid = 0; -+ spin_unlock(&fhsm->fhsm_spin); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_fhsm_br_alloc(struct au_branch *br) -+{ -+ int err; -+ -+ err = 0; -+ br->br_fhsm = kmalloc(sizeof(*br->br_fhsm), GFP_NOFS); -+ if (br->br_fhsm) -+ au_br_fhsm_init(br->br_fhsm); -+ else -+ err = -ENOMEM; -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_fhsm_fin(struct super_block *sb) -+{ -+ au_fhsm_notify(sb, /*val*/-1); -+} -+ -+void au_fhsm_init(struct au_sbinfo *sbinfo) -+{ -+ struct au_fhsm *fhsm; -+ -+ fhsm = &sbinfo->si_fhsm; -+ spin_lock_init(&fhsm->fhsm_spin); -+ init_waitqueue_head(&fhsm->fhsm_wqh); -+ atomic_set(&fhsm->fhsm_readable, 0); -+ fhsm->fhsm_expire -+ = msecs_to_jiffies(AUFS_FHSM_CACHE_DEF_SEC * MSEC_PER_SEC); -+ fhsm->fhsm_bottom = -1; -+} -+ -+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec) -+{ -+ sbinfo->si_fhsm.fhsm_expire -+ = msecs_to_jiffies(sec * MSEC_PER_SEC); -+} -+ -+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo) -+{ -+ unsigned int u; -+ -+ if (!au_ftest_si(sbinfo, FHSM)) -+ return; -+ -+ u = jiffies_to_msecs(sbinfo->si_fhsm.fhsm_expire) / MSEC_PER_SEC; -+ if (u != AUFS_FHSM_CACHE_DEF_SEC) -+ seq_printf(seq, ",fhsm_sec=%u", u); -+} -diff --git a/fs/aufs/file.c b/fs/aufs/file.c -new file mode 100644 -index 000000000..c01b98791 ---- /dev/null -+++ b/fs/aufs/file.c -@@ -0,0 +1,863 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * handling file/dir, and address_space operation -+ */ -+ -+#ifdef CONFIG_AUFS_DEBUG -+#include -+#endif -+#include -+#include "aufs.h" -+ -+/* drop flags for writing */ -+unsigned int au_file_roflags(unsigned int flags) -+{ -+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC); -+ flags |= O_RDONLY | O_NOATIME; -+ return flags; -+} -+ -+/* common functions to regular file and dir */ -+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, -+ struct file *file, int force_wr) -+{ -+ struct file *h_file; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct path h_path; -+ int err; -+ -+ /* a race condition can happen between open and unlink/rmdir */ -+ h_file = ERR_PTR(-ENOENT); -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (au_test_nfsd() && (!h_dentry || d_is_negative(h_dentry))) -+ goto out; -+ h_inode = d_inode(h_dentry); -+ spin_lock(&h_dentry->d_lock); -+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry)) -+ /* || !d_inode(dentry)->i_nlink */ -+ ; -+ spin_unlock(&h_dentry->d_lock); -+ if (unlikely(err)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ br = au_sbr(sb, bindex); -+ err = au_br_test_oflag(flags, br); -+ h_file = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ -+ /* drop flags for writing */ -+ if (au_test_ro(sb, bindex, d_inode(dentry))) { -+ if (force_wr && !(flags & O_WRONLY)) -+ force_wr = 0; -+ flags = au_file_roflags(flags); -+ if (force_wr) { -+ h_file = ERR_PTR(-EROFS); -+ flags = au_file_roflags(flags); -+ if (unlikely(vfsub_native_ro(h_inode) -+ || IS_APPEND(h_inode))) -+ goto out; -+ flags &= ~O_ACCMODE; -+ flags |= O_WRONLY; -+ } -+ } -+ flags &= ~O_CREAT; -+ au_lcnt_inc(&br->br_nfiles); -+ h_path.dentry = h_dentry; -+ h_path.mnt = au_br_mnt(br); -+ h_file = vfsub_dentry_open(&h_path, flags); -+ if (IS_ERR(h_file)) -+ goto out_br; -+ -+ if (flags & __FMODE_EXEC) { -+ err = deny_write_access(h_file); -+ if (unlikely(err)) { -+ fput(h_file); -+ h_file = ERR_PTR(err); -+ goto out_br; -+ } -+ } -+ fsnotify_open(h_file); -+ goto out; /* success */ -+ -+out_br: -+ au_lcnt_dec(&br->br_nfiles); -+out: -+ return h_file; -+} -+ -+static int au_cmoo(struct dentry *dentry) -+{ -+ int err, cmoo, matched; -+ unsigned int udba; -+ struct path h_path; -+ struct au_pin pin; -+ struct au_cp_generic cpg = { -+ .dentry = dentry, -+ .bdst = -1, -+ .bsrc = -1, -+ .len = -1, -+ .pin = &pin, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN -+ }; -+ struct inode *delegated; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ pid_t pid; -+ struct au_branch *br; -+ struct dentry *parent; -+ struct au_hinode *hdir; -+ -+ DiMustWriteLock(dentry); -+ IiMustWriteLock(d_inode(dentry)); -+ -+ err = 0; -+ if (IS_ROOT(dentry)) -+ goto out; -+ cpg.bsrc = au_dbtop(dentry); -+ if (!cpg.bsrc) -+ goto out; -+ -+ sb = dentry->d_sb; -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ pid = au_fhsm_pid(fhsm); -+ rcu_read_lock(); -+ matched = (pid -+ && (current->pid == pid -+ || rcu_dereference(current->real_parent)->pid == pid)); -+ rcu_read_unlock(); -+ if (matched) -+ goto out; -+ -+ br = au_sbr(sb, cpg.bsrc); -+ cmoo = au_br_cmoo(br->br_perm); -+ if (!cmoo) -+ goto out; -+ if (!d_is_reg(dentry)) -+ cmoo &= AuBrAttr_COO_ALL; -+ if (!cmoo) -+ goto out; -+ -+ parent = dget_parent(dentry); -+ di_write_lock_parent(parent); -+ err = au_wbr_do_copyup_bu(dentry, cpg.bsrc - 1); -+ cpg.bdst = err; -+ if (unlikely(err < 0)) { -+ err = 0; /* there is no upper writable branch */ -+ goto out_dgrade; -+ } -+ AuDbg("bsrc %d, bdst %d\n", cpg.bsrc, cpg.bdst); -+ -+ /* do not respect the coo attrib for the target branch */ -+ err = au_cpup_dirs(dentry, cpg.bdst); -+ if (unlikely(err)) -+ goto out_dgrade; -+ -+ di_downgrade_lock(parent, AuLock_IR); -+ udba = au_opt_udba(sb); -+ err = au_pin(&pin, dentry, cpg.bdst, udba, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ err = au_sio_cpup_simple(&cpg); -+ au_unpin(&pin); -+ if (unlikely(err)) -+ goto out_parent; -+ if (!(cmoo & AuBrWAttr_MOO)) -+ goto out_parent; /* success */ -+ -+ err = au_pin(&pin, dentry, cpg.bsrc, udba, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ h_path.mnt = au_br_mnt(br); -+ h_path.dentry = au_h_dptr(dentry, cpg.bsrc); -+ hdir = au_hi(d_inode(parent), cpg.bsrc); -+ delegated = NULL; -+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1); -+ au_unpin(&pin); -+ /* todo: keep h_dentry or not? */ -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ if (unlikely(err)) { -+ pr_err("unlink %pd after coo failed (%d), ignored\n", -+ dentry, err); -+ err = 0; -+ } -+ goto out_parent; /* success */ -+ -+out_dgrade: -+ di_downgrade_lock(parent, AuLock_IR); -+out_parent: -+ di_read_unlock(parent, AuLock_IR); -+ dput(parent); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_do_open(struct file *file, struct au_do_open_args *args) -+{ -+ int err, aopen = args->aopen; -+ struct dentry *dentry; -+ struct au_finfo *finfo; -+ -+ if (!aopen) -+ err = au_finfo_init(file, args->fidir); -+ else { -+ lockdep_off(); -+ err = au_finfo_init(file, args->fidir); -+ lockdep_on(); -+ } -+ if (unlikely(err)) -+ goto out; -+ -+ dentry = file->f_path.dentry; -+ AuDebugOn(IS_ERR_OR_NULL(dentry)); -+ di_write_lock_child(dentry); -+ err = au_cmoo(dentry); -+ di_downgrade_lock(dentry, AuLock_IR); -+ if (!err) { -+ if (!aopen) -+ err = args->open(file, vfsub_file_flags(file), NULL); -+ else { -+ lockdep_off(); -+ err = args->open(file, vfsub_file_flags(file), -+ args->h_file); -+ lockdep_on(); -+ } -+ } -+ di_read_unlock(dentry, AuLock_IR); -+ -+ finfo = au_fi(file); -+ if (!err) { -+ finfo->fi_file = file; -+ au_hbl_add(&finfo->fi_hlist, -+ &au_sbi(file->f_path.dentry->d_sb)->si_files); -+ } -+ if (!aopen) -+ fi_write_unlock(file); -+ else { -+ lockdep_off(); -+ fi_write_unlock(file); -+ lockdep_on(); -+ } -+ if (unlikely(err)) { -+ finfo->fi_hdir = NULL; -+ au_finfo_fin(file); -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_reopen_nondir(struct file *file) -+{ -+ int err; -+ aufs_bindex_t btop; -+ struct dentry *dentry; -+ struct au_branch *br; -+ struct file *h_file, *h_file_tmp; -+ -+ dentry = file->f_path.dentry; -+ btop = au_dbtop(dentry); -+ br = au_sbr(dentry->d_sb, btop); -+ h_file_tmp = NULL; -+ if (au_fbtop(file) == btop) { -+ h_file = au_hf_top(file); -+ if (file->f_mode == h_file->f_mode) -+ return 0; /* success */ -+ h_file_tmp = h_file; -+ get_file(h_file_tmp); -+ au_lcnt_inc(&br->br_nfiles); -+ au_set_h_fptr(file, btop, NULL); -+ } -+ AuDebugOn(au_fi(file)->fi_hdir); -+ /* -+ * it can happen -+ * file exists on both of rw and ro -+ * open --> dbtop and fbtop are both 0 -+ * prepend a branch as rw, "rw" become ro -+ * remove rw/file -+ * delete the top branch, "rw" becomes rw again -+ * --> dbtop is 1, fbtop is still 0 -+ * write --> fbtop is 0 but dbtop is 1 -+ */ -+ /* AuDebugOn(au_fbtop(file) < btop); */ -+ -+ h_file = au_h_open(dentry, btop, vfsub_file_flags(file) & ~O_TRUNC, -+ file, /*force_wr*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) { -+ if (h_file_tmp) { -+ /* revert */ -+ au_set_h_fptr(file, btop, h_file_tmp); -+ h_file_tmp = NULL; -+ } -+ goto out; /* todo: close all? */ -+ } -+ -+ err = 0; -+ au_set_fbtop(file, btop); -+ au_set_h_fptr(file, btop, h_file); -+ au_update_figen(file); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ -+out: -+ if (h_file_tmp) { -+ fput(h_file_tmp); -+ au_lcnt_dec(&br->br_nfiles); -+ } -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt, -+ struct dentry *hi_wh) -+{ -+ int err; -+ aufs_bindex_t btop; -+ struct au_dinfo *dinfo; -+ struct dentry *h_dentry; -+ struct au_hdentry *hdp; -+ -+ dinfo = au_di(file->f_path.dentry); -+ AuRwMustWriteLock(&dinfo->di_rwsem); -+ -+ btop = dinfo->di_btop; -+ dinfo->di_btop = btgt; -+ hdp = au_hdentry(dinfo, btgt); -+ h_dentry = hdp->hd_dentry; -+ hdp->hd_dentry = hi_wh; -+ err = au_reopen_nondir(file); -+ hdp->hd_dentry = h_dentry; -+ dinfo->di_btop = btop; -+ -+ return err; -+} -+ -+static int au_ready_to_write_wh(struct file *file, loff_t len, -+ aufs_bindex_t bcpup, struct au_pin *pin) -+{ -+ int err; -+ struct inode *inode, *h_inode; -+ struct dentry *h_dentry, *hi_wh; -+ struct au_cp_generic cpg = { -+ .dentry = file->f_path.dentry, -+ .bdst = bcpup, -+ .bsrc = -1, -+ .len = len, -+ .pin = pin -+ }; -+ -+ au_update_dbtop(cpg.dentry); -+ inode = d_inode(cpg.dentry); -+ h_inode = NULL; -+ if (au_dbtop(cpg.dentry) <= bcpup -+ && au_dbbot(cpg.dentry) >= bcpup) { -+ h_dentry = au_h_dptr(cpg.dentry, bcpup); -+ if (h_dentry && d_is_positive(h_dentry)) -+ h_inode = d_inode(h_dentry); -+ } -+ hi_wh = au_hi_wh(inode, bcpup); -+ if (!hi_wh && !h_inode) -+ err = au_sio_cpup_wh(&cpg, file); -+ else -+ /* already copied-up after unlink */ -+ err = au_reopen_wh(file, bcpup, hi_wh); -+ -+ if (!err -+ && (inode->i_nlink > 1 -+ || (inode->i_state & I_LINKABLE)) -+ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK)) -+ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup)); -+ -+ return err; -+} -+ -+/* -+ * prepare the @file for writing. -+ */ -+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin) -+{ -+ int err; -+ aufs_bindex_t dbtop; -+ struct dentry *parent; -+ struct inode *inode; -+ struct super_block *sb; -+ struct file *h_file; -+ struct au_cp_generic cpg = { -+ .dentry = file->f_path.dentry, -+ .bdst = -1, -+ .bsrc = -1, -+ .len = len, -+ .pin = pin, -+ .flags = AuCpup_DTIME -+ }; -+ -+ sb = cpg.dentry->d_sb; -+ inode = d_inode(cpg.dentry); -+ cpg.bsrc = au_fbtop(file); -+ err = au_test_ro(sb, cpg.bsrc, inode); -+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) { -+ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE, -+ /*flags*/0); -+ goto out; -+ } -+ -+ /* need to cpup or reopen */ -+ parent = dget_parent(cpg.dentry); -+ di_write_lock_parent(parent); -+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry); -+ cpg.bdst = err; -+ if (unlikely(err < 0)) -+ goto out_dgrade; -+ err = 0; -+ -+ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) { -+ err = au_cpup_dirs(cpg.dentry, cpg.bdst); -+ if (unlikely(err)) -+ goto out_dgrade; -+ } -+ -+ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out_dgrade; -+ -+ dbtop = au_dbtop(cpg.dentry); -+ if (dbtop <= cpg.bdst) -+ cpg.bsrc = cpg.bdst; -+ -+ if (dbtop <= cpg.bdst /* just reopen */ -+ || !d_unhashed(cpg.dentry) /* copyup and reopen */ -+ ) { -+ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0); -+ if (IS_ERR(h_file)) -+ err = PTR_ERR(h_file); -+ else { -+ di_downgrade_lock(parent, AuLock_IR); -+ if (dbtop > cpg.bdst) -+ err = au_sio_cpup_simple(&cpg); -+ if (!err) -+ err = au_reopen_nondir(file); -+ au_h_open_post(cpg.dentry, cpg.bsrc, h_file); -+ } -+ } else { /* copyup as wh and reopen */ -+ /* -+ * since writable hfsplus branch is not supported, -+ * h_open_pre/post() are unnecessary. -+ */ -+ err = au_ready_to_write_wh(file, len, cpg.bdst, pin); -+ di_downgrade_lock(parent, AuLock_IR); -+ } -+ -+ if (!err) { -+ au_pin_set_parent_lflag(pin, /*lflag*/0); -+ goto out_dput; /* success */ -+ } -+ au_unpin(pin); -+ goto out_unlock; -+ -+out_dgrade: -+ di_downgrade_lock(parent, AuLock_IR); -+out_unlock: -+ di_read_unlock(parent, AuLock_IR); -+out_dput: -+ dput(parent); -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_do_flush(struct file *file, fl_owner_t id, -+ int (*flush)(struct file *file, fl_owner_t id)) -+{ -+ int err; -+ struct super_block *sb; -+ struct inode *inode; -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ si_noflush_read_lock(sb); -+ fi_read_lock(file); -+ ii_read_lock_child(inode); -+ -+ err = flush(file, id); -+ au_cpup_attr_timesizes(inode); -+ -+ ii_read_unlock(inode); -+ fi_read_unlock(file); -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_file_refresh_by_inode(struct file *file, int *need_reopen) -+{ -+ int err; -+ struct au_pin pin; -+ struct au_finfo *finfo; -+ struct dentry *parent, *hi_wh; -+ struct inode *inode; -+ struct super_block *sb; -+ struct au_cp_generic cpg = { -+ .dentry = file->f_path.dentry, -+ .bdst = -1, -+ .bsrc = -1, -+ .len = -1, -+ .pin = &pin, -+ .flags = AuCpup_DTIME -+ }; -+ -+ FiMustWriteLock(file); -+ -+ err = 0; -+ finfo = au_fi(file); -+ sb = cpg.dentry->d_sb; -+ inode = d_inode(cpg.dentry); -+ cpg.bdst = au_ibtop(inode); -+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry)) -+ goto out; -+ -+ parent = dget_parent(cpg.dentry); -+ if (au_test_ro(sb, cpg.bdst, inode)) { -+ di_read_lock_parent(parent, !AuLock_IR); -+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry); -+ cpg.bdst = err; -+ di_read_unlock(parent, !AuLock_IR); -+ if (unlikely(err < 0)) -+ goto out_parent; -+ err = 0; -+ } -+ -+ di_read_lock_parent(parent, AuLock_IR); -+ hi_wh = au_hi_wh(inode, cpg.bdst); -+ if (!S_ISDIR(inode->i_mode) -+ && au_opt_test(au_mntflags(sb), PLINK) -+ && au_plink_test(inode) -+ && !d_unhashed(cpg.dentry) -+ && cpg.bdst < au_dbtop(cpg.dentry)) { -+ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ /* always superio. */ -+ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (!err) { -+ err = au_sio_cpup_simple(&cpg); -+ au_unpin(&pin); -+ } -+ } else if (hi_wh) { -+ /* already copied-up after unlink */ -+ err = au_reopen_wh(file, cpg.bdst, hi_wh); -+ *need_reopen = 0; -+ } -+ -+out_unlock: -+ di_read_unlock(parent, AuLock_IR); -+out_parent: -+ dput(parent); -+out: -+ return err; -+} -+ -+static void au_do_refresh_dir(struct file *file) -+{ -+ aufs_bindex_t bindex, bbot, new_bindex, brid; -+ struct au_hfile *p, tmp, *q; -+ struct au_finfo *finfo; -+ struct super_block *sb; -+ struct au_fidir *fidir; -+ -+ FiMustWriteLock(file); -+ -+ sb = file->f_path.dentry->d_sb; -+ finfo = au_fi(file); -+ fidir = finfo->fi_hdir; -+ AuDebugOn(!fidir); -+ p = fidir->fd_hfile + finfo->fi_btop; -+ brid = p->hf_br->br_id; -+ bbot = fidir->fd_bbot; -+ for (bindex = finfo->fi_btop; bindex <= bbot; bindex++, p++) { -+ if (!p->hf_file) -+ continue; -+ -+ new_bindex = au_br_index(sb, p->hf_br->br_id); -+ if (new_bindex == bindex) -+ continue; -+ if (new_bindex < 0) { -+ au_set_h_fptr(file, bindex, NULL); -+ continue; -+ } -+ -+ /* swap two lower inode, and loop again */ -+ q = fidir->fd_hfile + new_bindex; -+ tmp = *q; -+ *q = *p; -+ *p = tmp; -+ if (tmp.hf_file) { -+ bindex--; -+ p--; -+ } -+ } -+ -+ p = fidir->fd_hfile; -+ if (!au_test_mmapped(file) && !d_unlinked(file->f_path.dentry)) { -+ bbot = au_sbbot(sb); -+ for (finfo->fi_btop = 0; finfo->fi_btop <= bbot; -+ finfo->fi_btop++, p++) -+ if (p->hf_file) { -+ if (file_inode(p->hf_file)) -+ break; -+ au_hfput(p, /*execed*/0); -+ } -+ } else { -+ bbot = au_br_index(sb, brid); -+ for (finfo->fi_btop = 0; finfo->fi_btop < bbot; -+ finfo->fi_btop++, p++) -+ if (p->hf_file) -+ au_hfput(p, /*execed*/0); -+ bbot = au_sbbot(sb); -+ } -+ -+ p = fidir->fd_hfile + bbot; -+ for (fidir->fd_bbot = bbot; fidir->fd_bbot >= finfo->fi_btop; -+ fidir->fd_bbot--, p--) -+ if (p->hf_file) { -+ if (file_inode(p->hf_file)) -+ break; -+ au_hfput(p, /*execed*/0); -+ } -+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop); -+} -+ -+/* -+ * after branch manipulating, refresh the file. -+ */ -+static int refresh_file(struct file *file, int (*reopen)(struct file *file)) -+{ -+ int err, need_reopen, nbr; -+ aufs_bindex_t bbot, bindex; -+ struct dentry *dentry; -+ struct super_block *sb; -+ struct au_finfo *finfo; -+ struct au_hfile *hfile; -+ -+ dentry = file->f_path.dentry; -+ sb = dentry->d_sb; -+ nbr = au_sbbot(sb) + 1; -+ finfo = au_fi(file); -+ if (!finfo->fi_hdir) { -+ hfile = &finfo->fi_htop; -+ AuDebugOn(!hfile->hf_file); -+ bindex = au_br_index(sb, hfile->hf_br->br_id); -+ AuDebugOn(bindex < 0); -+ if (bindex != finfo->fi_btop) -+ au_set_fbtop(file, bindex); -+ } else { -+ err = au_fidir_realloc(finfo, nbr, /*may_shrink*/0); -+ if (unlikely(err)) -+ goto out; -+ au_do_refresh_dir(file); -+ } -+ -+ err = 0; -+ need_reopen = 1; -+ if (!au_test_mmapped(file)) -+ err = au_file_refresh_by_inode(file, &need_reopen); -+ if (finfo->fi_hdir) -+ /* harmless if err */ -+ au_fidir_realloc(finfo, nbr, /*may_shrink*/1); -+ if (!err && need_reopen && !d_unlinked(dentry)) -+ err = reopen(file); -+ if (!err) { -+ au_update_figen(file); -+ goto out; /* success */ -+ } -+ -+ /* error, close all lower files */ -+ if (finfo->fi_hdir) { -+ bbot = au_fbbot_dir(file); -+ for (bindex = au_fbtop(file); bindex <= bbot; bindex++) -+ au_set_h_fptr(file, bindex, NULL); -+ } -+ -+out: -+ return err; -+} -+ -+/* common function to regular file and dir */ -+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), -+ int wlock, unsigned int fi_lsc) -+{ -+ int err; -+ unsigned int sigen, figen; -+ aufs_bindex_t btop; -+ unsigned char pseudo_link; -+ struct dentry *dentry; -+ struct inode *inode; -+ -+ err = 0; -+ dentry = file->f_path.dentry; -+ inode = d_inode(dentry); -+ sigen = au_sigen(dentry->d_sb); -+ fi_write_lock_nested(file, fi_lsc); -+ figen = au_figen(file); -+ if (!fi_lsc) -+ di_write_lock_child(dentry); -+ else -+ di_write_lock_child2(dentry); -+ btop = au_dbtop(dentry); -+ pseudo_link = (btop != au_ibtop(inode)); -+ if (sigen == figen && !pseudo_link && au_fbtop(file) == btop) { -+ if (!wlock) { -+ di_downgrade_lock(dentry, AuLock_IR); -+ fi_downgrade_lock(file); -+ } -+ goto out; /* success */ -+ } -+ -+ AuDbg("sigen %d, figen %d\n", sigen, figen); -+ if (au_digen_test(dentry, sigen)) { -+ err = au_reval_dpath(dentry, sigen); -+ AuDebugOn(!err && au_digen_test(dentry, sigen)); -+ } -+ -+ if (!err) -+ err = refresh_file(file, reopen); -+ if (!err) { -+ if (!wlock) { -+ di_downgrade_lock(dentry, AuLock_IR); -+ fi_downgrade_lock(file); -+ } -+ } else { -+ di_write_unlock(dentry); -+ fi_write_unlock(file); -+ } -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* cf. aufs_nopage() */ -+/* for madvise(2) */ -+static int aufs_readpage(struct file *file __maybe_unused, struct page *page) -+{ -+ unlock_page(page); -+ return 0; -+} -+ -+/* it will never be called, but necessary to support O_DIRECT */ -+static ssize_t aufs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) -+{ BUG(); return 0; } -+ -+/* they will never be called. */ -+#ifdef CONFIG_AUFS_DEBUG -+static int aufs_write_begin(struct file *file, struct address_space *mapping, -+ loff_t pos, unsigned len, unsigned flags, -+ struct page **pagep, void **fsdata) -+{ AuUnsupport(); return 0; } -+static int aufs_write_end(struct file *file, struct address_space *mapping, -+ loff_t pos, unsigned len, unsigned copied, -+ struct page *page, void *fsdata) -+{ AuUnsupport(); return 0; } -+static int aufs_writepage(struct page *page, struct writeback_control *wbc) -+{ AuUnsupport(); return 0; } -+ -+static int aufs_set_page_dirty(struct page *page) -+{ AuUnsupport(); return 0; } -+static void aufs_invalidatepage(struct page *page, unsigned int offset, -+ unsigned int length) -+{ AuUnsupport(); } -+static int aufs_releasepage(struct page *page, gfp_t gfp) -+{ AuUnsupport(); return 0; } -+#if 0 /* called by memory compaction regardless file */ -+static int aufs_migratepage(struct address_space *mapping, struct page *newpage, -+ struct page *page, enum migrate_mode mode) -+{ AuUnsupport(); return 0; } -+#endif -+static bool aufs_isolate_page(struct page *page, isolate_mode_t mode) -+{ AuUnsupport(); return true; } -+static void aufs_putback_page(struct page *page) -+{ AuUnsupport(); } -+static int aufs_launder_page(struct page *page) -+{ AuUnsupport(); return 0; } -+static int aufs_is_partially_uptodate(struct page *page, -+ unsigned long from, -+ unsigned long count) -+{ AuUnsupport(); return 0; } -+static void aufs_is_dirty_writeback(struct page *page, bool *dirty, -+ bool *writeback) -+{ AuUnsupport(); } -+static int aufs_error_remove_page(struct address_space *mapping, -+ struct page *page) -+{ AuUnsupport(); return 0; } -+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file, -+ sector_t *span) -+{ AuUnsupport(); return 0; } -+static void aufs_swap_deactivate(struct file *file) -+{ AuUnsupport(); } -+#endif /* CONFIG_AUFS_DEBUG */ -+ -+const struct address_space_operations aufs_aop = { -+ .readpage = aufs_readpage, -+ .direct_IO = aufs_direct_IO, -+#ifdef CONFIG_AUFS_DEBUG -+ .writepage = aufs_writepage, -+ /* no writepages, because of writepage */ -+ .set_page_dirty = aufs_set_page_dirty, -+ /* no readpages, because of readpage */ -+ .write_begin = aufs_write_begin, -+ .write_end = aufs_write_end, -+ /* no bmap, no block device */ -+ .invalidatepage = aufs_invalidatepage, -+ .releasepage = aufs_releasepage, -+ /* is fallback_migrate_page ok? */ -+ /* .migratepage = aufs_migratepage, */ -+ .isolate_page = aufs_isolate_page, -+ .putback_page = aufs_putback_page, -+ .launder_page = aufs_launder_page, -+ .is_partially_uptodate = aufs_is_partially_uptodate, -+ .is_dirty_writeback = aufs_is_dirty_writeback, -+ .error_remove_page = aufs_error_remove_page, -+ .swap_activate = aufs_swap_activate, -+ .swap_deactivate = aufs_swap_deactivate -+#endif /* CONFIG_AUFS_DEBUG */ -+}; -diff --git a/fs/aufs/file.h b/fs/aufs/file.h -new file mode 100644 -index 000000000..11bc65480 ---- /dev/null -+++ b/fs/aufs/file.h -@@ -0,0 +1,341 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * file operations -+ */ -+ -+#ifndef __AUFS_FILE_H__ -+#define __AUFS_FILE_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+#include "rwsem.h" -+ -+struct au_branch; -+struct au_hfile { -+ struct file *hf_file; -+ struct au_branch *hf_br; -+}; -+ -+struct au_vdir; -+struct au_fidir { -+ aufs_bindex_t fd_bbot; -+ aufs_bindex_t fd_nent; -+ struct au_vdir *fd_vdir_cache; -+ struct au_hfile fd_hfile[]; -+}; -+ -+static inline int au_fidir_sz(int nent) -+{ -+ AuDebugOn(nent < 0); -+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent; -+} -+ -+struct au_finfo { -+ atomic_t fi_generation; -+ -+ struct au_rwsem fi_rwsem; -+ aufs_bindex_t fi_btop; -+ -+ /* do not union them */ -+ struct { /* for non-dir */ -+ struct au_hfile fi_htop; -+ atomic_t fi_mmapped; -+ }; -+ struct au_fidir *fi_hdir; /* for dir only */ -+ -+ struct hlist_bl_node fi_hlist; -+ struct file *fi_file; /* very ugly */ -+} ____cacheline_aligned_in_smp; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* file.c */ -+extern const struct address_space_operations aufs_aop; -+unsigned int au_file_roflags(unsigned int flags); -+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, -+ struct file *file, int force_wr); -+struct au_do_open_args { -+ int aopen; -+ int (*open)(struct file *file, int flags, -+ struct file *h_file); -+ struct au_fidir *fidir; -+ struct file *h_file; -+}; -+int au_do_open(struct file *file, struct au_do_open_args *args); -+int au_reopen_nondir(struct file *file); -+struct au_pin; -+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin); -+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), -+ int wlock, unsigned int fi_lsc); -+int au_do_flush(struct file *file, fl_owner_t id, -+ int (*flush)(struct file *file, fl_owner_t id)); -+ -+/* poll.c */ -+#ifdef CONFIG_AUFS_POLL -+__poll_t aufs_poll(struct file *file, struct poll_table_struct *pt); -+#endif -+ -+#ifdef CONFIG_AUFS_BR_HFSPLUS -+/* hfsplus.c */ -+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex, -+ int force_wr); -+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex, -+ struct file *h_file); -+#else -+AuStub(struct file *, au_h_open_pre, return NULL, struct dentry *dentry, -+ aufs_bindex_t bindex, int force_wr) -+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex, -+ struct file *h_file); -+#endif -+ -+/* f_op.c */ -+extern const struct file_operations aufs_file_fop; -+int au_do_open_nondir(struct file *file, int flags, struct file *h_file); -+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file); -+struct file *au_read_pre(struct file *file, int keep_fi, unsigned int lsc); -+ -+/* finfo.c */ -+void au_hfput(struct au_hfile *hf, int execed); -+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, -+ struct file *h_file); -+ -+void au_update_figen(struct file *file); -+struct au_fidir *au_fidir_alloc(struct super_block *sb); -+int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink); -+ -+void au_fi_init_once(void *_fi); -+void au_finfo_fin(struct file *file); -+int au_finfo_init(struct file *file, struct au_fidir *fidir); -+ -+/* ioctl.c */ -+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg); -+#ifdef CONFIG_COMPAT -+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd, -+ unsigned long arg); -+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd, -+ unsigned long arg); -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct au_finfo *au_fi(struct file *file) -+{ -+ return file->private_data; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define fi_read_lock(f) au_rw_read_lock(&au_fi(f)->fi_rwsem) -+#define fi_write_lock(f) au_rw_write_lock(&au_fi(f)->fi_rwsem) -+#define fi_read_trylock(f) au_rw_read_trylock(&au_fi(f)->fi_rwsem) -+#define fi_write_trylock(f) au_rw_write_trylock(&au_fi(f)->fi_rwsem) -+/* -+#define fi_read_trylock_nested(f) \ -+ au_rw_read_trylock_nested(&au_fi(f)->fi_rwsem) -+#define fi_write_trylock_nested(f) \ -+ au_rw_write_trylock_nested(&au_fi(f)->fi_rwsem) -+*/ -+ -+#define fi_read_unlock(f) au_rw_read_unlock(&au_fi(f)->fi_rwsem) -+#define fi_write_unlock(f) au_rw_write_unlock(&au_fi(f)->fi_rwsem) -+#define fi_downgrade_lock(f) au_rw_dgrade_lock(&au_fi(f)->fi_rwsem) -+ -+/* lock subclass for finfo */ -+enum { -+ AuLsc_FI_1, -+ AuLsc_FI_2 -+}; -+ -+static inline void fi_read_lock_nested(struct file *f, unsigned int lsc) -+{ -+ au_rw_read_lock_nested(&au_fi(f)->fi_rwsem, lsc); -+} -+ -+static inline void fi_write_lock_nested(struct file *f, unsigned int lsc) -+{ -+ au_rw_write_lock_nested(&au_fi(f)->fi_rwsem, lsc); -+} -+ -+/* -+ * fi_read_lock_1, fi_write_lock_1, -+ * fi_read_lock_2, fi_write_lock_2 -+ */ -+#define AuReadLockFunc(name) \ -+static inline void fi_read_lock_##name(struct file *f) \ -+{ fi_read_lock_nested(f, AuLsc_FI_##name); } -+ -+#define AuWriteLockFunc(name) \ -+static inline void fi_write_lock_##name(struct file *f) \ -+{ fi_write_lock_nested(f, AuLsc_FI_##name); } -+ -+#define AuRWLockFuncs(name) \ -+ AuReadLockFunc(name) \ -+ AuWriteLockFunc(name) -+ -+AuRWLockFuncs(1); -+AuRWLockFuncs(2); -+ -+#undef AuReadLockFunc -+#undef AuWriteLockFunc -+#undef AuRWLockFuncs -+ -+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem) -+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem) -+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem) -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* todo: hard/soft set? */ -+static inline aufs_bindex_t au_fbtop(struct file *file) -+{ -+ FiMustAnyLock(file); -+ return au_fi(file)->fi_btop; -+} -+ -+static inline aufs_bindex_t au_fbbot_dir(struct file *file) -+{ -+ FiMustAnyLock(file); -+ AuDebugOn(!au_fi(file)->fi_hdir); -+ return au_fi(file)->fi_hdir->fd_bbot; -+} -+ -+static inline struct au_vdir *au_fvdir_cache(struct file *file) -+{ -+ FiMustAnyLock(file); -+ AuDebugOn(!au_fi(file)->fi_hdir); -+ return au_fi(file)->fi_hdir->fd_vdir_cache; -+} -+ -+static inline void au_set_fbtop(struct file *file, aufs_bindex_t bindex) -+{ -+ FiMustWriteLock(file); -+ au_fi(file)->fi_btop = bindex; -+} -+ -+static inline void au_set_fbbot_dir(struct file *file, aufs_bindex_t bindex) -+{ -+ FiMustWriteLock(file); -+ AuDebugOn(!au_fi(file)->fi_hdir); -+ au_fi(file)->fi_hdir->fd_bbot = bindex; -+} -+ -+static inline void au_set_fvdir_cache(struct file *file, -+ struct au_vdir *vdir_cache) -+{ -+ FiMustWriteLock(file); -+ AuDebugOn(!au_fi(file)->fi_hdir); -+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache; -+} -+ -+static inline struct file *au_hf_top(struct file *file) -+{ -+ FiMustAnyLock(file); -+ AuDebugOn(au_fi(file)->fi_hdir); -+ return au_fi(file)->fi_htop.hf_file; -+} -+ -+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex) -+{ -+ FiMustAnyLock(file); -+ AuDebugOn(!au_fi(file)->fi_hdir); -+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file; -+} -+ -+/* todo: memory barrier? */ -+static inline unsigned int au_figen(struct file *f) -+{ -+ return atomic_read(&au_fi(f)->fi_generation); -+} -+ -+static inline void au_set_mmapped(struct file *f) -+{ -+ if (atomic_inc_return(&au_fi(f)->fi_mmapped)) -+ return; -+ pr_warn("fi_mmapped wrapped around\n"); -+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped)) -+ ; -+} -+ -+static inline void au_unset_mmapped(struct file *f) -+{ -+ atomic_dec(&au_fi(f)->fi_mmapped); -+} -+ -+static inline int au_test_mmapped(struct file *f) -+{ -+ return atomic_read(&au_fi(f)->fi_mmapped); -+} -+ -+/* customize vma->vm_file */ -+ -+static inline void au_do_vm_file_reset(struct vm_area_struct *vma, -+ struct file *file) -+{ -+ struct file *f; -+ -+ f = vma->vm_file; -+ get_file(file); -+ vma->vm_file = file; -+ fput(f); -+} -+ -+#ifdef CONFIG_MMU -+#define AuDbgVmRegion(file, vma) do {} while (0) -+ -+static inline void au_vm_file_reset(struct vm_area_struct *vma, -+ struct file *file) -+{ -+ au_do_vm_file_reset(vma, file); -+} -+#else -+#define AuDbgVmRegion(file, vma) \ -+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file)) -+ -+static inline void au_vm_file_reset(struct vm_area_struct *vma, -+ struct file *file) -+{ -+ struct file *f; -+ -+ au_do_vm_file_reset(vma, file); -+ f = vma->vm_region->vm_file; -+ get_file(file); -+ vma->vm_region->vm_file = file; -+ fput(f); -+} -+#endif /* CONFIG_MMU */ -+ -+/* handle vma->vm_prfile */ -+static inline void au_vm_prfile_set(struct vm_area_struct *vma, -+ struct file *file) -+{ -+ get_file(file); -+ vma->vm_prfile = file; -+#ifndef CONFIG_MMU -+ get_file(file); -+ vma->vm_region->vm_prfile = file; -+#endif -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_FILE_H__ */ -diff --git a/fs/aufs/finfo.c b/fs/aufs/finfo.c -new file mode 100644 -index 000000000..44636ce6c ---- /dev/null -+++ b/fs/aufs/finfo.c -@@ -0,0 +1,149 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * file private data -+ */ -+ -+#include "aufs.h" -+ -+void au_hfput(struct au_hfile *hf, int execed) -+{ -+ if (execed) -+ allow_write_access(hf->hf_file); -+ fput(hf->hf_file); -+ hf->hf_file = NULL; -+ au_lcnt_dec(&hf->hf_br->br_nfiles); -+ hf->hf_br = NULL; -+} -+ -+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val) -+{ -+ struct au_finfo *finfo = au_fi(file); -+ struct au_hfile *hf; -+ struct au_fidir *fidir; -+ -+ fidir = finfo->fi_hdir; -+ if (!fidir) { -+ AuDebugOn(finfo->fi_btop != bindex); -+ hf = &finfo->fi_htop; -+ } else -+ hf = fidir->fd_hfile + bindex; -+ -+ if (hf && hf->hf_file) -+ au_hfput(hf, vfsub_file_execed(file)); -+ if (val) { -+ FiMustWriteLock(file); -+ AuDebugOn(IS_ERR_OR_NULL(file->f_path.dentry)); -+ hf->hf_file = val; -+ hf->hf_br = au_sbr(file->f_path.dentry->d_sb, bindex); -+ } -+} -+ -+void au_update_figen(struct file *file) -+{ -+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_path.dentry)); -+ /* smp_mb(); */ /* atomic_set */ -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_fidir *au_fidir_alloc(struct super_block *sb) -+{ -+ struct au_fidir *fidir; -+ int nbr; -+ -+ nbr = au_sbbot(sb) + 1; -+ if (nbr < 2) -+ nbr = 2; /* initial allocate for 2 branches */ -+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS); -+ if (fidir) { -+ fidir->fd_bbot = -1; -+ fidir->fd_nent = nbr; -+ } -+ -+ return fidir; -+} -+ -+int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink) -+{ -+ int err; -+ struct au_fidir *fidir, *p; -+ -+ AuRwMustWriteLock(&finfo->fi_rwsem); -+ fidir = finfo->fi_hdir; -+ AuDebugOn(!fidir); -+ -+ err = -ENOMEM; -+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr), -+ GFP_NOFS, may_shrink); -+ if (p) { -+ p->fd_nent = nbr; -+ finfo->fi_hdir = p; -+ err = 0; -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_finfo_fin(struct file *file) -+{ -+ struct au_finfo *finfo; -+ -+ au_lcnt_dec(&au_sbi(file->f_path.dentry->d_sb)->si_nfiles); -+ -+ finfo = au_fi(file); -+ AuDebugOn(finfo->fi_hdir); -+ AuRwDestroy(&finfo->fi_rwsem); -+ au_cache_free_finfo(finfo); -+} -+ -+void au_fi_init_once(void *_finfo) -+{ -+ struct au_finfo *finfo = _finfo; -+ -+ au_rw_init(&finfo->fi_rwsem); -+} -+ -+int au_finfo_init(struct file *file, struct au_fidir *fidir) -+{ -+ int err; -+ struct au_finfo *finfo; -+ struct dentry *dentry; -+ -+ err = -ENOMEM; -+ dentry = file->f_path.dentry; -+ finfo = au_cache_alloc_finfo(); -+ if (unlikely(!finfo)) -+ goto out; -+ -+ err = 0; -+ au_lcnt_inc(&au_sbi(dentry->d_sb)->si_nfiles); -+ au_rw_write_lock(&finfo->fi_rwsem); -+ finfo->fi_btop = -1; -+ finfo->fi_hdir = fidir; -+ atomic_set(&finfo->fi_generation, au_digen(dentry)); -+ /* smp_mb(); */ /* atomic_set */ -+ -+ file->private_data = finfo; -+ -+out: -+ return err; -+} -diff --git a/fs/aufs/fstype.h b/fs/aufs/fstype.h -new file mode 100644 -index 000000000..4e295869b ---- /dev/null -+++ b/fs/aufs/fstype.h -@@ -0,0 +1,401 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * judging filesystem type -+ */ -+ -+#ifndef __AUFS_FSTYPE_H__ -+#define __AUFS_FSTYPE_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+ -+static inline int au_test_aufs(struct super_block *sb) -+{ -+ return sb->s_magic == AUFS_SUPER_MAGIC; -+} -+ -+static inline const char *au_sbtype(struct super_block *sb) -+{ -+ return sb->s_type->name; -+} -+ -+static inline int au_test_iso9660(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_ISO9660_FS) -+ return sb->s_magic == ISOFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_romfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_ROMFS_FS) -+ return sb->s_magic == ROMFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_cramfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_CRAMFS) -+ return sb->s_magic == CRAMFS_MAGIC; -+#endif -+ return 0; -+} -+ -+static inline int au_test_nfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_NFS_FS) -+ return sb->s_magic == NFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_fuse(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_FUSE_FS) -+ return sb->s_magic == FUSE_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_xfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_XFS_FS) -+ return sb->s_magic == XFS_SB_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused) -+{ -+#ifdef CONFIG_TMPFS -+ return sb->s_magic == TMPFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_ECRYPT_FS) -+ return !strcmp(au_sbtype(sb), "ecryptfs"); -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_ramfs(struct super_block *sb) -+{ -+ return sb->s_magic == RAMFS_MAGIC; -+} -+ -+static inline int au_test_ubifs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_UBIFS_FS) -+ return sb->s_magic == UBIFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_procfs(struct super_block *sb __maybe_unused) -+{ -+#ifdef CONFIG_PROC_FS -+ return sb->s_magic == PROC_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_sysfs(struct super_block *sb __maybe_unused) -+{ -+#ifdef CONFIG_SYSFS -+ return sb->s_magic == SYSFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_configfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_CONFIGFS_FS) -+ return sb->s_magic == CONFIGFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_minix(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_MINIX_FS) -+ return sb->s_magic == MINIX3_SUPER_MAGIC -+ || sb->s_magic == MINIX2_SUPER_MAGIC -+ || sb->s_magic == MINIX2_SUPER_MAGIC2 -+ || sb->s_magic == MINIX_SUPER_MAGIC -+ || sb->s_magic == MINIX_SUPER_MAGIC2; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_fat(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_FAT_FS) -+ return sb->s_magic == MSDOS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_msdos(struct super_block *sb) -+{ -+ return au_test_fat(sb); -+} -+ -+static inline int au_test_vfat(struct super_block *sb) -+{ -+ return au_test_fat(sb); -+} -+ -+static inline int au_test_securityfs(struct super_block *sb __maybe_unused) -+{ -+#ifdef CONFIG_SECURITYFS -+ return sb->s_magic == SECURITYFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_squashfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_SQUASHFS) -+ return sb->s_magic == SQUASHFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_btrfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_BTRFS_FS) -+ return sb->s_magic == BTRFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_xenfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_XENFS) -+ return sb->s_magic == XENFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_debugfs(struct super_block *sb __maybe_unused) -+{ -+#ifdef CONFIG_DEBUG_FS -+ return sb->s_magic == DEBUGFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_nilfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_NILFS) -+ return sb->s_magic == NILFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_HFSPLUS_FS) -+ return sb->s_magic == HFSPLUS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * they can't be an aufs branch. -+ */ -+static inline int au_test_fs_unsuppoted(struct super_block *sb) -+{ -+ return -+#ifndef CONFIG_AUFS_BR_RAMFS -+ au_test_ramfs(sb) || -+#endif -+ au_test_procfs(sb) -+ || au_test_sysfs(sb) -+ || au_test_configfs(sb) -+ || au_test_debugfs(sb) -+ || au_test_securityfs(sb) -+ || au_test_xenfs(sb) -+ || au_test_ecryptfs(sb) -+ /* || !strcmp(au_sbtype(sb), "unionfs") */ -+ || au_test_aufs(sb); /* will be supported in next version */ -+} -+ -+static inline int au_test_fs_remote(struct super_block *sb) -+{ -+ return !au_test_tmpfs(sb) -+#ifdef CONFIG_AUFS_BR_RAMFS -+ && !au_test_ramfs(sb) -+#endif -+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * Note: these functions (below) are created after reading ->getattr() in all -+ * filesystems under linux/fs. it means we have to do so in every update... -+ */ -+ -+/* -+ * some filesystems require getattr to refresh the inode attributes before -+ * referencing. -+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs) -+ * and leave the work for d_revalidate() -+ */ -+static inline int au_test_fs_refresh_iattr(struct super_block *sb) -+{ -+ return au_test_nfs(sb) -+ || au_test_fuse(sb) -+ /* || au_test_btrfs(sb) */ /* untested */ -+ ; -+} -+ -+/* -+ * filesystems which don't maintain i_size or i_blocks. -+ */ -+static inline int au_test_fs_bad_iattr_size(struct super_block *sb) -+{ -+ return au_test_xfs(sb) -+ || au_test_btrfs(sb) -+ || au_test_ubifs(sb) -+ || au_test_hfsplus(sb) /* maintained, but incorrect */ -+ /* || au_test_minix(sb) */ /* untested */ -+ ; -+} -+ -+/* -+ * filesystems which don't store the correct value in some of their inode -+ * attributes. -+ */ -+static inline int au_test_fs_bad_iattr(struct super_block *sb) -+{ -+ return au_test_fs_bad_iattr_size(sb) -+ || au_test_fat(sb) -+ || au_test_msdos(sb) -+ || au_test_vfat(sb); -+} -+ -+/* they don't check i_nlink in link(2) */ -+static inline int au_test_fs_no_limit_nlink(struct super_block *sb) -+{ -+ return au_test_tmpfs(sb) -+#ifdef CONFIG_AUFS_BR_RAMFS -+ || au_test_ramfs(sb) -+#endif -+ || au_test_ubifs(sb) -+ || au_test_hfsplus(sb); -+} -+ -+/* -+ * filesystems which sets S_NOATIME and S_NOCMTIME. -+ */ -+static inline int au_test_fs_notime(struct super_block *sb) -+{ -+ return au_test_nfs(sb) -+ || au_test_fuse(sb) -+ || au_test_ubifs(sb) -+ ; -+} -+ -+/* temporary support for i#1 in cramfs */ -+static inline int au_test_fs_unique_ino(struct inode *inode) -+{ -+ if (au_test_cramfs(inode->i_sb)) -+ return inode->i_ino != 1; -+ return 1; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * the filesystem where the xino files placed must support i/o after unlink and -+ * maintain i_size and i_blocks. -+ */ -+static inline int au_test_fs_bad_xino(struct super_block *sb) -+{ -+ return au_test_fs_remote(sb) -+ || au_test_fs_bad_iattr_size(sb) -+ /* don't want unnecessary work for xino */ -+ || au_test_aufs(sb) -+ || au_test_ecryptfs(sb) -+ || au_test_nilfs(sb); -+} -+ -+static inline int au_test_fs_trunc_xino(struct super_block *sb) -+{ -+ return au_test_tmpfs(sb) -+ || au_test_ramfs(sb); -+} -+ -+/* -+ * test if the @sb is real-readonly. -+ */ -+static inline int au_test_fs_rr(struct super_block *sb) -+{ -+ return au_test_squashfs(sb) -+ || au_test_iso9660(sb) -+ || au_test_cramfs(sb) -+ || au_test_romfs(sb); -+} -+ -+/* -+ * test if the @inode is nfs with 'noacl' option -+ * NFS always sets SB_POSIXACL regardless its mount option 'noacl.' -+ */ -+static inline int au_test_nfs_noacl(struct inode *inode) -+{ -+ return au_test_nfs(inode->i_sb) -+ /* && IS_POSIXACL(inode) */ -+ && !nfs_server_capable(inode, NFS_CAP_ACLS); -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_FSTYPE_H__ */ -diff --git a/fs/aufs/hbl.h b/fs/aufs/hbl.h -new file mode 100644 -index 000000000..265d7ab61 ---- /dev/null -+++ b/fs/aufs/hbl.h -@@ -0,0 +1,65 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2017-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * helpers for hlist_bl.h -+ */ -+ -+#ifndef __AUFS_HBL_H__ -+#define __AUFS_HBL_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+static inline void au_hbl_add(struct hlist_bl_node *node, -+ struct hlist_bl_head *hbl) -+{ -+ hlist_bl_lock(hbl); -+ hlist_bl_add_head(node, hbl); -+ hlist_bl_unlock(hbl); -+} -+ -+static inline void au_hbl_del(struct hlist_bl_node *node, -+ struct hlist_bl_head *hbl) -+{ -+ hlist_bl_lock(hbl); -+ hlist_bl_del(node); -+ hlist_bl_unlock(hbl); -+} -+ -+#define au_hbl_for_each(pos, head) \ -+ for (pos = hlist_bl_first(head); \ -+ pos; \ -+ pos = pos->next) -+ -+static inline unsigned long au_hbl_count(struct hlist_bl_head *hbl) -+{ -+ unsigned long cnt; -+ struct hlist_bl_node *pos; -+ -+ cnt = 0; -+ hlist_bl_lock(hbl); -+ au_hbl_for_each(pos, hbl) -+ cnt++; -+ hlist_bl_unlock(hbl); -+ return cnt; -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_HBL_H__ */ -diff --git a/fs/aufs/hfsnotify.c b/fs/aufs/hfsnotify.c -new file mode 100644 -index 000000000..7ec50daf7 ---- /dev/null -+++ b/fs/aufs/hfsnotify.c -@@ -0,0 +1,289 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * fsnotify for the lower directories -+ */ -+ -+#include "aufs.h" -+ -+/* FS_IN_IGNORED is unnecessary */ -+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE -+ | FS_CREATE | FS_EVENT_ON_CHILD); -+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq); -+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0); -+ -+static void au_hfsn_free_mark(struct fsnotify_mark *mark) -+{ -+ struct au_hnotify *hn = container_of(mark, struct au_hnotify, -+ hn_mark); -+ /* AuDbg("here\n"); */ -+ au_cache_free_hnotify(hn); -+ smp_mb__before_atomic(); /* for atomic64_dec */ -+ if (atomic64_dec_and_test(&au_hfsn_ifree)) -+ wake_up(&au_hfsn_wq); -+} -+ -+static int au_hfsn_alloc(struct au_hinode *hinode) -+{ -+ int err; -+ struct au_hnotify *hn; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct fsnotify_mark *mark; -+ aufs_bindex_t bindex; -+ -+ hn = hinode->hi_notify; -+ sb = hn->hn_aufs_inode->i_sb; -+ bindex = au_br_index(sb, hinode->hi_id); -+ br = au_sbr(sb, bindex); -+ AuDebugOn(!br->br_hfsn); -+ -+ mark = &hn->hn_mark; -+ fsnotify_init_mark(mark, br->br_hfsn->hfsn_group); -+ mark->mask = AuHfsnMask; -+ /* -+ * by udba rename or rmdir, aufs assign a new inode to the known -+ * h_inode, so specify 1 to allow dups. -+ */ -+ lockdep_off(); -+ err = fsnotify_add_inode_mark(mark, hinode->hi_inode, /*allow_dups*/1); -+ lockdep_on(); -+ -+ return err; -+} -+ -+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn) -+{ -+ struct fsnotify_mark *mark; -+ unsigned long long ull; -+ struct fsnotify_group *group; -+ -+ ull = atomic64_inc_return(&au_hfsn_ifree); -+ BUG_ON(!ull); -+ -+ mark = &hn->hn_mark; -+ spin_lock(&mark->lock); -+ group = mark->group; -+ fsnotify_get_group(group); -+ spin_unlock(&mark->lock); -+ lockdep_off(); -+ fsnotify_destroy_mark(mark, group); -+ fsnotify_put_mark(mark); -+ fsnotify_put_group(group); -+ lockdep_on(); -+ -+ /* free hn by myself */ -+ return 0; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set) -+{ -+ struct fsnotify_mark *mark; -+ -+ mark = &hinode->hi_notify->hn_mark; -+ spin_lock(&mark->lock); -+ if (do_set) { -+ AuDebugOn(mark->mask & AuHfsnMask); -+ mark->mask |= AuHfsnMask; -+ } else { -+ AuDebugOn(!(mark->mask & AuHfsnMask)); -+ mark->mask &= ~AuHfsnMask; -+ } -+ spin_unlock(&mark->lock); -+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */ -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* #define AuDbgHnotify */ -+#ifdef AuDbgHnotify -+static char *au_hfsn_name(u32 mask) -+{ -+#ifdef CONFIG_AUFS_DEBUG -+#define test_ret(flag) \ -+ do { \ -+ if (mask & flag) \ -+ return #flag; \ -+ } while (0) -+ test_ret(FS_ACCESS); -+ test_ret(FS_MODIFY); -+ test_ret(FS_ATTRIB); -+ test_ret(FS_CLOSE_WRITE); -+ test_ret(FS_CLOSE_NOWRITE); -+ test_ret(FS_OPEN); -+ test_ret(FS_MOVED_FROM); -+ test_ret(FS_MOVED_TO); -+ test_ret(FS_CREATE); -+ test_ret(FS_DELETE); -+ test_ret(FS_DELETE_SELF); -+ test_ret(FS_MOVE_SELF); -+ test_ret(FS_UNMOUNT); -+ test_ret(FS_Q_OVERFLOW); -+ test_ret(FS_IN_IGNORED); -+ test_ret(FS_ISDIR); -+ test_ret(FS_IN_ONESHOT); -+ test_ret(FS_EVENT_ON_CHILD); -+ return ""; -+#undef test_ret -+#else -+ return "??"; -+#endif -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_hfsn_free_group(struct fsnotify_group *group) -+{ -+ struct au_br_hfsnotify *hfsn = group->private; -+ -+ /* AuDbg("here\n"); */ -+ kfree(hfsn); -+} -+ -+static int au_hfsn_handle_event(struct fsnotify_group *group, -+ struct inode *inode, -+ u32 mask, const void *data, int data_type, -+ const unsigned char *file_name, u32 cookie, -+ struct fsnotify_iter_info *iter_info) -+{ -+ int err; -+ struct au_hnotify *hnotify; -+ struct inode *h_dir, *h_inode; -+ struct qstr h_child_qstr = QSTR_INIT(file_name, strlen(file_name)); -+ struct fsnotify_mark *inode_mark; -+ -+ AuDebugOn(data_type != FSNOTIFY_EVENT_INODE); -+ -+ err = 0; -+ /* if FS_UNMOUNT happens, there must be another bug */ -+ AuDebugOn(mask & FS_UNMOUNT); -+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT)) -+ goto out; -+ -+ h_dir = inode; -+ h_inode = NULL; -+#ifdef AuDbgHnotify -+ au_debug_on(); -+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1 -+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) { -+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n", -+ h_dir->i_ino, mask, au_hfsn_name(mask), -+ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0); -+ /* WARN_ON(1); */ -+ } -+ au_debug_off(); -+#endif -+ -+ inode_mark = fsnotify_iter_inode_mark(iter_info); -+ AuDebugOn(!inode_mark); -+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark); -+ err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode); -+ -+out: -+ return err; -+} -+ -+static struct fsnotify_ops au_hfsn_ops = { -+ .handle_event = au_hfsn_handle_event, -+ .free_group_priv = au_hfsn_free_group, -+ .free_mark = au_hfsn_free_mark -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_hfsn_fin_br(struct au_branch *br) -+{ -+ struct au_br_hfsnotify *hfsn; -+ -+ hfsn = br->br_hfsn; -+ if (hfsn) { -+ lockdep_off(); -+ fsnotify_put_group(hfsn->hfsn_group); -+ lockdep_on(); -+ } -+} -+ -+static int au_hfsn_init_br(struct au_branch *br, int perm) -+{ -+ int err; -+ struct fsnotify_group *group; -+ struct au_br_hfsnotify *hfsn; -+ -+ err = 0; -+ br->br_hfsn = NULL; -+ if (!au_br_hnotifyable(perm)) -+ goto out; -+ -+ err = -ENOMEM; -+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS); -+ if (unlikely(!hfsn)) -+ goto out; -+ -+ err = 0; -+ group = fsnotify_alloc_group(&au_hfsn_ops); -+ if (IS_ERR(group)) { -+ err = PTR_ERR(group); -+ pr_err("fsnotify_alloc_group() failed, %d\n", err); -+ goto out_hfsn; -+ } -+ -+ group->private = hfsn; -+ hfsn->hfsn_group = group; -+ br->br_hfsn = hfsn; -+ goto out; /* success */ -+ -+out_hfsn: -+ kfree(hfsn); -+out: -+ return err; -+} -+ -+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm) -+{ -+ int err; -+ -+ err = 0; -+ if (!br->br_hfsn) -+ err = au_hfsn_init_br(br, perm); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_hfsn_fin(void) -+{ -+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree)); -+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree)); -+} -+ -+const struct au_hnotify_op au_hnotify_op = { -+ .ctl = au_hfsn_ctl, -+ .alloc = au_hfsn_alloc, -+ .free = au_hfsn_free, -+ -+ .fin = au_hfsn_fin, -+ -+ .reset_br = au_hfsn_reset_br, -+ .fin_br = au_hfsn_fin_br, -+ .init_br = au_hfsn_init_br -+}; -diff --git a/fs/aufs/hfsplus.c b/fs/aufs/hfsplus.c -new file mode 100644 -index 000000000..b1f59970d ---- /dev/null -+++ b/fs/aufs/hfsplus.c -@@ -0,0 +1,60 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2010-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * special support for filesystems which acquires an inode mutex -+ * at final closing a file, eg, hfsplus. -+ * -+ * This trick is very simple and stupid, just to open the file before really -+ * necessary open to tell hfsplus that this is not the final closing. -+ * The caller should call au_h_open_pre() after acquiring the inode mutex, -+ * and au_h_open_post() after releasing it. -+ */ -+ -+#include "aufs.h" -+ -+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex, -+ int force_wr) -+{ -+ struct file *h_file; -+ struct dentry *h_dentry; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ AuDebugOn(!h_dentry); -+ AuDebugOn(d_is_negative(h_dentry)); -+ -+ h_file = NULL; -+ if (au_test_hfsplus(h_dentry->d_sb) -+ && d_is_reg(h_dentry)) -+ h_file = au_h_open(dentry, bindex, -+ O_RDONLY | O_NOATIME | O_LARGEFILE, -+ /*file*/NULL, force_wr); -+ return h_file; -+} -+ -+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex, -+ struct file *h_file) -+{ -+ struct au_branch *br; -+ -+ if (h_file) { -+ fput(h_file); -+ br = au_sbr(dentry->d_sb, bindex); -+ au_lcnt_dec(&br->br_nfiles); -+ } -+} -diff --git a/fs/aufs/hnotify.c b/fs/aufs/hnotify.c -new file mode 100644 -index 000000000..452f5609c ---- /dev/null -+++ b/fs/aufs/hnotify.c -@@ -0,0 +1,720 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * abstraction to notify the direct changes on lower directories -+ */ -+ -+#include "aufs.h" -+ -+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode) -+{ -+ int err; -+ struct au_hnotify *hn; -+ -+ err = -ENOMEM; -+ hn = au_cache_alloc_hnotify(); -+ if (hn) { -+ hn->hn_aufs_inode = inode; -+ hinode->hi_notify = hn; -+ err = au_hnotify_op.alloc(hinode); -+ AuTraceErr(err); -+ if (unlikely(err)) { -+ hinode->hi_notify = NULL; -+ au_cache_free_hnotify(hn); -+ /* -+ * The upper dir was removed by udba, but the same named -+ * dir left. In this case, aufs assigns a new inode -+ * number and set the monitor again. -+ * For the lower dir, the old monitor is still left. -+ */ -+ if (err == -EEXIST) -+ err = 0; -+ } -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_hn_free(struct au_hinode *hinode) -+{ -+ struct au_hnotify *hn; -+ -+ hn = hinode->hi_notify; -+ if (hn) { -+ hinode->hi_notify = NULL; -+ if (au_hnotify_op.free(hinode, hn)) -+ au_cache_free_hnotify(hn); -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_hn_ctl(struct au_hinode *hinode, int do_set) -+{ -+ if (hinode->hi_notify) -+ au_hnotify_op.ctl(hinode, do_set); -+} -+ -+void au_hn_reset(struct inode *inode, unsigned int flags) -+{ -+ aufs_bindex_t bindex, bbot; -+ struct inode *hi; -+ struct dentry *iwhdentry; -+ -+ bbot = au_ibbot(inode); -+ for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) { -+ hi = au_h_iptr(inode, bindex); -+ if (!hi) -+ continue; -+ -+ /* inode_lock_nested(hi, AuLsc_I_CHILD); */ -+ iwhdentry = au_hi_wh(inode, bindex); -+ if (iwhdentry) -+ dget(iwhdentry); -+ au_igrab(hi); -+ au_set_h_iptr(inode, bindex, NULL, 0); -+ au_set_h_iptr(inode, bindex, au_igrab(hi), -+ flags & ~AuHi_XINO); -+ iput(hi); -+ dput(iwhdentry); -+ /* inode_unlock(hi); */ -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int hn_xino(struct inode *inode, struct inode *h_inode) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot, bfound, btop; -+ struct inode *h_i; -+ -+ err = 0; -+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { -+ pr_warn("branch root dir was changed\n"); -+ goto out; -+ } -+ -+ bfound = -1; -+ bbot = au_ibbot(inode); -+ btop = au_ibtop(inode); -+#if 0 /* reserved for future use */ -+ if (bindex == bbot) { -+ /* keep this ino in rename case */ -+ goto out; -+ } -+#endif -+ for (bindex = btop; bindex <= bbot; bindex++) -+ if (au_h_iptr(inode, bindex) == h_inode) { -+ bfound = bindex; -+ break; -+ } -+ if (bfound < 0) -+ goto out; -+ -+ for (bindex = btop; bindex <= bbot; bindex++) { -+ h_i = au_h_iptr(inode, bindex); -+ if (!h_i) -+ continue; -+ -+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0); -+ /* ignore this error */ -+ /* bad action? */ -+ } -+ -+ /* children inode number will be broken */ -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int hn_gen_tree(struct dentry *dentry) -+{ -+ int err, i, j, ndentry; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry **dentries; -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL); -+ if (unlikely(err)) -+ goto out_dpages; -+ -+ for (i = 0; i < dpages.ndpage; i++) { -+ dpage = dpages.dpages + i; -+ dentries = dpage->dentries; -+ ndentry = dpage->ndentry; -+ for (j = 0; j < ndentry; j++) { -+ struct dentry *d; -+ -+ d = dentries[j]; -+ if (IS_ROOT(d)) -+ continue; -+ -+ au_digen_dec(d); -+ if (d_really_is_positive(d)) -+ /* todo: reset children xino? -+ cached children only? */ -+ au_iigen_dec(d_inode(d)); -+ } -+ } -+ -+out_dpages: -+ au_dpages_free(&dpages); -+ -+#if 0 -+ /* discard children */ -+ dentry_unhash(dentry); -+ dput(dentry); -+#endif -+out: -+ return err; -+} -+ -+/* -+ * return 0 if processed. -+ */ -+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode, -+ const unsigned int isdir) -+{ -+ int err; -+ struct dentry *d; -+ struct qstr *dname; -+ -+ err = 1; -+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { -+ pr_warn("branch root dir was changed\n"); -+ err = 0; -+ goto out; -+ } -+ -+ if (!isdir) { -+ AuDebugOn(!name); -+ au_iigen_dec(inode); -+ spin_lock(&inode->i_lock); -+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) { -+ spin_lock(&d->d_lock); -+ dname = &d->d_name; -+ if (dname->len != nlen -+ && memcmp(dname->name, name, nlen)) { -+ spin_unlock(&d->d_lock); -+ continue; -+ } -+ err = 0; -+ au_digen_dec(d); -+ spin_unlock(&d->d_lock); -+ break; -+ } -+ spin_unlock(&inode->i_lock); -+ } else { -+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR); -+ d = d_find_any_alias(inode); -+ if (!d) { -+ au_iigen_dec(inode); -+ goto out; -+ } -+ -+ spin_lock(&d->d_lock); -+ dname = &d->d_name; -+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) { -+ spin_unlock(&d->d_lock); -+ err = hn_gen_tree(d); -+ spin_lock(&d->d_lock); -+ } -+ spin_unlock(&d->d_lock); -+ dput(d); -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir) -+{ -+ int err; -+ -+ if (IS_ROOT(dentry)) { -+ pr_warn("branch root dir was changed\n"); -+ return 0; -+ } -+ -+ err = 0; -+ if (!isdir) { -+ au_digen_dec(dentry); -+ if (d_really_is_positive(dentry)) -+ au_iigen_dec(d_inode(dentry)); -+ } else { -+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR); -+ if (d_really_is_positive(dentry)) -+ err = hn_gen_tree(dentry); -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* hnotify job flags */ -+#define AuHnJob_XINO0 1 -+#define AuHnJob_GEN (1 << 1) -+#define AuHnJob_DIRENT (1 << 2) -+#define AuHnJob_ISDIR (1 << 3) -+#define AuHnJob_TRYXINO0 (1 << 4) -+#define AuHnJob_MNTPNT (1 << 5) -+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name) -+#define au_fset_hnjob(flags, name) \ -+ do { (flags) |= AuHnJob_##name; } while (0) -+#define au_fclr_hnjob(flags, name) \ -+ do { (flags) &= ~AuHnJob_##name; } while (0) -+ -+enum { -+ AuHn_CHILD, -+ AuHn_PARENT, -+ AuHnLast -+}; -+ -+struct au_hnotify_args { -+ struct inode *h_dir, *dir, *h_child_inode; -+ u32 mask; -+ unsigned int flags[AuHnLast]; -+ unsigned int h_child_nlen; -+ char h_child_name[]; -+}; -+ -+struct hn_job_args { -+ unsigned int flags; -+ struct inode *inode, *h_inode, *dir, *h_dir; -+ struct dentry *dentry; -+ char *h_name; -+ int h_nlen; -+}; -+ -+static int hn_job(struct hn_job_args *a) -+{ -+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR); -+ int e; -+ -+ /* reset xino */ -+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode) -+ hn_xino(a->inode, a->h_inode); /* ignore this error */ -+ -+ if (au_ftest_hnjob(a->flags, TRYXINO0) -+ && a->inode -+ && a->h_inode) { -+ inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD); -+ if (!a->h_inode->i_nlink -+ && !(a->h_inode->i_state & I_LINKABLE)) -+ hn_xino(a->inode, a->h_inode); /* ignore this error */ -+ inode_unlock_shared(a->h_inode); -+ } -+ -+ /* make the generation obsolete */ -+ if (au_ftest_hnjob(a->flags, GEN)) { -+ e = -1; -+ if (a->inode) -+ e = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode, -+ isdir); -+ if (e && a->dentry) -+ hn_gen_by_name(a->dentry, isdir); -+ /* ignore this error */ -+ } -+ -+ /* make dir entries obsolete */ -+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) { -+ struct au_vdir *vdir; -+ -+ vdir = au_ivdir(a->inode); -+ if (vdir) -+ vdir->vd_jiffy = 0; -+ /* IMustLock(a->inode); */ -+ /* inode_inc_iversion(a->inode); */ -+ } -+ -+ /* can do nothing but warn */ -+ if (au_ftest_hnjob(a->flags, MNTPNT) -+ && a->dentry -+ && d_mountpoint(a->dentry)) -+ pr_warn("mount-point %pd is removed or renamed\n", a->dentry); -+ -+ return 0; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen, -+ struct inode *dir) -+{ -+ struct dentry *dentry, *d, *parent; -+ struct qstr *dname; -+ -+ parent = d_find_any_alias(dir); -+ if (!parent) -+ return NULL; -+ -+ dentry = NULL; -+ spin_lock(&parent->d_lock); -+ list_for_each_entry(d, &parent->d_subdirs, d_child) { -+ /* AuDbg("%pd\n", d); */ -+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED); -+ dname = &d->d_name; -+ if (dname->len != nlen || memcmp(dname->name, name, nlen)) -+ goto cont_unlock; -+ if (au_di(d)) -+ au_digen_dec(d); -+ else -+ goto cont_unlock; -+ if (au_dcount(d) > 0) { -+ dentry = dget_dlock(d); -+ spin_unlock(&d->d_lock); -+ break; -+ } -+ -+cont_unlock: -+ spin_unlock(&d->d_lock); -+ } -+ spin_unlock(&parent->d_lock); -+ dput(parent); -+ -+ if (dentry) -+ di_write_lock_child(dentry); -+ -+ return dentry; -+} -+ -+static struct inode *lookup_wlock_by_ino(struct super_block *sb, -+ aufs_bindex_t bindex, ino_t h_ino) -+{ -+ struct inode *inode; -+ ino_t ino; -+ int err; -+ -+ inode = NULL; -+ err = au_xino_read(sb, bindex, h_ino, &ino); -+ if (!err && ino) -+ inode = ilookup(sb, ino); -+ if (!inode) -+ goto out; -+ -+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { -+ pr_warn("wrong root branch\n"); -+ iput(inode); -+ inode = NULL; -+ goto out; -+ } -+ -+ ii_write_lock_child(inode); -+ -+out: -+ return inode; -+} -+ -+static void au_hn_bh(void *_args) -+{ -+ struct au_hnotify_args *a = _args; -+ struct super_block *sb; -+ aufs_bindex_t bindex, bbot, bfound; -+ unsigned char xino, try_iput; -+ int err; -+ struct inode *inode; -+ ino_t h_ino; -+ struct hn_job_args args; -+ struct dentry *dentry; -+ struct au_sbinfo *sbinfo; -+ -+ AuDebugOn(!_args); -+ AuDebugOn(!a->h_dir); -+ AuDebugOn(!a->dir); -+ AuDebugOn(!a->mask); -+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n", -+ a->mask, a->dir->i_ino, a->h_dir->i_ino, -+ a->h_child_inode ? a->h_child_inode->i_ino : 0); -+ -+ inode = NULL; -+ dentry = NULL; -+ /* -+ * do not lock a->dir->i_mutex here -+ * because of d_revalidate() may cause a deadlock. -+ */ -+ sb = a->dir->i_sb; -+ AuDebugOn(!sb); -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!sbinfo); -+ si_write_lock(sb, AuLock_NOPLMW); -+ -+ if (au_opt_test(sbinfo->si_mntflags, DIRREN)) -+ switch (a->mask & FS_EVENTS_POSS_ON_CHILD) { -+ case FS_MOVED_FROM: -+ case FS_MOVED_TO: -+ AuWarn1("DIRREN with UDBA may not work correctly " -+ "for the direct rename(2)\n"); -+ } -+ -+ ii_read_lock_parent(a->dir); -+ bfound = -1; -+ bbot = au_ibbot(a->dir); -+ for (bindex = au_ibtop(a->dir); bindex <= bbot; bindex++) -+ if (au_h_iptr(a->dir, bindex) == a->h_dir) { -+ bfound = bindex; -+ break; -+ } -+ ii_read_unlock(a->dir); -+ if (unlikely(bfound < 0)) -+ goto out; -+ -+ xino = !!au_opt_test(au_mntflags(sb), XINO); -+ h_ino = 0; -+ if (a->h_child_inode) -+ h_ino = a->h_child_inode->i_ino; -+ -+ if (a->h_child_nlen -+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN) -+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT))) -+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen, -+ a->dir); -+ try_iput = 0; -+ if (dentry && d_really_is_positive(dentry)) -+ inode = d_inode(dentry); -+ if (xino && !inode && h_ino -+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0) -+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0) -+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) { -+ inode = lookup_wlock_by_ino(sb, bfound, h_ino); -+ try_iput = 1; -+ } -+ -+ args.flags = a->flags[AuHn_CHILD]; -+ args.dentry = dentry; -+ args.inode = inode; -+ args.h_inode = a->h_child_inode; -+ args.dir = a->dir; -+ args.h_dir = a->h_dir; -+ args.h_name = a->h_child_name; -+ args.h_nlen = a->h_child_nlen; -+ err = hn_job(&args); -+ if (dentry) { -+ if (au_di(dentry)) -+ di_write_unlock(dentry); -+ dput(dentry); -+ } -+ if (inode && try_iput) { -+ ii_write_unlock(inode); -+ iput(inode); -+ } -+ -+ ii_write_lock_parent(a->dir); -+ args.flags = a->flags[AuHn_PARENT]; -+ args.dentry = NULL; -+ args.inode = a->dir; -+ args.h_inode = a->h_dir; -+ args.dir = NULL; -+ args.h_dir = NULL; -+ args.h_name = NULL; -+ args.h_nlen = 0; -+ err = hn_job(&args); -+ ii_write_unlock(a->dir); -+ -+out: -+ iput(a->h_child_inode); -+ iput(a->h_dir); -+ iput(a->dir); -+ si_write_unlock(sb); -+ au_nwt_done(&sbinfo->si_nowait); -+ kfree(a); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask, -+ struct qstr *h_child_qstr, struct inode *h_child_inode) -+{ -+ int err, len; -+ unsigned int flags[AuHnLast], f; -+ unsigned char isdir, isroot, wh; -+ struct inode *dir; -+ struct au_hnotify_args *args; -+ char *p, *h_child_name; -+ -+ err = 0; -+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode); -+ dir = igrab(hnotify->hn_aufs_inode); -+ if (!dir) -+ goto out; -+ -+ isroot = (dir->i_ino == AUFS_ROOT_INO); -+ wh = 0; -+ h_child_name = (void *)h_child_qstr->name; -+ len = h_child_qstr->len; -+ if (h_child_name) { -+ if (len > AUFS_WH_PFX_LEN -+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { -+ h_child_name += AUFS_WH_PFX_LEN; -+ len -= AUFS_WH_PFX_LEN; -+ wh = 1; -+ } -+ } -+ -+ isdir = 0; -+ if (h_child_inode) -+ isdir = !!S_ISDIR(h_child_inode->i_mode); -+ flags[AuHn_PARENT] = AuHnJob_ISDIR; -+ flags[AuHn_CHILD] = 0; -+ if (isdir) -+ flags[AuHn_CHILD] = AuHnJob_ISDIR; -+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT); -+ au_fset_hnjob(flags[AuHn_CHILD], GEN); -+ switch (mask & FS_EVENTS_POSS_ON_CHILD) { -+ case FS_MOVED_FROM: -+ case FS_MOVED_TO: -+ au_fset_hnjob(flags[AuHn_CHILD], XINO0); -+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT); -+ /*FALLTHROUGH*/ -+ case FS_CREATE: -+ AuDebugOn(!h_child_name); -+ break; -+ -+ case FS_DELETE: -+ /* -+ * aufs never be able to get this child inode. -+ * revalidation should be in d_revalidate() -+ * by checking i_nlink, i_generation or d_unhashed(). -+ */ -+ AuDebugOn(!h_child_name); -+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0); -+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT); -+ break; -+ -+ default: -+ AuDebugOn(1); -+ } -+ -+ if (wh) -+ h_child_inode = NULL; -+ -+ err = -ENOMEM; -+ /* iput() and kfree() will be called in au_hnotify() */ -+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS); -+ if (unlikely(!args)) { -+ AuErr1("no memory\n"); -+ iput(dir); -+ goto out; -+ } -+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT]; -+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD]; -+ args->mask = mask; -+ args->dir = dir; -+ args->h_dir = igrab(h_dir); -+ if (h_child_inode) -+ h_child_inode = igrab(h_child_inode); /* can be NULL */ -+ args->h_child_inode = h_child_inode; -+ args->h_child_nlen = len; -+ if (len) { -+ p = (void *)args; -+ p += sizeof(*args); -+ memcpy(p, h_child_name, len); -+ p[len] = 0; -+ } -+ -+ /* NFS fires the event for silly-renamed one from kworker */ -+ f = 0; -+ if (!dir->i_nlink -+ || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE))) -+ f = AuWkq_NEST; -+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f); -+ if (unlikely(err)) { -+ pr_err("wkq %d\n", err); -+ iput(args->h_child_inode); -+ iput(args->h_dir); -+ iput(args->dir); -+ kfree(args); -+ } -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm) -+{ -+ int err; -+ -+ AuDebugOn(!(udba & AuOptMask_UDBA)); -+ -+ err = 0; -+ if (au_hnotify_op.reset_br) -+ err = au_hnotify_op.reset_br(udba, br, perm); -+ -+ return err; -+} -+ -+int au_hnotify_init_br(struct au_branch *br, int perm) -+{ -+ int err; -+ -+ err = 0; -+ if (au_hnotify_op.init_br) -+ err = au_hnotify_op.init_br(br, perm); -+ -+ return err; -+} -+ -+void au_hnotify_fin_br(struct au_branch *br) -+{ -+ if (au_hnotify_op.fin_br) -+ au_hnotify_op.fin_br(br); -+} -+ -+static void au_hn_destroy_cache(void) -+{ -+ kmem_cache_destroy(au_cache[AuCache_HNOTIFY]); -+ au_cache[AuCache_HNOTIFY] = NULL; -+} -+ -+int __init au_hnotify_init(void) -+{ -+ int err; -+ -+ err = -ENOMEM; -+ au_cache[AuCache_HNOTIFY] = AuCache(au_hnotify); -+ if (au_cache[AuCache_HNOTIFY]) { -+ err = 0; -+ if (au_hnotify_op.init) -+ err = au_hnotify_op.init(); -+ if (unlikely(err)) -+ au_hn_destroy_cache(); -+ } -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_hnotify_fin(void) -+{ -+ if (au_hnotify_op.fin) -+ au_hnotify_op.fin(); -+ -+ /* cf. au_cache_fin() */ -+ if (au_cache[AuCache_HNOTIFY]) -+ au_hn_destroy_cache(); -+} -diff --git a/fs/aufs/i_op.c b/fs/aufs/i_op.c -new file mode 100644 -index 000000000..e1210975e ---- /dev/null -+++ b/fs/aufs/i_op.c -@@ -0,0 +1,1506 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * inode operations (except add/del/rename) -+ */ -+ -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+static int h_permission(struct inode *h_inode, int mask, -+ struct path *h_path, int brperm) -+{ -+ int err; -+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND)); -+ -+ err = -EPERM; -+ if (write_mask && IS_IMMUTABLE(h_inode)) -+ goto out; -+ -+ err = -EACCES; -+ if (((mask & MAY_EXEC) -+ && S_ISREG(h_inode->i_mode) -+ && (path_noexec(h_path) -+ || !(h_inode->i_mode & 0111)))) -+ goto out; -+ -+ /* -+ * - skip the lower fs test in the case of write to ro branch. -+ * - nfs dir permission write check is optimized, but a policy for -+ * link/rename requires a real check. -+ * - nfs always sets SB_POSIXACL regardless its mount option 'noacl.' -+ * in this case, generic_permission() returns -EOPNOTSUPP. -+ */ -+ if ((write_mask && !au_br_writable(brperm)) -+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode) -+ && write_mask && !(mask & MAY_READ)) -+ || !h_inode->i_op->permission) { -+ /* AuLabel(generic_permission); */ -+ /* AuDbg("get_acl %ps\n", h_inode->i_op->get_acl); */ -+ err = generic_permission(h_inode, mask); -+ if (err == -EOPNOTSUPP && au_test_nfs_noacl(h_inode)) -+ err = h_inode->i_op->permission(h_inode, mask); -+ AuTraceErr(err); -+ } else { -+ /* AuLabel(h_inode->permission); */ -+ err = h_inode->i_op->permission(h_inode, mask); -+ AuTraceErr(err); -+ } -+ -+ if (!err) -+ err = devcgroup_inode_permission(h_inode, mask); -+ if (!err) -+ err = security_inode_permission(h_inode, mask); -+ -+#if 0 -+ if (!err) { -+ /* todo: do we need to call ima_path_check()? */ -+ struct path h_path = { -+ .dentry = -+ .mnt = h_mnt -+ }; -+ err = ima_path_check(&h_path, -+ mask & (MAY_READ | MAY_WRITE | MAY_EXEC), -+ IMA_COUNT_LEAVE); -+ } -+#endif -+ -+out: -+ return err; -+} -+ -+static int aufs_permission(struct inode *inode, int mask) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ const unsigned char isdir = !!S_ISDIR(inode->i_mode), -+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND)); -+ struct inode *h_inode; -+ struct super_block *sb; -+ struct au_branch *br; -+ -+ /* todo: support rcu-walk? */ -+ if (mask & MAY_NOT_BLOCK) -+ return -ECHILD; -+ -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ ii_read_lock_child(inode); -+#if 0 -+ err = au_iigen_test(inode, au_sigen(sb)); -+ if (unlikely(err)) -+ goto out; -+#endif -+ -+ if (!isdir -+ || write_mask -+ || au_opt_test(au_mntflags(sb), DIRPERM1)) { -+ err = au_busy_or_stale(); -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ if (unlikely(!h_inode -+ || (h_inode->i_mode & S_IFMT) -+ != (inode->i_mode & S_IFMT))) -+ goto out; -+ -+ err = 0; -+ bindex = au_ibtop(inode); -+ br = au_sbr(sb, bindex); -+ err = h_permission(h_inode, mask, &br->br_path, br->br_perm); -+ if (write_mask -+ && !err -+ && !special_file(h_inode->i_mode)) { -+ /* test whether the upper writable branch exists */ -+ err = -EROFS; -+ for (; bindex >= 0; bindex--) -+ if (!au_br_rdonly(au_sbr(sb, bindex))) { -+ err = 0; -+ break; -+ } -+ } -+ goto out; -+ } -+ -+ /* non-write to dir */ -+ err = 0; -+ bbot = au_ibbot(inode); -+ for (bindex = au_ibtop(inode); !err && bindex <= bbot; bindex++) { -+ h_inode = au_h_iptr(inode, bindex); -+ if (h_inode) { -+ err = au_busy_or_stale(); -+ if (unlikely(!S_ISDIR(h_inode->i_mode))) -+ break; -+ -+ br = au_sbr(sb, bindex); -+ err = h_permission(h_inode, mask, &br->br_path, -+ br->br_perm); -+ } -+ } -+ -+out: -+ ii_read_unlock(inode); -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry, -+ unsigned int flags) -+{ -+ struct dentry *ret, *parent; -+ struct inode *inode; -+ struct super_block *sb; -+ int err, npositive; -+ -+ IMustLock(dir); -+ -+ /* todo: support rcu-walk? */ -+ ret = ERR_PTR(-ECHILD); -+ if (flags & LOOKUP_RCU) -+ goto out; -+ -+ ret = ERR_PTR(-ENAMETOOLONG); -+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN)) -+ goto out; -+ -+ sb = dir->i_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ ret = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_di_init(dentry); -+ ret = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_si; -+ -+ inode = NULL; -+ npositive = 0; /* suppress a warning */ -+ parent = dentry->d_parent; /* dir inode is locked */ -+ di_read_lock_parent(parent, AuLock_IR); -+ err = au_alive_dir(parent); -+ if (!err) -+ err = au_digen_test(parent, au_sigen(sb)); -+ if (!err) { -+ /* regardless LOOKUP_CREATE, always ALLOW_NEG */ -+ npositive = au_lkup_dentry(dentry, au_dbtop(parent), -+ AuLkup_ALLOW_NEG); -+ err = npositive; -+ } -+ di_read_unlock(parent, AuLock_IR); -+ ret = ERR_PTR(err); -+ if (unlikely(err < 0)) -+ goto out_unlock; -+ -+ if (npositive) { -+ inode = au_new_inode(dentry, /*must_new*/0); -+ if (IS_ERR(inode)) { -+ ret = (void *)inode; -+ inode = NULL; -+ goto out_unlock; -+ } -+ } -+ -+ if (inode) -+ atomic_inc(&inode->i_count); -+ ret = d_splice_alias(inode, dentry); -+#if 0 -+ if (unlikely(d_need_lookup(dentry))) { -+ spin_lock(&dentry->d_lock); -+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP; -+ spin_unlock(&dentry->d_lock); -+ } else -+#endif -+ if (inode) { -+ if (!IS_ERR(ret)) { -+ iput(inode); -+ if (ret && ret != dentry) -+ ii_write_unlock(inode); -+ } else { -+ ii_write_unlock(inode); -+ iput(inode); -+ inode = NULL; -+ } -+ } -+ -+out_unlock: -+ di_write_unlock(dentry); -+out_si: -+ si_read_unlock(sb); -+out: -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * very dirty and complicated aufs ->atomic_open(). -+ * aufs_atomic_open() -+ * + au_aopen_or_create() -+ * + add_simple() -+ * + vfsub_atomic_open() -+ * + branch fs ->atomic_open() -+ * may call the actual 'open' for h_file -+ * + inc br_nfiles only if opened -+ * + au_aopen_no_open() or au_aopen_do_open() -+ * -+ * au_aopen_do_open() -+ * + finish_open() -+ * + au_do_aopen() -+ * + au_do_open() the body of all 'open' -+ * + au_do_open_nondir() -+ * set the passed h_file -+ * -+ * au_aopen_no_open() -+ * + finish_no_open() -+ */ -+ -+struct aopen_node { -+ struct hlist_bl_node hblist; -+ struct file *file, *h_file; -+}; -+ -+static int au_do_aopen(struct inode *inode, struct file *file) -+{ -+ struct hlist_bl_head *aopen; -+ struct hlist_bl_node *pos; -+ struct aopen_node *node; -+ struct au_do_open_args args = { -+ .aopen = 1, -+ .open = au_do_open_nondir -+ }; -+ -+ aopen = &au_sbi(inode->i_sb)->si_aopen; -+ hlist_bl_lock(aopen); -+ hlist_bl_for_each_entry(node, pos, aopen, hblist) -+ if (node->file == file) { -+ args.h_file = node->h_file; -+ break; -+ } -+ hlist_bl_unlock(aopen); -+ /* AuDebugOn(!args.h_file); */ -+ -+ return au_do_open(file, &args); -+} -+ -+static int au_aopen_do_open(struct file *file, struct dentry *dentry, -+ struct aopen_node *aopen_node) -+{ -+ int err; -+ struct hlist_bl_head *aopen; -+ -+ AuLabel(here); -+ aopen = &au_sbi(dentry->d_sb)->si_aopen; -+ au_hbl_add(&aopen_node->hblist, aopen); -+ err = finish_open(file, dentry, au_do_aopen); -+ au_hbl_del(&aopen_node->hblist, aopen); -+ /* AuDbgFile(file); */ -+ AuDbg("%pd%s%s\n", dentry, -+ (file->f_mode & FMODE_CREATED) ? " created" : "", -+ (file->f_mode & FMODE_OPENED) ? " opened" : ""); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_aopen_no_open(struct file *file, struct dentry *dentry) -+{ -+ int err; -+ -+ AuLabel(here); -+ dget(dentry); -+ err = finish_no_open(file, dentry); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int aufs_atomic_open(struct inode *dir, struct dentry *dentry, -+ struct file *file, unsigned int open_flag, -+ umode_t create_mode) -+{ -+ int err, did_open; -+ unsigned int lkup_flags; -+ aufs_bindex_t bindex; -+ struct super_block *sb; -+ struct dentry *parent, *d; -+ struct vfsub_aopen_args args = { -+ .open_flag = open_flag, -+ .create_mode = create_mode -+ }; -+ struct aopen_node aopen_node = { -+ .file = file -+ }; -+ -+ IMustLock(dir); -+ AuDbg("open_flag 0%o\n", open_flag); -+ AuDbgDentry(dentry); -+ -+ err = 0; -+ if (!au_di(dentry)) { -+ lkup_flags = LOOKUP_OPEN; -+ if (open_flag & O_CREAT) -+ lkup_flags |= LOOKUP_CREATE; -+ d = aufs_lookup(dir, dentry, lkup_flags); -+ if (IS_ERR(d)) { -+ err = PTR_ERR(d); -+ AuTraceErr(err); -+ goto out; -+ } else if (d) { -+ /* -+ * obsoleted dentry found. -+ * another error will be returned later. -+ */ -+ d_drop(d); -+ AuDbgDentry(d); -+ dput(d); -+ } -+ AuDbgDentry(dentry); -+ } -+ -+ if (d_is_positive(dentry) -+ || d_unhashed(dentry) -+ || d_unlinked(dentry) -+ || !(open_flag & O_CREAT)) { -+ err = au_aopen_no_open(file, dentry); -+ goto out; /* success */ -+ } -+ -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN); -+ if (unlikely(err)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ parent = dentry->d_parent; /* dir is locked */ -+ di_write_lock_parent(parent); -+ err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG); -+ if (unlikely(err < 0)) -+ goto out_parent; -+ -+ AuDbgDentry(dentry); -+ if (d_is_positive(dentry)) { -+ err = au_aopen_no_open(file, dentry); -+ goto out_parent; /* success */ -+ } -+ -+ args.file = alloc_empty_file(file->f_flags, current_cred()); -+ err = PTR_ERR(args.file); -+ if (IS_ERR(args.file)) -+ goto out_parent; -+ -+ bindex = au_dbtop(dentry); -+ err = au_aopen_or_create(dir, dentry, &args); -+ AuTraceErr(err); -+ AuDbgFile(args.file); -+ file->f_mode = args.file->f_mode & ~FMODE_OPENED; -+ did_open = !!(args.file->f_mode & FMODE_OPENED); -+ if (!did_open) { -+ fput(args.file); -+ args.file = NULL; -+ } -+ di_write_unlock(parent); -+ di_write_unlock(dentry); -+ if (unlikely(err < 0)) { -+ if (args.file) -+ fput(args.file); -+ goto out_sb; -+ } -+ -+ if (!did_open) -+ err = au_aopen_no_open(file, dentry); -+ else { -+ aopen_node.h_file = args.file; -+ err = au_aopen_do_open(file, dentry, &aopen_node); -+ } -+ if (unlikely(err < 0)) { -+ if (args.file) -+ fput(args.file); -+ if (did_open) -+ au_lcnt_dec(&args.br->br_nfiles); -+ } -+ goto out_sb; /* success */ -+ -+out_parent: -+ di_write_unlock(parent); -+ di_write_unlock(dentry); -+out_sb: -+ si_read_unlock(sb); -+out: -+ AuTraceErr(err); -+ AuDbgFile(file); -+ return err; -+} -+ -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent, -+ const unsigned char add_entry, aufs_bindex_t bcpup, -+ aufs_bindex_t btop) -+{ -+ int err; -+ struct dentry *h_parent; -+ struct inode *h_dir; -+ -+ if (add_entry) -+ IMustLock(d_inode(parent)); -+ else -+ di_write_lock_parent(parent); -+ -+ err = 0; -+ if (!au_h_dptr(parent, bcpup)) { -+ if (btop > bcpup) -+ err = au_cpup_dirs(dentry, bcpup); -+ else if (btop < bcpup) -+ err = au_cpdown_dirs(dentry, bcpup); -+ else -+ BUG(); -+ } -+ if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) { -+ h_parent = au_h_dptr(parent, bcpup); -+ h_dir = d_inode(h_parent); -+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT); -+ err = au_lkup_neg(dentry, bcpup, /*wh*/0); -+ /* todo: no unlock here */ -+ inode_unlock_shared(h_dir); -+ -+ AuDbg("bcpup %d\n", bcpup); -+ if (!err) { -+ if (d_really_is_negative(dentry)) -+ au_set_h_dptr(dentry, btop, NULL); -+ au_update_dbrange(dentry, /*do_put_zero*/0); -+ } -+ } -+ -+ if (!add_entry) -+ di_write_unlock(parent); -+ if (!err) -+ err = bcpup; /* success */ -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * decide the branch and the parent dir where we will create a new entry. -+ * returns new bindex or an error. -+ * copyup the parent dir if needed. -+ */ -+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, -+ struct au_wr_dir_args *args) -+{ -+ int err; -+ unsigned int flags; -+ aufs_bindex_t bcpup, btop, src_btop; -+ const unsigned char add_entry -+ = au_ftest_wrdir(args->flags, ADD_ENTRY) -+ | au_ftest_wrdir(args->flags, TMPFILE); -+ struct super_block *sb; -+ struct dentry *parent; -+ struct au_sbinfo *sbinfo; -+ -+ sb = dentry->d_sb; -+ sbinfo = au_sbi(sb); -+ parent = dget_parent(dentry); -+ btop = au_dbtop(dentry); -+ bcpup = btop; -+ if (args->force_btgt < 0) { -+ if (src_dentry) { -+ src_btop = au_dbtop(src_dentry); -+ if (src_btop < btop) -+ bcpup = src_btop; -+ } else if (add_entry) { -+ flags = 0; -+ if (au_ftest_wrdir(args->flags, ISDIR)) -+ au_fset_wbr(flags, DIR); -+ err = AuWbrCreate(sbinfo, dentry, flags); -+ bcpup = err; -+ } -+ -+ if (bcpup < 0 || au_test_ro(sb, bcpup, d_inode(dentry))) { -+ if (add_entry) -+ err = AuWbrCopyup(sbinfo, dentry); -+ else { -+ if (!IS_ROOT(dentry)) { -+ di_read_lock_parent(parent, !AuLock_IR); -+ err = AuWbrCopyup(sbinfo, dentry); -+ di_read_unlock(parent, !AuLock_IR); -+ } else -+ err = AuWbrCopyup(sbinfo, dentry); -+ } -+ bcpup = err; -+ if (unlikely(err < 0)) -+ goto out; -+ } -+ } else { -+ bcpup = args->force_btgt; -+ AuDebugOn(au_test_ro(sb, bcpup, d_inode(dentry))); -+ } -+ -+ AuDbg("btop %d, bcpup %d\n", btop, bcpup); -+ err = bcpup; -+ if (bcpup == btop) -+ goto out; /* success */ -+ -+ /* copyup the new parent into the branch we process */ -+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, btop); -+ if (err >= 0) { -+ if (d_really_is_negative(dentry)) { -+ au_set_h_dptr(dentry, btop, NULL); -+ au_set_dbtop(dentry, bcpup); -+ au_set_dbbot(dentry, bcpup); -+ } -+ AuDebugOn(add_entry -+ && !au_ftest_wrdir(args->flags, TMPFILE) -+ && !au_h_dptr(dentry, bcpup)); -+ } -+ -+out: -+ dput(parent); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_pin_hdir_unlock(struct au_pin *p) -+{ -+ if (p->hdir) -+ au_hn_inode_unlock(p->hdir); -+} -+ -+int au_pin_hdir_lock(struct au_pin *p) -+{ -+ int err; -+ -+ err = 0; -+ if (!p->hdir) -+ goto out; -+ -+ /* even if an error happens later, keep this lock */ -+ au_hn_inode_lock_nested(p->hdir, p->lsc_hi); -+ -+ err = -EBUSY; -+ if (unlikely(p->hdir->hi_inode != d_inode(p->h_parent))) -+ goto out; -+ -+ err = 0; -+ if (p->h_dentry) -+ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode, -+ p->h_parent, p->br); -+ -+out: -+ return err; -+} -+ -+int au_pin_hdir_relock(struct au_pin *p) -+{ -+ int err, i; -+ struct inode *h_i; -+ struct dentry *h_d[] = { -+ p->h_dentry, -+ p->h_parent -+ }; -+ -+ err = au_pin_hdir_lock(p); -+ if (unlikely(err)) -+ goto out; -+ -+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) { -+ if (!h_d[i]) -+ continue; -+ if (d_is_positive(h_d[i])) { -+ h_i = d_inode(h_d[i]); -+ err = !h_i->i_nlink; -+ } -+ } -+ -+out: -+ return err; -+} -+ -+static void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task) -+{ -+#if !defined(CONFIG_RWSEM_GENERIC_SPINLOCK) && defined(CONFIG_RWSEM_SPIN_ON_OWNER) -+ p->hdir->hi_inode->i_rwsem.owner = task; -+#endif -+} -+ -+void au_pin_hdir_acquire_nest(struct au_pin *p) -+{ -+ if (p->hdir) { -+ rwsem_acquire_nest(&p->hdir->hi_inode->i_rwsem.dep_map, -+ p->lsc_hi, 0, NULL, _RET_IP_); -+ au_pin_hdir_set_owner(p, current); -+ } -+} -+ -+void au_pin_hdir_release(struct au_pin *p) -+{ -+ if (p->hdir) { -+ au_pin_hdir_set_owner(p, p->task); -+ rwsem_release(&p->hdir->hi_inode->i_rwsem.dep_map, 1, _RET_IP_); -+ } -+} -+ -+struct dentry *au_pinned_h_parent(struct au_pin *pin) -+{ -+ if (pin && pin->parent) -+ return au_h_dptr(pin->parent, pin->bindex); -+ return NULL; -+} -+ -+void au_unpin(struct au_pin *p) -+{ -+ if (p->hdir) -+ au_pin_hdir_unlock(p); -+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE)) -+ vfsub_mnt_drop_write(p->h_mnt); -+ if (!p->hdir) -+ return; -+ -+ if (!au_ftest_pin(p->flags, DI_LOCKED)) -+ di_read_unlock(p->parent, AuLock_IR); -+ iput(p->hdir->hi_inode); -+ dput(p->parent); -+ p->parent = NULL; -+ p->hdir = NULL; -+ p->h_mnt = NULL; -+ /* do not clear p->task */ -+} -+ -+int au_do_pin(struct au_pin *p) -+{ -+ int err; -+ struct super_block *sb; -+ struct inode *h_dir; -+ -+ err = 0; -+ sb = p->dentry->d_sb; -+ p->br = au_sbr(sb, p->bindex); -+ if (IS_ROOT(p->dentry)) { -+ if (au_ftest_pin(p->flags, MNT_WRITE)) { -+ p->h_mnt = au_br_mnt(p->br); -+ err = vfsub_mnt_want_write(p->h_mnt); -+ if (unlikely(err)) { -+ au_fclr_pin(p->flags, MNT_WRITE); -+ goto out_err; -+ } -+ } -+ goto out; -+ } -+ -+ p->h_dentry = NULL; -+ if (p->bindex <= au_dbbot(p->dentry)) -+ p->h_dentry = au_h_dptr(p->dentry, p->bindex); -+ -+ p->parent = dget_parent(p->dentry); -+ if (!au_ftest_pin(p->flags, DI_LOCKED)) -+ di_read_lock(p->parent, AuLock_IR, p->lsc_di); -+ -+ h_dir = NULL; -+ p->h_parent = au_h_dptr(p->parent, p->bindex); -+ p->hdir = au_hi(d_inode(p->parent), p->bindex); -+ if (p->hdir) -+ h_dir = p->hdir->hi_inode; -+ -+ /* -+ * udba case, or -+ * if DI_LOCKED is not set, then p->parent may be different -+ * and h_parent can be NULL. -+ */ -+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) { -+ err = -EBUSY; -+ if (!au_ftest_pin(p->flags, DI_LOCKED)) -+ di_read_unlock(p->parent, AuLock_IR); -+ dput(p->parent); -+ p->parent = NULL; -+ goto out_err; -+ } -+ -+ if (au_ftest_pin(p->flags, MNT_WRITE)) { -+ p->h_mnt = au_br_mnt(p->br); -+ err = vfsub_mnt_want_write(p->h_mnt); -+ if (unlikely(err)) { -+ au_fclr_pin(p->flags, MNT_WRITE); -+ if (!au_ftest_pin(p->flags, DI_LOCKED)) -+ di_read_unlock(p->parent, AuLock_IR); -+ dput(p->parent); -+ p->parent = NULL; -+ goto out_err; -+ } -+ } -+ -+ au_igrab(h_dir); -+ err = au_pin_hdir_lock(p); -+ if (!err) -+ goto out; /* success */ -+ -+ au_unpin(p); -+ -+out_err: -+ pr_err("err %d\n", err); -+ err = au_busy_or_stale(); -+out: -+ return err; -+} -+ -+void au_pin_init(struct au_pin *p, struct dentry *dentry, -+ aufs_bindex_t bindex, int lsc_di, int lsc_hi, -+ unsigned int udba, unsigned char flags) -+{ -+ p->dentry = dentry; -+ p->udba = udba; -+ p->lsc_di = lsc_di; -+ p->lsc_hi = lsc_hi; -+ p->flags = flags; -+ p->bindex = bindex; -+ -+ p->parent = NULL; -+ p->hdir = NULL; -+ p->h_mnt = NULL; -+ -+ p->h_dentry = NULL; -+ p->h_parent = NULL; -+ p->br = NULL; -+ p->task = current; -+} -+ -+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, -+ unsigned int udba, unsigned char flags) -+{ -+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2, -+ udba, flags); -+ return au_do_pin(pin); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * ->setattr() and ->getattr() are called in various cases. -+ * chmod, stat: dentry is revalidated. -+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be -+ * unhashed. -+ * for ->setattr(), ia->ia_file is passed from ftruncate only. -+ */ -+/* todo: consolidate with do_refresh() and simple_reval_dpath() */ -+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen) -+{ -+ int err; -+ struct dentry *parent; -+ -+ err = 0; -+ if (au_digen_test(dentry, sigen)) { -+ parent = dget_parent(dentry); -+ di_read_lock_parent(parent, AuLock_IR); -+ err = au_refresh_dentry(dentry, parent); -+ di_read_unlock(parent, AuLock_IR); -+ dput(parent); -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia, -+ struct au_icpup_args *a) -+{ -+ int err; -+ loff_t sz; -+ aufs_bindex_t btop, ibtop; -+ struct dentry *hi_wh, *parent; -+ struct inode *inode; -+ struct au_wr_dir_args wr_dir_args = { -+ .force_btgt = -1, -+ .flags = 0 -+ }; -+ -+ if (d_is_dir(dentry)) -+ au_fset_wrdir(wr_dir_args.flags, ISDIR); -+ /* plink or hi_wh() case */ -+ btop = au_dbtop(dentry); -+ inode = d_inode(dentry); -+ ibtop = au_ibtop(inode); -+ if (btop != ibtop && !au_test_ro(inode->i_sb, ibtop, inode)) -+ wr_dir_args.force_btgt = ibtop; -+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args); -+ if (unlikely(err < 0)) -+ goto out; -+ a->btgt = err; -+ if (err != btop) -+ au_fset_icpup(a->flags, DID_CPUP); -+ -+ err = 0; -+ a->pin_flags = AuPin_MNT_WRITE; -+ parent = NULL; -+ if (!IS_ROOT(dentry)) { -+ au_fset_pin(a->pin_flags, DI_LOCKED); -+ parent = dget_parent(dentry); -+ di_write_lock_parent(parent); -+ } -+ -+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ sz = -1; -+ a->h_path.dentry = au_h_dptr(dentry, btop); -+ a->h_inode = d_inode(a->h_path.dentry); -+ if (ia && (ia->ia_valid & ATTR_SIZE)) { -+ inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD); -+ if (ia->ia_size < i_size_read(a->h_inode)) -+ sz = ia->ia_size; -+ inode_unlock_shared(a->h_inode); -+ } -+ -+ hi_wh = NULL; -+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) { -+ hi_wh = au_hi_wh(inode, a->btgt); -+ if (!hi_wh) { -+ struct au_cp_generic cpg = { -+ .dentry = dentry, -+ .bdst = a->btgt, -+ .bsrc = -1, -+ .len = sz, -+ .pin = &a->pin -+ }; -+ err = au_sio_cpup_wh(&cpg, /*file*/NULL); -+ if (unlikely(err)) -+ goto out_unlock; -+ hi_wh = au_hi_wh(inode, a->btgt); -+ /* todo: revalidate hi_wh? */ -+ } -+ } -+ -+ if (parent) { -+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0); -+ di_downgrade_lock(parent, AuLock_IR); -+ dput(parent); -+ parent = NULL; -+ } -+ if (!au_ftest_icpup(a->flags, DID_CPUP)) -+ goto out; /* success */ -+ -+ if (!d_unhashed(dentry)) { -+ struct au_cp_generic cpg = { -+ .dentry = dentry, -+ .bdst = a->btgt, -+ .bsrc = btop, -+ .len = sz, -+ .pin = &a->pin, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN -+ }; -+ err = au_sio_cpup_simple(&cpg); -+ if (!err) -+ a->h_path.dentry = au_h_dptr(dentry, a->btgt); -+ } else if (!hi_wh) -+ a->h_path.dentry = au_h_dptr(dentry, a->btgt); -+ else -+ a->h_path.dentry = hi_wh; /* do not dget here */ -+ -+out_unlock: -+ a->h_inode = d_inode(a->h_path.dentry); -+ if (!err) -+ goto out; /* success */ -+ au_unpin(&a->pin); -+out_parent: -+ if (parent) { -+ di_write_unlock(parent); -+ dput(parent); -+ } -+out: -+ if (!err) -+ inode_lock_nested(a->h_inode, AuLsc_I_CHILD); -+ return err; -+} -+ -+static int aufs_setattr(struct dentry *dentry, struct iattr *ia) -+{ -+ int err; -+ struct inode *inode, *delegated; -+ struct super_block *sb; -+ struct file *file; -+ struct au_icpup_args *a; -+ -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ -+ err = setattr_prepare(dentry, ia); -+ if (unlikely(err)) -+ goto out; -+ -+ err = -ENOMEM; -+ a = kzalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) -+ ia->ia_valid &= ~ATTR_MODE; -+ -+ file = NULL; -+ sb = dentry->d_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out_kfree; -+ -+ if (ia->ia_valid & ATTR_FILE) { -+ /* currently ftruncate(2) only */ -+ AuDebugOn(!d_is_reg(dentry)); -+ file = ia->ia_file; -+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, -+ /*fi_lsc*/0); -+ if (unlikely(err)) -+ goto out_si; -+ ia->ia_file = au_hf_top(file); -+ a->udba = AuOpt_UDBA_NONE; -+ } else { -+ /* fchmod() doesn't pass ia_file */ -+ a->udba = au_opt_udba(sb); -+ di_write_lock_child(dentry); -+ /* no d_unlinked(), to set UDBA_NONE for root */ -+ if (d_unhashed(dentry)) -+ a->udba = AuOpt_UDBA_NONE; -+ if (a->udba != AuOpt_UDBA_NONE) { -+ AuDebugOn(IS_ROOT(dentry)); -+ err = au_reval_for_attr(dentry, au_sigen(sb)); -+ if (unlikely(err)) -+ goto out_dentry; -+ } -+ } -+ -+ err = au_pin_and_icpup(dentry, ia, a); -+ if (unlikely(err < 0)) -+ goto out_dentry; -+ if (au_ftest_icpup(a->flags, DID_CPUP)) { -+ ia->ia_file = NULL; -+ ia->ia_valid &= ~ATTR_FILE; -+ } -+ -+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt); -+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME)) -+ == (ATTR_MODE | ATTR_CTIME)) { -+ err = security_path_chmod(&a->h_path, ia->ia_mode); -+ if (unlikely(err)) -+ goto out_unlock; -+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID)) -+ && (ia->ia_valid & ATTR_CTIME)) { -+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid); -+ if (unlikely(err)) -+ goto out_unlock; -+ } -+ -+ if (ia->ia_valid & ATTR_SIZE) { -+ struct file *f; -+ -+ if (ia->ia_size < i_size_read(inode)) -+ /* unmap only */ -+ truncate_setsize(inode, ia->ia_size); -+ -+ f = NULL; -+ if (ia->ia_valid & ATTR_FILE) -+ f = ia->ia_file; -+ inode_unlock(a->h_inode); -+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f); -+ inode_lock_nested(a->h_inode, AuLsc_I_CHILD); -+ } else { -+ delegated = NULL; -+ while (1) { -+ err = vfsub_notify_change(&a->h_path, ia, &delegated); -+ if (delegated) { -+ err = break_deleg_wait(&delegated); -+ if (!err) -+ continue; -+ } -+ break; -+ } -+ } -+ /* -+ * regardless aufs 'acl' option setting. -+ * why don't all acl-aware fs call this func from their ->setattr()? -+ */ -+ if (!err && (ia->ia_valid & ATTR_MODE)) -+ err = vfsub_acl_chmod(a->h_inode, ia->ia_mode); -+ if (!err) -+ au_cpup_attr_changeable(inode); -+ -+out_unlock: -+ inode_unlock(a->h_inode); -+ au_unpin(&a->pin); -+ if (unlikely(err)) -+ au_update_dbtop(dentry); -+out_dentry: -+ di_write_unlock(dentry); -+ if (file) { -+ fi_write_unlock(file); -+ ia->ia_file = file; -+ ia->ia_valid |= ATTR_FILE; -+ } -+out_si: -+ si_read_unlock(sb); -+out_kfree: -+ kfree(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL) -+static int au_h_path_to_set_attr(struct dentry *dentry, -+ struct au_icpup_args *a, struct path *h_path) -+{ -+ int err; -+ struct super_block *sb; -+ -+ sb = dentry->d_sb; -+ a->udba = au_opt_udba(sb); -+ /* no d_unlinked(), to set UDBA_NONE for root */ -+ if (d_unhashed(dentry)) -+ a->udba = AuOpt_UDBA_NONE; -+ if (a->udba != AuOpt_UDBA_NONE) { -+ AuDebugOn(IS_ROOT(dentry)); -+ err = au_reval_for_attr(dentry, au_sigen(sb)); -+ if (unlikely(err)) -+ goto out; -+ } -+ err = au_pin_and_icpup(dentry, /*ia*/NULL, a); -+ if (unlikely(err < 0)) -+ goto out; -+ -+ h_path->dentry = a->h_path.dentry; -+ h_path->mnt = au_sbr_mnt(sb, a->btgt); -+ -+out: -+ return err; -+} -+ -+ssize_t au_sxattr(struct dentry *dentry, struct inode *inode, -+ struct au_sxattr *arg) -+{ -+ int err; -+ struct path h_path; -+ struct super_block *sb; -+ struct au_icpup_args *a; -+ struct inode *h_inode; -+ -+ IMustLock(inode); -+ -+ err = -ENOMEM; -+ a = kzalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out_kfree; -+ -+ h_path.dentry = NULL; /* silence gcc */ -+ di_write_lock_child(dentry); -+ err = au_h_path_to_set_attr(dentry, a, &h_path); -+ if (unlikely(err)) -+ goto out_di; -+ -+ inode_unlock(a->h_inode); -+ switch (arg->type) { -+ case AU_XATTR_SET: -+ AuDebugOn(d_is_negative(h_path.dentry)); -+ err = vfsub_setxattr(h_path.dentry, -+ arg->u.set.name, arg->u.set.value, -+ arg->u.set.size, arg->u.set.flags); -+ break; -+ case AU_ACL_SET: -+ err = -EOPNOTSUPP; -+ h_inode = d_inode(h_path.dentry); -+ if (h_inode->i_op->set_acl) -+ /* this will call posix_acl_update_mode */ -+ err = h_inode->i_op->set_acl(h_inode, -+ arg->u.acl_set.acl, -+ arg->u.acl_set.type); -+ break; -+ } -+ if (!err) -+ au_cpup_attr_timesizes(inode); -+ -+ au_unpin(&a->pin); -+ if (unlikely(err)) -+ au_update_dbtop(dentry); -+ -+out_di: -+ di_write_unlock(dentry); -+ si_read_unlock(sb); -+out_kfree: -+ kfree(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -+#endif -+ -+static void au_refresh_iattr(struct inode *inode, struct kstat *st, -+ unsigned int nlink) -+{ -+ unsigned int n; -+ -+ inode->i_mode = st->mode; -+ /* don't i_[ug]id_write() here */ -+ inode->i_uid = st->uid; -+ inode->i_gid = st->gid; -+ inode->i_atime = st->atime; -+ inode->i_mtime = st->mtime; -+ inode->i_ctime = st->ctime; -+ -+ au_cpup_attr_nlink(inode, /*force*/0); -+ if (S_ISDIR(inode->i_mode)) { -+ n = inode->i_nlink; -+ n -= nlink; -+ n += st->nlink; -+ smp_mb(); /* for i_nlink */ -+ /* 0 can happen */ -+ set_nlink(inode, n); -+ } -+ -+ spin_lock(&inode->i_lock); -+ inode->i_blocks = st->blocks; -+ i_size_write(inode, st->size); -+ spin_unlock(&inode->i_lock); -+} -+ -+/* -+ * common routine for aufs_getattr() and au_getxattr(). -+ * returns zero or negative (an error). -+ * @dentry will be read-locked in success. -+ */ -+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path, -+ int locked) -+{ -+ int err; -+ unsigned int mnt_flags, sigen; -+ unsigned char udba_none; -+ aufs_bindex_t bindex; -+ struct super_block *sb, *h_sb; -+ struct inode *inode; -+ -+ h_path->mnt = NULL; -+ h_path->dentry = NULL; -+ -+ err = 0; -+ sb = dentry->d_sb; -+ mnt_flags = au_mntflags(sb); -+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE); -+ -+ if (unlikely(locked)) -+ goto body; /* skip locking dinfo */ -+ -+ /* support fstat(2) */ -+ if (!d_unlinked(dentry) && !udba_none) { -+ sigen = au_sigen(sb); -+ err = au_digen_test(dentry, sigen); -+ if (!err) { -+ di_read_lock_child(dentry, AuLock_IR); -+ err = au_dbrange_test(dentry); -+ if (unlikely(err)) { -+ di_read_unlock(dentry, AuLock_IR); -+ goto out; -+ } -+ } else { -+ AuDebugOn(IS_ROOT(dentry)); -+ di_write_lock_child(dentry); -+ err = au_dbrange_test(dentry); -+ if (!err) -+ err = au_reval_for_attr(dentry, sigen); -+ if (!err) -+ di_downgrade_lock(dentry, AuLock_IR); -+ else { -+ di_write_unlock(dentry); -+ goto out; -+ } -+ } -+ } else -+ di_read_lock_child(dentry, AuLock_IR); -+ -+body: -+ inode = d_inode(dentry); -+ bindex = au_ibtop(inode); -+ h_path->mnt = au_sbr_mnt(sb, bindex); -+ h_sb = h_path->mnt->mnt_sb; -+ if (!force -+ && !au_test_fs_bad_iattr(h_sb) -+ && udba_none) -+ goto out; /* success */ -+ -+ if (au_dbtop(dentry) == bindex) -+ h_path->dentry = au_h_dptr(dentry, bindex); -+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) { -+ h_path->dentry = au_plink_lkup(inode, bindex); -+ if (IS_ERR(h_path->dentry)) -+ /* pretending success */ -+ h_path->dentry = NULL; -+ else -+ dput(h_path->dentry); -+ } -+ -+out: -+ return err; -+} -+ -+static int aufs_getattr(const struct path *path, struct kstat *st, -+ u32 request, unsigned int query) -+{ -+ int err; -+ unsigned char positive; -+ struct path h_path; -+ struct dentry *dentry; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ dentry = path->dentry; -+ inode = d_inode(dentry); -+ sb = dentry->d_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out; -+ err = au_h_path_getattr(dentry, /*force*/0, &h_path, /*locked*/0); -+ if (unlikely(err)) -+ goto out_si; -+ if (unlikely(!h_path.dentry)) -+ /* illegally overlapped or something */ -+ goto out_fill; /* pretending success */ -+ -+ positive = d_is_positive(h_path.dentry); -+ if (positive) -+ /* no vfsub version */ -+ err = vfs_getattr(&h_path, st, request, query); -+ if (!err) { -+ if (positive) -+ au_refresh_iattr(inode, st, -+ d_inode(h_path.dentry)->i_nlink); -+ goto out_fill; /* success */ -+ } -+ AuTraceErr(err); -+ goto out_di; -+ -+out_fill: -+ generic_fillattr(inode, st); -+out_di: -+ di_read_unlock(dentry, AuLock_IR); -+out_si: -+ si_read_unlock(sb); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static const char *aufs_get_link(struct dentry *dentry, struct inode *inode, -+ struct delayed_call *done) -+{ -+ const char *ret; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ int err; -+ aufs_bindex_t bindex; -+ -+ ret = NULL; /* suppress a warning */ -+ err = -ECHILD; -+ if (!dentry) -+ goto out; -+ -+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_d_hashed_positive(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ err = -EINVAL; -+ inode = d_inode(dentry); -+ bindex = au_ibtop(inode); -+ h_inode = au_h_iptr(inode, bindex); -+ if (unlikely(!h_inode->i_op->get_link)) -+ goto out_unlock; -+ -+ err = -EBUSY; -+ h_dentry = NULL; -+ if (au_dbtop(dentry) <= bindex) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry) -+ dget(h_dentry); -+ } -+ if (!h_dentry) { -+ h_dentry = d_find_any_alias(h_inode); -+ if (IS_ERR(h_dentry)) { -+ err = PTR_ERR(h_dentry); -+ goto out_unlock; -+ } -+ } -+ if (unlikely(!h_dentry)) -+ goto out_unlock; -+ -+ err = 0; -+ AuDbg("%ps\n", h_inode->i_op->get_link); -+ AuDbgDentry(h_dentry); -+ ret = vfs_get_link(h_dentry, done); -+ dput(h_dentry); -+ if (IS_ERR(ret)) -+ err = PTR_ERR(ret); -+ -+out_unlock: -+ aufs_read_unlock(dentry, AuLock_IR); -+out: -+ if (unlikely(err)) -+ ret = ERR_PTR(err); -+ AuTraceErrPtr(ret); -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_is_special(struct inode *inode) -+{ -+ return (inode->i_mode & (S_IFBLK | S_IFCHR | S_IFIFO | S_IFSOCK)); -+} -+ -+static int aufs_update_time(struct inode *inode, struct timespec64 *ts, -+ int flags) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct super_block *sb; -+ struct inode *h_inode; -+ struct vfsmount *h_mnt; -+ -+ sb = inode->i_sb; -+ WARN_ONCE((flags & S_ATIME) && !IS_NOATIME(inode), -+ "unexpected s_flags 0x%lx", sb->s_flags); -+ -+ /* mmap_sem might be acquired already, cf. aufs_mmap() */ -+ lockdep_off(); -+ si_read_lock(sb, AuLock_FLUSH); -+ ii_write_lock_child(inode); -+ -+ err = 0; -+ bindex = au_ibtop(inode); -+ h_inode = au_h_iptr(inode, bindex); -+ if (!au_test_ro(sb, bindex, inode)) { -+ h_mnt = au_sbr_mnt(sb, bindex); -+ err = vfsub_mnt_want_write(h_mnt); -+ if (!err) { -+ err = vfsub_update_time(h_inode, ts, flags); -+ vfsub_mnt_drop_write(h_mnt); -+ } -+ } else if (au_is_special(h_inode)) { -+ /* -+ * Never copy-up here. -+ * These special files may already be opened and used for -+ * communicating. If we copied it up, then the communication -+ * would be corrupted. -+ */ -+ AuWarn1("timestamps for i%lu are ignored " -+ "since it is on readonly branch (hi%lu).\n", -+ inode->i_ino, h_inode->i_ino); -+ } else if (flags & ~S_ATIME) { -+ err = -EIO; -+ AuIOErr1("unexpected flags 0x%x\n", flags); -+ AuDebugOn(1); -+ } -+ -+ if (!err) -+ au_cpup_attr_timesizes(inode); -+ ii_write_unlock(inode); -+ si_read_unlock(sb); -+ lockdep_on(); -+ -+ if (!err && (flags & S_VERSION)) -+ inode_inc_iversion(inode); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* no getattr version will be set by module.c:aufs_init() */ -+struct inode_operations aufs_iop_nogetattr[AuIop_Last], -+ aufs_iop[] = { -+ [AuIop_SYMLINK] = { -+ .permission = aufs_permission, -+#ifdef CONFIG_FS_POSIX_ACL -+ .get_acl = aufs_get_acl, -+ .set_acl = aufs_set_acl, /* unsupport for symlink? */ -+#endif -+ -+ .setattr = aufs_setattr, -+ .getattr = aufs_getattr, -+ -+#ifdef CONFIG_AUFS_XATTR -+ .listxattr = aufs_listxattr, -+#endif -+ -+ .get_link = aufs_get_link, -+ -+ /* .update_time = aufs_update_time */ -+ }, -+ [AuIop_DIR] = { -+ .create = aufs_create, -+ .lookup = aufs_lookup, -+ .link = aufs_link, -+ .unlink = aufs_unlink, -+ .symlink = aufs_symlink, -+ .mkdir = aufs_mkdir, -+ .rmdir = aufs_rmdir, -+ .mknod = aufs_mknod, -+ .rename = aufs_rename, -+ -+ .permission = aufs_permission, -+#ifdef CONFIG_FS_POSIX_ACL -+ .get_acl = aufs_get_acl, -+ .set_acl = aufs_set_acl, -+#endif -+ -+ .setattr = aufs_setattr, -+ .getattr = aufs_getattr, -+ -+#ifdef CONFIG_AUFS_XATTR -+ .listxattr = aufs_listxattr, -+#endif -+ -+ .update_time = aufs_update_time, -+ .atomic_open = aufs_atomic_open, -+ .tmpfile = aufs_tmpfile -+ }, -+ [AuIop_OTHER] = { -+ .permission = aufs_permission, -+#ifdef CONFIG_FS_POSIX_ACL -+ .get_acl = aufs_get_acl, -+ .set_acl = aufs_set_acl, -+#endif -+ -+ .setattr = aufs_setattr, -+ .getattr = aufs_getattr, -+ -+#ifdef CONFIG_AUFS_XATTR -+ .listxattr = aufs_listxattr, -+#endif -+ -+ .update_time = aufs_update_time -+ } -+}; -diff --git a/fs/aufs/i_op_add.c b/fs/aufs/i_op_add.c -new file mode 100644 -index 000000000..97af9e5e1 ---- /dev/null -+++ b/fs/aufs/i_op_add.c -@@ -0,0 +1,935 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * inode operations (add entry) -+ */ -+ -+#include "aufs.h" -+ -+/* -+ * final procedure of adding a new entry, except link(2). -+ * remove whiteout, instantiate, copyup the parent dir's times and size -+ * and update version. -+ * if it failed, re-create the removed whiteout. -+ */ -+static int epilog(struct inode *dir, aufs_bindex_t bindex, -+ struct dentry *wh_dentry, struct dentry *dentry) -+{ -+ int err, rerr; -+ aufs_bindex_t bwh; -+ struct path h_path; -+ struct super_block *sb; -+ struct inode *inode, *h_dir; -+ struct dentry *wh; -+ -+ bwh = -1; -+ sb = dir->i_sb; -+ if (wh_dentry) { -+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */ -+ IMustLock(h_dir); -+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir); -+ bwh = au_dbwh(dentry); -+ h_path.dentry = wh_dentry; -+ h_path.mnt = au_sbr_mnt(sb, bindex); -+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, -+ dentry); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ inode = au_new_inode(dentry, /*must_new*/1); -+ if (!IS_ERR(inode)) { -+ d_instantiate(dentry, inode); -+ dir = d_inode(dentry->d_parent); /* dir inode is locked */ -+ IMustLock(dir); -+ au_dir_ts(dir, bindex); -+ inode_inc_iversion(dir); -+ au_fhsm_wrote(sb, bindex, /*force*/0); -+ return 0; /* success */ -+ } -+ -+ err = PTR_ERR(inode); -+ if (!wh_dentry) -+ goto out; -+ -+ /* revert */ -+ /* dir inode is locked */ -+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent); -+ rerr = PTR_ERR(wh); -+ if (IS_ERR(wh)) { -+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", -+ dentry, err, rerr); -+ err = -EIO; -+ } else -+ dput(wh); -+ -+out: -+ return err; -+} -+ -+static int au_d_may_add(struct dentry *dentry) -+{ -+ int err; -+ -+ err = 0; -+ if (unlikely(d_unhashed(dentry))) -+ err = -ENOENT; -+ if (unlikely(d_really_is_positive(dentry))) -+ err = -EEXIST; -+ return err; -+} -+ -+/* -+ * simple tests for the adding inode operations. -+ * following the checks in vfs, plus the parent-child relationship. -+ */ -+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent, int isdir) -+{ -+ int err; -+ umode_t h_mode; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ -+ err = -ENAMETOOLONG; -+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN)) -+ goto out; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (d_really_is_negative(dentry)) { -+ err = -EEXIST; -+ if (unlikely(d_is_positive(h_dentry))) -+ goto out; -+ } else { -+ /* rename(2) case */ -+ err = -EIO; -+ if (unlikely(d_is_negative(h_dentry))) -+ goto out; -+ h_inode = d_inode(h_dentry); -+ if (unlikely(!h_inode->i_nlink)) -+ goto out; -+ -+ h_mode = h_inode->i_mode; -+ if (!isdir) { -+ err = -EISDIR; -+ if (unlikely(S_ISDIR(h_mode))) -+ goto out; -+ } else if (unlikely(!S_ISDIR(h_mode))) { -+ err = -ENOTDIR; -+ goto out; -+ } -+ } -+ -+ err = 0; -+ /* expected parent dir is locked */ -+ if (unlikely(h_parent != h_dentry->d_parent)) -+ err = -EIO; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * initial procedure of adding a new entry. -+ * prepare writable branch and the parent dir, lock it, -+ * and lookup whiteout for the new entry. -+ */ -+static struct dentry* -+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt, -+ struct dentry *src_dentry, struct au_pin *pin, -+ struct au_wr_dir_args *wr_dir_args) -+{ -+ struct dentry *wh_dentry, *h_parent; -+ struct super_block *sb; -+ struct au_branch *br; -+ int err; -+ unsigned int udba; -+ aufs_bindex_t bcpup; -+ -+ AuDbg("%pd\n", dentry); -+ -+ err = au_wr_dir(dentry, src_dentry, wr_dir_args); -+ bcpup = err; -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err < 0)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ udba = au_opt_udba(sb); -+ err = au_pin(pin, dentry, bcpup, udba, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ -+ h_parent = au_pinned_h_parent(pin); -+ if (udba != AuOpt_UDBA_NONE -+ && au_dbtop(dentry) == bcpup) -+ err = au_may_add(dentry, bcpup, h_parent, -+ au_ftest_wrdir(wr_dir_args->flags, ISDIR)); -+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN)) -+ err = -ENAMETOOLONG; -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_unpin; -+ -+ br = au_sbr(sb, bcpup); -+ if (dt) { -+ struct path tmp = { -+ .dentry = h_parent, -+ .mnt = au_br_mnt(br) -+ }; -+ au_dtime_store(dt, au_pinned_parent(pin), &tmp); -+ } -+ -+ wh_dentry = NULL; -+ if (bcpup != au_dbwh(dentry)) -+ goto out; /* success */ -+ -+ /* -+ * ENAMETOOLONG here means that if we allowed create such name, then it -+ * would not be able to removed in the future. So we don't allow such -+ * name here and we don't handle ENAMETOOLONG differently here. -+ */ -+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br); -+ -+out_unpin: -+ if (IS_ERR(wh_dentry)) -+ au_unpin(pin); -+out: -+ return wh_dentry; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+enum { Mknod, Symlink, Creat }; -+struct simple_arg { -+ int type; -+ union { -+ struct { -+ umode_t mode; -+ bool want_excl; -+ bool try_aopen; -+ struct vfsub_aopen_args *aopen; -+ } c; -+ struct { -+ const char *symname; -+ } s; -+ struct { -+ umode_t mode; -+ dev_t dev; -+ } m; -+ } u; -+}; -+ -+static int add_simple(struct inode *dir, struct dentry *dentry, -+ struct simple_arg *arg) -+{ -+ int err, rerr; -+ aufs_bindex_t btop; -+ unsigned char created; -+ const unsigned char try_aopen -+ = (arg->type == Creat && arg->u.c.try_aopen); -+ struct vfsub_aopen_args *aopen = arg->u.c.aopen; -+ struct dentry *wh_dentry, *parent; -+ struct inode *h_dir; -+ struct super_block *sb; -+ struct au_branch *br; -+ /* to reduce stack size */ -+ struct { -+ struct au_dtime dt; -+ struct au_pin pin; -+ struct path h_path; -+ struct au_wr_dir_args wr_dir_args; -+ } *a; -+ -+ AuDbg("%pd\n", dentry); -+ IMustLock(dir); -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ a->wr_dir_args.force_btgt = -1; -+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY; -+ -+ parent = dentry->d_parent; /* dir inode is locked */ -+ if (!try_aopen) { -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN); -+ if (unlikely(err)) -+ goto out_free; -+ } -+ err = au_d_may_add(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ if (!try_aopen) -+ di_write_lock_parent(parent); -+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL, -+ &a->pin, &a->wr_dir_args); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ btop = au_dbtop(dentry); -+ sb = dentry->d_sb; -+ br = au_sbr(sb, btop); -+ a->h_path.dentry = au_h_dptr(dentry, btop); -+ a->h_path.mnt = au_br_mnt(br); -+ h_dir = au_pinned_h_dir(&a->pin); -+ switch (arg->type) { -+ case Creat: -+ if (!try_aopen || !h_dir->i_op->atomic_open) { -+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode, -+ arg->u.c.want_excl); -+ created = !err; -+ if (!err && try_aopen) -+ aopen->file->f_mode |= FMODE_CREATED; -+ } else { -+ aopen->br = br; -+ err = vfsub_atomic_open(h_dir, a->h_path.dentry, aopen); -+ AuDbg("err %d\n", err); -+ AuDbgFile(aopen->file); -+ created = err >= 0 -+ && !!(aopen->file->f_mode & FMODE_CREATED); -+ } -+ break; -+ case Symlink: -+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname); -+ created = !err; -+ break; -+ case Mknod: -+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode, -+ arg->u.m.dev); -+ created = !err; -+ break; -+ default: -+ BUG(); -+ } -+ if (unlikely(err < 0)) -+ goto out_unpin; -+ -+ err = epilog(dir, btop, wh_dentry, dentry); -+ if (!err) -+ goto out_unpin; /* success */ -+ -+ /* revert */ -+ if (created /* && d_is_positive(a->h_path.dentry) */) { -+ /* no delegation since it is just created */ -+ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL, -+ /*force*/0); -+ if (rerr) { -+ AuIOErr("%pd revert failure(%d, %d)\n", -+ dentry, err, rerr); -+ err = -EIO; -+ } -+ au_dtime_revert(&a->dt); -+ } -+ if (try_aopen && h_dir->i_op->atomic_open -+ && (aopen->file->f_mode & FMODE_OPENED)) -+ /* aopen->file is still opened */ -+ au_lcnt_dec(&aopen->br->br_nfiles); -+ -+out_unpin: -+ au_unpin(&a->pin); -+ dput(wh_dentry); -+out_parent: -+ if (!try_aopen) -+ di_write_unlock(parent); -+out_unlock: -+ if (unlikely(err)) { -+ au_update_dbtop(dentry); -+ d_drop(dentry); -+ } -+ if (!try_aopen) -+ aufs_read_unlock(dentry, AuLock_DW); -+out_free: -+ kfree(a); -+out: -+ return err; -+} -+ -+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, -+ dev_t dev) -+{ -+ struct simple_arg arg = { -+ .type = Mknod, -+ .u.m = { -+ .mode = mode, -+ .dev = dev -+ } -+ }; -+ return add_simple(dir, dentry, &arg); -+} -+ -+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) -+{ -+ struct simple_arg arg = { -+ .type = Symlink, -+ .u.s.symname = symname -+ }; -+ return add_simple(dir, dentry, &arg); -+} -+ -+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode, -+ bool want_excl) -+{ -+ struct simple_arg arg = { -+ .type = Creat, -+ .u.c = { -+ .mode = mode, -+ .want_excl = want_excl -+ } -+ }; -+ return add_simple(dir, dentry, &arg); -+} -+ -+int au_aopen_or_create(struct inode *dir, struct dentry *dentry, -+ struct vfsub_aopen_args *aopen_args) -+{ -+ struct simple_arg arg = { -+ .type = Creat, -+ .u.c = { -+ .mode = aopen_args->create_mode, -+ .want_excl = aopen_args->open_flag & O_EXCL, -+ .try_aopen = true, -+ .aopen = aopen_args -+ } -+ }; -+ return add_simple(dir, dentry, &arg); -+} -+ -+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct super_block *sb; -+ struct dentry *parent, *h_parent, *h_dentry; -+ struct inode *h_dir, *inode; -+ struct vfsmount *h_mnt; -+ struct au_wr_dir_args wr_dir_args = { -+ .force_btgt = -1, -+ .flags = AuWrDir_TMPFILE -+ }; -+ -+ /* copy-up may happen */ -+ inode_lock(dir); -+ -+ sb = dir->i_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_di_init(dentry); -+ if (unlikely(err)) -+ goto out_si; -+ -+ err = -EBUSY; -+ parent = d_find_any_alias(dir); -+ AuDebugOn(!parent); -+ di_write_lock_parent(parent); -+ if (unlikely(d_inode(parent) != dir)) -+ goto out_parent; -+ -+ err = au_digen_test(parent, au_sigen(sb)); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ bindex = au_dbtop(parent); -+ au_set_dbtop(dentry, bindex); -+ au_set_dbbot(dentry, bindex); -+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args); -+ bindex = err; -+ if (unlikely(err < 0)) -+ goto out_parent; -+ -+ err = -EOPNOTSUPP; -+ h_dir = au_h_iptr(dir, bindex); -+ if (unlikely(!h_dir->i_op->tmpfile)) -+ goto out_parent; -+ -+ h_mnt = au_sbr_mnt(sb, bindex); -+ err = vfsub_mnt_want_write(h_mnt); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ h_parent = au_h_dptr(parent, bindex); -+ h_dentry = vfs_tmpfile(h_parent, mode, /*open_flag*/0); -+ if (IS_ERR(h_dentry)) { -+ err = PTR_ERR(h_dentry); -+ goto out_mnt; -+ } -+ -+ au_set_dbtop(dentry, bindex); -+ au_set_dbbot(dentry, bindex); -+ au_set_h_dptr(dentry, bindex, dget(h_dentry)); -+ inode = au_new_inode(dentry, /*must_new*/1); -+ if (IS_ERR(inode)) { -+ err = PTR_ERR(inode); -+ au_set_h_dptr(dentry, bindex, NULL); -+ au_set_dbtop(dentry, -1); -+ au_set_dbbot(dentry, -1); -+ } else { -+ if (!inode->i_nlink) -+ set_nlink(inode, 1); -+ d_tmpfile(dentry, inode); -+ au_di(dentry)->di_tmpfile = 1; -+ -+ /* update without i_mutex */ -+ if (au_ibtop(dir) == au_dbtop(dentry)) -+ au_cpup_attr_timesizes(dir); -+ } -+ dput(h_dentry); -+ -+out_mnt: -+ vfsub_mnt_drop_write(h_mnt); -+out_parent: -+ di_write_unlock(parent); -+ dput(parent); -+ di_write_unlock(dentry); -+ if (unlikely(err)) { -+ au_di_fin(dentry); -+ dentry->d_fsdata = NULL; -+ } -+out_si: -+ si_read_unlock(sb); -+out: -+ inode_unlock(dir); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_link_args { -+ aufs_bindex_t bdst, bsrc; -+ struct au_pin pin; -+ struct path h_path; -+ struct dentry *src_parent, *parent; -+}; -+ -+static int au_cpup_before_link(struct dentry *src_dentry, -+ struct au_link_args *a) -+{ -+ int err; -+ struct dentry *h_src_dentry; -+ struct au_cp_generic cpg = { -+ .dentry = src_dentry, -+ .bdst = a->bdst, -+ .bsrc = a->bsrc, -+ .len = -1, -+ .pin = &a->pin, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */ -+ }; -+ -+ di_read_lock_parent(a->src_parent, AuLock_IR); -+ err = au_test_and_cpup_dirs(src_dentry, a->bdst); -+ if (unlikely(err)) -+ goto out; -+ -+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc); -+ err = au_pin(&a->pin, src_dentry, a->bdst, -+ au_opt_udba(src_dentry->d_sb), -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_sio_cpup_simple(&cpg); -+ au_unpin(&a->pin); -+ -+out: -+ di_read_unlock(a->src_parent, AuLock_IR); -+ return err; -+} -+ -+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry, -+ struct au_link_args *a) -+{ -+ int err; -+ unsigned char plink; -+ aufs_bindex_t bbot; -+ struct dentry *h_src_dentry; -+ struct inode *h_inode, *inode, *delegated; -+ struct super_block *sb; -+ struct file *h_file; -+ -+ plink = 0; -+ h_inode = NULL; -+ sb = src_dentry->d_sb; -+ inode = d_inode(src_dentry); -+ if (au_ibtop(inode) <= a->bdst) -+ h_inode = au_h_iptr(inode, a->bdst); -+ if (!h_inode || !h_inode->i_nlink) { -+ /* copyup src_dentry as the name of dentry. */ -+ bbot = au_dbbot(dentry); -+ if (bbot < a->bsrc) -+ au_set_dbbot(dentry, a->bsrc); -+ au_set_h_dptr(dentry, a->bsrc, -+ dget(au_h_dptr(src_dentry, a->bsrc))); -+ dget(a->h_path.dentry); -+ au_set_h_dptr(dentry, a->bdst, NULL); -+ AuDbg("temporary d_inode...\n"); -+ spin_lock(&dentry->d_lock); -+ dentry->d_inode = d_inode(src_dentry); /* tmp */ -+ spin_unlock(&dentry->d_lock); -+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0); -+ if (IS_ERR(h_file)) -+ err = PTR_ERR(h_file); -+ else { -+ struct au_cp_generic cpg = { -+ .dentry = dentry, -+ .bdst = a->bdst, -+ .bsrc = -1, -+ .len = -1, -+ .pin = &a->pin, -+ .flags = AuCpup_KEEPLINO -+ }; -+ err = au_sio_cpup_simple(&cpg); -+ au_h_open_post(dentry, a->bsrc, h_file); -+ if (!err) { -+ dput(a->h_path.dentry); -+ a->h_path.dentry = au_h_dptr(dentry, a->bdst); -+ } else -+ au_set_h_dptr(dentry, a->bdst, -+ a->h_path.dentry); -+ } -+ spin_lock(&dentry->d_lock); -+ dentry->d_inode = NULL; /* restore */ -+ spin_unlock(&dentry->d_lock); -+ AuDbg("temporary d_inode...done\n"); -+ au_set_h_dptr(dentry, a->bsrc, NULL); -+ au_set_dbbot(dentry, bbot); -+ } else { -+ /* the inode of src_dentry already exists on a.bdst branch */ -+ h_src_dentry = d_find_alias(h_inode); -+ if (!h_src_dentry && au_plink_test(inode)) { -+ plink = 1; -+ h_src_dentry = au_plink_lkup(inode, a->bdst); -+ err = PTR_ERR(h_src_dentry); -+ if (IS_ERR(h_src_dentry)) -+ goto out; -+ -+ if (unlikely(d_is_negative(h_src_dentry))) { -+ dput(h_src_dentry); -+ h_src_dentry = NULL; -+ } -+ -+ } -+ if (h_src_dentry) { -+ delegated = NULL; -+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), -+ &a->h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ dput(h_src_dentry); -+ } else { -+ AuIOErr("no dentry found for hi%lu on b%d\n", -+ h_inode->i_ino, a->bdst); -+ err = -EIO; -+ } -+ } -+ -+ if (!err && !plink) -+ au_plink_append(inode, a->bdst, a->h_path.dentry); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int aufs_link(struct dentry *src_dentry, struct inode *dir, -+ struct dentry *dentry) -+{ -+ int err, rerr; -+ struct au_dtime dt; -+ struct au_link_args *a; -+ struct dentry *wh_dentry, *h_src_dentry; -+ struct inode *inode, *delegated; -+ struct super_block *sb; -+ struct au_wr_dir_args wr_dir_args = { -+ /* .force_btgt = -1, */ -+ .flags = AuWrDir_ADD_ENTRY -+ }; -+ -+ IMustLock(dir); -+ inode = d_inode(src_dentry); -+ IMustLock(inode); -+ -+ err = -ENOMEM; -+ a = kzalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ a->parent = dentry->d_parent; /* dir inode is locked */ -+ err = aufs_read_and_write_lock2(dentry, src_dentry, -+ AuLock_NOPLM | AuLock_GEN); -+ if (unlikely(err)) -+ goto out_kfree; -+ err = au_d_linkable(src_dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ err = au_d_may_add(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ a->src_parent = dget_parent(src_dentry); -+ wr_dir_args.force_btgt = au_ibtop(inode); -+ -+ di_write_lock_parent(a->parent); -+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt); -+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin, -+ &wr_dir_args); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ err = 0; -+ sb = dentry->d_sb; -+ a->bdst = au_dbtop(dentry); -+ a->h_path.dentry = au_h_dptr(dentry, a->bdst); -+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst); -+ a->bsrc = au_ibtop(inode); -+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc); -+ if (!h_src_dentry && au_di(src_dentry)->di_tmpfile) -+ h_src_dentry = dget(au_hi_wh(inode, a->bsrc)); -+ if (!h_src_dentry) { -+ a->bsrc = au_dbtop(src_dentry); -+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc); -+ AuDebugOn(!h_src_dentry); -+ } else if (IS_ERR(h_src_dentry)) { -+ err = PTR_ERR(h_src_dentry); -+ goto out_parent; -+ } -+ -+ /* -+ * aufs doesn't touch the credential so -+ * security_dentry_create_files_as() is unnecessary. -+ */ -+ if (au_opt_test(au_mntflags(sb), PLINK)) { -+ if (a->bdst < a->bsrc -+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) -+ err = au_cpup_or_link(src_dentry, dentry, a); -+ else { -+ delegated = NULL; -+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), -+ &a->h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ } -+ dput(h_src_dentry); -+ } else { -+ /* -+ * copyup src_dentry to the branch we process, -+ * and then link(2) to it. -+ */ -+ dput(h_src_dentry); -+ if (a->bdst < a->bsrc -+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) { -+ au_unpin(&a->pin); -+ di_write_unlock(a->parent); -+ err = au_cpup_before_link(src_dentry, a); -+ di_write_lock_parent(a->parent); -+ if (!err) -+ err = au_pin(&a->pin, dentry, a->bdst, -+ au_opt_udba(sb), -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out_wh; -+ } -+ if (!err) { -+ h_src_dentry = au_h_dptr(src_dentry, a->bdst); -+ err = -ENOENT; -+ if (h_src_dentry && d_is_positive(h_src_dentry)) { -+ delegated = NULL; -+ err = vfsub_link(h_src_dentry, -+ au_pinned_h_dir(&a->pin), -+ &a->h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry" -+ " for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ } -+ } -+ } -+ if (unlikely(err)) -+ goto out_unpin; -+ -+ if (wh_dentry) { -+ a->h_path.dentry = wh_dentry; -+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path, -+ dentry); -+ if (unlikely(err)) -+ goto out_revert; -+ } -+ -+ au_dir_ts(dir, a->bdst); -+ inode_inc_iversion(dir); -+ inc_nlink(inode); -+ inode->i_ctime = dir->i_ctime; -+ d_instantiate(dentry, au_igrab(inode)); -+ if (d_unhashed(a->h_path.dentry)) -+ /* some filesystem calls d_drop() */ -+ d_drop(dentry); -+ /* some filesystems consume an inode even hardlink */ -+ au_fhsm_wrote(sb, a->bdst, /*force*/0); -+ goto out_unpin; /* success */ -+ -+out_revert: -+ /* no delegation since it is just created */ -+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, -+ /*delegated*/NULL, /*force*/0); -+ if (unlikely(rerr)) { -+ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr); -+ err = -EIO; -+ } -+ au_dtime_revert(&dt); -+out_unpin: -+ au_unpin(&a->pin); -+out_wh: -+ dput(wh_dentry); -+out_parent: -+ di_write_unlock(a->parent); -+ dput(a->src_parent); -+out_unlock: -+ if (unlikely(err)) { -+ au_update_dbtop(dentry); -+ d_drop(dentry); -+ } -+ aufs_read_and_write_unlock2(dentry, src_dentry); -+out_kfree: -+ kfree(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) -+{ -+ int err, rerr; -+ aufs_bindex_t bindex; -+ unsigned char diropq; -+ struct path h_path; -+ struct dentry *wh_dentry, *parent, *opq_dentry; -+ struct inode *h_inode; -+ struct super_block *sb; -+ struct { -+ struct au_pin pin; -+ struct au_dtime dt; -+ } *a; /* reduce the stack usage */ -+ struct au_wr_dir_args wr_dir_args = { -+ .force_btgt = -1, -+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR -+ }; -+ -+ IMustLock(dir); -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN); -+ if (unlikely(err)) -+ goto out_free; -+ err = au_d_may_add(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ parent = dentry->d_parent; /* dir inode is locked */ -+ di_write_lock_parent(parent); -+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL, -+ &a->pin, &wr_dir_args); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ sb = dentry->d_sb; -+ bindex = au_dbtop(dentry); -+ h_path.dentry = au_h_dptr(dentry, bindex); -+ h_path.mnt = au_sbr_mnt(sb, bindex); -+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode); -+ if (unlikely(err)) -+ goto out_unpin; -+ -+ /* make the dir opaque */ -+ diropq = 0; -+ h_inode = d_inode(h_path.dentry); -+ if (wh_dentry -+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) { -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ opq_dentry = au_diropq_create(dentry, bindex); -+ inode_unlock(h_inode); -+ err = PTR_ERR(opq_dentry); -+ if (IS_ERR(opq_dentry)) -+ goto out_dir; -+ dput(opq_dentry); -+ diropq = 1; -+ } -+ -+ err = epilog(dir, bindex, wh_dentry, dentry); -+ if (!err) { -+ inc_nlink(dir); -+ goto out_unpin; /* success */ -+ } -+ -+ /* revert */ -+ if (diropq) { -+ AuLabel(revert opq); -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ rerr = au_diropq_remove(dentry, bindex); -+ inode_unlock(h_inode); -+ if (rerr) { -+ AuIOErr("%pd reverting diropq failed(%d, %d)\n", -+ dentry, err, rerr); -+ err = -EIO; -+ } -+ } -+ -+out_dir: -+ AuLabel(revert dir); -+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path); -+ if (rerr) { -+ AuIOErr("%pd reverting dir failed(%d, %d)\n", -+ dentry, err, rerr); -+ err = -EIO; -+ } -+ au_dtime_revert(&a->dt); -+out_unpin: -+ au_unpin(&a->pin); -+ dput(wh_dentry); -+out_parent: -+ di_write_unlock(parent); -+out_unlock: -+ if (unlikely(err)) { -+ au_update_dbtop(dentry); -+ d_drop(dentry); -+ } -+ aufs_read_unlock(dentry, AuLock_DW); -+out_free: -+ kfree(a); -+out: -+ return err; -+} -diff --git a/fs/aufs/i_op_del.c b/fs/aufs/i_op_del.c -new file mode 100644 -index 000000000..343617d68 ---- /dev/null -+++ b/fs/aufs/i_op_del.c -@@ -0,0 +1,512 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * inode operations (del entry) -+ */ -+ -+#include "aufs.h" -+ -+/* -+ * decide if a new whiteout for @dentry is necessary or not. -+ * when it is necessary, prepare the parent dir for the upper branch whose -+ * branch index is @bcpup for creation. the actual creation of the whiteout will -+ * be done by caller. -+ * return value: -+ * 0: wh is unnecessary -+ * plus: wh is necessary -+ * minus: error -+ */ -+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup) -+{ -+ int need_wh, err; -+ aufs_bindex_t btop; -+ struct super_block *sb; -+ -+ sb = dentry->d_sb; -+ btop = au_dbtop(dentry); -+ if (*bcpup < 0) { -+ *bcpup = btop; -+ if (au_test_ro(sb, btop, d_inode(dentry))) { -+ err = AuWbrCopyup(au_sbi(sb), dentry); -+ *bcpup = err; -+ if (unlikely(err < 0)) -+ goto out; -+ } -+ } else -+ AuDebugOn(btop < *bcpup -+ || au_test_ro(sb, *bcpup, d_inode(dentry))); -+ AuDbg("bcpup %d, btop %d\n", *bcpup, btop); -+ -+ if (*bcpup != btop) { -+ err = au_cpup_dirs(dentry, *bcpup); -+ if (unlikely(err)) -+ goto out; -+ need_wh = 1; -+ } else { -+ struct au_dinfo *dinfo, *tmp; -+ -+ need_wh = -ENOMEM; -+ dinfo = au_di(dentry); -+ tmp = au_di_alloc(sb, AuLsc_DI_TMP); -+ if (tmp) { -+ au_di_cp(tmp, dinfo); -+ au_di_swap(tmp, dinfo); -+ /* returns the number of positive dentries */ -+ need_wh = au_lkup_dentry(dentry, btop + 1, -+ /* AuLkup_IGNORE_PERM */ 0); -+ au_di_swap(tmp, dinfo); -+ au_rw_write_unlock(&tmp->di_rwsem); -+ au_di_free(tmp); -+ } -+ } -+ AuDbg("need_wh %d\n", need_wh); -+ err = need_wh; -+ -+out: -+ return err; -+} -+ -+/* -+ * simple tests for the del-entry operations. -+ * following the checks in vfs, plus the parent-child relationship. -+ */ -+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent, int isdir) -+{ -+ int err; -+ umode_t h_mode; -+ struct dentry *h_dentry, *h_latest; -+ struct inode *h_inode; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (d_really_is_positive(dentry)) { -+ err = -ENOENT; -+ if (unlikely(d_is_negative(h_dentry))) -+ goto out; -+ h_inode = d_inode(h_dentry); -+ if (unlikely(!h_inode->i_nlink)) -+ goto out; -+ -+ h_mode = h_inode->i_mode; -+ if (!isdir) { -+ err = -EISDIR; -+ if (unlikely(S_ISDIR(h_mode))) -+ goto out; -+ } else if (unlikely(!S_ISDIR(h_mode))) { -+ err = -ENOTDIR; -+ goto out; -+ } -+ } else { -+ /* rename(2) case */ -+ err = -EIO; -+ if (unlikely(d_is_positive(h_dentry))) -+ goto out; -+ } -+ -+ err = -ENOENT; -+ /* expected parent dir is locked */ -+ if (unlikely(h_parent != h_dentry->d_parent)) -+ goto out; -+ err = 0; -+ -+ /* -+ * rmdir a dir may break the consistency on some filesystem. -+ * let's try heavy test. -+ */ -+ err = -EACCES; -+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1) -+ && au_test_h_perm(d_inode(h_parent), -+ MAY_EXEC | MAY_WRITE))) -+ goto out; -+ -+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent); -+ err = -EIO; -+ if (IS_ERR(h_latest)) -+ goto out; -+ if (h_latest == h_dentry) -+ err = 0; -+ dput(h_latest); -+ -+out: -+ return err; -+} -+ -+/* -+ * decide the branch where we operate for @dentry. the branch index will be set -+ * @rbcpup. after deciding it, 'pin' it and store the timestamps of the parent -+ * dir for reverting. -+ * when a new whiteout is necessary, create it. -+ */ -+static struct dentry* -+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup, -+ struct au_dtime *dt, struct au_pin *pin) -+{ -+ struct dentry *wh_dentry; -+ struct super_block *sb; -+ struct path h_path; -+ int err, need_wh; -+ unsigned int udba; -+ aufs_bindex_t bcpup; -+ -+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup); -+ wh_dentry = ERR_PTR(need_wh); -+ if (unlikely(need_wh < 0)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ udba = au_opt_udba(sb); -+ bcpup = *rbcpup; -+ err = au_pin(pin, dentry, bcpup, udba, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ -+ h_path.dentry = au_pinned_h_parent(pin); -+ if (udba != AuOpt_UDBA_NONE -+ && au_dbtop(dentry) == bcpup) { -+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir); -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_unpin; -+ } -+ -+ h_path.mnt = au_sbr_mnt(sb, bcpup); -+ au_dtime_store(dt, au_pinned_parent(pin), &h_path); -+ wh_dentry = NULL; -+ if (!need_wh) -+ goto out; /* success, no need to create whiteout */ -+ -+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_unpin; -+ -+ /* returns with the parent is locked and wh_dentry is dget-ed */ -+ goto out; /* success */ -+ -+out_unpin: -+ au_unpin(pin); -+out: -+ return wh_dentry; -+} -+ -+/* -+ * when removing a dir, rename it to a unique temporary whiteout-ed name first -+ * in order to be revertible and save time for removing many child whiteouts -+ * under the dir. -+ * returns 1 when there are too many child whiteout and caller should remove -+ * them asynchronously. returns 0 when the number of children is enough small to -+ * remove now or the branch fs is a remote fs. -+ * otherwise return an error. -+ */ -+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex, -+ struct au_nhash *whlist, struct inode *dir) -+{ -+ int rmdir_later, err, dirwh; -+ struct dentry *h_dentry; -+ struct super_block *sb; -+ struct inode *inode; -+ -+ sb = dentry->d_sb; -+ SiMustAnyLock(sb); -+ h_dentry = au_h_dptr(dentry, bindex); -+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex)); -+ if (unlikely(err)) -+ goto out; -+ -+ /* stop monitoring */ -+ inode = d_inode(dentry); -+ au_hn_free(au_hi(inode, bindex)); -+ -+ if (!au_test_fs_remote(h_dentry->d_sb)) { -+ dirwh = au_sbi(sb)->si_dirwh; -+ rmdir_later = (dirwh <= 1); -+ if (!rmdir_later) -+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex, -+ dirwh); -+ if (rmdir_later) -+ return rmdir_later; -+ } -+ -+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist); -+ if (unlikely(err)) { -+ AuIOErr("rmdir %pd, b%d failed, %d. ignored\n", -+ h_dentry, bindex, err); -+ err = 0; -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * final procedure for deleting a entry. -+ * maintain dentry and iattr. -+ */ -+static void epilog(struct inode *dir, struct dentry *dentry, -+ aufs_bindex_t bindex) -+{ -+ struct inode *inode; -+ -+ inode = d_inode(dentry); -+ d_drop(dentry); -+ inode->i_ctime = dir->i_ctime; -+ -+ au_dir_ts(dir, bindex); -+ inode_inc_iversion(dir); -+} -+ -+/* -+ * when an error happened, remove the created whiteout and revert everything. -+ */ -+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex, -+ aufs_bindex_t bwh, struct dentry *wh_dentry, -+ struct dentry *dentry, struct au_dtime *dt) -+{ -+ int rerr; -+ struct path h_path = { -+ .dentry = wh_dentry, -+ .mnt = au_sbr_mnt(dir->i_sb, bindex) -+ }; -+ -+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry); -+ if (!rerr) { -+ au_set_dbwh(dentry, bwh); -+ au_dtime_revert(dt); -+ return 0; -+ } -+ -+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr); -+ return -EIO; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int aufs_unlink(struct inode *dir, struct dentry *dentry) -+{ -+ int err; -+ aufs_bindex_t bwh, bindex, btop; -+ struct inode *inode, *h_dir, *delegated; -+ struct dentry *parent, *wh_dentry; -+ /* to reduce stack size */ -+ struct { -+ struct au_dtime dt; -+ struct au_pin pin; -+ struct path h_path; -+ } *a; -+ -+ IMustLock(dir); -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN); -+ if (unlikely(err)) -+ goto out_free; -+ err = au_d_hashed_positive(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ err = -EISDIR; -+ if (unlikely(d_is_dir(dentry))) -+ goto out_unlock; /* possible? */ -+ -+ btop = au_dbtop(dentry); -+ bwh = au_dbwh(dentry); -+ bindex = -1; -+ parent = dentry->d_parent; /* dir inode is locked */ -+ di_write_lock_parent(parent); -+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt, -+ &a->pin); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, btop); -+ a->h_path.dentry = au_h_dptr(dentry, btop); -+ dget(a->h_path.dentry); -+ if (bindex == btop) { -+ h_dir = au_pinned_h_dir(&a->pin); -+ delegated = NULL; -+ err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ } else { -+ /* dir inode is locked */ -+ h_dir = d_inode(wh_dentry->d_parent); -+ IMustLock(h_dir); -+ err = 0; -+ } -+ -+ if (!err) { -+ vfsub_drop_nlink(inode); -+ epilog(dir, dentry, bindex); -+ -+ /* update target timestamps */ -+ if (bindex == btop) { -+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); -+ /*ignore*/ -+ inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime; -+ } else -+ /* todo: this timestamp may be reverted later */ -+ inode->i_ctime = h_dir->i_ctime; -+ goto out_unpin; /* success */ -+ } -+ -+ /* revert */ -+ if (wh_dentry) { -+ int rerr; -+ -+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, -+ &a->dt); -+ if (rerr) -+ err = rerr; -+ } -+ -+out_unpin: -+ au_unpin(&a->pin); -+ dput(wh_dentry); -+ dput(a->h_path.dentry); -+out_parent: -+ di_write_unlock(parent); -+out_unlock: -+ aufs_read_unlock(dentry, AuLock_DW); -+out_free: -+ kfree(a); -+out: -+ return err; -+} -+ -+int aufs_rmdir(struct inode *dir, struct dentry *dentry) -+{ -+ int err, rmdir_later; -+ aufs_bindex_t bwh, bindex, btop; -+ struct inode *inode; -+ struct dentry *parent, *wh_dentry, *h_dentry; -+ struct au_whtmp_rmdir *args; -+ /* to reduce stack size */ -+ struct { -+ struct au_dtime dt; -+ struct au_pin pin; -+ } *a; -+ -+ IMustLock(dir); -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN); -+ if (unlikely(err)) -+ goto out_free; -+ err = au_alive_dir(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ err = -ENOTDIR; -+ if (unlikely(!d_is_dir(dentry))) -+ goto out_unlock; /* possible? */ -+ -+ err = -ENOMEM; -+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS); -+ if (unlikely(!args)) -+ goto out_unlock; -+ -+ parent = dentry->d_parent; /* dir inode is locked */ -+ di_write_lock_parent(parent); -+ err = au_test_empty(dentry, &args->whlist); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ btop = au_dbtop(dentry); -+ bwh = au_dbwh(dentry); -+ bindex = -1; -+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt, -+ &a->pin); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ h_dentry = au_h_dptr(dentry, btop); -+ dget(h_dentry); -+ rmdir_later = 0; -+ if (bindex == btop) { -+ err = renwh_and_rmdir(dentry, btop, &args->whlist, dir); -+ if (err > 0) { -+ rmdir_later = err; -+ err = 0; -+ } -+ } else { -+ /* stop monitoring */ -+ au_hn_free(au_hi(inode, btop)); -+ -+ /* dir inode is locked */ -+ IMustLock(d_inode(wh_dentry->d_parent)); -+ err = 0; -+ } -+ -+ if (!err) { -+ vfsub_dead_dir(inode); -+ au_set_dbdiropq(dentry, -1); -+ epilog(dir, dentry, bindex); -+ -+ if (rmdir_later) { -+ au_whtmp_kick_rmdir(dir, btop, h_dentry, args); -+ args = NULL; -+ } -+ -+ goto out_unpin; /* success */ -+ } -+ -+ /* revert */ -+ AuLabel(revert); -+ if (wh_dentry) { -+ int rerr; -+ -+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, -+ &a->dt); -+ if (rerr) -+ err = rerr; -+ } -+ -+out_unpin: -+ au_unpin(&a->pin); -+ dput(wh_dentry); -+ dput(h_dentry); -+out_parent: -+ di_write_unlock(parent); -+ if (args) -+ au_whtmp_rmdir_free(args); -+out_unlock: -+ aufs_read_unlock(dentry, AuLock_DW); -+out_free: -+ kfree(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -diff --git a/fs/aufs/i_op_ren.c b/fs/aufs/i_op_ren.c -new file mode 100644 -index 000000000..f9e5d5d66 ---- /dev/null -+++ b/fs/aufs/i_op_ren.c -@@ -0,0 +1,1249 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * inode operation (rename entry) -+ * todo: this is crazy monster -+ */ -+ -+#include "aufs.h" -+ -+enum { AuSRC, AuDST, AuSrcDst }; -+enum { AuPARENT, AuCHILD, AuParentChild }; -+ -+#define AuRen_ISDIR_SRC 1 -+#define AuRen_ISDIR_DST (1 << 1) -+#define AuRen_ISSAMEDIR (1 << 2) -+#define AuRen_WHSRC (1 << 3) -+#define AuRen_WHDST (1 << 4) -+#define AuRen_MNT_WRITE (1 << 5) -+#define AuRen_DT_DSTDIR (1 << 6) -+#define AuRen_DIROPQ_SRC (1 << 7) -+#define AuRen_DIROPQ_DST (1 << 8) -+#define AuRen_DIRREN (1 << 9) -+#define AuRen_DROPPED_SRC (1 << 10) -+#define AuRen_DROPPED_DST (1 << 11) -+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name) -+#define au_fset_ren(flags, name) \ -+ do { (flags) |= AuRen_##name; } while (0) -+#define au_fclr_ren(flags, name) \ -+ do { (flags) &= ~AuRen_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_DIRREN -+#undef AuRen_DIRREN -+#define AuRen_DIRREN 0 -+#endif -+ -+struct au_ren_args { -+ struct { -+ struct dentry *dentry, *h_dentry, *parent, *h_parent, -+ *wh_dentry; -+ struct inode *dir, *inode; -+ struct au_hinode *hdir, *hinode; -+ struct au_dtime dt[AuParentChild]; -+ aufs_bindex_t btop, bdiropq; -+ } sd[AuSrcDst]; -+ -+#define src_dentry sd[AuSRC].dentry -+#define src_dir sd[AuSRC].dir -+#define src_inode sd[AuSRC].inode -+#define src_h_dentry sd[AuSRC].h_dentry -+#define src_parent sd[AuSRC].parent -+#define src_h_parent sd[AuSRC].h_parent -+#define src_wh_dentry sd[AuSRC].wh_dentry -+#define src_hdir sd[AuSRC].hdir -+#define src_hinode sd[AuSRC].hinode -+#define src_h_dir sd[AuSRC].hdir->hi_inode -+#define src_dt sd[AuSRC].dt -+#define src_btop sd[AuSRC].btop -+#define src_bdiropq sd[AuSRC].bdiropq -+ -+#define dst_dentry sd[AuDST].dentry -+#define dst_dir sd[AuDST].dir -+#define dst_inode sd[AuDST].inode -+#define dst_h_dentry sd[AuDST].h_dentry -+#define dst_parent sd[AuDST].parent -+#define dst_h_parent sd[AuDST].h_parent -+#define dst_wh_dentry sd[AuDST].wh_dentry -+#define dst_hdir sd[AuDST].hdir -+#define dst_hinode sd[AuDST].hinode -+#define dst_h_dir sd[AuDST].hdir->hi_inode -+#define dst_dt sd[AuDST].dt -+#define dst_btop sd[AuDST].btop -+#define dst_bdiropq sd[AuDST].bdiropq -+ -+ struct dentry *h_trap; -+ struct au_branch *br; -+ struct path h_path; -+ struct au_nhash whlist; -+ aufs_bindex_t btgt, src_bwh; -+ -+ struct { -+ unsigned short auren_flags; -+ unsigned char flags; /* syscall parameter */ -+ unsigned char exchange; -+ } __packed; -+ -+ struct au_whtmp_rmdir *thargs; -+ struct dentry *h_dst; -+ struct au_hinode *h_root; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * functions for reverting. -+ * when an error happened in a single rename systemcall, we should revert -+ * everything as if nothing happened. -+ * we don't need to revert the copied-up/down the parent dir since they are -+ * harmless. -+ */ -+ -+#define RevertFailure(fmt, ...) do { \ -+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \ -+ ##__VA_ARGS__, err, rerr); \ -+ err = -EIO; \ -+} while (0) -+ -+static void au_ren_do_rev_diropq(int err, struct au_ren_args *a, int idx) -+{ -+ int rerr; -+ struct dentry *d; -+#define src_or_dst(member) a->sd[idx].member -+ -+ d = src_or_dst(dentry); /* {src,dst}_dentry */ -+ au_hn_inode_lock_nested(src_or_dst(hinode), AuLsc_I_CHILD); -+ rerr = au_diropq_remove(d, a->btgt); -+ au_hn_inode_unlock(src_or_dst(hinode)); -+ au_set_dbdiropq(d, src_or_dst(bdiropq)); -+ if (rerr) -+ RevertFailure("remove diropq %pd", d); -+ -+#undef src_or_dst_ -+} -+ -+static void au_ren_rev_diropq(int err, struct au_ren_args *a) -+{ -+ if (au_ftest_ren(a->auren_flags, DIROPQ_SRC)) -+ au_ren_do_rev_diropq(err, a, AuSRC); -+ if (au_ftest_ren(a->auren_flags, DIROPQ_DST)) -+ au_ren_do_rev_diropq(err, a, AuDST); -+} -+ -+static void au_ren_rev_rename(int err, struct au_ren_args *a) -+{ -+ int rerr; -+ struct inode *delegated; -+ -+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name, -+ a->src_h_parent); -+ rerr = PTR_ERR(a->h_path.dentry); -+ if (IS_ERR(a->h_path.dentry)) { -+ RevertFailure("lkup one %pd", a->src_dentry); -+ return; -+ } -+ -+ delegated = NULL; -+ rerr = vfsub_rename(a->dst_h_dir, -+ au_h_dptr(a->src_dentry, a->btgt), -+ a->src_h_dir, &a->h_path, &delegated, a->flags); -+ if (unlikely(rerr == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal rename\n"); -+ iput(delegated); -+ } -+ d_drop(a->h_path.dentry); -+ dput(a->h_path.dentry); -+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */ -+ if (rerr) -+ RevertFailure("rename %pd", a->src_dentry); -+} -+ -+static void au_ren_rev_whtmp(int err, struct au_ren_args *a) -+{ -+ int rerr; -+ struct inode *delegated; -+ -+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name, -+ a->dst_h_parent); -+ rerr = PTR_ERR(a->h_path.dentry); -+ if (IS_ERR(a->h_path.dentry)) { -+ RevertFailure("lkup one %pd", a->dst_dentry); -+ return; -+ } -+ if (d_is_positive(a->h_path.dentry)) { -+ d_drop(a->h_path.dentry); -+ dput(a->h_path.dentry); -+ return; -+ } -+ -+ delegated = NULL; -+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path, -+ &delegated, a->flags); -+ if (unlikely(rerr == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal rename\n"); -+ iput(delegated); -+ } -+ d_drop(a->h_path.dentry); -+ dput(a->h_path.dentry); -+ if (!rerr) -+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst)); -+ else -+ RevertFailure("rename %pd", a->h_dst); -+} -+ -+static void au_ren_rev_whsrc(int err, struct au_ren_args *a) -+{ -+ int rerr; -+ -+ a->h_path.dentry = a->src_wh_dentry; -+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry); -+ au_set_dbwh(a->src_dentry, a->src_bwh); -+ if (rerr) -+ RevertFailure("unlink %pd", a->src_wh_dentry); -+} -+#undef RevertFailure -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * when we have to copyup the renaming entry, do it with the rename-target name -+ * in order to minimize the cost (the later actual rename is unnecessary). -+ * otherwise rename it on the target branch. -+ */ -+static int au_ren_or_cpup(struct au_ren_args *a) -+{ -+ int err; -+ struct dentry *d; -+ struct inode *delegated; -+ -+ d = a->src_dentry; -+ if (au_dbtop(d) == a->btgt) { -+ a->h_path.dentry = a->dst_h_dentry; -+ AuDebugOn(au_dbtop(d) != a->btgt); -+ delegated = NULL; -+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt), -+ a->dst_h_dir, &a->h_path, &delegated, -+ a->flags); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal rename\n"); -+ iput(delegated); -+ } -+ } else -+ BUG(); -+ -+ if (!err && a->h_dst) -+ /* it will be set to dinfo later */ -+ dget(a->h_dst); -+ -+ return err; -+} -+ -+/* cf. aufs_rmdir() */ -+static int au_ren_del_whtmp(struct au_ren_args *a) -+{ -+ int err; -+ struct inode *dir; -+ -+ dir = a->dst_dir; -+ SiMustAnyLock(dir->i_sb); -+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt, -+ au_sbi(dir->i_sb)->si_dirwh) -+ || au_test_fs_remote(a->h_dst->d_sb)) { -+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist); -+ if (unlikely(err)) -+ pr_warn("failed removing whtmp dir %pd (%d), " -+ "ignored.\n", a->h_dst, err); -+ } else { -+ au_nhash_wh_free(&a->thargs->whlist); -+ a->thargs->whlist = a->whlist; -+ a->whlist.nh_num = 0; -+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs); -+ dput(a->h_dst); -+ a->thargs = NULL; -+ } -+ -+ return 0; -+} -+ -+/* make it 'opaque' dir. */ -+static int au_ren_do_diropq(struct au_ren_args *a, int idx) -+{ -+ int err; -+ struct dentry *d, *diropq; -+#define src_or_dst(member) a->sd[idx].member -+ -+ err = 0; -+ d = src_or_dst(dentry); /* {src,dst}_dentry */ -+ src_or_dst(bdiropq) = au_dbdiropq(d); -+ src_or_dst(hinode) = au_hi(src_or_dst(inode), a->btgt); -+ au_hn_inode_lock_nested(src_or_dst(hinode), AuLsc_I_CHILD); -+ diropq = au_diropq_create(d, a->btgt); -+ au_hn_inode_unlock(src_or_dst(hinode)); -+ if (IS_ERR(diropq)) -+ err = PTR_ERR(diropq); -+ else -+ dput(diropq); -+ -+#undef src_or_dst_ -+ return err; -+} -+ -+static int au_ren_diropq(struct au_ren_args *a) -+{ -+ int err; -+ unsigned char always; -+ struct dentry *d; -+ -+ err = 0; -+ d = a->dst_dentry; /* already renamed on the branch */ -+ always = !!au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ); -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC) -+ && !au_ftest_ren(a->auren_flags, DIRREN) -+ && a->btgt != au_dbdiropq(a->src_dentry) -+ && (a->dst_wh_dentry -+ || a->btgt <= au_dbdiropq(d) -+ /* hide the lower to keep xino */ -+ /* the lowers may not be a dir, but we hide them anyway */ -+ || a->btgt < au_dbbot(d) -+ || always)) { -+ AuDbg("here\n"); -+ err = au_ren_do_diropq(a, AuSRC); -+ if (unlikely(err)) -+ goto out; -+ au_fset_ren(a->auren_flags, DIROPQ_SRC); -+ } -+ if (!a->exchange) -+ goto out; /* success */ -+ -+ d = a->src_dentry; /* already renamed on the branch */ -+ if (au_ftest_ren(a->auren_flags, ISDIR_DST) -+ && a->btgt != au_dbdiropq(a->dst_dentry) -+ && (a->btgt < au_dbdiropq(d) -+ || a->btgt < au_dbbot(d) -+ || always)) { -+ AuDbgDentry(a->src_dentry); -+ AuDbgDentry(a->dst_dentry); -+ err = au_ren_do_diropq(a, AuDST); -+ if (unlikely(err)) -+ goto out_rev_src; -+ au_fset_ren(a->auren_flags, DIROPQ_DST); -+ } -+ goto out; /* success */ -+ -+out_rev_src: -+ AuDbg("err %d, reverting src\n", err); -+ au_ren_rev_diropq(err, a); -+out: -+ return err; -+} -+ -+static int do_rename(struct au_ren_args *a) -+{ -+ int err; -+ struct dentry *d, *h_d; -+ -+ if (!a->exchange) { -+ /* prepare workqueue args for asynchronous rmdir */ -+ h_d = a->dst_h_dentry; -+ if (au_ftest_ren(a->auren_flags, ISDIR_DST) -+ /* && !au_ftest_ren(a->auren_flags, DIRREN) */ -+ && d_is_positive(h_d)) { -+ err = -ENOMEM; -+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, -+ GFP_NOFS); -+ if (unlikely(!a->thargs)) -+ goto out; -+ a->h_dst = dget(h_d); -+ } -+ -+ /* create whiteout for src_dentry */ -+ if (au_ftest_ren(a->auren_flags, WHSRC)) { -+ a->src_bwh = au_dbwh(a->src_dentry); -+ AuDebugOn(a->src_bwh >= 0); -+ a->src_wh_dentry = au_wh_create(a->src_dentry, a->btgt, -+ a->src_h_parent); -+ err = PTR_ERR(a->src_wh_dentry); -+ if (IS_ERR(a->src_wh_dentry)) -+ goto out_thargs; -+ } -+ -+ /* lookup whiteout for dentry */ -+ if (au_ftest_ren(a->auren_flags, WHDST)) { -+ h_d = au_wh_lkup(a->dst_h_parent, -+ &a->dst_dentry->d_name, a->br); -+ err = PTR_ERR(h_d); -+ if (IS_ERR(h_d)) -+ goto out_whsrc; -+ if (d_is_negative(h_d)) -+ dput(h_d); -+ else -+ a->dst_wh_dentry = h_d; -+ } -+ -+ /* rename dentry to tmpwh */ -+ if (a->thargs) { -+ err = au_whtmp_ren(a->dst_h_dentry, a->br); -+ if (unlikely(err)) -+ goto out_whdst; -+ -+ d = a->dst_dentry; -+ au_set_h_dptr(d, a->btgt, NULL); -+ err = au_lkup_neg(d, a->btgt, /*wh*/0); -+ if (unlikely(err)) -+ goto out_whtmp; -+ a->dst_h_dentry = au_h_dptr(d, a->btgt); -+ } -+ } -+ -+ BUG_ON(d_is_positive(a->dst_h_dentry) && a->src_btop != a->btgt); -+#if 0 -+ BUG_ON(!au_ftest_ren(a->auren_flags, DIRREN) -+ && d_is_positive(a->dst_h_dentry) -+ && a->src_btop != a->btgt); -+#endif -+ -+ /* rename by vfs_rename or cpup */ -+ err = au_ren_or_cpup(a); -+ if (unlikely(err)) -+ /* leave the copied-up one */ -+ goto out_whtmp; -+ -+ /* make dir opaque */ -+ err = au_ren_diropq(a); -+ if (unlikely(err)) -+ goto out_rename; -+ -+ /* update target timestamps */ -+ if (a->exchange) { -+ AuDebugOn(au_dbtop(a->dst_dentry) != a->btgt); -+ a->h_path.dentry = au_h_dptr(a->dst_dentry, a->btgt); -+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/ -+ a->dst_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime; -+ } -+ AuDebugOn(au_dbtop(a->src_dentry) != a->btgt); -+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt); -+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/ -+ a->src_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime; -+ -+ if (!a->exchange) { -+ /* remove whiteout for dentry */ -+ if (a->dst_wh_dentry) { -+ a->h_path.dentry = a->dst_wh_dentry; -+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path, -+ a->dst_dentry); -+ if (unlikely(err)) -+ goto out_diropq; -+ } -+ -+ /* remove whtmp */ -+ if (a->thargs) -+ au_ren_del_whtmp(a); /* ignore this error */ -+ -+ au_fhsm_wrote(a->src_dentry->d_sb, a->btgt, /*force*/0); -+ } -+ err = 0; -+ goto out_success; -+ -+out_diropq: -+ au_ren_rev_diropq(err, a); -+out_rename: -+ au_ren_rev_rename(err, a); -+ dput(a->h_dst); -+out_whtmp: -+ if (a->thargs) -+ au_ren_rev_whtmp(err, a); -+out_whdst: -+ dput(a->dst_wh_dentry); -+ a->dst_wh_dentry = NULL; -+out_whsrc: -+ if (a->src_wh_dentry) -+ au_ren_rev_whsrc(err, a); -+out_success: -+ dput(a->src_wh_dentry); -+ dput(a->dst_wh_dentry); -+out_thargs: -+ if (a->thargs) { -+ dput(a->h_dst); -+ au_whtmp_rmdir_free(a->thargs); -+ a->thargs = NULL; -+ } -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * test if @dentry dir can be rename destination or not. -+ * success means, it is a logically empty dir. -+ */ -+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist) -+{ -+ return au_test_empty(dentry, whlist); -+} -+ -+/* -+ * test if @a->src_dentry dir can be rename source or not. -+ * if it can, return 0. -+ * success means, -+ * - it is a logically empty dir. -+ * - or, it exists on writable branch and has no children including whiteouts -+ * on the lower branch unless DIRREN is on. -+ */ -+static int may_rename_srcdir(struct au_ren_args *a) -+{ -+ int err; -+ unsigned int rdhash; -+ aufs_bindex_t btop, btgt; -+ struct dentry *dentry; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ -+ dentry = a->src_dentry; -+ sb = dentry->d_sb; -+ sbinfo = au_sbi(sb); -+ if (au_opt_test(sbinfo->si_mntflags, DIRREN)) -+ au_fset_ren(a->auren_flags, DIRREN); -+ -+ btgt = a->btgt; -+ btop = au_dbtop(dentry); -+ if (btop != btgt) { -+ struct au_nhash whlist; -+ -+ SiMustAnyLock(sb); -+ rdhash = sbinfo->si_rdhash; -+ if (!rdhash) -+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, -+ dentry)); -+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_test_empty(dentry, &whlist); -+ au_nhash_wh_free(&whlist); -+ goto out; -+ } -+ -+ if (btop == au_dbtaildir(dentry)) -+ return 0; /* success */ -+ -+ err = au_test_empty_lower(dentry); -+ -+out: -+ if (err == -ENOTEMPTY) { -+ if (au_ftest_ren(a->auren_flags, DIRREN)) { -+ err = 0; -+ } else { -+ AuWarn1("renaming dir who has child(ren) on multiple " -+ "branches, is not supported\n"); -+ err = -EXDEV; -+ } -+ } -+ return err; -+} -+ -+/* side effect: sets whlist and h_dentry */ -+static int au_ren_may_dir(struct au_ren_args *a) -+{ -+ int err; -+ unsigned int rdhash; -+ struct dentry *d; -+ -+ d = a->dst_dentry; -+ SiMustAnyLock(d->d_sb); -+ -+ err = 0; -+ if (au_ftest_ren(a->auren_flags, ISDIR_DST) && a->dst_inode) { -+ rdhash = au_sbi(d->d_sb)->si_rdhash; -+ if (!rdhash) -+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d)); -+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ -+ if (!a->exchange) { -+ au_set_dbtop(d, a->dst_btop); -+ err = may_rename_dstdir(d, &a->whlist); -+ au_set_dbtop(d, a->btgt); -+ } else -+ err = may_rename_srcdir(a); -+ } -+ a->dst_h_dentry = au_h_dptr(d, au_dbtop(d)); -+ if (unlikely(err)) -+ goto out; -+ -+ d = a->src_dentry; -+ a->src_h_dentry = au_h_dptr(d, au_dbtop(d)); -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) { -+ err = may_rename_srcdir(a); -+ if (unlikely(err)) { -+ au_nhash_wh_free(&a->whlist); -+ a->whlist.nh_num = 0; -+ } -+ } -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * simple tests for rename. -+ * following the checks in vfs, plus the parent-child relationship. -+ */ -+static int au_may_ren(struct au_ren_args *a) -+{ -+ int err, isdir; -+ struct inode *h_inode; -+ -+ if (a->src_btop == a->btgt) { -+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent, -+ au_ftest_ren(a->auren_flags, ISDIR_SRC)); -+ if (unlikely(err)) -+ goto out; -+ err = -EINVAL; -+ if (unlikely(a->src_h_dentry == a->h_trap)) -+ goto out; -+ } -+ -+ err = 0; -+ if (a->dst_btop != a->btgt) -+ goto out; -+ -+ err = -ENOTEMPTY; -+ if (unlikely(a->dst_h_dentry == a->h_trap)) -+ goto out; -+ -+ err = -EIO; -+ isdir = !!au_ftest_ren(a->auren_flags, ISDIR_DST); -+ if (d_really_is_negative(a->dst_dentry)) { -+ if (d_is_negative(a->dst_h_dentry)) -+ err = au_may_add(a->dst_dentry, a->btgt, -+ a->dst_h_parent, isdir); -+ } else { -+ if (unlikely(d_is_negative(a->dst_h_dentry))) -+ goto out; -+ h_inode = d_inode(a->dst_h_dentry); -+ if (h_inode->i_nlink) -+ err = au_may_del(a->dst_dentry, a->btgt, -+ a->dst_h_parent, isdir); -+ } -+ -+out: -+ if (unlikely(err == -ENOENT || err == -EEXIST)) -+ err = -EIO; -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * locking order -+ * (VFS) -+ * - src_dir and dir by lock_rename() -+ * - inode if exists -+ * (aufs) -+ * - lock all -+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls, -+ * + si_read_lock -+ * + di_write_lock2_child() -+ * + di_write_lock_child() -+ * + ii_write_lock_child() -+ * + di_write_lock_child2() -+ * + ii_write_lock_child2() -+ * + src_parent and parent -+ * + di_write_lock_parent() -+ * + ii_write_lock_parent() -+ * + di_write_lock_parent2() -+ * + ii_write_lock_parent2() -+ * + lower src_dir and dir by vfsub_lock_rename() -+ * + verify the every relationships between child and parent. if any -+ * of them failed, unlock all and return -EBUSY. -+ */ -+static void au_ren_unlock(struct au_ren_args *a) -+{ -+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir, -+ a->dst_h_parent, a->dst_hdir); -+ if (au_ftest_ren(a->auren_flags, DIRREN) -+ && a->h_root) -+ au_hn_inode_unlock(a->h_root); -+ if (au_ftest_ren(a->auren_flags, MNT_WRITE)) -+ vfsub_mnt_drop_write(au_br_mnt(a->br)); -+} -+ -+static int au_ren_lock(struct au_ren_args *a) -+{ -+ int err; -+ unsigned int udba; -+ -+ err = 0; -+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt); -+ a->src_hdir = au_hi(a->src_dir, a->btgt); -+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt); -+ a->dst_hdir = au_hi(a->dst_dir, a->btgt); -+ -+ err = vfsub_mnt_want_write(au_br_mnt(a->br)); -+ if (unlikely(err)) -+ goto out; -+ au_fset_ren(a->auren_flags, MNT_WRITE); -+ if (au_ftest_ren(a->auren_flags, DIRREN)) { -+ struct dentry *root; -+ struct inode *dir; -+ -+ /* -+ * sbinfo is already locked, so this ii_read_lock is -+ * unnecessary. but our debugging feature checks it. -+ */ -+ root = a->src_inode->i_sb->s_root; -+ if (root != a->src_parent && root != a->dst_parent) { -+ dir = d_inode(root); -+ ii_read_lock_parent3(dir); -+ a->h_root = au_hi(dir, a->btgt); -+ ii_read_unlock(dir); -+ au_hn_inode_lock_nested(a->h_root, AuLsc_I_PARENT3); -+ } -+ } -+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir, -+ a->dst_h_parent, a->dst_hdir); -+ udba = au_opt_udba(a->src_dentry->d_sb); -+ if (unlikely(a->src_hdir->hi_inode != d_inode(a->src_h_parent) -+ || a->dst_hdir->hi_inode != d_inode(a->dst_h_parent))) -+ err = au_busy_or_stale(); -+ if (!err && au_dbtop(a->src_dentry) == a->btgt) -+ err = au_h_verify(a->src_h_dentry, udba, -+ d_inode(a->src_h_parent), a->src_h_parent, -+ a->br); -+ if (!err && au_dbtop(a->dst_dentry) == a->btgt) -+ err = au_h_verify(a->dst_h_dentry, udba, -+ d_inode(a->dst_h_parent), a->dst_h_parent, -+ a->br); -+ if (!err) -+ goto out; /* success */ -+ -+ err = au_busy_or_stale(); -+ au_ren_unlock(a); -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_ren_refresh_dir(struct au_ren_args *a) -+{ -+ struct inode *dir; -+ -+ dir = a->dst_dir; -+ inode_inc_iversion(dir); -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) { -+ /* is this updating defined in POSIX? */ -+ au_cpup_attr_timesizes(a->src_inode); -+ au_cpup_attr_nlink(dir, /*force*/1); -+ } -+ au_dir_ts(dir, a->btgt); -+ -+ if (a->exchange) { -+ dir = a->src_dir; -+ inode_inc_iversion(dir); -+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)) { -+ /* is this updating defined in POSIX? */ -+ au_cpup_attr_timesizes(a->dst_inode); -+ au_cpup_attr_nlink(dir, /*force*/1); -+ } -+ au_dir_ts(dir, a->btgt); -+ } -+ -+ if (au_ftest_ren(a->auren_flags, ISSAMEDIR)) -+ return; -+ -+ dir = a->src_dir; -+ inode_inc_iversion(dir); -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) -+ au_cpup_attr_nlink(dir, /*force*/1); -+ au_dir_ts(dir, a->btgt); -+} -+ -+static void au_ren_refresh(struct au_ren_args *a) -+{ -+ aufs_bindex_t bbot, bindex; -+ struct dentry *d, *h_d; -+ struct inode *i, *h_i; -+ struct super_block *sb; -+ -+ d = a->dst_dentry; -+ d_drop(d); -+ if (a->h_dst) -+ /* already dget-ed by au_ren_or_cpup() */ -+ au_set_h_dptr(d, a->btgt, a->h_dst); -+ -+ i = a->dst_inode; -+ if (i) { -+ if (!a->exchange) { -+ if (!au_ftest_ren(a->auren_flags, ISDIR_DST)) -+ vfsub_drop_nlink(i); -+ else { -+ vfsub_dead_dir(i); -+ au_cpup_attr_timesizes(i); -+ } -+ au_update_dbrange(d, /*do_put_zero*/1); -+ } else -+ au_cpup_attr_nlink(i, /*force*/1); -+ } else { -+ bbot = a->btgt; -+ for (bindex = au_dbtop(d); bindex < bbot; bindex++) -+ au_set_h_dptr(d, bindex, NULL); -+ bbot = au_dbbot(d); -+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) -+ au_set_h_dptr(d, bindex, NULL); -+ au_update_dbrange(d, /*do_put_zero*/0); -+ } -+ -+ if (a->exchange -+ || au_ftest_ren(a->auren_flags, DIRREN)) { -+ d_drop(a->src_dentry); -+ if (au_ftest_ren(a->auren_flags, DIRREN)) -+ au_set_dbwh(a->src_dentry, -1); -+ return; -+ } -+ -+ d = a->src_dentry; -+ au_set_dbwh(d, -1); -+ bbot = au_dbbot(d); -+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) { -+ h_d = au_h_dptr(d, bindex); -+ if (h_d) -+ au_set_h_dptr(d, bindex, NULL); -+ } -+ au_set_dbbot(d, a->btgt); -+ -+ sb = d->d_sb; -+ i = a->src_inode; -+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i)) -+ return; /* success */ -+ -+ bbot = au_ibbot(i); -+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) { -+ h_i = au_h_iptr(i, bindex); -+ if (h_i) { -+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0); -+ /* ignore this error */ -+ au_set_h_iptr(i, bindex, NULL, 0); -+ } -+ } -+ au_set_ibbot(i, a->btgt); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* mainly for link(2) and rename(2) */ -+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt) -+{ -+ aufs_bindex_t bdiropq, bwh; -+ struct dentry *parent; -+ struct au_branch *br; -+ -+ parent = dentry->d_parent; -+ IMustLock(d_inode(parent)); /* dir is locked */ -+ -+ bdiropq = au_dbdiropq(parent); -+ bwh = au_dbwh(dentry); -+ br = au_sbr(dentry->d_sb, btgt); -+ if (au_br_rdonly(br) -+ || (0 <= bdiropq && bdiropq < btgt) -+ || (0 <= bwh && bwh < btgt)) -+ btgt = -1; -+ -+ AuDbg("btgt %d\n", btgt); -+ return btgt; -+} -+ -+/* sets src_btop, dst_btop and btgt */ -+static int au_ren_wbr(struct au_ren_args *a) -+{ -+ int err; -+ struct au_wr_dir_args wr_dir_args = { -+ /* .force_btgt = -1, */ -+ .flags = AuWrDir_ADD_ENTRY -+ }; -+ -+ a->src_btop = au_dbtop(a->src_dentry); -+ a->dst_btop = au_dbtop(a->dst_dentry); -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC) -+ || au_ftest_ren(a->auren_flags, ISDIR_DST)) -+ au_fset_wrdir(wr_dir_args.flags, ISDIR); -+ wr_dir_args.force_btgt = a->src_btop; -+ if (a->dst_inode && a->dst_btop < a->src_btop) -+ wr_dir_args.force_btgt = a->dst_btop; -+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt); -+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args); -+ a->btgt = err; -+ if (a->exchange) -+ au_update_dbtop(a->dst_dentry); -+ -+ return err; -+} -+ -+static void au_ren_dt(struct au_ren_args *a) -+{ -+ a->h_path.dentry = a->src_h_parent; -+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path); -+ if (!au_ftest_ren(a->auren_flags, ISSAMEDIR)) { -+ a->h_path.dentry = a->dst_h_parent; -+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path); -+ } -+ -+ au_fclr_ren(a->auren_flags, DT_DSTDIR); -+ if (!au_ftest_ren(a->auren_flags, ISDIR_SRC) -+ && !a->exchange) -+ return; -+ -+ a->h_path.dentry = a->src_h_dentry; -+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path); -+ if (d_is_positive(a->dst_h_dentry)) { -+ au_fset_ren(a->auren_flags, DT_DSTDIR); -+ a->h_path.dentry = a->dst_h_dentry; -+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path); -+ } -+} -+ -+static void au_ren_rev_dt(int err, struct au_ren_args *a) -+{ -+ struct dentry *h_d; -+ struct inode *h_inode; -+ -+ au_dtime_revert(a->src_dt + AuPARENT); -+ if (!au_ftest_ren(a->auren_flags, ISSAMEDIR)) -+ au_dtime_revert(a->dst_dt + AuPARENT); -+ -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC) && err != -EIO) { -+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry; -+ h_inode = d_inode(h_d); -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ au_dtime_revert(a->src_dt + AuCHILD); -+ inode_unlock(h_inode); -+ -+ if (au_ftest_ren(a->auren_flags, DT_DSTDIR)) { -+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry; -+ h_inode = d_inode(h_d); -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ au_dtime_revert(a->dst_dt + AuCHILD); -+ inode_unlock(h_inode); -+ } -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry, -+ struct inode *_dst_dir, struct dentry *_dst_dentry, -+ unsigned int _flags) -+{ -+ int err, lock_flags; -+ void *rev; -+ /* reduce stack space */ -+ struct au_ren_args *a; -+ struct au_pin pin; -+ -+ AuDbg("%pd, %pd, 0x%x\n", _src_dentry, _dst_dentry, _flags); -+ IMustLock(_src_dir); -+ IMustLock(_dst_dir); -+ -+ err = -EINVAL; -+ if (unlikely(_flags & RENAME_WHITEOUT)) -+ goto out; -+ -+ err = -ENOMEM; -+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE); -+ a = kzalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ a->flags = _flags; -+ BUILD_BUG_ON(sizeof(a->exchange) == sizeof(u8) -+ && RENAME_EXCHANGE > U8_MAX); -+ a->exchange = _flags & RENAME_EXCHANGE; -+ a->src_dir = _src_dir; -+ a->src_dentry = _src_dentry; -+ a->src_inode = NULL; -+ if (d_really_is_positive(a->src_dentry)) -+ a->src_inode = d_inode(a->src_dentry); -+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */ -+ a->dst_dir = _dst_dir; -+ a->dst_dentry = _dst_dentry; -+ a->dst_inode = NULL; -+ if (d_really_is_positive(a->dst_dentry)) -+ a->dst_inode = d_inode(a->dst_dentry); -+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */ -+ if (a->dst_inode) { -+ /* -+ * if EXCHANGE && src is non-dir && dst is dir, -+ * dst is not locked. -+ */ -+ /* IMustLock(a->dst_inode); */ -+ au_igrab(a->dst_inode); -+ } -+ -+ err = -ENOTDIR; -+ lock_flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN; -+ if (d_is_dir(a->src_dentry)) { -+ au_fset_ren(a->auren_flags, ISDIR_SRC); -+ if (unlikely(!a->exchange -+ && d_really_is_positive(a->dst_dentry) -+ && !d_is_dir(a->dst_dentry))) -+ goto out_free; -+ lock_flags |= AuLock_DIRS; -+ } -+ if (a->dst_inode && d_is_dir(a->dst_dentry)) { -+ au_fset_ren(a->auren_flags, ISDIR_DST); -+ if (unlikely(!a->exchange -+ && d_really_is_positive(a->src_dentry) -+ && !d_is_dir(a->src_dentry))) -+ goto out_free; -+ lock_flags |= AuLock_DIRS; -+ } -+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, -+ lock_flags); -+ if (unlikely(err)) -+ goto out_free; -+ -+ err = au_d_hashed_positive(a->src_dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ err = -ENOENT; -+ if (a->dst_inode) { -+ /* -+ * If it is a dir, VFS unhash it before this -+ * function. It means we cannot rely upon d_unhashed(). -+ */ -+ if (unlikely(!a->dst_inode->i_nlink)) -+ goto out_unlock; -+ if (!au_ftest_ren(a->auren_flags, ISDIR_DST)) { -+ err = au_d_hashed_positive(a->dst_dentry); -+ if (unlikely(err && !a->exchange)) -+ goto out_unlock; -+ } else if (unlikely(IS_DEADDIR(a->dst_inode))) -+ goto out_unlock; -+ } else if (unlikely(d_unhashed(a->dst_dentry))) -+ goto out_unlock; -+ -+ /* -+ * is it possible? -+ * yes, it happened (in linux-3.3-rcN) but I don't know why. -+ * there may exist a problem somewhere else. -+ */ -+ err = -EINVAL; -+ if (unlikely(d_inode(a->dst_parent) == d_inode(a->src_dentry))) -+ goto out_unlock; -+ -+ au_fset_ren(a->auren_flags, ISSAMEDIR); /* temporary */ -+ di_write_lock_parent(a->dst_parent); -+ -+ /* which branch we process */ -+ err = au_ren_wbr(a); -+ if (unlikely(err < 0)) -+ goto out_parent; -+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt); -+ a->h_path.mnt = au_br_mnt(a->br); -+ -+ /* are they available to be renamed */ -+ err = au_ren_may_dir(a); -+ if (unlikely(err)) -+ goto out_children; -+ -+ /* prepare the writable parent dir on the same branch */ -+ if (a->dst_btop == a->btgt) { -+ au_fset_ren(a->auren_flags, WHDST); -+ } else { -+ err = au_cpup_dirs(a->dst_dentry, a->btgt); -+ if (unlikely(err)) -+ goto out_children; -+ } -+ -+ err = 0; -+ if (!a->exchange) { -+ if (a->src_dir != a->dst_dir) { -+ /* -+ * this temporary unlock is safe, -+ * because both dir->i_mutex are locked. -+ */ -+ di_write_unlock(a->dst_parent); -+ di_write_lock_parent(a->src_parent); -+ err = au_wr_dir_need_wh(a->src_dentry, -+ au_ftest_ren(a->auren_flags, -+ ISDIR_SRC), -+ &a->btgt); -+ di_write_unlock(a->src_parent); -+ di_write_lock2_parent(a->src_parent, a->dst_parent, -+ /*isdir*/1); -+ au_fclr_ren(a->auren_flags, ISSAMEDIR); -+ } else -+ err = au_wr_dir_need_wh(a->src_dentry, -+ au_ftest_ren(a->auren_flags, -+ ISDIR_SRC), -+ &a->btgt); -+ } -+ if (unlikely(err < 0)) -+ goto out_children; -+ if (err) -+ au_fset_ren(a->auren_flags, WHSRC); -+ -+ /* cpup src */ -+ if (a->src_btop != a->btgt) { -+ err = au_pin(&pin, a->src_dentry, a->btgt, -+ au_opt_udba(a->src_dentry->d_sb), -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (!err) { -+ struct au_cp_generic cpg = { -+ .dentry = a->src_dentry, -+ .bdst = a->btgt, -+ .bsrc = a->src_btop, -+ .len = -1, -+ .pin = &pin, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN -+ }; -+ AuDebugOn(au_dbtop(a->src_dentry) != a->src_btop); -+ err = au_sio_cpup_simple(&cpg); -+ au_unpin(&pin); -+ } -+ if (unlikely(err)) -+ goto out_children; -+ a->src_btop = a->btgt; -+ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt); -+ if (!a->exchange) -+ au_fset_ren(a->auren_flags, WHSRC); -+ } -+ -+ /* cpup dst */ -+ if (a->exchange && a->dst_inode -+ && a->dst_btop != a->btgt) { -+ err = au_pin(&pin, a->dst_dentry, a->btgt, -+ au_opt_udba(a->dst_dentry->d_sb), -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (!err) { -+ struct au_cp_generic cpg = { -+ .dentry = a->dst_dentry, -+ .bdst = a->btgt, -+ .bsrc = a->dst_btop, -+ .len = -1, -+ .pin = &pin, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN -+ }; -+ err = au_sio_cpup_simple(&cpg); -+ au_unpin(&pin); -+ } -+ if (unlikely(err)) -+ goto out_children; -+ a->dst_btop = a->btgt; -+ a->dst_h_dentry = au_h_dptr(a->dst_dentry, a->btgt); -+ } -+ -+ /* lock them all */ -+ err = au_ren_lock(a); -+ if (unlikely(err)) -+ /* leave the copied-up one */ -+ goto out_children; -+ -+ if (!a->exchange) { -+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE)) -+ err = au_may_ren(a); -+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN)) -+ err = -ENAMETOOLONG; -+ if (unlikely(err)) -+ goto out_hdir; -+ } -+ -+ /* store timestamps to be revertible */ -+ au_ren_dt(a); -+ -+ /* store dirren info */ -+ if (au_ftest_ren(a->auren_flags, DIRREN)) { -+ err = au_dr_rename(a->src_dentry, a->btgt, -+ &a->dst_dentry->d_name, &rev); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out_dt; -+ } -+ -+ /* here we go */ -+ err = do_rename(a); -+ if (unlikely(err)) -+ goto out_dirren; -+ -+ if (au_ftest_ren(a->auren_flags, DIRREN)) -+ au_dr_rename_fin(a->src_dentry, a->btgt, rev); -+ -+ /* update dir attributes */ -+ au_ren_refresh_dir(a); -+ -+ /* dput/iput all lower dentries */ -+ au_ren_refresh(a); -+ -+ goto out_hdir; /* success */ -+ -+out_dirren: -+ if (au_ftest_ren(a->auren_flags, DIRREN)) -+ au_dr_rename_rev(a->src_dentry, a->btgt, rev); -+out_dt: -+ au_ren_rev_dt(err, a); -+out_hdir: -+ au_ren_unlock(a); -+out_children: -+ au_nhash_wh_free(&a->whlist); -+ if (err && a->dst_inode && a->dst_btop != a->btgt) { -+ AuDbg("btop %d, btgt %d\n", a->dst_btop, a->btgt); -+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL); -+ au_set_dbtop(a->dst_dentry, a->dst_btop); -+ } -+out_parent: -+ if (!err) { -+ if (d_unhashed(a->src_dentry)) -+ au_fset_ren(a->auren_flags, DROPPED_SRC); -+ if (d_unhashed(a->dst_dentry)) -+ au_fset_ren(a->auren_flags, DROPPED_DST); -+ if (!a->exchange) -+ d_move(a->src_dentry, a->dst_dentry); -+ else { -+ d_exchange(a->src_dentry, a->dst_dentry); -+ if (au_ftest_ren(a->auren_flags, DROPPED_DST)) -+ d_drop(a->dst_dentry); -+ } -+ if (au_ftest_ren(a->auren_flags, DROPPED_SRC)) -+ d_drop(a->src_dentry); -+ } else { -+ au_update_dbtop(a->dst_dentry); -+ if (!a->dst_inode) -+ d_drop(a->dst_dentry); -+ } -+ if (au_ftest_ren(a->auren_flags, ISSAMEDIR)) -+ di_write_unlock(a->dst_parent); -+ else -+ di_write_unlock2(a->src_parent, a->dst_parent); -+out_unlock: -+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry); -+out_free: -+ iput(a->dst_inode); -+ if (a->thargs) -+ au_whtmp_rmdir_free(a->thargs); -+ kfree(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -diff --git a/fs/aufs/iinfo.c b/fs/aufs/iinfo.c -new file mode 100644 -index 000000000..f6c512d96 ---- /dev/null -+++ b/fs/aufs/iinfo.c -@@ -0,0 +1,286 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * inode private data -+ */ -+ -+#include "aufs.h" -+ -+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex) -+{ -+ struct inode *h_inode; -+ struct au_hinode *hinode; -+ -+ IiMustAnyLock(inode); -+ -+ hinode = au_hinode(au_ii(inode), bindex); -+ h_inode = hinode->hi_inode; -+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); -+ return h_inode; -+} -+ -+/* todo: hard/soft set? */ -+void au_hiput(struct au_hinode *hinode) -+{ -+ au_hn_free(hinode); -+ dput(hinode->hi_whdentry); -+ iput(hinode->hi_inode); -+} -+ -+unsigned int au_hi_flags(struct inode *inode, int isdir) -+{ -+ unsigned int flags; -+ const unsigned int mnt_flags = au_mntflags(inode->i_sb); -+ -+ flags = 0; -+ if (au_opt_test(mnt_flags, XINO)) -+ au_fset_hi(flags, XINO); -+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY)) -+ au_fset_hi(flags, HNOTIFY); -+ return flags; -+} -+ -+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, -+ struct inode *h_inode, unsigned int flags) -+{ -+ struct au_hinode *hinode; -+ struct inode *hi; -+ struct au_iinfo *iinfo = au_ii(inode); -+ -+ IiMustWriteLock(inode); -+ -+ hinode = au_hinode(iinfo, bindex); -+ hi = hinode->hi_inode; -+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); -+ -+ if (hi) -+ au_hiput(hinode); -+ hinode->hi_inode = h_inode; -+ if (h_inode) { -+ int err; -+ struct super_block *sb = inode->i_sb; -+ struct au_branch *br; -+ -+ AuDebugOn(inode->i_mode -+ && (h_inode->i_mode & S_IFMT) -+ != (inode->i_mode & S_IFMT)); -+ if (bindex == iinfo->ii_btop) -+ au_cpup_igen(inode, h_inode); -+ br = au_sbr(sb, bindex); -+ hinode->hi_id = br->br_id; -+ if (au_ftest_hi(flags, XINO)) { -+ err = au_xino_write(sb, bindex, h_inode->i_ino, -+ inode->i_ino); -+ if (unlikely(err)) -+ AuIOErr1("failed au_xino_write() %d\n", err); -+ } -+ -+ if (au_ftest_hi(flags, HNOTIFY) -+ && au_br_hnotifyable(br->br_perm)) { -+ err = au_hn_alloc(hinode, inode); -+ if (unlikely(err)) -+ AuIOErr1("au_hn_alloc() %d\n", err); -+ } -+ } -+} -+ -+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_wh) -+{ -+ struct au_hinode *hinode; -+ -+ IiMustWriteLock(inode); -+ -+ hinode = au_hinode(au_ii(inode), bindex); -+ AuDebugOn(hinode->hi_whdentry); -+ hinode->hi_whdentry = h_wh; -+} -+ -+void au_update_iigen(struct inode *inode, int half) -+{ -+ struct au_iinfo *iinfo; -+ struct au_iigen *iigen; -+ unsigned int sigen; -+ -+ sigen = au_sigen(inode->i_sb); -+ iinfo = au_ii(inode); -+ iigen = &iinfo->ii_generation; -+ spin_lock(&iigen->ig_spin); -+ iigen->ig_generation = sigen; -+ if (half) -+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED); -+ else -+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED); -+ spin_unlock(&iigen->ig_spin); -+} -+ -+/* it may be called at remount time, too */ -+void au_update_ibrange(struct inode *inode, int do_put_zero) -+{ -+ struct au_iinfo *iinfo; -+ aufs_bindex_t bindex, bbot; -+ -+ AuDebugOn(au_is_bad_inode(inode)); -+ IiMustWriteLock(inode); -+ -+ iinfo = au_ii(inode); -+ if (do_put_zero && iinfo->ii_btop >= 0) { -+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot; -+ bindex++) { -+ struct inode *h_i; -+ -+ h_i = au_hinode(iinfo, bindex)->hi_inode; -+ if (h_i -+ && !h_i->i_nlink -+ && !(h_i->i_state & I_LINKABLE)) -+ au_set_h_iptr(inode, bindex, NULL, 0); -+ } -+ } -+ -+ iinfo->ii_btop = -1; -+ iinfo->ii_bbot = -1; -+ bbot = au_sbbot(inode->i_sb); -+ for (bindex = 0; bindex <= bbot; bindex++) -+ if (au_hinode(iinfo, bindex)->hi_inode) { -+ iinfo->ii_btop = bindex; -+ break; -+ } -+ if (iinfo->ii_btop >= 0) -+ for (bindex = bbot; bindex >= iinfo->ii_btop; bindex--) -+ if (au_hinode(iinfo, bindex)->hi_inode) { -+ iinfo->ii_bbot = bindex; -+ break; -+ } -+ AuDebugOn(iinfo->ii_btop > iinfo->ii_bbot); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_icntnr_init_once(void *_c) -+{ -+ struct au_icntnr *c = _c; -+ struct au_iinfo *iinfo = &c->iinfo; -+ -+ spin_lock_init(&iinfo->ii_generation.ig_spin); -+ au_rw_init(&iinfo->ii_rwsem); -+ inode_init_once(&c->vfs_inode); -+} -+ -+void au_hinode_init(struct au_hinode *hinode) -+{ -+ hinode->hi_inode = NULL; -+ hinode->hi_id = -1; -+ au_hn_init(hinode); -+ hinode->hi_whdentry = NULL; -+} -+ -+int au_iinfo_init(struct inode *inode) -+{ -+ struct au_iinfo *iinfo; -+ struct super_block *sb; -+ struct au_hinode *hi; -+ int nbr, i; -+ -+ sb = inode->i_sb; -+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); -+ nbr = au_sbbot(sb) + 1; -+ if (unlikely(nbr <= 0)) -+ nbr = 1; -+ hi = kmalloc_array(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS); -+ if (hi) { -+ au_lcnt_inc(&au_sbi(sb)->si_ninodes); -+ -+ iinfo->ii_hinode = hi; -+ for (i = 0; i < nbr; i++, hi++) -+ au_hinode_init(hi); -+ -+ iinfo->ii_generation.ig_generation = au_sigen(sb); -+ iinfo->ii_btop = -1; -+ iinfo->ii_bbot = -1; -+ iinfo->ii_vdir = NULL; -+ return 0; -+ } -+ return -ENOMEM; -+} -+ -+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink) -+{ -+ int err, i; -+ struct au_hinode *hip; -+ -+ AuRwMustWriteLock(&iinfo->ii_rwsem); -+ -+ err = -ENOMEM; -+ hip = au_krealloc(iinfo->ii_hinode, sizeof(*hip) * nbr, GFP_NOFS, -+ may_shrink); -+ if (hip) { -+ iinfo->ii_hinode = hip; -+ i = iinfo->ii_bbot + 1; -+ hip += i; -+ for (; i < nbr; i++, hip++) -+ au_hinode_init(hip); -+ err = 0; -+ } -+ -+ return err; -+} -+ -+void au_iinfo_fin(struct inode *inode) -+{ -+ struct au_iinfo *iinfo; -+ struct au_hinode *hi; -+ struct super_block *sb; -+ aufs_bindex_t bindex, bbot; -+ const unsigned char unlinked = !inode->i_nlink; -+ -+ AuDebugOn(au_is_bad_inode(inode)); -+ -+ sb = inode->i_sb; -+ au_lcnt_dec(&au_sbi(sb)->si_ninodes); -+ if (si_pid_test(sb)) -+ au_xino_delete_inode(inode, unlinked); -+ else { -+ /* -+ * it is safe to hide the dependency between sbinfo and -+ * sb->s_umount. -+ */ -+ lockdep_off(); -+ si_noflush_read_lock(sb); -+ au_xino_delete_inode(inode, unlinked); -+ si_read_unlock(sb); -+ lockdep_on(); -+ } -+ -+ iinfo = au_ii(inode); -+ if (iinfo->ii_vdir) -+ au_vdir_free(iinfo->ii_vdir); -+ -+ bindex = iinfo->ii_btop; -+ if (bindex >= 0) { -+ hi = au_hinode(iinfo, bindex); -+ bbot = iinfo->ii_bbot; -+ while (bindex++ <= bbot) { -+ if (hi->hi_inode) -+ au_hiput(hi); -+ hi++; -+ } -+ } -+ kfree(iinfo->ii_hinode); -+ AuRwDestroy(&iinfo->ii_rwsem); -+} -diff --git a/fs/aufs/inode.c b/fs/aufs/inode.c -new file mode 100644 -index 000000000..50ec91179 ---- /dev/null -+++ b/fs/aufs/inode.c -@@ -0,0 +1,528 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * inode functions -+ */ -+ -+#include "aufs.h" -+ -+struct inode *au_igrab(struct inode *inode) -+{ -+ if (inode) { -+ AuDebugOn(!atomic_read(&inode->i_count)); -+ ihold(inode); -+ } -+ return inode; -+} -+ -+static void au_refresh_hinode_attr(struct inode *inode, int do_version) -+{ -+ au_cpup_attr_all(inode, /*force*/0); -+ au_update_iigen(inode, /*half*/1); -+ if (do_version) -+ inode_inc_iversion(inode); -+} -+ -+static int au_ii_refresh(struct inode *inode, int *update) -+{ -+ int err, e, nbr; -+ umode_t type; -+ aufs_bindex_t bindex, new_bindex; -+ struct super_block *sb; -+ struct au_iinfo *iinfo; -+ struct au_hinode *p, *q, tmp; -+ -+ AuDebugOn(au_is_bad_inode(inode)); -+ IiMustWriteLock(inode); -+ -+ *update = 0; -+ sb = inode->i_sb; -+ nbr = au_sbbot(sb) + 1; -+ type = inode->i_mode & S_IFMT; -+ iinfo = au_ii(inode); -+ err = au_hinode_realloc(iinfo, nbr, /*may_shrink*/0); -+ if (unlikely(err)) -+ goto out; -+ -+ AuDebugOn(iinfo->ii_btop < 0); -+ p = au_hinode(iinfo, iinfo->ii_btop); -+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot; -+ bindex++, p++) { -+ if (!p->hi_inode) -+ continue; -+ -+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT)); -+ new_bindex = au_br_index(sb, p->hi_id); -+ if (new_bindex == bindex) -+ continue; -+ -+ if (new_bindex < 0) { -+ *update = 1; -+ au_hiput(p); -+ p->hi_inode = NULL; -+ continue; -+ } -+ -+ if (new_bindex < iinfo->ii_btop) -+ iinfo->ii_btop = new_bindex; -+ if (iinfo->ii_bbot < new_bindex) -+ iinfo->ii_bbot = new_bindex; -+ /* swap two lower inode, and loop again */ -+ q = au_hinode(iinfo, new_bindex); -+ tmp = *q; -+ *q = *p; -+ *p = tmp; -+ if (tmp.hi_inode) { -+ bindex--; -+ p--; -+ } -+ } -+ au_update_ibrange(inode, /*do_put_zero*/0); -+ au_hinode_realloc(iinfo, nbr, /*may_shrink*/1); /* harmless if err */ -+ e = au_dy_irefresh(inode); -+ if (unlikely(e && !err)) -+ err = e; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_refresh_iop(struct inode *inode, int force_getattr) -+{ -+ int type; -+ struct au_sbinfo *sbi = au_sbi(inode->i_sb); -+ const struct inode_operations *iop -+ = force_getattr ? aufs_iop : sbi->si_iop_array; -+ -+ if (inode->i_op == iop) -+ return; -+ -+ switch (inode->i_mode & S_IFMT) { -+ case S_IFDIR: -+ type = AuIop_DIR; -+ break; -+ case S_IFLNK: -+ type = AuIop_SYMLINK; -+ break; -+ default: -+ type = AuIop_OTHER; -+ break; -+ } -+ -+ inode->i_op = iop + type; -+ /* unnecessary smp_wmb() */ -+} -+ -+int au_refresh_hinode_self(struct inode *inode) -+{ -+ int err, update; -+ -+ err = au_ii_refresh(inode, &update); -+ if (!err) -+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode)); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_refresh_hinode(struct inode *inode, struct dentry *dentry) -+{ -+ int err, e, update; -+ unsigned int flags; -+ umode_t mode; -+ aufs_bindex_t bindex, bbot; -+ unsigned char isdir; -+ struct au_hinode *p; -+ struct au_iinfo *iinfo; -+ -+ err = au_ii_refresh(inode, &update); -+ if (unlikely(err)) -+ goto out; -+ -+ update = 0; -+ iinfo = au_ii(inode); -+ p = au_hinode(iinfo, iinfo->ii_btop); -+ mode = (inode->i_mode & S_IFMT); -+ isdir = S_ISDIR(mode); -+ flags = au_hi_flags(inode, isdir); -+ bbot = au_dbbot(dentry); -+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) { -+ struct inode *h_i, *h_inode; -+ struct dentry *h_d; -+ -+ h_d = au_h_dptr(dentry, bindex); -+ if (!h_d || d_is_negative(h_d)) -+ continue; -+ -+ h_inode = d_inode(h_d); -+ AuDebugOn(mode != (h_inode->i_mode & S_IFMT)); -+ if (iinfo->ii_btop <= bindex && bindex <= iinfo->ii_bbot) { -+ h_i = au_h_iptr(inode, bindex); -+ if (h_i) { -+ if (h_i == h_inode) -+ continue; -+ err = -EIO; -+ break; -+ } -+ } -+ if (bindex < iinfo->ii_btop) -+ iinfo->ii_btop = bindex; -+ if (iinfo->ii_bbot < bindex) -+ iinfo->ii_bbot = bindex; -+ au_set_h_iptr(inode, bindex, au_igrab(h_inode), flags); -+ update = 1; -+ } -+ au_update_ibrange(inode, /*do_put_zero*/0); -+ e = au_dy_irefresh(inode); -+ if (unlikely(e && !err)) -+ err = e; -+ if (!err) -+ au_refresh_hinode_attr(inode, update && isdir); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int set_inode(struct inode *inode, struct dentry *dentry) -+{ -+ int err; -+ unsigned int flags; -+ umode_t mode; -+ aufs_bindex_t bindex, btop, btail; -+ unsigned char isdir; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ struct au_iinfo *iinfo; -+ struct inode_operations *iop; -+ -+ IiMustWriteLock(inode); -+ -+ err = 0; -+ isdir = 0; -+ iop = au_sbi(inode->i_sb)->si_iop_array; -+ btop = au_dbtop(dentry); -+ h_dentry = au_h_dptr(dentry, btop); -+ h_inode = d_inode(h_dentry); -+ mode = h_inode->i_mode; -+ switch (mode & S_IFMT) { -+ case S_IFREG: -+ btail = au_dbtail(dentry); -+ inode->i_op = iop + AuIop_OTHER; -+ inode->i_fop = &aufs_file_fop; -+ err = au_dy_iaop(inode, btop, h_inode); -+ if (unlikely(err)) -+ goto out; -+ break; -+ case S_IFDIR: -+ isdir = 1; -+ btail = au_dbtaildir(dentry); -+ inode->i_op = iop + AuIop_DIR; -+ inode->i_fop = &aufs_dir_fop; -+ break; -+ case S_IFLNK: -+ btail = au_dbtail(dentry); -+ inode->i_op = iop + AuIop_SYMLINK; -+ break; -+ case S_IFBLK: -+ case S_IFCHR: -+ case S_IFIFO: -+ case S_IFSOCK: -+ btail = au_dbtail(dentry); -+ inode->i_op = iop + AuIop_OTHER; -+ init_special_inode(inode, mode, h_inode->i_rdev); -+ break; -+ default: -+ AuIOErr("Unknown file type 0%o\n", mode); -+ err = -EIO; -+ goto out; -+ } -+ -+ /* do not set hnotify for whiteouted dirs (SHWH mode) */ -+ flags = au_hi_flags(inode, isdir); -+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH) -+ && au_ftest_hi(flags, HNOTIFY) -+ && dentry->d_name.len > AUFS_WH_PFX_LEN -+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) -+ au_fclr_hi(flags, HNOTIFY); -+ iinfo = au_ii(inode); -+ iinfo->ii_btop = btop; -+ iinfo->ii_bbot = btail; -+ for (bindex = btop; bindex <= btail; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry) -+ au_set_h_iptr(inode, bindex, -+ au_igrab(d_inode(h_dentry)), flags); -+ } -+ au_cpup_attr_all(inode, /*force*/1); -+ /* -+ * to force calling aufs_get_acl() every time, -+ * do not call cache_no_acl() for aufs inode. -+ */ -+ -+out: -+ return err; -+} -+ -+/* -+ * successful returns with iinfo write_locked -+ * minus: errno -+ * zero: success, matched -+ * plus: no error, but unmatched -+ */ -+static int reval_inode(struct inode *inode, struct dentry *dentry) -+{ -+ int err; -+ unsigned int gen, igflags; -+ aufs_bindex_t bindex, bbot; -+ struct inode *h_inode, *h_dinode; -+ struct dentry *h_dentry; -+ -+ /* -+ * before this function, if aufs got any iinfo lock, it must be only -+ * one, the parent dir. -+ * it can happen by UDBA and the obsoleted inode number. -+ */ -+ err = -EIO; -+ if (unlikely(inode->i_ino == parent_ino(dentry))) -+ goto out; -+ -+ err = 1; -+ ii_write_lock_new_child(inode); -+ h_dentry = au_h_dptr(dentry, au_dbtop(dentry)); -+ h_dinode = d_inode(h_dentry); -+ bbot = au_ibbot(inode); -+ for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) { -+ h_inode = au_h_iptr(inode, bindex); -+ if (!h_inode || h_inode != h_dinode) -+ continue; -+ -+ err = 0; -+ gen = au_iigen(inode, &igflags); -+ if (gen == au_digen(dentry) -+ && !au_ig_ftest(igflags, HALF_REFRESHED)) -+ break; -+ -+ /* fully refresh inode using dentry */ -+ err = au_refresh_hinode(inode, dentry); -+ if (!err) -+ au_update_iigen(inode, /*half*/0); -+ break; -+ } -+ -+ if (unlikely(err)) -+ ii_write_unlock(inode); -+out: -+ return err; -+} -+ -+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ unsigned int d_type, ino_t *ino) -+{ -+ int err, idx; -+ const int isnondir = d_type != DT_DIR; -+ -+ /* prevent hardlinked inode number from race condition */ -+ if (isnondir) { -+ err = au_xinondir_enter(sb, bindex, h_ino, &idx); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ err = au_xino_read(sb, bindex, h_ino, ino); -+ if (unlikely(err)) -+ goto out_xinondir; -+ -+ if (!*ino) { -+ err = -EIO; -+ *ino = au_xino_new_ino(sb); -+ if (unlikely(!*ino)) -+ goto out_xinondir; -+ err = au_xino_write(sb, bindex, h_ino, *ino); -+ if (unlikely(err)) -+ goto out_xinondir; -+ } -+ -+out_xinondir: -+ if (isnondir && idx >= 0) -+ au_xinondir_leave(sb, bindex, h_ino, idx); -+out: -+ return err; -+} -+ -+/* successful returns with iinfo write_locked */ -+/* todo: return with unlocked? */ -+struct inode *au_new_inode(struct dentry *dentry, int must_new) -+{ -+ struct inode *inode, *h_inode; -+ struct dentry *h_dentry; -+ struct super_block *sb; -+ ino_t h_ino, ino; -+ int err, idx, hlinked; -+ aufs_bindex_t btop; -+ -+ sb = dentry->d_sb; -+ btop = au_dbtop(dentry); -+ h_dentry = au_h_dptr(dentry, btop); -+ h_inode = d_inode(h_dentry); -+ h_ino = h_inode->i_ino; -+ hlinked = !d_is_dir(h_dentry) && h_inode->i_nlink > 1; -+ -+new_ino: -+ /* -+ * stop 'race'-ing between hardlinks under different -+ * parents. -+ */ -+ if (hlinked) { -+ err = au_xinondir_enter(sb, btop, h_ino, &idx); -+ inode = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ err = au_xino_read(sb, btop, h_ino, &ino); -+ inode = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_xinondir; -+ -+ if (!ino) { -+ ino = au_xino_new_ino(sb); -+ if (unlikely(!ino)) { -+ inode = ERR_PTR(-EIO); -+ goto out_xinondir; -+ } -+ } -+ -+ AuDbg("i%lu\n", (unsigned long)ino); -+ inode = au_iget_locked(sb, ino); -+ err = PTR_ERR(inode); -+ if (IS_ERR(inode)) -+ goto out_xinondir; -+ -+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW)); -+ if (inode->i_state & I_NEW) { -+ ii_write_lock_new_child(inode); -+ err = set_inode(inode, dentry); -+ if (!err) { -+ unlock_new_inode(inode); -+ goto out_xinondir; /* success */ -+ } -+ -+ /* -+ * iget_failed() calls iput(), but we need to call -+ * ii_write_unlock() after iget_failed(). so dirty hack for -+ * i_count. -+ */ -+ atomic_inc(&inode->i_count); -+ iget_failed(inode); -+ ii_write_unlock(inode); -+ au_xino_write(sb, btop, h_ino, /*ino*/0); -+ /* ignore this error */ -+ goto out_iput; -+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) { -+ /* -+ * horrible race condition between lookup, readdir and copyup -+ * (or something). -+ */ -+ if (hlinked && idx >= 0) -+ au_xinondir_leave(sb, btop, h_ino, idx); -+ err = reval_inode(inode, dentry); -+ if (unlikely(err < 0)) { -+ hlinked = 0; -+ goto out_iput; -+ } -+ if (!err) -+ goto out; /* success */ -+ else if (hlinked && idx >= 0) { -+ err = au_xinondir_enter(sb, btop, h_ino, &idx); -+ if (unlikely(err)) { -+ iput(inode); -+ inode = ERR_PTR(err); -+ goto out; -+ } -+ } -+ } -+ -+ if (unlikely(au_test_fs_unique_ino(h_inode))) -+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir," -+ " b%d, %s, %pd, hi%lu, i%lu.\n", -+ btop, au_sbtype(h_dentry->d_sb), dentry, -+ (unsigned long)h_ino, (unsigned long)ino); -+ ino = 0; -+ err = au_xino_write(sb, btop, h_ino, /*ino*/0); -+ if (!err) { -+ iput(inode); -+ if (hlinked && idx >= 0) -+ au_xinondir_leave(sb, btop, h_ino, idx); -+ goto new_ino; -+ } -+ -+out_iput: -+ iput(inode); -+ inode = ERR_PTR(err); -+out_xinondir: -+ if (hlinked && idx >= 0) -+ au_xinondir_leave(sb, btop, h_ino, idx); -+out: -+ return inode; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, -+ struct inode *inode) -+{ -+ int err; -+ struct inode *hi; -+ -+ err = au_br_rdonly(au_sbr(sb, bindex)); -+ -+ /* pseudo-link after flushed may happen out of bounds */ -+ if (!err -+ && inode -+ && au_ibtop(inode) <= bindex -+ && bindex <= au_ibbot(inode)) { -+ /* -+ * permission check is unnecessary since vfsub routine -+ * will be called later -+ */ -+ hi = au_h_iptr(inode, bindex); -+ if (hi) -+ err = IS_IMMUTABLE(hi) ? -EROFS : 0; -+ } -+ -+ return err; -+} -+ -+int au_test_h_perm(struct inode *h_inode, int mask) -+{ -+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) -+ return 0; -+ return inode_permission(h_inode, mask); -+} -+ -+int au_test_h_perm_sio(struct inode *h_inode, int mask) -+{ -+ if (au_test_nfs(h_inode->i_sb) -+ && (mask & MAY_WRITE) -+ && S_ISDIR(h_inode->i_mode)) -+ mask |= MAY_READ; /* force permission check */ -+ return au_test_h_perm(h_inode, mask); -+} -diff --git a/fs/aufs/inode.h b/fs/aufs/inode.h -new file mode 100644 -index 000000000..28e61b270 ---- /dev/null -+++ b/fs/aufs/inode.h -@@ -0,0 +1,696 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * inode operations -+ */ -+ -+#ifndef __AUFS_INODE_H__ -+#define __AUFS_INODE_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include "rwsem.h" -+ -+struct vfsmount; -+ -+struct au_hnotify { -+#ifdef CONFIG_AUFS_HNOTIFY -+#ifdef CONFIG_AUFS_HFSNOTIFY -+ /* never use fsnotify_add_vfsmount_mark() */ -+ struct fsnotify_mark hn_mark; -+#endif -+ struct inode *hn_aufs_inode; /* no get/put */ -+#endif -+} ____cacheline_aligned_in_smp; -+ -+struct au_hinode { -+ struct inode *hi_inode; -+ aufs_bindex_t hi_id; -+#ifdef CONFIG_AUFS_HNOTIFY -+ struct au_hnotify *hi_notify; -+#endif -+ -+ /* reference to the copied-up whiteout with get/put */ -+ struct dentry *hi_whdentry; -+}; -+ -+/* ig_flags */ -+#define AuIG_HALF_REFRESHED 1 -+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name) -+#define au_ig_fset(flags, name) \ -+ do { (flags) |= AuIG_##name; } while (0) -+#define au_ig_fclr(flags, name) \ -+ do { (flags) &= ~AuIG_##name; } while (0) -+ -+struct au_iigen { -+ spinlock_t ig_spin; -+ __u32 ig_generation, ig_flags; -+}; -+ -+struct au_vdir; -+struct au_iinfo { -+ struct au_iigen ii_generation; -+ struct super_block *ii_hsb1; /* no get/put */ -+ -+ struct au_rwsem ii_rwsem; -+ aufs_bindex_t ii_btop, ii_bbot; -+ __u32 ii_higen; -+ struct au_hinode *ii_hinode; -+ struct au_vdir *ii_vdir; -+}; -+ -+struct au_icntnr { -+ struct au_iinfo iinfo; -+ struct inode vfs_inode; -+ struct hlist_bl_node plink; -+} ____cacheline_aligned_in_smp; -+ -+/* au_pin flags */ -+#define AuPin_DI_LOCKED 1 -+#define AuPin_MNT_WRITE (1 << 1) -+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name) -+#define au_fset_pin(flags, name) \ -+ do { (flags) |= AuPin_##name; } while (0) -+#define au_fclr_pin(flags, name) \ -+ do { (flags) &= ~AuPin_##name; } while (0) -+ -+struct au_pin { -+ /* input */ -+ struct dentry *dentry; -+ unsigned int udba; -+ unsigned char lsc_di, lsc_hi, flags; -+ aufs_bindex_t bindex; -+ -+ /* output */ -+ struct dentry *parent; -+ struct au_hinode *hdir; -+ struct vfsmount *h_mnt; -+ -+ /* temporary unlock/relock for copyup */ -+ struct dentry *h_dentry, *h_parent; -+ struct au_branch *br; -+ struct task_struct *task; -+}; -+ -+void au_pin_hdir_unlock(struct au_pin *p); -+int au_pin_hdir_lock(struct au_pin *p); -+int au_pin_hdir_relock(struct au_pin *p); -+void au_pin_hdir_acquire_nest(struct au_pin *p); -+void au_pin_hdir_release(struct au_pin *p); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct au_iinfo *au_ii(struct inode *inode) -+{ -+ BUG_ON(is_bad_inode(inode)); -+ return &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* inode.c */ -+struct inode *au_igrab(struct inode *inode); -+void au_refresh_iop(struct inode *inode, int force_getattr); -+int au_refresh_hinode_self(struct inode *inode); -+int au_refresh_hinode(struct inode *inode, struct dentry *dentry); -+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ unsigned int d_type, ino_t *ino); -+struct inode *au_new_inode(struct dentry *dentry, int must_new); -+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, -+ struct inode *inode); -+int au_test_h_perm(struct inode *h_inode, int mask); -+int au_test_h_perm_sio(struct inode *h_inode, int mask); -+ -+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, -+ ino_t h_ino, unsigned int d_type, ino_t *ino) -+{ -+#ifdef CONFIG_AUFS_SHWH -+ return au_ino(sb, bindex, h_ino, d_type, ino); -+#else -+ return 0; -+#endif -+} -+ -+/* i_op.c */ -+enum { -+ AuIop_SYMLINK, -+ AuIop_DIR, -+ AuIop_OTHER, -+ AuIop_Last -+}; -+extern struct inode_operations aufs_iop[AuIop_Last], -+ aufs_iop_nogetattr[AuIop_Last]; -+ -+/* au_wr_dir flags */ -+#define AuWrDir_ADD_ENTRY 1 -+#define AuWrDir_ISDIR (1 << 1) -+#define AuWrDir_TMPFILE (1 << 2) -+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name) -+#define au_fset_wrdir(flags, name) \ -+ do { (flags) |= AuWrDir_##name; } while (0) -+#define au_fclr_wrdir(flags, name) \ -+ do { (flags) &= ~AuWrDir_##name; } while (0) -+ -+struct au_wr_dir_args { -+ aufs_bindex_t force_btgt; -+ unsigned char flags; -+}; -+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, -+ struct au_wr_dir_args *args); -+ -+struct dentry *au_pinned_h_parent(struct au_pin *pin); -+void au_pin_init(struct au_pin *pin, struct dentry *dentry, -+ aufs_bindex_t bindex, int lsc_di, int lsc_hi, -+ unsigned int udba, unsigned char flags); -+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, -+ unsigned int udba, unsigned char flags) __must_check; -+int au_do_pin(struct au_pin *pin) __must_check; -+void au_unpin(struct au_pin *pin); -+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen); -+ -+#define AuIcpup_DID_CPUP 1 -+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name) -+#define au_fset_icpup(flags, name) \ -+ do { (flags) |= AuIcpup_##name; } while (0) -+#define au_fclr_icpup(flags, name) \ -+ do { (flags) &= ~AuIcpup_##name; } while (0) -+ -+struct au_icpup_args { -+ unsigned char flags; -+ unsigned char pin_flags; -+ aufs_bindex_t btgt; -+ unsigned int udba; -+ struct au_pin pin; -+ struct path h_path; -+ struct inode *h_inode; -+}; -+ -+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia, -+ struct au_icpup_args *a); -+ -+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path, -+ int locked); -+ -+/* i_op_add.c */ -+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent, int isdir); -+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, -+ dev_t dev); -+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname); -+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode, -+ bool want_excl); -+struct vfsub_aopen_args; -+int au_aopen_or_create(struct inode *dir, struct dentry *dentry, -+ struct vfsub_aopen_args *args); -+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode); -+int aufs_link(struct dentry *src_dentry, struct inode *dir, -+ struct dentry *dentry); -+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode); -+ -+/* i_op_del.c */ -+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup); -+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent, int isdir); -+int aufs_unlink(struct inode *dir, struct dentry *dentry); -+int aufs_rmdir(struct inode *dir, struct dentry *dentry); -+ -+/* i_op_ren.c */ -+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt); -+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry, -+ struct inode *dir, struct dentry *dentry, -+ unsigned int flags); -+ -+/* iinfo.c */ -+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex); -+void au_hiput(struct au_hinode *hinode); -+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_wh); -+unsigned int au_hi_flags(struct inode *inode, int isdir); -+ -+/* hinode flags */ -+#define AuHi_XINO 1 -+#define AuHi_HNOTIFY (1 << 1) -+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name) -+#define au_fset_hi(flags, name) \ -+ do { (flags) |= AuHi_##name; } while (0) -+#define au_fclr_hi(flags, name) \ -+ do { (flags) &= ~AuHi_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_HNOTIFY -+#undef AuHi_HNOTIFY -+#define AuHi_HNOTIFY 0 -+#endif -+ -+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, -+ struct inode *h_inode, unsigned int flags); -+ -+void au_update_iigen(struct inode *inode, int half); -+void au_update_ibrange(struct inode *inode, int do_put_zero); -+ -+void au_icntnr_init_once(void *_c); -+void au_hinode_init(struct au_hinode *hinode); -+int au_iinfo_init(struct inode *inode); -+void au_iinfo_fin(struct inode *inode); -+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink); -+ -+#ifdef CONFIG_PROC_FS -+/* plink.c */ -+int au_plink_maint(struct super_block *sb, int flags); -+struct au_sbinfo; -+void au_plink_maint_leave(struct au_sbinfo *sbinfo); -+int au_plink_maint_enter(struct super_block *sb); -+#ifdef CONFIG_AUFS_DEBUG -+void au_plink_list(struct super_block *sb); -+#else -+AuStubVoid(au_plink_list, struct super_block *sb) -+#endif -+int au_plink_test(struct inode *inode); -+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex); -+void au_plink_append(struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_dentry); -+void au_plink_put(struct super_block *sb, int verbose); -+void au_plink_clean(struct super_block *sb, int verbose); -+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id); -+#else -+AuStubInt0(au_plink_maint, struct super_block *sb, int flags); -+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo); -+AuStubInt0(au_plink_maint_enter, struct super_block *sb); -+AuStubVoid(au_plink_list, struct super_block *sb); -+AuStubInt0(au_plink_test, struct inode *inode); -+AuStub(struct dentry *, au_plink_lkup, return NULL, -+ struct inode *inode, aufs_bindex_t bindex); -+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_dentry); -+AuStubVoid(au_plink_put, struct super_block *sb, int verbose); -+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose); -+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id); -+#endif /* CONFIG_PROC_FS */ -+ -+#ifdef CONFIG_AUFS_XATTR -+/* xattr.c */ -+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags, -+ unsigned int verbose); -+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size); -+void au_xattr_init(struct super_block *sb); -+#else -+AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src, -+ int ignore_flags, unsigned int verbose); -+AuStubVoid(au_xattr_init, struct super_block *sb); -+#endif -+ -+#ifdef CONFIG_FS_POSIX_ACL -+struct posix_acl *aufs_get_acl(struct inode *inode, int type); -+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type); -+#endif -+ -+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL) -+enum { -+ AU_XATTR_SET, -+ AU_ACL_SET -+}; -+ -+struct au_sxattr { -+ int type; -+ union { -+ struct { -+ const char *name; -+ const void *value; -+ size_t size; -+ int flags; -+ } set; -+ struct { -+ struct posix_acl *acl; -+ int type; -+ } acl_set; -+ } u; -+}; -+ssize_t au_sxattr(struct dentry *dentry, struct inode *inode, -+ struct au_sxattr *arg); -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* lock subclass for iinfo */ -+enum { -+ AuLsc_II_CHILD, /* child first */ -+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */ -+ AuLsc_II_CHILD3, /* copyup dirs */ -+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */ -+ AuLsc_II_PARENT2, -+ AuLsc_II_PARENT3, /* copyup dirs */ -+ AuLsc_II_NEW_CHILD -+}; -+ -+/* -+ * ii_read_lock_child, ii_write_lock_child, -+ * ii_read_lock_child2, ii_write_lock_child2, -+ * ii_read_lock_child3, ii_write_lock_child3, -+ * ii_read_lock_parent, ii_write_lock_parent, -+ * ii_read_lock_parent2, ii_write_lock_parent2, -+ * ii_read_lock_parent3, ii_write_lock_parent3, -+ * ii_read_lock_new_child, ii_write_lock_new_child, -+ */ -+#define AuReadLockFunc(name, lsc) \ -+static inline void ii_read_lock_##name(struct inode *i) \ -+{ \ -+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ -+} -+ -+#define AuWriteLockFunc(name, lsc) \ -+static inline void ii_write_lock_##name(struct inode *i) \ -+{ \ -+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ -+} -+ -+#define AuRWLockFuncs(name, lsc) \ -+ AuReadLockFunc(name, lsc) \ -+ AuWriteLockFunc(name, lsc) -+ -+AuRWLockFuncs(child, CHILD); -+AuRWLockFuncs(child2, CHILD2); -+AuRWLockFuncs(child3, CHILD3); -+AuRWLockFuncs(parent, PARENT); -+AuRWLockFuncs(parent2, PARENT2); -+AuRWLockFuncs(parent3, PARENT3); -+AuRWLockFuncs(new_child, NEW_CHILD); -+ -+#undef AuReadLockFunc -+#undef AuWriteLockFunc -+#undef AuRWLockFuncs -+ -+#define ii_read_unlock(i) au_rw_read_unlock(&au_ii(i)->ii_rwsem) -+#define ii_write_unlock(i) au_rw_write_unlock(&au_ii(i)->ii_rwsem) -+#define ii_downgrade_lock(i) au_rw_dgrade_lock(&au_ii(i)->ii_rwsem) -+ -+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem) -+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem) -+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem) -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline void au_icntnr_init(struct au_icntnr *c) -+{ -+#ifdef CONFIG_AUFS_DEBUG -+ c->vfs_inode.i_mode = 0; -+#endif -+} -+ -+static inline unsigned int au_iigen(struct inode *inode, unsigned int *igflags) -+{ -+ unsigned int gen; -+ struct au_iinfo *iinfo; -+ struct au_iigen *iigen; -+ -+ iinfo = au_ii(inode); -+ iigen = &iinfo->ii_generation; -+ spin_lock(&iigen->ig_spin); -+ if (igflags) -+ *igflags = iigen->ig_flags; -+ gen = iigen->ig_generation; -+ spin_unlock(&iigen->ig_spin); -+ -+ return gen; -+} -+ -+/* tiny test for inode number */ -+/* tmpfs generation is too rough */ -+static inline int au_test_higen(struct inode *inode, struct inode *h_inode) -+{ -+ struct au_iinfo *iinfo; -+ -+ iinfo = au_ii(inode); -+ AuRwMustAnyLock(&iinfo->ii_rwsem); -+ return !(iinfo->ii_hsb1 == h_inode->i_sb -+ && iinfo->ii_higen == h_inode->i_generation); -+} -+ -+static inline void au_iigen_dec(struct inode *inode) -+{ -+ struct au_iinfo *iinfo; -+ struct au_iigen *iigen; -+ -+ iinfo = au_ii(inode); -+ iigen = &iinfo->ii_generation; -+ spin_lock(&iigen->ig_spin); -+ iigen->ig_generation--; -+ spin_unlock(&iigen->ig_spin); -+} -+ -+static inline int au_iigen_test(struct inode *inode, unsigned int sigen) -+{ -+ int err; -+ -+ err = 0; -+ if (unlikely(inode && au_iigen(inode, NULL) != sigen)) -+ err = -EIO; -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct au_hinode *au_hinode(struct au_iinfo *iinfo, -+ aufs_bindex_t bindex) -+{ -+ return iinfo->ii_hinode + bindex; -+} -+ -+static inline int au_is_bad_inode(struct inode *inode) -+{ -+ return !!(is_bad_inode(inode) || !au_hinode(au_ii(inode), 0)); -+} -+ -+static inline aufs_bindex_t au_ii_br_id(struct inode *inode, -+ aufs_bindex_t bindex) -+{ -+ IiMustAnyLock(inode); -+ return au_hinode(au_ii(inode), bindex)->hi_id; -+} -+ -+static inline aufs_bindex_t au_ibtop(struct inode *inode) -+{ -+ IiMustAnyLock(inode); -+ return au_ii(inode)->ii_btop; -+} -+ -+static inline aufs_bindex_t au_ibbot(struct inode *inode) -+{ -+ IiMustAnyLock(inode); -+ return au_ii(inode)->ii_bbot; -+} -+ -+static inline struct au_vdir *au_ivdir(struct inode *inode) -+{ -+ IiMustAnyLock(inode); -+ return au_ii(inode)->ii_vdir; -+} -+ -+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex) -+{ -+ IiMustAnyLock(inode); -+ return au_hinode(au_ii(inode), bindex)->hi_whdentry; -+} -+ -+static inline void au_set_ibtop(struct inode *inode, aufs_bindex_t bindex) -+{ -+ IiMustWriteLock(inode); -+ au_ii(inode)->ii_btop = bindex; -+} -+ -+static inline void au_set_ibbot(struct inode *inode, aufs_bindex_t bindex) -+{ -+ IiMustWriteLock(inode); -+ au_ii(inode)->ii_bbot = bindex; -+} -+ -+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir) -+{ -+ IiMustWriteLock(inode); -+ au_ii(inode)->ii_vdir = vdir; -+} -+ -+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex) -+{ -+ IiMustAnyLock(inode); -+ return au_hinode(au_ii(inode), bindex); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct dentry *au_pinned_parent(struct au_pin *pin) -+{ -+ if (pin) -+ return pin->parent; -+ return NULL; -+} -+ -+static inline struct inode *au_pinned_h_dir(struct au_pin *pin) -+{ -+ if (pin && pin->hdir) -+ return pin->hdir->hi_inode; -+ return NULL; -+} -+ -+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin) -+{ -+ if (pin) -+ return pin->hdir; -+ return NULL; -+} -+ -+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry) -+{ -+ if (pin) -+ pin->dentry = dentry; -+} -+ -+static inline void au_pin_set_parent_lflag(struct au_pin *pin, -+ unsigned char lflag) -+{ -+ if (pin) { -+ if (lflag) -+ au_fset_pin(pin->flags, DI_LOCKED); -+ else -+ au_fclr_pin(pin->flags, DI_LOCKED); -+ } -+} -+ -+#if 0 /* reserved */ -+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent) -+{ -+ if (pin) { -+ dput(pin->parent); -+ pin->parent = dget(parent); -+ } -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_branch; -+#ifdef CONFIG_AUFS_HNOTIFY -+struct au_hnotify_op { -+ void (*ctl)(struct au_hinode *hinode, int do_set); -+ int (*alloc)(struct au_hinode *hinode); -+ -+ /* -+ * if it returns true, the the caller should free hinode->hi_notify, -+ * otherwise ->free() frees it. -+ */ -+ int (*free)(struct au_hinode *hinode, -+ struct au_hnotify *hn) __must_check; -+ -+ void (*fin)(void); -+ int (*init)(void); -+ -+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm); -+ void (*fin_br)(struct au_branch *br); -+ int (*init_br)(struct au_branch *br, int perm); -+}; -+ -+/* hnotify.c */ -+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode); -+void au_hn_free(struct au_hinode *hinode); -+void au_hn_ctl(struct au_hinode *hinode, int do_set); -+void au_hn_reset(struct inode *inode, unsigned int flags); -+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask, -+ struct qstr *h_child_qstr, struct inode *h_child_inode); -+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm); -+int au_hnotify_init_br(struct au_branch *br, int perm); -+void au_hnotify_fin_br(struct au_branch *br); -+int __init au_hnotify_init(void); -+void au_hnotify_fin(void); -+ -+/* hfsnotify.c */ -+extern const struct au_hnotify_op au_hnotify_op; -+ -+static inline -+void au_hn_init(struct au_hinode *hinode) -+{ -+ hinode->hi_notify = NULL; -+} -+ -+static inline struct au_hnotify *au_hn(struct au_hinode *hinode) -+{ -+ return hinode->hi_notify; -+} -+ -+#else -+AuStub(int, au_hn_alloc, return -EOPNOTSUPP, -+ struct au_hinode *hinode __maybe_unused, -+ struct inode *inode __maybe_unused) -+AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode) -+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused) -+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused, -+ int do_set __maybe_unused) -+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused, -+ unsigned int flags __maybe_unused) -+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused, -+ struct au_branch *br __maybe_unused, -+ int perm __maybe_unused) -+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused, -+ int perm __maybe_unused) -+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused) -+AuStubInt0(__init au_hnotify_init, void) -+AuStubVoid(au_hnotify_fin, void) -+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused) -+#endif /* CONFIG_AUFS_HNOTIFY */ -+ -+static inline void au_hn_suspend(struct au_hinode *hdir) -+{ -+ au_hn_ctl(hdir, /*do_set*/0); -+} -+ -+static inline void au_hn_resume(struct au_hinode *hdir) -+{ -+ au_hn_ctl(hdir, /*do_set*/1); -+} -+ -+static inline void au_hn_inode_lock(struct au_hinode *hdir) -+{ -+ inode_lock(hdir->hi_inode); -+ au_hn_suspend(hdir); -+} -+ -+static inline void au_hn_inode_lock_nested(struct au_hinode *hdir, -+ unsigned int sc __maybe_unused) -+{ -+ inode_lock_nested(hdir->hi_inode, sc); -+ au_hn_suspend(hdir); -+} -+ -+#if 0 /* unused */ -+#include "vfsub.h" -+static inline void au_hn_inode_lock_shared_nested(struct au_hinode *hdir, -+ unsigned int sc) -+{ -+ inode_lock_shared_nested(hdir->hi_inode, sc); -+ au_hn_suspend(hdir); -+} -+#endif -+ -+static inline void au_hn_inode_unlock(struct au_hinode *hdir) -+{ -+ au_hn_resume(hdir); -+ inode_unlock(hdir->hi_inode); -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_INODE_H__ */ -diff --git a/fs/aufs/ioctl.c b/fs/aufs/ioctl.c -new file mode 100644 -index 000000000..279bd7498 ---- /dev/null -+++ b/fs/aufs/ioctl.c -@@ -0,0 +1,220 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * ioctl -+ * plink-management and readdir in userspace. -+ * assist the pathconf(3) wrapper library. -+ * move-down -+ * File-based Hierarchical Storage Management. -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg) -+{ -+ int err, fd; -+ aufs_bindex_t wbi, bindex, bbot; -+ struct file *h_file; -+ struct super_block *sb; -+ struct dentry *root; -+ struct au_branch *br; -+ struct aufs_wbr_fd wbrfd = { -+ .oflags = au_dir_roflags, -+ .brid = -1 -+ }; -+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY -+ | O_NOATIME | O_CLOEXEC; -+ -+ AuDebugOn(wbrfd.oflags & ~valid); -+ -+ if (arg) { -+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ goto out; -+ } -+ -+ err = -EINVAL; -+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid); -+ wbrfd.oflags |= au_dir_roflags; -+ AuDbg("0%o\n", wbrfd.oflags); -+ if (unlikely(wbrfd.oflags & ~valid)) -+ goto out; -+ } -+ -+ fd = get_unused_fd_flags(0); -+ err = fd; -+ if (unlikely(fd < 0)) -+ goto out; -+ -+ h_file = ERR_PTR(-EINVAL); -+ wbi = 0; -+ br = NULL; -+ sb = path->dentry->d_sb; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_IR); -+ bbot = au_sbbot(sb); -+ if (wbrfd.brid >= 0) { -+ wbi = au_br_index(sb, wbrfd.brid); -+ if (unlikely(wbi < 0 || wbi > bbot)) -+ goto out_unlock; -+ } -+ -+ h_file = ERR_PTR(-ENOENT); -+ br = au_sbr(sb, wbi); -+ if (!au_br_writable(br->br_perm)) { -+ if (arg) -+ goto out_unlock; -+ -+ bindex = wbi + 1; -+ wbi = -1; -+ for (; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_writable(br->br_perm)) { -+ wbi = bindex; -+ br = au_sbr(sb, wbi); -+ break; -+ } -+ } -+ } -+ AuDbg("wbi %d\n", wbi); -+ if (wbi >= 0) -+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL, -+ /*force_wr*/0); -+ -+out_unlock: -+ aufs_read_unlock(root, AuLock_IR); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out_fd; -+ -+ au_lcnt_dec(&br->br_nfiles); /* cf. au_h_open() */ -+ fd_install(fd, h_file); -+ err = fd; -+ goto out; /* success */ -+ -+out_fd: -+ put_unused_fd(fd); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long err; -+ struct dentry *dentry; -+ -+ switch (cmd) { -+ case AUFS_CTL_RDU: -+ case AUFS_CTL_RDU_INO: -+ err = au_rdu_ioctl(file, cmd, arg); -+ break; -+ -+ case AUFS_CTL_WBR_FD: -+ err = au_wbr_fd(&file->f_path, (void __user *)arg); -+ break; -+ -+ case AUFS_CTL_IBUSY: -+ err = au_ibusy_ioctl(file, arg); -+ break; -+ -+ case AUFS_CTL_BRINFO: -+ err = au_brinfo_ioctl(file, arg); -+ break; -+ -+ case AUFS_CTL_FHSM_FD: -+ dentry = file->f_path.dentry; -+ if (IS_ROOT(dentry)) -+ err = au_fhsm_fd(dentry->d_sb, arg); -+ else -+ err = -ENOTTY; -+ break; -+ -+ default: -+ /* do not call the lower */ -+ AuDbg("0x%x\n", cmd); -+ err = -ENOTTY; -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long err; -+ -+ switch (cmd) { -+ case AUFS_CTL_MVDOWN: -+ err = au_mvdown(file->f_path.dentry, (void __user *)arg); -+ break; -+ -+ case AUFS_CTL_WBR_FD: -+ err = au_wbr_fd(&file->f_path, (void __user *)arg); -+ break; -+ -+ default: -+ /* do not call the lower */ -+ AuDbg("0x%x\n", cmd); -+ err = -ENOTTY; -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+#ifdef CONFIG_COMPAT -+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ long err; -+ -+ switch (cmd) { -+ case AUFS_CTL_RDU: -+ case AUFS_CTL_RDU_INO: -+ err = au_rdu_compat_ioctl(file, cmd, arg); -+ break; -+ -+ case AUFS_CTL_IBUSY: -+ err = au_ibusy_compat_ioctl(file, arg); -+ break; -+ -+ case AUFS_CTL_BRINFO: -+ err = au_brinfo_compat_ioctl(file, arg); -+ break; -+ -+ default: -+ err = aufs_ioctl_dir(file, cmd, arg); -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg)); -+} -+#endif -diff --git a/fs/aufs/lcnt.h b/fs/aufs/lcnt.h -new file mode 100644 -index 000000000..5e089c93f ---- /dev/null -+++ b/fs/aufs/lcnt.h -@@ -0,0 +1,186 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * simple long counter wrapper -+ */ -+ -+#ifndef __AUFS_LCNT_H__ -+#define __AUFS_LCNT_H__ -+ -+#ifdef __KERNEL__ -+ -+#include "debug.h" -+ -+#define AuLCntATOMIC 1 -+#define AuLCntPCPUCNT 2 -+/* -+ * why does percpu_refcount require extra synchronize_rcu()s in -+ * au_br_do_free() -+ */ -+#define AuLCntPCPUREF 3 -+ -+/* #define AuLCntChosen AuLCntATOMIC */ -+#define AuLCntChosen AuLCntPCPUCNT -+/* #define AuLCntChosen AuLCntPCPUREF */ -+ -+#if AuLCntChosen == AuLCntATOMIC -+#include -+ -+typedef atomic_long_t au_lcnt_t; -+ -+static inline int au_lcnt_init(au_lcnt_t *cnt, void *release __maybe_unused) -+{ -+ atomic_long_set(cnt, 0); -+ return 0; -+} -+ -+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused) -+{ -+ /* empty */ -+} -+ -+static inline void au_lcnt_fin(au_lcnt_t *cnt __maybe_unused, -+ int do_sync __maybe_unused) -+{ -+ /* empty */ -+} -+ -+static inline void au_lcnt_inc(au_lcnt_t *cnt) -+{ -+ atomic_long_inc(cnt); -+} -+ -+static inline void au_lcnt_dec(au_lcnt_t *cnt) -+{ -+ atomic_long_dec(cnt); -+} -+ -+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev __maybe_unused) -+{ -+ return atomic_long_read(cnt); -+} -+#endif -+ -+#if AuLCntChosen == AuLCntPCPUCNT -+#include -+ -+typedef struct percpu_counter au_lcnt_t; -+ -+static inline int au_lcnt_init(au_lcnt_t *cnt, void *release __maybe_unused) -+{ -+ return percpu_counter_init(cnt, 0, GFP_NOFS); -+} -+ -+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused) -+{ -+ /* empty */ -+} -+ -+static inline void au_lcnt_fin(au_lcnt_t *cnt, int do_sync __maybe_unused) -+{ -+ percpu_counter_destroy(cnt); -+} -+ -+static inline void au_lcnt_inc(au_lcnt_t *cnt) -+{ -+ percpu_counter_inc(cnt); -+} -+ -+static inline void au_lcnt_dec(au_lcnt_t *cnt) -+{ -+ percpu_counter_dec(cnt); -+} -+ -+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev __maybe_unused) -+{ -+ s64 n; -+ -+ n = percpu_counter_sum(cnt); -+ BUG_ON(n < 0); -+ if (LONG_MAX != LLONG_MAX -+ && n > LONG_MAX) -+ AuWarn1("%s\n", "wrap-around"); -+ -+ return n; -+} -+#endif -+ -+#if AuLCntChosen == AuLCntPCPUREF -+#include -+ -+typedef struct percpu_ref au_lcnt_t; -+ -+static inline int au_lcnt_init(au_lcnt_t *cnt, percpu_ref_func_t *release) -+{ -+ if (!release) -+ release = percpu_ref_exit; -+ return percpu_ref_init(cnt, release, /*percpu mode*/0, GFP_NOFS); -+} -+ -+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused) -+{ -+ synchronize_rcu(); -+} -+ -+static inline void au_lcnt_fin(au_lcnt_t *cnt, int do_sync) -+{ -+ percpu_ref_kill(cnt); -+ if (do_sync) -+ au_lcnt_wait_for_fin(cnt); -+} -+ -+static inline void au_lcnt_inc(au_lcnt_t *cnt) -+{ -+ percpu_ref_get(cnt); -+} -+ -+static inline void au_lcnt_dec(au_lcnt_t *cnt) -+{ -+ percpu_ref_put(cnt); -+} -+ -+/* -+ * avoid calling this func as possible. -+ */ -+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev) -+{ -+ long l; -+ -+ percpu_ref_switch_to_atomic_sync(cnt); -+ l = atomic_long_read(&cnt->count); -+ if (do_rev) -+ percpu_ref_switch_to_percpu(cnt); -+ -+ /* percpu_ref is initialized by 1 instead of 0 */ -+ return l - 1; -+} -+#endif -+ -+#ifdef CONFIG_AUFS_DEBUG -+#define AuLCntZero(val) do { \ -+ long l = val; \ -+ if (l) \ -+ AuDbg("%s = %ld\n", #val, l); \ -+} while (0) -+#else -+#define AuLCntZero(val) do {} while (0) -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_LCNT_H__ */ -diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c -new file mode 100644 -index 000000000..0c6af623a ---- /dev/null -+++ b/fs/aufs/loop.c -@@ -0,0 +1,148 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * support for loopback block device as a branch -+ */ -+ -+#include "aufs.h" -+ -+/* added into drivers/block/loop.c */ -+static struct file *(*backing_file_func)(struct super_block *sb); -+ -+/* -+ * test if two lower dentries have overlapping branches. -+ */ -+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding) -+{ -+ struct super_block *h_sb; -+ struct file *backing_file; -+ -+ if (unlikely(!backing_file_func)) { -+ /* don't load "loop" module here */ -+ backing_file_func = symbol_get(loop_backing_file); -+ if (unlikely(!backing_file_func)) -+ /* "loop" module is not loaded */ -+ return 0; -+ } -+ -+ h_sb = h_adding->d_sb; -+ backing_file = backing_file_func(h_sb); -+ if (!backing_file) -+ return 0; -+ -+ h_adding = backing_file->f_path.dentry; -+ /* -+ * h_adding can be local NFS. -+ * in this case aufs cannot detect the loop. -+ */ -+ if (unlikely(h_adding->d_sb == sb)) -+ return 1; -+ return !!au_test_subdir(h_adding, sb->s_root); -+} -+ -+/* true if a kernel thread named 'loop[0-9].*' accesses a file */ -+int au_test_loopback_kthread(void) -+{ -+ int ret; -+ struct task_struct *tsk = current; -+ char c, comm[sizeof(tsk->comm)]; -+ -+ ret = 0; -+ if (tsk->flags & PF_KTHREAD) { -+ get_task_comm(comm, tsk); -+ c = comm[4]; -+ ret = ('0' <= c && c <= '9' -+ && !strncmp(comm, "loop", 4)); -+ } -+ -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define au_warn_loopback_step 16 -+static int au_warn_loopback_nelem = au_warn_loopback_step; -+static unsigned long *au_warn_loopback_array; -+ -+void au_warn_loopback(struct super_block *h_sb) -+{ -+ int i, new_nelem; -+ unsigned long *a, magic; -+ static DEFINE_SPINLOCK(spin); -+ -+ magic = h_sb->s_magic; -+ spin_lock(&spin); -+ a = au_warn_loopback_array; -+ for (i = 0; i < au_warn_loopback_nelem && *a; i++) -+ if (a[i] == magic) { -+ spin_unlock(&spin); -+ return; -+ } -+ -+ /* h_sb is new to us, print it */ -+ if (i < au_warn_loopback_nelem) { -+ a[i] = magic; -+ goto pr; -+ } -+ -+ /* expand the array */ -+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step; -+ a = au_kzrealloc(au_warn_loopback_array, -+ au_warn_loopback_nelem * sizeof(unsigned long), -+ new_nelem * sizeof(unsigned long), GFP_ATOMIC, -+ /*may_shrink*/0); -+ if (a) { -+ au_warn_loopback_nelem = new_nelem; -+ au_warn_loopback_array = a; -+ a[i] = magic; -+ goto pr; -+ } -+ -+ spin_unlock(&spin); -+ AuWarn1("realloc failed, ignored\n"); -+ return; -+ -+pr: -+ spin_unlock(&spin); -+ pr_warn("you may want to try another patch for loopback file " -+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic); -+} -+ -+int au_loopback_init(void) -+{ -+ int err; -+ struct super_block *sb __maybe_unused; -+ -+ BUILD_BUG_ON(sizeof(sb->s_magic) != sizeof(unsigned long)); -+ -+ err = 0; -+ au_warn_loopback_array = kcalloc(au_warn_loopback_step, -+ sizeof(unsigned long), GFP_NOFS); -+ if (unlikely(!au_warn_loopback_array)) -+ err = -ENOMEM; -+ -+ return err; -+} -+ -+void au_loopback_fin(void) -+{ -+ if (backing_file_func) -+ symbol_put(loop_backing_file); -+ kfree(au_warn_loopback_array); -+} -diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h -new file mode 100644 -index 000000000..048a6504f ---- /dev/null -+++ b/fs/aufs/loop.h -@@ -0,0 +1,53 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * support for loopback mount as a branch -+ */ -+ -+#ifndef __AUFS_LOOP_H__ -+#define __AUFS_LOOP_H__ -+ -+#ifdef __KERNEL__ -+ -+struct dentry; -+struct super_block; -+ -+#ifdef CONFIG_AUFS_BDEV_LOOP -+/* drivers/block/loop.c */ -+struct file *loop_backing_file(struct super_block *sb); -+ -+/* loop.c */ -+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding); -+int au_test_loopback_kthread(void); -+void au_warn_loopback(struct super_block *h_sb); -+ -+int au_loopback_init(void); -+void au_loopback_fin(void); -+#else -+AuStubInt0(au_test_loopback_overlap, struct super_block *sb, -+ struct dentry *h_adding) -+AuStubInt0(au_test_loopback_kthread, void) -+AuStubVoid(au_warn_loopback, struct super_block *h_sb) -+ -+AuStubInt0(au_loopback_init, void) -+AuStubVoid(au_loopback_fin, void) -+#endif /* BLK_DEV_LOOP */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_LOOP_H__ */ -diff --git a/fs/aufs/magic.mk b/fs/aufs/magic.mk -new file mode 100644 -index 000000000..7bc9eef3f ---- /dev/null -+++ b/fs/aufs/magic.mk -@@ -0,0 +1,31 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+# defined in ${srctree}/fs/fuse/inode.c -+# tristate -+ifdef CONFIG_FUSE_FS -+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546 -+endif -+ -+# defined in ${srctree}/fs/xfs/xfs_sb.h -+# tristate -+ifdef CONFIG_XFS_FS -+ccflags-y += -DXFS_SB_MAGIC=0x58465342 -+endif -+ -+# defined in ${srctree}/fs/configfs/mount.c -+# tristate -+ifdef CONFIG_CONFIGFS_FS -+ccflags-y += -DCONFIGFS_MAGIC=0x62656570 -+endif -+ -+# defined in ${srctree}/fs/ubifs/ubifs.h -+# tristate -+ifdef CONFIG_UBIFS_FS -+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905 -+endif -+ -+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h -+# tristate -+ifdef CONFIG_HFSPLUS_FS -+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b -+endif -diff --git a/fs/aufs/module.c b/fs/aufs/module.c -new file mode 100644 -index 000000000..5f5f67e64 ---- /dev/null -+++ b/fs/aufs/module.c -@@ -0,0 +1,273 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * module global variables and operations -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+/* shrinkable realloc */ -+void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink) -+{ -+ size_t sz; -+ int diff; -+ -+ sz = 0; -+ diff = -1; -+ if (p) { -+#if 0 /* unused */ -+ if (!new_sz) { -+ kfree(p); -+ p = NULL; -+ goto out; -+ } -+#else -+ AuDebugOn(!new_sz); -+#endif -+ sz = ksize(p); -+ diff = au_kmidx_sub(sz, new_sz); -+ } -+ if (sz && !diff) -+ goto out; -+ -+ if (sz < new_sz) -+ /* expand or SLOB */ -+ p = krealloc(p, new_sz, gfp); -+ else if (new_sz < sz && may_shrink) { -+ /* shrink */ -+ void *q; -+ -+ q = kmalloc(new_sz, gfp); -+ if (q) { -+ if (p) { -+ memcpy(q, p, new_sz); -+ kfree(p); -+ } -+ p = q; -+ } else -+ p = NULL; -+ } -+ -+out: -+ return p; -+} -+ -+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp, -+ int may_shrink) -+{ -+ p = au_krealloc(p, new_sz, gfp, may_shrink); -+ if (p && new_sz > nused) -+ memset(p + nused, 0, new_sz - nused); -+ return p; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * aufs caches -+ */ -+struct kmem_cache *au_cache[AuCache_Last]; -+ -+static void au_cache_fin(void) -+{ -+ int i; -+ -+ /* -+ * Make sure all delayed rcu free inodes are flushed before we -+ * destroy cache. -+ */ -+ rcu_barrier(); -+ -+ /* excluding AuCache_HNOTIFY */ -+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last); -+ for (i = 0; i < AuCache_HNOTIFY; i++) { -+ kmem_cache_destroy(au_cache[i]); -+ au_cache[i] = NULL; -+ } -+} -+ -+static int __init au_cache_init(void) -+{ -+ au_cache[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once); -+ if (au_cache[AuCache_DINFO]) -+ /* SLAB_DESTROY_BY_RCU */ -+ au_cache[AuCache_ICNTNR] = AuCacheCtor(au_icntnr, -+ au_icntnr_init_once); -+ if (au_cache[AuCache_ICNTNR]) -+ au_cache[AuCache_FINFO] = AuCacheCtor(au_finfo, -+ au_fi_init_once); -+ if (au_cache[AuCache_FINFO]) -+ au_cache[AuCache_VDIR] = AuCache(au_vdir); -+ if (au_cache[AuCache_VDIR]) -+ au_cache[AuCache_DEHSTR] = AuCache(au_vdir_dehstr); -+ if (au_cache[AuCache_DEHSTR]) -+ return 0; -+ -+ au_cache_fin(); -+ return -ENOMEM; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_dir_roflags; -+ -+#ifdef CONFIG_AUFS_SBILIST -+/* -+ * iterate_supers_type() doesn't protect us from -+ * remounting (branch management) -+ */ -+struct hlist_bl_head au_sbilist; -+#endif -+ -+/* -+ * functions for module interface. -+ */ -+MODULE_LICENSE("GPL"); -+/* MODULE_LICENSE("GPL v2"); */ -+MODULE_AUTHOR("Junjiro R. Okajima "); -+MODULE_DESCRIPTION(AUFS_NAME -+ " -- Advanced multi layered unification filesystem"); -+MODULE_VERSION(AUFS_VERSION); -+MODULE_ALIAS_FS(AUFS_NAME); -+ -+/* this module parameter has no meaning when SYSFS is disabled */ -+int sysaufs_brs = 1; -+MODULE_PARM_DESC(brs, "use /fs/aufs/si_*/brN"); -+module_param_named(brs, sysaufs_brs, int, 0444); -+ -+/* this module parameter has no meaning when USER_NS is disabled */ -+bool au_userns; -+MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns"); -+module_param_named(allow_userns, au_userns, bool, 0444); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */ -+ -+int au_seq_path(struct seq_file *seq, struct path *path) -+{ -+ int err; -+ -+ err = seq_path(seq, path, au_esc_chars); -+ if (err >= 0) -+ err = 0; -+ else -+ err = -ENOMEM; -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int __init aufs_init(void) -+{ -+ int err, i; -+ char *p; -+ -+ p = au_esc_chars; -+ for (i = 1; i <= ' '; i++) -+ *p++ = i; -+ *p++ = '\\'; -+ *p++ = '\x7f'; -+ *p = 0; -+ -+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE); -+ -+ memcpy(aufs_iop_nogetattr, aufs_iop, sizeof(aufs_iop)); -+ for (i = 0; i < AuIop_Last; i++) -+ aufs_iop_nogetattr[i].getattr = NULL; -+ -+ memset(au_cache, 0, sizeof(au_cache)); /* including hnotify */ -+ -+ au_sbilist_init(); -+ sysaufs_brs_init(); -+ au_debug_init(); -+ au_dy_init(); -+ err = sysaufs_init(); -+ if (unlikely(err)) -+ goto out; -+ err = dbgaufs_init(); -+ if (unlikely(err)) -+ goto out_sysaufs; -+ err = au_procfs_init(); -+ if (unlikely(err)) -+ goto out_dbgaufs; -+ err = au_wkq_init(); -+ if (unlikely(err)) -+ goto out_procfs; -+ err = au_loopback_init(); -+ if (unlikely(err)) -+ goto out_wkq; -+ err = au_hnotify_init(); -+ if (unlikely(err)) -+ goto out_loopback; -+ err = au_sysrq_init(); -+ if (unlikely(err)) -+ goto out_hin; -+ err = au_cache_init(); -+ if (unlikely(err)) -+ goto out_sysrq; -+ -+ aufs_fs_type.fs_flags |= au_userns ? FS_USERNS_MOUNT : 0; -+ err = register_filesystem(&aufs_fs_type); -+ if (unlikely(err)) -+ goto out_cache; -+ -+ /* since we define pr_fmt, call printk directly */ -+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n"); -+ goto out; /* success */ -+ -+out_cache: -+ au_cache_fin(); -+out_sysrq: -+ au_sysrq_fin(); -+out_hin: -+ au_hnotify_fin(); -+out_loopback: -+ au_loopback_fin(); -+out_wkq: -+ au_wkq_fin(); -+out_procfs: -+ au_procfs_fin(); -+out_dbgaufs: -+ dbgaufs_fin(); -+out_sysaufs: -+ sysaufs_fin(); -+ au_dy_fin(); -+out: -+ return err; -+} -+ -+static void __exit aufs_exit(void) -+{ -+ unregister_filesystem(&aufs_fs_type); -+ au_cache_fin(); -+ au_sysrq_fin(); -+ au_hnotify_fin(); -+ au_loopback_fin(); -+ au_wkq_fin(); -+ au_procfs_fin(); -+ dbgaufs_fin(); -+ sysaufs_fin(); -+ au_dy_fin(); -+} -+ -+module_init(aufs_init); -+module_exit(aufs_exit); -diff --git a/fs/aufs/module.h b/fs/aufs/module.h -new file mode 100644 -index 000000000..000761049 ---- /dev/null -+++ b/fs/aufs/module.h -@@ -0,0 +1,102 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * module initialization and module-global -+ */ -+ -+#ifndef __AUFS_MODULE_H__ -+#define __AUFS_MODULE_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+struct path; -+struct seq_file; -+ -+/* module parameters */ -+extern int sysaufs_brs; -+extern bool au_userns; -+ -+/* ---------------------------------------------------------------------- */ -+ -+extern int au_dir_roflags; -+ -+void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink); -+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp, -+ int may_shrink); -+ -+static inline int au_kmidx_sub(size_t sz, size_t new_sz) -+{ -+#ifndef CONFIG_SLOB -+ return kmalloc_index(sz) - kmalloc_index(new_sz); -+#else -+ return -1; /* SLOB is untested */ -+#endif -+} -+ -+int au_seq_path(struct seq_file *seq, struct path *path); -+ -+#ifdef CONFIG_PROC_FS -+/* procfs.c */ -+int __init au_procfs_init(void); -+void au_procfs_fin(void); -+#else -+AuStubInt0(au_procfs_init, void); -+AuStubVoid(au_procfs_fin, void); -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* kmem cache */ -+enum { -+ AuCache_DINFO, -+ AuCache_ICNTNR, -+ AuCache_FINFO, -+ AuCache_VDIR, -+ AuCache_DEHSTR, -+ AuCache_HNOTIFY, /* must be last */ -+ AuCache_Last -+}; -+ -+extern struct kmem_cache *au_cache[AuCache_Last]; -+ -+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD) -+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags) -+#define AuCacheCtor(type, ctor) \ -+ kmem_cache_create(#type, sizeof(struct type), \ -+ __alignof__(struct type), AuCacheFlags, ctor) -+ -+#define AuCacheFuncs(name, index) \ -+static inline struct au_##name *au_cache_alloc_##name(void) \ -+{ return kmem_cache_alloc(au_cache[AuCache_##index], GFP_NOFS); } \ -+static inline void au_cache_free_##name(struct au_##name *p) \ -+{ kmem_cache_free(au_cache[AuCache_##index], p); } -+ -+AuCacheFuncs(dinfo, DINFO); -+AuCacheFuncs(icntnr, ICNTNR); -+AuCacheFuncs(finfo, FINFO); -+AuCacheFuncs(vdir, VDIR); -+AuCacheFuncs(vdir_dehstr, DEHSTR); -+#ifdef CONFIG_AUFS_HNOTIFY -+AuCacheFuncs(hnotify, HNOTIFY); -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_MODULE_H__ */ -diff --git a/fs/aufs/mvdown.c b/fs/aufs/mvdown.c -new file mode 100644 -index 000000000..9603ef739 ---- /dev/null -+++ b/fs/aufs/mvdown.c -@@ -0,0 +1,705 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2011-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * move-down, opposite of copy-up -+ */ -+ -+#include "aufs.h" -+ -+struct au_mvd_args { -+ struct { -+ struct super_block *h_sb; -+ struct dentry *h_parent; -+ struct au_hinode *hdir; -+ struct inode *h_dir, *h_inode; -+ struct au_pin pin; -+ } info[AUFS_MVDOWN_NARRAY]; -+ -+ struct aufs_mvdown mvdown; -+ struct dentry *dentry, *parent; -+ struct inode *inode, *dir; -+ struct super_block *sb; -+ aufs_bindex_t bopq, bwh, bfound; -+ unsigned char rename_lock; -+}; -+ -+#define mvd_errno mvdown.au_errno -+#define mvd_bsrc mvdown.stbr[AUFS_MVDOWN_UPPER].bindex -+#define mvd_src_brid mvdown.stbr[AUFS_MVDOWN_UPPER].brid -+#define mvd_bdst mvdown.stbr[AUFS_MVDOWN_LOWER].bindex -+#define mvd_dst_brid mvdown.stbr[AUFS_MVDOWN_LOWER].brid -+ -+#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb -+#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent -+#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir -+#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir -+#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode -+#define mvd_pin_src info[AUFS_MVDOWN_UPPER].pin -+ -+#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb -+#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent -+#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir -+#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir -+#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode -+#define mvd_pin_dst info[AUFS_MVDOWN_LOWER].pin -+ -+#define AU_MVD_PR(flag, ...) do { \ -+ if (flag) \ -+ pr_err(__VA_ARGS__); \ -+ } while (0) -+ -+static int find_lower_writable(struct au_mvd_args *a) -+{ -+ struct super_block *sb; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ sb = a->sb; -+ bindex = a->mvd_bsrc; -+ bbot = au_sbbot(sb); -+ if (a->mvdown.flags & AUFS_MVDOWN_FHSM_LOWER) -+ for (bindex++; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_fhsm(br->br_perm) -+ && !sb_rdonly(au_br_sb(br))) -+ return bindex; -+ } -+ else if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER)) -+ for (bindex++; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (!au_br_rdonly(br)) -+ return bindex; -+ } -+ else -+ for (bindex++; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (!sb_rdonly(au_br_sb(br))) { -+ if (au_br_rdonly(br)) -+ a->mvdown.flags -+ |= AUFS_MVDOWN_ROLOWER_R; -+ return bindex; -+ } -+ } -+ -+ return -1; -+} -+ -+/* make the parent dir on bdst */ -+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ -+ err = 0; -+ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc); -+ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst); -+ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc); -+ a->mvd_h_dst_parent = NULL; -+ if (au_dbbot(a->parent) >= a->mvd_bdst) -+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst); -+ if (!a->mvd_h_dst_parent) { -+ err = au_cpdown_dirs(a->dentry, a->mvd_bdst); -+ if (unlikely(err)) { -+ AU_MVD_PR(dmsg, "cpdown_dirs failed\n"); -+ goto out; -+ } -+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst); -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* lock them all */ -+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct dentry *h_trap; -+ -+ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc); -+ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst); -+ err = au_pin(&a->mvd_pin_dst, a->dentry, a->mvd_bdst, -+ au_opt_udba(a->sb), -+ AuPin_MNT_WRITE | AuPin_DI_LOCKED); -+ AuTraceErr(err); -+ if (unlikely(err)) { -+ AU_MVD_PR(dmsg, "pin_dst failed\n"); -+ goto out; -+ } -+ -+ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) { -+ a->rename_lock = 0; -+ au_pin_init(&a->mvd_pin_src, a->dentry, a->mvd_bsrc, -+ AuLsc_DI_PARENT, AuLsc_I_PARENT3, -+ au_opt_udba(a->sb), -+ AuPin_MNT_WRITE | AuPin_DI_LOCKED); -+ err = au_do_pin(&a->mvd_pin_src); -+ AuTraceErr(err); -+ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent); -+ if (unlikely(err)) { -+ AU_MVD_PR(dmsg, "pin_src failed\n"); -+ goto out_dst; -+ } -+ goto out; /* success */ -+ } -+ -+ a->rename_lock = 1; -+ au_pin_hdir_unlock(&a->mvd_pin_dst); -+ err = au_pin(&a->mvd_pin_src, a->dentry, a->mvd_bsrc, -+ au_opt_udba(a->sb), -+ AuPin_MNT_WRITE | AuPin_DI_LOCKED); -+ AuTraceErr(err); -+ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent); -+ if (unlikely(err)) { -+ AU_MVD_PR(dmsg, "pin_src failed\n"); -+ au_pin_hdir_lock(&a->mvd_pin_dst); -+ goto out_dst; -+ } -+ au_pin_hdir_unlock(&a->mvd_pin_src); -+ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src, -+ a->mvd_h_dst_parent, a->mvd_hdir_dst); -+ if (h_trap) { -+ err = (h_trap != a->mvd_h_src_parent); -+ if (err) -+ err = (h_trap != a->mvd_h_dst_parent); -+ } -+ BUG_ON(err); /* it should never happen */ -+ if (unlikely(a->mvd_h_src_dir != au_pinned_h_dir(&a->mvd_pin_src))) { -+ err = -EBUSY; -+ AuTraceErr(err); -+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src, -+ a->mvd_h_dst_parent, a->mvd_hdir_dst); -+ au_pin_hdir_lock(&a->mvd_pin_src); -+ au_unpin(&a->mvd_pin_src); -+ au_pin_hdir_lock(&a->mvd_pin_dst); -+ goto out_dst; -+ } -+ goto out; /* success */ -+ -+out_dst: -+ au_unpin(&a->mvd_pin_dst); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ if (!a->rename_lock) -+ au_unpin(&a->mvd_pin_src); -+ else { -+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src, -+ a->mvd_h_dst_parent, a->mvd_hdir_dst); -+ au_pin_hdir_lock(&a->mvd_pin_src); -+ au_unpin(&a->mvd_pin_src); -+ au_pin_hdir_lock(&a->mvd_pin_dst); -+ } -+ au_unpin(&a->mvd_pin_dst); -+} -+ -+/* copy-down the file */ -+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct au_cp_generic cpg = { -+ .dentry = a->dentry, -+ .bdst = a->mvd_bdst, -+ .bsrc = a->mvd_bsrc, -+ .len = -1, -+ .pin = &a->mvd_pin_dst, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN -+ }; -+ -+ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst); -+ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER) -+ au_fset_cpup(cpg.flags, OVERWRITE); -+ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER) -+ au_fset_cpup(cpg.flags, RWDST); -+ err = au_sio_cpdown_simple(&cpg); -+ if (unlikely(err)) -+ AU_MVD_PR(dmsg, "cpdown failed\n"); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * unlink the whiteout on bdst if exist which may be created by UDBA while we -+ * were sleeping -+ */ -+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct path h_path; -+ struct au_branch *br; -+ struct inode *delegated; -+ -+ br = au_sbr(a->sb, a->mvd_bdst); -+ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br); -+ err = PTR_ERR(h_path.dentry); -+ if (IS_ERR(h_path.dentry)) { -+ AU_MVD_PR(dmsg, "wh_lkup failed\n"); -+ goto out; -+ } -+ -+ err = 0; -+ if (d_is_positive(h_path.dentry)) { -+ h_path.mnt = au_br_mnt(br); -+ delegated = NULL; -+ err = vfsub_unlink(d_inode(a->mvd_h_dst_parent), &h_path, -+ &delegated, /*force*/0); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ if (unlikely(err)) -+ AU_MVD_PR(dmsg, "wh_unlink failed\n"); -+ } -+ dput(h_path.dentry); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * unlink the topmost h_dentry -+ */ -+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct path h_path; -+ struct inode *delegated; -+ -+ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc); -+ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc); -+ delegated = NULL; -+ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ if (unlikely(err)) -+ AU_MVD_PR(dmsg, "unlink failed\n"); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+/* Since mvdown succeeded, we ignore an error of this function */ -+static void au_do_stfs(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct au_branch *br; -+ -+ a->mvdown.flags |= AUFS_MVDOWN_STFS_FAILED; -+ br = au_sbr(a->sb, a->mvd_bsrc); -+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_UPPER].stfs); -+ if (!err) { -+ br = au_sbr(a->sb, a->mvd_bdst); -+ a->mvdown.stbr[AUFS_MVDOWN_LOWER].brid = br->br_id; -+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_LOWER].stfs); -+ } -+ if (!err) -+ a->mvdown.flags &= ~AUFS_MVDOWN_STFS_FAILED; -+ else -+ AU_MVD_PR(dmsg, "statfs failed (%d), ignored\n", err); -+} -+ -+/* -+ * copy-down the file and unlink the bsrc file. -+ * - unlink the bdst whout if exist -+ * - copy-down the file (with whtmp name and rename) -+ * - unlink the bsrc file -+ */ -+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ -+ err = au_do_mkdir(dmsg, a); -+ if (!err) -+ err = au_do_lock(dmsg, a); -+ if (unlikely(err)) -+ goto out; -+ -+ /* -+ * do not revert the activities we made on bdst since they should be -+ * harmless in aufs. -+ */ -+ -+ err = au_do_cpdown(dmsg, a); -+ if (!err) -+ err = au_do_unlink_wh(dmsg, a); -+ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) -+ err = au_do_unlink(dmsg, a); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ AuDbg("%pd2, 0x%x, %d --> %d\n", -+ a->dentry, a->mvdown.flags, a->mvd_bsrc, a->mvd_bdst); -+ if (find_lower_writable(a) < 0) -+ a->mvdown.flags |= AUFS_MVDOWN_BOTTOM; -+ -+ if (a->mvdown.flags & AUFS_MVDOWN_STFS) -+ au_do_stfs(dmsg, a); -+ -+ /* maintain internal array */ -+ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) { -+ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL); -+ au_set_dbtop(a->dentry, a->mvd_bdst); -+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0); -+ au_set_ibtop(a->inode, a->mvd_bdst); -+ } else { -+ /* hide the lower */ -+ au_set_h_dptr(a->dentry, a->mvd_bdst, NULL); -+ au_set_dbbot(a->dentry, a->mvd_bsrc); -+ au_set_h_iptr(a->inode, a->mvd_bdst, NULL, /*flags*/0); -+ au_set_ibbot(a->inode, a->mvd_bsrc); -+ } -+ if (au_dbbot(a->dentry) < a->mvd_bdst) -+ au_set_dbbot(a->dentry, a->mvd_bdst); -+ if (au_ibbot(a->inode) < a->mvd_bdst) -+ au_set_ibbot(a->inode, a->mvd_bdst); -+ -+out_unlock: -+ au_do_unlock(dmsg, a); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* make sure the file is idle */ -+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err, plinked; -+ -+ err = 0; -+ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK); -+ if (au_dbtop(a->dentry) == a->mvd_bsrc -+ && au_dcount(a->dentry) == 1 -+ && atomic_read(&a->inode->i_count) == 1 -+ /* && a->mvd_h_src_inode->i_nlink == 1 */ -+ && (!plinked || !au_plink_test(a->inode)) -+ && a->inode->i_nlink == 1) -+ goto out; -+ -+ err = -EBUSY; -+ AU_MVD_PR(dmsg, -+ "b%d, d{b%d, c%d?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n", -+ a->mvd_bsrc, au_dbtop(a->dentry), au_dcount(a->dentry), -+ atomic_read(&a->inode->i_count), a->inode->i_nlink, -+ a->mvd_h_src_inode->i_nlink, -+ plinked, plinked ? au_plink_test(a->inode) : 0); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* make sure the parent dir is fine */ -+static int au_mvd_args_parent(const unsigned char dmsg, -+ struct au_mvd_args *a) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ -+ err = 0; -+ if (unlikely(au_alive_dir(a->parent))) { -+ err = -ENOENT; -+ AU_MVD_PR(dmsg, "parent dir is dead\n"); -+ goto out; -+ } -+ -+ a->bopq = au_dbdiropq(a->parent); -+ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst); -+ AuDbg("b%d\n", bindex); -+ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst) -+ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) { -+ err = -EINVAL; -+ a->mvd_errno = EAU_MVDOWN_OPAQUE; -+ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n", -+ a->bopq, a->mvd_bdst); -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_mvd_args_intermediate(const unsigned char dmsg, -+ struct au_mvd_args *a) -+{ -+ int err; -+ struct au_dinfo *dinfo, *tmp; -+ -+ /* lookup the next lower positive entry */ -+ err = -ENOMEM; -+ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP); -+ if (unlikely(!tmp)) -+ goto out; -+ -+ a->bfound = -1; -+ a->bwh = -1; -+ dinfo = au_di(a->dentry); -+ au_di_cp(tmp, dinfo); -+ au_di_swap(tmp, dinfo); -+ -+ /* returns the number of positive dentries */ -+ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1, -+ /* AuLkup_IGNORE_PERM */ 0); -+ if (!err) -+ a->bwh = au_dbwh(a->dentry); -+ else if (err > 0) -+ a->bfound = au_dbtop(a->dentry); -+ -+ au_di_swap(tmp, dinfo); -+ au_rw_write_unlock(&tmp->di_rwsem); -+ au_di_free(tmp); -+ if (unlikely(err < 0)) -+ AU_MVD_PR(dmsg, "failed look-up lower\n"); -+ -+ /* -+ * here, we have these cases. -+ * bfound == -1 -+ * no positive dentry under bsrc. there are more sub-cases. -+ * bwh < 0 -+ * there no whiteout, we can safely move-down. -+ * bwh <= bsrc -+ * impossible -+ * bsrc < bwh && bwh < bdst -+ * there is a whiteout on RO branch. cannot proceed. -+ * bwh == bdst -+ * there is a whiteout on the RW target branch. it should -+ * be removed. -+ * bdst < bwh -+ * there is a whiteout somewhere unrelated branch. -+ * -1 < bfound && bfound <= bsrc -+ * impossible. -+ * bfound < bdst -+ * found, but it is on RO branch between bsrc and bdst. cannot -+ * proceed. -+ * bfound == bdst -+ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return -+ * error. -+ * bdst < bfound -+ * found, after we create the file on bdst, it will be hidden. -+ */ -+ -+ AuDebugOn(a->bfound == -1 -+ && a->bwh != -1 -+ && a->bwh <= a->mvd_bsrc); -+ AuDebugOn(-1 < a->bfound -+ && a->bfound <= a->mvd_bsrc); -+ -+ err = -EINVAL; -+ if (a->bfound == -1 -+ && a->mvd_bsrc < a->bwh -+ && a->bwh != -1 -+ && a->bwh < a->mvd_bdst) { -+ a->mvd_errno = EAU_MVDOWN_WHITEOUT; -+ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n", -+ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh); -+ goto out; -+ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) { -+ a->mvd_errno = EAU_MVDOWN_UPPER; -+ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n", -+ a->mvd_bdst, a->bfound); -+ goto out; -+ } -+ -+ err = 0; /* success */ -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ -+ err = 0; -+ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER) -+ && a->bfound == a->mvd_bdst) -+ err = -EEXIST; -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct au_branch *br; -+ -+ err = -EISDIR; -+ if (unlikely(S_ISDIR(a->inode->i_mode))) -+ goto out; -+ -+ err = -EINVAL; -+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER)) -+ a->mvd_bsrc = au_ibtop(a->inode); -+ else { -+ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid); -+ if (unlikely(a->mvd_bsrc < 0 -+ || (a->mvd_bsrc < au_dbtop(a->dentry) -+ || au_dbbot(a->dentry) < a->mvd_bsrc -+ || !au_h_dptr(a->dentry, a->mvd_bsrc)) -+ || (a->mvd_bsrc < au_ibtop(a->inode) -+ || au_ibbot(a->inode) < a->mvd_bsrc -+ || !au_h_iptr(a->inode, a->mvd_bsrc)))) { -+ a->mvd_errno = EAU_MVDOWN_NOUPPER; -+ AU_MVD_PR(dmsg, "no upper\n"); -+ goto out; -+ } -+ } -+ if (unlikely(a->mvd_bsrc == au_sbbot(a->sb))) { -+ a->mvd_errno = EAU_MVDOWN_BOTTOM; -+ AU_MVD_PR(dmsg, "on the bottom\n"); -+ goto out; -+ } -+ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc); -+ br = au_sbr(a->sb, a->mvd_bsrc); -+ err = au_br_rdonly(br); -+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) { -+ if (unlikely(err)) -+ goto out; -+ } else if (!(vfsub_native_ro(a->mvd_h_src_inode) -+ || IS_APPEND(a->mvd_h_src_inode))) { -+ if (err) -+ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R; -+ /* go on */ -+ } else -+ goto out; -+ -+ err = -EINVAL; -+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) { -+ a->mvd_bdst = find_lower_writable(a); -+ if (unlikely(a->mvd_bdst < 0)) { -+ a->mvd_errno = EAU_MVDOWN_BOTTOM; -+ AU_MVD_PR(dmsg, "no writable lower branch\n"); -+ goto out; -+ } -+ } else { -+ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid); -+ if (unlikely(a->mvd_bdst < 0 -+ || au_sbbot(a->sb) < a->mvd_bdst)) { -+ a->mvd_errno = EAU_MVDOWN_NOLOWERBR; -+ AU_MVD_PR(dmsg, "no lower brid\n"); -+ goto out; -+ } -+ } -+ -+ err = au_mvd_args_busy(dmsg, a); -+ if (!err) -+ err = au_mvd_args_parent(dmsg, a); -+ if (!err) -+ err = au_mvd_args_intermediate(dmsg, a); -+ if (!err) -+ err = au_mvd_args_exist(dmsg, a); -+ if (!err) -+ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg) -+{ -+ int err, e; -+ unsigned char dmsg; -+ struct au_mvd_args *args; -+ struct inode *inode; -+ -+ inode = d_inode(dentry); -+ err = -EPERM; -+ if (unlikely(!capable(CAP_SYS_ADMIN))) -+ goto out; -+ -+ err = -ENOMEM; -+ args = kmalloc(sizeof(*args), GFP_NOFS); -+ if (unlikely(!args)) -+ goto out; -+ -+ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown)); -+ if (!err) -+ err = !access_ok(VERIFY_WRITE, uarg, sizeof(*uarg)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ goto out_free; -+ } -+ AuDbg("flags 0x%x\n", args->mvdown.flags); -+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R); -+ args->mvdown.au_errno = 0; -+ args->dentry = dentry; -+ args->inode = inode; -+ args->sb = dentry->d_sb; -+ -+ err = -ENOENT; -+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG); -+ args->parent = dget_parent(dentry); -+ args->dir = d_inode(args->parent); -+ inode_lock_nested(args->dir, I_MUTEX_PARENT); -+ dput(args->parent); -+ if (unlikely(args->parent != dentry->d_parent)) { -+ AU_MVD_PR(dmsg, "parent dir is moved\n"); -+ goto out_dir; -+ } -+ -+ inode_lock_nested(inode, I_MUTEX_CHILD); -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_NOPLMW); -+ if (unlikely(err)) -+ goto out_inode; -+ -+ di_write_lock_parent(args->parent); -+ err = au_mvd_args(dmsg, args); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ err = au_do_mvdown(dmsg, args); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ au_cpup_attr_timesizes(args->dir); -+ au_cpup_attr_timesizes(inode); -+ if (!(args->mvdown.flags & AUFS_MVDOWN_KUPPER)) -+ au_cpup_igen(inode, au_h_iptr(inode, args->mvd_bdst)); -+ /* au_digen_dec(dentry); */ -+ -+out_parent: -+ di_write_unlock(args->parent); -+ aufs_read_unlock(dentry, AuLock_DW); -+out_inode: -+ inode_unlock(inode); -+out_dir: -+ inode_unlock(args->dir); -+out_free: -+ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown)); -+ if (unlikely(e)) -+ err = -EFAULT; -+ kfree(args); -+out: -+ AuTraceErr(err); -+ return err; -+} -diff --git a/fs/aufs/opts.c b/fs/aufs/opts.c -new file mode 100644 -index 000000000..3a8ba2867 ---- /dev/null -+++ b/fs/aufs/opts.c -@@ -0,0 +1,1877 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * mount options/flags -+ */ -+ -+#include -+#include /* a distribution requires */ -+#include -+#include "aufs.h" -+ -+/* ---------------------------------------------------------------------- */ -+ -+enum { -+ Opt_br, -+ Opt_add, Opt_del, Opt_mod, Opt_append, Opt_prepend, -+ Opt_idel, Opt_imod, -+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, -+ Opt_rdblk_def, Opt_rdhash_def, -+ Opt_xino, Opt_noxino, -+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino, -+ Opt_trunc_xino_path, Opt_itrunc_xino, -+ Opt_trunc_xib, Opt_notrunc_xib, -+ Opt_shwh, Opt_noshwh, -+ Opt_plink, Opt_noplink, Opt_list_plink, -+ Opt_udba, -+ Opt_dio, Opt_nodio, -+ Opt_diropq_a, Opt_diropq_w, -+ Opt_warn_perm, Opt_nowarn_perm, -+ Opt_wbr_copyup, Opt_wbr_create, -+ Opt_fhsm_sec, -+ Opt_verbose, Opt_noverbose, -+ Opt_sum, Opt_nosum, Opt_wsum, -+ Opt_dirperm1, Opt_nodirperm1, -+ Opt_dirren, Opt_nodirren, -+ Opt_acl, Opt_noacl, -+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err -+}; -+ -+static match_table_t options = { -+ {Opt_br, "br=%s"}, -+ {Opt_br, "br:%s"}, -+ -+ {Opt_add, "add=%d:%s"}, -+ {Opt_add, "add:%d:%s"}, -+ {Opt_add, "ins=%d:%s"}, -+ {Opt_add, "ins:%d:%s"}, -+ {Opt_append, "append=%s"}, -+ {Opt_append, "append:%s"}, -+ {Opt_prepend, "prepend=%s"}, -+ {Opt_prepend, "prepend:%s"}, -+ -+ {Opt_del, "del=%s"}, -+ {Opt_del, "del:%s"}, -+ /* {Opt_idel, "idel:%d"}, */ -+ {Opt_mod, "mod=%s"}, -+ {Opt_mod, "mod:%s"}, -+ /* {Opt_imod, "imod:%d:%s"}, */ -+ -+ {Opt_dirwh, "dirwh=%d"}, -+ -+ {Opt_xino, "xino=%s"}, -+ {Opt_noxino, "noxino"}, -+ {Opt_trunc_xino, "trunc_xino"}, -+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"}, -+ {Opt_notrunc_xino, "notrunc_xino"}, -+ {Opt_trunc_xino_path, "trunc_xino=%s"}, -+ {Opt_itrunc_xino, "itrunc_xino=%d"}, -+ /* {Opt_zxino, "zxino=%s"}, */ -+ {Opt_trunc_xib, "trunc_xib"}, -+ {Opt_notrunc_xib, "notrunc_xib"}, -+ -+#ifdef CONFIG_PROC_FS -+ {Opt_plink, "plink"}, -+#else -+ {Opt_ignore_silent, "plink"}, -+#endif -+ -+ {Opt_noplink, "noplink"}, -+ -+#ifdef CONFIG_AUFS_DEBUG -+ {Opt_list_plink, "list_plink"}, -+#endif -+ -+ {Opt_udba, "udba=%s"}, -+ -+ {Opt_dio, "dio"}, -+ {Opt_nodio, "nodio"}, -+ -+#ifdef CONFIG_AUFS_DIRREN -+ {Opt_dirren, "dirren"}, -+ {Opt_nodirren, "nodirren"}, -+#else -+ {Opt_ignore, "dirren"}, -+ {Opt_ignore_silent, "nodirren"}, -+#endif -+ -+#ifdef CONFIG_AUFS_FHSM -+ {Opt_fhsm_sec, "fhsm_sec=%d"}, -+#else -+ {Opt_ignore, "fhsm_sec=%d"}, -+#endif -+ -+ {Opt_diropq_a, "diropq=always"}, -+ {Opt_diropq_a, "diropq=a"}, -+ {Opt_diropq_w, "diropq=whiteouted"}, -+ {Opt_diropq_w, "diropq=w"}, -+ -+ {Opt_warn_perm, "warn_perm"}, -+ {Opt_nowarn_perm, "nowarn_perm"}, -+ -+ /* keep them temporary */ -+ {Opt_ignore_silent, "nodlgt"}, -+ {Opt_ignore, "clean_plink"}, -+ -+#ifdef CONFIG_AUFS_SHWH -+ {Opt_shwh, "shwh"}, -+#endif -+ {Opt_noshwh, "noshwh"}, -+ -+ {Opt_dirperm1, "dirperm1"}, -+ {Opt_nodirperm1, "nodirperm1"}, -+ -+ {Opt_verbose, "verbose"}, -+ {Opt_verbose, "v"}, -+ {Opt_noverbose, "noverbose"}, -+ {Opt_noverbose, "quiet"}, -+ {Opt_noverbose, "q"}, -+ {Opt_noverbose, "silent"}, -+ -+ {Opt_sum, "sum"}, -+ {Opt_nosum, "nosum"}, -+ {Opt_wsum, "wsum"}, -+ -+ {Opt_rdcache, "rdcache=%d"}, -+ {Opt_rdblk, "rdblk=%d"}, -+ {Opt_rdblk_def, "rdblk=def"}, -+ {Opt_rdhash, "rdhash=%d"}, -+ {Opt_rdhash_def, "rdhash=def"}, -+ -+ {Opt_wbr_create, "create=%s"}, -+ {Opt_wbr_create, "create_policy=%s"}, -+ {Opt_wbr_copyup, "cpup=%s"}, -+ {Opt_wbr_copyup, "copyup=%s"}, -+ {Opt_wbr_copyup, "copyup_policy=%s"}, -+ -+ /* generic VFS flag */ -+#ifdef CONFIG_FS_POSIX_ACL -+ {Opt_acl, "acl"}, -+ {Opt_noacl, "noacl"}, -+#else -+ {Opt_ignore, "acl"}, -+ {Opt_ignore_silent, "noacl"}, -+#endif -+ -+ /* internal use for the scripts */ -+ {Opt_ignore_silent, "si=%s"}, -+ -+ {Opt_br, "dirs=%s"}, -+ {Opt_ignore, "debug=%d"}, -+ {Opt_ignore, "delete=whiteout"}, -+ {Opt_ignore, "delete=all"}, -+ {Opt_ignore, "imap=%s"}, -+ -+ /* temporary workaround, due to old mount(8)? */ -+ {Opt_ignore_silent, "relatime"}, -+ -+ {Opt_err, NULL} -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static const char *au_parser_pattern(int val, match_table_t tbl) -+{ -+ struct match_token *p; -+ -+ p = tbl; -+ while (p->pattern) { -+ if (p->token == val) -+ return p->pattern; -+ p++; -+ } -+ BUG(); -+ return "??"; -+} -+ -+static const char *au_optstr(int *val, match_table_t tbl) -+{ -+ struct match_token *p; -+ int v; -+ -+ v = *val; -+ if (!v) -+ goto out; -+ p = tbl; -+ while (p->pattern) { -+ if (p->token -+ && (v & p->token) == p->token) { -+ *val &= ~p->token; -+ return p->pattern; -+ } -+ p++; -+ } -+ -+out: -+ return NULL; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static match_table_t brperm = { -+ {AuBrPerm_RO, AUFS_BRPERM_RO}, -+ {AuBrPerm_RR, AUFS_BRPERM_RR}, -+ {AuBrPerm_RW, AUFS_BRPERM_RW}, -+ {0, NULL} -+}; -+ -+static match_table_t brattr = { -+ /* general */ -+ {AuBrAttr_COO_REG, AUFS_BRATTR_COO_REG}, -+ {AuBrAttr_COO_ALL, AUFS_BRATTR_COO_ALL}, -+ /* 'unpin' attrib is meaningless since linux-3.18-rc1 */ -+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN}, -+#ifdef CONFIG_AUFS_FHSM -+ {AuBrAttr_FHSM, AUFS_BRATTR_FHSM}, -+#endif -+#ifdef CONFIG_AUFS_XATTR -+ {AuBrAttr_ICEX, AUFS_BRATTR_ICEX}, -+ {AuBrAttr_ICEX_SEC, AUFS_BRATTR_ICEX_SEC}, -+ {AuBrAttr_ICEX_SYS, AUFS_BRATTR_ICEX_SYS}, -+ {AuBrAttr_ICEX_TR, AUFS_BRATTR_ICEX_TR}, -+ {AuBrAttr_ICEX_USR, AUFS_BRATTR_ICEX_USR}, -+ {AuBrAttr_ICEX_OTH, AUFS_BRATTR_ICEX_OTH}, -+#endif -+ -+ /* ro/rr branch */ -+ {AuBrRAttr_WH, AUFS_BRRATTR_WH}, -+ -+ /* rw branch */ -+ {AuBrWAttr_MOO, AUFS_BRWATTR_MOO}, -+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH}, -+ -+ {0, NULL} -+}; -+ -+static int br_attr_val(char *str, match_table_t table, substring_t args[]) -+{ -+ int attr, v; -+ char *p; -+ -+ attr = 0; -+ do { -+ p = strchr(str, '+'); -+ if (p) -+ *p = 0; -+ v = match_token(str, table, args); -+ if (v) { -+ if (v & AuBrAttr_CMOO_Mask) -+ attr &= ~AuBrAttr_CMOO_Mask; -+ attr |= v; -+ } else { -+ if (p) -+ *p = '+'; -+ pr_warn("ignored branch attribute %s\n", str); -+ break; -+ } -+ if (p) -+ str = p + 1; -+ } while (p); -+ -+ return attr; -+} -+ -+static int au_do_optstr_br_attr(au_br_perm_str_t *str, int perm) -+{ -+ int sz; -+ const char *p; -+ char *q; -+ -+ q = str->a; -+ *q = 0; -+ p = au_optstr(&perm, brattr); -+ if (p) { -+ sz = strlen(p); -+ memcpy(q, p, sz + 1); -+ q += sz; -+ } else -+ goto out; -+ -+ do { -+ p = au_optstr(&perm, brattr); -+ if (p) { -+ *q++ = '+'; -+ sz = strlen(p); -+ memcpy(q, p, sz + 1); -+ q += sz; -+ } -+ } while (p); -+ -+out: -+ return q - str->a; -+} -+ -+static int noinline_for_stack br_perm_val(char *perm) -+{ -+ int val, bad, sz; -+ char *p; -+ substring_t args[MAX_OPT_ARGS]; -+ au_br_perm_str_t attr; -+ -+ p = strchr(perm, '+'); -+ if (p) -+ *p = 0; -+ val = match_token(perm, brperm, args); -+ if (!val) { -+ if (p) -+ *p = '+'; -+ pr_warn("ignored branch permission %s\n", perm); -+ val = AuBrPerm_RO; -+ goto out; -+ } -+ if (!p) -+ goto out; -+ -+ val |= br_attr_val(p + 1, brattr, args); -+ -+ bad = 0; -+ switch (val & AuBrPerm_Mask) { -+ case AuBrPerm_RO: -+ case AuBrPerm_RR: -+ bad = val & AuBrWAttr_Mask; -+ val &= ~AuBrWAttr_Mask; -+ break; -+ case AuBrPerm_RW: -+ bad = val & AuBrRAttr_Mask; -+ val &= ~AuBrRAttr_Mask; -+ break; -+ } -+ -+ /* -+ * 'unpin' attrib becomes meaningless since linux-3.18-rc1, but aufs -+ * does not treat it as an error, just warning. -+ * this is a tiny guard for the user operation. -+ */ -+ if (val & AuBrAttr_UNPIN) { -+ bad |= AuBrAttr_UNPIN; -+ val &= ~AuBrAttr_UNPIN; -+ } -+ -+ if (unlikely(bad)) { -+ sz = au_do_optstr_br_attr(&attr, bad); -+ AuDebugOn(!sz); -+ pr_warn("ignored branch attribute %s\n", attr.a); -+ } -+ -+out: -+ return val; -+} -+ -+void au_optstr_br_perm(au_br_perm_str_t *str, int perm) -+{ -+ au_br_perm_str_t attr; -+ const char *p; -+ char *q; -+ int sz; -+ -+ q = str->a; -+ p = au_optstr(&perm, brperm); -+ AuDebugOn(!p || !*p); -+ sz = strlen(p); -+ memcpy(q, p, sz + 1); -+ q += sz; -+ -+ sz = au_do_optstr_br_attr(&attr, perm); -+ if (sz) { -+ *q++ = '+'; -+ memcpy(q, attr.a, sz + 1); -+ } -+ -+ AuDebugOn(strlen(str->a) >= sizeof(str->a)); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static match_table_t udbalevel = { -+ {AuOpt_UDBA_REVAL, "reval"}, -+ {AuOpt_UDBA_NONE, "none"}, -+#ifdef CONFIG_AUFS_HNOTIFY -+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */ -+#ifdef CONFIG_AUFS_HFSNOTIFY -+ {AuOpt_UDBA_HNOTIFY, "fsnotify"}, -+#endif -+#endif -+ {-1, NULL} -+}; -+ -+static int noinline_for_stack udba_val(char *str) -+{ -+ substring_t args[MAX_OPT_ARGS]; -+ -+ return match_token(str, udbalevel, args); -+} -+ -+const char *au_optstr_udba(int udba) -+{ -+ return au_parser_pattern(udba, udbalevel); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static match_table_t au_wbr_create_policy = { -+ {AuWbrCreate_TDP, "tdp"}, -+ {AuWbrCreate_TDP, "top-down-parent"}, -+ {AuWbrCreate_RR, "rr"}, -+ {AuWbrCreate_RR, "round-robin"}, -+ {AuWbrCreate_MFS, "mfs"}, -+ {AuWbrCreate_MFS, "most-free-space"}, -+ {AuWbrCreate_MFSV, "mfs:%d"}, -+ {AuWbrCreate_MFSV, "most-free-space:%d"}, -+ -+ /* top-down regardless the parent, and then mfs */ -+ {AuWbrCreate_TDMFS, "tdmfs:%d"}, -+ {AuWbrCreate_TDMFSV, "tdmfs:%d:%d"}, -+ -+ {AuWbrCreate_MFSRR, "mfsrr:%d"}, -+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"}, -+ {AuWbrCreate_PMFS, "pmfs"}, -+ {AuWbrCreate_PMFSV, "pmfs:%d"}, -+ {AuWbrCreate_PMFSRR, "pmfsrr:%d"}, -+ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"}, -+ -+ {-1, NULL} -+}; -+ -+static int au_wbr_mfs_wmark(substring_t *arg, char *str, -+ struct au_opt_wbr_create *create) -+{ -+ int err; -+ unsigned long long ull; -+ -+ err = 0; -+ if (!match_u64(arg, &ull)) -+ create->mfsrr_watermark = ull; -+ else { -+ pr_err("bad integer in %s\n", str); -+ err = -EINVAL; -+ } -+ -+ return err; -+} -+ -+static int au_wbr_mfs_sec(substring_t *arg, char *str, -+ struct au_opt_wbr_create *create) -+{ -+ int n, err; -+ -+ err = 0; -+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC) -+ create->mfs_second = n; -+ else { -+ pr_err("bad integer in %s\n", str); -+ err = -EINVAL; -+ } -+ -+ return err; -+} -+ -+static int noinline_for_stack -+au_wbr_create_val(char *str, struct au_opt_wbr_create *create) -+{ -+ int err, e; -+ substring_t args[MAX_OPT_ARGS]; -+ -+ err = match_token(str, au_wbr_create_policy, args); -+ create->wbr_create = err; -+ switch (err) { -+ case AuWbrCreate_MFSRRV: -+ case AuWbrCreate_TDMFSV: -+ case AuWbrCreate_PMFSRRV: -+ e = au_wbr_mfs_wmark(&args[0], str, create); -+ if (!e) -+ e = au_wbr_mfs_sec(&args[1], str, create); -+ if (unlikely(e)) -+ err = e; -+ break; -+ case AuWbrCreate_MFSRR: -+ case AuWbrCreate_TDMFS: -+ case AuWbrCreate_PMFSRR: -+ e = au_wbr_mfs_wmark(&args[0], str, create); -+ if (unlikely(e)) { -+ err = e; -+ break; -+ } -+ /*FALLTHROUGH*/ -+ case AuWbrCreate_MFS: -+ case AuWbrCreate_PMFS: -+ create->mfs_second = AUFS_MFS_DEF_SEC; -+ break; -+ case AuWbrCreate_MFSV: -+ case AuWbrCreate_PMFSV: -+ e = au_wbr_mfs_sec(&args[0], str, create); -+ if (unlikely(e)) -+ err = e; -+ break; -+ } -+ -+ return err; -+} -+ -+const char *au_optstr_wbr_create(int wbr_create) -+{ -+ return au_parser_pattern(wbr_create, au_wbr_create_policy); -+} -+ -+static match_table_t au_wbr_copyup_policy = { -+ {AuWbrCopyup_TDP, "tdp"}, -+ {AuWbrCopyup_TDP, "top-down-parent"}, -+ {AuWbrCopyup_BUP, "bup"}, -+ {AuWbrCopyup_BUP, "bottom-up-parent"}, -+ {AuWbrCopyup_BU, "bu"}, -+ {AuWbrCopyup_BU, "bottom-up"}, -+ {-1, NULL} -+}; -+ -+static int noinline_for_stack au_wbr_copyup_val(char *str) -+{ -+ substring_t args[MAX_OPT_ARGS]; -+ -+ return match_token(str, au_wbr_copyup_policy, args); -+} -+ -+const char *au_optstr_wbr_copyup(int wbr_copyup) -+{ -+ return au_parser_pattern(wbr_copyup, au_wbr_copyup_policy); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY; -+ -+static void dump_opts(struct au_opts *opts) -+{ -+#ifdef CONFIG_AUFS_DEBUG -+ /* reduce stack space */ -+ union { -+ struct au_opt_add *add; -+ struct au_opt_del *del; -+ struct au_opt_mod *mod; -+ struct au_opt_xino *xino; -+ struct au_opt_xino_itrunc *xino_itrunc; -+ struct au_opt_wbr_create *create; -+ } u; -+ struct au_opt *opt; -+ -+ opt = opts->opt; -+ while (opt->type != Opt_tail) { -+ switch (opt->type) { -+ case Opt_add: -+ u.add = &opt->add; -+ AuDbg("add {b%d, %s, 0x%x, %p}\n", -+ u.add->bindex, u.add->pathname, u.add->perm, -+ u.add->path.dentry); -+ break; -+ case Opt_del: -+ case Opt_idel: -+ u.del = &opt->del; -+ AuDbg("del {%s, %p}\n", -+ u.del->pathname, u.del->h_path.dentry); -+ break; -+ case Opt_mod: -+ case Opt_imod: -+ u.mod = &opt->mod; -+ AuDbg("mod {%s, 0x%x, %p}\n", -+ u.mod->path, u.mod->perm, u.mod->h_root); -+ break; -+ case Opt_append: -+ u.add = &opt->add; -+ AuDbg("append {b%d, %s, 0x%x, %p}\n", -+ u.add->bindex, u.add->pathname, u.add->perm, -+ u.add->path.dentry); -+ break; -+ case Opt_prepend: -+ u.add = &opt->add; -+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n", -+ u.add->bindex, u.add->pathname, u.add->perm, -+ u.add->path.dentry); -+ break; -+ case Opt_dirwh: -+ AuDbg("dirwh %d\n", opt->dirwh); -+ break; -+ case Opt_rdcache: -+ AuDbg("rdcache %d\n", opt->rdcache); -+ break; -+ case Opt_rdblk: -+ AuDbg("rdblk %u\n", opt->rdblk); -+ break; -+ case Opt_rdblk_def: -+ AuDbg("rdblk_def\n"); -+ break; -+ case Opt_rdhash: -+ AuDbg("rdhash %u\n", opt->rdhash); -+ break; -+ case Opt_rdhash_def: -+ AuDbg("rdhash_def\n"); -+ break; -+ case Opt_xino: -+ u.xino = &opt->xino; -+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file); -+ break; -+ case Opt_trunc_xino: -+ AuLabel(trunc_xino); -+ break; -+ case Opt_notrunc_xino: -+ AuLabel(notrunc_xino); -+ break; -+ case Opt_trunc_xino_path: -+ case Opt_itrunc_xino: -+ u.xino_itrunc = &opt->xino_itrunc; -+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex); -+ break; -+ case Opt_noxino: -+ AuLabel(noxino); -+ break; -+ case Opt_trunc_xib: -+ AuLabel(trunc_xib); -+ break; -+ case Opt_notrunc_xib: -+ AuLabel(notrunc_xib); -+ break; -+ case Opt_shwh: -+ AuLabel(shwh); -+ break; -+ case Opt_noshwh: -+ AuLabel(noshwh); -+ break; -+ case Opt_dirperm1: -+ AuLabel(dirperm1); -+ break; -+ case Opt_nodirperm1: -+ AuLabel(nodirperm1); -+ break; -+ case Opt_plink: -+ AuLabel(plink); -+ break; -+ case Opt_noplink: -+ AuLabel(noplink); -+ break; -+ case Opt_list_plink: -+ AuLabel(list_plink); -+ break; -+ case Opt_udba: -+ AuDbg("udba %d, %s\n", -+ opt->udba, au_optstr_udba(opt->udba)); -+ break; -+ case Opt_dio: -+ AuLabel(dio); -+ break; -+ case Opt_nodio: -+ AuLabel(nodio); -+ break; -+ case Opt_diropq_a: -+ AuLabel(diropq_a); -+ break; -+ case Opt_diropq_w: -+ AuLabel(diropq_w); -+ break; -+ case Opt_warn_perm: -+ AuLabel(warn_perm); -+ break; -+ case Opt_nowarn_perm: -+ AuLabel(nowarn_perm); -+ break; -+ case Opt_verbose: -+ AuLabel(verbose); -+ break; -+ case Opt_noverbose: -+ AuLabel(noverbose); -+ break; -+ case Opt_sum: -+ AuLabel(sum); -+ break; -+ case Opt_nosum: -+ AuLabel(nosum); -+ break; -+ case Opt_wsum: -+ AuLabel(wsum); -+ break; -+ case Opt_wbr_create: -+ u.create = &opt->wbr_create; -+ AuDbg("create %d, %s\n", u.create->wbr_create, -+ au_optstr_wbr_create(u.create->wbr_create)); -+ switch (u.create->wbr_create) { -+ case AuWbrCreate_MFSV: -+ case AuWbrCreate_PMFSV: -+ AuDbg("%d sec\n", u.create->mfs_second); -+ break; -+ case AuWbrCreate_MFSRR: -+ case AuWbrCreate_TDMFS: -+ AuDbg("%llu watermark\n", -+ u.create->mfsrr_watermark); -+ break; -+ case AuWbrCreate_MFSRRV: -+ case AuWbrCreate_TDMFSV: -+ case AuWbrCreate_PMFSRRV: -+ AuDbg("%llu watermark, %d sec\n", -+ u.create->mfsrr_watermark, -+ u.create->mfs_second); -+ break; -+ } -+ break; -+ case Opt_wbr_copyup: -+ AuDbg("copyup %d, %s\n", opt->wbr_copyup, -+ au_optstr_wbr_copyup(opt->wbr_copyup)); -+ break; -+ case Opt_fhsm_sec: -+ AuDbg("fhsm_sec %u\n", opt->fhsm_second); -+ break; -+ case Opt_dirren: -+ AuLabel(dirren); -+ break; -+ case Opt_nodirren: -+ AuLabel(nodirren); -+ break; -+ case Opt_acl: -+ AuLabel(acl); -+ break; -+ case Opt_noacl: -+ AuLabel(noacl); -+ break; -+ default: -+ BUG(); -+ } -+ opt++; -+ } -+#endif -+} -+ -+void au_opts_free(struct au_opts *opts) -+{ -+ struct au_opt *opt; -+ -+ opt = opts->opt; -+ while (opt->type != Opt_tail) { -+ switch (opt->type) { -+ case Opt_add: -+ case Opt_append: -+ case Opt_prepend: -+ path_put(&opt->add.path); -+ break; -+ case Opt_del: -+ case Opt_idel: -+ path_put(&opt->del.h_path); -+ break; -+ case Opt_mod: -+ case Opt_imod: -+ dput(opt->mod.h_root); -+ break; -+ case Opt_xino: -+ fput(opt->xino.file); -+ break; -+ } -+ opt++; -+ } -+} -+ -+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags, -+ aufs_bindex_t bindex) -+{ -+ int err; -+ struct au_opt_add *add = &opt->add; -+ char *p; -+ -+ add->bindex = bindex; -+ add->perm = AuBrPerm_RO; -+ add->pathname = opt_str; -+ p = strchr(opt_str, '='); -+ if (p) { -+ *p++ = 0; -+ if (*p) -+ add->perm = br_perm_val(p); -+ } -+ -+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path); -+ if (!err) { -+ if (!p) { -+ add->perm = AuBrPerm_RO; -+ if (au_test_fs_rr(add->path.dentry->d_sb)) -+ add->perm = AuBrPerm_RR; -+ else if (!bindex && !(sb_flags & SB_RDONLY)) -+ add->perm = AuBrPerm_RW; -+ } -+ opt->type = Opt_add; -+ goto out; -+ } -+ pr_err("lookup failed %s (%d)\n", add->pathname, err); -+ err = -EINVAL; -+ -+out: -+ return err; -+} -+ -+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[]) -+{ -+ int err; -+ -+ del->pathname = args[0].from; -+ AuDbg("del path %s\n", del->pathname); -+ -+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path); -+ if (unlikely(err)) -+ pr_err("lookup failed %s (%d)\n", del->pathname, err); -+ -+ return err; -+} -+ -+#if 0 /* reserved for future use */ -+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex, -+ struct au_opt_del *del, substring_t args[]) -+{ -+ int err; -+ struct dentry *root; -+ -+ err = -EINVAL; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_FLUSH); -+ if (bindex < 0 || au_sbbot(sb) < bindex) { -+ pr_err("out of bounds, %d\n", bindex); -+ goto out; -+ } -+ -+ err = 0; -+ del->h_path.dentry = dget(au_h_dptr(root, bindex)); -+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex)); -+ -+out: -+ aufs_read_unlock(root, !AuLock_IR); -+ return err; -+} -+#endif -+ -+static int noinline_for_stack -+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[]) -+{ -+ int err; -+ struct path path; -+ char *p; -+ -+ err = -EINVAL; -+ mod->path = args[0].from; -+ p = strchr(mod->path, '='); -+ if (unlikely(!p)) { -+ pr_err("no permission %s\n", args[0].from); -+ goto out; -+ } -+ -+ *p++ = 0; -+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path); -+ if (unlikely(err)) { -+ pr_err("lookup failed %s (%d)\n", mod->path, err); -+ goto out; -+ } -+ -+ mod->perm = br_perm_val(p); -+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p); -+ mod->h_root = dget(path.dentry); -+ path_put(&path); -+ -+out: -+ return err; -+} -+ -+#if 0 /* reserved for future use */ -+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex, -+ struct au_opt_mod *mod, substring_t args[]) -+{ -+ int err; -+ struct dentry *root; -+ -+ err = -EINVAL; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_FLUSH); -+ if (bindex < 0 || au_sbbot(sb) < bindex) { -+ pr_err("out of bounds, %d\n", bindex); -+ goto out; -+ } -+ -+ err = 0; -+ mod->perm = br_perm_val(args[1].from); -+ AuDbg("mod path %s, perm 0x%x, %s\n", -+ mod->path, mod->perm, args[1].from); -+ mod->h_root = dget(au_h_dptr(root, bindex)); -+ -+out: -+ aufs_read_unlock(root, !AuLock_IR); -+ return err; -+} -+#endif -+ -+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino, -+ substring_t args[]) -+{ -+ int err; -+ struct file *file; -+ -+ file = au_xino_create(sb, args[0].from, /*silent*/0); -+ err = PTR_ERR(file); -+ if (IS_ERR(file)) -+ goto out; -+ -+ err = -EINVAL; -+ if (unlikely(file->f_path.dentry->d_sb == sb)) { -+ fput(file); -+ pr_err("%s must be outside\n", args[0].from); -+ goto out; -+ } -+ -+ err = 0; -+ xino->file = file; -+ xino->path = args[0].from; -+ -+out: -+ return err; -+} -+ -+static int noinline_for_stack -+au_opts_parse_xino_itrunc_path(struct super_block *sb, -+ struct au_opt_xino_itrunc *xino_itrunc, -+ substring_t args[]) -+{ -+ int err; -+ aufs_bindex_t bbot, bindex; -+ struct path path; -+ struct dentry *root; -+ -+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path); -+ if (unlikely(err)) { -+ pr_err("lookup failed %s (%d)\n", args[0].from, err); -+ goto out; -+ } -+ -+ xino_itrunc->bindex = -1; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_FLUSH); -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ if (au_h_dptr(root, bindex) == path.dentry) { -+ xino_itrunc->bindex = bindex; -+ break; -+ } -+ } -+ aufs_read_unlock(root, !AuLock_IR); -+ path_put(&path); -+ -+ if (unlikely(xino_itrunc->bindex < 0)) { -+ pr_err("no such branch %s\n", args[0].from); -+ err = -EINVAL; -+ } -+ -+out: -+ return err; -+} -+ -+/* called without aufs lock */ -+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts) -+{ -+ int err, n, token; -+ aufs_bindex_t bindex; -+ unsigned char skipped; -+ struct dentry *root; -+ struct au_opt *opt, *opt_tail; -+ char *opt_str; -+ /* reduce the stack space */ -+ union { -+ struct au_opt_xino_itrunc *xino_itrunc; -+ struct au_opt_wbr_create *create; -+ } u; -+ struct { -+ substring_t args[MAX_OPT_ARGS]; -+ } *a; -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ root = sb->s_root; -+ err = 0; -+ bindex = 0; -+ opt = opts->opt; -+ opt_tail = opt + opts->max_opt - 1; -+ opt->type = Opt_tail; -+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) { -+ err = -EINVAL; -+ skipped = 0; -+ token = match_token(opt_str, options, a->args); -+ switch (token) { -+ case Opt_br: -+ err = 0; -+ while (!err && (opt_str = strsep(&a->args[0].from, ":")) -+ && *opt_str) { -+ err = opt_add(opt, opt_str, opts->sb_flags, -+ bindex++); -+ if (unlikely(!err && ++opt > opt_tail)) { -+ err = -E2BIG; -+ break; -+ } -+ opt->type = Opt_tail; -+ skipped = 1; -+ } -+ break; -+ case Opt_add: -+ if (unlikely(match_int(&a->args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ bindex = n; -+ err = opt_add(opt, a->args[1].from, opts->sb_flags, -+ bindex); -+ if (!err) -+ opt->type = token; -+ break; -+ case Opt_append: -+ err = opt_add(opt, a->args[0].from, opts->sb_flags, -+ /*dummy bindex*/1); -+ if (!err) -+ opt->type = token; -+ break; -+ case Opt_prepend: -+ err = opt_add(opt, a->args[0].from, opts->sb_flags, -+ /*bindex*/0); -+ if (!err) -+ opt->type = token; -+ break; -+ case Opt_del: -+ err = au_opts_parse_del(&opt->del, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+#if 0 /* reserved for future use */ -+ case Opt_idel: -+ del->pathname = "(indexed)"; -+ if (unlikely(match_int(&args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ err = au_opts_parse_idel(sb, n, &opt->del, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+#endif -+ case Opt_mod: -+ err = au_opts_parse_mod(&opt->mod, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+#ifdef IMOD /* reserved for future use */ -+ case Opt_imod: -+ u.mod->path = "(indexed)"; -+ if (unlikely(match_int(&a->args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+#endif -+ case Opt_xino: -+ err = au_opts_parse_xino(sb, &opt->xino, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+ -+ case Opt_trunc_xino_path: -+ err = au_opts_parse_xino_itrunc_path -+ (sb, &opt->xino_itrunc, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+ -+ case Opt_itrunc_xino: -+ u.xino_itrunc = &opt->xino_itrunc; -+ if (unlikely(match_int(&a->args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ u.xino_itrunc->bindex = n; -+ aufs_read_lock(root, AuLock_FLUSH); -+ if (n < 0 || au_sbbot(sb) < n) { -+ pr_err("out of bounds, %d\n", n); -+ aufs_read_unlock(root, !AuLock_IR); -+ break; -+ } -+ aufs_read_unlock(root, !AuLock_IR); -+ err = 0; -+ opt->type = token; -+ break; -+ -+ case Opt_dirwh: -+ if (unlikely(match_int(&a->args[0], &opt->dirwh))) -+ break; -+ err = 0; -+ opt->type = token; -+ break; -+ -+ case Opt_rdcache: -+ if (unlikely(match_int(&a->args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ if (unlikely(n > AUFS_RDCACHE_MAX)) { -+ pr_err("rdcache must be smaller than %d\n", -+ AUFS_RDCACHE_MAX); -+ break; -+ } -+ opt->rdcache = n; -+ err = 0; -+ opt->type = token; -+ break; -+ case Opt_rdblk: -+ if (unlikely(match_int(&a->args[0], &n) -+ || n < 0 -+ || n > KMALLOC_MAX_SIZE)) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ if (unlikely(n && n < NAME_MAX)) { -+ pr_err("rdblk must be larger than %d\n", -+ NAME_MAX); -+ break; -+ } -+ opt->rdblk = n; -+ err = 0; -+ opt->type = token; -+ break; -+ case Opt_rdhash: -+ if (unlikely(match_int(&a->args[0], &n) -+ || n < 0 -+ || n * sizeof(struct hlist_head) -+ > KMALLOC_MAX_SIZE)) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ opt->rdhash = n; -+ err = 0; -+ opt->type = token; -+ break; -+ -+ case Opt_trunc_xino: -+ case Opt_notrunc_xino: -+ case Opt_noxino: -+ case Opt_trunc_xib: -+ case Opt_notrunc_xib: -+ case Opt_shwh: -+ case Opt_noshwh: -+ case Opt_dirperm1: -+ case Opt_nodirperm1: -+ case Opt_plink: -+ case Opt_noplink: -+ case Opt_list_plink: -+ case Opt_dio: -+ case Opt_nodio: -+ case Opt_diropq_a: -+ case Opt_diropq_w: -+ case Opt_warn_perm: -+ case Opt_nowarn_perm: -+ case Opt_verbose: -+ case Opt_noverbose: -+ case Opt_sum: -+ case Opt_nosum: -+ case Opt_wsum: -+ case Opt_rdblk_def: -+ case Opt_rdhash_def: -+ case Opt_dirren: -+ case Opt_nodirren: -+ case Opt_acl: -+ case Opt_noacl: -+ err = 0; -+ opt->type = token; -+ break; -+ -+ case Opt_udba: -+ opt->udba = udba_val(a->args[0].from); -+ if (opt->udba >= 0) { -+ err = 0; -+ opt->type = token; -+ } else -+ pr_err("wrong value, %s\n", opt_str); -+ break; -+ -+ case Opt_wbr_create: -+ u.create = &opt->wbr_create; -+ u.create->wbr_create -+ = au_wbr_create_val(a->args[0].from, u.create); -+ if (u.create->wbr_create >= 0) { -+ err = 0; -+ opt->type = token; -+ } else -+ pr_err("wrong value, %s\n", opt_str); -+ break; -+ case Opt_wbr_copyup: -+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from); -+ if (opt->wbr_copyup >= 0) { -+ err = 0; -+ opt->type = token; -+ } else -+ pr_err("wrong value, %s\n", opt_str); -+ break; -+ -+ case Opt_fhsm_sec: -+ if (unlikely(match_int(&a->args[0], &n) -+ || n < 0)) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ if (sysaufs_brs) { -+ opt->fhsm_second = n; -+ opt->type = token; -+ } else -+ pr_warn("ignored %s\n", opt_str); -+ err = 0; -+ break; -+ -+ case Opt_ignore: -+ pr_warn("ignored %s\n", opt_str); -+ /*FALLTHROUGH*/ -+ case Opt_ignore_silent: -+ skipped = 1; -+ err = 0; -+ break; -+ case Opt_err: -+ pr_err("unknown option %s\n", opt_str); -+ break; -+ } -+ -+ if (!err && !skipped) { -+ if (unlikely(++opt > opt_tail)) { -+ err = -E2BIG; -+ opt--; -+ opt->type = Opt_tail; -+ break; -+ } -+ opt->type = Opt_tail; -+ } -+ } -+ -+ kfree(a); -+ dump_opts(opts); -+ if (unlikely(err)) -+ au_opts_free(opts); -+ -+out: -+ return err; -+} -+ -+static int au_opt_wbr_create(struct super_block *sb, -+ struct au_opt_wbr_create *create) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ err = 1; /* handled */ -+ sbinfo = au_sbi(sb); -+ if (sbinfo->si_wbr_create_ops->fin) { -+ err = sbinfo->si_wbr_create_ops->fin(sb); -+ if (!err) -+ err = 1; -+ } -+ -+ sbinfo->si_wbr_create = create->wbr_create; -+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create; -+ switch (create->wbr_create) { -+ case AuWbrCreate_MFSRRV: -+ case AuWbrCreate_MFSRR: -+ case AuWbrCreate_TDMFS: -+ case AuWbrCreate_TDMFSV: -+ case AuWbrCreate_PMFSRR: -+ case AuWbrCreate_PMFSRRV: -+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark; -+ /*FALLTHROUGH*/ -+ case AuWbrCreate_MFS: -+ case AuWbrCreate_MFSV: -+ case AuWbrCreate_PMFS: -+ case AuWbrCreate_PMFSV: -+ sbinfo->si_wbr_mfs.mfs_expire -+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC); -+ break; -+ } -+ -+ if (sbinfo->si_wbr_create_ops->init) -+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */ -+ -+ return err; -+} -+ -+/* -+ * returns, -+ * plus: processed without an error -+ * zero: unprocessed -+ */ -+static int au_opt_simple(struct super_block *sb, struct au_opt *opt, -+ struct au_opts *opts) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ err = 1; /* handled */ -+ sbinfo = au_sbi(sb); -+ switch (opt->type) { -+ case Opt_udba: -+ sbinfo->si_mntflags &= ~AuOptMask_UDBA; -+ sbinfo->si_mntflags |= opt->udba; -+ opts->given_udba |= opt->udba; -+ break; -+ -+ case Opt_plink: -+ au_opt_set(sbinfo->si_mntflags, PLINK); -+ break; -+ case Opt_noplink: -+ if (au_opt_test(sbinfo->si_mntflags, PLINK)) -+ au_plink_put(sb, /*verbose*/1); -+ au_opt_clr(sbinfo->si_mntflags, PLINK); -+ break; -+ case Opt_list_plink: -+ if (au_opt_test(sbinfo->si_mntflags, PLINK)) -+ au_plink_list(sb); -+ break; -+ -+ case Opt_dio: -+ au_opt_set(sbinfo->si_mntflags, DIO); -+ au_fset_opts(opts->flags, REFRESH_DYAOP); -+ break; -+ case Opt_nodio: -+ au_opt_clr(sbinfo->si_mntflags, DIO); -+ au_fset_opts(opts->flags, REFRESH_DYAOP); -+ break; -+ -+ case Opt_fhsm_sec: -+ au_fhsm_set(sbinfo, opt->fhsm_second); -+ break; -+ -+ case Opt_diropq_a: -+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ); -+ break; -+ case Opt_diropq_w: -+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ); -+ break; -+ -+ case Opt_warn_perm: -+ au_opt_set(sbinfo->si_mntflags, WARN_PERM); -+ break; -+ case Opt_nowarn_perm: -+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM); -+ break; -+ -+ case Opt_verbose: -+ au_opt_set(sbinfo->si_mntflags, VERBOSE); -+ break; -+ case Opt_noverbose: -+ au_opt_clr(sbinfo->si_mntflags, VERBOSE); -+ break; -+ -+ case Opt_sum: -+ au_opt_set(sbinfo->si_mntflags, SUM); -+ break; -+ case Opt_wsum: -+ au_opt_clr(sbinfo->si_mntflags, SUM); -+ au_opt_set(sbinfo->si_mntflags, SUM_W); -+ case Opt_nosum: -+ au_opt_clr(sbinfo->si_mntflags, SUM); -+ au_opt_clr(sbinfo->si_mntflags, SUM_W); -+ break; -+ -+ case Opt_wbr_create: -+ err = au_opt_wbr_create(sb, &opt->wbr_create); -+ break; -+ case Opt_wbr_copyup: -+ sbinfo->si_wbr_copyup = opt->wbr_copyup; -+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup; -+ break; -+ -+ case Opt_dirwh: -+ sbinfo->si_dirwh = opt->dirwh; -+ break; -+ -+ case Opt_rdcache: -+ sbinfo->si_rdcache -+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC); -+ break; -+ case Opt_rdblk: -+ sbinfo->si_rdblk = opt->rdblk; -+ break; -+ case Opt_rdblk_def: -+ sbinfo->si_rdblk = AUFS_RDBLK_DEF; -+ break; -+ case Opt_rdhash: -+ sbinfo->si_rdhash = opt->rdhash; -+ break; -+ case Opt_rdhash_def: -+ sbinfo->si_rdhash = AUFS_RDHASH_DEF; -+ break; -+ -+ case Opt_shwh: -+ au_opt_set(sbinfo->si_mntflags, SHWH); -+ break; -+ case Opt_noshwh: -+ au_opt_clr(sbinfo->si_mntflags, SHWH); -+ break; -+ -+ case Opt_dirperm1: -+ au_opt_set(sbinfo->si_mntflags, DIRPERM1); -+ break; -+ case Opt_nodirperm1: -+ au_opt_clr(sbinfo->si_mntflags, DIRPERM1); -+ break; -+ -+ case Opt_trunc_xino: -+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO); -+ break; -+ case Opt_notrunc_xino: -+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO); -+ break; -+ -+ case Opt_trunc_xino_path: -+ case Opt_itrunc_xino: -+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex, -+ /*idx_begin*/0); -+ if (!err) -+ err = 1; -+ break; -+ -+ case Opt_trunc_xib: -+ au_fset_opts(opts->flags, TRUNC_XIB); -+ break; -+ case Opt_notrunc_xib: -+ au_fclr_opts(opts->flags, TRUNC_XIB); -+ break; -+ -+ case Opt_dirren: -+ err = 1; -+ if (!au_opt_test(sbinfo->si_mntflags, DIRREN)) { -+ err = au_dr_opt_set(sb); -+ if (!err) -+ err = 1; -+ } -+ if (err == 1) -+ au_opt_set(sbinfo->si_mntflags, DIRREN); -+ break; -+ case Opt_nodirren: -+ err = 1; -+ if (au_opt_test(sbinfo->si_mntflags, DIRREN)) { -+ err = au_dr_opt_clr(sb, au_ftest_opts(opts->flags, -+ DR_FLUSHED)); -+ if (!err) -+ err = 1; -+ } -+ if (err == 1) -+ au_opt_clr(sbinfo->si_mntflags, DIRREN); -+ break; -+ -+ case Opt_acl: -+ sb->s_flags |= SB_POSIXACL; -+ break; -+ case Opt_noacl: -+ sb->s_flags &= ~SB_POSIXACL; -+ break; -+ -+ default: -+ err = 0; -+ break; -+ } -+ -+ return err; -+} -+ -+/* -+ * returns tri-state. -+ * plus: processed without an error -+ * zero: unprocessed -+ * minus: error -+ */ -+static int au_opt_br(struct super_block *sb, struct au_opt *opt, -+ struct au_opts *opts) -+{ -+ int err, do_refresh; -+ -+ err = 0; -+ switch (opt->type) { -+ case Opt_append: -+ opt->add.bindex = au_sbbot(sb) + 1; -+ if (opt->add.bindex < 0) -+ opt->add.bindex = 0; -+ goto add; -+ case Opt_prepend: -+ opt->add.bindex = 0; -+ add: /* indented label */ -+ case Opt_add: -+ err = au_br_add(sb, &opt->add, -+ au_ftest_opts(opts->flags, REMOUNT)); -+ if (!err) { -+ err = 1; -+ au_fset_opts(opts->flags, REFRESH); -+ } -+ break; -+ -+ case Opt_del: -+ case Opt_idel: -+ err = au_br_del(sb, &opt->del, -+ au_ftest_opts(opts->flags, REMOUNT)); -+ if (!err) { -+ err = 1; -+ au_fset_opts(opts->flags, TRUNC_XIB); -+ au_fset_opts(opts->flags, REFRESH); -+ } -+ break; -+ -+ case Opt_mod: -+ case Opt_imod: -+ err = au_br_mod(sb, &opt->mod, -+ au_ftest_opts(opts->flags, REMOUNT), -+ &do_refresh); -+ if (!err) { -+ err = 1; -+ if (do_refresh) -+ au_fset_opts(opts->flags, REFRESH); -+ } -+ break; -+ } -+ return err; -+} -+ -+static int au_opt_xino(struct super_block *sb, struct au_opt *opt, -+ struct au_opt_xino **opt_xino, -+ struct au_opts *opts) -+{ -+ int err; -+ -+ err = 0; -+ switch (opt->type) { -+ case Opt_xino: -+ err = au_xino_set(sb, &opt->xino, -+ !!au_ftest_opts(opts->flags, REMOUNT)); -+ if (unlikely(err)) -+ break; -+ -+ *opt_xino = &opt->xino; -+ break; -+ -+ case Opt_noxino: -+ au_xino_clr(sb); -+ *opt_xino = (void *)-1; -+ break; -+ } -+ -+ return err; -+} -+ -+int au_opts_verify(struct super_block *sb, unsigned long sb_flags, -+ unsigned int pending) -+{ -+ int err, fhsm; -+ aufs_bindex_t bindex, bbot; -+ unsigned char do_plink, skip, do_free, can_no_dreval; -+ struct au_branch *br; -+ struct au_wbr *wbr; -+ struct dentry *root, *dentry; -+ struct inode *dir, *h_dir; -+ struct au_sbinfo *sbinfo; -+ struct au_hinode *hdir; -+ -+ SiMustAnyLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA)); -+ -+ if (!(sb_flags & SB_RDONLY)) { -+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0)))) -+ pr_warn("first branch should be rw\n"); -+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH))) -+ pr_warn_once("shwh should be used with ro\n"); -+ } -+ -+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY) -+ && !au_opt_test(sbinfo->si_mntflags, XINO)) -+ pr_warn_once("udba=*notify requires xino\n"); -+ -+ if (au_opt_test(sbinfo->si_mntflags, DIRPERM1)) -+ pr_warn_once("dirperm1 breaks the protection" -+ " by the permission bits on the lower branch\n"); -+ -+ err = 0; -+ fhsm = 0; -+ root = sb->s_root; -+ dir = d_inode(root); -+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK); -+ can_no_dreval = !!au_opt_test((sbinfo->si_mntflags | pending), -+ UDBA_NONE); -+ bbot = au_sbbot(sb); -+ for (bindex = 0; !err && bindex <= bbot; bindex++) { -+ skip = 0; -+ h_dir = au_h_iptr(dir, bindex); -+ br = au_sbr(sb, bindex); -+ -+ if ((br->br_perm & AuBrAttr_ICEX) -+ && !h_dir->i_op->listxattr) -+ br->br_perm &= ~AuBrAttr_ICEX; -+#if 0 -+ if ((br->br_perm & AuBrAttr_ICEX_SEC) -+ && (au_br_sb(br)->s_flags & SB_NOSEC)) -+ br->br_perm &= ~AuBrAttr_ICEX_SEC; -+#endif -+ -+ do_free = 0; -+ wbr = br->br_wbr; -+ if (wbr) -+ wbr_wh_read_lock(wbr); -+ -+ if (!au_br_writable(br->br_perm)) { -+ do_free = !!wbr; -+ skip = (!wbr -+ || (!wbr->wbr_whbase -+ && !wbr->wbr_plink -+ && !wbr->wbr_orph)); -+ } else if (!au_br_wh_linkable(br->br_perm)) { -+ /* skip = (!br->br_whbase && !br->br_orph); */ -+ skip = (!wbr || !wbr->wbr_whbase); -+ if (skip && wbr) { -+ if (do_plink) -+ skip = !!wbr->wbr_plink; -+ else -+ skip = !wbr->wbr_plink; -+ } -+ } else { -+ /* skip = (br->br_whbase && br->br_ohph); */ -+ skip = (wbr && wbr->wbr_whbase); -+ if (skip) { -+ if (do_plink) -+ skip = !!wbr->wbr_plink; -+ else -+ skip = !wbr->wbr_plink; -+ } -+ } -+ if (wbr) -+ wbr_wh_read_unlock(wbr); -+ -+ if (can_no_dreval) { -+ dentry = br->br_path.dentry; -+ spin_lock(&dentry->d_lock); -+ if (dentry->d_flags & -+ (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE)) -+ can_no_dreval = 0; -+ spin_unlock(&dentry->d_lock); -+ } -+ -+ if (au_br_fhsm(br->br_perm)) { -+ fhsm++; -+ AuDebugOn(!br->br_fhsm); -+ } -+ -+ if (skip) -+ continue; -+ -+ hdir = au_hi(dir, bindex); -+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT); -+ if (wbr) -+ wbr_wh_write_lock(wbr); -+ err = au_wh_init(br, sb); -+ if (wbr) -+ wbr_wh_write_unlock(wbr); -+ au_hn_inode_unlock(hdir); -+ -+ if (!err && do_free) { -+ kfree(wbr); -+ br->br_wbr = NULL; -+ } -+ } -+ -+ if (can_no_dreval) -+ au_fset_si(sbinfo, NO_DREVAL); -+ else -+ au_fclr_si(sbinfo, NO_DREVAL); -+ -+ if (fhsm >= 2) { -+ au_fset_si(sbinfo, FHSM); -+ for (bindex = bbot; bindex >= 0; bindex--) { -+ br = au_sbr(sb, bindex); -+ if (au_br_fhsm(br->br_perm)) { -+ au_fhsm_set_bottom(sb, bindex); -+ break; -+ } -+ } -+ } else { -+ au_fclr_si(sbinfo, FHSM); -+ au_fhsm_set_bottom(sb, -1); -+ } -+ -+ return err; -+} -+ -+int au_opts_mount(struct super_block *sb, struct au_opts *opts) -+{ -+ int err; -+ unsigned int tmp; -+ aufs_bindex_t bindex, bbot; -+ struct au_opt *opt; -+ struct au_opt_xino *opt_xino, xino; -+ struct au_sbinfo *sbinfo; -+ struct au_branch *br; -+ struct inode *dir; -+ -+ SiMustWriteLock(sb); -+ -+ err = 0; -+ opt_xino = NULL; -+ opt = opts->opt; -+ while (err >= 0 && opt->type != Opt_tail) -+ err = au_opt_simple(sb, opt++, opts); -+ if (err > 0) -+ err = 0; -+ else if (unlikely(err < 0)) -+ goto out; -+ -+ /* disable xino and udba temporary */ -+ sbinfo = au_sbi(sb); -+ tmp = sbinfo->si_mntflags; -+ au_opt_clr(sbinfo->si_mntflags, XINO); -+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL); -+ -+ opt = opts->opt; -+ while (err >= 0 && opt->type != Opt_tail) -+ err = au_opt_br(sb, opt++, opts); -+ if (err > 0) -+ err = 0; -+ else if (unlikely(err < 0)) -+ goto out; -+ -+ bbot = au_sbbot(sb); -+ if (unlikely(bbot < 0)) { -+ err = -EINVAL; -+ pr_err("no branches\n"); -+ goto out; -+ } -+ -+ if (au_opt_test(tmp, XINO)) -+ au_opt_set(sbinfo->si_mntflags, XINO); -+ opt = opts->opt; -+ while (!err && opt->type != Opt_tail) -+ err = au_opt_xino(sb, opt++, &opt_xino, opts); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_opts_verify(sb, sb->s_flags, tmp); -+ if (unlikely(err)) -+ goto out; -+ -+ /* restore xino */ -+ if (au_opt_test(tmp, XINO) && !opt_xino) { -+ xino.file = au_xino_def(sb); -+ err = PTR_ERR(xino.file); -+ if (IS_ERR(xino.file)) -+ goto out; -+ -+ err = au_xino_set(sb, &xino, /*remount*/0); -+ fput(xino.file); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ /* restore udba */ -+ tmp &= AuOptMask_UDBA; -+ sbinfo->si_mntflags &= ~AuOptMask_UDBA; -+ sbinfo->si_mntflags |= tmp; -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ err = au_hnotify_reset_br(tmp, br, br->br_perm); -+ if (unlikely(err)) -+ AuIOErr("hnotify failed on br %d, %d, ignored\n", -+ bindex, err); -+ /* go on even if err */ -+ } -+ if (au_opt_test(tmp, UDBA_HNOTIFY)) { -+ dir = d_inode(sb->s_root); -+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO); -+ } -+ -+out: -+ return err; -+} -+ -+int au_opts_remount(struct super_block *sb, struct au_opts *opts) -+{ -+ int err, rerr; -+ unsigned char no_dreval; -+ struct inode *dir; -+ struct au_opt_xino *opt_xino; -+ struct au_opt *opt; -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ err = au_dr_opt_flush(sb); -+ if (unlikely(err)) -+ goto out; -+ au_fset_opts(opts->flags, DR_FLUSHED); -+ -+ dir = d_inode(sb->s_root); -+ sbinfo = au_sbi(sb); -+ opt_xino = NULL; -+ opt = opts->opt; -+ while (err >= 0 && opt->type != Opt_tail) { -+ err = au_opt_simple(sb, opt, opts); -+ if (!err) -+ err = au_opt_br(sb, opt, opts); -+ if (!err) -+ err = au_opt_xino(sb, opt, &opt_xino, opts); -+ opt++; -+ } -+ if (err > 0) -+ err = 0; -+ AuTraceErr(err); -+ /* go on even err */ -+ -+ no_dreval = !!au_ftest_si(sbinfo, NO_DREVAL); -+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0); -+ if (unlikely(rerr && !err)) -+ err = rerr; -+ -+ if (no_dreval != !!au_ftest_si(sbinfo, NO_DREVAL)) -+ au_fset_opts(opts->flags, REFRESH_IDOP); -+ -+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) { -+ rerr = au_xib_trunc(sb); -+ if (unlikely(rerr && !err)) -+ err = rerr; -+ } -+ -+ /* will be handled by the caller */ -+ if (!au_ftest_opts(opts->flags, REFRESH) -+ && (opts->given_udba -+ || au_opt_test(sbinfo->si_mntflags, XINO) -+ || au_ftest_opts(opts->flags, REFRESH_IDOP) -+ )) -+ au_fset_opts(opts->flags, REFRESH); -+ -+ AuDbg("status 0x%x\n", opts->flags); -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+unsigned int au_opt_udba(struct super_block *sb) -+{ -+ return au_mntflags(sb) & AuOptMask_UDBA; -+} -diff --git a/fs/aufs/opts.h b/fs/aufs/opts.h -new file mode 100644 -index 000000000..fd167bd0f ---- /dev/null -+++ b/fs/aufs/opts.h -@@ -0,0 +1,225 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * mount options/flags -+ */ -+ -+#ifndef __AUFS_OPTS_H__ -+#define __AUFS_OPTS_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+struct file; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* mount flags */ -+#define AuOpt_XINO 1 /* external inode number bitmap -+ and translation table */ -+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */ -+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */ -+#define AuOpt_UDBA_REVAL (1 << 3) -+#define AuOpt_UDBA_HNOTIFY (1 << 4) -+#define AuOpt_SHWH (1 << 5) /* show whiteout */ -+#define AuOpt_PLINK (1 << 6) /* pseudo-link */ -+#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm -+ bits */ -+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */ -+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */ -+#define AuOpt_SUM_W (1 << 11) /* unimplemented */ -+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */ -+#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */ -+#define AuOpt_DIO (1 << 14) /* direct io */ -+#define AuOpt_DIRREN (1 << 15) /* directory rename */ -+ -+#ifndef CONFIG_AUFS_HNOTIFY -+#undef AuOpt_UDBA_HNOTIFY -+#define AuOpt_UDBA_HNOTIFY 0 -+#endif -+#ifndef CONFIG_AUFS_DIRREN -+#undef AuOpt_DIRREN -+#define AuOpt_DIRREN 0 -+#endif -+#ifndef CONFIG_AUFS_SHWH -+#undef AuOpt_SHWH -+#define AuOpt_SHWH 0 -+#endif -+ -+#define AuOpt_Def (AuOpt_XINO \ -+ | AuOpt_UDBA_REVAL \ -+ | AuOpt_PLINK \ -+ /* | AuOpt_DIRPERM1 */ \ -+ | AuOpt_WARN_PERM) -+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \ -+ | AuOpt_UDBA_REVAL \ -+ | AuOpt_UDBA_HNOTIFY) -+ -+#define au_opt_test(flags, name) (flags & AuOpt_##name) -+#define au_opt_set(flags, name) do { \ -+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \ -+ ((flags) |= AuOpt_##name); \ -+} while (0) -+#define au_opt_set_udba(flags, name) do { \ -+ (flags) &= ~AuOptMask_UDBA; \ -+ ((flags) |= AuOpt_##name); \ -+} while (0) -+#define au_opt_clr(flags, name) do { \ -+ ((flags) &= ~AuOpt_##name); \ -+} while (0) -+ -+static inline unsigned int au_opts_plink(unsigned int mntflags) -+{ -+#ifdef CONFIG_PROC_FS -+ return mntflags; -+#else -+ return mntflags & ~AuOpt_PLINK; -+#endif -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* policies to select one among multiple writable branches */ -+enum { -+ AuWbrCreate_TDP, /* top down parent */ -+ AuWbrCreate_RR, /* round robin */ -+ AuWbrCreate_MFS, /* most free space */ -+ AuWbrCreate_MFSV, /* mfs with seconds */ -+ AuWbrCreate_MFSRR, /* mfs then rr */ -+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */ -+ AuWbrCreate_TDMFS, /* top down regardless parent and mfs */ -+ AuWbrCreate_TDMFSV, /* top down regardless parent and mfs */ -+ AuWbrCreate_PMFS, /* parent and mfs */ -+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */ -+ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */ -+ AuWbrCreate_PMFSRRV, /* plus seconds */ -+ -+ AuWbrCreate_Def = AuWbrCreate_TDP -+}; -+ -+enum { -+ AuWbrCopyup_TDP, /* top down parent */ -+ AuWbrCopyup_BUP, /* bottom up parent */ -+ AuWbrCopyup_BU, /* bottom up */ -+ -+ AuWbrCopyup_Def = AuWbrCopyup_TDP -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_opt_add { -+ aufs_bindex_t bindex; -+ char *pathname; -+ int perm; -+ struct path path; -+}; -+ -+struct au_opt_del { -+ char *pathname; -+ struct path h_path; -+}; -+ -+struct au_opt_mod { -+ char *path; -+ int perm; -+ struct dentry *h_root; -+}; -+ -+struct au_opt_xino { -+ char *path; -+ struct file *file; -+}; -+ -+struct au_opt_xino_itrunc { -+ aufs_bindex_t bindex; -+}; -+ -+struct au_opt_wbr_create { -+ int wbr_create; -+ int mfs_second; -+ unsigned long long mfsrr_watermark; -+}; -+ -+struct au_opt { -+ int type; -+ union { -+ struct au_opt_xino xino; -+ struct au_opt_xino_itrunc xino_itrunc; -+ struct au_opt_add add; -+ struct au_opt_del del; -+ struct au_opt_mod mod; -+ int dirwh; -+ int rdcache; -+ unsigned int rdblk; -+ unsigned int rdhash; -+ int udba; -+ struct au_opt_wbr_create wbr_create; -+ int wbr_copyup; -+ unsigned int fhsm_second; -+ }; -+}; -+ -+/* opts flags */ -+#define AuOpts_REMOUNT 1 -+#define AuOpts_REFRESH (1 << 1) -+#define AuOpts_TRUNC_XIB (1 << 2) -+#define AuOpts_REFRESH_DYAOP (1 << 3) -+#define AuOpts_REFRESH_IDOP (1 << 4) -+#define AuOpts_DR_FLUSHED (1 << 5) -+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name) -+#define au_fset_opts(flags, name) \ -+ do { (flags) |= AuOpts_##name; } while (0) -+#define au_fclr_opts(flags, name) \ -+ do { (flags) &= ~AuOpts_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_DIRREN -+#undef AuOpts_DR_FLUSHED -+#define AuOpts_DR_FLUSHED 0 -+#endif -+ -+struct au_opts { -+ struct au_opt *opt; -+ int max_opt; -+ -+ unsigned int given_udba; -+ unsigned int flags; -+ unsigned long sb_flags; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* opts.c */ -+void au_optstr_br_perm(au_br_perm_str_t *str, int perm); -+const char *au_optstr_udba(int udba); -+const char *au_optstr_wbr_copyup(int wbr_copyup); -+const char *au_optstr_wbr_create(int wbr_create); -+ -+void au_opts_free(struct au_opts *opts); -+struct super_block; -+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts); -+int au_opts_verify(struct super_block *sb, unsigned long sb_flags, -+ unsigned int pending); -+int au_opts_mount(struct super_block *sb, struct au_opts *opts); -+int au_opts_remount(struct super_block *sb, struct au_opts *opts); -+ -+unsigned int au_opt_udba(struct super_block *sb); -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_OPTS_H__ */ -diff --git a/fs/aufs/plink.c b/fs/aufs/plink.c -new file mode 100644 -index 000000000..83b80ede3 ---- /dev/null -+++ b/fs/aufs/plink.c -@@ -0,0 +1,516 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * pseudo-link -+ */ -+ -+#include "aufs.h" -+ -+/* -+ * the pseudo-link maintenance mode. -+ * during a user process maintains the pseudo-links, -+ * prohibit adding a new plink and branch manipulation. -+ * -+ * Flags -+ * NOPLM: -+ * For entry functions which will handle plink, and i_mutex is already held -+ * in VFS. -+ * They cannot wait and should return an error at once. -+ * Callers has to check the error. -+ * NOPLMW: -+ * For entry functions which will handle plink, but i_mutex is not held -+ * in VFS. -+ * They can wait the plink maintenance mode to finish. -+ * -+ * They behave like F_SETLK and F_SETLKW. -+ * If the caller never handle plink, then both flags are unnecessary. -+ */ -+ -+int au_plink_maint(struct super_block *sb, int flags) -+{ -+ int err; -+ pid_t pid, ppid; -+ struct task_struct *parent, *prev; -+ struct au_sbinfo *sbi; -+ -+ SiMustAnyLock(sb); -+ -+ err = 0; -+ if (!au_opt_test(au_mntflags(sb), PLINK)) -+ goto out; -+ -+ sbi = au_sbi(sb); -+ pid = sbi->si_plink_maint_pid; -+ if (!pid || pid == current->pid) -+ goto out; -+ -+ /* todo: it highly depends upon /sbin/mount.aufs */ -+ prev = NULL; -+ parent = current; -+ ppid = 0; -+ rcu_read_lock(); -+ while (1) { -+ parent = rcu_dereference(parent->real_parent); -+ if (parent == prev) -+ break; -+ ppid = task_pid_vnr(parent); -+ if (pid == ppid) { -+ rcu_read_unlock(); -+ goto out; -+ } -+ prev = parent; -+ } -+ rcu_read_unlock(); -+ -+ if (au_ftest_lock(flags, NOPLMW)) { -+ /* if there is no i_mutex lock in VFS, we don't need to wait */ -+ /* AuDebugOn(!lockdep_depth(current)); */ -+ while (sbi->si_plink_maint_pid) { -+ si_read_unlock(sb); -+ /* gave up wake_up_bit() */ -+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid); -+ -+ if (au_ftest_lock(flags, FLUSH)) -+ au_nwt_flush(&sbi->si_nowait); -+ si_noflush_read_lock(sb); -+ } -+ } else if (au_ftest_lock(flags, NOPLM)) { -+ AuDbg("ppid %d, pid %d\n", ppid, pid); -+ err = -EAGAIN; -+ } -+ -+out: -+ return err; -+} -+ -+void au_plink_maint_leave(struct au_sbinfo *sbinfo) -+{ -+ spin_lock(&sbinfo->si_plink_maint_lock); -+ sbinfo->si_plink_maint_pid = 0; -+ spin_unlock(&sbinfo->si_plink_maint_lock); -+ wake_up_all(&sbinfo->si_plink_wq); -+} -+ -+int au_plink_maint_enter(struct super_block *sb) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ /* make sure i am the only one in this fs */ -+ si_write_lock(sb, AuLock_FLUSH); -+ if (au_opt_test(au_mntflags(sb), PLINK)) { -+ spin_lock(&sbinfo->si_plink_maint_lock); -+ if (!sbinfo->si_plink_maint_pid) -+ sbinfo->si_plink_maint_pid = current->pid; -+ else -+ err = -EBUSY; -+ spin_unlock(&sbinfo->si_plink_maint_lock); -+ } -+ si_write_unlock(sb); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_DEBUG -+void au_plink_list(struct super_block *sb) -+{ -+ int i; -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ struct au_icntnr *icntnr; -+ -+ SiMustAnyLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); -+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM)); -+ -+ for (i = 0; i < AuPlink_NHASH; i++) { -+ hbl = sbinfo->si_plink + i; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink) -+ AuDbg("%lu\n", icntnr->vfs_inode.i_ino); -+ hlist_bl_unlock(hbl); -+ } -+} -+#endif -+ -+/* is the inode pseudo-linked? */ -+int au_plink_test(struct inode *inode) -+{ -+ int found, i; -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ struct au_icntnr *icntnr; -+ -+ sbinfo = au_sbi(inode->i_sb); -+ AuRwMustAnyLock(&sbinfo->si_rwsem); -+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK)); -+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM)); -+ -+ found = 0; -+ i = au_plink_hash(inode->i_ino); -+ hbl = sbinfo->si_plink + i; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink) -+ if (&icntnr->vfs_inode == inode) { -+ found = 1; -+ break; -+ } -+ hlist_bl_unlock(hbl); -+ return found; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * generate a name for plink. -+ * the file will be stored under AUFS_WH_PLINKDIR. -+ */ -+/* 20 is max digits length of ulong 64 */ -+#define PLINK_NAME_LEN ((20 + 1) * 2) -+ -+static int plink_name(char *name, int len, struct inode *inode, -+ aufs_bindex_t bindex) -+{ -+ int rlen; -+ struct inode *h_inode; -+ -+ h_inode = au_h_iptr(inode, bindex); -+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino); -+ return rlen; -+} -+ -+struct au_do_plink_lkup_args { -+ struct dentry **errp; -+ struct qstr *tgtname; -+ struct dentry *h_parent; -+ struct au_branch *br; -+}; -+ -+static struct dentry *au_do_plink_lkup(struct qstr *tgtname, -+ struct dentry *h_parent, -+ struct au_branch *br) -+{ -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ -+ h_inode = d_inode(h_parent); -+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD2); -+ h_dentry = vfsub_lkup_one(tgtname, h_parent); -+ inode_unlock_shared(h_inode); -+ return h_dentry; -+} -+ -+static void au_call_do_plink_lkup(void *args) -+{ -+ struct au_do_plink_lkup_args *a = args; -+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br); -+} -+ -+/* lookup the plink-ed @inode under the branch at @bindex */ -+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex) -+{ -+ struct dentry *h_dentry, *h_parent; -+ struct au_branch *br; -+ int wkq_err; -+ char a[PLINK_NAME_LEN]; -+ struct qstr tgtname = QSTR_INIT(a, 0); -+ -+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM)); -+ -+ br = au_sbr(inode->i_sb, bindex); -+ h_parent = br->br_wbr->wbr_plink; -+ tgtname.len = plink_name(a, sizeof(a), inode, bindex); -+ -+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) { -+ struct au_do_plink_lkup_args args = { -+ .errp = &h_dentry, -+ .tgtname = &tgtname, -+ .h_parent = h_parent, -+ .br = br -+ }; -+ -+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args); -+ if (unlikely(wkq_err)) -+ h_dentry = ERR_PTR(wkq_err); -+ } else -+ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br); -+ -+ return h_dentry; -+} -+ -+/* create a pseudo-link */ -+static int do_whplink(struct qstr *tgt, struct dentry *h_parent, -+ struct dentry *h_dentry, struct au_branch *br) -+{ -+ int err; -+ struct path h_path = { -+ .mnt = au_br_mnt(br) -+ }; -+ struct inode *h_dir, *delegated; -+ -+ h_dir = d_inode(h_parent); -+ inode_lock_nested(h_dir, AuLsc_I_CHILD2); -+again: -+ h_path.dentry = vfsub_lkup_one(tgt, h_parent); -+ err = PTR_ERR(h_path.dentry); -+ if (IS_ERR(h_path.dentry)) -+ goto out; -+ -+ err = 0; -+ /* wh.plink dir is not monitored */ -+ /* todo: is it really safe? */ -+ if (d_is_positive(h_path.dentry) -+ && d_inode(h_path.dentry) != d_inode(h_dentry)) { -+ delegated = NULL; -+ err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ dput(h_path.dentry); -+ h_path.dentry = NULL; -+ if (!err) -+ goto again; -+ } -+ if (!err && d_is_negative(h_path.dentry)) { -+ delegated = NULL; -+ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ } -+ dput(h_path.dentry); -+ -+out: -+ inode_unlock(h_dir); -+ return err; -+} -+ -+struct do_whplink_args { -+ int *errp; -+ struct qstr *tgt; -+ struct dentry *h_parent; -+ struct dentry *h_dentry; -+ struct au_branch *br; -+}; -+ -+static void call_do_whplink(void *args) -+{ -+ struct do_whplink_args *a = args; -+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br); -+} -+ -+static int whplink(struct dentry *h_dentry, struct inode *inode, -+ aufs_bindex_t bindex, struct au_branch *br) -+{ -+ int err, wkq_err; -+ struct au_wbr *wbr; -+ struct dentry *h_parent; -+ char a[PLINK_NAME_LEN]; -+ struct qstr tgtname = QSTR_INIT(a, 0); -+ -+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr; -+ h_parent = wbr->wbr_plink; -+ tgtname.len = plink_name(a, sizeof(a), inode, bindex); -+ -+ /* always superio. */ -+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) { -+ struct do_whplink_args args = { -+ .errp = &err, -+ .tgt = &tgtname, -+ .h_parent = h_parent, -+ .h_dentry = h_dentry, -+ .br = br -+ }; -+ wkq_err = au_wkq_wait(call_do_whplink, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } else -+ err = do_whplink(&tgtname, h_parent, h_dentry, br); -+ -+ return err; -+} -+ -+/* -+ * create a new pseudo-link for @h_dentry on @bindex. -+ * the linked inode is held in aufs @inode. -+ */ -+void au_plink_append(struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_dentry) -+{ -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ struct au_icntnr *icntnr; -+ int found, err, cnt, i; -+ -+ sb = inode->i_sb; -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); -+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM)); -+ -+ found = au_plink_test(inode); -+ if (found) -+ return; -+ -+ i = au_plink_hash(inode->i_ino); -+ hbl = sbinfo->si_plink + i; -+ au_igrab(inode); -+ -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink) { -+ if (&icntnr->vfs_inode == inode) { -+ found = 1; -+ break; -+ } -+ } -+ if (!found) { -+ icntnr = container_of(inode, struct au_icntnr, vfs_inode); -+ hlist_bl_add_head(&icntnr->plink, hbl); -+ } -+ hlist_bl_unlock(hbl); -+ if (!found) { -+ cnt = au_hbl_count(hbl); -+#define msg "unexpectedly unbalanced or too many pseudo-links" -+ if (cnt > AUFS_PLINK_WARN) -+ AuWarn1(msg ", %d\n", cnt); -+#undef msg -+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex)); -+ if (unlikely(err)) { -+ pr_warn("err %d, damaged pseudo link.\n", err); -+ au_hbl_del(&icntnr->plink, hbl); -+ iput(&icntnr->vfs_inode); -+ } -+ } else -+ iput(&icntnr->vfs_inode); -+} -+ -+/* free all plinks */ -+void au_plink_put(struct super_block *sb, int verbose) -+{ -+ int i, warned; -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos, *tmp; -+ struct au_icntnr *icntnr; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); -+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM)); -+ -+ /* no spin_lock since sbinfo is write-locked */ -+ warned = 0; -+ for (i = 0; i < AuPlink_NHASH; i++) { -+ hbl = sbinfo->si_plink + i; -+ if (!warned && verbose && !hlist_bl_empty(hbl)) { -+ pr_warn("pseudo-link is not flushed"); -+ warned = 1; -+ } -+ hlist_bl_for_each_entry_safe(icntnr, pos, tmp, hbl, plink) -+ iput(&icntnr->vfs_inode); -+ INIT_HLIST_BL_HEAD(hbl); -+ } -+} -+ -+void au_plink_clean(struct super_block *sb, int verbose) -+{ -+ struct dentry *root; -+ -+ root = sb->s_root; -+ aufs_write_lock(root); -+ if (au_opt_test(au_mntflags(sb), PLINK)) -+ au_plink_put(sb, verbose); -+ aufs_write_unlock(root); -+} -+ -+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id) -+{ -+ int do_put; -+ aufs_bindex_t btop, bbot, bindex; -+ -+ do_put = 0; -+ btop = au_ibtop(inode); -+ bbot = au_ibbot(inode); -+ if (btop >= 0) { -+ for (bindex = btop; bindex <= bbot; bindex++) { -+ if (!au_h_iptr(inode, bindex) -+ || au_ii_br_id(inode, bindex) != br_id) -+ continue; -+ au_set_h_iptr(inode, bindex, NULL, 0); -+ do_put = 1; -+ break; -+ } -+ if (do_put) -+ for (bindex = btop; bindex <= bbot; bindex++) -+ if (au_h_iptr(inode, bindex)) { -+ do_put = 0; -+ break; -+ } -+ } else -+ do_put = 1; -+ -+ return do_put; -+} -+ -+/* free the plinks on a branch specified by @br_id */ -+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id) -+{ -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos, *tmp; -+ struct au_icntnr *icntnr; -+ struct inode *inode; -+ int i, do_put; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); -+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM)); -+ -+ /* no bit_lock since sbinfo is write-locked */ -+ for (i = 0; i < AuPlink_NHASH; i++) { -+ hbl = sbinfo->si_plink + i; -+ hlist_bl_for_each_entry_safe(icntnr, pos, tmp, hbl, plink) { -+ inode = au_igrab(&icntnr->vfs_inode); -+ ii_write_lock_child(inode); -+ do_put = au_plink_do_half_refresh(inode, br_id); -+ if (do_put) { -+ hlist_bl_del(&icntnr->plink); -+ iput(inode); -+ } -+ ii_write_unlock(inode); -+ iput(inode); -+ } -+ } -+} -diff --git a/fs/aufs/poll.c b/fs/aufs/poll.c -new file mode 100644 -index 000000000..a653b6c74 ---- /dev/null -+++ b/fs/aufs/poll.c -@@ -0,0 +1,51 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * poll operation -+ * There is only one filesystem which implements ->poll operation, currently. -+ */ -+ -+#include "aufs.h" -+ -+__poll_t aufs_poll(struct file *file, struct poll_table_struct *pt) -+{ -+ __poll_t mask; -+ struct file *h_file; -+ struct super_block *sb; -+ -+ /* We should pretend an error happened. */ -+ mask = EPOLLERR /* | EPOLLIN | EPOLLOUT */; -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0); -+ if (IS_ERR(h_file)) { -+ AuDbg("h_file %ld\n", PTR_ERR(h_file)); -+ goto out; -+ } -+ -+ mask = vfs_poll(h_file, pt); -+ fput(h_file); /* instead of au_read_post() */ -+ -+out: -+ si_read_unlock(sb); -+ if (mask & EPOLLERR) -+ AuDbg("mask 0x%x\n", mask); -+ return mask; -+} -diff --git a/fs/aufs/posix_acl.c b/fs/aufs/posix_acl.c -new file mode 100644 -index 000000000..9ce21ec98 ---- /dev/null -+++ b/fs/aufs/posix_acl.c -@@ -0,0 +1,103 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2014-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * posix acl operations -+ */ -+ -+#include -+#include "aufs.h" -+ -+struct posix_acl *aufs_get_acl(struct inode *inode, int type) -+{ -+ struct posix_acl *acl; -+ int err; -+ aufs_bindex_t bindex; -+ struct inode *h_inode; -+ struct super_block *sb; -+ -+ acl = NULL; -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ ii_read_lock_child(inode); -+ if (!(sb->s_flags & SB_POSIXACL)) -+ goto out; -+ -+ bindex = au_ibtop(inode); -+ h_inode = au_h_iptr(inode, bindex); -+ if (unlikely(!h_inode -+ || ((h_inode->i_mode & S_IFMT) -+ != (inode->i_mode & S_IFMT)))) { -+ err = au_busy_or_stale(); -+ acl = ERR_PTR(err); -+ goto out; -+ } -+ -+ /* always topmost only */ -+ acl = get_acl(h_inode, type); -+ if (!IS_ERR_OR_NULL(acl)) -+ set_cached_acl(inode, type, acl); -+ -+out: -+ ii_read_unlock(inode); -+ si_read_unlock(sb); -+ -+ AuTraceErrPtr(acl); -+ return acl; -+} -+ -+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type) -+{ -+ int err; -+ ssize_t ssz; -+ struct dentry *dentry; -+ struct au_sxattr arg = { -+ .type = AU_ACL_SET, -+ .u.acl_set = { -+ .acl = acl, -+ .type = type -+ }, -+ }; -+ -+ IMustLock(inode); -+ -+ if (inode->i_ino == AUFS_ROOT_INO) -+ dentry = dget(inode->i_sb->s_root); -+ else { -+ dentry = d_find_alias(inode); -+ if (!dentry) -+ dentry = d_find_any_alias(inode); -+ if (!dentry) { -+ pr_warn("cannot handle this inode, " -+ "please report to aufs-users ML\n"); -+ err = -ENOENT; -+ goto out; -+ } -+ } -+ -+ ssz = au_sxattr(dentry, inode, &arg); -+ dput(dentry); -+ err = ssz; -+ if (ssz >= 0) { -+ err = 0; -+ set_cached_acl(inode, type, acl); -+ } -+ -+out: -+ return err; -+} -diff --git a/fs/aufs/procfs.c b/fs/aufs/procfs.c -new file mode 100644 -index 000000000..100dbcfeb ---- /dev/null -+++ b/fs/aufs/procfs.c -@@ -0,0 +1,171 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2010-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * procfs interfaces -+ */ -+ -+#include -+#include "aufs.h" -+ -+static int au_procfs_plm_release(struct inode *inode, struct file *file) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ sbinfo = file->private_data; -+ if (sbinfo) { -+ au_plink_maint_leave(sbinfo); -+ kobject_put(&sbinfo->si_kobj); -+ } -+ -+ return 0; -+} -+ -+static void au_procfs_plm_write_clean(struct file *file) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ sbinfo = file->private_data; -+ if (sbinfo) -+ au_plink_clean(sbinfo->si_sb, /*verbose*/0); -+} -+ -+static int au_procfs_plm_write_si(struct file *file, unsigned long id) -+{ -+ int err; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_node *pos; -+ -+ err = -EBUSY; -+ if (unlikely(file->private_data)) -+ goto out; -+ -+ sb = NULL; -+ /* don't use au_sbilist_lock() here */ -+ hlist_bl_lock(&au_sbilist); -+ hlist_bl_for_each_entry(sbinfo, pos, &au_sbilist, si_list) -+ if (id == sysaufs_si_id(sbinfo)) { -+ kobject_get(&sbinfo->si_kobj); -+ sb = sbinfo->si_sb; -+ break; -+ } -+ hlist_bl_unlock(&au_sbilist); -+ -+ err = -EINVAL; -+ if (unlikely(!sb)) -+ goto out; -+ -+ err = au_plink_maint_enter(sb); -+ if (!err) -+ /* keep kobject_get() */ -+ file->private_data = sbinfo; -+ else -+ kobject_put(&sbinfo->si_kobj); -+out: -+ return err; -+} -+ -+/* -+ * Accept a valid "si=xxxx" only. -+ * Once it is accepted successfully, accept "clean" too. -+ */ -+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf, -+ size_t count, loff_t *ppos) -+{ -+ ssize_t err; -+ unsigned long id; -+ /* last newline is allowed */ -+ char buf[3 + sizeof(unsigned long) * 2 + 1]; -+ -+ err = -EACCES; -+ if (unlikely(!capable(CAP_SYS_ADMIN))) -+ goto out; -+ -+ err = -EINVAL; -+ if (unlikely(count > sizeof(buf))) -+ goto out; -+ -+ err = copy_from_user(buf, ubuf, count); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ goto out; -+ } -+ buf[count] = 0; -+ -+ err = -EINVAL; -+ if (!strcmp("clean", buf)) { -+ au_procfs_plm_write_clean(file); -+ goto out_success; -+ } else if (unlikely(strncmp("si=", buf, 3))) -+ goto out; -+ -+ err = kstrtoul(buf + 3, 16, &id); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_procfs_plm_write_si(file, id); -+ if (unlikely(err)) -+ goto out; -+ -+out_success: -+ err = count; /* success */ -+out: -+ return err; -+} -+ -+static const struct file_operations au_procfs_plm_fop = { -+ .write = au_procfs_plm_write, -+ .release = au_procfs_plm_release, -+ .owner = THIS_MODULE -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct proc_dir_entry *au_procfs_dir; -+ -+void au_procfs_fin(void) -+{ -+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir); -+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL); -+} -+ -+int __init au_procfs_init(void) -+{ -+ int err; -+ struct proc_dir_entry *entry; -+ -+ err = -ENOMEM; -+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL); -+ if (unlikely(!au_procfs_dir)) -+ goto out; -+ -+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | 0200, -+ au_procfs_dir, &au_procfs_plm_fop); -+ if (unlikely(!entry)) -+ goto out_dir; -+ -+ err = 0; -+ goto out; /* success */ -+ -+ -+out_dir: -+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL); -+out: -+ return err; -+} -diff --git a/fs/aufs/rdu.c b/fs/aufs/rdu.c -new file mode 100644 -index 000000000..60f4957b7 ---- /dev/null -+++ b/fs/aufs/rdu.c -@@ -0,0 +1,382 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * readdir in userspace. -+ */ -+ -+#include -+#include -+#include -+#include "aufs.h" -+ -+/* bits for struct aufs_rdu.flags */ -+#define AuRdu_CALLED 1 -+#define AuRdu_CONT (1 << 1) -+#define AuRdu_FULL (1 << 2) -+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name) -+#define au_fset_rdu(flags, name) \ -+ do { (flags) |= AuRdu_##name; } while (0) -+#define au_fclr_rdu(flags, name) \ -+ do { (flags) &= ~AuRdu_##name; } while (0) -+ -+struct au_rdu_arg { -+ struct dir_context ctx; -+ struct aufs_rdu *rdu; -+ union au_rdu_ent_ul ent; -+ unsigned long end; -+ -+ struct super_block *sb; -+ int err; -+}; -+ -+static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen, -+ loff_t offset, u64 h_ino, unsigned int d_type) -+{ -+ int err, len; -+ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx); -+ struct aufs_rdu *rdu = arg->rdu; -+ struct au_rdu_ent ent; -+ -+ err = 0; -+ arg->err = 0; -+ au_fset_rdu(rdu->cookie.flags, CALLED); -+ len = au_rdu_len(nlen); -+ if (arg->ent.ul + len < arg->end) { -+ ent.ino = h_ino; -+ ent.bindex = rdu->cookie.bindex; -+ ent.type = d_type; -+ ent.nlen = nlen; -+ if (unlikely(nlen > AUFS_MAX_NAMELEN)) -+ ent.type = DT_UNKNOWN; -+ -+ /* unnecessary to support mmap_sem since this is a dir */ -+ err = -EFAULT; -+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent))) -+ goto out; -+ if (copy_to_user(arg->ent.e->name, name, nlen)) -+ goto out; -+ /* the terminating NULL */ -+ if (__put_user(0, arg->ent.e->name + nlen)) -+ goto out; -+ err = 0; -+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */ -+ arg->ent.ul += len; -+ rdu->rent++; -+ } else { -+ err = -EFAULT; -+ au_fset_rdu(rdu->cookie.flags, FULL); -+ rdu->full = 1; -+ rdu->tail = arg->ent; -+ } -+ -+out: -+ /* AuTraceErr(err); */ -+ return err; -+} -+ -+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg) -+{ -+ int err; -+ loff_t offset; -+ struct au_rdu_cookie *cookie = &arg->rdu->cookie; -+ -+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */ -+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET); -+ err = offset; -+ if (unlikely(offset != cookie->h_pos)) -+ goto out; -+ -+ err = 0; -+ do { -+ arg->err = 0; -+ au_fclr_rdu(cookie->flags, CALLED); -+ /* smp_mb(); */ -+ err = vfsub_iterate_dir(h_file, &arg->ctx); -+ if (err >= 0) -+ err = arg->err; -+ } while (!err -+ && au_ftest_rdu(cookie->flags, CALLED) -+ && !au_ftest_rdu(cookie->flags, FULL)); -+ cookie->h_pos = h_file->f_pos; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_rdu(struct file *file, struct aufs_rdu *rdu) -+{ -+ int err; -+ aufs_bindex_t bbot; -+ struct au_rdu_arg arg = { -+ .ctx = { -+ .actor = au_rdu_fill -+ } -+ }; -+ struct dentry *dentry; -+ struct inode *inode; -+ struct file *h_file; -+ struct au_rdu_cookie *cookie = &rdu->cookie; -+ -+ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ goto out; -+ } -+ rdu->rent = 0; -+ rdu->tail = rdu->ent; -+ rdu->full = 0; -+ arg.rdu = rdu; -+ arg.ent = rdu->ent; -+ arg.end = arg.ent.ul; -+ arg.end += rdu->sz; -+ -+ err = -ENOTDIR; -+ if (unlikely(!file->f_op->iterate && !file->f_op->iterate_shared)) -+ goto out; -+ -+ err = security_file_permission(file, MAY_READ); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out; -+ -+ dentry = file->f_path.dentry; -+ inode = d_inode(dentry); -+ inode_lock_shared(inode); -+ -+ arg.sb = inode->i_sb; -+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out_mtx; -+ err = au_alive_dir(dentry); -+ if (unlikely(err)) -+ goto out_si; -+ /* todo: reval? */ -+ fi_read_lock(file); -+ -+ err = -EAGAIN; -+ if (unlikely(au_ftest_rdu(cookie->flags, CONT) -+ && cookie->generation != au_figen(file))) -+ goto out_unlock; -+ -+ err = 0; -+ if (!rdu->blk) { -+ rdu->blk = au_sbi(arg.sb)->si_rdblk; -+ if (!rdu->blk) -+ rdu->blk = au_dir_size(file, /*dentry*/NULL); -+ } -+ bbot = au_fbtop(file); -+ if (cookie->bindex < bbot) -+ cookie->bindex = bbot; -+ bbot = au_fbbot_dir(file); -+ /* AuDbg("b%d, b%d\n", cookie->bindex, bbot); */ -+ for (; !err && cookie->bindex <= bbot; -+ cookie->bindex++, cookie->h_pos = 0) { -+ h_file = au_hf_dir(file, cookie->bindex); -+ if (!h_file) -+ continue; -+ -+ au_fclr_rdu(cookie->flags, FULL); -+ err = au_rdu_do(h_file, &arg); -+ AuTraceErr(err); -+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err)) -+ break; -+ } -+ AuDbg("rent %llu\n", rdu->rent); -+ -+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) { -+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH); -+ au_fset_rdu(cookie->flags, CONT); -+ cookie->generation = au_figen(file); -+ } -+ -+ ii_read_lock_child(inode); -+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibtop(inode))); -+ ii_read_unlock(inode); -+ -+out_unlock: -+ fi_read_unlock(file); -+out_si: -+ si_read_unlock(arg.sb); -+out_mtx: -+ inode_unlock_shared(inode); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu) -+{ -+ int err; -+ ino_t ino; -+ unsigned long long nent; -+ union au_rdu_ent_ul *u; -+ struct au_rdu_ent ent; -+ struct super_block *sb; -+ -+ err = 0; -+ nent = rdu->nent; -+ u = &rdu->ent; -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ while (nent-- > 0) { -+ /* unnecessary to support mmap_sem since this is a dir */ -+ err = copy_from_user(&ent, u->e, sizeof(ent)); -+ if (!err) -+ err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ break; -+ } -+ -+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */ -+ if (!ent.wh) -+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino); -+ else -+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type, -+ &ino); -+ if (unlikely(err)) { -+ AuTraceErr(err); -+ break; -+ } -+ -+ err = __put_user(ino, &u->e->ino); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ break; -+ } -+ u->ul += au_rdu_len(ent.nlen); -+ } -+ si_read_unlock(sb); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_rdu_verify(struct aufs_rdu *rdu) -+{ -+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | " -+ "%llu, b%d, 0x%x, g%u}\n", -+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ], -+ rdu->blk, -+ rdu->rent, rdu->shwh, rdu->full, -+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags, -+ rdu->cookie.generation); -+ -+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu)) -+ return 0; -+ -+ AuDbg("%u:%u\n", -+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu)); -+ return -EINVAL; -+} -+ -+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long err, e; -+ struct aufs_rdu rdu; -+ void __user *p = (void __user *)arg; -+ -+ err = copy_from_user(&rdu, p, sizeof(rdu)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ goto out; -+ } -+ err = au_rdu_verify(&rdu); -+ if (unlikely(err)) -+ goto out; -+ -+ switch (cmd) { -+ case AUFS_CTL_RDU: -+ err = au_rdu(file, &rdu); -+ if (unlikely(err)) -+ break; -+ -+ e = copy_to_user(p, &rdu, sizeof(rdu)); -+ if (unlikely(e)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ } -+ break; -+ case AUFS_CTL_RDU_INO: -+ err = au_rdu_ino(file, &rdu); -+ break; -+ -+ default: -+ /* err = -ENOTTY; */ -+ err = -EINVAL; -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+#ifdef CONFIG_COMPAT -+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long err, e; -+ struct aufs_rdu rdu; -+ void __user *p = compat_ptr(arg); -+ -+ /* todo: get_user()? */ -+ err = copy_from_user(&rdu, p, sizeof(rdu)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ goto out; -+ } -+ rdu.ent.e = compat_ptr(rdu.ent.ul); -+ err = au_rdu_verify(&rdu); -+ if (unlikely(err)) -+ goto out; -+ -+ switch (cmd) { -+ case AUFS_CTL_RDU: -+ err = au_rdu(file, &rdu); -+ if (unlikely(err)) -+ break; -+ -+ rdu.ent.ul = ptr_to_compat(rdu.ent.e); -+ rdu.tail.ul = ptr_to_compat(rdu.tail.e); -+ e = copy_to_user(p, &rdu, sizeof(rdu)); -+ if (unlikely(e)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ } -+ break; -+ case AUFS_CTL_RDU_INO: -+ err = au_rdu_ino(file, &rdu); -+ break; -+ -+ default: -+ /* err = -ENOTTY; */ -+ err = -EINVAL; -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+#endif -diff --git a/fs/aufs/rwsem.h b/fs/aufs/rwsem.h -new file mode 100644 -index 000000000..bcb538eed ---- /dev/null -+++ b/fs/aufs/rwsem.h -@@ -0,0 +1,73 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * simple read-write semaphore wrappers -+ */ -+ -+#ifndef __AUFS_RWSEM_H__ -+#define __AUFS_RWSEM_H__ -+ -+#ifdef __KERNEL__ -+ -+#include "debug.h" -+ -+/* in the future, the name 'au_rwsem' will be totally gone */ -+#define au_rwsem rw_semaphore -+ -+/* to debug easier, do not make them inlined functions */ -+#define AuRwMustNoWaiters(rw) AuDebugOn(rwsem_is_contended(rw)) -+/* rwsem_is_locked() is unusable */ -+#define AuRwMustReadLock(rw) AuDebugOn(!lockdep_recursing(current) \ -+ && debug_locks \ -+ && !lockdep_is_held_type(rw, 1)) -+#define AuRwMustWriteLock(rw) AuDebugOn(!lockdep_recursing(current) \ -+ && debug_locks \ -+ && !lockdep_is_held_type(rw, 0)) -+#define AuRwMustAnyLock(rw) AuDebugOn(!lockdep_recursing(current) \ -+ && debug_locks \ -+ && !lockdep_is_held(rw)) -+#define AuRwDestroy(rw) AuDebugOn(!lockdep_recursing(current) \ -+ && debug_locks \ -+ && lockdep_is_held(rw)) -+ -+#define au_rw_init(rw) init_rwsem(rw) -+ -+#define au_rw_init_wlock(rw) do { \ -+ au_rw_init(rw); \ -+ down_write(rw); \ -+ } while (0) -+ -+#define au_rw_init_wlock_nested(rw, lsc) do { \ -+ au_rw_init(rw); \ -+ down_write_nested(rw, lsc); \ -+ } while (0) -+ -+#define au_rw_read_lock(rw) down_read(rw) -+#define au_rw_read_lock_nested(rw, lsc) down_read_nested(rw, lsc) -+#define au_rw_read_unlock(rw) up_read(rw) -+#define au_rw_dgrade_lock(rw) downgrade_write(rw) -+#define au_rw_write_lock(rw) down_write(rw) -+#define au_rw_write_lock_nested(rw, lsc) down_write_nested(rw, lsc) -+#define au_rw_write_unlock(rw) up_write(rw) -+/* why is not _nested version defined? */ -+#define au_rw_read_trylock(rw) down_read_trylock(rw) -+#define au_rw_write_trylock(rw) down_write_trylock(rw) -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_RWSEM_H__ */ -diff --git a/fs/aufs/sbinfo.c b/fs/aufs/sbinfo.c -new file mode 100644 -index 000000000..a013c7517 ---- /dev/null -+++ b/fs/aufs/sbinfo.c -@@ -0,0 +1,313 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * superblock private data -+ */ -+ -+#include "aufs.h" -+ -+/* -+ * they are necessary regardless sysfs is disabled. -+ */ -+void au_si_free(struct kobject *kobj) -+{ -+ int i; -+ struct au_sbinfo *sbinfo; -+ char *locked __maybe_unused; /* debug only */ -+ -+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); -+ for (i = 0; i < AuPlink_NHASH; i++) -+ AuDebugOn(!hlist_bl_empty(sbinfo->si_plink + i)); -+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len)); -+ -+ AuLCntZero(au_lcnt_read(&sbinfo->si_ninodes, /*do_rev*/0)); -+ au_lcnt_fin(&sbinfo->si_ninodes, /*do_sync*/0); -+ AuLCntZero(au_lcnt_read(&sbinfo->si_nfiles, /*do_rev*/0)); -+ au_lcnt_fin(&sbinfo->si_nfiles, /*do_sync*/0); -+ -+ dbgaufs_si_fin(sbinfo); -+ au_rw_write_lock(&sbinfo->si_rwsem); -+ au_br_free(sbinfo); -+ au_rw_write_unlock(&sbinfo->si_rwsem); -+ -+ kfree(sbinfo->si_branch); -+ mutex_destroy(&sbinfo->si_xib_mtx); -+ AuRwDestroy(&sbinfo->si_rwsem); -+ -+ au_lcnt_wait_for_fin(&sbinfo->si_ninodes); -+ /* si_nfiles is waited too */ -+ kfree(sbinfo); -+} -+ -+int au_si_alloc(struct super_block *sb) -+{ -+ int err, i; -+ struct au_sbinfo *sbinfo; -+ -+ err = -ENOMEM; -+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS); -+ if (unlikely(!sbinfo)) -+ goto out; -+ -+ /* will be reallocated separately */ -+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS); -+ if (unlikely(!sbinfo->si_branch)) -+ goto out_sbinfo; -+ -+ err = sysaufs_si_init(sbinfo); -+ if (!err) { -+ dbgaufs_si_null(sbinfo); -+ err = dbgaufs_si_init(sbinfo); -+ if (unlikely(err)) -+ kobject_put(&sbinfo->si_kobj); -+ } -+ if (unlikely(err)) -+ goto out_br; -+ -+ au_nwt_init(&sbinfo->si_nowait); -+ au_rw_init_wlock(&sbinfo->si_rwsem); -+ -+ au_lcnt_init(&sbinfo->si_ninodes, /*release*/NULL); -+ au_lcnt_init(&sbinfo->si_nfiles, /*release*/NULL); -+ -+ sbinfo->si_bbot = -1; -+ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2; -+ -+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def; -+ sbinfo->si_wbr_create = AuWbrCreate_Def; -+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup; -+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create; -+ -+ au_fhsm_init(sbinfo); -+ -+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def); -+ -+ sbinfo->si_xino_jiffy = jiffies; -+ sbinfo->si_xino_expire -+ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC); -+ mutex_init(&sbinfo->si_xib_mtx); -+ /* leave si_xib_last_pindex and si_xib_next_bit */ -+ -+ INIT_HLIST_BL_HEAD(&sbinfo->si_aopen); -+ -+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC); -+ sbinfo->si_rdblk = AUFS_RDBLK_DEF; -+ sbinfo->si_rdhash = AUFS_RDHASH_DEF; -+ sbinfo->si_dirwh = AUFS_DIRWH_DEF; -+ -+ for (i = 0; i < AuPlink_NHASH; i++) -+ INIT_HLIST_BL_HEAD(sbinfo->si_plink + i); -+ init_waitqueue_head(&sbinfo->si_plink_wq); -+ spin_lock_init(&sbinfo->si_plink_maint_lock); -+ -+ INIT_HLIST_BL_HEAD(&sbinfo->si_files); -+ -+ /* with getattr by default */ -+ sbinfo->si_iop_array = aufs_iop; -+ -+ /* leave other members for sysaufs and si_mnt. */ -+ sbinfo->si_sb = sb; -+ sb->s_fs_info = sbinfo; -+ si_pid_set(sb); -+ return 0; /* success */ -+ -+out_br: -+ kfree(sbinfo->si_branch); -+out_sbinfo: -+ kfree(sbinfo); -+out: -+ return err; -+} -+ -+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink) -+{ -+ int err, sz; -+ struct au_branch **brp; -+ -+ AuRwMustWriteLock(&sbinfo->si_rwsem); -+ -+ err = -ENOMEM; -+ sz = sizeof(*brp) * (sbinfo->si_bbot + 1); -+ if (unlikely(!sz)) -+ sz = sizeof(*brp); -+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS, -+ may_shrink); -+ if (brp) { -+ sbinfo->si_branch = brp; -+ err = 0; -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+unsigned int au_sigen_inc(struct super_block *sb) -+{ -+ unsigned int gen; -+ struct inode *inode; -+ -+ SiMustWriteLock(sb); -+ -+ gen = ++au_sbi(sb)->si_generation; -+ au_update_digen(sb->s_root); -+ inode = d_inode(sb->s_root); -+ au_update_iigen(inode, /*half*/0); -+ inode_inc_iversion(inode); -+ return gen; -+} -+ -+aufs_bindex_t au_new_br_id(struct super_block *sb) -+{ -+ aufs_bindex_t br_id; -+ int i; -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) { -+ br_id = ++sbinfo->si_last_br_id; -+ AuDebugOn(br_id < 0); -+ if (br_id && au_br_index(sb, br_id) < 0) -+ return br_id; -+ } -+ -+ return -1; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* it is ok that new 'nwt' tasks are appended while we are sleeping */ -+int si_read_lock(struct super_block *sb, int flags) -+{ -+ int err; -+ -+ err = 0; -+ if (au_ftest_lock(flags, FLUSH)) -+ au_nwt_flush(&au_sbi(sb)->si_nowait); -+ -+ si_noflush_read_lock(sb); -+ err = au_plink_maint(sb, flags); -+ if (unlikely(err)) -+ si_read_unlock(sb); -+ -+ return err; -+} -+ -+int si_write_lock(struct super_block *sb, int flags) -+{ -+ int err; -+ -+ if (au_ftest_lock(flags, FLUSH)) -+ au_nwt_flush(&au_sbi(sb)->si_nowait); -+ -+ si_noflush_write_lock(sb); -+ err = au_plink_maint(sb, flags); -+ if (unlikely(err)) -+ si_write_unlock(sb); -+ -+ return err; -+} -+ -+/* dentry and super_block lock. call at entry point */ -+int aufs_read_lock(struct dentry *dentry, int flags) -+{ -+ int err; -+ struct super_block *sb; -+ -+ sb = dentry->d_sb; -+ err = si_read_lock(sb, flags); -+ if (unlikely(err)) -+ goto out; -+ -+ if (au_ftest_lock(flags, DW)) -+ di_write_lock_child(dentry); -+ else -+ di_read_lock_child(dentry, flags); -+ -+ if (au_ftest_lock(flags, GEN)) { -+ err = au_digen_test(dentry, au_sigen(sb)); -+ if (!au_opt_test(au_mntflags(sb), UDBA_NONE)) -+ AuDebugOn(!err && au_dbrange_test(dentry)); -+ else if (!err) -+ err = au_dbrange_test(dentry); -+ if (unlikely(err)) -+ aufs_read_unlock(dentry, flags); -+ } -+ -+out: -+ return err; -+} -+ -+void aufs_read_unlock(struct dentry *dentry, int flags) -+{ -+ if (au_ftest_lock(flags, DW)) -+ di_write_unlock(dentry); -+ else -+ di_read_unlock(dentry, flags); -+ si_read_unlock(dentry->d_sb); -+} -+ -+void aufs_write_lock(struct dentry *dentry) -+{ -+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW); -+ di_write_lock_child(dentry); -+} -+ -+void aufs_write_unlock(struct dentry *dentry) -+{ -+ di_write_unlock(dentry); -+ si_write_unlock(dentry->d_sb); -+} -+ -+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags) -+{ -+ int err; -+ unsigned int sigen; -+ struct super_block *sb; -+ -+ sb = d1->d_sb; -+ err = si_read_lock(sb, flags); -+ if (unlikely(err)) -+ goto out; -+ -+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIRS)); -+ -+ if (au_ftest_lock(flags, GEN)) { -+ sigen = au_sigen(sb); -+ err = au_digen_test(d1, sigen); -+ AuDebugOn(!err && au_dbrange_test(d1)); -+ if (!err) { -+ err = au_digen_test(d2, sigen); -+ AuDebugOn(!err && au_dbrange_test(d2)); -+ } -+ if (unlikely(err)) -+ aufs_read_and_write_unlock2(d1, d2); -+ } -+ -+out: -+ return err; -+} -+ -+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2) -+{ -+ di_write_unlock2(d1, d2); -+ si_read_unlock(d1->d_sb); -+} -diff --git a/fs/aufs/super.c b/fs/aufs/super.c -new file mode 100644 -index 000000000..a09c846ea ---- /dev/null -+++ b/fs/aufs/super.c -@@ -0,0 +1,1048 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * mount and super_block operations -+ */ -+ -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+/* -+ * super_operations -+ */ -+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused) -+{ -+ struct au_icntnr *c; -+ -+ c = au_cache_alloc_icntnr(); -+ if (c) { -+ au_icntnr_init(c); -+ inode_set_iversion(&c->vfs_inode, 1); /* sigen(sb); */ -+ c->iinfo.ii_hinode = NULL; -+ return &c->vfs_inode; -+ } -+ return NULL; -+} -+ -+static void aufs_destroy_inode_cb(struct rcu_head *head) -+{ -+ struct inode *inode = container_of(head, struct inode, i_rcu); -+ -+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode)); -+} -+ -+static void aufs_destroy_inode(struct inode *inode) -+{ -+ if (!au_is_bad_inode(inode)) -+ au_iinfo_fin(inode); -+ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb); -+} -+ -+struct inode *au_iget_locked(struct super_block *sb, ino_t ino) -+{ -+ struct inode *inode; -+ int err; -+ -+ inode = iget_locked(sb, ino); -+ if (unlikely(!inode)) { -+ inode = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ if (!(inode->i_state & I_NEW)) -+ goto out; -+ -+ err = au_xigen_new(inode); -+ if (!err) -+ err = au_iinfo_init(inode); -+ if (!err) -+ inode_inc_iversion(inode); -+ else { -+ iget_failed(inode); -+ inode = ERR_PTR(err); -+ } -+ -+out: -+ /* never return NULL */ -+ AuDebugOn(!inode); -+ AuTraceErrPtr(inode); -+ return inode; -+} -+ -+/* lock free root dinfo */ -+static int au_show_brs(struct seq_file *seq, struct super_block *sb) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct path path; -+ struct au_hdentry *hdp; -+ struct au_branch *br; -+ au_br_perm_str_t perm; -+ -+ err = 0; -+ bbot = au_sbbot(sb); -+ bindex = 0; -+ hdp = au_hdentry(au_di(sb->s_root), bindex); -+ for (; !err && bindex <= bbot; bindex++, hdp++) { -+ br = au_sbr(sb, bindex); -+ path.mnt = au_br_mnt(br); -+ path.dentry = hdp->hd_dentry; -+ err = au_seq_path(seq, &path); -+ if (!err) { -+ au_optstr_br_perm(&perm, br->br_perm); -+ seq_printf(seq, "=%s", perm.a); -+ if (bindex != bbot) -+ seq_putc(seq, ':'); -+ } -+ } -+ if (unlikely(err || seq_has_overflowed(seq))) -+ err = -E2BIG; -+ -+ return err; -+} -+ -+static void au_gen_fmt(char *fmt, int len __maybe_unused, const char *pat, -+ const char *append) -+{ -+ char *p; -+ -+ p = fmt; -+ while (*pat != ':') -+ *p++ = *pat++; -+ *p++ = *pat++; -+ strcpy(p, append); -+ AuDebugOn(strlen(fmt) >= len); -+} -+ -+static void au_show_wbr_create(struct seq_file *m, int v, -+ struct au_sbinfo *sbinfo) -+{ -+ const char *pat; -+ char fmt[32]; -+ struct au_wbr_mfs *mfs; -+ -+ AuRwMustAnyLock(&sbinfo->si_rwsem); -+ -+ seq_puts(m, ",create="); -+ pat = au_optstr_wbr_create(v); -+ mfs = &sbinfo->si_wbr_mfs; -+ switch (v) { -+ case AuWbrCreate_TDP: -+ case AuWbrCreate_RR: -+ case AuWbrCreate_MFS: -+ case AuWbrCreate_PMFS: -+ seq_puts(m, pat); -+ break; -+ case AuWbrCreate_MFSRR: -+ case AuWbrCreate_TDMFS: -+ case AuWbrCreate_PMFSRR: -+ au_gen_fmt(fmt, sizeof(fmt), pat, "%llu"); -+ seq_printf(m, fmt, mfs->mfsrr_watermark); -+ break; -+ case AuWbrCreate_MFSV: -+ case AuWbrCreate_PMFSV: -+ au_gen_fmt(fmt, sizeof(fmt), pat, "%lu"); -+ seq_printf(m, fmt, -+ jiffies_to_msecs(mfs->mfs_expire) -+ / MSEC_PER_SEC); -+ break; -+ case AuWbrCreate_MFSRRV: -+ case AuWbrCreate_TDMFSV: -+ case AuWbrCreate_PMFSRRV: -+ au_gen_fmt(fmt, sizeof(fmt), pat, "%llu:%lu"); -+ seq_printf(m, fmt, mfs->mfsrr_watermark, -+ jiffies_to_msecs(mfs->mfs_expire) / MSEC_PER_SEC); -+ break; -+ default: -+ BUG(); -+ } -+} -+ -+static int au_show_xino(struct seq_file *seq, struct super_block *sb) -+{ -+#ifdef CONFIG_SYSFS -+ return 0; -+#else -+ int err; -+ const int len = sizeof(AUFS_XINO_FNAME) - 1; -+ aufs_bindex_t bindex, brid; -+ struct qstr *name; -+ struct file *f; -+ struct dentry *d, *h_root; -+ struct au_branch *br; -+ -+ AuRwMustAnyLock(&sbinfo->si_rwsem); -+ -+ err = 0; -+ f = au_sbi(sb)->si_xib; -+ if (!f) -+ goto out; -+ -+ /* stop printing the default xino path on the first writable branch */ -+ h_root = NULL; -+ bindex = au_xi_root(sb, f->f_path.dentry); -+ if (bindex >= 0) { -+ br = au_sbr_sb(sb, bindex); -+ h_root = au_br_dentry(br); -+ } -+ -+ d = f->f_path.dentry; -+ name = &d->d_name; -+ /* safe ->d_parent because the file is unlinked */ -+ if (d->d_parent == h_root -+ && name->len == len -+ && !memcmp(name->name, AUFS_XINO_FNAME, len)) -+ goto out; -+ -+ seq_puts(seq, ",xino="); -+ err = au_xino_path(seq, f); -+ -+out: -+ return err; -+#endif -+} -+ -+/* seq_file will re-call me in case of too long string */ -+static int aufs_show_options(struct seq_file *m, struct dentry *dentry) -+{ -+ int err; -+ unsigned int mnt_flags, v; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ -+#define AuBool(name, str) do { \ -+ v = au_opt_test(mnt_flags, name); \ -+ if (v != au_opt_test(AuOpt_Def, name)) \ -+ seq_printf(m, ",%s" #str, v ? "" : "no"); \ -+} while (0) -+ -+#define AuStr(name, str) do { \ -+ v = mnt_flags & AuOptMask_##name; \ -+ if (v != (AuOpt_Def & AuOptMask_##name)) \ -+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \ -+} while (0) -+ -+#define AuUInt(name, str, val) do { \ -+ if (val != AUFS_##name##_DEF) \ -+ seq_printf(m, "," #str "=%u", val); \ -+} while (0) -+ -+ sb = dentry->d_sb; -+ if (sb->s_flags & SB_POSIXACL) -+ seq_puts(m, ",acl"); -+#if 0 -+ if (sb->s_flags & SB_I_VERSION) -+ seq_puts(m, ",i_version"); -+#endif -+ -+ /* lock free root dinfo */ -+ si_noflush_read_lock(sb); -+ sbinfo = au_sbi(sb); -+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo)); -+ -+ mnt_flags = au_mntflags(sb); -+ if (au_opt_test(mnt_flags, XINO)) { -+ err = au_show_xino(m, sb); -+ if (unlikely(err)) -+ goto out; -+ } else -+ seq_puts(m, ",noxino"); -+ -+ AuBool(TRUNC_XINO, trunc_xino); -+ AuStr(UDBA, udba); -+ AuBool(SHWH, shwh); -+ AuBool(PLINK, plink); -+ AuBool(DIO, dio); -+ AuBool(DIRPERM1, dirperm1); -+ -+ v = sbinfo->si_wbr_create; -+ if (v != AuWbrCreate_Def) -+ au_show_wbr_create(m, v, sbinfo); -+ -+ v = sbinfo->si_wbr_copyup; -+ if (v != AuWbrCopyup_Def) -+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v)); -+ -+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ); -+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ)) -+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w'); -+ -+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh); -+ -+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC; -+ AuUInt(RDCACHE, rdcache, v); -+ -+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk); -+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash); -+ -+ au_fhsm_show(m, sbinfo); -+ -+ AuBool(DIRREN, dirren); -+ AuBool(SUM, sum); -+ /* AuBool(SUM_W, wsum); */ -+ AuBool(WARN_PERM, warn_perm); -+ AuBool(VERBOSE, verbose); -+ -+out: -+ /* be sure to print "br:" last */ -+ if (!sysaufs_brs) { -+ seq_puts(m, ",br:"); -+ au_show_brs(m, sb); -+ } -+ si_read_unlock(sb); -+ return 0; -+ -+#undef AuBool -+#undef AuStr -+#undef AuUInt -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* sum mode which returns the summation for statfs(2) */ -+ -+static u64 au_add_till_max(u64 a, u64 b) -+{ -+ u64 old; -+ -+ old = a; -+ a += b; -+ if (old <= a) -+ return a; -+ return ULLONG_MAX; -+} -+ -+static u64 au_mul_till_max(u64 a, long mul) -+{ -+ u64 old; -+ -+ old = a; -+ a *= mul; -+ if (old <= a) -+ return a; -+ return ULLONG_MAX; -+} -+ -+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf) -+{ -+ int err; -+ long bsize, factor; -+ u64 blocks, bfree, bavail, files, ffree; -+ aufs_bindex_t bbot, bindex, i; -+ unsigned char shared; -+ struct path h_path; -+ struct super_block *h_sb; -+ -+ err = 0; -+ bsize = LONG_MAX; -+ files = 0; -+ ffree = 0; -+ blocks = 0; -+ bfree = 0; -+ bavail = 0; -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ h_path.mnt = au_sbr_mnt(sb, bindex); -+ h_sb = h_path.mnt->mnt_sb; -+ shared = 0; -+ for (i = 0; !shared && i < bindex; i++) -+ shared = (au_sbr_sb(sb, i) == h_sb); -+ if (shared) -+ continue; -+ -+ /* sb->s_root for NFS is unreliable */ -+ h_path.dentry = h_path.mnt->mnt_root; -+ err = vfs_statfs(&h_path, buf); -+ if (unlikely(err)) -+ goto out; -+ -+ if (bsize > buf->f_bsize) { -+ /* -+ * we will reduce bsize, so we have to expand blocks -+ * etc. to match them again -+ */ -+ factor = (bsize / buf->f_bsize); -+ blocks = au_mul_till_max(blocks, factor); -+ bfree = au_mul_till_max(bfree, factor); -+ bavail = au_mul_till_max(bavail, factor); -+ bsize = buf->f_bsize; -+ } -+ -+ factor = (buf->f_bsize / bsize); -+ blocks = au_add_till_max(blocks, -+ au_mul_till_max(buf->f_blocks, factor)); -+ bfree = au_add_till_max(bfree, -+ au_mul_till_max(buf->f_bfree, factor)); -+ bavail = au_add_till_max(bavail, -+ au_mul_till_max(buf->f_bavail, factor)); -+ files = au_add_till_max(files, buf->f_files); -+ ffree = au_add_till_max(ffree, buf->f_ffree); -+ } -+ -+ buf->f_bsize = bsize; -+ buf->f_blocks = blocks; -+ buf->f_bfree = bfree; -+ buf->f_bavail = bavail; -+ buf->f_files = files; -+ buf->f_ffree = ffree; -+ buf->f_frsize = 0; -+ -+out: -+ return err; -+} -+ -+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf) -+{ -+ int err; -+ struct path h_path; -+ struct super_block *sb; -+ -+ /* lock free root dinfo */ -+ sb = dentry->d_sb; -+ si_noflush_read_lock(sb); -+ if (!au_opt_test(au_mntflags(sb), SUM)) { -+ /* sb->s_root for NFS is unreliable */ -+ h_path.mnt = au_sbr_mnt(sb, 0); -+ h_path.dentry = h_path.mnt->mnt_root; -+ err = vfs_statfs(&h_path, buf); -+ } else -+ err = au_statfs_sum(sb, buf); -+ si_read_unlock(sb); -+ -+ if (!err) { -+ buf->f_type = AUFS_SUPER_MAGIC; -+ buf->f_namelen = AUFS_MAX_NAMELEN; -+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid)); -+ } -+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */ -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int aufs_sync_fs(struct super_block *sb, int wait) -+{ -+ int err, e; -+ aufs_bindex_t bbot, bindex; -+ struct au_branch *br; -+ struct super_block *h_sb; -+ -+ err = 0; -+ si_noflush_read_lock(sb); -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (!au_br_writable(br->br_perm)) -+ continue; -+ -+ h_sb = au_sbr_sb(sb, bindex); -+ e = vfsub_sync_filesystem(h_sb, wait); -+ if (unlikely(e && !err)) -+ err = e; -+ /* go on even if an error happens */ -+ } -+ si_read_unlock(sb); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* final actions when unmounting a file system */ -+static void aufs_put_super(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ sbinfo = au_sbi(sb); -+ if (sbinfo) -+ kobject_put(&sbinfo->si_kobj); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, -+ struct super_block *sb, void *arg) -+{ -+ void *array; -+ unsigned long long n, sz; -+ -+ array = NULL; -+ n = 0; -+ if (!*hint) -+ goto out; -+ -+ if (*hint > ULLONG_MAX / sizeof(array)) { -+ array = ERR_PTR(-EMFILE); -+ pr_err("hint %llu\n", *hint); -+ goto out; -+ } -+ -+ sz = sizeof(array) * *hint; -+ array = kzalloc(sz, GFP_NOFS); -+ if (unlikely(!array)) -+ array = vzalloc(sz); -+ if (unlikely(!array)) { -+ array = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ -+ n = cb(sb, array, *hint, arg); -+ AuDebugOn(n > *hint); -+ -+out: -+ *hint = n; -+ return array; -+} -+ -+static unsigned long long au_iarray_cb(struct super_block *sb, void *a, -+ unsigned long long max __maybe_unused, -+ void *arg) -+{ -+ unsigned long long n; -+ struct inode **p, *inode; -+ struct list_head *head; -+ -+ n = 0; -+ p = a; -+ head = arg; -+ spin_lock(&sb->s_inode_list_lock); -+ list_for_each_entry(inode, head, i_sb_list) { -+ if (!au_is_bad_inode(inode) -+ && au_ii(inode)->ii_btop >= 0) { -+ spin_lock(&inode->i_lock); -+ if (atomic_read(&inode->i_count)) { -+ au_igrab(inode); -+ *p++ = inode; -+ n++; -+ AuDebugOn(n > max); -+ } -+ spin_unlock(&inode->i_lock); -+ } -+ } -+ spin_unlock(&sb->s_inode_list_lock); -+ -+ return n; -+} -+ -+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max) -+{ -+ struct au_sbinfo *sbi; -+ -+ sbi = au_sbi(sb); -+ *max = au_lcnt_read(&sbi->si_ninodes, /*do_rev*/1); -+ return au_array_alloc(max, au_iarray_cb, sb, &sb->s_inodes); -+} -+ -+void au_iarray_free(struct inode **a, unsigned long long max) -+{ -+ unsigned long long ull; -+ -+ for (ull = 0; ull < max; ull++) -+ iput(a[ull]); -+ kvfree(a); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * refresh dentry and inode at remount time. -+ */ -+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */ -+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags, -+ struct dentry *parent) -+{ -+ int err; -+ -+ di_write_lock_child(dentry); -+ di_read_lock_parent(parent, AuLock_IR); -+ err = au_refresh_dentry(dentry, parent); -+ if (!err && dir_flags) -+ au_hn_reset(d_inode(dentry), dir_flags); -+ di_read_unlock(parent, AuLock_IR); -+ di_write_unlock(dentry); -+ -+ return err; -+} -+ -+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen, -+ struct au_sbinfo *sbinfo, -+ const unsigned int dir_flags, unsigned int do_idop) -+{ -+ int err; -+ struct dentry *parent; -+ -+ err = 0; -+ parent = dget_parent(dentry); -+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) { -+ if (d_really_is_positive(dentry)) { -+ if (!d_is_dir(dentry)) -+ err = au_do_refresh(dentry, /*dir_flags*/0, -+ parent); -+ else { -+ err = au_do_refresh(dentry, dir_flags, parent); -+ if (unlikely(err)) -+ au_fset_si(sbinfo, FAILED_REFRESH_DIR); -+ } -+ } else -+ err = au_do_refresh(dentry, /*dir_flags*/0, parent); -+ AuDbgDentry(dentry); -+ } -+ dput(parent); -+ -+ if (!err) { -+ if (do_idop) -+ au_refresh_dop(dentry, /*force_reval*/0); -+ } else -+ au_refresh_dop(dentry, /*force_reval*/1); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_refresh_d(struct super_block *sb, unsigned int do_idop) -+{ -+ int err, i, j, ndentry, e; -+ unsigned int sigen; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry **dentries, *d; -+ struct au_sbinfo *sbinfo; -+ struct dentry *root = sb->s_root; -+ const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1); -+ -+ if (do_idop) -+ au_refresh_dop(root, /*force_reval*/0); -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_dcsub_pages(&dpages, root, NULL, NULL); -+ if (unlikely(err)) -+ goto out_dpages; -+ -+ sigen = au_sigen(sb); -+ sbinfo = au_sbi(sb); -+ for (i = 0; i < dpages.ndpage; i++) { -+ dpage = dpages.dpages + i; -+ dentries = dpage->dentries; -+ ndentry = dpage->ndentry; -+ for (j = 0; j < ndentry; j++) { -+ d = dentries[j]; -+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags, -+ do_idop); -+ if (unlikely(e && !err)) -+ err = e; -+ /* go on even err */ -+ } -+ } -+ -+out_dpages: -+ au_dpages_free(&dpages); -+out: -+ return err; -+} -+ -+static int au_refresh_i(struct super_block *sb, unsigned int do_idop) -+{ -+ int err, e; -+ unsigned int sigen; -+ unsigned long long max, ull; -+ struct inode *inode, **array; -+ -+ array = au_iarray_alloc(sb, &max); -+ err = PTR_ERR(array); -+ if (IS_ERR(array)) -+ goto out; -+ -+ err = 0; -+ sigen = au_sigen(sb); -+ for (ull = 0; ull < max; ull++) { -+ inode = array[ull]; -+ if (unlikely(!inode)) -+ break; -+ -+ e = 0; -+ ii_write_lock_child(inode); -+ if (au_iigen(inode, NULL) != sigen) { -+ e = au_refresh_hinode_self(inode); -+ if (unlikely(e)) { -+ au_refresh_iop(inode, /*force_getattr*/1); -+ pr_err("error %d, i%lu\n", e, inode->i_ino); -+ if (!err) -+ err = e; -+ /* go on even if err */ -+ } -+ } -+ if (!e && do_idop) -+ au_refresh_iop(inode, /*force_getattr*/0); -+ ii_write_unlock(inode); -+ } -+ -+ au_iarray_free(array, max); -+ -+out: -+ return err; -+} -+ -+static void au_remount_refresh(struct super_block *sb, unsigned int do_idop) -+{ -+ int err, e; -+ unsigned int udba; -+ aufs_bindex_t bindex, bbot; -+ struct dentry *root; -+ struct inode *inode; -+ struct au_branch *br; -+ struct au_sbinfo *sbi; -+ -+ au_sigen_inc(sb); -+ sbi = au_sbi(sb); -+ au_fclr_si(sbi, FAILED_REFRESH_DIR); -+ -+ root = sb->s_root; -+ DiMustNoWaiters(root); -+ inode = d_inode(root); -+ IiMustNoWaiters(inode); -+ -+ udba = au_opt_udba(sb); -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ err = au_hnotify_reset_br(udba, br, br->br_perm); -+ if (unlikely(err)) -+ AuIOErr("hnotify failed on br %d, %d, ignored\n", -+ bindex, err); -+ /* go on even if err */ -+ } -+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1)); -+ -+ if (do_idop) { -+ if (au_ftest_si(sbi, NO_DREVAL)) { -+ AuDebugOn(sb->s_d_op == &aufs_dop_noreval); -+ sb->s_d_op = &aufs_dop_noreval; -+ AuDebugOn(sbi->si_iop_array == aufs_iop_nogetattr); -+ sbi->si_iop_array = aufs_iop_nogetattr; -+ } else { -+ AuDebugOn(sb->s_d_op == &aufs_dop); -+ sb->s_d_op = &aufs_dop; -+ AuDebugOn(sbi->si_iop_array == aufs_iop); -+ sbi->si_iop_array = aufs_iop; -+ } -+ pr_info("reset to %ps and %ps\n", -+ sb->s_d_op, sbi->si_iop_array); -+ } -+ -+ di_write_unlock(root); -+ err = au_refresh_d(sb, do_idop); -+ e = au_refresh_i(sb, do_idop); -+ if (unlikely(e && !err)) -+ err = e; -+ /* aufs_write_lock() calls ..._child() */ -+ di_write_lock_child(root); -+ -+ au_cpup_attr_all(inode, /*force*/1); -+ -+ if (unlikely(err)) -+ AuIOErr("refresh failed, ignored, %d\n", err); -+} -+ -+/* stop extra interpretation of errno in mount(8), and strange error messages */ -+static int cvt_err(int err) -+{ -+ AuTraceErr(err); -+ -+ switch (err) { -+ case -ENOENT: -+ case -ENOTDIR: -+ case -EEXIST: -+ case -EIO: -+ err = -EINVAL; -+ } -+ return err; -+} -+ -+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data) -+{ -+ int err, do_dx; -+ unsigned int mntflags; -+ struct au_opts opts = { -+ .opt = NULL -+ }; -+ struct dentry *root; -+ struct inode *inode; -+ struct au_sbinfo *sbinfo; -+ -+ err = 0; -+ root = sb->s_root; -+ if (!data || !*data) { -+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (!err) { -+ di_write_lock_child(root); -+ err = au_opts_verify(sb, *flags, /*pending*/0); -+ aufs_write_unlock(root); -+ } -+ goto out; -+ } -+ -+ err = -ENOMEM; -+ opts.opt = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!opts.opt)) -+ goto out; -+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); -+ opts.flags = AuOpts_REMOUNT; -+ opts.sb_flags = *flags; -+ -+ /* parse it before aufs lock */ -+ err = au_opts_parse(sb, data, &opts); -+ if (unlikely(err)) -+ goto out_opts; -+ -+ sbinfo = au_sbi(sb); -+ inode = d_inode(root); -+ inode_lock(inode); -+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out_mtx; -+ di_write_lock_child(root); -+ -+ /* au_opts_remount() may return an error */ -+ err = au_opts_remount(sb, &opts); -+ au_opts_free(&opts); -+ -+ if (au_ftest_opts(opts.flags, REFRESH)) -+ au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_IDOP)); -+ -+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) { -+ mntflags = au_mntflags(sb); -+ do_dx = !!au_opt_test(mntflags, DIO); -+ au_dy_arefresh(do_dx); -+ } -+ -+ au_fhsm_wrote_all(sb, /*force*/1); /* ?? */ -+ aufs_write_unlock(root); -+ -+out_mtx: -+ inode_unlock(inode); -+out_opts: -+ free_page((unsigned long)opts.opt); -+out: -+ err = cvt_err(err); -+ AuTraceErr(err); -+ return err; -+} -+ -+static const struct super_operations aufs_sop = { -+ .alloc_inode = aufs_alloc_inode, -+ .destroy_inode = aufs_destroy_inode, -+ /* always deleting, no clearing */ -+ .drop_inode = generic_delete_inode, -+ .show_options = aufs_show_options, -+ .statfs = aufs_statfs, -+ .put_super = aufs_put_super, -+ .sync_fs = aufs_sync_fs, -+ .remount_fs = aufs_remount_fs -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int alloc_root(struct super_block *sb) -+{ -+ int err; -+ struct inode *inode; -+ struct dentry *root; -+ -+ err = -ENOMEM; -+ inode = au_iget_locked(sb, AUFS_ROOT_INO); -+ err = PTR_ERR(inode); -+ if (IS_ERR(inode)) -+ goto out; -+ -+ inode->i_op = aufs_iop + AuIop_DIR; /* with getattr by default */ -+ inode->i_fop = &aufs_dir_fop; -+ inode->i_mode = S_IFDIR; -+ set_nlink(inode, 2); -+ unlock_new_inode(inode); -+ -+ root = d_make_root(inode); -+ if (unlikely(!root)) -+ goto out; -+ err = PTR_ERR(root); -+ if (IS_ERR(root)) -+ goto out; -+ -+ err = au_di_init(root); -+ if (!err) { -+ sb->s_root = root; -+ return 0; /* success */ -+ } -+ dput(root); -+ -+out: -+ return err; -+} -+ -+static int aufs_fill_super(struct super_block *sb, void *raw_data, -+ int silent __maybe_unused) -+{ -+ int err; -+ struct au_opts opts = { -+ .opt = NULL -+ }; -+ struct au_sbinfo *sbinfo; -+ struct dentry *root; -+ struct inode *inode; -+ char *arg = raw_data; -+ -+ if (unlikely(!arg || !*arg)) { -+ err = -EINVAL; -+ pr_err("no arg\n"); -+ goto out; -+ } -+ -+ err = -ENOMEM; -+ opts.opt = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!opts.opt)) -+ goto out; -+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); -+ opts.sb_flags = sb->s_flags; -+ -+ err = au_si_alloc(sb); -+ if (unlikely(err)) -+ goto out_opts; -+ sbinfo = au_sbi(sb); -+ -+ /* all timestamps always follow the ones on the branch */ -+ sb->s_flags |= SB_NOATIME | SB_NODIRATIME; -+ sb->s_flags |= SB_I_VERSION; /* do we really need this? */ -+ sb->s_op = &aufs_sop; -+ sb->s_d_op = &aufs_dop; -+ sb->s_magic = AUFS_SUPER_MAGIC; -+ sb->s_maxbytes = 0; -+ sb->s_stack_depth = 1; -+ au_export_init(sb); -+ au_xattr_init(sb); -+ -+ err = alloc_root(sb); -+ if (unlikely(err)) { -+ si_write_unlock(sb); -+ goto out_info; -+ } -+ root = sb->s_root; -+ inode = d_inode(root); -+ -+ /* -+ * actually we can parse options regardless aufs lock here. -+ * but at remount time, parsing must be done before aufs lock. -+ * so we follow the same rule. -+ */ -+ ii_write_lock_parent(inode); -+ aufs_write_unlock(root); -+ err = au_opts_parse(sb, arg, &opts); -+ if (unlikely(err)) -+ goto out_root; -+ -+ /* lock vfs_inode first, then aufs. */ -+ inode_lock(inode); -+ aufs_write_lock(root); -+ err = au_opts_mount(sb, &opts); -+ au_opts_free(&opts); -+ if (!err && au_ftest_si(sbinfo, NO_DREVAL)) { -+ sb->s_d_op = &aufs_dop_noreval; -+ pr_info("%ps\n", sb->s_d_op); -+ au_refresh_dop(root, /*force_reval*/0); -+ sbinfo->si_iop_array = aufs_iop_nogetattr; -+ au_refresh_iop(inode, /*force_getattr*/0); -+ } -+ aufs_write_unlock(root); -+ inode_unlock(inode); -+ if (!err) -+ goto out_opts; /* success */ -+ -+out_root: -+ dput(root); -+ sb->s_root = NULL; -+out_info: -+ kobject_put(&sbinfo->si_kobj); -+ sb->s_fs_info = NULL; -+out_opts: -+ free_page((unsigned long)opts.opt); -+out: -+ AuTraceErr(err); -+ err = cvt_err(err); -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags, -+ const char *dev_name __maybe_unused, -+ void *raw_data) -+{ -+ struct dentry *root; -+ -+ /* all timestamps always follow the ones on the branch */ -+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */ -+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super); -+ if (IS_ERR(root)) -+ goto out; -+ -+ au_sbilist_add(root->d_sb); -+ -+out: -+ return root; -+} -+ -+static void aufs_kill_sb(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ sbinfo = au_sbi(sb); -+ if (sbinfo) { -+ au_sbilist_del(sb); -+ aufs_write_lock(sb->s_root); -+ au_fhsm_fin(sb); -+ if (sbinfo->si_wbr_create_ops->fin) -+ sbinfo->si_wbr_create_ops->fin(sb); -+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) { -+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE); -+ au_remount_refresh(sb, /*do_idop*/0); -+ } -+ if (au_opt_test(sbinfo->si_mntflags, PLINK)) -+ au_plink_put(sb, /*verbose*/1); -+ au_xino_clr(sb); -+ au_dr_opt_flush(sb); -+ sbinfo->si_sb = NULL; -+ aufs_write_unlock(sb->s_root); -+ au_nwt_flush(&sbinfo->si_nowait); -+ } -+ kill_anon_super(sb); -+} -+ -+struct file_system_type aufs_fs_type = { -+ .name = AUFS_FSTYPE, -+ /* a race between rename and others */ -+ .fs_flags = FS_RENAME_DOES_D_MOVE, -+ .mount = aufs_mount, -+ .kill_sb = aufs_kill_sb, -+ /* no need to __module_get() and module_put(). */ -+ .owner = THIS_MODULE, -+}; -diff --git a/fs/aufs/super.h b/fs/aufs/super.h -new file mode 100644 -index 000000000..79e47da4e ---- /dev/null -+++ b/fs/aufs/super.h -@@ -0,0 +1,589 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * super_block operations -+ */ -+ -+#ifndef __AUFS_SUPER_H__ -+#define __AUFS_SUPER_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include "hbl.h" -+#include "lcnt.h" -+#include "rwsem.h" -+#include "wkq.h" -+ -+/* policies to select one among multiple writable branches */ -+struct au_wbr_copyup_operations { -+ int (*copyup)(struct dentry *dentry); -+}; -+ -+#define AuWbr_DIR 1 /* target is a dir */ -+#define AuWbr_PARENT (1 << 1) /* always require a parent */ -+ -+#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name) -+#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; } -+#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; } -+ -+struct au_wbr_create_operations { -+ int (*create)(struct dentry *dentry, unsigned int flags); -+ int (*init)(struct super_block *sb); -+ int (*fin)(struct super_block *sb); -+}; -+ -+struct au_wbr_mfs { -+ struct mutex mfs_lock; /* protect this structure */ -+ unsigned long mfs_jiffy; -+ unsigned long mfs_expire; -+ aufs_bindex_t mfs_bindex; -+ -+ unsigned long long mfsrr_bytes; -+ unsigned long long mfsrr_watermark; -+}; -+ -+#define AuPlink_NHASH 100 -+static inline int au_plink_hash(ino_t ino) -+{ -+ return ino % AuPlink_NHASH; -+} -+ -+/* File-based Hierarchical Storage Management */ -+struct au_fhsm { -+#ifdef CONFIG_AUFS_FHSM -+ /* allow only one process who can receive the notification */ -+ spinlock_t fhsm_spin; -+ pid_t fhsm_pid; -+ wait_queue_head_t fhsm_wqh; -+ atomic_t fhsm_readable; -+ -+ /* these are protected by si_rwsem */ -+ unsigned long fhsm_expire; -+ aufs_bindex_t fhsm_bottom; -+#endif -+}; -+ -+struct au_branch; -+struct au_sbinfo { -+ /* nowait tasks in the system-wide workqueue */ -+ struct au_nowait_tasks si_nowait; -+ -+ /* -+ * tried sb->s_umount, but failed due to the dependency between i_mutex. -+ * rwsem for au_sbinfo is necessary. -+ */ -+ struct au_rwsem si_rwsem; -+ -+ /* -+ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from -+ * remount. -+ */ -+ au_lcnt_t si_ninodes, si_nfiles; -+ -+ /* branch management */ -+ unsigned int si_generation; -+ -+ /* see AuSi_ flags */ -+ unsigned char au_si_status; -+ -+ aufs_bindex_t si_bbot; -+ -+ /* dirty trick to keep br_id plus */ -+ unsigned int si_last_br_id : -+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1; -+ struct au_branch **si_branch; -+ -+ /* policy to select a writable branch */ -+ unsigned char si_wbr_copyup; -+ unsigned char si_wbr_create; -+ struct au_wbr_copyup_operations *si_wbr_copyup_ops; -+ struct au_wbr_create_operations *si_wbr_create_ops; -+ -+ /* round robin */ -+ atomic_t si_wbr_rr_next; -+ -+ /* most free space */ -+ struct au_wbr_mfs si_wbr_mfs; -+ -+ /* File-based Hierarchical Storage Management */ -+ struct au_fhsm si_fhsm; -+ -+ /* mount flags */ -+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */ -+ unsigned int si_mntflags; -+ -+ /* external inode number (bitmap and translation table) */ -+ vfs_readf_t si_xread; -+ vfs_writef_t si_xwrite; -+ loff_t si_ximaxent; /* max entries in a xino */ -+ -+ struct file *si_xib; -+ struct mutex si_xib_mtx; /* protect xib members */ -+ unsigned long *si_xib_buf; -+ unsigned long si_xib_last_pindex; -+ int si_xib_next_bit; -+ -+ unsigned long si_xino_jiffy; -+ unsigned long si_xino_expire; -+ /* reserved for future use */ -+ /* unsigned long long si_xib_limit; */ /* Max xib file size */ -+ -+#ifdef CONFIG_AUFS_EXPORT -+ /* i_generation */ -+ /* todo: make xigen file an array to support many inode numbers */ -+ struct file *si_xigen; -+ atomic_t si_xigen_next; -+#endif -+ -+ /* dirty trick to support atomic_open */ -+ struct hlist_bl_head si_aopen; -+ -+ /* vdir parameters */ -+ unsigned long si_rdcache; /* max cache time in jiffies */ -+ unsigned int si_rdblk; /* deblk size */ -+ unsigned int si_rdhash; /* hash size */ -+ -+ /* -+ * If the number of whiteouts are larger than si_dirwh, leave all of -+ * them after au_whtmp_ren to reduce the cost of rmdir(2). -+ * future fsck.aufs or kernel thread will remove them later. -+ * Otherwise, remove all whiteouts and the dir in rmdir(2). -+ */ -+ unsigned int si_dirwh; -+ -+ /* pseudo_link list */ -+ struct hlist_bl_head si_plink[AuPlink_NHASH]; -+ wait_queue_head_t si_plink_wq; -+ spinlock_t si_plink_maint_lock; -+ pid_t si_plink_maint_pid; -+ -+ /* file list */ -+ struct hlist_bl_head si_files; -+ -+ /* with/without getattr, brother of sb->s_d_op */ -+ struct inode_operations *si_iop_array; -+ -+ /* -+ * sysfs and lifetime management. -+ * this is not a small structure and it may be a waste of memory in case -+ * of sysfs is disabled, particularly when many aufs-es are mounted. -+ * but using sysfs is majority. -+ */ -+ struct kobject si_kobj; -+#ifdef CONFIG_DEBUG_FS -+ struct dentry *si_dbgaufs; -+ struct dentry *si_dbgaufs_plink; -+ struct dentry *si_dbgaufs_xib; -+#ifdef CONFIG_AUFS_EXPORT -+ struct dentry *si_dbgaufs_xigen; -+#endif -+#endif -+ -+#ifdef CONFIG_AUFS_SBILIST -+ struct hlist_bl_node si_list; -+#endif -+ -+ /* dirty, necessary for unmounting, sysfs and sysrq */ -+ struct super_block *si_sb; -+}; -+ -+/* sbinfo status flags */ -+/* -+ * set true when refresh_dirs() failed at remount time. -+ * then try refreshing dirs at access time again. -+ * if it is false, refreshing dirs at access time is unnecessary -+ */ -+#define AuSi_FAILED_REFRESH_DIR 1 -+#define AuSi_FHSM (1 << 1) /* fhsm is active now */ -+#define AuSi_NO_DREVAL (1 << 2) /* disable all d_revalidate */ -+ -+#ifndef CONFIG_AUFS_FHSM -+#undef AuSi_FHSM -+#define AuSi_FHSM 0 -+#endif -+ -+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi, -+ unsigned int flag) -+{ -+ AuRwMustAnyLock(&sbi->si_rwsem); -+ return sbi->au_si_status & flag; -+} -+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name) -+#define au_fset_si(sbinfo, name) do { \ -+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \ -+ (sbinfo)->au_si_status |= AuSi_##name; \ -+} while (0) -+#define au_fclr_si(sbinfo, name) do { \ -+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \ -+ (sbinfo)->au_si_status &= ~AuSi_##name; \ -+} while (0) -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* policy to select one among writable branches */ -+#define AuWbrCopyup(sbinfo, ...) \ -+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__)) -+#define AuWbrCreate(sbinfo, ...) \ -+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__)) -+ -+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */ -+#define AuLock_DW 1 /* write-lock dentry */ -+#define AuLock_IR (1 << 1) /* read-lock inode */ -+#define AuLock_IW (1 << 2) /* write-lock inode */ -+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */ -+#define AuLock_DIRS (1 << 4) /* target is a pair of dirs */ -+ /* except RENAME_EXCHANGE */ -+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */ -+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */ -+#define AuLock_GEN (1 << 7) /* test digen/iigen */ -+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name) -+#define au_fset_lock(flags, name) \ -+ do { (flags) |= AuLock_##name; } while (0) -+#define au_fclr_lock(flags, name) \ -+ do { (flags) &= ~AuLock_##name; } while (0) -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* super.c */ -+extern struct file_system_type aufs_fs_type; -+struct inode *au_iget_locked(struct super_block *sb, ino_t ino); -+typedef unsigned long long (*au_arraycb_t)(struct super_block *sb, void *array, -+ unsigned long long max, void *arg); -+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, -+ struct super_block *sb, void *arg); -+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max); -+void au_iarray_free(struct inode **a, unsigned long long max); -+ -+/* sbinfo.c */ -+void au_si_free(struct kobject *kobj); -+int au_si_alloc(struct super_block *sb); -+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink); -+ -+unsigned int au_sigen_inc(struct super_block *sb); -+aufs_bindex_t au_new_br_id(struct super_block *sb); -+ -+int si_read_lock(struct super_block *sb, int flags); -+int si_write_lock(struct super_block *sb, int flags); -+int aufs_read_lock(struct dentry *dentry, int flags); -+void aufs_read_unlock(struct dentry *dentry, int flags); -+void aufs_write_lock(struct dentry *dentry); -+void aufs_write_unlock(struct dentry *dentry); -+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags); -+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2); -+ -+/* wbr_policy.c */ -+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[]; -+extern struct au_wbr_create_operations au_wbr_create_ops[]; -+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst); -+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex); -+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop); -+ -+/* mvdown.c */ -+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg); -+ -+#ifdef CONFIG_AUFS_FHSM -+/* fhsm.c */ -+ -+static inline pid_t au_fhsm_pid(struct au_fhsm *fhsm) -+{ -+ pid_t pid; -+ -+ spin_lock(&fhsm->fhsm_spin); -+ pid = fhsm->fhsm_pid; -+ spin_unlock(&fhsm->fhsm_spin); -+ -+ return pid; -+} -+ -+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force); -+void au_fhsm_wrote_all(struct super_block *sb, int force); -+int au_fhsm_fd(struct super_block *sb, int oflags); -+int au_fhsm_br_alloc(struct au_branch *br); -+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex); -+void au_fhsm_fin(struct super_block *sb); -+void au_fhsm_init(struct au_sbinfo *sbinfo); -+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec); -+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo); -+#else -+AuStubVoid(au_fhsm_wrote, struct super_block *sb, aufs_bindex_t bindex, -+ int force) -+AuStubVoid(au_fhsm_wrote_all, struct super_block *sb, int force) -+AuStub(int, au_fhsm_fd, return -EOPNOTSUPP, struct super_block *sb, int oflags) -+AuStub(pid_t, au_fhsm_pid, return 0, struct au_fhsm *fhsm) -+AuStubInt0(au_fhsm_br_alloc, struct au_branch *br) -+AuStubVoid(au_fhsm_set_bottom, struct super_block *sb, aufs_bindex_t bindex) -+AuStubVoid(au_fhsm_fin, struct super_block *sb) -+AuStubVoid(au_fhsm_init, struct au_sbinfo *sbinfo) -+AuStubVoid(au_fhsm_set, struct au_sbinfo *sbinfo, unsigned int sec) -+AuStubVoid(au_fhsm_show, struct seq_file *seq, struct au_sbinfo *sbinfo) -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct au_sbinfo *au_sbi(struct super_block *sb) -+{ -+ return sb->s_fs_info; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_EXPORT -+int au_test_nfsd(void); -+void au_export_init(struct super_block *sb); -+void au_xigen_inc(struct inode *inode); -+int au_xigen_new(struct inode *inode); -+int au_xigen_set(struct super_block *sb, struct path *path); -+void au_xigen_clr(struct super_block *sb); -+ -+static inline int au_busy_or_stale(void) -+{ -+ if (!au_test_nfsd()) -+ return -EBUSY; -+ return -ESTALE; -+} -+#else -+AuStubInt0(au_test_nfsd, void) -+AuStubVoid(au_export_init, struct super_block *sb) -+AuStubVoid(au_xigen_inc, struct inode *inode) -+AuStubInt0(au_xigen_new, struct inode *inode) -+AuStubInt0(au_xigen_set, struct super_block *sb, struct path *path) -+AuStubVoid(au_xigen_clr, struct super_block *sb) -+AuStub(int, au_busy_or_stale, return -EBUSY, void) -+#endif /* CONFIG_AUFS_EXPORT */ -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_SBILIST -+/* module.c */ -+extern struct hlist_bl_head au_sbilist; -+ -+static inline void au_sbilist_init(void) -+{ -+ INIT_HLIST_BL_HEAD(&au_sbilist); -+} -+ -+static inline void au_sbilist_add(struct super_block *sb) -+{ -+ au_hbl_add(&au_sbi(sb)->si_list, &au_sbilist); -+} -+ -+static inline void au_sbilist_del(struct super_block *sb) -+{ -+ au_hbl_del(&au_sbi(sb)->si_list, &au_sbilist); -+} -+ -+#ifdef CONFIG_AUFS_MAGIC_SYSRQ -+static inline void au_sbilist_lock(void) -+{ -+ hlist_bl_lock(&au_sbilist); -+} -+ -+static inline void au_sbilist_unlock(void) -+{ -+ hlist_bl_unlock(&au_sbilist); -+} -+#define AuGFP_SBILIST GFP_ATOMIC -+#else -+AuStubVoid(au_sbilist_lock, void) -+AuStubVoid(au_sbilist_unlock, void) -+#define AuGFP_SBILIST GFP_NOFS -+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */ -+#else -+AuStubVoid(au_sbilist_init, void) -+AuStubVoid(au_sbilist_add, struct super_block *sb) -+AuStubVoid(au_sbilist_del, struct super_block *sb) -+AuStubVoid(au_sbilist_lock, void) -+AuStubVoid(au_sbilist_unlock, void) -+#define AuGFP_SBILIST GFP_NOFS -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo) -+{ -+ /* -+ * This function is a dynamic '__init' function actually, -+ * so the tiny check for si_rwsem is unnecessary. -+ */ -+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ -+#ifdef CONFIG_DEBUG_FS -+ sbinfo->si_dbgaufs = NULL; -+ sbinfo->si_dbgaufs_plink = NULL; -+ sbinfo->si_dbgaufs_xib = NULL; -+#ifdef CONFIG_AUFS_EXPORT -+ sbinfo->si_dbgaufs_xigen = NULL; -+#endif -+#endif -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* current->atomic_flags */ -+/* this value should never corrupt the ones defined in linux/sched.h */ -+#define PFA_AUFS 7 -+ -+TASK_PFA_TEST(AUFS, test_aufs) /* task_test_aufs */ -+TASK_PFA_SET(AUFS, aufs) /* task_set_aufs */ -+TASK_PFA_CLEAR(AUFS, aufs) /* task_clear_aufs */ -+ -+static inline int si_pid_test(struct super_block *sb) -+{ -+ return !!task_test_aufs(current); -+} -+ -+static inline void si_pid_clr(struct super_block *sb) -+{ -+ AuDebugOn(!task_test_aufs(current)); -+ task_clear_aufs(current); -+} -+ -+static inline void si_pid_set(struct super_block *sb) -+{ -+ AuDebugOn(task_test_aufs(current)); -+ task_set_aufs(current); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* lock superblock. mainly for entry point functions */ -+#define __si_read_lock(sb) au_rw_read_lock(&au_sbi(sb)->si_rwsem) -+#define __si_write_lock(sb) au_rw_write_lock(&au_sbi(sb)->si_rwsem) -+#define __si_read_trylock(sb) au_rw_read_trylock(&au_sbi(sb)->si_rwsem) -+#define __si_write_trylock(sb) au_rw_write_trylock(&au_sbi(sb)->si_rwsem) -+/* -+#define __si_read_trylock_nested(sb) \ -+ au_rw_read_trylock_nested(&au_sbi(sb)->si_rwsem) -+#define __si_write_trylock_nested(sb) \ -+ au_rw_write_trylock_nested(&au_sbi(sb)->si_rwsem) -+*/ -+ -+#define __si_read_unlock(sb) au_rw_read_unlock(&au_sbi(sb)->si_rwsem) -+#define __si_write_unlock(sb) au_rw_write_unlock(&au_sbi(sb)->si_rwsem) -+#define __si_downgrade_lock(sb) au_rw_dgrade_lock(&au_sbi(sb)->si_rwsem) -+ -+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem) -+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem) -+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem) -+ -+static inline void si_noflush_read_lock(struct super_block *sb) -+{ -+ __si_read_lock(sb); -+ si_pid_set(sb); -+} -+ -+static inline int si_noflush_read_trylock(struct super_block *sb) -+{ -+ int locked; -+ -+ locked = __si_read_trylock(sb); -+ if (locked) -+ si_pid_set(sb); -+ return locked; -+} -+ -+static inline void si_noflush_write_lock(struct super_block *sb) -+{ -+ __si_write_lock(sb); -+ si_pid_set(sb); -+} -+ -+static inline int si_noflush_write_trylock(struct super_block *sb) -+{ -+ int locked; -+ -+ locked = __si_write_trylock(sb); -+ if (locked) -+ si_pid_set(sb); -+ return locked; -+} -+ -+#if 0 /* reserved */ -+static inline int si_read_trylock(struct super_block *sb, int flags) -+{ -+ if (au_ftest_lock(flags, FLUSH)) -+ au_nwt_flush(&au_sbi(sb)->si_nowait); -+ return si_noflush_read_trylock(sb); -+} -+#endif -+ -+static inline void si_read_unlock(struct super_block *sb) -+{ -+ si_pid_clr(sb); -+ __si_read_unlock(sb); -+} -+ -+#if 0 /* reserved */ -+static inline int si_write_trylock(struct super_block *sb, int flags) -+{ -+ if (au_ftest_lock(flags, FLUSH)) -+ au_nwt_flush(&au_sbi(sb)->si_nowait); -+ return si_noflush_write_trylock(sb); -+} -+#endif -+ -+static inline void si_write_unlock(struct super_block *sb) -+{ -+ si_pid_clr(sb); -+ __si_write_unlock(sb); -+} -+ -+#if 0 /* reserved */ -+static inline void si_downgrade_lock(struct super_block *sb) -+{ -+ __si_downgrade_lock(sb); -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline aufs_bindex_t au_sbbot(struct super_block *sb) -+{ -+ SiMustAnyLock(sb); -+ return au_sbi(sb)->si_bbot; -+} -+ -+static inline unsigned int au_mntflags(struct super_block *sb) -+{ -+ SiMustAnyLock(sb); -+ return au_sbi(sb)->si_mntflags; -+} -+ -+static inline unsigned int au_sigen(struct super_block *sb) -+{ -+ SiMustAnyLock(sb); -+ return au_sbi(sb)->si_generation; -+} -+ -+static inline struct au_branch *au_sbr(struct super_block *sb, -+ aufs_bindex_t bindex) -+{ -+ SiMustAnyLock(sb); -+ return au_sbi(sb)->si_branch[0 + bindex]; -+} -+ -+static inline loff_t au_xi_maxent(struct super_block *sb) -+{ -+ SiMustAnyLock(sb); -+ return au_sbi(sb)->si_ximaxent; -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_SUPER_H__ */ -diff --git a/fs/aufs/sysaufs.c b/fs/aufs/sysaufs.c -new file mode 100644 -index 000000000..cb34a53f3 ---- /dev/null -+++ b/fs/aufs/sysaufs.c -@@ -0,0 +1,93 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * sysfs interface and lifetime management -+ * they are necessary regardless sysfs is disabled. -+ */ -+ -+#include -+#include "aufs.h" -+ -+unsigned long sysaufs_si_mask; -+struct kset *sysaufs_kset; -+ -+#define AuSiAttr(_name) { \ -+ .attr = { .name = __stringify(_name), .mode = 0444 }, \ -+ .show = sysaufs_si_##_name, \ -+} -+ -+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path); -+struct attribute *sysaufs_si_attrs[] = { -+ &sysaufs_si_attr_xi_path.attr, -+ NULL, -+}; -+ -+static const struct sysfs_ops au_sbi_ops = { -+ .show = sysaufs_si_show -+}; -+ -+static struct kobj_type au_sbi_ktype = { -+ .release = au_si_free, -+ .sysfs_ops = &au_sbi_ops, -+ .default_attrs = sysaufs_si_attrs -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+int sysaufs_si_init(struct au_sbinfo *sbinfo) -+{ -+ int err; -+ -+ sbinfo->si_kobj.kset = sysaufs_kset; -+ /* cf. sysaufs_name() */ -+ err = kobject_init_and_add -+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL, -+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo)); -+ -+ return err; -+} -+ -+void sysaufs_fin(void) -+{ -+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group); -+ kset_unregister(sysaufs_kset); -+} -+ -+int __init sysaufs_init(void) -+{ -+ int err; -+ -+ do { -+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask)); -+ } while (!sysaufs_si_mask); -+ -+ err = -EINVAL; -+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj); -+ if (unlikely(!sysaufs_kset)) -+ goto out; -+ err = PTR_ERR(sysaufs_kset); -+ if (IS_ERR(sysaufs_kset)) -+ goto out; -+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group); -+ if (unlikely(err)) -+ kset_unregister(sysaufs_kset); -+ -+out: -+ return err; -+} -diff --git a/fs/aufs/sysaufs.h b/fs/aufs/sysaufs.h -new file mode 100644 -index 000000000..9a64191c5 ---- /dev/null -+++ b/fs/aufs/sysaufs.h -@@ -0,0 +1,102 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * sysfs interface and mount lifetime management -+ */ -+ -+#ifndef __SYSAUFS_H__ -+#define __SYSAUFS_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include "module.h" -+ -+struct super_block; -+struct au_sbinfo; -+ -+struct sysaufs_si_attr { -+ struct attribute attr; -+ int (*show)(struct seq_file *seq, struct super_block *sb); -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* sysaufs.c */ -+extern unsigned long sysaufs_si_mask; -+extern struct kset *sysaufs_kset; -+extern struct attribute *sysaufs_si_attrs[]; -+int sysaufs_si_init(struct au_sbinfo *sbinfo); -+int __init sysaufs_init(void); -+void sysaufs_fin(void); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* some people doesn't like to show a pointer in kernel */ -+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo) -+{ -+ return sysaufs_si_mask ^ (unsigned long)sbinfo; -+} -+ -+#define SysaufsSiNamePrefix "si_" -+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16) -+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name) -+{ -+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx", -+ sysaufs_si_id(sbinfo)); -+} -+ -+struct au_branch; -+#ifdef CONFIG_SYSFS -+/* sysfs.c */ -+extern struct attribute_group *sysaufs_attr_group; -+ -+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb); -+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, -+ char *buf); -+long au_brinfo_ioctl(struct file *file, unsigned long arg); -+#ifdef CONFIG_COMPAT -+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg); -+#endif -+ -+void sysaufs_br_init(struct au_branch *br); -+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex); -+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex); -+ -+#define sysaufs_brs_init() do {} while (0) -+ -+#else -+#define sysaufs_attr_group NULL -+ -+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb) -+AuStub(ssize_t, sysaufs_si_show, return 0, struct kobject *kobj, -+ struct attribute *attr, char *buf) -+AuStubVoid(sysaufs_br_init, struct au_branch *br) -+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex) -+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex) -+ -+static inline void sysaufs_brs_init(void) -+{ -+ sysaufs_brs = 0; -+} -+ -+#endif /* CONFIG_SYSFS */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __SYSAUFS_H__ */ -diff --git a/fs/aufs/sysfs.c b/fs/aufs/sysfs.c -new file mode 100644 -index 000000000..89a4cbf66 ---- /dev/null -+++ b/fs/aufs/sysfs.c -@@ -0,0 +1,373 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * sysfs interface -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+#ifdef CONFIG_AUFS_FS_MODULE -+/* this entry violates the "one line per file" policy of sysfs */ -+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr, -+ char *buf) -+{ -+ ssize_t err; -+ static char *conf = -+/* this file is generated at compiling */ -+#include "conf.str" -+ ; -+ -+ err = snprintf(buf, PAGE_SIZE, conf); -+ if (unlikely(err >= PAGE_SIZE)) -+ err = -EFBIG; -+ return err; -+} -+ -+static struct kobj_attribute au_config_attr = __ATTR_RO(config); -+#endif -+ -+static struct attribute *au_attr[] = { -+#ifdef CONFIG_AUFS_FS_MODULE -+ &au_config_attr.attr, -+#endif -+ NULL, /* need to NULL terminate the list of attributes */ -+}; -+ -+static struct attribute_group sysaufs_attr_group_body = { -+ .attrs = au_attr -+}; -+ -+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body; -+ -+/* ---------------------------------------------------------------------- */ -+ -+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb) -+{ -+ int err; -+ -+ SiMustAnyLock(sb); -+ -+ err = 0; -+ if (au_opt_test(au_mntflags(sb), XINO)) { -+ err = au_xino_path(seq, au_sbi(sb)->si_xib); -+ seq_putc(seq, '\n'); -+ } -+ return err; -+} -+ -+/* -+ * the lifetime of branch is independent from the entry under sysfs. -+ * sysfs handles the lifetime of the entry, and never call ->show() after it is -+ * unlinked. -+ */ -+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb, -+ aufs_bindex_t bindex, int idx) -+{ -+ int err; -+ struct path path; -+ struct dentry *root; -+ struct au_branch *br; -+ au_br_perm_str_t perm; -+ -+ AuDbg("b%d\n", bindex); -+ -+ err = 0; -+ root = sb->s_root; -+ di_read_lock_parent(root, !AuLock_IR); -+ br = au_sbr(sb, bindex); -+ -+ switch (idx) { -+ case AuBrSysfs_BR: -+ path.mnt = au_br_mnt(br); -+ path.dentry = au_h_dptr(root, bindex); -+ err = au_seq_path(seq, &path); -+ if (!err) { -+ au_optstr_br_perm(&perm, br->br_perm); -+ seq_printf(seq, "=%s\n", perm.a); -+ } -+ break; -+ case AuBrSysfs_BRID: -+ seq_printf(seq, "%d\n", br->br_id); -+ break; -+ } -+ di_read_unlock(root, !AuLock_IR); -+ if (unlikely(err || seq_has_overflowed(seq))) -+ err = -E2BIG; -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct seq_file *au_seq(char *p, ssize_t len) -+{ -+ struct seq_file *seq; -+ -+ seq = kzalloc(sizeof(*seq), GFP_NOFS); -+ if (seq) { -+ /* mutex_init(&seq.lock); */ -+ seq->buf = p; -+ seq->size = len; -+ return seq; /* success */ -+ } -+ -+ seq = ERR_PTR(-ENOMEM); -+ return seq; -+} -+ -+#define SysaufsBr_PREFIX "br" -+#define SysaufsBrid_PREFIX "brid" -+ -+/* todo: file size may exceed PAGE_SIZE */ -+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, -+ char *buf) -+{ -+ ssize_t err; -+ int idx; -+ long l; -+ aufs_bindex_t bbot; -+ struct au_sbinfo *sbinfo; -+ struct super_block *sb; -+ struct seq_file *seq; -+ char *name; -+ struct attribute **cattr; -+ -+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); -+ sb = sbinfo->si_sb; -+ -+ /* -+ * prevent a race condition between sysfs and aufs. -+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which -+ * prohibits maintaining the sysfs entries. -+ * hew we acquire read lock after sysfs_get_active_two(). -+ * on the other hand, the remount process may maintain the sysfs/aufs -+ * entries after acquiring write lock. -+ * it can cause a deadlock. -+ * simply we gave up processing read here. -+ */ -+ err = -EBUSY; -+ if (unlikely(!si_noflush_read_trylock(sb))) -+ goto out; -+ -+ seq = au_seq(buf, PAGE_SIZE); -+ err = PTR_ERR(seq); -+ if (IS_ERR(seq)) -+ goto out_unlock; -+ -+ name = (void *)attr->name; -+ cattr = sysaufs_si_attrs; -+ while (*cattr) { -+ if (!strcmp(name, (*cattr)->name)) { -+ err = container_of(*cattr, struct sysaufs_si_attr, attr) -+ ->show(seq, sb); -+ goto out_seq; -+ } -+ cattr++; -+ } -+ -+ if (!strncmp(name, SysaufsBrid_PREFIX, -+ sizeof(SysaufsBrid_PREFIX) - 1)) { -+ idx = AuBrSysfs_BRID; -+ name += sizeof(SysaufsBrid_PREFIX) - 1; -+ } else if (!strncmp(name, SysaufsBr_PREFIX, -+ sizeof(SysaufsBr_PREFIX) - 1)) { -+ idx = AuBrSysfs_BR; -+ name += sizeof(SysaufsBr_PREFIX) - 1; -+ } else -+ BUG(); -+ -+ err = kstrtol(name, 10, &l); -+ if (!err) { -+ bbot = au_sbbot(sb); -+ if (l <= bbot) -+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx); -+ else -+ err = -ENOENT; -+ } -+ -+out_seq: -+ if (!err) { -+ err = seq->count; -+ /* sysfs limit */ -+ if (unlikely(err == PAGE_SIZE)) -+ err = -EFBIG; -+ } -+ kfree(seq); -+out_unlock: -+ si_read_unlock(sb); -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_brinfo(struct super_block *sb, union aufs_brinfo __user *arg) -+{ -+ int err; -+ int16_t brid; -+ aufs_bindex_t bindex, bbot; -+ size_t sz; -+ char *buf; -+ struct seq_file *seq; -+ struct au_branch *br; -+ -+ si_read_lock(sb, AuLock_FLUSH); -+ bbot = au_sbbot(sb); -+ err = bbot + 1; -+ if (!arg) -+ goto out; -+ -+ err = -ENOMEM; -+ buf = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!buf)) -+ goto out; -+ -+ seq = au_seq(buf, PAGE_SIZE); -+ err = PTR_ERR(seq); -+ if (IS_ERR(seq)) -+ goto out_buf; -+ -+ sz = sizeof(*arg) - offsetof(union aufs_brinfo, path); -+ for (bindex = 0; bindex <= bbot; bindex++, arg++) { -+ err = !access_ok(VERIFY_WRITE, arg, sizeof(*arg)); -+ if (unlikely(err)) -+ break; -+ -+ br = au_sbr(sb, bindex); -+ brid = br->br_id; -+ BUILD_BUG_ON(sizeof(brid) != sizeof(arg->id)); -+ err = __put_user(brid, &arg->id); -+ if (unlikely(err)) -+ break; -+ -+ BUILD_BUG_ON(sizeof(br->br_perm) != sizeof(arg->perm)); -+ err = __put_user(br->br_perm, &arg->perm); -+ if (unlikely(err)) -+ break; -+ -+ err = au_seq_path(seq, &br->br_path); -+ if (unlikely(err)) -+ break; -+ seq_putc(seq, '\0'); -+ if (!seq_has_overflowed(seq)) { -+ err = copy_to_user(arg->path, seq->buf, seq->count); -+ seq->count = 0; -+ if (unlikely(err)) -+ break; -+ } else { -+ err = -E2BIG; -+ goto out_seq; -+ } -+ } -+ if (unlikely(err)) -+ err = -EFAULT; -+ -+out_seq: -+ kfree(seq); -+out_buf: -+ free_page((unsigned long)buf); -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+long au_brinfo_ioctl(struct file *file, unsigned long arg) -+{ -+ return au_brinfo(file->f_path.dentry->d_sb, (void __user *)arg); -+} -+ -+#ifdef CONFIG_COMPAT -+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg) -+{ -+ return au_brinfo(file->f_path.dentry->d_sb, compat_ptr(arg)); -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+void sysaufs_br_init(struct au_branch *br) -+{ -+ int i; -+ struct au_brsysfs *br_sysfs; -+ struct attribute *attr; -+ -+ br_sysfs = br->br_sysfs; -+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) { -+ attr = &br_sysfs->attr; -+ sysfs_attr_init(attr); -+ attr->name = br_sysfs->name; -+ attr->mode = 0444; -+ br_sysfs++; -+ } -+} -+ -+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ struct au_branch *br; -+ struct kobject *kobj; -+ struct au_brsysfs *br_sysfs; -+ int i; -+ aufs_bindex_t bbot; -+ -+ if (!sysaufs_brs) -+ return; -+ -+ kobj = &au_sbi(sb)->si_kobj; -+ bbot = au_sbbot(sb); -+ for (; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ br_sysfs = br->br_sysfs; -+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) { -+ sysfs_remove_file(kobj, &br_sysfs->attr); -+ br_sysfs++; -+ } -+ } -+} -+ -+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ int err, i; -+ aufs_bindex_t bbot; -+ struct kobject *kobj; -+ struct au_branch *br; -+ struct au_brsysfs *br_sysfs; -+ -+ if (!sysaufs_brs) -+ return; -+ -+ kobj = &au_sbi(sb)->si_kobj; -+ bbot = au_sbbot(sb); -+ for (; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ br_sysfs = br->br_sysfs; -+ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name), -+ SysaufsBr_PREFIX "%d", bindex); -+ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name), -+ SysaufsBrid_PREFIX "%d", bindex); -+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) { -+ err = sysfs_create_file(kobj, &br_sysfs->attr); -+ if (unlikely(err)) -+ pr_warn("failed %s under sysfs(%d)\n", -+ br_sysfs->name, err); -+ br_sysfs++; -+ } -+ } -+} -diff --git a/fs/aufs/sysrq.c b/fs/aufs/sysrq.c -new file mode 100644 -index 000000000..2dbf23741 ---- /dev/null -+++ b/fs/aufs/sysrq.c -@@ -0,0 +1,160 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * magic sysrq handler -+ */ -+ -+/* #include */ -+#include -+#include "aufs.h" -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void sysrq_sb(struct super_block *sb) -+{ -+ char *plevel; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ struct hlist_bl_head *files; -+ struct hlist_bl_node *pos; -+ struct au_finfo *finfo; -+ -+ plevel = au_plevel; -+ au_plevel = KERN_WARNING; -+ -+ /* since we define pr_fmt, call printk directly */ -+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str) -+ -+ sbinfo = au_sbi(sb); -+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo)); -+ pr("superblock\n"); -+ au_dpri_sb(sb); -+ -+#if 0 -+ pr("root dentry\n"); -+ au_dpri_dentry(sb->s_root); -+ pr("root inode\n"); -+ au_dpri_inode(d_inode(sb->s_root)); -+#endif -+ -+#if 0 -+ do { -+ int err, i, j, ndentry; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ -+ err = au_dpages_init(&dpages, GFP_ATOMIC); -+ if (unlikely(err)) -+ break; -+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL); -+ if (!err) -+ for (i = 0; i < dpages.ndpage; i++) { -+ dpage = dpages.dpages + i; -+ ndentry = dpage->ndentry; -+ for (j = 0; j < ndentry; j++) -+ au_dpri_dentry(dpage->dentries[j]); -+ } -+ au_dpages_free(&dpages); -+ } while (0); -+#endif -+ -+#if 1 -+ { -+ struct inode *i; -+ -+ pr("isolated inode\n"); -+ spin_lock(&sb->s_inode_list_lock); -+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) { -+ spin_lock(&i->i_lock); -+ if (1 || hlist_empty(&i->i_dentry)) -+ au_dpri_inode(i); -+ spin_unlock(&i->i_lock); -+ } -+ spin_unlock(&sb->s_inode_list_lock); -+ } -+#endif -+ pr("files\n"); -+ files = &au_sbi(sb)->si_files; -+ hlist_bl_lock(files); -+ hlist_bl_for_each_entry(finfo, pos, files, fi_hlist) { -+ umode_t mode; -+ -+ file = finfo->fi_file; -+ mode = file_inode(file)->i_mode; -+ if (!special_file(mode)) -+ au_dpri_file(file); -+ } -+ hlist_bl_unlock(files); -+ pr("done\n"); -+ -+#undef pr -+ au_plevel = plevel; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* module parameter */ -+static char *aufs_sysrq_key = "a"; -+module_param_named(sysrq, aufs_sysrq_key, charp, 0444); -+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME); -+ -+static void au_sysrq(int key __maybe_unused) -+{ -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_node *pos; -+ -+ lockdep_off(); -+ au_sbilist_lock(); -+ hlist_bl_for_each_entry(sbinfo, pos, &au_sbilist, si_list) -+ sysrq_sb(sbinfo->si_sb); -+ au_sbilist_unlock(); -+ lockdep_on(); -+} -+ -+static struct sysrq_key_op au_sysrq_op = { -+ .handler = au_sysrq, -+ .help_msg = "Aufs", -+ .action_msg = "Aufs", -+ .enable_mask = SYSRQ_ENABLE_DUMP -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+int __init au_sysrq_init(void) -+{ -+ int err; -+ char key; -+ -+ err = -1; -+ key = *aufs_sysrq_key; -+ if ('a' <= key && key <= 'z') -+ err = register_sysrq_key(key, &au_sysrq_op); -+ if (unlikely(err)) -+ pr_err("err %d, sysrq=%c\n", err, key); -+ return err; -+} -+ -+void au_sysrq_fin(void) -+{ -+ int err; -+ -+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op); -+ if (unlikely(err)) -+ pr_err("err %d (ignored)\n", err); -+} -diff --git a/fs/aufs/vdir.c b/fs/aufs/vdir.c -new file mode 100644 -index 000000000..f83ca0689 ---- /dev/null -+++ b/fs/aufs/vdir.c -@@ -0,0 +1,895 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * virtual or vertical directory -+ */ -+ -+#include "aufs.h" -+ -+static unsigned int calc_size(int nlen) -+{ -+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t)); -+} -+ -+static int set_deblk_end(union au_vdir_deblk_p *p, -+ union au_vdir_deblk_p *deblk_end) -+{ -+ if (calc_size(0) <= deblk_end->deblk - p->deblk) { -+ p->de->de_str.len = 0; -+ /* smp_mb(); */ -+ return 0; -+ } -+ return -1; /* error */ -+} -+ -+/* returns true or false */ -+static int is_deblk_end(union au_vdir_deblk_p *p, -+ union au_vdir_deblk_p *deblk_end) -+{ -+ if (calc_size(0) <= deblk_end->deblk - p->deblk) -+ return !p->de->de_str.len; -+ return 1; -+} -+ -+static unsigned char *last_deblk(struct au_vdir *vdir) -+{ -+ return vdir->vd_deblk[vdir->vd_nblk - 1]; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* estimate the appropriate size for name hash table */ -+unsigned int au_rdhash_est(loff_t sz) -+{ -+ unsigned int n; -+ -+ n = UINT_MAX; -+ sz >>= 10; -+ if (sz < n) -+ n = sz; -+ if (sz < AUFS_RDHASH_DEF) -+ n = AUFS_RDHASH_DEF; -+ /* pr_info("n %u\n", n); */ -+ return n; -+} -+ -+/* -+ * the allocated memory has to be freed by -+ * au_nhash_wh_free() or au_nhash_de_free(). -+ */ -+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp) -+{ -+ struct hlist_head *head; -+ unsigned int u; -+ size_t sz; -+ -+ sz = sizeof(*nhash->nh_head) * num_hash; -+ head = kmalloc(sz, gfp); -+ if (head) { -+ nhash->nh_num = num_hash; -+ nhash->nh_head = head; -+ for (u = 0; u < num_hash; u++) -+ INIT_HLIST_HEAD(head++); -+ return 0; /* success */ -+ } -+ -+ return -ENOMEM; -+} -+ -+static void nhash_count(struct hlist_head *head) -+{ -+#if 0 -+ unsigned long n; -+ struct hlist_node *pos; -+ -+ n = 0; -+ hlist_for_each(pos, head) -+ n++; -+ pr_info("%lu\n", n); -+#endif -+} -+ -+static void au_nhash_wh_do_free(struct hlist_head *head) -+{ -+ struct au_vdir_wh *pos; -+ struct hlist_node *node; -+ -+ hlist_for_each_entry_safe(pos, node, head, wh_hash) -+ kfree(pos); -+} -+ -+static void au_nhash_de_do_free(struct hlist_head *head) -+{ -+ struct au_vdir_dehstr *pos; -+ struct hlist_node *node; -+ -+ hlist_for_each_entry_safe(pos, node, head, hash) -+ au_cache_free_vdir_dehstr(pos); -+} -+ -+static void au_nhash_do_free(struct au_nhash *nhash, -+ void (*free)(struct hlist_head *head)) -+{ -+ unsigned int n; -+ struct hlist_head *head; -+ -+ n = nhash->nh_num; -+ if (!n) -+ return; -+ -+ head = nhash->nh_head; -+ while (n-- > 0) { -+ nhash_count(head); -+ free(head++); -+ } -+ kfree(nhash->nh_head); -+} -+ -+void au_nhash_wh_free(struct au_nhash *whlist) -+{ -+ au_nhash_do_free(whlist, au_nhash_wh_do_free); -+} -+ -+static void au_nhash_de_free(struct au_nhash *delist) -+{ -+ au_nhash_do_free(delist, au_nhash_de_do_free); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, -+ int limit) -+{ -+ int num; -+ unsigned int u, n; -+ struct hlist_head *head; -+ struct au_vdir_wh *pos; -+ -+ num = 0; -+ n = whlist->nh_num; -+ head = whlist->nh_head; -+ for (u = 0; u < n; u++, head++) -+ hlist_for_each_entry(pos, head, wh_hash) -+ if (pos->wh_bindex == btgt && ++num > limit) -+ return 1; -+ return 0; -+} -+ -+static struct hlist_head *au_name_hash(struct au_nhash *nhash, -+ unsigned char *name, -+ unsigned int len) -+{ -+ unsigned int v; -+ /* const unsigned int magic_bit = 12; */ -+ -+ AuDebugOn(!nhash->nh_num || !nhash->nh_head); -+ -+ v = 0; -+ if (len > 8) -+ len = 8; -+ while (len--) -+ v += *name++; -+ /* v = hash_long(v, magic_bit); */ -+ v %= nhash->nh_num; -+ return nhash->nh_head + v; -+} -+ -+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name, -+ int nlen) -+{ -+ return str->len == nlen && !memcmp(str->name, name, nlen); -+} -+ -+/* returns found or not */ -+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen) -+{ -+ struct hlist_head *head; -+ struct au_vdir_wh *pos; -+ struct au_vdir_destr *str; -+ -+ head = au_name_hash(whlist, name, nlen); -+ hlist_for_each_entry(pos, head, wh_hash) { -+ str = &pos->wh_str; -+ AuDbg("%.*s\n", str->len, str->name); -+ if (au_nhash_test_name(str, name, nlen)) -+ return 1; -+ } -+ return 0; -+} -+ -+/* returns found(true) or not */ -+static int test_known(struct au_nhash *delist, char *name, int nlen) -+{ -+ struct hlist_head *head; -+ struct au_vdir_dehstr *pos; -+ struct au_vdir_destr *str; -+ -+ head = au_name_hash(delist, name, nlen); -+ hlist_for_each_entry(pos, head, hash) { -+ str = pos->str; -+ AuDbg("%.*s\n", str->len, str->name); -+ if (au_nhash_test_name(str, name, nlen)) -+ return 1; -+ } -+ return 0; -+} -+ -+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino, -+ unsigned char d_type) -+{ -+#ifdef CONFIG_AUFS_SHWH -+ wh->wh_ino = ino; -+ wh->wh_type = d_type; -+#endif -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino, -+ unsigned int d_type, aufs_bindex_t bindex, -+ unsigned char shwh) -+{ -+ int err; -+ struct au_vdir_destr *str; -+ struct au_vdir_wh *wh; -+ -+ AuDbg("%.*s\n", nlen, name); -+ AuDebugOn(!whlist->nh_num || !whlist->nh_head); -+ -+ err = -ENOMEM; -+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS); -+ if (unlikely(!wh)) -+ goto out; -+ -+ err = 0; -+ wh->wh_bindex = bindex; -+ if (shwh) -+ au_shwh_init_wh(wh, ino, d_type); -+ str = &wh->wh_str; -+ str->len = nlen; -+ memcpy(str->name, name, nlen); -+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen)); -+ /* smp_mb(); */ -+ -+out: -+ return err; -+} -+ -+static int append_deblk(struct au_vdir *vdir) -+{ -+ int err; -+ unsigned long ul; -+ const unsigned int deblk_sz = vdir->vd_deblk_sz; -+ union au_vdir_deblk_p p, deblk_end; -+ unsigned char **o; -+ -+ err = -ENOMEM; -+ o = au_krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1), -+ GFP_NOFS, /*may_shrink*/0); -+ if (unlikely(!o)) -+ goto out; -+ -+ vdir->vd_deblk = o; -+ p.deblk = kmalloc(deblk_sz, GFP_NOFS); -+ if (p.deblk) { -+ ul = vdir->vd_nblk++; -+ vdir->vd_deblk[ul] = p.deblk; -+ vdir->vd_last.ul = ul; -+ vdir->vd_last.p.deblk = p.deblk; -+ deblk_end.deblk = p.deblk + deblk_sz; -+ err = set_deblk_end(&p, &deblk_end); -+ } -+ -+out: -+ return err; -+} -+ -+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino, -+ unsigned int d_type, struct au_nhash *delist) -+{ -+ int err; -+ unsigned int sz; -+ const unsigned int deblk_sz = vdir->vd_deblk_sz; -+ union au_vdir_deblk_p p, *room, deblk_end; -+ struct au_vdir_dehstr *dehstr; -+ -+ p.deblk = last_deblk(vdir); -+ deblk_end.deblk = p.deblk + deblk_sz; -+ room = &vdir->vd_last.p; -+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk -+ || !is_deblk_end(room, &deblk_end)); -+ -+ sz = calc_size(nlen); -+ if (unlikely(sz > deblk_end.deblk - room->deblk)) { -+ err = append_deblk(vdir); -+ if (unlikely(err)) -+ goto out; -+ -+ p.deblk = last_deblk(vdir); -+ deblk_end.deblk = p.deblk + deblk_sz; -+ /* smp_mb(); */ -+ AuDebugOn(room->deblk != p.deblk); -+ } -+ -+ err = -ENOMEM; -+ dehstr = au_cache_alloc_vdir_dehstr(); -+ if (unlikely(!dehstr)) -+ goto out; -+ -+ dehstr->str = &room->de->de_str; -+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen)); -+ room->de->de_ino = ino; -+ room->de->de_type = d_type; -+ room->de->de_str.len = nlen; -+ memcpy(room->de->de_str.name, name, nlen); -+ -+ err = 0; -+ room->deblk += sz; -+ if (unlikely(set_deblk_end(room, &deblk_end))) -+ err = append_deblk(vdir); -+ /* smp_mb(); */ -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_vdir_free(struct au_vdir *vdir) -+{ -+ unsigned char **deblk; -+ -+ deblk = vdir->vd_deblk; -+ while (vdir->vd_nblk--) -+ kfree(*deblk++); -+ kfree(vdir->vd_deblk); -+ au_cache_free_vdir(vdir); -+} -+ -+static struct au_vdir *alloc_vdir(struct file *file) -+{ -+ struct au_vdir *vdir; -+ struct super_block *sb; -+ int err; -+ -+ sb = file->f_path.dentry->d_sb; -+ SiMustAnyLock(sb); -+ -+ err = -ENOMEM; -+ vdir = au_cache_alloc_vdir(); -+ if (unlikely(!vdir)) -+ goto out; -+ -+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS); -+ if (unlikely(!vdir->vd_deblk)) -+ goto out_free; -+ -+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk; -+ if (!vdir->vd_deblk_sz) { -+ /* estimate the appropriate size for deblk */ -+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL); -+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */ -+ } -+ vdir->vd_nblk = 0; -+ vdir->vd_version = 0; -+ vdir->vd_jiffy = 0; -+ err = append_deblk(vdir); -+ if (!err) -+ return vdir; /* success */ -+ -+ kfree(vdir->vd_deblk); -+ -+out_free: -+ au_cache_free_vdir(vdir); -+out: -+ vdir = ERR_PTR(err); -+ return vdir; -+} -+ -+static int reinit_vdir(struct au_vdir *vdir) -+{ -+ int err; -+ union au_vdir_deblk_p p, deblk_end; -+ -+ while (vdir->vd_nblk > 1) { -+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]); -+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */ -+ vdir->vd_nblk--; -+ } -+ p.deblk = vdir->vd_deblk[0]; -+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz; -+ err = set_deblk_end(&p, &deblk_end); -+ /* keep vd_dblk_sz */ -+ vdir->vd_last.ul = 0; -+ vdir->vd_last.p.deblk = vdir->vd_deblk[0]; -+ vdir->vd_version = 0; -+ vdir->vd_jiffy = 0; -+ /* smp_mb(); */ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define AuFillVdir_CALLED 1 -+#define AuFillVdir_WHABLE (1 << 1) -+#define AuFillVdir_SHWH (1 << 2) -+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name) -+#define au_fset_fillvdir(flags, name) \ -+ do { (flags) |= AuFillVdir_##name; } while (0) -+#define au_fclr_fillvdir(flags, name) \ -+ do { (flags) &= ~AuFillVdir_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_SHWH -+#undef AuFillVdir_SHWH -+#define AuFillVdir_SHWH 0 -+#endif -+ -+struct fillvdir_arg { -+ struct dir_context ctx; -+ struct file *file; -+ struct au_vdir *vdir; -+ struct au_nhash delist; -+ struct au_nhash whlist; -+ aufs_bindex_t bindex; -+ unsigned int flags; -+ int err; -+}; -+ -+static int fillvdir(struct dir_context *ctx, const char *__name, int nlen, -+ loff_t offset __maybe_unused, u64 h_ino, -+ unsigned int d_type) -+{ -+ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx); -+ char *name = (void *)__name; -+ struct super_block *sb; -+ ino_t ino; -+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH); -+ -+ arg->err = 0; -+ sb = arg->file->f_path.dentry->d_sb; -+ au_fset_fillvdir(arg->flags, CALLED); -+ /* smp_mb(); */ -+ if (nlen <= AUFS_WH_PFX_LEN -+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { -+ if (test_known(&arg->delist, name, nlen) -+ || au_nhash_test_known_wh(&arg->whlist, name, nlen)) -+ goto out; /* already exists or whiteouted */ -+ -+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino); -+ if (!arg->err) { -+ if (unlikely(nlen > AUFS_MAX_NAMELEN)) -+ d_type = DT_UNKNOWN; -+ arg->err = append_de(arg->vdir, name, nlen, ino, -+ d_type, &arg->delist); -+ } -+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) { -+ name += AUFS_WH_PFX_LEN; -+ nlen -= AUFS_WH_PFX_LEN; -+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen)) -+ goto out; /* already whiteouted */ -+ -+ ino = 0; /* just to suppress a warning */ -+ if (shwh) -+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type, -+ &ino); -+ if (!arg->err) { -+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN) -+ d_type = DT_UNKNOWN; -+ arg->err = au_nhash_append_wh -+ (&arg->whlist, name, nlen, ino, d_type, -+ arg->bindex, shwh); -+ } -+ } -+ -+out: -+ if (!arg->err) -+ arg->vdir->vd_jiffy = jiffies; -+ /* smp_mb(); */ -+ AuTraceErr(arg->err); -+ return arg->err; -+} -+ -+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir, -+ struct au_nhash *whlist, struct au_nhash *delist) -+{ -+#ifdef CONFIG_AUFS_SHWH -+ int err; -+ unsigned int nh, u; -+ struct hlist_head *head; -+ struct au_vdir_wh *pos; -+ struct hlist_node *n; -+ char *p, *o; -+ struct au_vdir_destr *destr; -+ -+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH)); -+ -+ err = -ENOMEM; -+ o = p = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!p)) -+ goto out; -+ -+ err = 0; -+ nh = whlist->nh_num; -+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); -+ p += AUFS_WH_PFX_LEN; -+ for (u = 0; u < nh; u++) { -+ head = whlist->nh_head + u; -+ hlist_for_each_entry_safe(pos, n, head, wh_hash) { -+ destr = &pos->wh_str; -+ memcpy(p, destr->name, destr->len); -+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN, -+ pos->wh_ino, pos->wh_type, delist); -+ if (unlikely(err)) -+ break; -+ } -+ } -+ -+ free_page((unsigned long)o); -+ -+out: -+ AuTraceErr(err); -+ return err; -+#else -+ return 0; -+#endif -+} -+ -+static int au_do_read_vdir(struct fillvdir_arg *arg) -+{ -+ int err; -+ unsigned int rdhash; -+ loff_t offset; -+ aufs_bindex_t bbot, bindex, btop; -+ unsigned char shwh; -+ struct file *hf, *file; -+ struct super_block *sb; -+ -+ file = arg->file; -+ sb = file->f_path.dentry->d_sb; -+ SiMustAnyLock(sb); -+ -+ rdhash = au_sbi(sb)->si_rdhash; -+ if (!rdhash) -+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL)); -+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS); -+ if (unlikely(err)) -+ goto out_delist; -+ -+ err = 0; -+ arg->flags = 0; -+ shwh = 0; -+ if (au_opt_test(au_mntflags(sb), SHWH)) { -+ shwh = 1; -+ au_fset_fillvdir(arg->flags, SHWH); -+ } -+ btop = au_fbtop(file); -+ bbot = au_fbbot_dir(file); -+ for (bindex = btop; !err && bindex <= bbot; bindex++) { -+ hf = au_hf_dir(file, bindex); -+ if (!hf) -+ continue; -+ -+ offset = vfsub_llseek(hf, 0, SEEK_SET); -+ err = offset; -+ if (unlikely(offset)) -+ break; -+ -+ arg->bindex = bindex; -+ au_fclr_fillvdir(arg->flags, WHABLE); -+ if (shwh -+ || (bindex != bbot -+ && au_br_whable(au_sbr_perm(sb, bindex)))) -+ au_fset_fillvdir(arg->flags, WHABLE); -+ do { -+ arg->err = 0; -+ au_fclr_fillvdir(arg->flags, CALLED); -+ /* smp_mb(); */ -+ err = vfsub_iterate_dir(hf, &arg->ctx); -+ if (err >= 0) -+ err = arg->err; -+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED)); -+ -+ /* -+ * dir_relax() may be good for concurrency, but aufs should not -+ * use it since it will cause a lockdep problem. -+ */ -+ } -+ -+ if (!err && shwh) -+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist); -+ -+ au_nhash_wh_free(&arg->whlist); -+ -+out_delist: -+ au_nhash_de_free(&arg->delist); -+out: -+ return err; -+} -+ -+static int read_vdir(struct file *file, int may_read) -+{ -+ int err; -+ unsigned long expire; -+ unsigned char do_read; -+ struct fillvdir_arg arg = { -+ .ctx = { -+ .actor = fillvdir -+ } -+ }; -+ struct inode *inode; -+ struct au_vdir *vdir, *allocated; -+ -+ err = 0; -+ inode = file_inode(file); -+ IMustLock(inode); -+ IiMustWriteLock(inode); -+ SiMustAnyLock(inode->i_sb); -+ -+ allocated = NULL; -+ do_read = 0; -+ expire = au_sbi(inode->i_sb)->si_rdcache; -+ vdir = au_ivdir(inode); -+ if (!vdir) { -+ do_read = 1; -+ vdir = alloc_vdir(file); -+ err = PTR_ERR(vdir); -+ if (IS_ERR(vdir)) -+ goto out; -+ err = 0; -+ allocated = vdir; -+ } else if (may_read -+ && (!inode_eq_iversion(inode, vdir->vd_version) -+ || time_after(jiffies, vdir->vd_jiffy + expire))) { -+ do_read = 1; -+ err = reinit_vdir(vdir); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ if (!do_read) -+ return 0; /* success */ -+ -+ arg.file = file; -+ arg.vdir = vdir; -+ err = au_do_read_vdir(&arg); -+ if (!err) { -+ /* file->f_pos = 0; */ /* todo: ctx->pos? */ -+ vdir->vd_version = inode_query_iversion(inode); -+ vdir->vd_last.ul = 0; -+ vdir->vd_last.p.deblk = vdir->vd_deblk[0]; -+ if (allocated) -+ au_set_ivdir(inode, allocated); -+ } else if (allocated) -+ au_vdir_free(allocated); -+ -+out: -+ return err; -+} -+ -+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src) -+{ -+ int err, rerr; -+ unsigned long ul, n; -+ const unsigned int deblk_sz = src->vd_deblk_sz; -+ -+ AuDebugOn(tgt->vd_nblk != 1); -+ -+ err = -ENOMEM; -+ if (tgt->vd_nblk < src->vd_nblk) { -+ unsigned char **p; -+ -+ p = au_krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk, -+ GFP_NOFS, /*may_shrink*/0); -+ if (unlikely(!p)) -+ goto out; -+ tgt->vd_deblk = p; -+ } -+ -+ if (tgt->vd_deblk_sz != deblk_sz) { -+ unsigned char *p; -+ -+ tgt->vd_deblk_sz = deblk_sz; -+ p = au_krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS, -+ /*may_shrink*/1); -+ if (unlikely(!p)) -+ goto out; -+ tgt->vd_deblk[0] = p; -+ } -+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz); -+ tgt->vd_version = src->vd_version; -+ tgt->vd_jiffy = src->vd_jiffy; -+ -+ n = src->vd_nblk; -+ for (ul = 1; ul < n; ul++) { -+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz, -+ GFP_NOFS); -+ if (unlikely(!tgt->vd_deblk[ul])) -+ goto out; -+ tgt->vd_nblk++; -+ } -+ tgt->vd_nblk = n; -+ tgt->vd_last.ul = tgt->vd_last.ul; -+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul]; -+ tgt->vd_last.p.deblk += src->vd_last.p.deblk -+ - src->vd_deblk[src->vd_last.ul]; -+ /* smp_mb(); */ -+ return 0; /* success */ -+ -+out: -+ rerr = reinit_vdir(tgt); -+ BUG_ON(rerr); -+ return err; -+} -+ -+int au_vdir_init(struct file *file) -+{ -+ int err; -+ struct inode *inode; -+ struct au_vdir *vdir_cache, *allocated; -+ -+ /* test file->f_pos here instead of ctx->pos */ -+ err = read_vdir(file, !file->f_pos); -+ if (unlikely(err)) -+ goto out; -+ -+ allocated = NULL; -+ vdir_cache = au_fvdir_cache(file); -+ if (!vdir_cache) { -+ vdir_cache = alloc_vdir(file); -+ err = PTR_ERR(vdir_cache); -+ if (IS_ERR(vdir_cache)) -+ goto out; -+ allocated = vdir_cache; -+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) { -+ /* test file->f_pos here instead of ctx->pos */ -+ err = reinit_vdir(vdir_cache); -+ if (unlikely(err)) -+ goto out; -+ } else -+ return 0; /* success */ -+ -+ inode = file_inode(file); -+ err = copy_vdir(vdir_cache, au_ivdir(inode)); -+ if (!err) { -+ file->f_version = inode_query_iversion(inode); -+ if (allocated) -+ au_set_fvdir_cache(file, allocated); -+ } else if (allocated) -+ au_vdir_free(allocated); -+ -+out: -+ return err; -+} -+ -+static loff_t calc_offset(struct au_vdir *vdir) -+{ -+ loff_t offset; -+ union au_vdir_deblk_p p; -+ -+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul]; -+ offset = vdir->vd_last.p.deblk - p.deblk; -+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul; -+ return offset; -+} -+ -+/* returns true or false */ -+static int seek_vdir(struct file *file, struct dir_context *ctx) -+{ -+ int valid; -+ unsigned int deblk_sz; -+ unsigned long ul, n; -+ loff_t offset; -+ union au_vdir_deblk_p p, deblk_end; -+ struct au_vdir *vdir_cache; -+ -+ valid = 1; -+ vdir_cache = au_fvdir_cache(file); -+ offset = calc_offset(vdir_cache); -+ AuDbg("offset %lld\n", offset); -+ if (ctx->pos == offset) -+ goto out; -+ -+ vdir_cache->vd_last.ul = 0; -+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0]; -+ if (!ctx->pos) -+ goto out; -+ -+ valid = 0; -+ deblk_sz = vdir_cache->vd_deblk_sz; -+ ul = div64_u64(ctx->pos, deblk_sz); -+ AuDbg("ul %lu\n", ul); -+ if (ul >= vdir_cache->vd_nblk) -+ goto out; -+ -+ n = vdir_cache->vd_nblk; -+ for (; ul < n; ul++) { -+ p.deblk = vdir_cache->vd_deblk[ul]; -+ deblk_end.deblk = p.deblk + deblk_sz; -+ offset = ul; -+ offset *= deblk_sz; -+ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) { -+ unsigned int l; -+ -+ l = calc_size(p.de->de_str.len); -+ offset += l; -+ p.deblk += l; -+ } -+ if (!is_deblk_end(&p, &deblk_end)) { -+ valid = 1; -+ vdir_cache->vd_last.ul = ul; -+ vdir_cache->vd_last.p = p; -+ break; -+ } -+ } -+ -+out: -+ /* smp_mb(); */ -+ if (!valid) -+ AuDbg("valid %d\n", !valid); -+ return valid; -+} -+ -+int au_vdir_fill_de(struct file *file, struct dir_context *ctx) -+{ -+ unsigned int l, deblk_sz; -+ union au_vdir_deblk_p deblk_end; -+ struct au_vdir *vdir_cache; -+ struct au_vdir_de *de; -+ -+ if (!seek_vdir(file, ctx)) -+ return 0; -+ -+ vdir_cache = au_fvdir_cache(file); -+ deblk_sz = vdir_cache->vd_deblk_sz; -+ while (1) { -+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul]; -+ deblk_end.deblk += deblk_sz; -+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) { -+ de = vdir_cache->vd_last.p.de; -+ AuDbg("%.*s, off%lld, i%lu, dt%d\n", -+ de->de_str.len, de->de_str.name, ctx->pos, -+ (unsigned long)de->de_ino, de->de_type); -+ if (unlikely(!dir_emit(ctx, de->de_str.name, -+ de->de_str.len, de->de_ino, -+ de->de_type))) { -+ /* todo: ignore the error caused by udba? */ -+ /* return err; */ -+ return 0; -+ } -+ -+ l = calc_size(de->de_str.len); -+ vdir_cache->vd_last.p.deblk += l; -+ ctx->pos += l; -+ } -+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) { -+ vdir_cache->vd_last.ul++; -+ vdir_cache->vd_last.p.deblk -+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul]; -+ ctx->pos = deblk_sz * vdir_cache->vd_last.ul; -+ continue; -+ } -+ break; -+ } -+ -+ /* smp_mb(); */ -+ return 0; -+} -diff --git a/fs/aufs/vfsub.c b/fs/aufs/vfsub.c -new file mode 100644 -index 000000000..de22e6eae ---- /dev/null -+++ b/fs/aufs/vfsub.c -@@ -0,0 +1,902 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * sub-routines for VFS -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+#ifdef CONFIG_AUFS_BR_FUSE -+int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb) -+{ -+ if (!au_test_fuse(h_sb) || !au_userns) -+ return 0; -+ -+ return is_current_mnt_ns(mnt) ? 0 : -EACCES; -+} -+#endif -+ -+int vfsub_sync_filesystem(struct super_block *h_sb, int wait) -+{ -+ int err; -+ -+ lockdep_off(); -+ down_read(&h_sb->s_umount); -+ err = __sync_filesystem(h_sb, wait); -+ up_read(&h_sb->s_umount); -+ lockdep_on(); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int vfsub_update_h_iattr(struct path *h_path, int *did) -+{ -+ int err; -+ struct kstat st; -+ struct super_block *h_sb; -+ -+ /* for remote fs, leave work for its getattr or d_revalidate */ -+ /* for bad i_attr fs, handle them in aufs_getattr() */ -+ /* still some fs may acquire i_mutex. we need to skip them */ -+ err = 0; -+ if (!did) -+ did = &err; -+ h_sb = h_path->dentry->d_sb; -+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb)); -+ if (*did) -+ err = vfsub_getattr(h_path, &st); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct file *vfsub_dentry_open(struct path *path, int flags) -+{ -+ struct file *file; -+ -+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */, -+ current_cred()); -+ if (!IS_ERR_OR_NULL(file) -+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) -+ i_readcount_inc(d_inode(path->dentry)); -+ -+ return file; -+} -+ -+struct file *vfsub_filp_open(const char *path, int oflags, int mode) -+{ -+ struct file *file; -+ -+ lockdep_off(); -+ file = filp_open(path, -+ oflags /* | __FMODE_NONOTIFY */, -+ mode); -+ lockdep_on(); -+ if (IS_ERR(file)) -+ goto out; -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ -+ -+out: -+ return file; -+} -+ -+/* -+ * Ideally this function should call VFS:do_last() in order to keep all its -+ * checkings. But it is very hard for aufs to regenerate several VFS internal -+ * structure such as nameidata. This is a second (or third) best approach. -+ * cf. linux/fs/namei.c:do_last(), lookup_open() and atomic_open(). -+ */ -+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry, -+ struct vfsub_aopen_args *args) -+{ -+ int err; -+ struct au_branch *br = args->br; -+ struct file *file = args->file; -+ /* copied from linux/fs/namei.c:atomic_open() */ -+ struct dentry *const DENTRY_NOT_SET = (void *)-1UL; -+ -+ IMustLock(dir); -+ AuDebugOn(!dir->i_op->atomic_open); -+ -+ err = au_br_test_oflag(args->open_flag, br); -+ if (unlikely(err)) -+ goto out; -+ -+ au_lcnt_inc(&br->br_nfiles); -+ file->f_path.dentry = DENTRY_NOT_SET; -+ file->f_path.mnt = au_br_mnt(br); -+ AuDbg("%ps\n", dir->i_op->atomic_open); -+ err = dir->i_op->atomic_open(dir, dentry, file, args->open_flag, -+ args->create_mode); -+ if (unlikely(err < 0)) { -+ au_lcnt_dec(&br->br_nfiles); -+ goto out; -+ } -+ -+ /* temporary workaround for nfsv4 branch */ -+ if (au_test_nfs(dir->i_sb)) -+ nfs_mark_for_revalidate(dir); -+ -+ if (file->f_mode & FMODE_CREATED) -+ fsnotify_create(dir, dentry); -+ if (!(file->f_mode & FMODE_OPENED)) { -+ au_lcnt_dec(&br->br_nfiles); -+ goto out; -+ } -+ -+ /* todo: call VFS:may_open() here */ -+ /* todo: ima_file_check() too? */ -+ if (!err && (args->open_flag & __FMODE_EXEC)) -+ err = deny_write_access(file); -+ if (!err) -+ fsnotify_open(file); -+ else -+ au_lcnt_dec(&br->br_nfiles); -+ /* note that the file is created and still opened */ -+ -+out: -+ return err; -+} -+ -+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path) -+{ -+ int err; -+ -+ err = kern_path(name, flags, path); -+ if (!err && d_is_positive(path->dentry)) -+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+struct dentry *vfsub_lookup_one_len_unlocked(const char *name, -+ struct dentry *parent, int len) -+{ -+ struct path path = { -+ .mnt = NULL -+ }; -+ -+ path.dentry = lookup_one_len_unlocked(name, parent, len); -+ if (IS_ERR(path.dentry)) -+ goto out; -+ if (d_is_positive(path.dentry)) -+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/ -+ -+out: -+ AuTraceErrPtr(path.dentry); -+ return path.dentry; -+} -+ -+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, -+ int len) -+{ -+ struct path path = { -+ .mnt = NULL -+ }; -+ -+ /* VFS checks it too, but by WARN_ON_ONCE() */ -+ IMustLock(d_inode(parent)); -+ -+ path.dentry = lookup_one_len(name, parent, len); -+ if (IS_ERR(path.dentry)) -+ goto out; -+ if (d_is_positive(path.dentry)) -+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/ -+ -+out: -+ AuTraceErrPtr(path.dentry); -+ return path.dentry; -+} -+ -+void vfsub_call_lkup_one(void *args) -+{ -+ struct vfsub_lkup_one_args *a = args; -+ *a->errp = vfsub_lkup_one(a->name, a->parent); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1, -+ struct dentry *d2, struct au_hinode *hdir2) -+{ -+ struct dentry *d; -+ -+ lockdep_off(); -+ d = lock_rename(d1, d2); -+ lockdep_on(); -+ au_hn_suspend(hdir1); -+ if (hdir1 != hdir2) -+ au_hn_suspend(hdir2); -+ -+ return d; -+} -+ -+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1, -+ struct dentry *d2, struct au_hinode *hdir2) -+{ -+ au_hn_resume(hdir1); -+ if (hdir1 != hdir2) -+ au_hn_resume(hdir2); -+ lockdep_off(); -+ unlock_rename(d1, d2); -+ lockdep_on(); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl) -+{ -+ int err; -+ struct dentry *d; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_mknod(path, d, mode, 0); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_create(dir, path->dentry, mode, want_excl); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = *path; -+ int did; -+ -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = path->dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname) -+{ -+ int err; -+ struct dentry *d; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_symlink(path, d, symname); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_symlink(dir, path->dentry, symname); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = *path; -+ int did; -+ -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = path->dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev) -+{ -+ int err; -+ struct dentry *d; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_mknod(path, d, mode, new_encode_dev(dev)); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_mknod(dir, path->dentry, mode, dev); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = *path; -+ int did; -+ -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = path->dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+static int au_test_nlink(struct inode *inode) -+{ -+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */ -+ -+ if (!au_test_fs_no_limit_nlink(inode->i_sb) -+ || inode->i_nlink < link_max) -+ return 0; -+ return -EMLINK; -+} -+ -+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path, -+ struct inode **delegated_inode) -+{ -+ int err; -+ struct dentry *d; -+ -+ IMustLock(dir); -+ -+ err = au_test_nlink(d_inode(src_dentry)); -+ if (unlikely(err)) -+ return err; -+ -+ /* we don't call may_linkat() */ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_link(src_dentry, path, d); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_link(src_dentry, dir, path->dentry, delegated_inode); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = *path; -+ int did; -+ -+ /* fuse has different memory inode for the same inumber */ -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = path->dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ tmp.dentry = src_dentry; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, -+ struct inode *dir, struct path *path, -+ struct inode **delegated_inode, unsigned int flags) -+{ -+ int err; -+ struct path tmp = { -+ .mnt = path->mnt -+ }; -+ struct dentry *d; -+ -+ IMustLock(dir); -+ IMustLock(src_dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ tmp.dentry = src_dentry->d_parent; -+ err = security_path_rename(&tmp, src_dentry, path, d, /*flags*/0); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry, -+ delegated_inode, flags); -+ lockdep_on(); -+ if (!err) { -+ int did; -+ -+ tmp.dentry = d->d_parent; -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = src_dentry; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ tmp.dentry = src_dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+int vfsub_mkdir(struct inode *dir, struct path *path, int mode) -+{ -+ int err; -+ struct dentry *d; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_mkdir(path, d, mode); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_mkdir(dir, path->dentry, mode); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = *path; -+ int did; -+ -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = path->dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+int vfsub_rmdir(struct inode *dir, struct path *path) -+{ -+ int err; -+ struct dentry *d; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_rmdir(path, d); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_rmdir(dir, path->dentry); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = { -+ .dentry = path->dentry->d_parent, -+ .mnt = path->mnt -+ }; -+ -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* todo: support mmap_sem? */ -+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ -+ lockdep_off(); -+ err = vfs_read(file, ubuf, count, ppos); -+ lockdep_on(); -+ if (err >= 0) -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+/* todo: kernel_read()? */ -+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ char __user *u; -+ } buf; -+ -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ err = vfsub_read_u(file, buf.u, count, ppos); -+ set_fs(oldfs); -+ return err; -+} -+ -+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ -+ lockdep_off(); -+ err = vfs_write(file, ubuf, count, ppos); -+ lockdep_on(); -+ if (err >= 0) -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos) -+{ -+ ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ const char __user *u; -+ } buf; -+ -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ err = vfsub_write_u(file, buf.u, count, ppos); -+ set_fs(oldfs); -+ return err; -+} -+ -+int vfsub_flush(struct file *file, fl_owner_t id) -+{ -+ int err; -+ -+ err = 0; -+ if (file->f_op->flush) { -+ if (!au_test_nfs(file->f_path.dentry->d_sb)) -+ err = file->f_op->flush(file, id); -+ else { -+ lockdep_off(); -+ err = file->f_op->flush(file, id); -+ lockdep_on(); -+ } -+ if (!err) -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); -+ /*ignore*/ -+ } -+ return err; -+} -+ -+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx) -+{ -+ int err; -+ -+ AuDbg("%pD, ctx{%ps, %llu}\n", file, ctx->actor, ctx->pos); -+ -+ lockdep_off(); -+ err = iterate_dir(file, ctx); -+ lockdep_on(); -+ if (err >= 0) -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ -+ -+ return err; -+} -+ -+long vfsub_splice_to(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags) -+{ -+ long err; -+ -+ lockdep_off(); -+ err = do_splice_to(in, ppos, pipe, len, flags); -+ lockdep_on(); -+ file_accessed(in); -+ if (err >= 0) -+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags) -+{ -+ long err; -+ -+ lockdep_off(); -+ err = do_splice_from(pipe, out, ppos, len, flags); -+ lockdep_on(); -+ if (err >= 0) -+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+int vfsub_fsync(struct file *file, struct path *path, int datasync) -+{ -+ int err; -+ -+ /* file can be NULL */ -+ lockdep_off(); -+ err = vfs_fsync(file, datasync); -+ lockdep_on(); -+ if (!err) { -+ if (!path) { -+ AuDebugOn(!file); -+ path = &file->f_path; -+ } -+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/ -+ } -+ return err; -+} -+ -+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */ -+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr, -+ struct file *h_file) -+{ -+ int err; -+ struct inode *h_inode; -+ struct super_block *h_sb; -+ -+ if (!h_file) { -+ err = vfsub_truncate(h_path, length); -+ goto out; -+ } -+ -+ h_inode = d_inode(h_path->dentry); -+ h_sb = h_inode->i_sb; -+ lockdep_off(); -+ sb_start_write(h_sb); -+ lockdep_on(); -+ err = locks_verify_truncate(h_inode, h_file, length); -+ if (!err) -+ err = security_path_truncate(h_path); -+ if (!err) { -+ lockdep_off(); -+ err = do_truncate(h_path->dentry, length, attr, h_file); -+ lockdep_on(); -+ } -+ lockdep_off(); -+ sb_end_write(h_sb); -+ lockdep_on(); -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_vfsub_mkdir_args { -+ int *errp; -+ struct inode *dir; -+ struct path *path; -+ int mode; -+}; -+ -+static void au_call_vfsub_mkdir(void *args) -+{ -+ struct au_vfsub_mkdir_args *a = args; -+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode); -+} -+ -+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode) -+{ -+ int err, do_sio, wkq_err; -+ -+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE); -+ if (!do_sio) { -+ lockdep_off(); -+ err = vfsub_mkdir(dir, path, mode); -+ lockdep_on(); -+ } else { -+ struct au_vfsub_mkdir_args args = { -+ .errp = &err, -+ .dir = dir, -+ .path = path, -+ .mode = mode -+ }; -+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ return err; -+} -+ -+struct au_vfsub_rmdir_args { -+ int *errp; -+ struct inode *dir; -+ struct path *path; -+}; -+ -+static void au_call_vfsub_rmdir(void *args) -+{ -+ struct au_vfsub_rmdir_args *a = args; -+ *a->errp = vfsub_rmdir(a->dir, a->path); -+} -+ -+int vfsub_sio_rmdir(struct inode *dir, struct path *path) -+{ -+ int err, do_sio, wkq_err; -+ -+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE); -+ if (!do_sio) { -+ lockdep_off(); -+ err = vfsub_rmdir(dir, path); -+ lockdep_on(); -+ } else { -+ struct au_vfsub_rmdir_args args = { -+ .errp = &err, -+ .dir = dir, -+ .path = path -+ }; -+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct notify_change_args { -+ int *errp; -+ struct path *path; -+ struct iattr *ia; -+ struct inode **delegated_inode; -+}; -+ -+static void call_notify_change(void *args) -+{ -+ struct notify_change_args *a = args; -+ struct inode *h_inode; -+ -+ h_inode = d_inode(a->path->dentry); -+ IMustLock(h_inode); -+ -+ *a->errp = -EPERM; -+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) { -+ lockdep_off(); -+ *a->errp = notify_change(a->path->dentry, a->ia, -+ a->delegated_inode); -+ lockdep_on(); -+ if (!*a->errp) -+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/ -+ } -+ AuTraceErr(*a->errp); -+} -+ -+int vfsub_notify_change(struct path *path, struct iattr *ia, -+ struct inode **delegated_inode) -+{ -+ int err; -+ struct notify_change_args args = { -+ .errp = &err, -+ .path = path, -+ .ia = ia, -+ .delegated_inode = delegated_inode -+ }; -+ -+ call_notify_change(&args); -+ -+ return err; -+} -+ -+int vfsub_sio_notify_change(struct path *path, struct iattr *ia, -+ struct inode **delegated_inode) -+{ -+ int err, wkq_err; -+ struct notify_change_args args = { -+ .errp = &err, -+ .path = path, -+ .ia = ia, -+ .delegated_inode = delegated_inode -+ }; -+ -+ wkq_err = au_wkq_wait(call_notify_change, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct unlink_args { -+ int *errp; -+ struct inode *dir; -+ struct path *path; -+ struct inode **delegated_inode; -+}; -+ -+static void call_unlink(void *args) -+{ -+ struct unlink_args *a = args; -+ struct dentry *d = a->path->dentry; -+ struct inode *h_inode; -+ const int stop_sillyrename = (au_test_nfs(d->d_sb) -+ && au_dcount(d) == 1); -+ -+ IMustLock(a->dir); -+ -+ a->path->dentry = d->d_parent; -+ *a->errp = security_path_unlink(a->path, d); -+ a->path->dentry = d; -+ if (unlikely(*a->errp)) -+ return; -+ -+ if (!stop_sillyrename) -+ dget(d); -+ h_inode = NULL; -+ if (d_is_positive(d)) { -+ h_inode = d_inode(d); -+ ihold(h_inode); -+ } -+ -+ lockdep_off(); -+ *a->errp = vfs_unlink(a->dir, d, a->delegated_inode); -+ lockdep_on(); -+ if (!*a->errp) { -+ struct path tmp = { -+ .dentry = d->d_parent, -+ .mnt = a->path->mnt -+ }; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/ -+ } -+ -+ if (!stop_sillyrename) -+ dput(d); -+ if (h_inode) -+ iput(h_inode); -+ -+ AuTraceErr(*a->errp); -+} -+ -+/* -+ * @dir: must be locked. -+ * @dentry: target dentry. -+ */ -+int vfsub_unlink(struct inode *dir, struct path *path, -+ struct inode **delegated_inode, int force) -+{ -+ int err; -+ struct unlink_args args = { -+ .errp = &err, -+ .dir = dir, -+ .path = path, -+ .delegated_inode = delegated_inode -+ }; -+ -+ if (!force) -+ call_unlink(&args); -+ else { -+ int wkq_err; -+ -+ wkq_err = au_wkq_wait(call_unlink, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ return err; -+} -diff --git a/fs/aufs/vfsub.h b/fs/aufs/vfsub.h -new file mode 100644 -index 000000000..c0564abaa ---- /dev/null -+++ b/fs/aufs/vfsub.h -@@ -0,0 +1,355 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * sub-routines for VFS -+ */ -+ -+#ifndef __AUFS_VFSUB_H__ -+#define __AUFS_VFSUB_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+#include -+#include "debug.h" -+ -+/* copied from linux/fs/internal.h */ -+/* todo: BAD approach!! */ -+extern void __mnt_drop_write(struct vfsmount *); -+extern struct file *alloc_empty_file(int, const struct cred *); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* lock subclass for lower inode */ -+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */ -+/* reduce? gave up. */ -+enum { -+ AuLsc_I_Begin = I_MUTEX_PARENT2, /* 5 */ -+ AuLsc_I_PARENT, /* lower inode, parent first */ -+ AuLsc_I_PARENT2, /* copyup dirs */ -+ AuLsc_I_PARENT3, /* copyup wh */ -+ AuLsc_I_CHILD, -+ AuLsc_I_CHILD2, -+ AuLsc_I_End -+}; -+ -+/* to debug easier, do not make them inlined functions */ -+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx)) -+#define IMustLock(i) AuDebugOn(!inode_is_locked(i)) -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline void vfsub_drop_nlink(struct inode *inode) -+{ -+ AuDebugOn(!inode->i_nlink); -+ drop_nlink(inode); -+} -+ -+static inline void vfsub_dead_dir(struct inode *inode) -+{ -+ AuDebugOn(!S_ISDIR(inode->i_mode)); -+ inode->i_flags |= S_DEAD; -+ clear_nlink(inode); -+} -+ -+static inline int vfsub_native_ro(struct inode *inode) -+{ -+ return sb_rdonly(inode->i_sb) -+ || IS_RDONLY(inode) -+ /* || IS_APPEND(inode) */ -+ || IS_IMMUTABLE(inode); -+} -+ -+#ifdef CONFIG_AUFS_BR_FUSE -+int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb); -+#else -+AuStubInt0(vfsub_test_mntns, struct vfsmount *mnt, struct super_block *h_sb); -+#endif -+ -+int vfsub_sync_filesystem(struct super_block *h_sb, int wait); -+ -+/* ---------------------------------------------------------------------- */ -+ -+int vfsub_update_h_iattr(struct path *h_path, int *did); -+struct file *vfsub_dentry_open(struct path *path, int flags); -+struct file *vfsub_filp_open(const char *path, int oflags, int mode); -+struct au_branch; -+struct vfsub_aopen_args { -+ struct file *file; -+ unsigned int open_flag; -+ umode_t create_mode; -+ struct au_branch *br; -+}; -+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry, -+ struct vfsub_aopen_args *args); -+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path); -+ -+struct dentry *vfsub_lookup_one_len_unlocked(const char *name, -+ struct dentry *parent, int len); -+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, -+ int len); -+ -+struct vfsub_lkup_one_args { -+ struct dentry **errp; -+ struct qstr *name; -+ struct dentry *parent; -+}; -+ -+static inline struct dentry *vfsub_lkup_one(struct qstr *name, -+ struct dentry *parent) -+{ -+ return vfsub_lookup_one_len(name->name, parent, name->len); -+} -+ -+void vfsub_call_lkup_one(void *args); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline int vfsub_mnt_want_write(struct vfsmount *mnt) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = mnt_want_write(mnt); -+ lockdep_on(); -+ return err; -+} -+ -+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt) -+{ -+ lockdep_off(); -+ mnt_drop_write(mnt); -+ lockdep_on(); -+} -+ -+#if 0 /* reserved */ -+static inline void vfsub_mnt_drop_write_file(struct file *file) -+{ -+ lockdep_off(); -+ mnt_drop_write_file(file); -+ lockdep_on(); -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_hinode; -+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1, -+ struct dentry *d2, struct au_hinode *hdir2); -+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1, -+ struct dentry *d2, struct au_hinode *hdir2); -+ -+int vfsub_create(struct inode *dir, struct path *path, int mode, -+ bool want_excl); -+int vfsub_symlink(struct inode *dir, struct path *path, -+ const char *symname); -+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev); -+int vfsub_link(struct dentry *src_dentry, struct inode *dir, -+ struct path *path, struct inode **delegated_inode); -+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry, -+ struct inode *hdir, struct path *path, -+ struct inode **delegated_inode, unsigned int flags); -+int vfsub_mkdir(struct inode *dir, struct path *path, int mode); -+int vfsub_rmdir(struct inode *dir, struct path *path); -+ -+/* ---------------------------------------------------------------------- */ -+ -+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, -+ loff_t *ppos); -+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, -+ loff_t *ppos); -+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, -+ loff_t *ppos); -+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, -+ loff_t *ppos); -+int vfsub_flush(struct file *file, fl_owner_t id); -+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx); -+ -+static inline loff_t vfsub_f_size_read(struct file *file) -+{ -+ return i_size_read(file_inode(file)); -+} -+ -+static inline unsigned int vfsub_file_flags(struct file *file) -+{ -+ unsigned int flags; -+ -+ spin_lock(&file->f_lock); -+ flags = file->f_flags; -+ spin_unlock(&file->f_lock); -+ -+ return flags; -+} -+ -+static inline int vfsub_file_execed(struct file *file) -+{ -+ /* todo: direct access f_flags */ -+ return !!(vfsub_file_flags(file) & __FMODE_EXEC); -+} -+ -+#if 0 /* reserved */ -+static inline void vfsub_file_accessed(struct file *h_file) -+{ -+ file_accessed(h_file); -+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/ -+} -+#endif -+ -+#if 0 /* reserved */ -+static inline void vfsub_touch_atime(struct vfsmount *h_mnt, -+ struct dentry *h_dentry) -+{ -+ struct path h_path = { -+ .dentry = h_dentry, -+ .mnt = h_mnt -+ }; -+ touch_atime(&h_path); -+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/ -+} -+#endif -+ -+static inline int vfsub_update_time(struct inode *h_inode, -+ struct timespec64 *ts, int flags) -+{ -+ return update_time(h_inode, ts, flags); -+ /* no vfsub_update_h_iattr() since we don't have struct path */ -+} -+ -+#ifdef CONFIG_FS_POSIX_ACL -+static inline int vfsub_acl_chmod(struct inode *h_inode, umode_t h_mode) -+{ -+ int err; -+ -+ err = posix_acl_chmod(h_inode, h_mode); -+ if (err == -EOPNOTSUPP) -+ err = 0; -+ return err; -+} -+#else -+AuStubInt0(vfsub_acl_chmod, struct inode *h_inode, umode_t h_mode); -+#endif -+ -+long vfsub_splice_to(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags); -+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags); -+ -+static inline long vfsub_truncate(struct path *path, loff_t length) -+{ -+ long err; -+ -+ lockdep_off(); -+ err = vfs_truncate(path, length); -+ lockdep_on(); -+ return err; -+} -+ -+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr, -+ struct file *h_file); -+int vfsub_fsync(struct file *file, struct path *path, int datasync); -+ -+/* -+ * re-use branch fs's ioctl(FICLONE) while aufs itself doesn't support such -+ * ioctl. -+ */ -+static inline int vfsub_clone_file_range(struct file *src, struct file *dst, -+ u64 len) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = vfs_clone_file_range(src, 0, dst, 0, len); -+ lockdep_on(); -+ -+ return err; -+} -+ -+/* copy_file_range(2) is a systemcall */ -+static inline ssize_t vfsub_copy_file_range(struct file *src, loff_t src_pos, -+ struct file *dst, loff_t dst_pos, -+ size_t len, unsigned int flags) -+{ -+ ssize_t ssz; -+ -+ lockdep_off(); -+ ssz = vfs_copy_file_range(src, src_pos, dst, dst_pos, len, flags); -+ lockdep_on(); -+ -+ return ssz; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin) -+{ -+ loff_t err; -+ -+ lockdep_off(); -+ err = vfs_llseek(file, offset, origin); -+ lockdep_on(); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode); -+int vfsub_sio_rmdir(struct inode *dir, struct path *path); -+int vfsub_sio_notify_change(struct path *path, struct iattr *ia, -+ struct inode **delegated_inode); -+int vfsub_notify_change(struct path *path, struct iattr *ia, -+ struct inode **delegated_inode); -+int vfsub_unlink(struct inode *dir, struct path *path, -+ struct inode **delegated_inode, int force); -+ -+static inline int vfsub_getattr(const struct path *path, struct kstat *st) -+{ -+ return vfs_getattr(path, st, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline int vfsub_setxattr(struct dentry *dentry, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = vfs_setxattr(dentry, name, value, size, flags); -+ lockdep_on(); -+ -+ return err; -+} -+ -+static inline int vfsub_removexattr(struct dentry *dentry, const char *name) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = vfs_removexattr(dentry, name); -+ lockdep_on(); -+ -+ return err; -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_VFSUB_H__ */ -diff --git a/fs/aufs/wbr_policy.c b/fs/aufs/wbr_policy.c -new file mode 100644 -index 000000000..6e97c806a ---- /dev/null -+++ b/fs/aufs/wbr_policy.c -@@ -0,0 +1,830 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * policies for selecting one among multiple writable branches -+ */ -+ -+#include -+#include "aufs.h" -+ -+/* subset of cpup_attr() */ -+static noinline_for_stack -+int au_cpdown_attr(struct path *h_path, struct dentry *h_src) -+{ -+ int err, sbits; -+ struct iattr ia; -+ struct inode *h_isrc; -+ -+ h_isrc = d_inode(h_src); -+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID; -+ ia.ia_mode = h_isrc->i_mode; -+ ia.ia_uid = h_isrc->i_uid; -+ ia.ia_gid = h_isrc->i_gid; -+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID)); -+ au_cpup_attr_flags(d_inode(h_path->dentry), h_isrc->i_flags); -+ /* no delegation since it is just created */ -+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL); -+ -+ /* is this nfs only? */ -+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) { -+ ia.ia_valid = ATTR_FORCE | ATTR_MODE; -+ ia.ia_mode = h_isrc->i_mode; -+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL); -+ } -+ -+ return err; -+} -+ -+#define AuCpdown_PARENT_OPQ 1 -+#define AuCpdown_WHED (1 << 1) -+#define AuCpdown_MADE_DIR (1 << 2) -+#define AuCpdown_DIROPQ (1 << 3) -+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name) -+#define au_fset_cpdown(flags, name) \ -+ do { (flags) |= AuCpdown_##name; } while (0) -+#define au_fclr_cpdown(flags, name) \ -+ do { (flags) &= ~AuCpdown_##name; } while (0) -+ -+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst, -+ unsigned int *flags) -+{ -+ int err; -+ struct dentry *opq_dentry; -+ -+ opq_dentry = au_diropq_create(dentry, bdst); -+ err = PTR_ERR(opq_dentry); -+ if (IS_ERR(opq_dentry)) -+ goto out; -+ dput(opq_dentry); -+ au_fset_cpdown(*flags, DIROPQ); -+ -+out: -+ return err; -+} -+ -+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent, -+ struct inode *dir, aufs_bindex_t bdst) -+{ -+ int err; -+ struct path h_path; -+ struct au_branch *br; -+ -+ br = au_sbr(dentry->d_sb, bdst); -+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br); -+ err = PTR_ERR(h_path.dentry); -+ if (IS_ERR(h_path.dentry)) -+ goto out; -+ -+ err = 0; -+ if (d_is_positive(h_path.dentry)) { -+ h_path.mnt = au_br_mnt(br); -+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path, -+ dentry); -+ } -+ dput(h_path.dentry); -+ -+out: -+ return err; -+} -+ -+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst, -+ struct au_pin *pin, -+ struct dentry *h_parent, void *arg) -+{ -+ int err, rerr; -+ aufs_bindex_t bopq, btop; -+ struct path h_path; -+ struct dentry *parent; -+ struct inode *h_dir, *h_inode, *inode, *dir; -+ unsigned int *flags = arg; -+ -+ btop = au_dbtop(dentry); -+ /* dentry is di-locked */ -+ parent = dget_parent(dentry); -+ dir = d_inode(parent); -+ h_dir = d_inode(h_parent); -+ AuDebugOn(h_dir != au_h_iptr(dir, bdst)); -+ IMustLock(h_dir); -+ -+ err = au_lkup_neg(dentry, bdst, /*wh*/0); -+ if (unlikely(err < 0)) -+ goto out; -+ h_path.dentry = au_h_dptr(dentry, bdst); -+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst); -+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path, 0755); -+ if (unlikely(err)) -+ goto out_put; -+ au_fset_cpdown(*flags, MADE_DIR); -+ -+ bopq = au_dbdiropq(dentry); -+ au_fclr_cpdown(*flags, WHED); -+ au_fclr_cpdown(*flags, DIROPQ); -+ if (au_dbwh(dentry) == bdst) -+ au_fset_cpdown(*flags, WHED); -+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst) -+ au_fset_cpdown(*flags, PARENT_OPQ); -+ h_inode = d_inode(h_path.dentry); -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ if (au_ftest_cpdown(*flags, WHED)) { -+ err = au_cpdown_dir_opq(dentry, bdst, flags); -+ if (unlikely(err)) { -+ inode_unlock(h_inode); -+ goto out_dir; -+ } -+ } -+ -+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, btop)); -+ inode_unlock(h_inode); -+ if (unlikely(err)) -+ goto out_opq; -+ -+ if (au_ftest_cpdown(*flags, WHED)) { -+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst); -+ if (unlikely(err)) -+ goto out_opq; -+ } -+ -+ inode = d_inode(dentry); -+ if (au_ibbot(inode) < bdst) -+ au_set_ibbot(inode, bdst); -+ au_set_h_iptr(inode, bdst, au_igrab(h_inode), -+ au_hi_flags(inode, /*isdir*/1)); -+ au_fhsm_wrote(dentry->d_sb, bdst, /*force*/0); -+ goto out; /* success */ -+ -+ /* revert */ -+out_opq: -+ if (au_ftest_cpdown(*flags, DIROPQ)) { -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ rerr = au_diropq_remove(dentry, bdst); -+ inode_unlock(h_inode); -+ if (unlikely(rerr)) { -+ AuIOErr("failed removing diropq for %pd b%d (%d)\n", -+ dentry, bdst, rerr); -+ err = -EIO; -+ goto out; -+ } -+ } -+out_dir: -+ if (au_ftest_cpdown(*flags, MADE_DIR)) { -+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path); -+ if (unlikely(rerr)) { -+ AuIOErr("failed removing %pd b%d (%d)\n", -+ dentry, bdst, rerr); -+ err = -EIO; -+ } -+ } -+out_put: -+ au_set_h_dptr(dentry, bdst, NULL); -+ if (au_dbbot(dentry) == bdst) -+ au_update_dbbot(dentry); -+out: -+ dput(parent); -+ return err; -+} -+ -+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst) -+{ -+ int err; -+ unsigned int flags; -+ -+ flags = 0; -+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* policies for create */ -+ -+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ int err, i, j, ndentry; -+ aufs_bindex_t bopq; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry **dentries, *parent, *d; -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ parent = dget_parent(dentry); -+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0); -+ if (unlikely(err)) -+ goto out_free; -+ -+ err = bindex; -+ for (i = 0; i < dpages.ndpage; i++) { -+ dpage = dpages.dpages + i; -+ dentries = dpage->dentries; -+ ndentry = dpage->ndentry; -+ for (j = 0; j < ndentry; j++) { -+ d = dentries[j]; -+ di_read_lock_parent2(d, !AuLock_IR); -+ bopq = au_dbdiropq(d); -+ di_read_unlock(d, !AuLock_IR); -+ if (bopq >= 0 && bopq < err) -+ err = bopq; -+ } -+ } -+ -+out_free: -+ dput(parent); -+ au_dpages_free(&dpages); -+out: -+ return err; -+} -+ -+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ for (; bindex >= 0; bindex--) -+ if (!au_br_rdonly(au_sbr(sb, bindex))) -+ return bindex; -+ return -EROFS; -+} -+ -+/* top down parent */ -+static int au_wbr_create_tdp(struct dentry *dentry, -+ unsigned int flags __maybe_unused) -+{ -+ int err; -+ aufs_bindex_t btop, bindex; -+ struct super_block *sb; -+ struct dentry *parent, *h_parent; -+ -+ sb = dentry->d_sb; -+ btop = au_dbtop(dentry); -+ err = btop; -+ if (!au_br_rdonly(au_sbr(sb, btop))) -+ goto out; -+ -+ err = -EROFS; -+ parent = dget_parent(dentry); -+ for (bindex = au_dbtop(parent); bindex < btop; bindex++) { -+ h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || d_is_negative(h_parent)) -+ continue; -+ -+ if (!au_br_rdonly(au_sbr(sb, bindex))) { -+ err = bindex; -+ break; -+ } -+ } -+ dput(parent); -+ -+ /* bottom up here */ -+ if (unlikely(err < 0)) { -+ err = au_wbr_bu(sb, btop - 1); -+ if (err >= 0) -+ err = au_wbr_nonopq(dentry, err); -+ } -+ -+out: -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* an exception for the policy other than tdp */ -+static int au_wbr_create_exp(struct dentry *dentry) -+{ -+ int err; -+ aufs_bindex_t bwh, bdiropq; -+ struct dentry *parent; -+ -+ err = -1; -+ bwh = au_dbwh(dentry); -+ parent = dget_parent(dentry); -+ bdiropq = au_dbdiropq(parent); -+ if (bwh >= 0) { -+ if (bdiropq >= 0) -+ err = min(bdiropq, bwh); -+ else -+ err = bwh; -+ AuDbg("%d\n", err); -+ } else if (bdiropq >= 0) { -+ err = bdiropq; -+ AuDbg("%d\n", err); -+ } -+ dput(parent); -+ -+ if (err >= 0) -+ err = au_wbr_nonopq(dentry, err); -+ -+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err))) -+ err = -1; -+ -+ AuDbg("%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* round robin */ -+static int au_wbr_create_init_rr(struct super_block *sb) -+{ -+ int err; -+ -+ err = au_wbr_bu(sb, au_sbbot(sb)); -+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */ -+ /* smp_mb(); */ -+ -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags) -+{ -+ int err, nbr; -+ unsigned int u; -+ aufs_bindex_t bindex, bbot; -+ struct super_block *sb; -+ atomic_t *next; -+ -+ err = au_wbr_create_exp(dentry); -+ if (err >= 0) -+ goto out; -+ -+ sb = dentry->d_sb; -+ next = &au_sbi(sb)->si_wbr_rr_next; -+ bbot = au_sbbot(sb); -+ nbr = bbot + 1; -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ if (!au_ftest_wbr(flags, DIR)) { -+ err = atomic_dec_return(next) + 1; -+ /* modulo for 0 is meaningless */ -+ if (unlikely(!err)) -+ err = atomic_dec_return(next) + 1; -+ } else -+ err = atomic_read(next); -+ AuDbg("%d\n", err); -+ u = err; -+ err = u % nbr; -+ AuDbg("%d\n", err); -+ if (!au_br_rdonly(au_sbr(sb, err))) -+ break; -+ err = -EROFS; -+ } -+ -+ if (err >= 0) -+ err = au_wbr_nonopq(dentry, err); -+ -+out: -+ AuDbg("%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* most free space */ -+static void au_mfs(struct dentry *dentry, struct dentry *parent) -+{ -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_wbr_mfs *mfs; -+ struct dentry *h_parent; -+ aufs_bindex_t bindex, bbot; -+ int err; -+ unsigned long long b, bavail; -+ struct path h_path; -+ /* reduce the stack usage */ -+ struct kstatfs *st; -+ -+ st = kmalloc(sizeof(*st), GFP_NOFS); -+ if (unlikely(!st)) { -+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM); -+ return; -+ } -+ -+ bavail = 0; -+ sb = dentry->d_sb; -+ mfs = &au_sbi(sb)->si_wbr_mfs; -+ MtxMustLock(&mfs->mfs_lock); -+ mfs->mfs_bindex = -EROFS; -+ mfs->mfsrr_bytes = 0; -+ if (!parent) { -+ bindex = 0; -+ bbot = au_sbbot(sb); -+ } else { -+ bindex = au_dbtop(parent); -+ bbot = au_dbtaildir(parent); -+ } -+ -+ for (; bindex <= bbot; bindex++) { -+ if (parent) { -+ h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || d_is_negative(h_parent)) -+ continue; -+ } -+ br = au_sbr(sb, bindex); -+ if (au_br_rdonly(br)) -+ continue; -+ -+ /* sb->s_root for NFS is unreliable */ -+ h_path.mnt = au_br_mnt(br); -+ h_path.dentry = h_path.mnt->mnt_root; -+ err = vfs_statfs(&h_path, st); -+ if (unlikely(err)) { -+ AuWarn1("failed statfs, b%d, %d\n", bindex, err); -+ continue; -+ } -+ -+ /* when the available size is equal, select the lower one */ -+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail) -+ || sizeof(b) < sizeof(st->f_bsize)); -+ b = st->f_bavail * st->f_bsize; -+ br->br_wbr->wbr_bytes = b; -+ if (b >= bavail) { -+ bavail = b; -+ mfs->mfs_bindex = bindex; -+ mfs->mfs_jiffy = jiffies; -+ } -+ } -+ -+ mfs->mfsrr_bytes = bavail; -+ AuDbg("b%d\n", mfs->mfs_bindex); -+ kfree(st); -+} -+ -+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags) -+{ -+ int err; -+ struct dentry *parent; -+ struct super_block *sb; -+ struct au_wbr_mfs *mfs; -+ -+ err = au_wbr_create_exp(dentry); -+ if (err >= 0) -+ goto out; -+ -+ sb = dentry->d_sb; -+ parent = NULL; -+ if (au_ftest_wbr(flags, PARENT)) -+ parent = dget_parent(dentry); -+ mfs = &au_sbi(sb)->si_wbr_mfs; -+ mutex_lock(&mfs->mfs_lock); -+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire) -+ || mfs->mfs_bindex < 0 -+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex))) -+ au_mfs(dentry, parent); -+ mutex_unlock(&mfs->mfs_lock); -+ err = mfs->mfs_bindex; -+ dput(parent); -+ -+ if (err >= 0) -+ err = au_wbr_nonopq(dentry, err); -+ -+out: -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+static int au_wbr_create_init_mfs(struct super_block *sb) -+{ -+ struct au_wbr_mfs *mfs; -+ -+ mfs = &au_sbi(sb)->si_wbr_mfs; -+ mutex_init(&mfs->mfs_lock); -+ mfs->mfs_jiffy = 0; -+ mfs->mfs_bindex = -EROFS; -+ -+ return 0; -+} -+ -+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused) -+{ -+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock); -+ return 0; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* top down regardless parent, and then mfs */ -+static int au_wbr_create_tdmfs(struct dentry *dentry, -+ unsigned int flags __maybe_unused) -+{ -+ int err; -+ aufs_bindex_t bwh, btail, bindex, bfound, bmfs; -+ unsigned long long watermark; -+ struct super_block *sb; -+ struct au_wbr_mfs *mfs; -+ struct au_branch *br; -+ struct dentry *parent; -+ -+ sb = dentry->d_sb; -+ mfs = &au_sbi(sb)->si_wbr_mfs; -+ mutex_lock(&mfs->mfs_lock); -+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire) -+ || mfs->mfs_bindex < 0) -+ au_mfs(dentry, /*parent*/NULL); -+ watermark = mfs->mfsrr_watermark; -+ bmfs = mfs->mfs_bindex; -+ mutex_unlock(&mfs->mfs_lock); -+ -+ /* another style of au_wbr_create_exp() */ -+ bwh = au_dbwh(dentry); -+ parent = dget_parent(dentry); -+ btail = au_dbtaildir(parent); -+ if (bwh >= 0 && bwh < btail) -+ btail = bwh; -+ -+ err = au_wbr_nonopq(dentry, btail); -+ if (unlikely(err < 0)) -+ goto out; -+ btail = err; -+ bfound = -1; -+ for (bindex = 0; bindex <= btail; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_rdonly(br)) -+ continue; -+ if (br->br_wbr->wbr_bytes > watermark) { -+ bfound = bindex; -+ break; -+ } -+ } -+ err = bfound; -+ if (err < 0) -+ err = bmfs; -+ -+out: -+ dput(parent); -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* most free space and then round robin */ -+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags) -+{ -+ int err; -+ struct au_wbr_mfs *mfs; -+ -+ err = au_wbr_create_mfs(dentry, flags); -+ if (err >= 0) { -+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs; -+ mutex_lock(&mfs->mfs_lock); -+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark) -+ err = au_wbr_create_rr(dentry, flags); -+ mutex_unlock(&mfs->mfs_lock); -+ } -+ -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+static int au_wbr_create_init_mfsrr(struct super_block *sb) -+{ -+ int err; -+ -+ au_wbr_create_init_mfs(sb); /* ignore */ -+ err = au_wbr_create_init_rr(sb); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* top down parent and most free space */ -+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags) -+{ -+ int err, e2; -+ unsigned long long b; -+ aufs_bindex_t bindex, btop, bbot; -+ struct super_block *sb; -+ struct dentry *parent, *h_parent; -+ struct au_branch *br; -+ -+ err = au_wbr_create_tdp(dentry, flags); -+ if (unlikely(err < 0)) -+ goto out; -+ parent = dget_parent(dentry); -+ btop = au_dbtop(parent); -+ bbot = au_dbtaildir(parent); -+ if (btop == bbot) -+ goto out_parent; /* success */ -+ -+ e2 = au_wbr_create_mfs(dentry, flags); -+ if (e2 < 0) -+ goto out_parent; /* success */ -+ -+ /* when the available size is equal, select upper one */ -+ sb = dentry->d_sb; -+ br = au_sbr(sb, err); -+ b = br->br_wbr->wbr_bytes; -+ AuDbg("b%d, %llu\n", err, b); -+ -+ for (bindex = btop; bindex <= bbot; bindex++) { -+ h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || d_is_negative(h_parent)) -+ continue; -+ -+ br = au_sbr(sb, bindex); -+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) { -+ b = br->br_wbr->wbr_bytes; -+ err = bindex; -+ AuDbg("b%d, %llu\n", err, b); -+ } -+ } -+ -+ if (err >= 0) -+ err = au_wbr_nonopq(dentry, err); -+ -+out_parent: -+ dput(parent); -+out: -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * - top down parent -+ * - most free space with parent -+ * - most free space round-robin regardless parent -+ */ -+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags) -+{ -+ int err; -+ unsigned long long watermark; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_wbr_mfs *mfs; -+ -+ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT); -+ if (unlikely(err < 0)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ br = au_sbr(sb, err); -+ mfs = &au_sbi(sb)->si_wbr_mfs; -+ mutex_lock(&mfs->mfs_lock); -+ watermark = mfs->mfsrr_watermark; -+ mutex_unlock(&mfs->mfs_lock); -+ if (br->br_wbr->wbr_bytes < watermark) -+ /* regardless the parent dir */ -+ err = au_wbr_create_mfsrr(dentry, flags); -+ -+out: -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* policies for copyup */ -+ -+/* top down parent */ -+static int au_wbr_copyup_tdp(struct dentry *dentry) -+{ -+ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0); -+} -+ -+/* bottom up parent */ -+static int au_wbr_copyup_bup(struct dentry *dentry) -+{ -+ int err; -+ aufs_bindex_t bindex, btop; -+ struct dentry *parent, *h_parent; -+ struct super_block *sb; -+ -+ err = -EROFS; -+ sb = dentry->d_sb; -+ parent = dget_parent(dentry); -+ btop = au_dbtop(parent); -+ for (bindex = au_dbtop(dentry); bindex >= btop; bindex--) { -+ h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || d_is_negative(h_parent)) -+ continue; -+ -+ if (!au_br_rdonly(au_sbr(sb, bindex))) { -+ err = bindex; -+ break; -+ } -+ } -+ dput(parent); -+ -+ /* bottom up here */ -+ if (unlikely(err < 0)) -+ err = au_wbr_bu(sb, btop - 1); -+ -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+/* bottom up */ -+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop) -+{ -+ int err; -+ -+ err = au_wbr_bu(dentry->d_sb, btop); -+ AuDbg("b%d\n", err); -+ if (err > btop) -+ err = au_wbr_nonopq(dentry, err); -+ -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+static int au_wbr_copyup_bu(struct dentry *dentry) -+{ -+ int err; -+ aufs_bindex_t btop; -+ -+ btop = au_dbtop(dentry); -+ err = au_wbr_do_copyup_bu(dentry, btop); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = { -+ [AuWbrCopyup_TDP] = { -+ .copyup = au_wbr_copyup_tdp -+ }, -+ [AuWbrCopyup_BUP] = { -+ .copyup = au_wbr_copyup_bup -+ }, -+ [AuWbrCopyup_BU] = { -+ .copyup = au_wbr_copyup_bu -+ } -+}; -+ -+struct au_wbr_create_operations au_wbr_create_ops[] = { -+ [AuWbrCreate_TDP] = { -+ .create = au_wbr_create_tdp -+ }, -+ [AuWbrCreate_RR] = { -+ .create = au_wbr_create_rr, -+ .init = au_wbr_create_init_rr -+ }, -+ [AuWbrCreate_MFS] = { -+ .create = au_wbr_create_mfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_MFSV] = { -+ .create = au_wbr_create_mfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_MFSRR] = { -+ .create = au_wbr_create_mfsrr, -+ .init = au_wbr_create_init_mfsrr, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_MFSRRV] = { -+ .create = au_wbr_create_mfsrr, -+ .init = au_wbr_create_init_mfsrr, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_TDMFS] = { -+ .create = au_wbr_create_tdmfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_TDMFSV] = { -+ .create = au_wbr_create_tdmfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_PMFS] = { -+ .create = au_wbr_create_pmfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_PMFSV] = { -+ .create = au_wbr_create_pmfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_PMFSRR] = { -+ .create = au_wbr_create_pmfsrr, -+ .init = au_wbr_create_init_mfsrr, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_PMFSRRV] = { -+ .create = au_wbr_create_pmfsrr, -+ .init = au_wbr_create_init_mfsrr, -+ .fin = au_wbr_create_fin_mfs -+ } -+}; -diff --git a/fs/aufs/whout.c b/fs/aufs/whout.c -new file mode 100644 -index 000000000..2325c2ee5 ---- /dev/null -+++ b/fs/aufs/whout.c -@@ -0,0 +1,1062 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * whiteout for logical deletion and opaque directory -+ */ -+ -+#include "aufs.h" -+ -+#define WH_MASK 0444 -+ -+/* -+ * If a directory contains this file, then it is opaque. We start with the -+ * .wh. flag so that it is blocked by lookup. -+ */ -+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ, -+ sizeof(AUFS_WH_DIROPQ) - 1); -+ -+/* -+ * generate whiteout name, which is NOT terminated by NULL. -+ * @name: original d_name.name -+ * @len: original d_name.len -+ * @wh: whiteout qstr -+ * returns zero when succeeds, otherwise error. -+ * succeeded value as wh->name should be freed by kfree(). -+ */ -+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name) -+{ -+ char *p; -+ -+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN)) -+ return -ENAMETOOLONG; -+ -+ wh->len = name->len + AUFS_WH_PFX_LEN; -+ p = kmalloc(wh->len, GFP_NOFS); -+ wh->name = p; -+ if (p) { -+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); -+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len); -+ /* smp_mb(); */ -+ return 0; -+ } -+ return -ENOMEM; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * test if the @wh_name exists under @h_parent. -+ * @try_sio specifies the necessary of super-io. -+ */ -+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio) -+{ -+ int err; -+ struct dentry *wh_dentry; -+ -+ if (!try_sio) -+ wh_dentry = vfsub_lkup_one(wh_name, h_parent); -+ else -+ wh_dentry = au_sio_lkup_one(wh_name, h_parent); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) { -+ if (err == -ENAMETOOLONG) -+ err = 0; -+ goto out; -+ } -+ -+ err = 0; -+ if (d_is_negative(wh_dentry)) -+ goto out_wh; /* success */ -+ -+ err = 1; -+ if (d_is_reg(wh_dentry)) -+ goto out_wh; /* success */ -+ -+ err = -EIO; -+ AuIOErr("%pd Invalid whiteout entry type 0%o.\n", -+ wh_dentry, d_inode(wh_dentry)->i_mode); -+ -+out_wh: -+ dput(wh_dentry); -+out: -+ return err; -+} -+ -+/* -+ * test if the @h_dentry sets opaque or not. -+ */ -+int au_diropq_test(struct dentry *h_dentry) -+{ -+ int err; -+ struct inode *h_dir; -+ -+ h_dir = d_inode(h_dentry); -+ err = au_wh_test(h_dentry, &diropq_name, -+ au_test_h_perm_sio(h_dir, MAY_EXEC)); -+ return err; -+} -+ -+/* -+ * returns a negative dentry whose name is unique and temporary. -+ */ -+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br, -+ struct qstr *prefix) -+{ -+ struct dentry *dentry; -+ int i; -+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1], -+ *name, *p; -+ /* strict atomic_t is unnecessary here */ -+ static unsigned short cnt; -+ struct qstr qs; -+ -+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN); -+ -+ name = defname; -+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1; -+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) { -+ dentry = ERR_PTR(-ENAMETOOLONG); -+ if (unlikely(qs.len > NAME_MAX)) -+ goto out; -+ dentry = ERR_PTR(-ENOMEM); -+ name = kmalloc(qs.len + 1, GFP_NOFS); -+ if (unlikely(!name)) -+ goto out; -+ } -+ -+ /* doubly whiteout-ed */ -+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2); -+ p = name + AUFS_WH_PFX_LEN * 2; -+ memcpy(p, prefix->name, prefix->len); -+ p += prefix->len; -+ *p++ = '.'; -+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN); -+ -+ qs.name = name; -+ for (i = 0; i < 3; i++) { -+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++); -+ dentry = au_sio_lkup_one(&qs, h_parent); -+ if (IS_ERR(dentry) || d_is_negative(dentry)) -+ goto out_name; -+ dput(dentry); -+ } -+ /* pr_warn("could not get random name\n"); */ -+ dentry = ERR_PTR(-EEXIST); -+ AuDbg("%.*s\n", AuLNPair(&qs)); -+ BUG(); -+ -+out_name: -+ if (name != defname) -+ kfree(name); -+out: -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+/* -+ * rename the @h_dentry on @br to the whiteouted temporary name. -+ */ -+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br) -+{ -+ int err; -+ struct path h_path = { -+ .mnt = au_br_mnt(br) -+ }; -+ struct inode *h_dir, *delegated; -+ struct dentry *h_parent; -+ -+ h_parent = h_dentry->d_parent; /* dir inode is locked */ -+ h_dir = d_inode(h_parent); -+ IMustLock(h_dir); -+ -+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name); -+ err = PTR_ERR(h_path.dentry); -+ if (IS_ERR(h_path.dentry)) -+ goto out; -+ -+ /* under the same dir, no need to lock_rename() */ -+ delegated = NULL; -+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated, -+ /*flags*/0); -+ AuTraceErr(err); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal rename\n"); -+ iput(delegated); -+ } -+ dput(h_path.dentry); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * functions for removing a whiteout -+ */ -+ -+static int do_unlink_wh(struct inode *h_dir, struct path *h_path) -+{ -+ int err, force; -+ struct inode *delegated; -+ -+ /* -+ * forces superio when the dir has a sticky bit. -+ * this may be a violation of unix fs semantics. -+ */ -+ force = (h_dir->i_mode & S_ISVTX) -+ && !uid_eq(current_fsuid(), d_inode(h_path->dentry)->i_uid); -+ delegated = NULL; -+ err = vfsub_unlink(h_dir, h_path, &delegated, force); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ return err; -+} -+ -+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path, -+ struct dentry *dentry) -+{ -+ int err; -+ -+ err = do_unlink_wh(h_dir, h_path); -+ if (!err && dentry) -+ au_set_dbwh(dentry, -1); -+ -+ return err; -+} -+ -+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh, -+ struct au_branch *br) -+{ -+ int err; -+ struct path h_path = { -+ .mnt = au_br_mnt(br) -+ }; -+ -+ err = 0; -+ h_path.dentry = vfsub_lkup_one(wh, h_parent); -+ if (IS_ERR(h_path.dentry)) -+ err = PTR_ERR(h_path.dentry); -+ else { -+ if (d_is_reg(h_path.dentry)) -+ err = do_unlink_wh(d_inode(h_parent), &h_path); -+ dput(h_path.dentry); -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * initialize/clean whiteout for a branch -+ */ -+ -+static void au_wh_clean(struct inode *h_dir, struct path *whpath, -+ const int isdir) -+{ -+ int err; -+ struct inode *delegated; -+ -+ if (d_is_negative(whpath->dentry)) -+ return; -+ -+ if (isdir) -+ err = vfsub_rmdir(h_dir, whpath); -+ else { -+ delegated = NULL; -+ err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ } -+ if (unlikely(err)) -+ pr_warn("failed removing %pd (%d), ignored.\n", -+ whpath->dentry, err); -+} -+ -+static int test_linkable(struct dentry *h_root) -+{ -+ struct inode *h_dir = d_inode(h_root); -+ -+ if (h_dir->i_op->link) -+ return 0; -+ -+ pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n", -+ h_root, au_sbtype(h_root->d_sb)); -+ return -ENOSYS; -+} -+ -+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */ -+static int au_whdir(struct inode *h_dir, struct path *path) -+{ -+ int err; -+ -+ err = -EEXIST; -+ if (d_is_negative(path->dentry)) { -+ int mode = 0700; -+ -+ if (au_test_nfs(path->dentry->d_sb)) -+ mode |= 0111; -+ err = vfsub_mkdir(h_dir, path, mode); -+ } else if (d_is_dir(path->dentry)) -+ err = 0; -+ else -+ pr_err("unknown %pd exists\n", path->dentry); -+ -+ return err; -+} -+ -+struct au_wh_base { -+ const struct qstr *name; -+ struct dentry *dentry; -+}; -+ -+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[], -+ struct path *h_path) -+{ -+ h_path->dentry = base[AuBrWh_BASE].dentry; -+ au_wh_clean(h_dir, h_path, /*isdir*/0); -+ h_path->dentry = base[AuBrWh_PLINK].dentry; -+ au_wh_clean(h_dir, h_path, /*isdir*/1); -+ h_path->dentry = base[AuBrWh_ORPH].dentry; -+ au_wh_clean(h_dir, h_path, /*isdir*/1); -+} -+ -+/* -+ * returns tri-state, -+ * minus: error, caller should print the message -+ * zero: success -+ * plus: error, caller should NOT print the message -+ */ -+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr, -+ int do_plink, struct au_wh_base base[], -+ struct path *h_path) -+{ -+ int err; -+ struct inode *h_dir; -+ -+ h_dir = d_inode(h_root); -+ h_path->dentry = base[AuBrWh_BASE].dentry; -+ au_wh_clean(h_dir, h_path, /*isdir*/0); -+ h_path->dentry = base[AuBrWh_PLINK].dentry; -+ if (do_plink) { -+ err = test_linkable(h_root); -+ if (unlikely(err)) { -+ err = 1; -+ goto out; -+ } -+ -+ err = au_whdir(h_dir, h_path); -+ if (unlikely(err)) -+ goto out; -+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); -+ } else -+ au_wh_clean(h_dir, h_path, /*isdir*/1); -+ h_path->dentry = base[AuBrWh_ORPH].dentry; -+ err = au_whdir(h_dir, h_path); -+ if (unlikely(err)) -+ goto out; -+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry); -+ -+out: -+ return err; -+} -+ -+/* -+ * for the moment, aufs supports the branch filesystem which does not support -+ * link(2). testing on FAT which does not support i_op->setattr() fully either, -+ * copyup failed. finally, such filesystem will not be used as the writable -+ * branch. -+ * -+ * returns tri-state, see above. -+ */ -+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr, -+ int do_plink, struct au_wh_base base[], -+ struct path *h_path) -+{ -+ int err; -+ struct inode *h_dir; -+ -+ WbrWhMustWriteLock(wbr); -+ -+ err = test_linkable(h_root); -+ if (unlikely(err)) { -+ err = 1; -+ goto out; -+ } -+ -+ /* -+ * todo: should this create be done in /sbin/mount.aufs helper? -+ */ -+ err = -EEXIST; -+ h_dir = d_inode(h_root); -+ if (d_is_negative(base[AuBrWh_BASE].dentry)) { -+ h_path->dentry = base[AuBrWh_BASE].dentry; -+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true); -+ } else if (d_is_reg(base[AuBrWh_BASE].dentry)) -+ err = 0; -+ else -+ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry); -+ if (unlikely(err)) -+ goto out; -+ -+ h_path->dentry = base[AuBrWh_PLINK].dentry; -+ if (do_plink) { -+ err = au_whdir(h_dir, h_path); -+ if (unlikely(err)) -+ goto out; -+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); -+ } else -+ au_wh_clean(h_dir, h_path, /*isdir*/1); -+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry); -+ -+ h_path->dentry = base[AuBrWh_ORPH].dentry; -+ err = au_whdir(h_dir, h_path); -+ if (unlikely(err)) -+ goto out; -+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry); -+ -+out: -+ return err; -+} -+ -+/* -+ * initialize the whiteout base file/dir for @br. -+ */ -+int au_wh_init(struct au_branch *br, struct super_block *sb) -+{ -+ int err, i; -+ const unsigned char do_plink -+ = !!au_opt_test(au_mntflags(sb), PLINK); -+ struct inode *h_dir; -+ struct path path = br->br_path; -+ struct dentry *h_root = path.dentry; -+ struct au_wbr *wbr = br->br_wbr; -+ static const struct qstr base_name[] = { -+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME, -+ sizeof(AUFS_BASE_NAME) - 1), -+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME, -+ sizeof(AUFS_PLINKDIR_NAME) - 1), -+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME, -+ sizeof(AUFS_ORPHDIR_NAME) - 1) -+ }; -+ struct au_wh_base base[] = { -+ [AuBrWh_BASE] = { -+ .name = base_name + AuBrWh_BASE, -+ .dentry = NULL -+ }, -+ [AuBrWh_PLINK] = { -+ .name = base_name + AuBrWh_PLINK, -+ .dentry = NULL -+ }, -+ [AuBrWh_ORPH] = { -+ .name = base_name + AuBrWh_ORPH, -+ .dentry = NULL -+ } -+ }; -+ -+ if (wbr) -+ WbrWhMustWriteLock(wbr); -+ -+ for (i = 0; i < AuBrWh_Last; i++) { -+ /* doubly whiteouted */ -+ struct dentry *d; -+ -+ d = au_wh_lkup(h_root, (void *)base[i].name, br); -+ err = PTR_ERR(d); -+ if (IS_ERR(d)) -+ goto out; -+ -+ base[i].dentry = d; -+ AuDebugOn(wbr -+ && wbr->wbr_wh[i] -+ && wbr->wbr_wh[i] != base[i].dentry); -+ } -+ -+ if (wbr) -+ for (i = 0; i < AuBrWh_Last; i++) { -+ dput(wbr->wbr_wh[i]); -+ wbr->wbr_wh[i] = NULL; -+ } -+ -+ err = 0; -+ if (!au_br_writable(br->br_perm)) { -+ h_dir = d_inode(h_root); -+ au_wh_init_ro(h_dir, base, &path); -+ } else if (!au_br_wh_linkable(br->br_perm)) { -+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path); -+ if (err > 0) -+ goto out; -+ else if (err) -+ goto out_err; -+ } else { -+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path); -+ if (err > 0) -+ goto out; -+ else if (err) -+ goto out_err; -+ } -+ goto out; /* success */ -+ -+out_err: -+ pr_err("an error(%d) on the writable branch %pd(%s)\n", -+ err, h_root, au_sbtype(h_root->d_sb)); -+out: -+ for (i = 0; i < AuBrWh_Last; i++) -+ dput(base[i].dentry); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * whiteouts are all hard-linked usually. -+ * when its link count reaches a ceiling, we create a new whiteout base -+ * asynchronously. -+ */ -+ -+struct reinit_br_wh { -+ struct super_block *sb; -+ struct au_branch *br; -+}; -+ -+static void reinit_br_wh(void *arg) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct path h_path; -+ struct reinit_br_wh *a = arg; -+ struct au_wbr *wbr; -+ struct inode *dir, *delegated; -+ struct dentry *h_root; -+ struct au_hinode *hdir; -+ -+ err = 0; -+ wbr = a->br->br_wbr; -+ /* big aufs lock */ -+ si_noflush_write_lock(a->sb); -+ if (!au_br_writable(a->br->br_perm)) -+ goto out; -+ bindex = au_br_index(a->sb, a->br->br_id); -+ if (unlikely(bindex < 0)) -+ goto out; -+ -+ di_read_lock_parent(a->sb->s_root, AuLock_IR); -+ dir = d_inode(a->sb->s_root); -+ hdir = au_hi(dir, bindex); -+ h_root = au_h_dptr(a->sb->s_root, bindex); -+ AuDebugOn(h_root != au_br_dentry(a->br)); -+ -+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT); -+ wbr_wh_write_lock(wbr); -+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode, -+ h_root, a->br); -+ if (!err) { -+ h_path.dentry = wbr->wbr_whbase; -+ h_path.mnt = au_br_mnt(a->br); -+ delegated = NULL; -+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, -+ /*force*/0); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ } else { -+ pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase); -+ err = 0; -+ } -+ dput(wbr->wbr_whbase); -+ wbr->wbr_whbase = NULL; -+ if (!err) -+ err = au_wh_init(a->br, a->sb); -+ wbr_wh_write_unlock(wbr); -+ au_hn_inode_unlock(hdir); -+ di_read_unlock(a->sb->s_root, AuLock_IR); -+ if (!err) -+ au_fhsm_wrote(a->sb, bindex, /*force*/0); -+ -+out: -+ if (wbr) -+ atomic_dec(&wbr->wbr_wh_running); -+ au_lcnt_dec(&a->br->br_count); -+ si_write_unlock(a->sb); -+ au_nwt_done(&au_sbi(a->sb)->si_nowait); -+ kfree(arg); -+ if (unlikely(err)) -+ AuIOErr("err %d\n", err); -+} -+ -+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br) -+{ -+ int do_dec, wkq_err; -+ struct reinit_br_wh *arg; -+ -+ do_dec = 1; -+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1) -+ goto out; -+ -+ /* ignore ENOMEM */ -+ arg = kmalloc(sizeof(*arg), GFP_NOFS); -+ if (arg) { -+ /* -+ * dec(wh_running), kfree(arg) and dec(br_count) -+ * in reinit function -+ */ -+ arg->sb = sb; -+ arg->br = br; -+ au_lcnt_inc(&br->br_count); -+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0); -+ if (unlikely(wkq_err)) { -+ atomic_dec(&br->br_wbr->wbr_wh_running); -+ au_lcnt_dec(&br->br_count); -+ kfree(arg); -+ } -+ do_dec = 0; -+ } -+ -+out: -+ if (do_dec) -+ atomic_dec(&br->br_wbr->wbr_wh_running); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * create the whiteout @wh. -+ */ -+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex, -+ struct dentry *wh) -+{ -+ int err; -+ struct path h_path = { -+ .dentry = wh -+ }; -+ struct au_branch *br; -+ struct au_wbr *wbr; -+ struct dentry *h_parent; -+ struct inode *h_dir, *delegated; -+ -+ h_parent = wh->d_parent; /* dir inode is locked */ -+ h_dir = d_inode(h_parent); -+ IMustLock(h_dir); -+ -+ br = au_sbr(sb, bindex); -+ h_path.mnt = au_br_mnt(br); -+ wbr = br->br_wbr; -+ wbr_wh_read_lock(wbr); -+ if (wbr->wbr_whbase) { -+ delegated = NULL; -+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ if (!err || err != -EMLINK) -+ goto out; -+ -+ /* link count full. re-initialize br_whbase. */ -+ kick_reinit_br_wh(sb, br); -+ } -+ -+ /* return this error in this context */ -+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true); -+ if (!err) -+ au_fhsm_wrote(sb, bindex, /*force*/0); -+ -+out: -+ wbr_wh_read_unlock(wbr); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * create or remove the diropq. -+ */ -+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex, -+ unsigned int flags) -+{ -+ struct dentry *opq_dentry, *h_dentry; -+ struct super_block *sb; -+ struct au_branch *br; -+ int err; -+ -+ sb = dentry->d_sb; -+ br = au_sbr(sb, bindex); -+ h_dentry = au_h_dptr(dentry, bindex); -+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry); -+ if (IS_ERR(opq_dentry)) -+ goto out; -+ -+ if (au_ftest_diropq(flags, CREATE)) { -+ err = link_or_create_wh(sb, bindex, opq_dentry); -+ if (!err) { -+ au_set_dbdiropq(dentry, bindex); -+ goto out; /* success */ -+ } -+ } else { -+ struct path tmp = { -+ .dentry = opq_dentry, -+ .mnt = au_br_mnt(br) -+ }; -+ err = do_unlink_wh(au_h_iptr(d_inode(dentry), bindex), &tmp); -+ if (!err) -+ au_set_dbdiropq(dentry, -1); -+ } -+ dput(opq_dentry); -+ opq_dentry = ERR_PTR(err); -+ -+out: -+ return opq_dentry; -+} -+ -+struct do_diropq_args { -+ struct dentry **errp; -+ struct dentry *dentry; -+ aufs_bindex_t bindex; -+ unsigned int flags; -+}; -+ -+static void call_do_diropq(void *args) -+{ -+ struct do_diropq_args *a = args; -+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags); -+} -+ -+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, -+ unsigned int flags) -+{ -+ struct dentry *diropq, *h_dentry; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!au_test_h_perm_sio(d_inode(h_dentry), MAY_EXEC | MAY_WRITE)) -+ diropq = do_diropq(dentry, bindex, flags); -+ else { -+ int wkq_err; -+ struct do_diropq_args args = { -+ .errp = &diropq, -+ .dentry = dentry, -+ .bindex = bindex, -+ .flags = flags -+ }; -+ -+ wkq_err = au_wkq_wait(call_do_diropq, &args); -+ if (unlikely(wkq_err)) -+ diropq = ERR_PTR(wkq_err); -+ } -+ -+ return diropq; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * lookup whiteout dentry. -+ * @h_parent: lower parent dentry which must exist and be locked -+ * @base_name: name of dentry which will be whiteouted -+ * returns dentry for whiteout. -+ */ -+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, -+ struct au_branch *br) -+{ -+ int err; -+ struct qstr wh_name; -+ struct dentry *wh_dentry; -+ -+ err = au_wh_name_alloc(&wh_name, base_name); -+ wh_dentry = ERR_PTR(err); -+ if (!err) { -+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent); -+ kfree(wh_name.name); -+ } -+ return wh_dentry; -+} -+ -+/* -+ * link/create a whiteout for @dentry on @bindex. -+ */ -+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent) -+{ -+ struct dentry *wh_dentry; -+ struct super_block *sb; -+ int err; -+ -+ sb = dentry->d_sb; -+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex)); -+ if (!IS_ERR(wh_dentry) && d_is_negative(wh_dentry)) { -+ err = link_or_create_wh(sb, bindex, wh_dentry); -+ if (!err) { -+ au_set_dbwh(dentry, bindex); -+ au_fhsm_wrote(sb, bindex, /*force*/0); -+ } else { -+ dput(wh_dentry); -+ wh_dentry = ERR_PTR(err); -+ } -+ } -+ -+ return wh_dentry; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* Delete all whiteouts in this directory on branch bindex. */ -+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist, -+ aufs_bindex_t bindex, struct au_branch *br) -+{ -+ int err; -+ unsigned long ul, n; -+ struct qstr wh_name; -+ char *p; -+ struct hlist_head *head; -+ struct au_vdir_wh *pos; -+ struct au_vdir_destr *str; -+ -+ err = -ENOMEM; -+ p = (void *)__get_free_page(GFP_NOFS); -+ wh_name.name = p; -+ if (unlikely(!wh_name.name)) -+ goto out; -+ -+ err = 0; -+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); -+ p += AUFS_WH_PFX_LEN; -+ n = whlist->nh_num; -+ head = whlist->nh_head; -+ for (ul = 0; !err && ul < n; ul++, head++) { -+ hlist_for_each_entry(pos, head, wh_hash) { -+ if (pos->wh_bindex != bindex) -+ continue; -+ -+ str = &pos->wh_str; -+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) { -+ memcpy(p, str->name, str->len); -+ wh_name.len = AUFS_WH_PFX_LEN + str->len; -+ err = unlink_wh_name(h_dentry, &wh_name, br); -+ if (!err) -+ continue; -+ break; -+ } -+ AuIOErr("whiteout name too long %.*s\n", -+ str->len, str->name); -+ err = -EIO; -+ break; -+ } -+ } -+ free_page((unsigned long)wh_name.name); -+ -+out: -+ return err; -+} -+ -+struct del_wh_children_args { -+ int *errp; -+ struct dentry *h_dentry; -+ struct au_nhash *whlist; -+ aufs_bindex_t bindex; -+ struct au_branch *br; -+}; -+ -+static void call_del_wh_children(void *args) -+{ -+ struct del_wh_children_args *a = args; -+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp) -+{ -+ struct au_whtmp_rmdir *whtmp; -+ int err; -+ unsigned int rdhash; -+ -+ SiMustAnyLock(sb); -+ -+ whtmp = kzalloc(sizeof(*whtmp), gfp); -+ if (unlikely(!whtmp)) { -+ whtmp = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ -+ /* no estimation for dir size */ -+ rdhash = au_sbi(sb)->si_rdhash; -+ if (!rdhash) -+ rdhash = AUFS_RDHASH_DEF; -+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp); -+ if (unlikely(err)) { -+ kfree(whtmp); -+ whtmp = ERR_PTR(err); -+ } -+ -+out: -+ return whtmp; -+} -+ -+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp) -+{ -+ if (whtmp->br) -+ au_lcnt_dec(&whtmp->br->br_count); -+ dput(whtmp->wh_dentry); -+ iput(whtmp->dir); -+ au_nhash_wh_free(&whtmp->whlist); -+ kfree(whtmp); -+} -+ -+/* -+ * rmdir the whiteouted temporary named dir @h_dentry. -+ * @whlist: whiteouted children. -+ */ -+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, -+ struct dentry *wh_dentry, struct au_nhash *whlist) -+{ -+ int err; -+ unsigned int h_nlink; -+ struct path h_tmp; -+ struct inode *wh_inode, *h_dir; -+ struct au_branch *br; -+ -+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */ -+ IMustLock(h_dir); -+ -+ br = au_sbr(dir->i_sb, bindex); -+ wh_inode = d_inode(wh_dentry); -+ inode_lock_nested(wh_inode, AuLsc_I_CHILD); -+ -+ /* -+ * someone else might change some whiteouts while we were sleeping. -+ * it means this whlist may have an obsoleted entry. -+ */ -+ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE)) -+ err = del_wh_children(wh_dentry, whlist, bindex, br); -+ else { -+ int wkq_err; -+ struct del_wh_children_args args = { -+ .errp = &err, -+ .h_dentry = wh_dentry, -+ .whlist = whlist, -+ .bindex = bindex, -+ .br = br -+ }; -+ -+ wkq_err = au_wkq_wait(call_del_wh_children, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ inode_unlock(wh_inode); -+ -+ if (!err) { -+ h_tmp.dentry = wh_dentry; -+ h_tmp.mnt = au_br_mnt(br); -+ h_nlink = h_dir->i_nlink; -+ err = vfsub_rmdir(h_dir, &h_tmp); -+ /* some fs doesn't change the parent nlink in some cases */ -+ h_nlink -= h_dir->i_nlink; -+ } -+ -+ if (!err) { -+ if (au_ibtop(dir) == bindex) { -+ /* todo: dir->i_mutex is necessary */ -+ au_cpup_attr_timesizes(dir); -+ if (h_nlink) -+ vfsub_drop_nlink(dir); -+ } -+ return 0; /* success */ -+ } -+ -+ pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err); -+ return err; -+} -+ -+static void call_rmdir_whtmp(void *args) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct au_whtmp_rmdir *a = args; -+ struct super_block *sb; -+ struct dentry *h_parent; -+ struct inode *h_dir; -+ struct au_hinode *hdir; -+ -+ /* rmdir by nfsd may cause deadlock with this i_mutex */ -+ /* inode_lock(a->dir); */ -+ err = -EROFS; -+ sb = a->dir->i_sb; -+ si_read_lock(sb, !AuLock_FLUSH); -+ if (!au_br_writable(a->br->br_perm)) -+ goto out; -+ bindex = au_br_index(sb, a->br->br_id); -+ if (unlikely(bindex < 0)) -+ goto out; -+ -+ err = -EIO; -+ ii_write_lock_parent(a->dir); -+ h_parent = dget_parent(a->wh_dentry); -+ h_dir = d_inode(h_parent); -+ hdir = au_hi(a->dir, bindex); -+ err = vfsub_mnt_want_write(au_br_mnt(a->br)); -+ if (unlikely(err)) -+ goto out_mnt; -+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT); -+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent, -+ a->br); -+ if (!err) -+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist); -+ au_hn_inode_unlock(hdir); -+ vfsub_mnt_drop_write(au_br_mnt(a->br)); -+ -+out_mnt: -+ dput(h_parent); -+ ii_write_unlock(a->dir); -+out: -+ /* inode_unlock(a->dir); */ -+ au_whtmp_rmdir_free(a); -+ si_read_unlock(sb); -+ au_nwt_done(&au_sbi(sb)->si_nowait); -+ if (unlikely(err)) -+ AuIOErr("err %d\n", err); -+} -+ -+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, -+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args) -+{ -+ int wkq_err; -+ struct super_block *sb; -+ -+ IMustLock(dir); -+ -+ /* all post-process will be done in do_rmdir_whtmp(). */ -+ sb = dir->i_sb; -+ args->dir = au_igrab(dir); -+ args->br = au_sbr(sb, bindex); -+ au_lcnt_inc(&args->br->br_count); -+ args->wh_dentry = dget(wh_dentry); -+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0); -+ if (unlikely(wkq_err)) { -+ pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err); -+ au_whtmp_rmdir_free(args); -+ } -+} -diff --git a/fs/aufs/whout.h b/fs/aufs/whout.h -new file mode 100644 -index 000000000..2bbc38ba3 ---- /dev/null -+++ b/fs/aufs/whout.h -@@ -0,0 +1,86 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * whiteout for logical deletion and opaque directory -+ */ -+ -+#ifndef __AUFS_WHOUT_H__ -+#define __AUFS_WHOUT_H__ -+ -+#ifdef __KERNEL__ -+ -+#include "dir.h" -+ -+/* whout.c */ -+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name); -+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio); -+int au_diropq_test(struct dentry *h_dentry); -+struct au_branch; -+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br, -+ struct qstr *prefix); -+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br); -+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path, -+ struct dentry *dentry); -+int au_wh_init(struct au_branch *br, struct super_block *sb); -+ -+/* diropq flags */ -+#define AuDiropq_CREATE 1 -+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name) -+#define au_fset_diropq(flags, name) \ -+ do { (flags) |= AuDiropq_##name; } while (0) -+#define au_fclr_diropq(flags, name) \ -+ do { (flags) &= ~AuDiropq_##name; } while (0) -+ -+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, -+ unsigned int flags); -+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, -+ struct au_branch *br); -+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent); -+ -+/* real rmdir for the whiteout-ed dir */ -+struct au_whtmp_rmdir { -+ struct inode *dir; -+ struct au_branch *br; -+ struct dentry *wh_dentry; -+ struct au_nhash whlist; -+}; -+ -+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp); -+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp); -+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, -+ struct dentry *wh_dentry, struct au_nhash *whlist); -+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, -+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct dentry *au_diropq_create(struct dentry *dentry, -+ aufs_bindex_t bindex) -+{ -+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE); -+} -+ -+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE)); -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_WHOUT_H__ */ -diff --git a/fs/aufs/wkq.c b/fs/aufs/wkq.c -new file mode 100644 -index 000000000..55fab985c ---- /dev/null -+++ b/fs/aufs/wkq.c -@@ -0,0 +1,392 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * workqueue for asynchronous/super-io operations -+ * todo: try new credential scheme -+ */ -+ -+#include -+#include "aufs.h" -+ -+/* internal workqueue named AUFS_WKQ_NAME */ -+ -+static struct workqueue_struct *au_wkq; -+ -+struct au_wkinfo { -+ struct work_struct wk; -+ struct kobject *kobj; -+ -+ unsigned int flags; /* see wkq.h */ -+ -+ au_wkq_func_t func; -+ void *args; -+ -+#ifdef CONFIG_LOCKDEP -+ int dont_check; -+ struct held_lock **hlock; -+#endif -+ -+ struct completion *comp; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * Aufs passes some operations to the workqueue such as the internal copyup. -+ * This scheme looks rather unnatural for LOCKDEP debugging feature, since the -+ * job run by workqueue depends upon the locks acquired in the other task. -+ * Delegating a small operation to the workqueue, aufs passes its lockdep -+ * information too. And the job in the workqueue restores the info in order to -+ * pretend as if it acquired those locks. This is just to make LOCKDEP work -+ * correctly and expectedly. -+ */ -+ -+#ifndef CONFIG_LOCKDEP -+AuStubInt0(au_wkq_lockdep_alloc, struct au_wkinfo *wkinfo); -+AuStubVoid(au_wkq_lockdep_free, struct au_wkinfo *wkinfo); -+AuStubVoid(au_wkq_lockdep_pre, struct au_wkinfo *wkinfo); -+AuStubVoid(au_wkq_lockdep_post, struct au_wkinfo *wkinfo); -+AuStubVoid(au_wkq_lockdep_init, struct au_wkinfo *wkinfo); -+#else -+static void au_wkq_lockdep_init(struct au_wkinfo *wkinfo) -+{ -+ wkinfo->hlock = NULL; -+ wkinfo->dont_check = 0; -+} -+ -+/* -+ * 1: matched -+ * 0: unmatched -+ */ -+static int au_wkq_lockdep_test(struct lock_class_key *key, const char *name) -+{ -+ static DEFINE_SPINLOCK(spin); -+ static struct { -+ char *name; -+ struct lock_class_key *key; -+ } a[] = { -+ { .name = "&sbinfo->si_rwsem" }, -+ { .name = "&finfo->fi_rwsem" }, -+ { .name = "&dinfo->di_rwsem" }, -+ { .name = "&iinfo->ii_rwsem" } -+ }; -+ static int set; -+ int i; -+ -+ /* lockless read from 'set.' see below */ -+ if (set == ARRAY_SIZE(a)) { -+ for (i = 0; i < ARRAY_SIZE(a); i++) -+ if (a[i].key == key) -+ goto match; -+ goto unmatch; -+ } -+ -+ spin_lock(&spin); -+ if (set) -+ for (i = 0; i < ARRAY_SIZE(a); i++) -+ if (a[i].key == key) { -+ spin_unlock(&spin); -+ goto match; -+ } -+ for (i = 0; i < ARRAY_SIZE(a); i++) { -+ if (a[i].key) { -+ if (unlikely(a[i].key == key)) { /* rare but possible */ -+ spin_unlock(&spin); -+ goto match; -+ } else -+ continue; -+ } -+ if (strstr(a[i].name, name)) { -+ /* -+ * the order of these three lines is important for the -+ * lockless read above. -+ */ -+ a[i].key = key; -+ spin_unlock(&spin); -+ set++; -+ /* AuDbg("%d, %s\n", set, name); */ -+ goto match; -+ } -+ } -+ spin_unlock(&spin); -+ goto unmatch; -+ -+match: -+ return 1; -+unmatch: -+ return 0; -+} -+ -+static int au_wkq_lockdep_alloc(struct au_wkinfo *wkinfo) -+{ -+ int err, n; -+ struct task_struct *curr; -+ struct held_lock **hl, *held_locks, *p; -+ -+ err = 0; -+ curr = current; -+ wkinfo->dont_check = lockdep_recursing(curr); -+ if (wkinfo->dont_check) -+ goto out; -+ n = curr->lockdep_depth; -+ if (!n) -+ goto out; -+ -+ err = -ENOMEM; -+ wkinfo->hlock = kmalloc_array(n + 1, sizeof(*wkinfo->hlock), GFP_NOFS); -+ if (unlikely(!wkinfo->hlock)) -+ goto out; -+ -+ err = 0; -+#if 0 -+ if (0 && au_debug_test()) /* left for debugging */ -+ lockdep_print_held_locks(curr); -+#endif -+ held_locks = curr->held_locks; -+ hl = wkinfo->hlock; -+ while (n--) { -+ p = held_locks++; -+ if (au_wkq_lockdep_test(p->instance->key, p->instance->name)) -+ *hl++ = p; -+ } -+ *hl = NULL; -+ -+out: -+ return err; -+} -+ -+static void au_wkq_lockdep_free(struct au_wkinfo *wkinfo) -+{ -+ kfree(wkinfo->hlock); -+} -+ -+static void au_wkq_lockdep_pre(struct au_wkinfo *wkinfo) -+{ -+ struct held_lock *p, **hl = wkinfo->hlock; -+ int subclass; -+ -+ if (wkinfo->dont_check) -+ lockdep_off(); -+ if (!hl) -+ return; -+ while ((p = *hl++)) { /* assignment */ -+ subclass = lockdep_hlock_class(p)->subclass; -+ /* AuDbg("%s, %d\n", p->instance->name, subclass); */ -+ if (p->read) -+ rwsem_acquire_read(p->instance, subclass, 0, -+ /*p->acquire_ip*/_RET_IP_); -+ else -+ rwsem_acquire(p->instance, subclass, 0, -+ /*p->acquire_ip*/_RET_IP_); -+ } -+} -+ -+static void au_wkq_lockdep_post(struct au_wkinfo *wkinfo) -+{ -+ struct held_lock *p, **hl = wkinfo->hlock; -+ -+ if (wkinfo->dont_check) -+ lockdep_on(); -+ if (!hl) -+ return; -+ while ((p = *hl++)) /* assignment */ -+ rwsem_release(p->instance, 0, /*p->acquire_ip*/_RET_IP_); -+} -+#endif -+ -+static void wkq_func(struct work_struct *wk) -+{ -+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk); -+ -+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)); -+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY); -+ -+ au_wkq_lockdep_pre(wkinfo); -+ wkinfo->func(wkinfo->args); -+ au_wkq_lockdep_post(wkinfo); -+ if (au_ftest_wkq(wkinfo->flags, WAIT)) -+ complete(wkinfo->comp); -+ else { -+ kobject_put(wkinfo->kobj); -+ module_put(THIS_MODULE); /* todo: ?? */ -+ kfree(wkinfo); -+ } -+} -+ -+/* -+ * Since struct completion is large, try allocating it dynamically. -+ */ -+#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */ -+#define AuWkqCompDeclare(name) struct completion *comp = NULL -+ -+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) -+{ -+ *comp = kmalloc(sizeof(**comp), GFP_NOFS); -+ if (*comp) { -+ init_completion(*comp); -+ wkinfo->comp = *comp; -+ return 0; -+ } -+ return -ENOMEM; -+} -+ -+static void au_wkq_comp_free(struct completion *comp) -+{ -+ kfree(comp); -+} -+ -+#else -+ -+/* no braces */ -+#define AuWkqCompDeclare(name) \ -+ DECLARE_COMPLETION_ONSTACK(_ ## name); \ -+ struct completion *comp = &_ ## name -+ -+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) -+{ -+ wkinfo->comp = *comp; -+ return 0; -+} -+ -+static void au_wkq_comp_free(struct completion *comp __maybe_unused) -+{ -+ /* empty */ -+} -+#endif /* 4KSTACKS */ -+ -+static void au_wkq_run(struct au_wkinfo *wkinfo) -+{ -+ if (au_ftest_wkq(wkinfo->flags, NEST)) { -+ if (au_wkq_test()) { -+ AuWarn1("wkq from wkq, unless silly-rename on NFS," -+ " due to a dead dir by UDBA," -+ " or async xino write?\n"); -+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT)); -+ } -+ } else -+ au_dbg_verify_kthread(); -+ -+ if (au_ftest_wkq(wkinfo->flags, WAIT)) { -+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func); -+ queue_work(au_wkq, &wkinfo->wk); -+ } else { -+ INIT_WORK(&wkinfo->wk, wkq_func); -+ schedule_work(&wkinfo->wk); -+ } -+} -+ -+/* -+ * Be careful. It is easy to make deadlock happen. -+ * processA: lock, wkq and wait -+ * processB: wkq and wait, lock in wkq -+ * --> deadlock -+ */ -+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args) -+{ -+ int err; -+ AuWkqCompDeclare(comp); -+ struct au_wkinfo wkinfo = { -+ .flags = flags, -+ .func = func, -+ .args = args -+ }; -+ -+ err = au_wkq_comp_alloc(&wkinfo, &comp); -+ if (unlikely(err)) -+ goto out; -+ err = au_wkq_lockdep_alloc(&wkinfo); -+ if (unlikely(err)) -+ goto out_comp; -+ if (!err) { -+ au_wkq_run(&wkinfo); -+ /* no timeout, no interrupt */ -+ wait_for_completion(wkinfo.comp); -+ } -+ au_wkq_lockdep_free(&wkinfo); -+ -+out_comp: -+ au_wkq_comp_free(comp); -+out: -+ destroy_work_on_stack(&wkinfo.wk); -+ return err; -+} -+ -+/* -+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a -+ * problem in a concurrent umounting. -+ */ -+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb, -+ unsigned int flags) -+{ -+ int err; -+ struct au_wkinfo *wkinfo; -+ -+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len); -+ -+ /* -+ * wkq_func() must free this wkinfo. -+ * it highly depends upon the implementation of workqueue. -+ */ -+ err = 0; -+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS); -+ if (wkinfo) { -+ wkinfo->kobj = &au_sbi(sb)->si_kobj; -+ wkinfo->flags = flags & ~AuWkq_WAIT; -+ wkinfo->func = func; -+ wkinfo->args = args; -+ wkinfo->comp = NULL; -+ au_wkq_lockdep_init(wkinfo); -+ kobject_get(wkinfo->kobj); -+ __module_get(THIS_MODULE); /* todo: ?? */ -+ -+ au_wkq_run(wkinfo); -+ } else { -+ err = -ENOMEM; -+ au_nwt_done(&au_sbi(sb)->si_nowait); -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_nwt_init(struct au_nowait_tasks *nwt) -+{ -+ atomic_set(&nwt->nw_len, 0); -+ /* smp_mb(); */ /* atomic_set */ -+ init_waitqueue_head(&nwt->nw_wq); -+} -+ -+void au_wkq_fin(void) -+{ -+ destroy_workqueue(au_wkq); -+} -+ -+int __init au_wkq_init(void) -+{ -+ int err; -+ -+ err = 0; -+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE); -+ if (IS_ERR(au_wkq)) -+ err = PTR_ERR(au_wkq); -+ else if (!au_wkq) -+ err = -ENOMEM; -+ -+ return err; -+} -diff --git a/fs/aufs/wkq.h b/fs/aufs/wkq.h -new file mode 100644 -index 000000000..2e50ed834 ---- /dev/null -+++ b/fs/aufs/wkq.h -@@ -0,0 +1,89 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * workqueue for asynchronous/super-io operations -+ * todo: try new credentials management scheme -+ */ -+ -+#ifndef __AUFS_WKQ_H__ -+#define __AUFS_WKQ_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+struct super_block; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue -+ */ -+struct au_nowait_tasks { -+ atomic_t nw_len; -+ wait_queue_head_t nw_wq; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+typedef void (*au_wkq_func_t)(void *args); -+ -+/* wkq flags */ -+#define AuWkq_WAIT 1 -+#define AuWkq_NEST (1 << 1) -+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name) -+#define au_fset_wkq(flags, name) \ -+ do { (flags) |= AuWkq_##name; } while (0) -+#define au_fclr_wkq(flags, name) \ -+ do { (flags) &= ~AuWkq_##name; } while (0) -+ -+/* wkq.c */ -+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args); -+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb, -+ unsigned int flags); -+void au_nwt_init(struct au_nowait_tasks *nwt); -+int __init au_wkq_init(void); -+void au_wkq_fin(void); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline int au_wkq_test(void) -+{ -+ return current->flags & PF_WQ_WORKER; -+} -+ -+static inline int au_wkq_wait(au_wkq_func_t func, void *args) -+{ -+ return au_wkq_do_wait(AuWkq_WAIT, func, args); -+} -+ -+static inline void au_nwt_done(struct au_nowait_tasks *nwt) -+{ -+ if (atomic_dec_and_test(&nwt->nw_len)) -+ wake_up_all(&nwt->nw_wq); -+} -+ -+static inline int au_nwt_flush(struct au_nowait_tasks *nwt) -+{ -+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len)); -+ return 0; -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_WKQ_H__ */ -diff --git a/fs/aufs/xattr.c b/fs/aufs/xattr.c -new file mode 100644 -index 000000000..70b891716 ---- /dev/null -+++ b/fs/aufs/xattr.c -@@ -0,0 +1,356 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2014-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * handling xattr functions -+ */ -+ -+#include -+#include -+#include -+#include "aufs.h" -+ -+static int au_xattr_ignore(int err, char *name, unsigned int ignore_flags) -+{ -+ if (!ignore_flags) -+ goto out; -+ switch (err) { -+ case -ENOMEM: -+ case -EDQUOT: -+ goto out; -+ } -+ -+ if ((ignore_flags & AuBrAttr_ICEX) == AuBrAttr_ICEX) { -+ err = 0; -+ goto out; -+ } -+ -+#define cmp(brattr, prefix) do { \ -+ if (!strncmp(name, XATTR_##prefix##_PREFIX, \ -+ XATTR_##prefix##_PREFIX_LEN)) { \ -+ if (ignore_flags & AuBrAttr_ICEX_##brattr) \ -+ err = 0; \ -+ goto out; \ -+ } \ -+ } while (0) -+ -+ cmp(SEC, SECURITY); -+ cmp(SYS, SYSTEM); -+ cmp(TR, TRUSTED); -+ cmp(USR, USER); -+#undef cmp -+ -+ if (ignore_flags & AuBrAttr_ICEX_OTH) -+ err = 0; -+ -+out: -+ return err; -+} -+ -+static const int au_xattr_out_of_list = AuBrAttr_ICEX_OTH << 1; -+ -+static int au_do_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, -+ char *name, char **buf, unsigned int ignore_flags, -+ unsigned int verbose) -+{ -+ int err; -+ ssize_t ssz; -+ struct inode *h_idst; -+ -+ ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS); -+ err = ssz; -+ if (unlikely(err <= 0)) { -+ if (err == -ENODATA -+ || (err == -EOPNOTSUPP -+ && ((ignore_flags & au_xattr_out_of_list) -+ || (au_test_nfs_noacl(d_inode(h_src)) -+ && (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) -+ || !strcmp(name, -+ XATTR_NAME_POSIX_ACL_DEFAULT)))) -+ )) -+ err = 0; -+ if (err && (verbose || au_debug_test())) -+ pr_err("%s, err %d\n", name, err); -+ goto out; -+ } -+ -+ /* unlock it temporary */ -+ h_idst = d_inode(h_dst); -+ inode_unlock(h_idst); -+ err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0); -+ inode_lock_nested(h_idst, AuLsc_I_CHILD2); -+ if (unlikely(err)) { -+ if (verbose || au_debug_test()) -+ pr_err("%s, err %d\n", name, err); -+ err = au_xattr_ignore(err, name, ignore_flags); -+ } -+ -+out: -+ return err; -+} -+ -+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags, -+ unsigned int verbose) -+{ -+ int err, unlocked, acl_access, acl_default; -+ ssize_t ssz; -+ struct inode *h_isrc, *h_idst; -+ char *value, *p, *o, *e; -+ -+ /* try stopping to update the source inode while we are referencing */ -+ /* there should not be the parent-child relationship between them */ -+ h_isrc = d_inode(h_src); -+ h_idst = d_inode(h_dst); -+ inode_unlock(h_idst); -+ inode_lock_shared_nested(h_isrc, AuLsc_I_CHILD); -+ inode_lock_nested(h_idst, AuLsc_I_CHILD2); -+ unlocked = 0; -+ -+ /* some filesystems don't list POSIX ACL, for example tmpfs */ -+ ssz = vfs_listxattr(h_src, NULL, 0); -+ err = ssz; -+ if (unlikely(err < 0)) { -+ AuTraceErr(err); -+ if (err == -ENODATA -+ || err == -EOPNOTSUPP) -+ err = 0; /* ignore */ -+ goto out; -+ } -+ -+ err = 0; -+ p = NULL; -+ o = NULL; -+ if (ssz) { -+ err = -ENOMEM; -+ p = kmalloc(ssz, GFP_NOFS); -+ o = p; -+ if (unlikely(!p)) -+ goto out; -+ err = vfs_listxattr(h_src, p, ssz); -+ } -+ inode_unlock_shared(h_isrc); -+ unlocked = 1; -+ AuDbg("err %d, ssz %zd\n", err, ssz); -+ if (unlikely(err < 0)) -+ goto out_free; -+ -+ err = 0; -+ e = p + ssz; -+ value = NULL; -+ acl_access = 0; -+ acl_default = 0; -+ while (!err && p < e) { -+ acl_access |= !strncmp(p, XATTR_NAME_POSIX_ACL_ACCESS, -+ sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1); -+ acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT, -+ sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) -+ - 1); -+ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags, -+ verbose); -+ p += strlen(p) + 1; -+ } -+ AuTraceErr(err); -+ ignore_flags |= au_xattr_out_of_list; -+ if (!err && !acl_access) { -+ err = au_do_cpup_xattr(h_dst, h_src, -+ XATTR_NAME_POSIX_ACL_ACCESS, &value, -+ ignore_flags, verbose); -+ AuTraceErr(err); -+ } -+ if (!err && !acl_default) { -+ err = au_do_cpup_xattr(h_dst, h_src, -+ XATTR_NAME_POSIX_ACL_DEFAULT, &value, -+ ignore_flags, verbose); -+ AuTraceErr(err); -+ } -+ -+ kfree(value); -+ -+out_free: -+ kfree(o); -+out: -+ if (!unlocked) -+ inode_unlock_shared(h_isrc); -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_smack_reentering(struct super_block *sb) -+{ -+#if IS_ENABLED(CONFIG_SECURITY_SMACK) -+ /* -+ * as a part of lookup, smack_d_instantiate() is called, and it calls -+ * i_op->getxattr(). ouch. -+ */ -+ return si_pid_test(sb); -+#else -+ return 0; -+#endif -+} -+ -+enum { -+ AU_XATTR_LIST, -+ AU_XATTR_GET -+}; -+ -+struct au_lgxattr { -+ int type; -+ union { -+ struct { -+ char *list; -+ size_t size; -+ } list; -+ struct { -+ const char *name; -+ void *value; -+ size_t size; -+ } get; -+ } u; -+}; -+ -+static ssize_t au_lgxattr(struct dentry *dentry, struct au_lgxattr *arg) -+{ -+ ssize_t err; -+ int reenter; -+ struct path h_path; -+ struct super_block *sb; -+ -+ sb = dentry->d_sb; -+ reenter = au_smack_reentering(sb); -+ if (!reenter) { -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out; -+ } -+ err = au_h_path_getattr(dentry, /*force*/1, &h_path, reenter); -+ if (unlikely(err)) -+ goto out_si; -+ if (unlikely(!h_path.dentry)) -+ /* illegally overlapped or something */ -+ goto out_di; /* pretending success */ -+ -+ /* always topmost entry only */ -+ switch (arg->type) { -+ case AU_XATTR_LIST: -+ err = vfs_listxattr(h_path.dentry, -+ arg->u.list.list, arg->u.list.size); -+ break; -+ case AU_XATTR_GET: -+ AuDebugOn(d_is_negative(h_path.dentry)); -+ err = vfs_getxattr(h_path.dentry, -+ arg->u.get.name, arg->u.get.value, -+ arg->u.get.size); -+ break; -+ } -+ -+out_di: -+ if (!reenter) -+ di_read_unlock(dentry, AuLock_IR); -+out_si: -+ if (!reenter) -+ si_read_unlock(sb); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size) -+{ -+ struct au_lgxattr arg = { -+ .type = AU_XATTR_LIST, -+ .u.list = { -+ .list = list, -+ .size = size -+ }, -+ }; -+ -+ return au_lgxattr(dentry, &arg); -+} -+ -+static ssize_t au_getxattr(struct dentry *dentry, -+ struct inode *inode __maybe_unused, -+ const char *name, void *value, size_t size) -+{ -+ struct au_lgxattr arg = { -+ .type = AU_XATTR_GET, -+ .u.get = { -+ .name = name, -+ .value = value, -+ .size = size -+ }, -+ }; -+ -+ return au_lgxattr(dentry, &arg); -+} -+ -+static int au_setxattr(struct dentry *dentry, struct inode *inode, -+ const char *name, const void *value, size_t size, -+ int flags) -+{ -+ struct au_sxattr arg = { -+ .type = AU_XATTR_SET, -+ .u.set = { -+ .name = name, -+ .value = value, -+ .size = size, -+ .flags = flags -+ }, -+ }; -+ -+ return au_sxattr(dentry, inode, &arg); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_xattr_get(const struct xattr_handler *handler, -+ struct dentry *dentry, struct inode *inode, -+ const char *name, void *buffer, size_t size) -+{ -+ return au_getxattr(dentry, inode, name, buffer, size); -+} -+ -+static int au_xattr_set(const struct xattr_handler *handler, -+ struct dentry *dentry, struct inode *inode, -+ const char *name, const void *value, size_t size, -+ int flags) -+{ -+ return au_setxattr(dentry, inode, name, value, size, flags); -+} -+ -+static const struct xattr_handler au_xattr_handler = { -+ .name = "", -+ .prefix = "", -+ .get = au_xattr_get, -+ .set = au_xattr_set -+}; -+ -+static const struct xattr_handler *au_xattr_handlers[] = { -+#ifdef CONFIG_FS_POSIX_ACL -+ &posix_acl_access_xattr_handler, -+ &posix_acl_default_xattr_handler, -+#endif -+ &au_xattr_handler, /* must be last */ -+ NULL -+}; -+ -+void au_xattr_init(struct super_block *sb) -+{ -+ sb->s_xattr = au_xattr_handlers; -+} -diff --git a/fs/aufs/xino.c b/fs/aufs/xino.c -new file mode 100644 -index 000000000..1236699a3 ---- /dev/null -+++ b/fs/aufs/xino.c -@@ -0,0 +1,1890 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+/* -+ * external inode number translation table and bitmap -+ * -+ * things to consider -+ * - the lifetime -+ * + au_xino object -+ * + XINO files (xino, xib, xigen) -+ * + dynamic debugfs entries (xiN) -+ * + static debugfs entries (xib, xigen) -+ * + static sysfs entry (xi_path) -+ * - several entry points to handle them. -+ * + mount(2) without xino option (default) -+ * + mount(2) with xino option -+ * + mount(2) with noxino option -+ * + umount(2) -+ * + remount with add/del branches -+ * + remount with xino/noxino options -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+static aufs_bindex_t sbr_find_shared(struct super_block *sb, aufs_bindex_t btop, -+ aufs_bindex_t bbot, -+ struct super_block *h_sb) -+{ -+ /* todo: try binary-search if the branches are many */ -+ for (; btop <= bbot; btop++) -+ if (h_sb == au_sbr_sb(sb, btop)) -+ return btop; -+ return -1; -+} -+ -+/* -+ * find another branch who is on the same filesystem of the specified -+ * branch{@btgt}. search until @bbot. -+ */ -+static aufs_bindex_t is_sb_shared(struct super_block *sb, aufs_bindex_t btgt, -+ aufs_bindex_t bbot) -+{ -+ aufs_bindex_t bindex; -+ struct super_block *tgt_sb; -+ -+ tgt_sb = au_sbr_sb(sb, btgt); -+ bindex = sbr_find_shared(sb, /*btop*/0, btgt - 1, tgt_sb); -+ if (bindex < 0) -+ bindex = sbr_find_shared(sb, btgt + 1, bbot, tgt_sb); -+ -+ return bindex; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * stop unnecessary notify events at creating xino files -+ */ -+ -+aufs_bindex_t au_xi_root(struct super_block *sb, struct dentry *dentry) -+{ -+ aufs_bindex_t bfound, bindex, bbot; -+ struct dentry *parent; -+ struct au_branch *br; -+ -+ bfound = -1; -+ parent = dentry->d_parent; /* safe d_parent access */ -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_dentry(br) == parent) { -+ bfound = bindex; -+ break; -+ } -+ } -+ -+ AuDbg("bfound b%d\n", bfound); -+ return bfound; -+} -+ -+struct au_xino_lock_dir { -+ struct au_hinode *hdir; -+ struct dentry *parent; -+ struct inode *dir; -+}; -+ -+static struct dentry *au_dget_parent_lock(struct dentry *dentry, -+ unsigned int lsc) -+{ -+ struct dentry *parent; -+ struct inode *dir; -+ -+ parent = dget_parent(dentry); -+ dir = d_inode(parent); -+ inode_lock_nested(dir, lsc); -+#if 0 /* it should not happen */ -+ spin_lock(&dentry->d_lock); -+ if (unlikely(dentry->d_parent != parent)) { -+ spin_unlock(&dentry->d_lock); -+ inode_unlock(dir); -+ dput(parent); -+ parent = NULL; -+ goto out; -+ } -+ spin_unlock(&dentry->d_lock); -+ -+out: -+#endif -+ return parent; -+} -+ -+static void au_xino_lock_dir(struct super_block *sb, struct path *xipath, -+ struct au_xino_lock_dir *ldir) -+{ -+ aufs_bindex_t bindex; -+ -+ ldir->hdir = NULL; -+ bindex = au_xi_root(sb, xipath->dentry); -+ if (bindex >= 0) { -+ /* rw branch root */ -+ ldir->hdir = au_hi(d_inode(sb->s_root), bindex); -+ au_hn_inode_lock_nested(ldir->hdir, AuLsc_I_PARENT); -+ } else { -+ /* other */ -+ ldir->parent = au_dget_parent_lock(xipath->dentry, -+ AuLsc_I_PARENT); -+ ldir->dir = d_inode(ldir->parent); -+ } -+} -+ -+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir) -+{ -+ if (ldir->hdir) -+ au_hn_inode_unlock(ldir->hdir); -+ else { -+ inode_unlock(ldir->dir); -+ dput(ldir->parent); -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * create and set a new xino file -+ */ -+struct file *au_xino_create(struct super_block *sb, char *fpath, int silent) -+{ -+ struct file *file; -+ struct dentry *h_parent, *d; -+ struct inode *h_dir, *inode; -+ int err; -+ -+ /* -+ * at mount-time, and the xino file is the default path, -+ * hnotify is disabled so we have no notify events to ignore. -+ * when a user specified the xino, we cannot get au_hdir to be ignored. -+ */ -+ file = vfsub_filp_open(fpath, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE -+ /* | __FMODE_NONOTIFY */, -+ 0666); -+ if (IS_ERR(file)) { -+ if (!silent) -+ pr_err("open %s(%ld)\n", fpath, PTR_ERR(file)); -+ return file; -+ } -+ -+ /* keep file count */ -+ err = 0; -+ d = file->f_path.dentry; -+ h_parent = au_dget_parent_lock(d, AuLsc_I_PARENT); -+ /* mnt_want_write() is unnecessary here */ -+ h_dir = d_inode(h_parent); -+ inode = file_inode(file); -+ /* no delegation since it is just created */ -+ if (inode->i_nlink) -+ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL, -+ /*force*/0); -+ inode_unlock(h_dir); -+ dput(h_parent); -+ if (unlikely(err)) { -+ if (!silent) -+ pr_err("unlink %s(%d)\n", fpath, err); -+ goto out; -+ } -+ -+ err = -EINVAL; -+ if (unlikely(sb == d->d_sb)) { -+ if (!silent) -+ pr_err("%s must be outside\n", fpath); -+ goto out; -+ } -+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) { -+ if (!silent) -+ pr_err("xino doesn't support %s(%s)\n", -+ fpath, au_sbtype(d->d_sb)); -+ goto out; -+ } -+ return file; /* success */ -+ -+out: -+ fput(file); -+ file = ERR_PTR(err); -+ return file; -+} -+ -+/* -+ * create a new xinofile at the same place/path as @base. -+ */ -+struct file *au_xino_create2(struct super_block *sb, struct path *base, -+ struct file *copy_src) -+{ -+ struct file *file; -+ struct dentry *dentry, *parent; -+ struct inode *dir, *delegated; -+ struct qstr *name; -+ struct path path; -+ int err, do_unlock; -+ struct au_xino_lock_dir ldir; -+ -+ do_unlock = 1; -+ au_xino_lock_dir(sb, base, &ldir); -+ dentry = base->dentry; -+ parent = dentry->d_parent; /* dir inode is locked */ -+ dir = d_inode(parent); -+ IMustLock(dir); -+ -+ name = &dentry->d_name; -+ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len); -+ if (IS_ERR(path.dentry)) { -+ file = (void *)path.dentry; -+ pr_err("%pd lookup err %ld\n", dentry, PTR_ERR(path.dentry)); -+ goto out; -+ } -+ -+ /* no need to mnt_want_write() since we call dentry_open() later */ -+ err = vfs_create(dir, path.dentry, 0666, NULL); -+ if (unlikely(err)) { -+ file = ERR_PTR(err); -+ pr_err("%pd create err %d\n", dentry, err); -+ goto out_dput; -+ } -+ -+ path.mnt = base->mnt; -+ file = vfsub_dentry_open(&path, -+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE -+ /* | __FMODE_NONOTIFY */); -+ if (IS_ERR(file)) { -+ pr_err("%pd open err %ld\n", dentry, PTR_ERR(file)); -+ goto out_dput; -+ } -+ -+ delegated = NULL; -+ err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0); -+ au_xino_unlock_dir(&ldir); -+ do_unlock = 0; -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ if (unlikely(err)) { -+ pr_err("%pd unlink err %d\n", dentry, err); -+ goto out_fput; -+ } -+ -+ if (copy_src) { -+ /* no one can touch copy_src xino */ -+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src)); -+ if (unlikely(err)) { -+ pr_err("%pd copy err %d\n", dentry, err); -+ goto out_fput; -+ } -+ } -+ goto out_dput; /* success */ -+ -+out_fput: -+ fput(file); -+ file = ERR_PTR(err); -+out_dput: -+ dput(path.dentry); -+out: -+ if (do_unlock) -+ au_xino_unlock_dir(&ldir); -+ return file; -+} -+ -+struct file *au_xino_file1(struct au_xino *xi) -+{ -+ struct file *file; -+ unsigned int u, nfile; -+ -+ file = NULL; -+ nfile = xi->xi_nfile; -+ for (u = 0; u < nfile; u++) { -+ file = xi->xi_file[u]; -+ if (file) -+ break; -+ } -+ -+ return file; -+} -+ -+static int au_xino_file_set(struct au_xino *xi, int idx, struct file *file) -+{ -+ int err; -+ struct file *f; -+ void *p; -+ -+ if (file) -+ get_file(file); -+ -+ err = 0; -+ f = NULL; -+ if (idx < xi->xi_nfile) { -+ f = xi->xi_file[idx]; -+ if (f) -+ fput(f); -+ } else { -+ p = au_kzrealloc(xi->xi_file, -+ sizeof(*xi->xi_file) * xi->xi_nfile, -+ sizeof(*xi->xi_file) * (idx + 1), -+ GFP_NOFS, /*may_shrink*/0); -+ if (p) { -+ MtxMustLock(&xi->xi_mtx); -+ xi->xi_file = p; -+ xi->xi_nfile = idx + 1; -+ } else { -+ err = -ENOMEM; -+ if (file) -+ fput(file); -+ goto out; -+ } -+ } -+ xi->xi_file[idx] = file; -+ -+out: -+ return err; -+} -+ -+/* -+ * if @xinew->xi is not set, then create new xigen file. -+ */ -+struct file *au_xi_new(struct super_block *sb, struct au_xi_new *xinew) -+{ -+ struct file *file; -+ int err; -+ -+ SiMustAnyLock(sb); -+ -+ file = au_xino_create2(sb, xinew->base, xinew->copy_src); -+ if (IS_ERR(file)) { -+ err = PTR_ERR(file); -+ pr_err("%s[%d], err %d\n", -+ xinew->xi ? "xino" : "xigen", -+ xinew->idx, err); -+ goto out; -+ } -+ -+ if (xinew->xi) -+ err = au_xino_file_set(xinew->xi, xinew->idx, file); -+ else { -+ BUG(); -+ /* todo: make xigen file an array */ -+ /* err = au_xigen_file_set(sb, xinew->idx, file); */ -+ } -+ fput(file); -+ if (unlikely(err)) -+ file = ERR_PTR(err); -+ -+out: -+ return file; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * truncate xino files -+ */ -+static int au_xino_do_trunc(struct super_block *sb, aufs_bindex_t bindex, -+ int idx, struct kstatfs *st) -+{ -+ int err; -+ blkcnt_t blocks; -+ struct file *file, *new_xino; -+ struct au_xi_new xinew = { -+ .idx = idx -+ }; -+ -+ err = 0; -+ xinew.xi = au_sbr(sb, bindex)->br_xino; -+ file = au_xino_file(xinew.xi, idx); -+ if (!file) -+ goto out; -+ -+ xinew.base = &file->f_path; -+ err = vfs_statfs(xinew.base, st); -+ if (unlikely(err)) { -+ AuErr1("statfs err %d, ignored\n", err); -+ err = 0; -+ goto out; -+ } -+ -+ blocks = file_inode(file)->i_blocks; -+ pr_info("begin truncating xino(b%d-%d), ib%llu, %llu/%llu free blks\n", -+ bindex, idx, (u64)blocks, st->f_bfree, st->f_blocks); -+ -+ xinew.copy_src = file; -+ new_xino = au_xi_new(sb, &xinew); -+ if (IS_ERR(new_xino)) { -+ err = PTR_ERR(new_xino); -+ pr_err("xino(b%d-%d), err %d, ignored\n", bindex, idx, err); -+ goto out; -+ } -+ -+ err = vfs_statfs(&new_xino->f_path, st); -+ if (!err) -+ pr_info("end truncating xino(b%d-%d), ib%llu, %llu/%llu free blks\n", -+ bindex, idx, (u64)file_inode(new_xino)->i_blocks, -+ st->f_bfree, st->f_blocks); -+ else { -+ AuErr1("statfs err %d, ignored\n", err); -+ err = 0; -+ } -+ -+out: -+ return err; -+} -+ -+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex, int idx_begin) -+{ -+ int err, i; -+ unsigned long jiffy; -+ aufs_bindex_t bbot; -+ struct kstatfs *st; -+ struct au_branch *br; -+ struct au_xino *xi; -+ -+ err = -ENOMEM; -+ st = kmalloc(sizeof(*st), GFP_NOFS); -+ if (unlikely(!st)) -+ goto out; -+ -+ err = -EINVAL; -+ bbot = au_sbbot(sb); -+ if (unlikely(bindex < 0 || bbot < bindex)) -+ goto out_st; -+ -+ err = 0; -+ jiffy = jiffies; -+ br = au_sbr(sb, bindex); -+ xi = br->br_xino; -+ for (i = idx_begin; !err && i < xi->xi_nfile; i++) -+ err = au_xino_do_trunc(sb, bindex, i, st); -+ if (!err) -+ au_sbi(sb)->si_xino_jiffy = jiffy; -+ -+out_st: -+ kfree(st); -+out: -+ return err; -+} -+ -+struct xino_do_trunc_args { -+ struct super_block *sb; -+ struct au_branch *br; -+ int idx; -+}; -+ -+static void xino_do_trunc(void *_args) -+{ -+ struct xino_do_trunc_args *args = _args; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct inode *dir; -+ int err, idx; -+ aufs_bindex_t bindex; -+ -+ err = 0; -+ sb = args->sb; -+ dir = d_inode(sb->s_root); -+ br = args->br; -+ idx = args->idx; -+ -+ si_noflush_write_lock(sb); -+ ii_read_lock_parent(dir); -+ bindex = au_br_index(sb, br->br_id); -+ err = au_xino_trunc(sb, bindex, idx); -+ ii_read_unlock(dir); -+ if (unlikely(err)) -+ pr_warn("err b%d, (%d)\n", bindex, err); -+ atomic_dec(&br->br_xino->xi_truncating); -+ au_lcnt_dec(&br->br_count); -+ si_write_unlock(sb); -+ au_nwt_done(&au_sbi(sb)->si_nowait); -+ kfree(args); -+} -+ -+/* -+ * returns the index in the xi_file array whose corresponding file is necessary -+ * to truncate, or -1 which means no need to truncate. -+ */ -+static int xino_trunc_test(struct super_block *sb, struct au_branch *br) -+{ -+ int err; -+ unsigned int u; -+ struct kstatfs st; -+ struct au_sbinfo *sbinfo; -+ struct au_xino *xi; -+ struct file *file; -+ -+ /* todo: si_xino_expire and the ratio should be customizable */ -+ sbinfo = au_sbi(sb); -+ if (time_before(jiffies, -+ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire)) -+ return -1; -+ -+ /* truncation border */ -+ xi = br->br_xino; -+ for (u = 0; u < xi->xi_nfile; u++) { -+ file = au_xino_file(xi, u); -+ if (!file) -+ continue; -+ -+ err = vfs_statfs(&file->f_path, &st); -+ if (unlikely(err)) { -+ AuErr1("statfs err %d, ignored\n", err); -+ return -1; -+ } -+ if (div64_u64(st.f_bfree * 100, st.f_blocks) -+ >= AUFS_XINO_DEF_TRUNC) -+ return u; -+ } -+ -+ return -1; -+} -+ -+static void xino_try_trunc(struct super_block *sb, struct au_branch *br) -+{ -+ int idx; -+ struct xino_do_trunc_args *args; -+ int wkq_err; -+ -+ idx = xino_trunc_test(sb, br); -+ if (idx < 0) -+ return; -+ -+ if (atomic_inc_return(&br->br_xino->xi_truncating) > 1) -+ goto out; -+ -+ /* lock and kfree() will be called in trunc_xino() */ -+ args = kmalloc(sizeof(*args), GFP_NOFS); -+ if (unlikely(!args)) { -+ AuErr1("no memory\n"); -+ goto out; -+ } -+ -+ au_lcnt_inc(&br->br_count); -+ args->sb = sb; -+ args->br = br; -+ args->idx = idx; -+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0); -+ if (!wkq_err) -+ return; /* success */ -+ -+ pr_err("wkq %d\n", wkq_err); -+ au_lcnt_dec(&br->br_count); -+ kfree(args); -+ -+out: -+ atomic_dec(&br->br_xino->xi_truncating); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_xi_calc { -+ int idx; -+ loff_t pos; -+}; -+ -+static void au_xi_calc(struct super_block *sb, ino_t h_ino, -+ struct au_xi_calc *calc) -+{ -+ loff_t maxent; -+ -+ maxent = au_xi_maxent(sb); -+ calc->idx = div64_u64_rem(h_ino, maxent, &calc->pos); -+ calc->pos *= sizeof(ino_t); -+} -+ -+static int au_xino_do_new_async(struct super_block *sb, struct au_branch *br, -+ struct au_xi_calc *calc) -+{ -+ int err; -+ struct file *file; -+ struct au_xino *xi = br->br_xino; -+ struct au_xi_new xinew = { -+ .xi = xi -+ }; -+ -+ SiMustAnyLock(sb); -+ -+ err = 0; -+ if (!xi) -+ goto out; -+ -+ mutex_lock(&xi->xi_mtx); -+ file = au_xino_file(xi, calc->idx); -+ if (file) -+ goto out_mtx; -+ -+ file = au_xino_file(xi, /*idx*/-1); -+ AuDebugOn(!file); -+ xinew.idx = calc->idx; -+ xinew.base = &file->f_path; -+ /* xinew.copy_src = NULL; */ -+ file = au_xi_new(sb, &xinew); -+ if (IS_ERR(file)) -+ err = PTR_ERR(file); -+ -+out_mtx: -+ mutex_unlock(&xi->xi_mtx); -+out: -+ return err; -+} -+ -+struct au_xino_do_new_async_args { -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_xi_calc calc; -+ ino_t ino; -+}; -+ -+static int au_xino_do_write(vfs_writef_t write, struct file *file, -+ struct au_xi_calc *calc, ino_t ino); -+ -+static void au_xino_call_do_new_async(void *args) -+{ -+ struct au_xino_do_new_async_args *a = args; -+ struct au_branch *br; -+ struct super_block *sb; -+ struct au_sbinfo *sbi; -+ struct inode *root; -+ struct file *file; -+ int err; -+ -+ br = a->br; -+ sb = a->sb; -+ sbi = au_sbi(sb); -+ si_noflush_read_lock(sb); -+ root = d_inode(sb->s_root); -+ ii_read_lock_child(root); -+ err = au_xino_do_new_async(sb, br, &a->calc); -+ if (!err) { -+ file = au_xino_file(br->br_xino, a->calc.idx); -+ if (file) -+ err = au_xino_do_write(sbi->si_xwrite, file, &a->calc, -+ a->ino); -+ if (unlikely(err)) -+ AuIOErr("err %d\n", err); -+ } else -+ AuIOErr("err %d\n", err); -+ au_lcnt_dec(&br->br_count); -+ ii_read_unlock(root); -+ si_read_unlock(sb); -+ au_nwt_done(&sbi->si_nowait); -+ kfree(args); -+} -+ -+/* -+ * create a new xino file asynchronously -+ */ -+static int au_xino_new_async(struct super_block *sb, struct au_branch *br, -+ struct au_xi_calc *calc, ino_t ino) -+{ -+ int err; -+ struct au_xino_do_new_async_args *arg; -+ -+ err = -ENOMEM; -+ arg = kmalloc(sizeof(*arg), GFP_NOFS); -+ if (unlikely(!arg)) -+ goto out; -+ -+ arg->sb = sb; -+ arg->br = br; -+ arg->calc = *calc; -+ arg->ino = ino; -+ au_lcnt_inc(&br->br_count); -+ err = au_wkq_nowait(au_xino_call_do_new_async, arg, sb, AuWkq_NEST); -+ if (unlikely(err)) { -+ pr_err("wkq %d\n", err); -+ au_lcnt_dec(&br->br_count); -+ kfree(arg); -+ } -+ -+out: -+ return err; -+} -+ -+/* -+ * read @ino from xinofile for the specified branch{@sb, @bindex} -+ * at the position of @h_ino. -+ */ -+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ ino_t *ino) -+{ -+ int err; -+ ssize_t sz; -+ struct au_xi_calc calc; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ -+ *ino = 0; -+ if (!au_opt_test(au_mntflags(sb), XINO)) -+ return 0; /* no xino */ -+ -+ err = 0; -+ au_xi_calc(sb, h_ino, &calc); -+ file = au_xino_file(au_sbr(sb, bindex)->br_xino, calc.idx); -+ if (!file -+ || vfsub_f_size_read(file) < calc.pos + sizeof(*ino)) -+ return 0; /* no ino */ -+ -+ sbinfo = au_sbi(sb); -+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &calc.pos); -+ if (sz == sizeof(*ino)) -+ return 0; /* success */ -+ -+ err = sz; -+ if (unlikely(sz >= 0)) { -+ err = -EIO; -+ AuIOErr("xino read error (%zd)\n", sz); -+ } -+ return err; -+} -+ -+static int au_xino_do_write(vfs_writef_t write, struct file *file, -+ struct au_xi_calc *calc, ino_t ino) -+{ -+ ssize_t sz; -+ -+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &calc->pos); -+ if (sz == sizeof(ino)) -+ return 0; /* success */ -+ -+ AuIOErr("write failed (%zd)\n", sz); -+ return -EIO; -+} -+ -+/* -+ * write @ino to the xinofile for the specified branch{@sb, @bindex} -+ * at the position of @h_ino. -+ * even if @ino is zero, it is written to the xinofile and means no entry. -+ * if the size of the xino file on a specific filesystem exceeds the watermark, -+ * try truncating it. -+ */ -+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ ino_t ino) -+{ -+ int err; -+ unsigned int mnt_flags; -+ struct au_xi_calc calc; -+ struct file *file; -+ struct au_branch *br; -+ struct au_xino *xi; -+ -+ SiMustAnyLock(sb); -+ -+ mnt_flags = au_mntflags(sb); -+ if (!au_opt_test(mnt_flags, XINO)) -+ return 0; -+ -+ au_xi_calc(sb, h_ino, &calc); -+ br = au_sbr(sb, bindex); -+ xi = br->br_xino; -+ file = au_xino_file(xi, calc.idx); -+ if (!file) { -+ /* create and write a new xino file asynchronously */ -+ err = au_xino_new_async(sb, br, &calc, ino); -+ if (!err) -+ return 0; /* success */ -+ goto out; -+ } -+ -+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, file, &calc, ino); -+ if (!err) { -+ br = au_sbr(sb, bindex); -+ if (au_opt_test(mnt_flags, TRUNC_XINO) -+ && au_test_fs_trunc_xino(au_br_sb(br))) -+ xino_try_trunc(sb, br); -+ return 0; /* success */ -+ } -+ -+out: -+ AuIOErr("write failed (%d)\n", err); -+ return -EIO; -+} -+ -+static ssize_t xino_fread_wkq(vfs_readf_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos); -+ -+/* todo: unnecessary to support mmap_sem since kernel-space? */ -+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *kbuf, size_t size, -+ loff_t *pos) -+{ -+ ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ char __user *u; -+ } buf; -+ int i; -+ const int prevent_endless = 10; -+ -+ i = 0; -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ do { -+ err = func(file, buf.u, size, pos); -+ if (err == -EINTR -+ && !au_wkq_test() -+ && fatal_signal_pending(current)) { -+ set_fs(oldfs); -+ err = xino_fread_wkq(func, file, kbuf, size, pos); -+ BUG_ON(err == -EINTR); -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ } -+ } while (i++ < prevent_endless -+ && (err == -EAGAIN || err == -EINTR)); -+ set_fs(oldfs); -+ -+#if 0 /* reserved for future use */ -+ if (err > 0) -+ fsnotify_access(file->f_path.dentry); -+#endif -+ -+ return err; -+} -+ -+struct xino_fread_args { -+ ssize_t *errp; -+ vfs_readf_t func; -+ struct file *file; -+ void *buf; -+ size_t size; -+ loff_t *pos; -+}; -+ -+static void call_xino_fread(void *args) -+{ -+ struct xino_fread_args *a = args; -+ *a->errp = xino_fread(a->func, a->file, a->buf, a->size, a->pos); -+} -+ -+static ssize_t xino_fread_wkq(vfs_readf_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos) -+{ -+ ssize_t err; -+ int wkq_err; -+ struct xino_fread_args args = { -+ .errp = &err, -+ .func = func, -+ .file = file, -+ .buf = buf, -+ .size = size, -+ .pos = pos -+ }; -+ -+ wkq_err = au_wkq_wait(call_xino_fread, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ -+ return err; -+} -+ -+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos); -+ -+static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf, -+ size_t size, loff_t *pos) -+{ -+ ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ const char __user *u; -+ } buf; -+ int i; -+ const int prevent_endless = 10; -+ -+ i = 0; -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ do { -+ err = func(file, buf.u, size, pos); -+ if (err == -EINTR -+ && !au_wkq_test() -+ && fatal_signal_pending(current)) { -+ set_fs(oldfs); -+ err = xino_fwrite_wkq(func, file, kbuf, size, pos); -+ BUG_ON(err == -EINTR); -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ } -+ } while (i++ < prevent_endless -+ && (err == -EAGAIN || err == -EINTR)); -+ set_fs(oldfs); -+ -+#if 0 /* reserved for future use */ -+ if (err > 0) -+ fsnotify_modify(file->f_path.dentry); -+#endif -+ -+ return err; -+} -+ -+struct do_xino_fwrite_args { -+ ssize_t *errp; -+ vfs_writef_t func; -+ struct file *file; -+ void *buf; -+ size_t size; -+ loff_t *pos; -+}; -+ -+static void call_do_xino_fwrite(void *args) -+{ -+ struct do_xino_fwrite_args *a = args; -+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos); -+} -+ -+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos) -+{ -+ ssize_t err; -+ int wkq_err; -+ struct do_xino_fwrite_args args = { -+ .errp = &err, -+ .func = func, -+ .file = file, -+ .buf = buf, -+ .size = size, -+ .pos = pos -+ }; -+ -+ /* -+ * it breaks RLIMIT_FSIZE and normal user's limit, -+ * users should care about quota and real 'filesystem full.' -+ */ -+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ -+ return err; -+} -+ -+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos) -+{ -+ ssize_t err; -+ -+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) { -+ lockdep_off(); -+ err = do_xino_fwrite(func, file, buf, size, pos); -+ lockdep_on(); -+ } else { -+ lockdep_off(); -+ err = xino_fwrite_wkq(func, file, buf, size, pos); -+ lockdep_on(); -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * inode number bitmap -+ */ -+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE; -+static ino_t xib_calc_ino(unsigned long pindex, int bit) -+{ -+ ino_t ino; -+ -+ AuDebugOn(bit < 0 || page_bits <= bit); -+ ino = AUFS_FIRST_INO + pindex * page_bits + bit; -+ return ino; -+} -+ -+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit) -+{ -+ AuDebugOn(ino < AUFS_FIRST_INO); -+ ino -= AUFS_FIRST_INO; -+ *pindex = ino / page_bits; -+ *bit = ino % page_bits; -+} -+ -+static int xib_pindex(struct super_block *sb, unsigned long pindex) -+{ -+ int err; -+ loff_t pos; -+ ssize_t sz; -+ struct au_sbinfo *sbinfo; -+ struct file *xib; -+ unsigned long *p; -+ -+ sbinfo = au_sbi(sb); -+ MtxMustLock(&sbinfo->si_xib_mtx); -+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE -+ || !au_opt_test(sbinfo->si_mntflags, XINO)); -+ -+ if (pindex == sbinfo->si_xib_last_pindex) -+ return 0; -+ -+ xib = sbinfo->si_xib; -+ p = sbinfo->si_xib_buf; -+ pos = sbinfo->si_xib_last_pindex; -+ pos *= PAGE_SIZE; -+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); -+ if (unlikely(sz != PAGE_SIZE)) -+ goto out; -+ -+ pos = pindex; -+ pos *= PAGE_SIZE; -+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE) -+ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos); -+ else { -+ memset(p, 0, PAGE_SIZE); -+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); -+ } -+ if (sz == PAGE_SIZE) { -+ sbinfo->si_xib_last_pindex = pindex; -+ return 0; /* success */ -+ } -+ -+out: -+ AuIOErr1("write failed (%zd)\n", sz); -+ err = sz; -+ if (sz >= 0) -+ err = -EIO; -+ return err; -+} -+ -+static void au_xib_clear_bit(struct inode *inode) -+{ -+ int err, bit; -+ unsigned long pindex; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ -+ AuDebugOn(inode->i_nlink); -+ -+ sb = inode->i_sb; -+ xib_calc_bit(inode->i_ino, &pindex, &bit); -+ AuDebugOn(page_bits <= bit); -+ sbinfo = au_sbi(sb); -+ mutex_lock(&sbinfo->si_xib_mtx); -+ err = xib_pindex(sb, pindex); -+ if (!err) { -+ clear_bit(bit, sbinfo->si_xib_buf); -+ sbinfo->si_xib_next_bit = bit; -+ } -+ mutex_unlock(&sbinfo->si_xib_mtx); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * truncate a xino bitmap file -+ */ -+ -+/* todo: slow */ -+static int do_xib_restore(struct super_block *sb, struct file *file, void *page) -+{ -+ int err, bit; -+ ssize_t sz; -+ unsigned long pindex; -+ loff_t pos, pend; -+ struct au_sbinfo *sbinfo; -+ vfs_readf_t func; -+ ino_t *ino; -+ unsigned long *p; -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ MtxMustLock(&sbinfo->si_xib_mtx); -+ p = sbinfo->si_xib_buf; -+ func = sbinfo->si_xread; -+ pend = vfsub_f_size_read(file); -+ pos = 0; -+ while (pos < pend) { -+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos); -+ err = sz; -+ if (unlikely(sz <= 0)) -+ goto out; -+ -+ err = 0; -+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) { -+ if (unlikely(*ino < AUFS_FIRST_INO)) -+ continue; -+ -+ xib_calc_bit(*ino, &pindex, &bit); -+ AuDebugOn(page_bits <= bit); -+ err = xib_pindex(sb, pindex); -+ if (!err) -+ set_bit(bit, p); -+ else -+ goto out; -+ } -+ } -+ -+out: -+ return err; -+} -+ -+static int xib_restore(struct super_block *sb) -+{ -+ int err, i; -+ unsigned int nfile; -+ aufs_bindex_t bindex, bbot; -+ void *page; -+ struct au_branch *br; -+ struct au_xino *xi; -+ struct file *file; -+ -+ err = -ENOMEM; -+ page = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!page)) -+ goto out; -+ -+ err = 0; -+ bbot = au_sbbot(sb); -+ for (bindex = 0; !err && bindex <= bbot; bindex++) -+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0) { -+ br = au_sbr(sb, bindex); -+ xi = br->br_xino; -+ nfile = xi->xi_nfile; -+ for (i = 0; i < nfile; i++) { -+ file = au_xino_file(xi, i); -+ if (file) -+ err = do_xib_restore(sb, file, page); -+ } -+ } else -+ AuDbg("skip shared b%d\n", bindex); -+ free_page((unsigned long)page); -+ -+out: -+ return err; -+} -+ -+int au_xib_trunc(struct super_block *sb) -+{ -+ int err; -+ ssize_t sz; -+ loff_t pos; -+ struct au_sbinfo *sbinfo; -+ unsigned long *p; -+ struct file *file; -+ -+ SiMustWriteLock(sb); -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ if (!au_opt_test(sbinfo->si_mntflags, XINO)) -+ goto out; -+ -+ file = sbinfo->si_xib; -+ if (vfsub_f_size_read(file) <= PAGE_SIZE) -+ goto out; -+ -+ file = au_xino_create2(sb, &sbinfo->si_xib->f_path, NULL); -+ err = PTR_ERR(file); -+ if (IS_ERR(file)) -+ goto out; -+ fput(sbinfo->si_xib); -+ sbinfo->si_xib = file; -+ -+ p = sbinfo->si_xib_buf; -+ memset(p, 0, PAGE_SIZE); -+ pos = 0; -+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos); -+ if (unlikely(sz != PAGE_SIZE)) { -+ err = sz; -+ AuIOErr("err %d\n", err); -+ if (sz >= 0) -+ err = -EIO; -+ goto out; -+ } -+ -+ mutex_lock(&sbinfo->si_xib_mtx); -+ /* mnt_want_write() is unnecessary here */ -+ err = xib_restore(sb); -+ mutex_unlock(&sbinfo->si_xib_mtx); -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_xino *au_xino_alloc(unsigned int nfile) -+{ -+ struct au_xino *xi; -+ -+ xi = kzalloc(sizeof(*xi), GFP_NOFS); -+ if (unlikely(!xi)) -+ goto out; -+ xi->xi_nfile = nfile; -+ xi->xi_file = kcalloc(nfile, sizeof(*xi->xi_file), GFP_NOFS); -+ if (unlikely(!xi->xi_file)) -+ goto out_free; -+ -+ xi->xi_nondir.total = 8; /* initial size */ -+ xi->xi_nondir.array = kcalloc(xi->xi_nondir.total, sizeof(ino_t), -+ GFP_NOFS); -+ if (unlikely(!xi->xi_nondir.array)) -+ goto out_file; -+ -+ spin_lock_init(&xi->xi_nondir.spin); -+ init_waitqueue_head(&xi->xi_nondir.wqh); -+ mutex_init(&xi->xi_mtx); -+ /* init_waitqueue_head(&xi->xi_wq); */ -+ /* atomic_set(&xi->xi_pending, 0); */ -+ atomic_set(&xi->xi_truncating, 0); -+ kref_init(&xi->xi_kref); -+ goto out; /* success */ -+ -+out_file: -+ kfree(xi->xi_file); -+out_free: -+ kfree(xi); -+ xi = NULL; -+out: -+ return xi; -+} -+ -+static int au_xino_init(struct au_branch *br, int idx, struct file *file) -+{ -+ int err; -+ struct au_xino *xi; -+ -+ err = 0; -+ xi = au_xino_alloc(idx + 1); -+ if (unlikely(!xi)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ if (file) -+ get_file(file); -+ xi->xi_file[idx] = file; -+ AuDebugOn(br->br_xino); -+ br->br_xino = xi; -+ -+out: -+ return err; -+} -+ -+static void au_xino_release(struct kref *kref) -+{ -+ struct au_xino *xi; -+ int i; -+ -+ xi = container_of(kref, struct au_xino, xi_kref); -+ for (i = 0; i < xi->xi_nfile; i++) -+ if (xi->xi_file[i]) -+ fput(xi->xi_file[i]); -+ for (i = xi->xi_nondir.total - 1; i >= 0; i--) -+ AuDebugOn(xi->xi_nondir.array[i]); -+ mutex_destroy(&xi->xi_mtx); -+ kfree(xi->xi_file); -+ kfree(xi->xi_nondir.array); -+ kfree(xi); -+} -+ -+int au_xino_put(struct au_branch *br) -+{ -+ int ret; -+ struct au_xino *xi; -+ -+ ret = 0; -+ xi = br->br_xino; -+ if (xi) { -+ br->br_xino = NULL; -+ ret = kref_put(&xi->xi_kref, au_xino_release); -+ } -+ -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * xino mount option handlers -+ */ -+ -+/* xino bitmap */ -+static void xino_clear_xib(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ /* unnecessary to clear sbinfo->si_xread and ->si_xwrite */ -+ if (sbinfo->si_xib) -+ fput(sbinfo->si_xib); -+ sbinfo->si_xib = NULL; -+ if (sbinfo->si_xib_buf) -+ free_page((unsigned long)sbinfo->si_xib_buf); -+ sbinfo->si_xib_buf = NULL; -+} -+ -+static int au_xino_set_xib(struct super_block *sb, struct path *path) -+{ -+ int err; -+ loff_t pos; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ struct super_block *xi_sb; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ file = au_xino_create2(sb, path, sbinfo->si_xib); -+ err = PTR_ERR(file); -+ if (IS_ERR(file)) -+ goto out; -+ if (sbinfo->si_xib) -+ fput(sbinfo->si_xib); -+ sbinfo->si_xib = file; -+ sbinfo->si_xread = vfs_readf(file); -+ sbinfo->si_xwrite = vfs_writef(file); -+ xi_sb = file_inode(file)->i_sb; -+ sbinfo->si_ximaxent = xi_sb->s_maxbytes; -+ if (unlikely(sbinfo->si_ximaxent < PAGE_SIZE)) { -+ err = -EIO; -+ pr_err("s_maxbytes(%llu) on %s is too small\n", -+ (u64)sbinfo->si_ximaxent, au_sbtype(xi_sb)); -+ goto out_unset; -+ } -+ sbinfo->si_ximaxent /= sizeof(ino_t); -+ -+ err = -ENOMEM; -+ if (!sbinfo->si_xib_buf) -+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS); -+ if (unlikely(!sbinfo->si_xib_buf)) -+ goto out_unset; -+ -+ sbinfo->si_xib_last_pindex = 0; -+ sbinfo->si_xib_next_bit = 0; -+ if (vfsub_f_size_read(file) < PAGE_SIZE) { -+ pos = 0; -+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf, -+ PAGE_SIZE, &pos); -+ if (unlikely(err != PAGE_SIZE)) -+ goto out_free; -+ } -+ err = 0; -+ goto out; /* success */ -+ -+out_free: -+ if (sbinfo->si_xib_buf) -+ free_page((unsigned long)sbinfo->si_xib_buf); -+ sbinfo->si_xib_buf = NULL; -+ if (err >= 0) -+ err = -EIO; -+out_unset: -+ fput(sbinfo->si_xib); -+ sbinfo->si_xib = NULL; -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* xino for each branch */ -+static void xino_clear_br(struct super_block *sb) -+{ -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ AuDebugOn(!br); -+ au_xino_put(br); -+ } -+} -+ -+static void au_xino_set_br_shared(struct super_block *sb, struct au_branch *br, -+ aufs_bindex_t bshared) -+{ -+ struct au_branch *brshared; -+ -+ brshared = au_sbr(sb, bshared); -+ AuDebugOn(!brshared->br_xino); -+ AuDebugOn(!brshared->br_xino->xi_file); -+ if (br->br_xino != brshared->br_xino) { -+ au_xino_get(brshared); -+ au_xino_put(br); -+ br->br_xino = brshared->br_xino; -+ } -+} -+ -+struct au_xino_do_set_br { -+ vfs_writef_t writef; -+ struct au_branch *br; -+ ino_t h_ino; -+ aufs_bindex_t bshared; -+}; -+ -+static int au_xino_do_set_br(struct super_block *sb, struct path *path, -+ struct au_xino_do_set_br *args) -+{ -+ int err; -+ struct au_xi_calc calc; -+ struct file *file; -+ struct au_branch *br; -+ struct au_xi_new xinew = { -+ .base = path -+ }; -+ -+ br = args->br; -+ xinew.xi = br->br_xino; -+ au_xi_calc(sb, args->h_ino, &calc); -+ xinew.copy_src = au_xino_file(xinew.xi, calc.idx); -+ if (args->bshared >= 0) -+ /* shared xino */ -+ au_xino_set_br_shared(sb, br, args->bshared); -+ else if (!xinew.xi) { -+ /* new xino */ -+ err = au_xino_init(br, calc.idx, xinew.copy_src); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ /* force re-creating */ -+ xinew.xi = br->br_xino; -+ xinew.idx = calc.idx; -+ mutex_lock(&xinew.xi->xi_mtx); -+ file = au_xi_new(sb, &xinew); -+ mutex_unlock(&xinew.xi->xi_mtx); -+ err = PTR_ERR(file); -+ if (IS_ERR(file)) -+ goto out; -+ AuDebugOn(!file); -+ -+ err = au_xino_do_write(args->writef, file, &calc, AUFS_ROOT_INO); -+ if (unlikely(err)) -+ au_xino_put(br); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_xino_set_br(struct super_block *sb, struct path *path) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct au_xino_do_set_br args; -+ struct inode *inode; -+ -+ SiMustWriteLock(sb); -+ -+ bbot = au_sbbot(sb); -+ inode = d_inode(sb->s_root); -+ args.writef = au_sbi(sb)->si_xwrite; -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ args.h_ino = au_h_iptr(inode, bindex)->i_ino; -+ args.br = au_sbr(sb, bindex); -+ args.bshared = is_sb_shared(sb, bindex, bindex - 1); -+ err = au_xino_do_set_br(sb, path, &args); -+ if (unlikely(err)) -+ break; -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_xino_clr(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ au_xigen_clr(sb); -+ xino_clear_xib(sb); -+ xino_clear_br(sb); -+ dbgaufs_brs_del(sb, 0); -+ sbinfo = au_sbi(sb); -+ /* lvalue, do not call au_mntflags() */ -+ au_opt_clr(sbinfo->si_mntflags, XINO); -+} -+ -+int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt, int remount) -+{ -+ int err, skip; -+ struct dentry *dentry, *parent, *cur_dentry, *cur_parent; -+ struct qstr *dname, *cur_name; -+ struct file *cur_xino; -+ struct au_sbinfo *sbinfo; -+ struct path *path, *cur_path; -+ -+ SiMustWriteLock(sb); -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ path = &xiopt->file->f_path; -+ dentry = path->dentry; -+ parent = dget_parent(dentry); -+ if (remount) { -+ skip = 0; -+ cur_xino = sbinfo->si_xib; -+ if (cur_xino) { -+ cur_path = &cur_xino->f_path; -+ cur_dentry = cur_path->dentry; -+ cur_parent = dget_parent(cur_dentry); -+ cur_name = &cur_dentry->d_name; -+ dname = &dentry->d_name; -+ skip = (cur_parent == parent -+ && au_qstreq(dname, cur_name)); -+ dput(cur_parent); -+ } -+ if (skip) -+ goto out; -+ } -+ -+ au_opt_set(sbinfo->si_mntflags, XINO); -+ err = au_xino_set_xib(sb, path); -+ /* si_x{read,write} are set */ -+ if (!err) -+ err = au_xigen_set(sb, path); -+ if (!err) -+ err = au_xino_set_br(sb, path); -+ if (!err) { -+ dbgaufs_brs_add(sb, 0, /*topdown*/1); -+ goto out; /* success */ -+ } -+ -+ /* reset all */ -+ AuIOErr("failed setting xino(%d).\n", err); -+ au_xino_clr(sb); -+ -+out: -+ dput(parent); -+ return err; -+} -+ -+/* -+ * create a xinofile at the default place/path. -+ */ -+struct file *au_xino_def(struct super_block *sb) -+{ -+ struct file *file; -+ char *page, *p; -+ struct au_branch *br; -+ struct super_block *h_sb; -+ struct path path; -+ aufs_bindex_t bbot, bindex, bwr; -+ -+ br = NULL; -+ bbot = au_sbbot(sb); -+ bwr = -1; -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_writable(br->br_perm) -+ && !au_test_fs_bad_xino(au_br_sb(br))) { -+ bwr = bindex; -+ break; -+ } -+ } -+ -+ if (bwr >= 0) { -+ file = ERR_PTR(-ENOMEM); -+ page = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!page)) -+ goto out; -+ path.mnt = au_br_mnt(br); -+ path.dentry = au_h_dptr(sb->s_root, bwr); -+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME)); -+ file = (void *)p; -+ if (!IS_ERR(p)) { -+ strcat(p, "/" AUFS_XINO_FNAME); -+ AuDbg("%s\n", p); -+ file = au_xino_create(sb, p, /*silent*/0); -+ } -+ free_page((unsigned long)page); -+ } else { -+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0); -+ if (IS_ERR(file)) -+ goto out; -+ h_sb = file->f_path.dentry->d_sb; -+ if (unlikely(au_test_fs_bad_xino(h_sb))) { -+ pr_err("xino doesn't support %s(%s)\n", -+ AUFS_XINO_DEFPATH, au_sbtype(h_sb)); -+ fput(file); -+ file = ERR_PTR(-EINVAL); -+ } -+ } -+ -+out: -+ return file; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * initialize the xinofile for the specified branch @br -+ * at the place/path where @base_file indicates. -+ * test whether another branch is on the same filesystem or not, -+ * if found then share the xinofile with another branch. -+ */ -+int au_xino_init_br(struct super_block *sb, struct au_branch *br, ino_t h_ino, -+ struct path *base) -+{ -+ int err; -+ struct au_xino_do_set_br args = { -+ .h_ino = h_ino, -+ .br = br -+ }; -+ -+ args.writef = au_sbi(sb)->si_xwrite; -+ args.bshared = sbr_find_shared(sb, /*btop*/0, au_sbbot(sb), -+ au_br_sb(br)); -+ err = au_xino_do_set_br(sb, base, &args); -+ if (unlikely(err)) -+ au_xino_put(br); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * get an unused inode number from bitmap -+ */ -+ino_t au_xino_new_ino(struct super_block *sb) -+{ -+ ino_t ino; -+ unsigned long *p, pindex, ul, pend; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ int free_bit, err; -+ -+ if (!au_opt_test(au_mntflags(sb), XINO)) -+ return iunique(sb, AUFS_FIRST_INO); -+ -+ sbinfo = au_sbi(sb); -+ mutex_lock(&sbinfo->si_xib_mtx); -+ p = sbinfo->si_xib_buf; -+ free_bit = sbinfo->si_xib_next_bit; -+ if (free_bit < page_bits && !test_bit(free_bit, p)) -+ goto out; /* success */ -+ free_bit = find_first_zero_bit(p, page_bits); -+ if (free_bit < page_bits) -+ goto out; /* success */ -+ -+ pindex = sbinfo->si_xib_last_pindex; -+ for (ul = pindex - 1; ul < ULONG_MAX; ul--) { -+ err = xib_pindex(sb, ul); -+ if (unlikely(err)) -+ goto out_err; -+ free_bit = find_first_zero_bit(p, page_bits); -+ if (free_bit < page_bits) -+ goto out; /* success */ -+ } -+ -+ file = sbinfo->si_xib; -+ pend = vfsub_f_size_read(file) / PAGE_SIZE; -+ for (ul = pindex + 1; ul <= pend; ul++) { -+ err = xib_pindex(sb, ul); -+ if (unlikely(err)) -+ goto out_err; -+ free_bit = find_first_zero_bit(p, page_bits); -+ if (free_bit < page_bits) -+ goto out; /* success */ -+ } -+ BUG(); -+ -+out: -+ set_bit(free_bit, p); -+ sbinfo->si_xib_next_bit = free_bit + 1; -+ pindex = sbinfo->si_xib_last_pindex; -+ mutex_unlock(&sbinfo->si_xib_mtx); -+ ino = xib_calc_ino(pindex, free_bit); -+ AuDbg("i%lu\n", (unsigned long)ino); -+ return ino; -+out_err: -+ mutex_unlock(&sbinfo->si_xib_mtx); -+ AuDbg("i0\n"); -+ return 0; -+} -+ -+/* for s_op->delete_inode() */ -+void au_xino_delete_inode(struct inode *inode, const int unlinked) -+{ -+ int err; -+ unsigned int mnt_flags; -+ aufs_bindex_t bindex, bbot, bi; -+ unsigned char try_trunc; -+ struct au_iinfo *iinfo; -+ struct super_block *sb; -+ struct au_hinode *hi; -+ struct inode *h_inode; -+ struct au_branch *br; -+ vfs_writef_t xwrite; -+ struct au_xi_calc calc; -+ struct file *file; -+ -+ AuDebugOn(au_is_bad_inode(inode)); -+ -+ sb = inode->i_sb; -+ mnt_flags = au_mntflags(sb); -+ if (!au_opt_test(mnt_flags, XINO) -+ || inode->i_ino == AUFS_ROOT_INO) -+ return; -+ -+ if (unlinked) { -+ au_xigen_inc(inode); -+ au_xib_clear_bit(inode); -+ } -+ -+ iinfo = au_ii(inode); -+ bindex = iinfo->ii_btop; -+ if (bindex < 0) -+ return; -+ -+ xwrite = au_sbi(sb)->si_xwrite; -+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO); -+ hi = au_hinode(iinfo, bindex); -+ bbot = iinfo->ii_bbot; -+ for (; bindex <= bbot; bindex++, hi++) { -+ h_inode = hi->hi_inode; -+ if (!h_inode -+ || (!unlinked && h_inode->i_nlink)) -+ continue; -+ -+ /* inode may not be revalidated */ -+ bi = au_br_index(sb, hi->hi_id); -+ if (bi < 0) -+ continue; -+ -+ br = au_sbr(sb, bi); -+ au_xi_calc(sb, h_inode->i_ino, &calc); -+ file = au_xino_file(br->br_xino, calc.idx); -+ if (IS_ERR_OR_NULL(file)) -+ continue; -+ -+ err = au_xino_do_write(xwrite, file, &calc, /*ino*/0); -+ if (!err && try_trunc -+ && au_test_fs_trunc_xino(au_br_sb(br))) -+ xino_try_trunc(sb, br); -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_xinondir_find(struct au_xino *xi, ino_t h_ino) -+{ -+ int found, total, i; -+ -+ found = -1; -+ total = xi->xi_nondir.total; -+ for (i = 0; i < total; i++) { -+ if (xi->xi_nondir.array[i] != h_ino) -+ continue; -+ found = i; -+ break; -+ } -+ -+ return found; -+} -+ -+static int au_xinondir_expand(struct au_xino *xi) -+{ -+ int err, sz; -+ ino_t *p; -+ -+ BUILD_BUG_ON(KMALLOC_MAX_SIZE > INT_MAX); -+ -+ err = -ENOMEM; -+ sz = xi->xi_nondir.total * sizeof(ino_t); -+ if (unlikely(sz > KMALLOC_MAX_SIZE / 2)) -+ goto out; -+ p = au_kzrealloc(xi->xi_nondir.array, sz, sz << 1, GFP_ATOMIC, -+ /*may_shrink*/0); -+ if (p) { -+ xi->xi_nondir.array = p; -+ xi->xi_nondir.total <<= 1; -+ AuDbg("xi_nondir.total %d\n", xi->xi_nondir.total); -+ err = 0; -+ } -+ -+out: -+ return err; -+} -+ -+void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex, -+ ino_t h_ino, int idx) -+{ -+ struct au_xino *xi; -+ -+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO)); -+ xi = au_sbr(sb, bindex)->br_xino; -+ AuDebugOn(idx < 0 || xi->xi_nondir.total <= idx); -+ -+ spin_lock(&xi->xi_nondir.spin); -+ AuDebugOn(xi->xi_nondir.array[idx] != h_ino); -+ xi->xi_nondir.array[idx] = 0; -+ spin_unlock(&xi->xi_nondir.spin); -+ wake_up_all(&xi->xi_nondir.wqh); -+} -+ -+int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ int *idx) -+{ -+ int err, found, empty; -+ struct au_xino *xi; -+ -+ err = 0; -+ *idx = -1; -+ if (!au_opt_test(au_mntflags(sb), XINO)) -+ goto out; /* no xino */ -+ -+ xi = au_sbr(sb, bindex)->br_xino; -+ -+again: -+ spin_lock(&xi->xi_nondir.spin); -+ found = au_xinondir_find(xi, h_ino); -+ if (found == -1) { -+ empty = au_xinondir_find(xi, /*h_ino*/0); -+ if (empty == -1) { -+ empty = xi->xi_nondir.total; -+ err = au_xinondir_expand(xi); -+ if (unlikely(err)) -+ goto out_unlock; -+ } -+ xi->xi_nondir.array[empty] = h_ino; -+ *idx = empty; -+ } else { -+ spin_unlock(&xi->xi_nondir.spin); -+ wait_event(xi->xi_nondir.wqh, -+ xi->xi_nondir.array[found] != h_ino); -+ goto again; -+ } -+ -+out_unlock: -+ spin_unlock(&xi->xi_nondir.spin); -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_xino_path(struct seq_file *seq, struct file *file) -+{ -+ int err; -+ -+ err = au_seq_path(seq, &file->f_path); -+ if (unlikely(err)) -+ goto out; -+ -+#define Deleted "\\040(deleted)" -+ seq->count -= sizeof(Deleted) - 1; -+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted, -+ sizeof(Deleted) - 1)); -+#undef Deleted -+ -+out: -+ return err; -+} -diff --git a/fs/dcache.c b/fs/dcache.c -index 2e7e8d85e..328a13662 100644 ---- a/fs/dcache.c -+++ b/fs/dcache.c -@@ -1238,7 +1238,7 @@ enum d_walk_ret { - * - * The @enter() callbacks are called with d_lock held. - */ --static void d_walk(struct dentry *parent, void *data, -+void d_walk(struct dentry *parent, void *data, - enum d_walk_ret (*enter)(void *, struct dentry *)) - { - struct dentry *this_parent; -@@ -1343,6 +1343,7 @@ static void d_walk(struct dentry *parent, void *data, - seq = 1; - goto again; - } -+EXPORT_SYMBOL_GPL(d_walk); - - struct check_mount { - struct vfsmount *mnt; -@@ -2837,6 +2838,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2) - - write_sequnlock(&rename_lock); - } -+EXPORT_SYMBOL_GPL(d_exchange); - - /** - * d_ancestor - search for an ancestor -diff --git a/fs/exec.c b/fs/exec.c -index 1ebf6e5a5..a72c29465 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -109,6 +109,7 @@ bool path_noexec(const struct path *path) - return (path->mnt->mnt_flags & MNT_NOEXEC) || - (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC); - } -+EXPORT_SYMBOL_GPL(path_noexec); - - #ifdef CONFIG_USELIB - /* -diff --git a/fs/fcntl.c b/fs/fcntl.c -index 4137d9653..77513097f 100644 ---- a/fs/fcntl.c -+++ b/fs/fcntl.c -@@ -32,7 +32,7 @@ - - #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME) - --static int setfl(int fd, struct file * filp, unsigned long arg) -+int setfl(int fd, struct file * filp, unsigned long arg) - { - struct inode * inode = file_inode(filp); - int error = 0; -@@ -63,6 +63,8 @@ static int setfl(int fd, struct file * filp, unsigned long arg) - - if (filp->f_op->check_flags) - error = filp->f_op->check_flags(arg); -+ if (!error && filp->f_op->setfl) -+ error = filp->f_op->setfl(filp, arg); - if (error) - return error; - -@@ -83,6 +85,7 @@ static int setfl(int fd, struct file * filp, unsigned long arg) - out: - return error; - } -+EXPORT_SYMBOL_GPL(setfl); - - static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, - int force) -diff --git a/fs/file_table.c b/fs/file_table.c -index e49af4caf..569020fd1 100644 ---- a/fs/file_table.c -+++ b/fs/file_table.c -@@ -161,6 +161,7 @@ struct file *alloc_empty_file(int flags, const struct cred *cred) - } - return ERR_PTR(-ENFILE); - } -+EXPORT_SYMBOL_GPL(alloc_empty_file); - - /* - * Variant of alloc_empty_file() that doesn't check and modify nr_files. -@@ -323,6 +324,7 @@ void flush_delayed_fput(void) - { - delayed_fput(NULL); - } -+EXPORT_SYMBOL_GPL(flush_delayed_fput); - - static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput); - -@@ -365,6 +367,7 @@ void __fput_sync(struct file *file) - } - - EXPORT_SYMBOL(fput); -+EXPORT_SYMBOL_GPL(__fput_sync); - - void __init files_init(void) - { -diff --git a/fs/inode.c b/fs/inode.c -index 42f6d25f3..69d4a6cde 100644 ---- a/fs/inode.c -+++ b/fs/inode.c -@@ -1657,7 +1657,7 @@ EXPORT_SYMBOL(generic_update_time); - * This does the actual work of updating an inodes time or version. Must have - * had called mnt_want_write() before calling this. - */ --static int update_time(struct inode *inode, struct timespec64 *time, int flags) -+int update_time(struct inode *inode, struct timespec64 *time, int flags) - { - int (*update_time)(struct inode *, struct timespec64 *, int); - -@@ -1666,6 +1666,7 @@ static int update_time(struct inode *inode, struct timespec64 *time, int flags) - - return update_time(inode, time, flags); - } -+EXPORT_SYMBOL_GPL(update_time); - - /** - * touch_atime - update the access time -diff --git a/fs/namespace.c b/fs/namespace.c -index 99186556f..c49803ce0 100644 ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -437,6 +437,7 @@ void __mnt_drop_write(struct vfsmount *mnt) - mnt_dec_writers(real_mount(mnt)); - preempt_enable(); - } -+EXPORT_SYMBOL_GPL(__mnt_drop_write); - - /** - * mnt_drop_write - give up write access to a mount -@@ -770,6 +771,13 @@ static inline int check_mnt(struct mount *mnt) - return mnt->mnt_ns == current->nsproxy->mnt_ns; - } - -+/* for aufs, CONFIG_AUFS_BR_FUSE */ -+int is_current_mnt_ns(struct vfsmount *mnt) -+{ -+ return check_mnt(real_mount(mnt)); -+} -+EXPORT_SYMBOL_GPL(is_current_mnt_ns); -+ - /* - * vfsmount lock must be held for write - */ -@@ -1826,6 +1834,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, - } - return 0; - } -+EXPORT_SYMBOL_GPL(iterate_mounts); - - static void cleanup_group_ids(struct mount *mnt, struct mount *end) - { -diff --git a/fs/notify/group.c b/fs/notify/group.c -index c03b83662..817f22c6e 100644 ---- a/fs/notify/group.c -+++ b/fs/notify/group.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include - #include "fsnotify.h" -@@ -112,6 +113,7 @@ void fsnotify_get_group(struct fsnotify_group *group) - { - refcount_inc(&group->refcnt); - } -+EXPORT_SYMBOL_GPL(fsnotify_get_group); - - /* - * Drop a reference to a group. Free it if it's through. -@@ -121,6 +123,7 @@ void fsnotify_put_group(struct fsnotify_group *group) - if (refcount_dec_and_test(&group->refcnt)) - fsnotify_final_destroy_group(group); - } -+EXPORT_SYMBOL_GPL(fsnotify_put_group); - - /* - * Create a new fsnotify_group and hold a reference for the group returned. -@@ -150,6 +153,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops) - - return group; - } -+EXPORT_SYMBOL_GPL(fsnotify_alloc_group); - - int fsnotify_fasync(int fd, struct file *file, int on) - { -diff --git a/fs/notify/mark.c b/fs/notify/mark.c -index 59cdb2782..ce365c73f 100644 ---- a/fs/notify/mark.c -+++ b/fs/notify/mark.c -@@ -263,6 +263,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark) - queue_delayed_work(system_unbound_wq, &reaper_work, - FSNOTIFY_REAPER_DELAY); - } -+EXPORT_SYMBOL_GPL(fsnotify_put_mark); - - /* - * Get mark reference when we found the mark via lockless traversal of object -@@ -417,6 +418,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark, - mutex_unlock(&group->mark_mutex); - fsnotify_free_mark(mark); - } -+EXPORT_SYMBOL_GPL(fsnotify_destroy_mark); - - /* - * Sorting function for lists of fsnotify marks. -@@ -632,6 +634,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, fsnotify_connp_t *connp, - mutex_unlock(&group->mark_mutex); - return ret; - } -+EXPORT_SYMBOL_GPL(fsnotify_add_mark); - - /* - * Given a list of marks, find the mark associated with given group. If found -@@ -754,6 +757,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark, - fsnotify_get_group(group); - mark->group = group; - } -+EXPORT_SYMBOL_GPL(fsnotify_init_mark); - - /* - * Destroy all marks in destroy_list, waits for SRCU period to finish before -diff --git a/fs/open.c b/fs/open.c -index 0285ce7db..cb81623a8 100644 ---- a/fs/open.c -+++ b/fs/open.c -@@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, - inode_unlock(dentry->d_inode); - return ret; - } -+EXPORT_SYMBOL_GPL(do_truncate); - - long vfs_truncate(const struct path *path, loff_t length) - { -diff --git a/fs/proc/base.c b/fs/proc/base.c -index 7e9f07bf2..3ab590110 100644 ---- a/fs/proc/base.c -+++ b/fs/proc/base.c -@@ -2016,7 +2016,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path) - down_read(&mm->mmap_sem); - vma = find_exact_vma(mm, vm_start, vm_end); - if (vma && vma->vm_file) { -- *path = vma->vm_file->f_path; -+ *path = vma_pr_or_file(vma)->f_path; - path_get(path); - rc = 0; - } -diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c -index 3b63be64e..fb9913bf3 100644 ---- a/fs/proc/nommu.c -+++ b/fs/proc/nommu.c -@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region) - file = region->vm_file; - - if (file) { -- struct inode *inode = file_inode(region->vm_file); -+ struct inode *inode; -+ -+ file = vmr_pr_or_file(region); -+ inode = file_inode(file); - dev = inode->i_sb->s_dev; - ino = inode->i_ino; - } -diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c -index 5ea1d64cb..7865a4707 100644 ---- a/fs/proc/task_mmu.c -+++ b/fs/proc/task_mmu.c -@@ -305,7 +305,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) - const char *name = NULL; - - if (file) { -- struct inode *inode = file_inode(vma->vm_file); -+ struct inode *inode; -+ -+ file = vma_pr_or_file(vma); -+ inode = file_inode(file); - dev = inode->i_sb->s_dev; - ino = inode->i_ino; - pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT; -@@ -1727,7 +1730,7 @@ static int show_numa_map(struct seq_file *m, void *v) - struct proc_maps_private *proc_priv = &numa_priv->proc_maps; - struct vm_area_struct *vma = v; - struct numa_maps *md = &numa_priv->md; -- struct file *file = vma->vm_file; -+ struct file *file = vma_pr_or_file(vma); - struct mm_struct *mm = vma->vm_mm; - struct mm_walk walk = { - .hugetlb_entry = gather_hugetlb_stats, -diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c -index 0b63d68de..400d1c594 100644 ---- a/fs/proc/task_nommu.c -+++ b/fs/proc/task_nommu.c -@@ -155,7 +155,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) - file = vma->vm_file; - - if (file) { -- struct inode *inode = file_inode(vma->vm_file); -+ struct inode *inode; -+ -+ file = vma_pr_or_file(vma); -+ inode = file_inode(file); - dev = inode->i_sb->s_dev; - ino = inode->i_ino; - pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT; -diff --git a/fs/read_write.c b/fs/read_write.c -index 8a2737f0d..d9cb9690e 100644 ---- a/fs/read_write.c -+++ b/fs/read_write.c -@@ -459,6 +459,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) - - return ret; - } -+EXPORT_SYMBOL_GPL(vfs_read); - - static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) - { -@@ -489,6 +490,30 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count, - return -EINVAL; - } - -+vfs_readf_t vfs_readf(struct file *file) -+{ -+ const struct file_operations *fop = file->f_op; -+ -+ if (fop->read) -+ return fop->read; -+ if (fop->read_iter) -+ return new_sync_read; -+ return ERR_PTR(-ENOSYS); -+} -+EXPORT_SYMBOL_GPL(vfs_readf); -+ -+vfs_writef_t vfs_writef(struct file *file) -+{ -+ const struct file_operations *fop = file->f_op; -+ -+ if (fop->write) -+ return fop->write; -+ if (fop->write_iter) -+ return new_sync_write; -+ return ERR_PTR(-ENOSYS); -+} -+EXPORT_SYMBOL_GPL(vfs_writef); -+ - ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) - { - mm_segment_t old_fs; -@@ -557,6 +582,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ - - return ret; - } -+EXPORT_SYMBOL_GPL(vfs_write); - - static inline loff_t file_pos_read(struct file *file) - { -diff --git a/fs/splice.c b/fs/splice.c -index b3daa971f..a5e3bcba0 100644 ---- a/fs/splice.c -+++ b/fs/splice.c -@@ -838,8 +838,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); - /* - * Attempt to initiate a splice from pipe to file. - */ --static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, -- loff_t *ppos, size_t len, unsigned int flags) -+long do_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags) - { - ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, - loff_t *, size_t, unsigned int); -@@ -851,13 +851,14 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, - - return splice_write(pipe, out, ppos, len, flags); - } -+EXPORT_SYMBOL_GPL(do_splice_from); - - /* - * Attempt to initiate a splice from a file to a pipe. - */ --static long do_splice_to(struct file *in, loff_t *ppos, -- struct pipe_inode_info *pipe, size_t len, -- unsigned int flags) -+long do_splice_to(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags) - { - ssize_t (*splice_read)(struct file *, loff_t *, - struct pipe_inode_info *, size_t, unsigned int); -@@ -880,6 +881,7 @@ static long do_splice_to(struct file *in, loff_t *ppos, - - return splice_read(in, ppos, pipe, len, flags); - } -+EXPORT_SYMBOL_GPL(do_splice_to); - - /** - * splice_direct_to_actor - splices data directly between two non-pipes -diff --git a/fs/sync.c b/fs/sync.c -index b54e0541a..ffd7ea438 100644 ---- a/fs/sync.c -+++ b/fs/sync.c -@@ -28,7 +28,7 @@ - * wait == 1 case since in that case write_inode() functions do - * sync_dirty_buffer() and thus effectively write one block at a time. - */ --static int __sync_filesystem(struct super_block *sb, int wait) -+int __sync_filesystem(struct super_block *sb, int wait) - { - if (wait) - sync_inodes_sb(sb); -@@ -39,6 +39,7 @@ static int __sync_filesystem(struct super_block *sb, int wait) - sb->s_op->sync_fs(sb, wait); - return __sync_blockdev(sb->s_bdev, wait); - } -+EXPORT_SYMBOL_GPL(__sync_filesystem); - - /* - * Write out and wait upon all dirty data associated with this -diff --git a/fs/xattr.c b/fs/xattr.c -index 0d6a6a4af..7ce4701b7 100644 ---- a/fs/xattr.c -+++ b/fs/xattr.c -@@ -295,6 +295,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, - *xattr_value = value; - return error; - } -+EXPORT_SYMBOL_GPL(vfs_getxattr_alloc); - - ssize_t - __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name, -diff --git a/include/linux/fs.h b/include/linux/fs.h -index 897eae8fa..7fb92a99e 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1286,6 +1286,7 @@ extern void fasync_free(struct fasync_struct *); - /* can be called from interrupts */ - extern void kill_fasync(struct fasync_struct **, int, int); - -+extern int setfl(int fd, struct file * filp, unsigned long arg); - extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force); - extern int f_setown(struct file *filp, unsigned long arg, int force); - extern void f_delown(struct file *filp); -@@ -1747,6 +1748,7 @@ struct file_operations { - ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); - unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); - int (*check_flags)(int); -+ int (*setfl)(struct file *, unsigned long); - int (*flock) (struct file *, int, struct file_lock *); - ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); - ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); -@@ -1818,6 +1820,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, - struct iovec *fast_pointer, - struct iovec **ret_pointer); - -+typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *); -+typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t, -+ loff_t *); -+vfs_readf_t vfs_readf(struct file *file); -+vfs_writef_t vfs_writef(struct file *file); -+ - extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *); - extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); - extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); -@@ -2243,6 +2251,7 @@ extern int current_umask(void); - extern void ihold(struct inode * inode); - extern void iput(struct inode *); - extern int generic_update_time(struct inode *, struct timespec64 *, int); -+extern int update_time(struct inode *, struct timespec64 *, int); - - /* /sys/fs */ - extern struct kobject *fs_kobj; -@@ -2530,6 +2539,7 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb) - return false; - } - #endif -+extern int __sync_filesystem(struct super_block *, int); - extern int sync_filesystem(struct super_block *); - extern const struct file_operations def_blk_fops; - extern const struct file_operations def_chr_fops; -diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h -index b0d0b51c4..f73ffaa01 100644 ---- a/include/linux/lockdep.h -+++ b/include/linux/lockdep.h -@@ -313,6 +313,8 @@ static inline int lockdep_match_key(struct lockdep_map *lock, - return lock->key == key; - } - -+struct lock_class *lockdep_hlock_class(struct held_lock *hlock); -+ - /* - * Acquire a lock. - * -@@ -439,6 +441,7 @@ struct lockdep_map { }; - - #define lockdep_depth(tsk) (0) - -+#define lockdep_is_held(lock) (1) - #define lockdep_is_held_type(l, r) (1) - - #define lockdep_assert_held(l) do { (void)(l); } while (0) -diff --git a/include/linux/mm.h b/include/linux/mm.h -index 0416a7204..4a298a926 100644 ---- a/include/linux/mm.h -+++ b/include/linux/mm.h -@@ -1440,6 +1440,28 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping, - unmap_mapping_range(mapping, holebegin, holelen, 0); - } - -+extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int); -+extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[], -+ int); -+extern void vma_do_get_file(struct vm_area_struct *, const char[], int); -+extern void vma_do_fput(struct vm_area_struct *, const char[], int); -+ -+#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \ -+ __LINE__) -+#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \ -+ __LINE__) -+#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__) -+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__) -+ -+#ifndef CONFIG_MMU -+extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int); -+extern void vmr_do_fput(struct vm_region *, const char[], int); -+ -+#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \ -+ __LINE__) -+#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__) -+#endif /* !CONFIG_MMU */ -+ - extern int access_process_vm(struct task_struct *tsk, unsigned long addr, - void *buf, int len, unsigned int gup_flags); - extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, -diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h -index 5ed8f6292..012297540 100644 ---- a/include/linux/mm_types.h -+++ b/include/linux/mm_types.h -@@ -239,6 +239,7 @@ struct vm_region { - unsigned long vm_top; /* region allocated to here */ - unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */ - struct file *vm_file; /* the backing file or NULL */ -+ struct file *vm_prfile; /* the virtual backing file or NULL */ - - int vm_usage; /* region usage count (access under nommu_region_sem) */ - bool vm_icache_flushed : 1; /* true if the icache has been flushed for -@@ -313,6 +314,7 @@ struct vm_area_struct { - unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE - units */ - struct file * vm_file; /* File we map to (can be NULL). */ -+ struct file *vm_prfile; /* shadow of vm_file */ - void * vm_private_data; /* was vm_pte (shared mem) */ - - atomic_long_t swap_readahead_info; -diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h -index 35942084c..24f5fd1a7 100644 ---- a/include/linux/mnt_namespace.h -+++ b/include/linux/mnt_namespace.h -@@ -6,11 +6,14 @@ - struct mnt_namespace; - struct fs_struct; - struct user_namespace; -+struct vfsmount; - - extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *, - struct user_namespace *, struct fs_struct *); - extern void put_mnt_ns(struct mnt_namespace *ns); - -+extern int is_current_mnt_ns(struct vfsmount *mnt); -+ - extern const struct file_operations proc_mounts_operations; - extern const struct file_operations proc_mountinfo_operations; - extern const struct file_operations proc_mountstats_operations; -diff --git a/include/linux/splice.h b/include/linux/splice.h -index 74b4911ac..19789fbea 100644 ---- a/include/linux/splice.h -+++ b/include/linux/splice.h -@@ -87,4 +87,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *); - - extern const struct pipe_buf_operations page_cache_pipe_buf_ops; - extern const struct pipe_buf_operations default_pipe_buf_ops; -+ -+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags); -+extern long do_splice_to(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags); - #endif -diff --git a/include/uapi/linux/aufs_type.h b/include/uapi/linux/aufs_type.h -new file mode 100644 -index 000000000..8958f874b ---- /dev/null -+++ b/include/uapi/linux/aufs_type.h -@@ -0,0 +1,448 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs 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, see . -+ */ -+ -+#ifndef __AUFS_TYPE_H__ -+#define __AUFS_TYPE_H__ -+ -+#define AUFS_NAME "aufs" -+ -+#ifdef __KERNEL__ -+/* -+ * define it before including all other headers. -+ * sched.h may use pr_* macros before defining "current", so define the -+ * no-current version first, and re-define later. -+ */ -+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__ -+#include -+#undef pr_fmt -+#define pr_fmt(fmt) \ -+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \ -+ (int)sizeof(current->comm), current->comm, current->pid -+#else -+#include -+#include -+#endif /* __KERNEL__ */ -+ -+#include -+ -+#define AUFS_VERSION "4.19-20181029" -+ -+/* todo? move this to linux-2.6.19/include/magic.h */ -+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_BRANCH_MAX_127 -+typedef int8_t aufs_bindex_t; -+#define AUFS_BRANCH_MAX 127 -+#else -+typedef int16_t aufs_bindex_t; -+#ifdef CONFIG_AUFS_BRANCH_MAX_511 -+#define AUFS_BRANCH_MAX 511 -+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023) -+#define AUFS_BRANCH_MAX 1023 -+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767) -+#define AUFS_BRANCH_MAX 32767 -+#endif -+#endif -+ -+#ifdef __KERNEL__ -+#ifndef AUFS_BRANCH_MAX -+#error unknown CONFIG_AUFS_BRANCH_MAX value -+#endif -+#endif /* __KERNEL__ */ -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define AUFS_FSTYPE AUFS_NAME -+ -+#define AUFS_ROOT_INO 2 -+#define AUFS_FIRST_INO 11 -+ -+#define AUFS_WH_PFX ".wh." -+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1) -+#define AUFS_WH_TMP_LEN 4 -+/* a limit for rmdir/rename a dir and copyup */ -+#define AUFS_MAX_NAMELEN (NAME_MAX \ -+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\ -+ - 1 /* dot */\ -+ - AUFS_WH_TMP_LEN) /* hex */ -+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino" -+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME -+#define AUFS_XINO_DEF_SEC 30 /* seconds */ -+#define AUFS_XINO_DEF_TRUNC 45 /* percentage */ -+#define AUFS_DIRWH_DEF 3 -+#define AUFS_RDCACHE_DEF 10 /* seconds */ -+#define AUFS_RDCACHE_MAX 3600 /* seconds */ -+#define AUFS_RDBLK_DEF 512 /* bytes */ -+#define AUFS_RDHASH_DEF 32 -+#define AUFS_WKQ_NAME AUFS_NAME "d" -+#define AUFS_MFS_DEF_SEC 30 /* seconds */ -+#define AUFS_MFS_MAX_SEC 3600 /* seconds */ -+#define AUFS_FHSM_CACHE_DEF_SEC 30 /* seconds */ -+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */ -+ -+/* pseudo-link maintenace under /proc */ -+#define AUFS_PLINK_MAINT_NAME "plink_maint" -+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME -+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME -+ -+/* dirren, renamed dir */ -+#define AUFS_DR_INFO_PFX AUFS_WH_PFX ".dr." -+#define AUFS_DR_BRHINO_NAME AUFS_WH_PFX "hino" -+/* whiteouted doubly */ -+#define AUFS_WH_DR_INFO_PFX AUFS_WH_PFX AUFS_DR_INFO_PFX -+#define AUFS_WH_DR_BRHINO AUFS_WH_PFX AUFS_DR_BRHINO_NAME -+ -+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */ -+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME -+ -+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME -+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk" -+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph" -+ -+/* doubly whiteouted */ -+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME -+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME -+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME -+ -+/* branch permissions and attributes */ -+#define AUFS_BRPERM_RW "rw" -+#define AUFS_BRPERM_RO "ro" -+#define AUFS_BRPERM_RR "rr" -+#define AUFS_BRATTR_COO_REG "coo_reg" -+#define AUFS_BRATTR_COO_ALL "coo_all" -+#define AUFS_BRATTR_FHSM "fhsm" -+#define AUFS_BRATTR_UNPIN "unpin" -+#define AUFS_BRATTR_ICEX "icex" -+#define AUFS_BRATTR_ICEX_SEC "icexsec" -+#define AUFS_BRATTR_ICEX_SYS "icexsys" -+#define AUFS_BRATTR_ICEX_TR "icextr" -+#define AUFS_BRATTR_ICEX_USR "icexusr" -+#define AUFS_BRATTR_ICEX_OTH "icexoth" -+#define AUFS_BRRATTR_WH "wh" -+#define AUFS_BRWATTR_NLWH "nolwh" -+#define AUFS_BRWATTR_MOO "moo" -+ -+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */ -+#define AuBrPerm_RO (1 << 1) /* readonly */ -+#define AuBrPerm_RR (1 << 2) /* natively readonly */ -+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR) -+ -+#define AuBrAttr_COO_REG (1 << 3) /* copy-up on open */ -+#define AuBrAttr_COO_ALL (1 << 4) -+#define AuBrAttr_COO_Mask (AuBrAttr_COO_REG | AuBrAttr_COO_ALL) -+ -+#define AuBrAttr_FHSM (1 << 5) /* file-based hsm */ -+#define AuBrAttr_UNPIN (1 << 6) /* rename-able top dir of -+ branch. meaningless since -+ linux-3.18-rc1 */ -+ -+/* ignore error in copying XATTR */ -+#define AuBrAttr_ICEX_SEC (1 << 7) -+#define AuBrAttr_ICEX_SYS (1 << 8) -+#define AuBrAttr_ICEX_TR (1 << 9) -+#define AuBrAttr_ICEX_USR (1 << 10) -+#define AuBrAttr_ICEX_OTH (1 << 11) -+#define AuBrAttr_ICEX (AuBrAttr_ICEX_SEC \ -+ | AuBrAttr_ICEX_SYS \ -+ | AuBrAttr_ICEX_TR \ -+ | AuBrAttr_ICEX_USR \ -+ | AuBrAttr_ICEX_OTH) -+ -+#define AuBrRAttr_WH (1 << 12) /* whiteout-able */ -+#define AuBrRAttr_Mask AuBrRAttr_WH -+ -+#define AuBrWAttr_NoLinkWH (1 << 13) /* un-hardlinkable whiteouts */ -+#define AuBrWAttr_MOO (1 << 14) /* move-up on open */ -+#define AuBrWAttr_Mask (AuBrWAttr_NoLinkWH | AuBrWAttr_MOO) -+ -+#define AuBrAttr_CMOO_Mask (AuBrAttr_COO_Mask | AuBrWAttr_MOO) -+ -+/* #warning test userspace */ -+#ifdef __KERNEL__ -+#ifndef CONFIG_AUFS_FHSM -+#undef AuBrAttr_FHSM -+#define AuBrAttr_FHSM 0 -+#endif -+#ifndef CONFIG_AUFS_XATTR -+#undef AuBrAttr_ICEX -+#define AuBrAttr_ICEX 0 -+#undef AuBrAttr_ICEX_SEC -+#define AuBrAttr_ICEX_SEC 0 -+#undef AuBrAttr_ICEX_SYS -+#define AuBrAttr_ICEX_SYS 0 -+#undef AuBrAttr_ICEX_TR -+#define AuBrAttr_ICEX_TR 0 -+#undef AuBrAttr_ICEX_USR -+#define AuBrAttr_ICEX_USR 0 -+#undef AuBrAttr_ICEX_OTH -+#define AuBrAttr_ICEX_OTH 0 -+#endif -+#endif -+ -+/* the longest combination */ -+/* AUFS_BRATTR_ICEX and AUFS_BRATTR_ICEX_TR don't affect here */ -+#define AuBrPermStrSz sizeof(AUFS_BRPERM_RW \ -+ "+" AUFS_BRATTR_COO_REG \ -+ "+" AUFS_BRATTR_FHSM \ -+ "+" AUFS_BRATTR_UNPIN \ -+ "+" AUFS_BRATTR_ICEX_SEC \ -+ "+" AUFS_BRATTR_ICEX_SYS \ -+ "+" AUFS_BRATTR_ICEX_USR \ -+ "+" AUFS_BRATTR_ICEX_OTH \ -+ "+" AUFS_BRWATTR_NLWH) -+ -+typedef struct { -+ char a[AuBrPermStrSz]; -+} au_br_perm_str_t; -+ -+static inline int au_br_writable(int brperm) -+{ -+ return brperm & AuBrPerm_RW; -+} -+ -+static inline int au_br_whable(int brperm) -+{ -+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH); -+} -+ -+static inline int au_br_wh_linkable(int brperm) -+{ -+ return !(brperm & AuBrWAttr_NoLinkWH); -+} -+ -+static inline int au_br_cmoo(int brperm) -+{ -+ return brperm & AuBrAttr_CMOO_Mask; -+} -+ -+static inline int au_br_fhsm(int brperm) -+{ -+ return brperm & AuBrAttr_FHSM; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* ioctl */ -+enum { -+ /* readdir in userspace */ -+ AuCtl_RDU, -+ AuCtl_RDU_INO, -+ -+ AuCtl_WBR_FD, /* pathconf wrapper */ -+ AuCtl_IBUSY, /* busy inode */ -+ AuCtl_MVDOWN, /* move-down */ -+ AuCtl_BR, /* info about branches */ -+ AuCtl_FHSM_FD /* connection for fhsm */ -+}; -+ -+/* borrowed from linux/include/linux/kernel.h */ -+#ifndef ALIGN -+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1) -+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) -+#endif -+ -+/* borrowed from linux/include/linux/compiler-gcc3.h */ -+#ifndef __aligned -+#define __aligned(x) __attribute__((aligned(x))) -+#endif -+ -+#ifdef __KERNEL__ -+#ifndef __packed -+#define __packed __attribute__((packed)) -+#endif -+#endif -+ -+struct au_rdu_cookie { -+ uint64_t h_pos; -+ int16_t bindex; -+ uint8_t flags; -+ uint8_t pad; -+ uint32_t generation; -+} __aligned(8); -+ -+struct au_rdu_ent { -+ uint64_t ino; -+ int16_t bindex; -+ uint8_t type; -+ uint8_t nlen; -+ uint8_t wh; -+ char name[0]; -+} __aligned(8); -+ -+static inline int au_rdu_len(int nlen) -+{ -+ /* include the terminating NULL */ -+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1, -+ sizeof(uint64_t)); -+} -+ -+union au_rdu_ent_ul { -+ struct au_rdu_ent __user *e; -+ uint64_t ul; -+}; -+ -+enum { -+ AufsCtlRduV_SZ, -+ AufsCtlRduV_End -+}; -+ -+struct aufs_rdu { -+ /* input */ -+ union { -+ uint64_t sz; /* AuCtl_RDU */ -+ uint64_t nent; /* AuCtl_RDU_INO */ -+ }; -+ union au_rdu_ent_ul ent; -+ uint16_t verify[AufsCtlRduV_End]; -+ -+ /* input/output */ -+ uint32_t blk; -+ -+ /* output */ -+ union au_rdu_ent_ul tail; -+ /* number of entries which were added in a single call */ -+ uint64_t rent; -+ uint8_t full; -+ uint8_t shwh; -+ -+ struct au_rdu_cookie cookie; -+} __aligned(8); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* dirren. the branch is identified by the filename who contains this */ -+struct au_drinfo { -+ uint64_t ino; -+ union { -+ uint8_t oldnamelen; -+ uint64_t _padding; -+ }; -+ uint8_t oldname[0]; -+} __aligned(8); -+ -+struct au_drinfo_fdata { -+ uint32_t magic; -+ struct au_drinfo drinfo; -+} __aligned(8); -+ -+#define AUFS_DRINFO_MAGIC_V1 ('a' << 24 | 'd' << 16 | 'r' << 8 | 0x01) -+/* future */ -+#define AUFS_DRINFO_MAGIC_V2 ('a' << 24 | 'd' << 16 | 'r' << 8 | 0x02) -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct aufs_wbr_fd { -+ uint32_t oflags; -+ int16_t brid; -+} __aligned(8); -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct aufs_ibusy { -+ uint64_t ino, h_ino; -+ int16_t bindex; -+} __aligned(8); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* error code for move-down */ -+/* the actual message strings are implemented in aufs-util.git */ -+enum { -+ EAU_MVDOWN_OPAQUE = 1, -+ EAU_MVDOWN_WHITEOUT, -+ EAU_MVDOWN_UPPER, -+ EAU_MVDOWN_BOTTOM, -+ EAU_MVDOWN_NOUPPER, -+ EAU_MVDOWN_NOLOWERBR, -+ EAU_Last -+}; -+ -+/* flags for move-down */ -+#define AUFS_MVDOWN_DMSG 1 -+#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */ -+#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */ -+#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */ -+#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */ -+#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */ -+#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */ -+#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */ -+#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */ -+#define AUFS_MVDOWN_FHSM_LOWER (1 << 9) /* find fhsm attr for lower */ -+#define AUFS_MVDOWN_STFS (1 << 10) /* req. stfs */ -+#define AUFS_MVDOWN_STFS_FAILED (1 << 11) /* output: stfs is unusable */ -+#define AUFS_MVDOWN_BOTTOM (1 << 12) /* output: no more lowers */ -+ -+/* index for move-down */ -+enum { -+ AUFS_MVDOWN_UPPER, -+ AUFS_MVDOWN_LOWER, -+ AUFS_MVDOWN_NARRAY -+}; -+ -+/* -+ * additional info of move-down -+ * number of free blocks and inodes. -+ * subset of struct kstatfs, but smaller and always 64bit. -+ */ -+struct aufs_stfs { -+ uint64_t f_blocks; -+ uint64_t f_bavail; -+ uint64_t f_files; -+ uint64_t f_ffree; -+}; -+ -+struct aufs_stbr { -+ int16_t brid; /* optional input */ -+ int16_t bindex; /* output */ -+ struct aufs_stfs stfs; /* output when AUFS_MVDOWN_STFS set */ -+} __aligned(8); -+ -+struct aufs_mvdown { -+ uint32_t flags; /* input/output */ -+ struct aufs_stbr stbr[AUFS_MVDOWN_NARRAY]; /* input/output */ -+ int8_t au_errno; /* output */ -+} __aligned(8); -+ -+/* ---------------------------------------------------------------------- */ -+ -+union aufs_brinfo { -+ /* PATH_MAX may differ between kernel-space and user-space */ -+ char _spacer[4096]; -+ struct { -+ int16_t id; -+ int perm; -+ char path[0]; -+ }; -+} __aligned(8); -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define AuCtlType 'A' -+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu) -+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu) -+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \ -+ struct aufs_wbr_fd) -+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy) -+#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \ -+ struct aufs_mvdown) -+#define AUFS_CTL_BRINFO _IOW(AuCtlType, AuCtl_BR, union aufs_brinfo) -+#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int) -+ -+#endif /* __AUFS_TYPE_H__ */ -diff --git a/kernel/fork.c b/kernel/fork.c -index f0b584795..fa562c364 100644 ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -505,7 +505,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, - struct inode *inode = file_inode(file); - struct address_space *mapping = file->f_mapping; - -- get_file(file); -+ vma_get_file(tmp); - if (tmp->vm_flags & VM_DENYWRITE) - atomic_dec(&inode->i_writecount); - i_mmap_lock_write(mapping); -diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c -index dd13f865a..7ac19efda 100644 ---- a/kernel/locking/lockdep.c -+++ b/kernel/locking/lockdep.c -@@ -140,7 +140,7 @@ static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES]; - unsigned long nr_lock_classes; - static struct lock_class lock_classes[MAX_LOCKDEP_KEYS]; - --static inline struct lock_class *hlock_class(struct held_lock *hlock) -+inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock) - { - if (!hlock->class_idx) { - /* -@@ -151,6 +151,8 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock) - } - return lock_classes + hlock->class_idx - 1; - } -+EXPORT_SYMBOL_GPL(lockdep_hlock_class); -+#define hlock_class(hlock) lockdep_hlock_class(hlock) - - #ifdef CONFIG_LOCK_STAT - static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats); -diff --git a/kernel/task_work.c b/kernel/task_work.c -index 0fef39566..83fb1ecfc 100644 ---- a/kernel/task_work.c -+++ b/kernel/task_work.c -@@ -116,3 +116,4 @@ void task_work_run(void) - } while (work); - } - } -+EXPORT_SYMBOL_GPL(task_work_run); -diff --git a/mm/Makefile b/mm/Makefile -index 26ef77a38..b2869af1e 100644 ---- a/mm/Makefile -+++ b/mm/Makefile -@@ -39,7 +39,7 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \ - mm_init.o mmu_context.o percpu.o slab_common.o \ - compaction.o vmacache.o \ - interval_tree.o list_lru.o workingset.o \ -- debug.o $(mmu-y) -+ prfile.o debug.o $(mmu-y) - - obj-y += init-mm.o - -diff --git a/mm/filemap.c b/mm/filemap.c -index 52517f28e..250f675dc 100644 ---- a/mm/filemap.c -+++ b/mm/filemap.c -@@ -2700,7 +2700,7 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf) - vm_fault_t ret = VM_FAULT_LOCKED; - - sb_start_pagefault(inode->i_sb); -- file_update_time(vmf->vma->vm_file); -+ vma_file_update_time(vmf->vma); - lock_page(page); - if (page->mapping != inode->i_mapping) { - unlock_page(page); -diff --git a/mm/mmap.c b/mm/mmap.c -index f7cd9cb96..515e88a19 100644 ---- a/mm/mmap.c -+++ b/mm/mmap.c -@@ -180,7 +180,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) - if (vma->vm_ops && vma->vm_ops->close) - vma->vm_ops->close(vma); - if (vma->vm_file) -- fput(vma->vm_file); -+ vma_fput(vma); - mpol_put(vma_policy(vma)); - vm_area_free(vma); - return next; -@@ -905,7 +905,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, - if (remove_next) { - if (file) { - uprobe_munmap(next, next->vm_start, next->vm_end); -- fput(file); -+ vma_fput(vma); - } - if (next->anon_vma) - anon_vma_merge(vma, next); -@@ -1821,8 +1821,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr, - return addr; - - unmap_and_free_vma: -+ vma_fput(vma); - vma->vm_file = NULL; -- fput(file); - - /* Undo any partial mapping done by a device driver. */ - unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); -@@ -2641,7 +2641,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, - goto out_free_mpol; - - if (new->vm_file) -- get_file(new->vm_file); -+ vma_get_file(new); - - if (new->vm_ops && new->vm_ops->open) - new->vm_ops->open(new); -@@ -2660,7 +2660,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, - if (new->vm_ops && new->vm_ops->close) - new->vm_ops->close(new); - if (new->vm_file) -- fput(new->vm_file); -+ vma_fput(new); - unlink_anon_vmas(new); - out_free_mpol: - mpol_put(vma_policy(new)); -@@ -2822,7 +2822,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, - struct vm_area_struct *vma; - unsigned long populate = 0; - unsigned long ret = -EINVAL; -- struct file *file; -+ struct file *file, *prfile; - - pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.rst.\n", - current->comm, current->pid); -@@ -2897,10 +2897,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, - } - } - -- file = get_file(vma->vm_file); -+ vma_get_file(vma); -+ file = vma->vm_file; -+ prfile = vma->vm_prfile; - ret = do_mmap_pgoff(vma->vm_file, start, size, - prot, flags, pgoff, &populate, NULL); -+ if (!IS_ERR_VALUE(ret) && file && prfile) { -+ struct vm_area_struct *new_vma; -+ -+ new_vma = find_vma(mm, ret); -+ if (!new_vma->vm_prfile) -+ new_vma->vm_prfile = prfile; -+ if (new_vma != vma) -+ get_file(prfile); -+ } -+ /* -+ * two fput()s instead of vma_fput(vma), -+ * coz vma may not be available anymore. -+ */ - fput(file); -+ if (prfile) -+ fput(prfile); - out: - up_write(&mm->mmap_sem); - if (populate) -@@ -3206,7 +3223,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, - if (anon_vma_clone(new_vma, vma)) - goto out_free_mempol; - if (new_vma->vm_file) -- get_file(new_vma->vm_file); -+ vma_get_file(new_vma); - if (new_vma->vm_ops && new_vma->vm_ops->open) - new_vma->vm_ops->open(new_vma); - vma_link(mm, new_vma, prev, rb_link, rb_parent); -diff --git a/mm/nommu.c b/mm/nommu.c -index e4aac3321..b27b200f1 100644 ---- a/mm/nommu.c -+++ b/mm/nommu.c -@@ -625,7 +625,7 @@ static void __put_nommu_region(struct vm_region *region) - up_write(&nommu_region_sem); - - if (region->vm_file) -- fput(region->vm_file); -+ vmr_fput(region); - - /* IO memory and memory shared directly out of the pagecache - * from ramfs/tmpfs mustn't be released here */ -@@ -763,7 +763,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma) - if (vma->vm_ops && vma->vm_ops->close) - vma->vm_ops->close(vma); - if (vma->vm_file) -- fput(vma->vm_file); -+ vma_fput(vma); - put_nommu_region(vma->vm_region); - vm_area_free(vma); - } -@@ -1286,7 +1286,7 @@ unsigned long do_mmap(struct file *file, - goto error_just_free; - } - } -- fput(region->vm_file); -+ vmr_fput(region); - kmem_cache_free(vm_region_jar, region); - region = pregion; - result = start; -@@ -1361,7 +1361,7 @@ unsigned long do_mmap(struct file *file, - up_write(&nommu_region_sem); - error: - if (region->vm_file) -- fput(region->vm_file); -+ vmr_fput(region); - kmem_cache_free(vm_region_jar, region); - if (vma->vm_file) - fput(vma->vm_file); -diff --git a/mm/prfile.c b/mm/prfile.c -new file mode 100644 -index 000000000..a27ac3688 ---- /dev/null -+++ b/mm/prfile.c -@@ -0,0 +1,86 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Mainly for aufs which mmap(2) different file and wants to print different -+ * path in /proc/PID/maps. -+ * Call these functions via macros defined in linux/mm.h. -+ * -+ * See Documentation/filesystems/aufs/design/06mmap.txt -+ * -+ * Copyright (c) 2014-2018 Junjro R. Okajima -+ * Copyright (c) 2014 Ian Campbell -+ */ -+ -+#include -+#include -+#include -+ -+/* #define PRFILE_TRACE */ -+static inline void prfile_trace(struct file *f, struct file *pr, -+ const char func[], int line, const char func2[]) -+{ -+#ifdef PRFILE_TRACE -+ if (pr) -+ pr_info("%s:%d: %s, %pD2\n", func, line, func2, f); -+#endif -+} -+ -+void vma_do_file_update_time(struct vm_area_struct *vma, const char func[], -+ int line) -+{ -+ struct file *f = vma->vm_file, *pr = vma->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ file_update_time(f); -+ if (f && pr) -+ file_update_time(pr); -+} -+ -+struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[], -+ int line) -+{ -+ struct file *f = vma->vm_file, *pr = vma->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ return (f && pr) ? pr : f; -+} -+ -+void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line) -+{ -+ struct file *f = vma->vm_file, *pr = vma->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ get_file(f); -+ if (f && pr) -+ get_file(pr); -+} -+ -+void vma_do_fput(struct vm_area_struct *vma, const char func[], int line) -+{ -+ struct file *f = vma->vm_file, *pr = vma->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ fput(f); -+ if (f && pr) -+ fput(pr); -+} -+ -+#ifndef CONFIG_MMU -+struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[], -+ int line) -+{ -+ struct file *f = region->vm_file, *pr = region->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ return (f && pr) ? pr : f; -+} -+ -+void vmr_do_fput(struct vm_region *region, const char func[], int line) -+{ -+ struct file *f = region->vm_file, *pr = region->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ fput(f); -+ if (f && pr) -+ fput(pr); -+} -+#endif /* !CONFIG_MMU */ -diff --git a/security/commoncap.c b/security/commoncap.c -index 2e489d6a3..1e146dafe 100644 ---- a/security/commoncap.c -+++ b/security/commoncap.c -@@ -1336,12 +1336,14 @@ int cap_mmap_addr(unsigned long addr) - } - return ret; - } -+EXPORT_SYMBOL_GPL(cap_mmap_addr); - - int cap_mmap_file(struct file *file, unsigned long reqprot, - unsigned long prot, unsigned long flags) - { - return 0; - } -+EXPORT_SYMBOL_GPL(cap_mmap_file); - - #ifdef CONFIG_SECURITY - -diff --git a/security/device_cgroup.c b/security/device_cgroup.c -index cd97929fa..424fd2308 100644 ---- a/security/device_cgroup.c -+++ b/security/device_cgroup.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -824,3 +825,4 @@ int __devcgroup_check_permission(short type, u32 major, u32 minor, - - return 0; - } -+EXPORT_SYMBOL_GPL(__devcgroup_check_permission); -diff --git a/security/security.c b/security/security.c -index 736e78da1..b3145394c 100644 ---- a/security/security.c -+++ b/security/security.c -@@ -542,6 +542,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry) - return 0; - return call_int_hook(path_rmdir, 0, dir, dentry); - } -+EXPORT_SYMBOL_GPL(security_path_rmdir); - - int security_path_unlink(const struct path *dir, struct dentry *dentry) - { -@@ -558,6 +559,7 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry, - return 0; - return call_int_hook(path_symlink, 0, dir, dentry, old_name); - } -+EXPORT_SYMBOL_GPL(security_path_symlink); - - int security_path_link(struct dentry *old_dentry, const struct path *new_dir, - struct dentry *new_dentry) -@@ -566,6 +568,7 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir, - return 0; - return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry); - } -+EXPORT_SYMBOL_GPL(security_path_link); - - int security_path_rename(const struct path *old_dir, struct dentry *old_dentry, - const struct path *new_dir, struct dentry *new_dentry, -@@ -593,6 +596,7 @@ int security_path_truncate(const struct path *path) - return 0; - return call_int_hook(path_truncate, 0, path); - } -+EXPORT_SYMBOL_GPL(security_path_truncate); - - int security_path_chmod(const struct path *path, umode_t mode) - { -@@ -600,6 +604,7 @@ int security_path_chmod(const struct path *path, umode_t mode) - return 0; - return call_int_hook(path_chmod, 0, path, mode); - } -+EXPORT_SYMBOL_GPL(security_path_chmod); - - int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) - { -@@ -607,6 +612,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) - return 0; - return call_int_hook(path_chown, 0, path, uid, gid); - } -+EXPORT_SYMBOL_GPL(security_path_chown); - - int security_path_chroot(const struct path *path) - { -@@ -692,6 +698,7 @@ int security_inode_readlink(struct dentry *dentry) - return 0; - return call_int_hook(inode_readlink, 0, dentry); - } -+EXPORT_SYMBOL_GPL(security_inode_readlink); - - int security_inode_follow_link(struct dentry *dentry, struct inode *inode, - bool rcu) -@@ -707,6 +714,7 @@ int security_inode_permission(struct inode *inode, int mask) - return 0; - return call_int_hook(inode_permission, 0, inode, mask); - } -+EXPORT_SYMBOL_GPL(security_inode_permission); - - int security_inode_setattr(struct dentry *dentry, struct iattr *attr) - { -@@ -878,6 +886,7 @@ int security_file_permission(struct file *file, int mask) - - return fsnotify_perm(file, mask); - } -+EXPORT_SYMBOL_GPL(security_file_permission); - - int security_file_alloc(struct file *file) - { -@@ -937,6 +946,7 @@ int security_mmap_file(struct file *file, unsigned long prot, - return ret; - return ima_file_mmap(file, prot); - } -+EXPORT_SYMBOL_GPL(security_mmap_file); - - int security_mmap_addr(unsigned long addr) - { diff --git a/patch/u-boot/legacy/board_bananapir2/enable-boot-from-ext4.patch b/patch/u-boot/v2024.07/board_bananapir2/enable-boot-from-ext4.patch similarity index 51% rename from patch/u-boot/legacy/board_bananapir2/enable-boot-from-ext4.patch rename to patch/u-boot/v2024.07/board_bananapir2/enable-boot-from-ext4.patch index 7fda489ed586..db882c38dcf8 100644 --- a/patch/u-boot/legacy/board_bananapir2/enable-boot-from-ext4.patch +++ b/patch/u-boot/v2024.07/board_bananapir2/enable-boot-from-ext4.patch @@ -6,17 +6,37 @@ Subject: Patching u-boot mt7623 files include/configs/mt7623.h Signed-off-by: Igor Pecovnik --- - include/configs/mt7623.h | 48 ++++++- - mt7623n_bpir2_defconfig | 70 ++++++++++ - 2 files changed, 113 insertions(+), 5 deletions(-) + configs/mt7623n_bpir2_defconfig | 5 + + include/configs/mt7623.h | 46 +++++++++- + 2 files changed, 47 insertions(+), 4 deletions(-) +diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig +index 111111111111..222222222222 100644 +--- a/configs/mt7623n_bpir2_defconfig ++++ b/configs/mt7623n_bpir2_defconfig +@@ -23,6 +23,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y + # CONFIG_DISPLAY_BOARDINFO is not set + CONFIG_SYS_PROMPT="U-Boot> " + CONFIG_SYS_MAXARGS=8 ++CONFIG_CMD_BOOTZ=y + CONFIG_CMD_BOOTMENU=y + # CONFIG_CMD_ELF is not set + # CONFIG_CMD_XIMG is not set +@@ -60,5 +61,9 @@ CONFIG_SYSRESET_WATCHDOG=y + CONFIG_TIMER=y + CONFIG_MTK_TIMER=y + CONFIG_WDT_MTK=y ++CONFIG_FS_EXT4=y ++CONFIG_EXT4_WRITE=y + CONFIG_LZMA=y + # CONFIG_EFI_GRUB_ARM32_WORKAROUND is not set ++CONFIG_CMD_EXT4=y ++CONFIG_CMD_EXT4_WRITE=y diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h -index db12377b00..3fb983060f 100644 +index 111111111111..222222222222 100644 --- a/include/configs/mt7623.h +++ b/include/configs/mt7623.h -@@ -22,15 +22,31 @@ - - /* DRAM */ +@@ -18,11 +18,27 @@ #define CFG_SYS_SDRAM_BASE 0x80000000 /* This is needed for kernel booting */ @@ -46,17 +66,12 @@ index db12377b00..3fb983060f 100644 "fdt_addr_r=" FDT_HIGH "\0" \ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" - /* Ethernet */ - -@@ -41,11 +57,33 @@ - - #include +@@ -35,9 +51,31 @@ /* Extra environment variables */ #define CFG_EXTRA_ENV_SETTINGS \ - ENV_MEM_LAYOUT_SETTINGS \ - BOOTENV -- + "loadaddr=0x82000000\0" \ + "kernel_addr_r=0x82000000\0" \ + "scriptaddr=0x85F80000\0" \ @@ -73,7 +88,7 @@ index db12377b00..3fb983060f 100644 + "devnum=1\0" \ + "mmcpart=1\0" \ + SCRIPT_BOOT -+ + +#define CONFIG_BOOTCOMMAND \ + "mmc dev 1;" \ + "run scriptload;" \ @@ -85,82 +100,6 @@ index db12377b00..3fb983060f 100644 #endif /* ifdef CONFIG_DISTRO_DEFAULTS*/ #endif -diff --git a/mt7623n_bpir2_defconfig b/mt7623n_bpir2_defconfig -new file mode 100644 -index 0000000000..ea8301a604 ---- /dev/null -+++ b/mt7623n_bpir2_defconfig -@@ -0,0 +1,70 @@ -+CONFIG_ARM=y -+CONFIG_SYS_HAS_NONCACHED_MEMORY=y -+CONFIG_SYS_THUMB_BUILD=y -+CONFIG_ARCH_MEDIATEK=y -+CONFIG_TEXT_BASE=0x81e00000 -+CONFIG_SYS_MALLOC_F_LEN=0x4000 -+CONFIG_NR_DRAM_BANKS=1 -+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y -+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x81ffff10 -+CONFIG_ENV_SIZE=0x1000 -+CONFIG_ENV_OFFSET=0x100000 -+CONFIG_DEFAULT_DEVICE_TREE="mt7623n-bananapi-bpi-r2" -+CONFIG_SYS_PROMPT="U-Boot> " -+CONFIG_CMD_BOOTZ=y -+CONFIG_TARGET_MT7623=y -+CONFIG_SYS_LOAD_ADDR=0x84000000 -+CONFIG_FIT=y -+CONFIG_FIT_VERBOSE=y -+CONFIG_DISTRO_DEFAULTS=y -+CONFIG_BOOTDELAY=3 -+CONFIG_DEFAULT_FDT_FILE="mt7623n-bananapi-bpi-r2.dtb" -+CONFIG_SYS_CONSOLE_IS_IN_ENV=y -+# CONFIG_DISPLAY_BOARDINFO is not set -+CONFIG_SYS_MAXARGS=8 -+CONFIG_SYS_PBSIZE=1049 -+CONFIG_SYS_BOOTM_LEN=0x4000000 -+CONFIG_CMD_BOOTMENU=y -+# CONFIG_CMD_ELF is not set -+# CONFIG_CMD_XIMG is not set -+CONFIG_CMD_GPIO=y -+CONFIG_CMD_GPT=y -+CONFIG_CMD_MMC=y -+CONFIG_CMD_READ=y -+CONFIG_CMD_EXT4=y -+CONFIG_CMD_EXT4_WRITE=y -+CONFIG_FS_EXT4=y -+CONFIG_EXT4_WRITE=y -+# CONFIG_CMD_SETEXPR is not set -+# CONFIG_CMD_NFS is not set -+CONFIG_ENV_OVERWRITE=y -+CONFIG_ENV_IS_IN_MMC=y -+CONFIG_SYS_RELOC_GD_ENV_ADDR=y -+CONFIG_NET_RANDOM_ETHADDR=y -+CONFIG_USE_IPADDR=y -+CONFIG_IPADDR="192.168.1.1" -+CONFIG_USE_SERVERIP=y -+CONFIG_SERVERIP="192.168.1.2" -+CONFIG_REGMAP=y -+CONFIG_SYSCON=y -+CONFIG_CLK=y -+# CONFIG_MMC_QUIRKS is not set -+CONFIG_SUPPORT_EMMC_BOOT=y -+CONFIG_MMC_HS400_SUPPORT=y -+CONFIG_MMC_MTK=y -+CONFIG_PHY_FIXED=y -+CONFIG_MEDIATEK_ETH=y -+CONFIG_PINCTRL=y -+CONFIG_PINCONF=y -+CONFIG_PINCTRL_MT7623=y -+CONFIG_POWER_DOMAIN=y -+CONFIG_MTK_POWER_DOMAIN=y -+CONFIG_DM_SERIAL=y -+CONFIG_MTK_SERIAL=y -+CONFIG_SYSRESET=y -+CONFIG_SYSRESET_WATCHDOG=y -+CONFIG_TIMER=y -+CONFIG_MTK_TIMER=y -+CONFIG_WDT_MTK=y -+CONFIG_LZMA=y -+# CONFIG_EFI_GRUB_ARM32_WORKAROUND is not set -- -Created with Armbian build tools https://github.com/armbian/build +Armbian