From e143e5cfce526d4160f61ea3ffaf047dea324d68 Mon Sep 17 00:00:00 2001 From: ColorfulRhino <131405023+ColorfulRhino@users.noreply.github.com> Date: Sun, 7 Jul 2024 12:11:18 +0200 Subject: [PATCH 1/4] mt7623: Bump `legacy` 4.19 to `current` 6.6 kernel NB: 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. - Adjust BananaPi R2 board config (board is mainlined) - Remove legacy kernel patch folder and kernel config - Remove unstable WiFi stuff --- config/boards/bananapir2.csc | 5 +- ...dge.config => linux-mt7623-current.config} | 0 config/kernel/linux-mt7623-legacy.config | 6831 - config/sources/families/mt7623.conf | 20 +- .../blobs/mt7623n/BPI-R2-preloader-2k.img.old | Bin 91996 -> 0 bytes packages/blobs/mt7623n/wireless/source.txt | 1 - .../blobs/mt7623n/wireless/stp_uart_launcher | Bin 33392 -> 0 bytes packages/blobs/mt7623n/wireless/wmt_loader | Bin 8448 -> 0 bytes packages/blobs/mt7623n/wireless/wmt_loopback | Bin 13372 -> 0 bytes packages/bsp/mt7623/mt7623-wifi.bash | 6 - packages/bsp/mt7623/mt7623-wifi.service | 14 - .../0001-r2-wifi-add-driver-folder.patch | 216262 --------------- .../mt7623-4.19/0002-r2-wifi-add-dt.patch | 842 - .../mt7623-4.19/0003-r2-gcc8-nic_rx.patch | 75 - .../0004-r2-power-off-and-rtc.patch.broken | 715 - .../mt7623-4.19/aufs4.19-20181029.patch | 39290 --- 16 files changed, 11 insertions(+), 264050 deletions(-) rename config/kernel/{linux-mt7623-edge.config => linux-mt7623-current.config} (100%) delete mode 100644 config/kernel/linux-mt7623-legacy.config delete mode 100644 packages/blobs/mt7623n/BPI-R2-preloader-2k.img.old delete mode 100644 packages/blobs/mt7623n/wireless/source.txt delete mode 100755 packages/blobs/mt7623n/wireless/stp_uart_launcher delete mode 100755 packages/blobs/mt7623n/wireless/wmt_loader delete mode 100755 packages/blobs/mt7623n/wireless/wmt_loopback delete mode 100644 packages/bsp/mt7623/mt7623-wifi.bash delete mode 100644 packages/bsp/mt7623/mt7623-wifi.service delete mode 100644 patch/kernel/archive/mt7623-4.19/0001-r2-wifi-add-driver-folder.patch delete mode 100644 patch/kernel/archive/mt7623-4.19/0002-r2-wifi-add-dt.patch delete mode 100644 patch/kernel/archive/mt7623-4.19/0003-r2-gcc8-nic_rx.patch delete mode 100644 patch/kernel/archive/mt7623-4.19/0004-r2-power-off-and-rtc.patch.broken delete mode 100644 patch/kernel/archive/mt7623-4.19/aufs4.19-20181029.patch 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 100% rename from config/kernel/linux-mt7623-edge.config rename to config/kernel/linux-mt7623-current.config 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..53892644ffae 100644 --- a/config/sources/families/mt7623.conf +++ b/config/sources/families/mt7623.conf @@ -17,11 +17,11 @@ 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 6107c764354e2b674285833b2b018f5fcaddf36b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91996 zcmd?Sd0bRS)<0bL_HDXp8fX?30kIcU1k?sxh?>}RnM^W6XObCB;@GGe6_U(FAzT`vf8Xk+Tbv~GKF{y{z3=SS0w7&lI zDC6ArVILg*qW`on7wqkGT=V3hSv?XCoH`xjTY0OWxoSb%3)|)oRowVq^VOerra25Tc8|q^qcv8vir?=dO+5eeTrf4)#U_n%#!6qR&fQ2n+Wt2>IuKHcxQ`HTGvEq|=;`ELAguRijd5$_He zwryh0*Q*oCYo|@`sQCEgA8-EGtqD_eXS75ob@X^@^vtra|8=Iy_dESx@@jL(E!MJ& zgs9&$$9^qc+WN@-PxtIh*8MQ^zG)M0ztiyXtAEa`1@SF+(oev%XWF`eO5+YWlT}KJxJgInOP9tNO%d=S#^OCj9c~0`aMb zl-kwFn`XXveuu&R{&23cEIaKNGyCVHEcoa1xncHs7e2Y29X9ltW396i#Ky5ZKlwW1 zUpKj73$|Bz#ba6hZ?7V;Z=F8ayXWk|Per_xvQPYK`hdSZ|KadE^Gu_E@rJx}>3|3A zgV%Zg8Ix9gZ1b~wqh~EvL@pVB-+NZK!Os(Zj<}ak%tTGu^uPUwybaX`9r^rMI&#OR zBguINa!q*Q8)Dh@4Ix!mi4LF#m;n|*F+c#60LlOrfGR*WpcYUE@Bm13eP2?0^{=Gt zDv<`((|E0}>MBFZ>WMU@eg}Esn`p#|uIwA#Ut+$W_34vWx!O;z>i)ufUmdOcKDsYK zUS0h@mLwKQTUt0tf3=$Q{ia&i_Z!+Dh7{MM?;4^n`-UTBS7^N5=S%zqc|Jj&G(DaH zX+*d88%~#Zh0&FHn7XQZC7zeDRMoS^Rp?5 zEc8DQ701Rd2zHH1?EfsLr&x=M0*_o+R6w@_{85r)Tmi6&V{Jtbj-5D-5VSV2$dL~k z+Qc~0eE<2ctA7&%qa7H_1?8L8uUxxKEH7PKx^Cn8Wvj~<&E2_n`J&RD^VdASe!JPYHKj`y?_9TJ`Rek8b2qIoUAS=9`nBuVEZw+s*V;LImd@Y2 zYS;St8`hLAUblPo{EbT&EMK%{`MQmZOG;MnE}g$;(bAGtr5oq$m?tjVynErCP4kv6 zTDNNHx?S^^tk}J0ow#o4hK*~tFPpP=&BDiauUfcnt3m2{|U9f)Lp7{$)mu%Wxx^9WMzO>}A-KC2cl$I{rSh`(YymJ1c#T$06LjFyg z*X-K3c-O+k%l2$sG-tzx(q;2juUox-L&?&etLCiRw0^^)EVJ31wQ9|Rd28k^+^~D~ z;>8>Ln-;EJTe@lSg0)K*tzWZ#V`(`CdHvGO z^UBw)TeqlW(S}uX=dWA5ykx=d4f8fGS-xp~`MkO7@!Yd_ZxDB5?Dp)Ozj)7*Wy=

_*SIu3xSzP|un)Rh~*Q{H<`SD$A#K+gJTUNS$)4J`8Hi^428avl5UAA!5 z;?f;+H!NSbwsiH*WgC{4u3I;M-G+^i?cOuesb9a`mU+Et- zLUhqF->3M7)a#-de@JC@uV{4_jqM5*{;)b~(9K67L(S3V?^Q!}SB{UWs!yb{v#RRq ztNO=1=Gdxwm5#Z>k_lI12>FffP0RPokzdyr`Sr{dPQUF+ao!8x9LtOM#6P;c-o66( z+Fl;6qN=|4naAsUoqnSJ!5Y=~OvSV-UZ3w(rsSb3tq9qw$FFF}r221szK>~Jv|cL9 zY2DRP=Wo#d(|-4eR{8r$((#$Aqg)t=?m$bETVQW%LuS44}BVx}KN?D}%A^ zPskyb#MGyO9>vC7-5OKHsP$C}Mqd@juoJE-$b>8=wknG?R%KysMzTzRwpCY^wM`$O z(K(=XF=m^dC1r+Vz>fic5x9YwRBy<#>5UBNz>fic5jZ5@Rim*w#t>T-^DpeXgv`L6 zFIc1Ko=Qdof_PQVC(%_5_I(9SW7HF_8WO4uI(?N1`*;qcMLfRBpw@3Q>cD@f&j5Zi za=;b(ZQG9Nw^h)(b68q$pia&+=$lT4cxk^m>F6~A-QXtyb@au!FlOi(`hd>Rn~;%o zTu9frD6;R43#HL<*=`Qds7}EUiyr;Jm=xC^1AZL1fhn#xFc!VZ06Oqvz>fnbr1+{S z`|g;qq^h1iGwttZUHv6x=Wi&A2i^R;&(|1MeEvoStMDjvc^;aN(zpHuU9t?isi@so z@1W0OnRta1e}J_b4_zjX848-Bc5gklWTfFaivc9-YRvNG^}4?-XSBjDFjvmixGl@; zV`;o(HwhCS@`QtL^d%2o(bvwu5;wdmFMIU%yx0*{6Jq;U)%SR?DsSkFoq6#ORZWQJ zG42BDEUBWrRL_!PMu9OzhL0+Oc4qlzD zuc`-+G+++EV^zpUF{-i&Sv@h%s6&bRY5BFm@kV`g?rGhWPW0?mgFf%7 z1UjeN_6us zH@Sqpswa6@vtqcbg>hrSm-?%_m^%%lyXe_*%By+F`Bz!c%Rsku(Q}fytCL~^^bMdZ zC@e&NOdsjKukV&C`y{)rFA78;ST&dp`cNr;_{RBCmwkzF%iF$$7cT( zZI3PHiGkL5>86euYPlc1<4h!JR-=;fwesI@=f$&{_K5bRBQyMEdp1Ud6*LjmpBgzX zaes`5=GOBAd0(sf`{X0j`6ToO{jxB;ov$h&X`Z^bt|uNLnPZx#zj^6q6k5@a2m{dZc8zc@V*8@=X5JyC&yRstERL1ZWD=CxK{<{H3M^MQQ_G! zulfuAc_pTMXH<2tFy-DERGSK|w3ozicmC9&`O6Q?pGkG7kAME+F%qwTM@MBF=1={9 zIe!x{e-HDa`7=M|Q6ES;$Q_!RA0=&WO9mIF7TbB6i|l`xKYB#T|F2A6W zQ6=r?4kR8)_0Os5zz%Dce^yzvu49Oa&S+pZ@thdfN50#}mz-4{;o3Fcq$88N=2YXK z(~o~Nr~G%xM<#a7X=-RrFV~&yn$sCSF{cynnN!!Bs^`goQU2a!V{B5sOMc$}#Lv>% zRbgK5!_1PjGPjXWIye=piN#Y>YG7RO{1)(0ZbHp+iIBVVoqHyd=Xm|u2>TF2gfl|A z-9bzmXK#MTjWlAMWnAc<%;db)QntL!ZCc3aj|*3YjQlyXa?g(hkK_a1hFrK?$5?+I z?*C~W{d7b+vt1m!Fl^zzQ=IssHMb_7C&m}8s=7Ft+4vgxI*0$oWG1`i`gTDf9!^vU zI$k<2ol)=~`b$B=A#d~y#>^rA>&QQpZ@Hc*el4*1iGp;#q=48<3KHfUi297e9x3(g zWL?CVD5%d@;2Frjh>o=nG_ZL7Rp&{~DbP+1Fc8%l_BExGF(_mvGJ%g3_ldD$MS-Gv zrp&d!gSDbMqtHAhb7t0{bUh_233DPzJS--O2ky-iMe``M$YG}W!_1sNzv?IRhofI{ zXE;7dWKOV#!{WoJ&3yK#%;}G!ysd#XnabE|-Fe!6WVgIrSKbojRhnu3Bo4Xf9F@cL zwA4{qrH`|jgkaebXOz4M2|+5EN?+@jK61d4dNu+PZh966paLw&95eJ$5Xs>%b|Ih6A(ml%%0FU$2f zTXovky2z*J71ieR<}*91l{|ZbnAl21-0lYBi%ZpEp zA0b3Yo4h$#>YW?)N-@0KRx@tu$_H9k5@Qx$%3xtnT^+gs+v|cj0q{ZDqC6n`K{Q%&+@<#s_W| zjzbd2BX7c%$+J=DAaGSb0KS$sG=_jF7Ih z<%q=iuw8NRu*g9lcB9sT=)ttldVr&@5qR*>&)2gW>DuN zo!hUEcO{hjS{HVX^M~^~3tbGjgv_DTM>_xMdDY6*Wy!H6O!h{Ld|h`cMvm1_vLv9V zMgD#jc3NDFF|p*4>q_)^XQvW9p4>Ug)u+^Yi%~Fx;%oZwq#xzW5uH;`4Y#NB!yS=Q zzdOV2mRm~=!?33Jv=4JI#$n^qUCK&@Y3Ge7@Qe3`uQmCmul0L`{{+zZw*dBLrfaTI zd0-%)C}@pg(sy@^*NJ|whtU%c9i=&)iPwYpfzJ5r9C(?lRALR~`o~h$Nqd>??Lj( ztp;cTZ-aIna_KUl13=}IIH7!Mb2KR%JxWLPSj&paKu>OW&>4QegU;}G9dw4zfufTX z%0xGJ_^VU2CrRi@OFJF4BOM(25%C%A_uo3`=)T;6`9EZn`{|is5}tk>UDakMUDc$3 zu4@~z>wda}mOSe(S>8ePBm8NHJI>2GjPp`Zu>Soq<;kKSd@G4bD?KgmJWbnv zq=O9F(!BCl=OIOs{N=WEm7CzNwG^><)Z(OJF|BE=KYbt{tmz5446Ax%N6|l(_H15> znNMq{y^Ww6%`Q^&PS=?AJwpsSqlgu~tV85EX?@$#8wn)Qo}AAf?(Im zy_da*qn9&M;@W%K;~c~oDfzr_w^T)QpT*e|4RPS7S>8Ao*W|OZEtVLz#l!X%bgo2z zDZkRH{%f?I_Tn3_+HN#NBDd4aL0+r%29gL!1C&lq#L3S<9tJD~P`#@bP&)bJEyob2 zbE|gg&LoSRbY14sRPHd>IV0Q74gFkxhtx*v&cncreJV3UM`p~Ux|(nNIm54AzqTie zzjiV0Yz|u)DZS)<+to+x*G#gRXA%XhIO{1_oDeG>vWC}HyQ=NI#YkzN_f311;Z5|i zwe7MjT_MIdT*$dZ>t*j~n@Hg&GV#>hF8aku`$riszqaeoT@?`Y?5Xzz<)TMglwbg69mA3*=PwBI9bjEGVdgGEP!N;SeZ zKq`A^h|phDiIL(1w!yak5?R~--{N6HYS+kdwjz6~L{@8sK4O?SL6!=K+4|Y~VZ8hN zh@$k5H}YsP;^R1*6(!5&=AjHD=Gg~|jOc$diR6WgU(1A)j8(c-Dw(w?>fF6L+-ftF5pWH>Wik)lpa7Srfl33OhA@&4li z6rG@kUSuj{Z6@%PRVtgUu_X!_qCsTE2wR-(D~0?;%D9w56MALx(`-`Nq&QoKaBtic zipM(wIpUlOVX!B_=k-_@l-G$_uPc3UXzU%Vmk!WU41x86^SzFf03N;W9UIZTa~p6~ zuaiKRKyOCaOhcq+qKt%a_sKtf=X8OaYI}-(#lnWLFdp;sfGtY+F|FrM&{F)PMEZk& z);+*84|KQ(i{QgrmA|eBFxzDh4ikk^8^P#p(8)j`XhY{@IA7i~uFOd@Uzr_P1 z+*@RA8e3n7Q6ei7g%l?(GYRvZW}~Ibgg~k8lt4L9l4(gJX2vEzg}7OjbE%xrLYfgH{Vi%H6C)6E{_`OnyWlu?AL9#I7-s<4qSt9x>vf}@MbfLb zk~47v+hVqkbi@fGofJm8v|>-OkN>%I$8l16KIJE!kRS|q4KEx4>19RhiGrfVYzyMq zt{`@oqoyn6F9tdWIR}i35Yq}x60t=HaUu=lg#NAs5o2gcz!-u*Eovb~)Z6oMZ2@7DA%YNBI6OhwHft&HQDQ626CtOnYH1hJ<}jebPCbhcy>^OT?L?^zJnx`J2< zWbtV5mjy5yV`KrJSrFaqWto+6uc;b)sC zGoG<>l)wDHkU!z%t%RPk!gD~)ult*VJI^8XzO8~zlfPZvX z5Q1;wL5~MLp2mSE&^*ACfhPk`2CfIL2d)R63Op5fD)2PmX~5HfX9CXzo(bFxTsrUj z*EY-wX2uiWrl{E0rl>CRKJEQuqb7V`8(Z~pV}!;%R(WX~W-uPGO=dk0m0X`3mcwM# zW<2R;hLu5!TlFR}(I-=of@F0a%IU@>b9GEU)97B|(8a8vBl*3X7|jEs-%z!)7CJ_x zQ4tlE^SsP?R*cQ9S;3n#THF(+&^_uq_iLq#N|P|stSP-TF2A7^*qoO!zEq~f3CDrW z=|hZe^`m`zpx?w$nh=&%A#=4Ava;fn#whJ4`RAIVqtj}Nq-brzz%p4``<**sV?s`x z9Ggry0t<1RoRF-}kCVfa5fdsL<;6^kIj_9p}UjV<~>$>sW{1-*%iV z4I9>@EiAJ~n{qVS8`h*|n7z-mrRz%UEW!+(V(&9@rjA33j!}X#T^EMmhjl8@XXwI9=3eBNA6AzmfD-yj4+FXR7J8yMf(_8&}*Zykg5~9T!VT%>xY-5~p&7^3IOI?GV zv{Gr(Rz{m5E0au7l{!;&Wn`lQmheCOlqa|IMa|D+H~GjHb~22=fK%NEKGjLSAtFM> zs}VcrV^0<|M5vVfHN?*NGMwz;`)xLfQ?Ql6^*;dXpF{4*M#5y;e626~QXTAJsyDKg z5dvMu5rWYPrw!1kJ{W-RxKN9*==EL3RVWZ8_z-r^2s0%rR z?Zu!yOM{mD{t&(6X3($(Mb+m83V?LhQCNX$ov+eh%=h_tlbew>` ziJfP|YLj1AfxXM0=WZ%ZBc?zq9cA{UuQlFxSzf)DJ$zX%IW=*dNlH=Jq#mgGkFZhw z36LS|-~(Dvpqvx?z0_y|&$o-&O54{FeCf zrR~AiE_Gf)?!ZU~TR6sN2$4lW2S~5K!ST?&)R?)GU-JQ2M#f zfxO=K;px8UXL5Ug8%fo^nruHdRdMKJ3o9`!*%t%Z72Q5rj?j@qv)(nHVvYAr$d@DZ zgFK9ph8Z}2!0(HcV-CwPhu4}gx0u6gn9I=!KgT&_2-Z~@;AKD))^HO{l?2>HoNBoJL6SIut=sU>J-u!GUcY(PH5|s?&YUP{QMN(InyyS#7|*1 z*z*1x+@w5ASH%QyXplRLP#brc{s#8oalpb3)89bc1x$6A{s!U>V7}HbI_zlMgw+(J zj|H7t4#RA1Qx96W99@Pczs;TJV)x~Z3uylqd!k^$xr03nnbK9;0~9-`!T5~uLQAcT zsf?|RtDHWQIr5Nf^l*(IXo)dd#y$4yOtw0`sG*J_l8SJRTbZJUG7{w_(gayoXldZM zJcKvhOb(ZE*-cWprZT1OwKvGiEo5aH|M#i)!7jC=!@#HWqj+X$n9YFE?rh^S8{GX* zQ9hE}sQu5($NObJmFs`O{9Xfa{S0I-Mz} zBSs%?G1Qrw9EBW{tdOHK6>=0pEg%A*K|CCw14L$Sx88uBmhdYb?@O(iawpwWaBhxZZjLx(M1vH~#Q5hch(8yiJ{y|J{lF*$xTF#o zg+OdCFbaWK1uzPM*wetCF5;wU#nbku9k9Z9U=6C(;IthTHNJsmiy9Pz$2TZaVzu}M zMUfNB#o0y)l-o@)tL@tytDPv}p{M&^U8Philu8-jU`rVwNviP;+kt-&H_ArK;9P8` z9Q+(^qhV8wDv}s&)JbK#B6eRJr(?2;8a`k+ca)cDRpG`deuc7~SxAh^cJ{gF+PJFU zK)+YH*+xdA^=iC{4J2A!GkOK(&F}oYchMb>d+=vJn;sZRF-e=mbvZkbCylC&Bx{{WZ8Ia-kRHLa!kR2|^Abhfs}BjZlkFi*P8yp$PqQ znVzGto^o;ip>uK0KNlzbb5Ya$@SD-E^?pP5DlzmO5G!-qSXo)fm}6!2w_S5HW&>MaDT<4y)=VD=H?+1I>rV zlFG~r6L}XOkJD9zG{o0V6iq6~|2bo$E=1WQ8d-+HsP08e#qvP%aU))}s3^%VU-A9* zFvpA2CZLX!(;iPeJ|Qvx)d`WFPq2qmnM?Qbqu{er)JkiQkXRoxf*Z~aiD)X0co*Ie zkN{DuiUMbu6mf;CC(be{He%{8MThm~znlr{2Vrue(~26lX^9jazN01z_SK#?E+gEl zy_46VWxjRKbIr5QFAA>9xmcGJBBW0`A9jU7e$KY1_}6TTFwK=Bkp2-;O=k{YBx(He z=Kli+qtnnXQ(glL{w>BE-d0}I)Ao?u zPp8jtG%!p7uzJ`qPVyV3DRB}|wCu=Jw5+sI9vW-c2oBH_1!dFLi5sV}EwgdX-Y|_D z79l;>dA5m*zUIE)mBrt0X9fg&I0`+Ckd}82a@{vRFe-h-Oji$#N*|0$KS@&d<|kuJ z4$VZbwEl64(t4vh^BSTU#YHY#g2^*3;K-z5R47D9V>)}des^0D z)6d?=KQeuUI9DIgb2_6=8th^1TwG-vtFLTRn!iX`m_qg%FmwGnnL+H=NlwNTCon^~ z%$u<55q*Ln`gd(oqQ8yJ&9(7_ICCYA;!CPpwJf1acc=>`G3v-L?Y0l)6tivAEH z{joFAsS}BGyVEEpK%&5k>k6C)jG{&`iai{OLJwz87lV@!5zDQE-Sjpq!ySv~7}PPV zp4z5A#2g6eSkHiWF(-ck(DV5<(CHbS-XG}li0%f`lR-}gjov5VuC3G6*&M-ueofbD~u)B-p*mcY4EnC*pvvJF>BkgQ#Vz#1jn}Qgp3)}pAa!j|K zn&R|)ve~iO`53)z@X-5|@i+$sZ&bR|F3ZjJ-S1Ua;$CHCw|kX;fJ1^eD_<&Fzql-a zRKK`zi5+xZ_uG{}Bj3N%Ou}7?&~?Z1s8b<4N_$oH8MLCm;_k}Xpw$*iWK&^7xE42L zwLh2k{(ngO0BQa+nMAZWm#zPV$9|!`<3{_nxFM;678Ym+ZDdMiGtk@GpG(8-9!>Mm zn-#80YvZ`!y$O2l35+Ja1qs}p{5!4t{Yg^S{YfJ3PiQ`RUqa`CmJZyZ{FwUF_b73& zJV$f^eb$AZFx=Zx{tDj9Qa+UTrss5z-s&MEcGz5nkMib=yu$9|iW6 zOxN-E@+;00t`mjeS3)f|uXI^#OahUjI#54WUv7slJ_as6ziV9eO z=)GYVXWv7Mpq$-B*=P^s+u$?_8(j3h7&H1K&c?lP?a!rA&i=Wy|HRpJrGQI+lCys* zjjk@r*+{E3ba6Jr7^JcZ27&Q&C*^EVYzB#}V19xY134Hg25tt2cX9Tx|J$5B2wdH- z3+Vh}XEvr6UY1KM5{3Q(IIkqFC~bT$Bz30OjNgsk{w|%PKWwA{X-&gKF$(8*g9whp zj`N5Y7CLbBq^}-;J%!3>3G$W7>0wwi4gkI1pmJL7lG8!i{6AeoRCd!fNaa73@l@_V zjQS@7r|T*W1zR@-c@kr;K8(#P;Rf5&nIu4ExkT9{Y7)gTye{ulx4? zzE5AJoq;!0TN`sYfoJ_%#0|8w5_LbWW}C<)1#VGwXAY2F&||h+**a*kMc(W2c4Dfu zD(WmUH-^b+yB^~zYR1wZl`xC$Z&PQHma^glvo6kJ484Wke1u3c?zqDol~!fl1euFI zU{&CJ(t4f1--CL!=+57Pzt0_?Z_5EfVoD0=>=4sO#=y;GNkK`0d?rGAtv%O~>%0#) z_r1gv@qQb;2&57vtRb8Nnkg5b-=I`R;vS!-762dH5C$!!L`msAK&KpKZBVk-28K-o zSCz2&4JNsIw&q^7&1e z%T3^!O&CnSO$B%vXk|16O?^h`y08#>VEg$SYIxkT*vr$-lA5{D_YPssbZ050?^)Qq zYp4w;_Y9qnNLS>zWO1r+Q2bJ?Du^h|g5$6ym{y6SPN$&Yl z)X9Or2;c?O{W5?_)1B$*))s1!|65t>m(e%mSqn9YUz1h%t(R$C|G@A08#+sbbnzYP z(?k3BC~Qctp^pCoeBiIkKuXS#{(4t=wSFA)dWsPJY4nHB+)$An05hNLU|uCsLtBz7 z*)bG0s|j){`RLRnoT8ZYR`+y~NpE&XKws=JE{snTBc#LLT~@`V7}q4&6*GhwJ4qb~ z>XS0{%kvG@;s#w&YR+Kcm3X0(_0S$aA?tZ{HNEGi&$uZCb}saj;^hbhz?d`xnE;4% zL^&fwTQgZj@8oG1CumTkrJ0n_J9#}qdM9saCM)QTJhUo!Gn5ou%Y%;A1gO{Rf_z-y zH9Cw=(>;9bnOA#z8%HDsNev5fT9C&*^Mah#Tcn)U1DxiW9dC;V=W-0?_eYilcrr(+ zglA2FPw%A#ICa_*THYw-usR!On=w~D?*VUlz*`>hRx0|MioW9Z-Wnk_w2ph_!2^*L<=5-I~P?{a5*h-YDtW z4-iKBsZ6&$oZ{iw-`Vs8SaMX(pmj%gek$g)1@lN{DAirmP;j3_82z@&r8)zzieiZIsmVD^;b-)#uJP&Uva#`V*ua#S}T1Wt&Tf=$MqdwbxQkIU%LU;-#xw*jM#o_ z_(jH$EhY;LPN^AUq9YF;5z(F~x56{`R4=r=#+MGc5bw$o%Po^+qmHrJ@S7ttIXOaf zM%blvQ2|>elbtT8F~S+5K7+kP$6^|Mkm*`_9nVc=MKi|yTfi51COZCe0aT8BjW|6| zD)~5Z4<8TDg87gL+b z>iCenqWkXJ!s9K{sx{65@WY}Ki26lh4-|s&lA-{m2Wp8GmyS=jEydmf52V>f_{WVB zhl=SUy-}t9abl4;e&M*$Vve5{&|gQv3$lAWClr6QFp%RBXNK^Ii=L-`O2eh+rk_ir z8t%`f{hWpii$pDa8>^^Cr2mZAb#{YCWbMzT!6VY2He4Jc@(tRspif-CZkh=l-+SYM z5le;)H`bZ(x2ezgTEBwbA`z{`h>2b2s<)chF&cL- zXM&&Fs~a`3F4`IGr$%?9#?(<69q>BS!rv@OOt4j>4s8vqr+T0Iyh5)&&j4!SOIC}s zV(nGE?nB@o0{;-Wd?t!dboIa+4M}1g{E4(RMa?T#7d4lx_O(9Ii94=IT+`Oc^wyu= z>vJtaehhB)jeZYJ+S@pHE^fTCAQx75hKKqBFXUif%z-zDWWOFNpQmFKY#Ftq4S5%RP8yOL z|MSu3#Bl$}fu@be%79Mv3u$-^G0R*=9md4aVn< z4^RT~ZuU5%ZFb>ZKiIqDK-c-q@iWIgQkW%X_{S!&igSc};~Am&8a36Yi7BX2_vV*7wp$2}KX+OB1u%4*t$+Jxi`%X;+uTN*{dh^$>7rBbY9pn?C`UKABGG&wQocJ^U_w+(Awu-+D~7r+KY6A55nhx^BC>) z9O7&Jowp~($JlMu0(eY_dI#@~sZaS@H+c1YxL=YVz}bZAP(huF>QXWwA3$|@s%ugm z-Y@U#;iF6K1)x!TfiB%Zh5)GT_Z-eN(}2$eP&P)dOA2q&6Iv1{#qLtau z5_MmOw{xo=_Un2_t*SaTc;cUJD*Fcpl~XOb+L)n@*VA~)snmacDxg;e>IBgDJZP=6 zQR36K*^b%HIj(M=;LW5s;2j+f{b8o#5oeP4$UW&6^WF5RjwEraYnn5KPsY0jI=qMR z5Z(%S$ga0!@|NZ*y#<>W&R^8qTBP;Cq63XIIwR$R)9!L)i?DZjqG4@f*^xM9msqV0 zitKEG6&Srn&`9Zb#yWV&&p2@`&T_Oo)}bxYmiEO6SQ>KCtDdlFo2e&ybFf!K?SXtb zt{eyD&oI0_l8t?Nc%iYm)@a0i^#I-qo4OSk^+eXd=iDfyd2rUwF$vYzQ|%@8I=QyE`xQ) zxuT7UckIqB&|E%EOhzGvQVkLUQ`E$84psgeFHhYeC)WKrsm za_9B4$oC20gv)ZP@5B?1qK2K1y<&euohZCA{tXo)}r&KY(*8qDo2)3Excf7gclsl ztgW+(ns;Q?%DFK|9lw_?F~67dV~U!~)*f<135W3Z;-Mm5F5Pr!JaWv+yOm1RLZa}T zGjYLl&O?AWQIm0`CIWYD&%k?LJ@80PIP6(5V)Q`vVud4GuNHdy@u&T`4%VE@@;m#& zRQP>AtdW@?-jo|2)=12|$HNoXkS7^qvT%RYTMSdtRGPB&XHz!)Y|7ehDGAWdR*ffN zsDH&uJJT{VFVISi$n;MXm%C!a;Hj~4nS*VaX|+nm*hFE8Up8;LE76-NzQ8$WS>Uux zL)_&$gJ#-kU!GuV%-C`IWs%yXKS1Y$HC`d55Ul@Owqk3W|O2=_@54M<){^-1k`5Eu>~kO@W}dH ze#y-A!|Fc;IJUe9JuojHPpNno^Zmjw|5K*H>w$!8;NOTdW(CfYc+2mE-(!`A_vX|{ z?{~}fdRMO3f0XM@xv05((kLNEnBba(Jrf?wVtY?@xW6x~8R!`3p!9)Mqk^r}Dp{bR7E+(rm>9x=*NsLaQ6t1R ze{!@4b$}R?GNK%7pd4#}+6jaECB3VmYiO@2hExFP+9ZH)LEnK;3y^{5BfNo7jS$j8 zCj+9%pT5&0w3_C|&~^MZ>iHUZ7}T>BPzIoDmae((eVyp&vf6PNgG4RFb_WD{!d8fe7c|*zM@mT+QNEH1@VWKnMKdd;dR@@q||iLK8~#nmtOJPBj8bCqqS;m@84#P%6-&!3Yn!JDQ3eW zXA~cB-fb;hda5%^q`AZPri%tqwU^${Q+auxm<6kcLCpIhc?I(8{IXL}>Q z_AEeBLL#B|F8{jrz*pfa0D5ijJ}G3VF2D;nuqK;PrWqlfvt8A%6^#~2rbTjYJ?ZGr zpR}7`2hxb=43$>RmrT1Niplwh%z09pOO|VEnBmOOTh}kk@@X=7cpZ~I^wLrII#9_E zDX*C#((@D@^L=9neEFR7oPlZAn5K&?P6y9eHFcG^eGQjJw(o;Z{mO)WPL=e$mpL3r z=h7qGPuq!+&T=^3|KEc=znZWId7kuY@J9Dvub0EFpUu-z3zrhwhn{5yTcjOj+g%R` z$-=)p+w3~SHst=3oOWsh%Km=B2E>+mA1fsN>CW}Mb?KLrW$kE1bIBZh3ujAD_htFQ zF#|l?)S1P6xb$ELgD)ygbuVjb>lzf;w5AL(ZC<| z_QR-V&Pv6oe$dv@y7Uf7d%I?YeFV}bc$IozYbQoz7`_1(E;+nIL!+MZB|Avr{#<@t zuh_?V6oa@L;ATZ-CcZ^t6vL$)^d=6xrE)6{P8iF%qr0Au_0Z?~`g#QHdjx*0dOpn0 z@k60Q((^YxhhN9}DtHDTk!c`{0i{a~M29?Pz!Kzn9W*`g-yr-wzylz~I>G_yzDLi7 zVS@~$5HK5XZi#{HK=@0*9|4_!oWW=Zby*Rnp)U2ANdM?6-1Jn~+4|QS+y`}%w1}_N zpdYZRzEt_Y^+3!Pcql{@HNN!#sG((peWy0(F(?!DRk**5=1X-~neB_HK7+NUXHhC( zIVLs1ax%X8<7+i`aw&;lQH%HyYtJun$LrI&&J9qtb0cu2%D;`3t7_b#Fz{;om&?ZD z?Gt7w=D+RMb)pa2euMR`$1~~hts(=z#Yjw+TPb?XZ>IroQ>jZRh2HV0q~H9O=JB;| z^C@`Ct;xk4PTs6RVPx^nrozaXRMJV5p()Wubyu0H-{N~6smw_eYNquv``P`9{VHi? zC+nxt7F5#WPQ^)DhL%-Hb32)n3VYNa!=(Xj^otv$<`?MSD(7nd`w|t^i2{5leTuX& zURj54YSgj#uEsJu@hk%uMzyItOYPq4zSbc=hF=Vdvd!1}RL3IMqH*{}kZ>Qr5VUqV z_>Ly2NL$ZTi0j#k6YCWfH`a3%X&aOk;)bw_6B|?&H#Vp%(l&-yh#NH(CpJb@+}NnC zn2z#TXG0WUO~c5)U=9CjD!h!tCAa(#*2eY~4`OW$lOOcc{vc0rolE7~RYN_S44YVKc=h@9t*3edQ4T}c}!iQ-x6LSY|&IyZHcJxY|&PX zMSI6(c5sT@j`fx4i^lILAN_*LL|+z0I~_A~QC3L{yxII#G77n$ltil0uJLDq({=wVgdKn!vw=(j zJOK#WTTc4zEhioDkG2;z?An+p{964=5hMIsl_&7cgr~NZ%kqrlfJ(LS5-cw-!SaF- zpq~Ab&wA=EE3PUV2$b0a-Z?* zu|bPONzNp>B$HYtYzTkh>~I7yE-O#wX26Ti11~nuWqI-y`mGpki`oCpn5ZV*_{(zs``u~Lhk6Q8hu1h$ zgf-)jFU}FDts+OHcOW_R=9T*P2_@ZZ6h)F{($dhgP-{O0=v^x__<+BYtJ#t?&*_3K z1J7Zmr_1h^3;~vx;7FjZ9D2&0>6#g`#&oxHOoQe0Zr?=BkDR2wYikfvgm_0 z7m@|L%QT(ke`<4?igMKMLTxV8W)rl#P`#hpVyOLv+Eu6x<_>7EtEAWw(ldbspf(kH zUZ?;xBOkS+Q2U7)zyZg%pUdc(q832U6G3|lwWCmbO3(#Y^bfyx`7dz>i zZ0>eX4ncNQdxT2!wvW2w9 zT=@H|NUq?t<1V2#Q&MTEk1cvqQ6%ZK)OthxU4z~QwEz3~SG(TVy)1uQMeD#Bs45W} z%%D2@{)1CeYv}ius4p(XQC}6U@2BeO$q)8_frr*Is>|x6@P`V-ZFox>?*aNlMQH50 z&zb?J%JNAm4ud_&F)y}cSuMAYuL{QL48}=iMTxK$<=tXf#y{GSkaOrail{yEZSd;b z2&tXp1o-=PKsDfPz&n6*0J;{a?ijR{kQik|4B%VPsXZlVOOa8>w@rcb*yGM8y6iy5 zT5hd~6Y%Y`Rl7rcsyDqSU(0%5o{>dDSa+M$WB1skHr`{CT7QpCYVAEXsnyQacso8$ zSnW~>1Ye6$2rFHy>_L15_34u~Su8jVCipGZ-Q$a0i$ggVA*WvQ2o}i#4?t?a=^mfs zPxTRt6cegPF9qW>aTAye$sK5adZ^B6{!%3r?lmIiPdnwH{S)unO5Fy|cnQfn0r=PV6ch-l1wPugIAY>;dA(nMj7hsssT zL-ZW~BU>Bzi`rkPtxZinA{UU4+S;sX&-I|THY#hWyrwe!0D#KupbaPicrrk#VpY@@ zq*5sS->6`fL`iKyN`-=@wjiZa8AfeE)DEOjvV_`!7^RX>J5W5z|GVu+i}x^xLC;f5 zh3!M33Ey5Z)EOpKdvgME5|*|*ty4PadC_b)+tt#2?PloD2Nl{ch9JjZNi7gH1RD!|9SI0=$1kKlkVC7L|l~>@U5g{ZN}JBc|g}b z`GokW{CEdI_g?rkk|FloGx(}w6It1NI@_Y3&F1vXC~A10jS-sN1L0TRmGVP^kX*C?(}?N=rY~b~mMWA=h$YP5ey-?lgzC!AhZpy(0-u`faaUZ{z){P+KkO z_mqpgoASfAXsaaDRxZw8x0V~oYJj=~`Z>ZKOL4c3a2vqaT2WKgv|ORdh`U(Tv{0eU zU@ufPJ)+Qhs+y*B#qt$O#PBk0h7xI46s(;zZYLNSe5oW2<5=DDV$j_{+!`ww+X~!#oegxJpHaE zJuhaWpR~?goRhVD9_k%)0bil^rM<be_U)Phw9(a?CjiogxTc!xP{=U(%yti-Z=vx~4_K2_K6kE<1?)HxMOM7+_p6#bw zGv3o$+E2C?Y>WCPsQ4&8=`+>9-WQaHw${h~73oqM`iN`I9FxnpwZ8u^g=vb+RS^9& zo67WrYU$1PcdR`wi14S;7}e76?;M35H|nf9Q*x)lk0=#w)X5Q^CqQL} zMl>-IP1lXQ(VpTUscPv1IR$m5-pPMUZ6ePwmGn#XYV$%~^(uUN(>PvLNAyL_^;v2u z;SQr$N$tKK$bUkPw?{diHI72-FUoi~(vc4AsLW)Bxpj6GT6|7sJS5d~9bYr{%c-~F zGef^2``au7xdh0?Iht5VOmsGUArPnUM`Qpm29yBs4Q+g#Tg~@|{i3BaT>2Bv^srI+ zeOZ(|(QEl$XfeBeD<6NB=;{0~IAsTAAjTs6qSmfOAEw9we?MuP5?{~?m-_ff+V#3B z>(H7ozCXT$Z{~;Phf7tRFC~3_{Ry;5`xThK?YvU@^&O?8=&U`>q^awa(qG#--g0)c zeKYDEC^vXWzfH~|Jm=ZywEXa44`|d6t#icj>oGQoa=0|(4z=B5%-X}Hd@p(~UGj$E zNgnWqOGCXS_9dt#OjhE1)8W!5fNdQd|IS%5q@~V`XZVBn9c$bLioNfxZrQM<;i6LN z(@xU<=?;^Wc!n!(PI|ZV@^vQl(IVn`w20<>!~2k9B(LCS*kN<=rJjA*KFOhyKKE66 zV8_)2dgJy|uB053;++hhR6i45`5;d@6aSZBpE{LtC++KQ?^g6RvqN{P5EhXcolE^A zyUBaPs<~(f&#I&oz5@FwgfIDKdz8{BJi+o#`4k;l6+ZwTp1COB+>ujSl@aTvv+{^{ zh=b)vp>I$4R40m>pIzZ?E%D~s)6r*@wAJ^A>ks5#OG-VJ|ASsoOPjql*J&vm-pye7 z!6;SYQ=9O8psK0(=F>vh*wtprpZd4(#)xG04si8>?@uf|QaQd~9i{y*#@+?Ksq+3G zKet@krfqrwN-6XtX-j$mLP4mC8rpJ5n?fs~Lu50hh$)~J@T+*)mvB*0(E$ZTst&Dg zg15HX&5A4tINhdOg0KO)8O03+-A+qOPA+YJ@6Sov!S?(8Uw_Ic&;9vt`knibDtmn0kcvsXNQxK`&i^Y8x);P0dUo!;n_OM!J~Co#n^(2 z=NNBCVs7k*`3k@XV5gawKh6aH7WN$2X9C{G9Df&cXddh<01pH90IK(aPZ;KB0M^>l ztvQ`ip|fsNF{r>Di#IuMo_DkQo@6)E`$}cM9s4`I1cF9Ny}POQWw5W!b=6KNa&s3v zT#=lkePihlj7HAU5KZ{py7BIpmlpQhM-^yUY_fQ zx;K^eG89_D(hxKePVx&hLo#_{6<6#w#cc2N9`K|1k2(q-Y?ojZ~;nNM*M z??cWG(fGhsSW95O0`pnGKQRV*aED=b!mXW-^`=oY=H)?PAN(1B5r9*Xb+*s$d!4K^B;$8m3;( z3{h+k{K@409bQG@iMafTU2akRD+1!ZI9Zze8MKnedRk%E%RTQh zUg|6AN9sccz*?1VElyJ@THR#K;3BRFGq`9%-Ewh4{e*dH-s>!MJBBoYYhB~iJgYHl zDQ`PY+SCruLX~#=_fV5;$2%z9 z0qBL4(lf~0hCJf=XCi;En*VTKWfWG+TC?1rcNx6AJcOCg^1xCetqbK)*+gqFT-QAb zzh&|UCdw#4 z`TA}ay_V}X_?O8yaLYx?7jG&teWKkQrwwojfn+rJaPlB*^j>rf*vpnd$XfWrxersOh3Y+)3s+5X6>c?%!n`(Z%Ylp5H zBS7^Z=WdxhJhq%X1RwCgqt~e~lbmdEd#`~%gSP&Rv*X?T6vi~!OMT8=*6$VQyP3E> zO|HZDhrc{2RpIUIG+k-fpVBq8u(*ybIeOtJuZb{M0f)nvRj2y3R^b%UE`GffaYc$d z;4cr5sq<;AVKwaU6xPsx4(BNwSAx@=vHmgN0S?&RFzaBhhS>nK1!jIX_i8if-8u7 zAU!H1=~1I5#UCEy^;ZbE60_O z+u#J(cu*jWb?Hs))j6&VImU+lwAxf5zbu!0S-D)XuABASEzs_U?@Y8X=o#D@taP8C z)q`BSympHR{;cW`?R&Bn{w(M#1elyn=Nz}xE$sm}0rf5AK>hh#EUwXp@jjx?9lYYI zvqvL)d5!#Y4fTNqYmR4dj%?S^{F#ovxViR6Dn&e7KvKe6%!`~%(W3efyG+tXDbHn< zo^$Q*6_Rp6RqU!<(pX=+x3SFpx5nIM^J{Q}kN5 zO`=tl!lTh^og&Vjpn$^)5(^qs{V}JbvEbjMGn_BZLEcPzubzh~?8Q3n;r3!B+2u83 zrKHu8(lCRZ2%d<+STIYq`_tPC#hxU!M zH+AyvkX7aO`XQFlmbM=_qXMQivyE-dYU5h7+xXT|Z9;3>?{NMPY4<0!jdy_B6rm{y zH6S!K5xO>HyQQU*HN}GC6~<({B^FFo*o0}jh5S<$Ya)gLA=X=lg3%b0Fs-*RkeD2e z3Dd>0Gk%k(lk1|R!DW63^YAZ#Wed_BSz9gGW5)^O3|SsXYxiVqeXL6-=Y*0GZ&b(x zE?CZD7d3M85NSnXyw{+-#Q>b7j1RypfVmGQ_9M)#1qKpIoye!gZWFqYXG_X;SR}d zkajtCyVKn|xhK5Ly}gn@z8&e_4s*CIK84%X(eOmK@!&T2?N5Y1279|2{wTuV4o`Ax zrG}n|;kzfyN}C<8&fVQX4WI3K!(u{Ok%2%FO(v5eZtX$<TEIlu_Vv0F$*!Cs!cP zA0toFPg5OZ&7Qy#$3&D>mZv%cs?Ao?{Zy z8Ihk8Ef>tU25QxubcviK$E$_Tgg^ywCzs7%zOKg3EmBb}svo{PGx{;M7nQI9EVJw8ExlTZ(>c}$?p0i7hE#fs--MNWs1 zlT9i@PM?N6J%wtDw~@k(6isH*Z)0+pK!vE4*T+~fEs*cf0jPcZ5NkYQjdzSy!`+|} z(R9$>^&8BuBY-~u2)`7qH!^?mx>;p1DXwMw6Y~eI3`Viu>jNFT7vM`LmbwZ zT}VTD5Z|gG?T{XqGN6s(4aoB@l2|Dn5=IY1i?KSSIdz zT4*v>dqIA3PyjwokUt1%<+DR2PWDxm)~R(UxOIrNa{eMGhjSJC>Jau5tR-HvGsmTs z9Wkx^`=L;956+Jabhs(lS2U8fC(pr}v(fTj4CMxLYlPQx9o33)ycXxa9Pk;f#Efo^ zxqF!B1i5E$lykLNl*YQ*fslzE*w`2g-WTHoMu&j(j|>U&sX-0SpnkN4+7$#qs{mui zc+psPKOr)D(81}hhCdV7SOoJYz!TEA-b#MvC-j7`%a-6?{y z`TmV;`K5$k(sAQ!-r??>6K? z= zvCF27^AOgLbXSHI*4yPV8$VUU)Y@E%{ZAs#yQzOuH_ihg@xVEjYO03C>oa=5gZgkA zO(XRgZZA94E{BnZdbM6&GBwdFYKs%?ow2u4??ZcgmmrUCJ!tXWRJVBOl95nq@n8QV z^p%lNN_+f2La$8w(MTxuyG|XAPPNS6sBKzVgBPI`PFi1hbJ6U+=@aMltzTU)Pfx0s zGn1Fh5s!~*5z9Fxf3;be@KB|amuFUTKH-$n&vDAA*DG<>=M>{oPDw|28o~_-*CSku za1FwRyf4n(IFCw>&x8FKp-0qyc^>oo?g?DWfl7Z@l5c+AdzF{ED!h-}BrScaa=o9$ zocl4uN_S7dSSeibfy$@5Qhe`K&hly@1@A@3Z=I@ee|l%m9f&EPy9Kd07tNB#5u+h* zA8=Db`u57D2*oTR{P|M}T=`Rp_Y{~My{o|F6Q+dWW^%$zNtlL& znVK-u5@veBG$zc9gqfKzvl3=@!W@+_N2?~|%`i`^W?p&a6_T;2?;eLYIkt3+pQI(Q zrCI*5&aqexwRktl!TmR(gQziUS?jW_rq-sc<*m!JZg0I^e`qi`4qDw9J0zUn7z_Fb zIjnW5j?@}@`O(T#-Zwasv1*k@Qyh0f11b3m@>2&dr`7!_)+Er%rIUAs^31_{JD-j!H5NcU5arkR~kC4pOoXh(6vk9Z`4C>jt01@ z*2;hS3T2(fB#p0P&CKq%Eezf{7Wde2u4f<{-`0cJQ(vq6+(%e0jY#{C4R2xeww5M6 z+B{0ileEyecL-FO&nUG_iDV&OVcZd;@Be3<*ZwQcuP9C(E4FngK^yAMSncwl$1{%= zCrehy2u%ywARD0!wxke+$sTaP_T29Pg*2#e*JFR%5m{e{^SGIrh?grlFi5T697aE{ zYjU-_s@xj%#~qDlU3WVz%kFkIEn_Vf7bC9>>&;h7`x;jxhu;ofXr9=3MrZHs@$6Rn z$=>%4Y%$yC5KOyUnKX4;=WfOJRsH!t&gUa(Lu}xrvi)c{~$E@zQ$kB7VTEPMJjF4Ywj-i{{#No z*IthBbD#^ZdqfsDk;WK>d!AM zBc0SqQzXUk3FkB7J?-qdKO){(=h5$&Ir`T!>iFIYPHbMN=<}gjusZB-bSuI4zfE%{ z;Y^TGD>ib06v*bo8P~DIr3CZwnl+AI^tLfxnqz~Q-|5%jjRWs_H|`dhNq||fw*dA4 z)&o2MnrCke2tUDZ4Tu^+VM%fRE{+Yasr2J-zvytHZM7b`Q;jKEm&;+$e&6`1<- znZU~E?DglfmjRO?!mNajTQbdgt8QHdO}7Xq{1}C&1AC)S#Nim=denHp^VkW)Q-3}S zaSUW4k5n?T^RU2Lq>0m9IzQDz*bjQ*C~h^DX)fawtJgTu3Yj9!n6*zv%iUVM*?v3L zupeiaC>MAhxTFg=F`_Eb%$AC_p;tChpV+$VaQ`~i%k!+9&+fK2C>C3CHG5rti6zWl zOgeq6*Hirg9+kQ24WNDJ@Q$BS#h=$OwnHu5TFJ076{qB4NF#Y`$k<8p+k?kj5TcPD zhZfm9DN~qfVZoUR>>u=>=v$XV1G*J;j0FQR5xR3pzRKsZc*?%x$s|#&`-zUNIKibl zQ|!Qnl^VPUKm&Mk9joTSB=P{ZDQ2a61#`ffjW=h=RE*=mybP3<$lW^WiH=dA>MqVo zla?1e`K^P|?cx)4s6hFUN)MgYuf-faJamz2KcC#0ENbQ5QFhk9pr26iUwYa{UM{edO_ z)e*t~a85V0Y%(^&OK+cPWH`ubtXLcOF_sw_8Y{wAGOZl6CJ&Dm2!IcJyxusNss}Sg7Y=ysY8y#DfE}k97w=O73FqN%%-LX)cZ+OkV2FlANkQYM;6*TFI6S%hH!fXW{19y_?%+?XDsh|ZyTE> zRj!0=&*L0^t$0^uic)E!%V>}XLl|)(^{b0`BJkUqw?KgGWw0akW|TN zVRuk0twdh~Kk}{r9ux;TI6=@la~*IuG@EIS)<}P7-iCf2EoI4^uE3`+VSPeLvj0Le zkFSa;&GvG@3uk+UBDM$=9u~H!zJK#tzLnd_S|H`EmD{heywn_@9}L!m_Q8$l;adN7 z0Z5EWl6*9deCf5P^(6-X(dK8hDJOHaGfq+;WywN%wpTlmn`p!)3SE+KoYs0- zxMm_d(G*~dm}dy9$(nynWejbUKJIDXrn!NgVwHAz3A0Vu^7bt+Zacp+7W{EcouTrJ zVQruXG#lJR&`wMgioO7qfr0k2O(X$tr=)eaNt?E9l=y;FY1*pe+QnWz!VaK~t!$gK zXXaft=@!VZS}46cS0}yN!%QrIhL*SwE7uR|(9V9}x|Mw^yDntqYfjsw9;LvzKo7iS zY$E0aSIYVfQ+PkdYdYJ?1rFj>i$C2o!O)o}{qbByLf$LJV1B+d+LMw--&QUAzdWZA(bA`A&7pOM%4w5ktL1FPx*jj-F*mm(86~X=T>F11r|A^8cVU&L z6+5N9Ugizp1Kh_GO>a{JT#f705zbD)?4Dpr4ZI(@rt^485^w??e9t>w8Y>IXAaQv$y*~vgYRM*6N@8 zpF&?SfeJ_)r5=f|!_+6lL&gBt$*jeGuNWEj}>uAK3jrO+s^IBiiq#>@>P|Q-=N(FCy~b3SLbx4yni|Nz+UC^b3&;B>k#d+ zqWay=j99T-(HA@vrgJ~7t(TAQLhWx?<>0Mh1Glq7CyllnaIWA$cO-W5g>1#c_N(kj zB^_#FCNc84jTOlGaP(~R3p)NJVW1#aGjg^W@&#vCNJ6iH!+MZT@>;_YHUPcmkn%*Q z{pL+)-Q50{wh6sf4N(EVFR%Nz;mhm(RrvC{p9x=H_s_x=YD?mE|0HZvUAL(9`!HOlwq%Lw`c2q+ zS-XB6HliN!c3l$~?%mhJm-p@~Y7K{b_k}BJ_{2xt&-$_g_BCmSPX5xjAm**=7o>my^J73jXDN^)i=IFKdz(dk-n2 zZJ#Q}j!zZq_QfbCo@-^FaUGp&u1(|+_6WTdn&G+n#LyDye{nL11=GS!YVB8ZkaY&P z7QM%tH>-9gyvDh7mQM5`6t9Z2gp>mw!Lf1p0TRh(Pp_E=Or2+Y{HYS`R zA5*rfeGv$qZEn*YQ#@Se$)Qem@;HC{HmhVajW)+m7I=dUA@n8I=HVz!YJi`dbjm6{ zfSh8%4?iI4fe1yt5c((aj(E3rm zpph)tj5TbpPJg0(+c=%(B-ZwI?ciQ|xjZQ_Z1Cl&$5h_9pPIpWR}UGS!`- z0QcJI0Q>r%vK~3ikt|n(q(NyFYxUSEH1Y$3?c125LKodQ{?XXJh33M9@OP`otX5w? zY29xOHFOT2kv$>Cy3~KRnNn~8GCBTiqk5Lv3%X@+A#H z%1K>tnc=FJmBv2U^9G-W270*rl^Yje2gx2>`=CS0$9Xw@Fj>y$vINovlLe|1ZrMk` zmVBf{aU(2q4a+jU3H{OpSOlo(cAJTsoqD8KeQhTCF;?Dx5YH^#?n1qj__v7)hWh2( zn1=2=YjC2D2vaF0_=VNGP<#)@8Q;qEJ&jeAkvW^gRpWp(`$jYBcqBU4p)--~P_)|7 zqT1e#R*r;sMQM%E^twdcUq-J<#C<7RF%tK==v9uTfvZN`yQ0$)@qZSzCE`CG zojel0C0gpJ4wR0#ABq+y;@=l7O2l6qEf@)39W^=1Apd!|?#rWi%~ET8TQn~be@QfV zBz#eH4B6GX&yS8u#I1>DCgN5{jU#cdkEY`FiDDCN4lB=i-+0Kk6#S9^=EvZ-0k{DB z0EYn`@VDOvUXU9ZmFI)*58IVm8;{+pTiva=88_c^3-V_gsqfOFH;>r$(M1luT5mpj zqr;=xh9dPN;Yy^A>}tLHBGBlm#`qyJHxc(+=<*!S_v=WdBQHSX6))#ZgvKjwKM}bu zk@ioKYZ7UHAEEJzhaZd3STVDI6qr8Z_g-Y`i2a?<lWsB4vs62O=dS;V(xfI{tQU z;)wgX2#r-d@24Z?MA{vZ{6yMqk?|wpk3?vk;%)RqauRVLjEqXey*H9I61OEn;}nm( zGLojoh>ud!LEL4%|9{8Hjd0d=K;`YYq~B$YIPQs(%1r!@Qz-)&STJpt;sTc7)M9O}|8?tfFPL|jJ-Q&_My!@9zu_sP@s*&$Ui8N1HNC7B8 zS^?o74Z4s{xFVfFmFB?9J%@~ksJsvFtd|e3@ifysJ`nzXMTL5+O^0Ojhns(UC(Zb+ z@fn{xtEsV5Gr--)0*gRcpw@7FA0ay^3Ch-;vX1A}+5AZOofULTMC|*GCWmxGCyO`_ zB2MEe(5ai!0@t9lb#N~@C0vEk$J$0dE5n3&@T{S_EDztK=26_q0poEX##t_|;Bbz9 z1&1HDED7mEoGhs9dZZFiZc2bFo9d7IQ+ZXCo9tObajpwbAFff05lWp|a22p+nvv2O zv-ccVmWkBy+E98+yf(8L^RE#m_^snnx5jIvj&szumhM#PgO#JDEzKWv8XT8`@BhH! zG;=BV?hp0yhS|1iE>-BYF>J{;FV`C@$Ie<}^~TJHzHPzmxYW~fi242AYd1HKy}e~_ zMYpzKb2HzYty$7c^i)e4*;&axd*64{O599|<_vpn*#9voVjd6oovS!>RI7W^pI)O_@!u8QwzYCh{e z3)(Sb_vYqPZsU1Yi1@y684qo4&TWRK%0{BGAsk04bf5^UEd7VqJkosR&atJl&kNOy z9Q)nc-dRZvipf}g{)6mf|3dc}oG>7FdC^0GpX(lgjahVGAP2Yja=dF)_lt{u638q~ zLA+CHJY&Jiz_WOv*yy2{KMhz&CQ@+=?*tYcWT&e8ndR37 z4A6B@Aa7V+(BD!pD$tGmRzW|@yIzDY%4Np^f2QZz(wk3>4!l#USHotWIeM|d(*AaJ zzo&X?;0daW?5Qpbw3g~nm!Io$yw$RO5#??USk;;`)#C%%s?D`1Cy=7r4ll|Iq(TnQ z#Z`NB;>mwClMJF~bz@Ja_poAKfEC#rH1e-Q7tdAq+ZSD2bw-zlv(p3jQLN8(+LO$b z3%+=qS3-C#p7M{E$D4ss zn*>QMId6-#oc+B{X3AAQZi?Q2Vf9(pYpX4dt5!EPmacAZED4Nt!^FYaMYzc>9XM+dkuSlm3M znRjpK90wjo7GMAvC0c8#Hit)QbCp^fkZ)kTiuc15ug+922O6Ov2ed#b;Gedy zVdUS$lCj4I8qIjc1h29DE6~L-TmCYp1@rA)Kntqj0_+0>0Ca9=EYeB=R5%~q*;VON za<;Rr{BiBdF5py0OQN(3CGSElV!@xsa%Fq+zLn{|hxKn(<{$55*b061rQq}nbkm!P z6>;)~d-c$k5qJc+(#+#k`WGrQM`DSH^{Sp?v3xEVVf7Z@+y44t2U zU*?b|)kx>Laz?%-Mqku8Z3HtmsrOy&d%%}HzfIHc`JXqse!%W{yo+$CFM#rtH9e!a zL=LWJqO1v$x$%;_9QEBEwb8C{BV%Ud@)+4&vsrUqpjbNIRf-YvAZ;5I@$4CR-6kBCsxxRHPWc#1hkkO*39j5|(L6<%uN;UPWFR9rxZxxmb(Q1Xw@gRb8g57BrJkH4{- zGm%uNqrjKZJHuZ<%}bn|q!s2v>^FjxDvj-o-$1^DjI4tyUJdaR@#tpqikH2bEhfyM z4!p2`R&$Eyu>Bx|JfB2dCXwf#f%&S!4oJAwJsl4>YY!a7oSQQKG2Cc5lLk7$?jF+g z$~^8|89Bgfa`0IJpLh5QQ;wuRz{C9$xH}NTwI)YOIv~L3rXj*WqqWI^6sAbKmvSqw z=18}^TrqTZrL(rRQaDAv)I(E-XigbQSwAB_46IZgctHt|8VhcWvfwjkuOA(lX-R9f z+?ft6iV^Pyqw$(Esx`$TN@@EUl(8h z(I$$k9pd&-dy+9zm?3^og((%b$e;jU*BS%t1B1w|^j+VoRayOqZv%Z4#(L2CQ?A==_p4PWjn0Pf-GDq_Epph1_ zdIsO?)u(UhU;9=P@^P(U_d?I>o?P?|g&r7W+rUNLsxRHpf7@GHF(-lV_2g<9dbev) zXFx1C5b>#a)L8JP0usdya|C5thNBlY%rAPWx;6So;D0~C>tigqAwsW3R%ulHyHw9KSlc>us~$t> z4UzU{wn)T_)`Z(*!Fr^pS5Dxp)SO0HxTi60m{IYUV|s1XfU1^e$Tdj)NmL`{fS!Y1 zk$2#HrE>2={{i(Eot^$&PRbSKj8k(j|F7KVU6K1Ym*u`}BzO8=#!E-u>Ko)<#+NyTgxcxooL4!BLl4;?e#=EH{ z=^1=E7zfaXtG%5P(ex1|Wh}T9HK5ozK6dXy_iJdkVZXtW`m_N(p7l%`zJ_e1>Kn3m z3PpwJ2bI1YG>cc^p2AGJf1f^-}R+F-qk_p=H#76R;IM_ z?xY?1o#U`S^LQz1>k@i9Qbcv_&N!gOcbywu43{!H{Q&T$9gLhA6?%mf`qo`*pu1d7 zMz~-~LufWa`KV?O_)9=fffY*rXM`}TWd9UYF7>hqGp~c0n6_6iY4%)`Sh+rrB<-Jk zmsLvpUB_H4zBw)9uRt644uLla9?Zp=JuqvS^76rrM7DJ2&PQb z;p0fWK3T9IiA+E^Q_9HSd)S%Wl#hXJRBT#Er;ZwrUKDUc5NZJvc{$(k!9~FZumFfk z05lp%S+WQxb#@$oJ|*QK<_GUfg1+h`IX}tX$Cduum)0KO$C7ambq@P-K6WN3z;*UZ z`jlZm9xqU=!GO|c_Zdfg5z|I`3@iJ@%l&3(<$P^*pMAtn>%%Kp2UbJyo8@!tPDh_- zBy5VWG;jvk+2Q&TrgpeiOJI-JB^S2g8l2I>S1orh+0@dOXtgJ=EMuIOJIPL^-l#vH zTsuQx+iK4zt(49)E@)y(W~*w?>n6^IR)k}U(sB&gK;2&U8r{wf{aJ5~bLz21^QSV} z*wWFyl0Z7G>9cvP#hkhp(|Z0*m?)lTeWy9G1e!%Q^!L5__j5*d-4;gT(z^Xe#5E@3 z8WC5IxToIaifmH$72n>rj$hR3q@ydhG~?V1t{U8fAy;===i5rb_9WS!lplU91P$}} zmgr29a-eWLBflBOOy_gdxgFnMUkS(eD%!z*uHL=%uN1>Bd30&9d|<* zl3n}$g_nW&?9?Il<}j@(ykDozP+cqLUIS*H?Zb=0YJfd4`^>Nx!QP0s&V3p=U&HUj zeB}SCp`P(tyMnX6rMys5sc{bu_^%Vtj!Bd~3&ZAts{y|HNEf=r!FlXe-dNQxd zm5pRh&6UOUEAz)W8t;Yid~$Q%r60DizTd2EY0z2+TQL=dX8o#v<_&WwX^#-pFIPla!#{dIa!(`Xtjw1N%*0_r(I8=H9yeZRu zY3xo`??M?hTbgqqwU^Jj71W;miFWWn6JM^-t7mFE!Pz!jk9oE*)DGMS%eMn#(e5T+ ziq-ClpKYt5S5#SUVjfc^jS8Tm+uD)-2mKqG@6s8~g-3bDwf8nEXSexat zP>#h@8|r$niZ9-x)Eak6uQWnt9rM{zgZIJO2Wz(|4x4@b0??)%QJ8mUvolZx5%vwK+H8$H1??-;;H=3BT)zHWcUnX=mxT$&hyuN4sA8;EISJXIMD@5rJxa~ZFHQ*15+c*`cR8U~hzKhfP z*l-PQakbcMo>NNPqNKr|MtpcB&^GPGjRhPKL+9O^-ggajr*cX7KKGt?op*nz$gU3+ z1rT-JtbY!v4sP!SE&G#rC03ftAtON2Qyd@tS?MnGV#6QgO^ti5+;NZ8PB{$ zbLK>+Fdk5qc?5>h>tX6)8URMv72p9*0Qjx^wK(0Brk|?ZI=gRY)=PbVU9htYbpEF{ zZ!PUPyw%ssGPpsCzzqV1V`rbL+WPiDc!TlyW;MO0H09Lct#|i7y)LJ^vTyA=PuHHx zZAir?(#224TPIAQcjvylvrc*0-eioVfj#9FK*9Oaz?8zpRRh76^Gul;)D*F4?|Q$^ zd*#x#qwIZmj=5WI!k+t5(rs1aZJKIP8VD{u56QJ_HmdfU&uiOenH|-->KyU9Y9^vt z!9}z-T^rF160S|x4O$Tk@JH8i^5d~XionEqZS~!bzU!G-@Lw@r(44@ziV-TXQbURk zfw7x4Ir?TXoP1x55qbGZU~({jF>Zf}RcVt?(nxKNk@T61r+M`JTi{%ZV}KYhf2|33 zcH}P5ZNwXM^ch&zE=sfew={BcJ@`z0F$P-qSfr>xydps(&A#*_P*QTT9h_Y}>REZo zJ(b)Qs(X`q^XBBKaM697m+$v7z#W1fM@$314liGadqg(Q<8%in8l4YXI5{^4eL^j< z;Qz+#vdEJCu`bARhwtO?T^F+h_fB^572tamzV4WKFdp6%6Z<_a8@tHGfzv9U*W#Ec ziwya0f$w)iL>G7jwr_?Yop*M;+`oaZmY1zDZGhad;Po+1_oow|or}9>#(16Xq!o2O z3+}4^(>nB?5%Pej^x_!aK_%W%f>149N|i%q^yM`GnnCsbt%x%wR@wLEocjK(MfSe2 zSKH;oXj!Y;hL=!BilK%4=yAyP?~%!4wHN+;@4d!fR2qC8U06kM&s!dI%+X0!?^RNT zce?a?<@bNRyI)$DU+wMUrf{b^x@gY4jJUvCAojf28)~{Z9fK76?SOReue$aPNG*?4 zzV5Z+>_qVy?<&-hFeX$3`=w3)11!mqC?8gPsulgSNbQpsh6K_sCxX@~CVJwveQU@r zdq&z|SK~cC5-&C8O2lisBEK><-o23e#DbcQWIC7NF1F7@d0!mbmq@b_dH=hAGSxIo zkv9Xvc<2Kj3V0xut9#C+m8_$02Ie{ouINoe4V^W8Gcw{n3b?56ABxXbk}sw29*dr> zh&cML!MAhc5OhhqHg=JVlfOpXrXfA(ai|5`UK?M4NZTJJ}qn=s!b2uYrwNOpaqMQ!QBm;8MYTy+XUF2Q*9z_ z&!{Q#VB4wMa$$Q?wdKIJb&z%?M_(E2n+9>dL{5`oe@KmCgY76Z!a#ixLi;%M&XK_qKHul^N>3Y}Tqc~b8B z$8jEe5#QLNK^j@IQ<}d=c`+7z7CrSq3on-rx-q-f57F-&1Yb5Jzl3luW$gXN27JSVc-0`N~#1(N_ZdV`ytKV*SGx zulXP0ejF0S{^kSj9y9d}OewKe>ks`#{l=MsLX`CDP@$7GL#`J3Vh!j>&5o5Ob1e&= z_KZL*c+*fz=f6w5`LYrlP=Y@SI`HY=bn#_)T`0pY&zH7L0Pp%rQzrPP=smgb-FPp* z7>$2l}+8r1F!m_aiAf5A&3Cf0GIm$@rB0+q!qYw@L?O*)>&`B-%yT6BhqRZ2f~4OAX`U@6;%rNH9bY=$r|D;If1~Sm%!LmI>DvT` zHOgz#PNt!peg#;p04Fa|oP8R8Pv!UMkv9hmTUri*M+(2d4-OW=1TPNyr3htDg*gW% z;d|_TUryZ)I&s>`wnWli1#QwG{r-W5Qgg_4_&GIzCZ{p)kdvmWIL)Yc(hE{+n3sgg`y=pjw;kSpSiR$0)po za|Dg^*Wv#hqcw=phnjH6>oZX0#q0FPFwF<5)9=)hs7H>4H^Z+SHgA~t38&&N#B{LR zb<*_?PTqqvVIIOdA(z0>Hvy8>@Nya61iJ{|UqHSf?Psyzi{S;56SU#X_NhqqQ=HML zUQeqrX&2a`#-yEiTbTIZdC7`+%`qA8?Bh4aV{b^bLXR^>e5R$L6+a6XYwf)$8y$Vg zNPVZ;76WYVux7iXFAcV)uogBWY(EL>V9SQ>marbS(XcI2OQy8-;f~5NpCt`kYRV69 zj!uId?p64{4gh`!xCo&2nZM4&|5U8o3;7<&#EGSC1IG0*Ua&%j zHnpEn+f+zXVOo<^i7K0=RPcYk9@4e}vvyd&muYR3G;Q3|go|Tab!|Gyj($Bfl+wmO zvj8JVl2}rog*GI}VsT>i>==4*Lff3&&#oQcHfPMKLiwK;He$w2 zR`=I>tc|{qSy*^tl2Zr1!TP|#Inr^%v+=WxJrp1LmqSedhS_AFeLfj^Oo#sj^!A>F z{{;9a!QTphnn~M2DQ)o-dCb@H;+~@770+Vabl1n_NRZqH##9VSMR7rnn;FLC@OKlm!RXa<730_=6!Odn&t%I5>;C{wuH-6>`E#%xu+v8l}1 z*%vgdSt^zKgZF&D*8O&~tr1*(Gq~zGy|J066+H0cg{=VEy(;#N?b$m=@BJM(Do%fw ztfooo6_Y&3LC5w7Z~mV6Jr+v8Q*gej{)#9Ba065xA$bVIAJ`xKO>AO~01O8>sg&)Y z5-6;}ext01%>tW7alvMWjZsWa#;W&@2RDp3j{|@=Yo0K$Z-vRt6qoqksVwqYG49{T zn1g0_u47ycC%-wk47MED_79#wD{~y9U~eBZH;;B?!S=%7vgT0^BW%wOl62UYnmHM# zIJ}XG(?2_h+w~zm?DNsTHvw(~JONn_63iO_Ho#0kGhid&5x_429{@fFTmnoa+!yXo z4}(8xoO_2<;NS=Lfv>H`z0%!|(tbQhH(9HaKVQVS?K9Jt0e`#%Z9<>)2mcxc?@14I zc(@uQrjVDjlrc49oMzzK_7yNwa-i=zqlRwOp5jPQLejy$#YpW@BB|n=<1Vim*np-E4r_*yFSr(sOKGB5tNbCiiHy6>mmZ%P5D%H9S7QIQah>9}cp1@&T8R z6OB z>K4vlSZi@FtcQ%H!VeXFK{+tAh5|u8e4)Mu^LyHdicu(ZYX(AQK;aQ3JNt-|Go6#) z3qP#nAtV(1S%^YDR763<>K+oAz5;tFxG!W!zE?x{IOTl3^Fw8N_J>ME!F9Dc@cU4i zRlv#0pv8Sn4M}%Of{$Im8l>(G4UlniL~#kz9Y+**Hf}wQo0Rd3828k9N0ik>u1kU-T6$xx6%87`Ktant!G1Y5a#B5eK8K36Q^J~j|4`ZG%Z zvr>Upe5d-F)U^D-re&WgM)>|s_03a#KU3_;@ucbld4RP^!bp=P&cu6Di8m4p2 z8Ykr@jKo@0Kz!4;F1d9H)mz^!;MIg?2rK{fJwcw=g9{vRRK=Zo;He&1(;r;?Eo7Zu zinVy~jvQUb+YO!cLc!No$y=+c`uFfzF1lkkh@!CtG)P*=!(l*q%gIlHGRg$J6H$6Z zf-ibi{4ns5z))h3;p9uvTOlKfk?n)w;Gc2w|7t4vJ~{}zWpr`pO^%zfdW^;?R32P} zTXe3ADO@<;7+C0NfPZp0cy4vxa^T^vJ*vm6Zn9i*WsO$c*?qLX4%Y(%>xtg-O069euDh zM0bYqkkXD@Nr;&o56g8-gG?<>zCSe9p}}`tTZz*RzWz0M`=a^Sg*is^kk($tB^v(# z_dftRbKw5_~1vAN&d!9~N&Tk)UG` zZymssfU*%MG*HchjxGtk_|JELG&kP<+hINcXamqUOLEAm?Qg+t?9Qme>k71ZW~}0O)kh&CH+zB&R}OhqNIr7U=6hCl_szp^YBeDUqB6c z<=m=IkSF!|w=g^2q;C!k-g$ZD)N?Pj7y@9u#Bw>6%mdWg9Nt`xYA*mO+wE z5=_CpoQpmq6S78|Rd-`t`|>Bf(35-#XDWaX_7eaR`gaQeR)7KiM!-`}u9!y0ph`9+ zTv=Qrb{ucU`psr7B*e0Q5j3r!WcTaLn<2Xod>U1IDj8YvBz6ZV220*bgGce1t4z}FN)PUWx7Ph=fJ<^Oq zKJ{`ApX9p>egqRl-#U2=f0AZ3YdFf3NUwl z1x;YkJ-GBMq-Xx9=mAD%o?|}fwULvJch&bB?6pq5SKzA@!I10X&_8Dy^#Q&t(L-g_ zL(r}6;>0f%$BUf&^Uw`WvfDdr`aQ+dT&SN8ccsuZxV1dcGR=kkCzLHh-(UwYxS<)& zdKp?_#9SB6zl|i5R6eY_QF3J|G5a!!EOc2KnS8M*pP#!5)c zu7xyrmpYT?$AbC4$+P5OL`GL$b*{`Z2DY3^8}OeG*})ftIiy58*{`QgU^1`mWEb5u ziurip-*b<#3okQ=g_o^}2lEx0ciDhEz$b`@f6UY4W-*6h7oqTJ={_(jWGV1&DZXDx|OJt{c9M=O; z>`ryCG9K5@8Jz6{JJ)@t6tMX&PuEeTI;x1XrM~S87gu?bJ&bZlG?Efg$)%braH3g-npw#65&r;)M{%3g`X8&h-ThU4*T4_WpJyVCv zBMnn%B{W49yQ#d-2LHP}BU+g^(#k8#v!Z>ZBWEGr81+d1Hugd<>{{60fPG_3J#S$} zXXRJ0PyD0?G%0|00MKuTmtd2#{?dep=$zg@(A;!X**>}cQa)-`e`)mndlrPNMD!hwjQkPZ&?=iAt}xz$KMOBfw^uL8q>{k21h!($Uf|EmJNwG6KW>Zrnqx- z(Gywjak|in(m?#Y7Ed3S?o9UVn(TPIlWM$^nOLRGswS{_%((V|;Z!tB6aFJL!`ZTf z&b`C!GOWNi0-*Ly`Ytv<)BGFfmx|};p&Imn^Eb6$D(l|{v|~-aw3R!96>2^7u^P(0 z0A2X6arR|-=uCxf_b-*jt>l6RK6h6=*|J=n&aU}g^K#r>b#|F$a!9*9LpJQKq&;4> zW2Iq06Rz5UO<^kB6r;jrQ%#%8s+v}psG6cnY^HFragpLOkgXb~xKj0725EIWNSYNe zk%w71GX^Tb!>A`CLi!+T$#Bn-whxZcyV$+76LQ!mnKtS{8Y|S!_E@b2Jk+S44fV5; z9rd#j%{tjpKO5<4BzfJ_RC5}>4{~3oJENK07OLMYvY~#nEGt#NWov288?c#k8`ogm zn3C6tHo1~9SN6{^=eq86-U(UaFAaQau2PI;t7>x_0m}im16DvvWM%FhphOsIcB(to zS}Rs@cWnkn#ExBhMeQBP{SN0H(DHT!JWeZU|5o3oZc?6`MdL9C=CToAmpXG=FegQ{ zeK_u-MBHkaw>a(4z-xyFUKS&6F9StbnOTmfpc;}p9%d{XPLDGJmD!lPQZ<+5u2RjW z+||P=bC>6?R{fSQRBVa#wzAwiRlnPTOB$m3a;m;&(%M0_j@Qbwj%qdCc@?zVnB{4i zX7zNk1a_WV0v&_cG0Q-=6q(|Lj)Fwn8T6$duZBiT`@lm@pDBl@&^Jfl)=}6&?^T}b zDnL&|SK8Wn0T%<^Ejyv3WV>i&84Y8AG`MYW&jLILcpdOQfMJq70!#tn)5&em^4z;D z-ShXMpS-c)`(wZU?fmaQ$!TQr{xS5ENsC|(N^k8yhIsQ=r+5}od;+Ak!L$Pel;^{B z^S-Z`|HXENb%tdO@Gk?@0UiS6F3YXWZ2~L@+zxzE!T>`GrbgaGSaJR3L_W@5Q zsJLqsk3S8og#|Val&bhoejE;nSkocvJr>geH_2vyiM1N%JMb?tVmf3K=YgkzeT@U< z+TJMJrjyq>TNi2I9# zT?_j@*jdEaQy$O@$H~Q@ABhF~f$;->kopT+BiK)?zh5Wp6sH3?M7+JmmV;V}un%U? zQ;}qTpX&dS`ulE-d=BDG>toOi>hDXSe*#~fn#Y@Jx@Xnj z=VA@GUtI(qa&sc>&(-+b6Y;4Q+f|>9YMEQq_@5*Gszm%p)zJ0o@7Hg&^hYwtjp3?s_`eOzcw}1 zqewL-k!qS6zd-#Rr=|jR3|hykKAGz8DD`*374|rOa1r{BoEM-%B^RO6&N1cXcq z>A{1@!G`;PAQ|uG;Ht)Z(gC%;jQ1PNVZmu)iU8Gs<$z6q7XW&vu{+nTuPf;xd=SkY z(Io^lP7P$!vN97A-Nr*Xz-wd!jDSN(6QAp#dtFPj9j83JAX|opXFCJE1>Ant%oJov z2%i_HsK^=u&l7lxHCQ7~f>IQcU|{np!}KKoLcU3Lr1OB=kC!UE_`ldfsaep14G_On zBJHn7(sqrcH6h(K0JUDC`VFR%%*WG6ht~zpi8nR|{Jq4l`eQ|iu+Yjy=a%U$arw90 zn;WpMFa@|-&0}`q`&Uv->1M$~-wEvXCY|6*w;N zX%2$dt3>M;vF^~9-80zi_+6kIx6Q@Ayf3;3zS{6(U-B0pPjdOX2cF)r#3xPqi9g+> z2VGbNZk3N)p0BJ$$dnD$xQQ0QRqxk}DW+oN@bul2eFo(4zy=$_>Z+cvEJn=64c8-v z&Xj`~Z{3~i)8dYsz3}vN#L2B`b2|EwZyfaAjGR zBPCuG$xfU=i&;vOw$QYpElFt`3Z+oGU_;tcpiT?4wB_E~EcentTLA@ALO}@$mhD9P zea}3PWZ6kr-uwIGeLtV;98;6v`ok*dlt8|?1ivraJ!PbU%~COOyoX?+ZEZ=4->gPj@N?%cG9pTx?jMF zQn!iPD2>}MozF5Qnq?*IC<}Zmyaq2&;(ds~*TZxpF&o;1wqpm}0+821Mg)^IXf?+b zpb=gYK{_wvbgSBw!1MJNZWr_TM{XDM_%!Sbk^U^mXEo&*W1qwXcf9<}mXZ}n?K6Ctb+Siw-ecgI~ zE^d3Ga5ccZ@w`U*s>4?=;uQTF@YTh04NXhX#>MS)ayLBI%I$KTxTF(lcyR(V1jFl$ z4%(GDn%&U+l%MPL&wXX3zD^8RN^ zN6g2ON@7T6N`w99T&_C{a&?MR&f|=vFgc0ygbz_05Pe6W?Q#dsV$MRi!-zwV^V%$M zXNU>(LI@jLj!-G19x0P)){XKW6pdtcr#9@R-3RUXpjY-59$UU%1S^kETKfq*}>cM zOpk0}dH)_s9mvJ1F?c)axdw5@xfbc;Z7X1|2*uUJ*J@o^Sox9%#F4qUX#bP$}-H6ycq2}^I!>xq zBe!bEyQp1I%R0dGYY8V&xeamoZ;s5e+&?JOmSD|Kt6!G$%TX;}xT!xoup6UEz;oe# z$d-wU?vBvSUeHyXgEN8aq#9f^Qp{^`^#}{xAEp|_Z3E$3O~t6enKicD z{2Xd*S+vFq&A&s96_}qzjcIs|q1<8Dz+bZRK!JGhgMSXueMJAUJ5kG^m6|B5MD2}? zs8D-Feubd(D}`nLn-UgTu2F7y_u0Mc4GTGK7Cb?x!{SEhPNEl4b8kQfpANo8_T%Jg z(v4G^Rt;PM`u~*I_KW9RGH3a5DnKXG(por9l7HZ?8QjJz%7uxpGijQ)Nu+6nmT!F^ zTtrLzG+JHIMe?Lsj#28H=bzwfSCY#~G7T=HBl~d+<|OX=Sd?PQqEznk zgL8L#MVqonZ2fB`pUPlO4TXNNu9#!~s5YOQ58#~>a^F^5fA*G2G2Z&KhoZLriuv4M z%Ev|aZ=*MS8`L|ATmN+f-vssUMXi;dPtJ++=W%Qu{{{b^EvEP-tl25WwF6qymw~@R zpNiMNGtalYaR4t%i>cKVE2T2tW|nd6TdU^?3EcJ~WL{!!ZmPc;Qfu80a!n6w)^NX5 z2D(3zq!^R}6BJmR)t~+SZmbDIilbE@{V*HnS4OUG8~md=D{KfFaQ=J?+Ryo{`ZJmGrEUt{gFC=1zsjdr^Cu6yvNTiC?3KM<;eew@#!y@pLscJ15&tc(gfOV*Dpd3_`>9s zIlq0q{LJUGicFQ}D?rWO$qM+^>%rp&x+fofJpu8(fcTyX=`9HoWfO{3lI?mf(2E=zuBla!sUbaV{{h<^?)IOssYCSkHJunSV+G$oa05mk+3uyL0?_Q0dt5C%FBixOj4|AgYZvci9l zP!5KH^Wuee^A4WcTwX&?#GQ_IK{d25$owbzLPt%0T zUuO|#uLM8!)y?qzyna6F&NT65|Hd=dZK*%|2M^tLaO48+u15NQK>A<3AU`@-DH~Be zUOoWX^x4+kW^+E$E|^Hq>Gs#3{iBEO1?cCag#l&Qfif(d$jGt#%cG-NQkgV{mDQj9 z)9$%Ezpk=fdeN3Cjclos*-)m+5`C0KVaax^Xin4(x?xhtq%yI6FRsoh6GPlnRDPyI zNMobU6UN(i5#vcIt~|+Xv=dcvE|TlBQCm#LX(%1qvwCwDdjjpQ z2`05eYR_MRy##(EFtfK{PZ#h6;5qn>hr>64ug^)ut0^pS2&?44dE6*AK%CXVaoO6B zM&y1K?6+b!oOnX&KdUge2M}IB`&V0V#>wRyNZhD4r{EOet+)eyTc)OEzQ?lxbC`>y zfLL1w)*)=cF%8QBWMbW%2Qx8`v_KO7s?It+w(SF)A;9{a?BDw!31{zgj8+XN2C=pr zBD~a~Y>j0=ja#vjvHo~EjPE4c^Efj~5*geOFd$o9f_DYjNY;Rm2#s4MP9TL73+}?n zJ{?n@UKx$=heP81VsWOW^>lOJ66me4{N=-I@M|1dT)Vg?&$7g&b)`Y_{@{thQ?f*8 z9%Zw0NrK``kAZ#EQ=Z>KGVkn`xZyN@O4T}<@3I)PTQX|0T^Wz2o3Vlk3ohukhSOj_ z7REW%RlO=RJX+WHI{^p&{3*LX-R_QIS%s{TY8lg4!^5Uby}Y2$lErY{7PkB#<2XAT-dkx&3T!_+w!a&RdRopCHD)i+y(sXZ@9oz=BH3ftid1d>&P!2In~#fuN(O= zzCMs3GY%-Z?8L@%5CX;kPV+jm3HjtXc~M?$g{wWcqR?&?$LCk*{OliJzWLTdbe zHMGw31%ChDoX6siD<7iUw`9F4pXU=1gO+tJ7eZKQXE}$Xa>t))+>ZfrJ z18FQO&ZTB6KB9V$!ya8mE|J`9FbR)U^%0wrWDE?Q` zPQDEQpKg$w9zES}qZ^%6BZf2uTm|42aH|`p74yFFLdor6xK#`X* za4Q_v!fpF_mgIKFxbWyAxLC&*NG`XHYaY#jOZ7PPfq33-7=LAeR?p?*S4uA4aq~c` zS!+r~sa4@r^UtzUL5-au%~L9~=BYS9JRlJ;2Y~(6MOfpY>^_*JAAJK%(v`jjZVj-L z{`3aeYXKbq4}j=Jy4A#w$Acr62?wz{USK*s)`0ge8u0R>Oq+}JpAF?=?)uX19OPgL zUL7R)?}f3GSV5Z~7t9NQ@mMGm7+>9;35>K5_7smD1y?G|PaN^N_Pf%|snypRAlJqX zRbPg?4=>~HcU@;l`pzBiB*-5~d%|6Hn#C7EUwIAEP6*3%i6cqoc*J`k6o+|u$=o=^ z`yMpv#QEkssPot|+<>xt4e$g&hcRO%+HG*GgP#C2`*SS|`dHyOWW3+Td7yK{+G;Jv z#O)zS;-Hmw?Kt6XfquT{iHzz6@Trr0YPe7J1(hj?x}kcg2xVd3XRTMDroK++cpRx_ zrlnhw=EC>-aNfXN)R-Ffg3xbA@d7Mti?LS_=TC-?D$ax9dr=5l_c)ubM?R?xBY*%P z^IDuke_zAvstESa0S*G>CfuyI<|~zoVU`~pp>y>bfH;51`xGXbPFOlIoVYYNT!^>5 z@tv#i=i_Z}1vJ-Z)qidwB)0)|;*~+!qWPFp>C|@GA|b$ai-yP zmZ$pLIm9C?&dV4ZMtGb8zz&oo7dH1ZO&mtAyDLxNUJATAjuR6%Po1kDB7cSD?#iP> z$=TZs;DB_V4Jm5|QdS*LfNO%~TSLj9Lb$|eSl|-hIDQ2>-Q&X~qai#B&u@7HcJeFr zXXPH!3T-j4Go!lGV;fHy&OC?vEtE?Bf>Vjg5{c!w6w4iI6{9$=w5-IaljZ_`7CUEY zh)3vxQ}Z^;4#|$BxQZv5~SU5zTI=a5!SQ;R~I;W`OUf@EiF!AqcS`Mg7Rl8b!>Bakc$_h<(ciDP4HCuLdr z=CQE?m`h=nOfpDA#>R5+eYN@Onz6C$$*XH+S^o$gJEn!ZFqsV=~|D8qoW%v`2ac#@CafIdzMTgE-^yWaXUUpAMMeHXM4eGU=6K#Pn+XxtB?YA;YD_ z*zoUBdhsQAJGFZppM!ai&*mp$E6?_O=lCJJ4=Y?5 zI6bHqU7?|(^n=sJnOUyO(x2Xsn?OA@C(UNU+=>F#V7no_?b<5-p3$Kx7$Tplk zu|skCVB-e7`lC1}^FAF+us$73YP~P0^rjqm6?!)JxfdFfEf3glMa&w%B0v6bGS?Lg zlxya;;MU6gk4D}fmG#Ni$Vyc~S>{Kh_u?fSv0av<+?3}ufB62`k;$$jD zUtu!AA3x%7KVYXEw(}g$@h^2Jo<7*(a3|~fxM28~8Pc*3kP(2ba&T_I* zjwdIywb>R0cGy~aUFKrwOP&B6BAsVC#d&6QscRlyu$p`Fyi}@yDQTw zwk5_{hQ8sN=Z17r!0Jc%7w3oDkVk5-amb$xuovHy_d8)?MKU)P;K8We@1EV4kr)tg(=&8yz)WZevxLRdm{$U-{)Rn{GpxZ9U6}gJaRL5pBO7xy%9Fu#3$A}f?*tpY@*)NW2GTdr+?q=1C^8E6^tXsn1o#WrI*SA{A zTtx%vuDPGD4;-}4^)PK2MxHGjUvVpo=0Q94)xmghFml-D9e4rfW#7MfOO4ib*p7A^ z%5^1ZRk(d>30kpmK7W5ophZz0*m83{a`Wr)99OIBrJ&}R`tcfb#p^X@y2tS6;})DN z!YSVIjb=N{AB|U=?FX^vFm5*A3-kNq8_ci6{LXmxe%VpPH>*5w_04n>vSUBp<|oh6 zx2SRZy8PyUyps}`1tuW!Zz1gG02Az9JMob+9r2Rd{qt~37w+&{S{_i|e4kzRx{ULf zFZmq@1^3$r=c`{GWO*zA^%Z}psC@|XyC#eWKSaCw1z;HP7GMmJxE<>cKm*$0GMJHZkNVA8 zd|Lr)VW)OV{b>ijzX13q;9kl3pOhax>}m|=>u@`4{*A*Vk5wE^aUHEPoXivy zN7$tL!;P;0PU{{X*~XT1;C@nyh3-$-=YqV#q~c#YLyz+>CI51S#$)`h53P1jVQvl~ zg`^wY_f%<4K7m(3@hsMo3dEX#km3tnM*cz<-A#9Dl(f}3CS6_V|R&!>CNjDF92gups!a zgL`VpmKNND-z$R4`tUNYhel1qd7tH@L2)*P_FlgS9NRKaw!a*GdaS?892yISJMlXi z{=naX5hKI(irZmX*tfuQ&w-By?;jkEPkxzXujP6Fjr-lrN}Tam+8_mO#wdaDy9Ksw33m-|d&>SZlAXYw{lJFMDAaS|LEnvk51st z0GM!!)8FFKfyFSo<|7sF6akBrz!0~|6s0%1!PQ&ClUu%g=mxa^w(LQ8?38c z*q7!>aeXw1IYMC^v6z*Z7ma~KN@ag_O`hw-hks#0|6Q&P8y`E@f77u+P5;v2*{=x& z+F{je2?d$Mnu6{TnRcPSydYz^zra1B)Ta3#!@Z0d!||`dyy=QzgzIj`$%`bomv_&l zZ`G9M3b5zjp3ypmaC+JA}v8Io1 zTA~={AqL#!5iFMCEcWF0DFS2DQmhKjLfG;P{B=#b=L~1fAy%Hd6VL(Z1PF1$+ykKJ zbAYpegyZ#R&7LbbHO10Sm36A5)dljvd6csnrN-GB&;{}mXgkjiqDP}1J^-DlewM+! z4(59Kb)JN$D1Ay-3t6n$1D(OXEKo8wm28w@64c7%wR?icA`kpUiVf#Kc&thut32>D zVkP?i8X+*=Al;j!5R`rhucstgpg(~0p-+$Rp>TGeOc3jX>OM5~3r-WF2hoMj;yVDV zI1ScCOL90^hf_t9@>^jZ4sL=y1p6k~YbEzu0jK6LKFyNN^=yLqv}}_{^sNGBt&kE_ zfJ)R(6rh*_dgdB#4~_MPb1k!x$4k?U1sL9{S%6w>K0jN)`Lp*7@}!s3Ycg=cJ~Y;N zKD&=@bo&R&Pu~`f^Y(k1vn`9#hEr=&IaWEa;?Zip2CUpZwEg$~J$Pak_H8C?Wc7AM;zW+Nj9a&#|;zLt*)76NgK+9mWR5AbjixkWLAd8v?1l`OvP>Q zv@qOIZ?DHa4-Tx1nlN{rcu2!;ykEn-Xm`vjp3Tg}IfZ_Ew?&cLO)qb#yXxt-)l8gv z=&Jiiuw;;IbOs``B`}tZyV3gXyO6)77j{<9%id|O^~i$qHMCdds@7(^%yK=x*UEyj z>#?66c2<{UJEytr54Tn?%Wj?K<_X)XTeyqtdW8N-cx*?w+0wi*%hX((-h$Vhwcu4Q zY_}}4>r5ZmvrM~MlC;-CVw7~KV9&$2tyMVm#bC~{(AWbwhrM|tBwtBcCY`AC{6r6obzPzQ;%CN%a9yj4IazcaO;!`UNtC^UBP!bZzRq_@pf+(Ng!4%!p6 zzYnIKFx4^eJo_&Yt`0ZOGTb(+Yzd9w2EFgl+k=_f#Ny(X^%meB^0ln9JPP;_P;7_Y zj<$MXZOb3Ts#<47lH8i&ILfQOmNJ$R&edE9>dq&*O z)^}SK-~$uF54O_lQOa;$YeGp{fo!_VdjOOdD*LMAGHrr| z&=0jfqUJpZY$(Riq|w4>E0Qi=U?nT%3lOm zn^zkHV_(N>3<~3YcHKa6C(Hlm2<-`+oA5)HLUN+lc)6&)sca3X&-XY@m=MAXGP7!x zrhJ!U0DLrd%0pvcI{yfCrqBH~4%{J)dIOKE5F5koZ~x}{j}*^tDGtO9y{{m2FE#ZC zF^>J(^jPJUC)ch_keknYT!C9G(joEpY^#=22~XiIn5PujB6t#E9|WEM1K>Gst+4{*RM3jsW^jl!xXH2!X9q%KZv-18 z+uvYo;BK!3>m}QZL0ZoZ2eVyuHQ6nY@;kf*P4)!X=ew>!Ob-Wjmi6Xq_<62+oXSeD(mYMR;Q!&b5He{> z=Z0_`bi^JUC`FjB2W5roVaTrvXN@Sbi*Sd`97qH7FlYJY**ci<{^e$sUs0$SQX+Jr zc^N|O32I$e2jUgVrRf_JhKM6cLA=djd7f-!F|fm9TX8lcX(-p63v6337cVfV)_!8{*0DcAgA7PrY#``are+9e-@B{t@2mod|a8?*_0=N}0_qBm*qfQc_uu;A2jL0wm$74SlKBkMyB%rK9^^wXX)hR?r*AUN&3>l)-CG*u zp$2(KV(eXZ;@IoT@cXs+<`7q3;H&w6~0H;86&sz$%>2;azm;zx{Xp`^C zSi|dqaJWpy;@;FCJ%)72#B0~GVt?-+uLKU2b1lNJMgICVhu@MTj(Eg*8_G=aDwy?k z#Fb8E`aQ}+aZujV;Mc+qzlDv$QTk>A=B%8KHR|=Z%{h*;uogj+030K5K(99zhL^ui zZu40K%6IH_N*D2dIR`jQe|VGukH?F29vBNxq{2)G-R^^(F+Wf9Jm!ce5cfYQe*E=q zIAOZ)$?&_!)D0j5V`2RDZ7G?TWpI8e*@C;%HwtWbwZNW&>4SMI;HR+5>IAk4psEqr z%`mHBS^&FY|KfgueHZYr8-RDCfLOC}jy(sE3%Gjj_R5Z3M(3Vo4neQe3(X$8x5wS% z?(Py=JGvda1fP4qQ_%J0_6Y^89lLyGWL2|I2;}tIea@JmYUXfz9j(3X%Nz{9Le@H= zZgWiyYp_<;)K?g*tgN=u$~ITl*EcakeVwU#12a_^n(D3BGIFb~-N39>hWag4aInI` z)W|kBB9s~#cRQRyMT0?T>+ZC>y99TayGQUjdwM-(YBg(f@6jR6T%X|ULBRw^XPe-% zceVLk_FYb)$KC1d?(Grsa@#t6OHiuKjg`ilW3fy&(0y|=5Q z+ukO|*XFf%@)DNiwh0Jo#J8=ox4qrzJ@(cPr-X}QRMl2Dd+l9Pz1w?xx`j4pkJHg3 z`H3F_p`b)Ohfc4z+nbdI0-*>Fo5SAWZbcEIQAv1ZycMZgVxo0hqH$BB;Bk6ek)<|g zhkc*m>u&GaYX`M>aIc-WKsD1Z(-ju$1&+5{LfvEU=yj?Y+-?-;PbUa^K`0W0VnHYo zgi=9RAqXo4VU-}PR}Rba#EB)84nl;q2-`RjBu^(-p3y5*arM-R*)CRkBam;qC7AsF}OVgZ9XSmw`q) zVIA@Vi(XhqEeN)vh*L3l;&dQ#>JmAXI7N5>vQaAZ$HS2&#-SL^u?-Kz=eB(zw`~bo zKf|Y*6{G0W%GqJ}p^-#tK*{bE?)xey|`XhvHTyLthdU2UY-&%hGw?bH{%&Q7}rA$Y#f{JhQ` zVgLbsClVBnZXaRW9S$ctSi9ZbfzifTTTSfuZshLMVildHqiz!_QC+!hWypz8h|&|$8@X*6jY~FP zZ>LzTd{Ea3j&8dbQ#0IrY9_h0ySpMT(Lq~?8T!lCt!wMGckn@f-8yL^z+g>;E8}rY zNA|%Ta|-zoI>*poB4xc0n{sVcZ8PTnin83k0!MdOyB-!)D$#A)q|k$z+eh_mXxJ<` z_BlG7K6Nt7tt`8dQB&3PUme?4Xzz3TFu9_f*T&ch2eSm9C-_Xk=L$YsV7?%a3i_#} z9|Qdu>8FZ*Oln5Pr<)uu#!^ER(PL`^W%$HUMmclXySlo2hz@PSG+&gwri$rxOs{A9 zVx}))`ci3v?XedL&Mum^BU3K9v~_pkdwWrHq@^`(sM~6&Ytj)tXSnGLh_vRdXpfDy z4O?x7`ptDsRaT+P>1-1)y=jg_yO-+nA z03wh0hml95sUDNDP(&0j#`q(YkVgroW}%ckR*=U^@>oS4tH@(DJoGwv==Jc>7wIDL zUQE*enG41;v(##G+n51^sT%{RAn`Lak=sy0smJg^KqOX$wXwl(3aWY?Y3!TE$kc zK(j-0(-$$&p6ORI{VJwk&5HD_sE8F6v!YT~w2~FAVnwT2v5pn%S#{51pFr){-qF#$ zms*gcyR(%t*0Z-;=-KCS@(D}W>vDE+FEEvEpTi5rQuK&4XJ@AyoMR(r)vZTziinuYV>u9(wfUS$$)NCuF>h4+$-oMx5=?1Ic;c09079(4G(J=YACV1Rk zo#K2!^A@qX5hogO+&jdok9ZkShM5`d?!sUnNg<{<9hjkf0`adPf#9=uN(G~`FO!nG zRD9F3+}`aKJPyisBuu9R>knEPboF*(p-~Va+cZa!dT6M~uMHSLOjfh@y@I<9({dL+ z)r^yi&ryPu9nrtjj#tz9lCL0X7N@_iPp{MIO7KI&eX`_Q z(|{x}rcG-kw6a6F#Bdy=_~S69la>=l8oZ*B7@h6*-i{ugdn_4w@49%xA$|kIiRA6m z1)|P76{yx)DlMGR!fjGgzU}VjWwrIjDx0-xgRPXt>6yONeE2ko8J;%-noDi8>f)}P z6x+AZ5ZtWmE7Dhqy#m%E9k(W{C6rEQCooD&OC;x5Di%fQArdwEDGv3~&)%+G=uBN= zj}>!9?QFZj<#g<7zNn5RhDfX~XKk%vd0j=FQK&Z3Y|)1q=+pm?W+75ZVwLa|qJFi; z8bNGbd^(D{OEeY!f69W?G^v>g1}-6?$xpDD_ZJ9YVH#>`1gcY>2O*jXY1XvzApr120R_01z}pase}os9PEbxCtyE;cusJ85-W%BO(#nN zAe>AIKpb=6J|_X70x<{$kp`HZPG^rD^Hn!3 zD7H7%*NeiRwVNxfP3r|3)G=X!*=loQj`lhoPB%t8vHP_l1R|V)>g(lelxco@?O2BR z_H{Y9ya|n^(^t5jeq$rxkz*m(CbZdmAaKgdC4tmb0#iaOBC;5N8A++4*^-1=;C7up zR@cp%YU?R{Lv6Kz&&_RAVn+`T;~?%)j07St6tK55Mi}N>QgE@5ESjMzAVa=K%u61h zsl|N8I#+eIEg{aEmsJ#d%}ge?1QMO21>mJ_tXz+YpL55O%!#T=D*1G3aypd>?j2pk zi=s2q64oc|uzOn};o=14C`2vJ8jvK9_%5jmC~r~s2py0?xlAUH{3RtNBqhz6!$Ah^ zQTT9R%-zQzMrSVs$WW{tXNCPtrd88dT=$3cB{!zhm+Xgrj@he&ZVv?2Eo3MTe~DH7 zgvlz6kuU9kG5Ku==u7s}366;r(!>;C$a6PEQjor`Ji$}I7o|X$NI?$+DZro;WM|cY27o|rj;EPfq zOr+2P15|=RDf~iALHa^^L?wJt3N1{okSh?eoGDfGPo-2S6hv{59+-2LDXLU$mLO;~ zi|~!Vl(YpYDQUAg5Ej)CuO$j5K@}Ijb@uGC?eetQc6i*~G!ti`ec~HKLTm31FsB{8 zol&No81qX)Y!ELvUWtjnBre4v;){Y3n!5@FJGeX&aDey0`i3&V8K+q1GI1yn7dDQ`zO*M@SwoBr7!bgFMpc$i3QoyToORr_=4Qi5=1A>h5$>xZ0)_rQ5bmPmm_V z&lXEGX^Ik^H#RpBkvru@WUr&x+be5~R)}q?8^LU1S-?bFU6rAU)musW17Qw0Iss%pWL>bV6U+xT7t?MJXCLxqWe zRT#HaMUktv7)2cHSJblFYpwMh$5heS#FN6jQrXmqP#D-EOq4X4Kyb4-*S8px4=)a3 z(061|r%8sAG1XfuqkbR|sSjKZ4-@)V2+mCqSNuYEZ+2wlHW#CN?8DtR>re z&IgJZ+Z&}7Q=@S?F-grrWv{!VO=!aI2#w+pbL;dgb$WeCAq-v73Q7_~GuB#MZqeF} zm0ug*h@nLTR_o+KJ0)meWC*<+rJx7Q2Q_dK;z95&x}r2(dWSe0A%}z;O`DPKan zx4VHCw%yu< z7UJ!32-wf_?Gt$#Y@%h+pPFHv2O2qd_d2^AQ=X^|9*kCjQC}OFFDC{;zURT)V}XE8 zklr5bc|-zK)i)Y!#4nc#P4x{ng9V*kFST9d!B*sRI&37Twm}YP_r?a}VgnMlNaG^} zkqFT4_WF8k)E;fLo)jI?8EIo|pRFC@3mUy_gu0@*sF?P#A_ca!wt9MPeAu)>a3cxa zxUZ)p;@;jaM#(egb@GH9v_Rt7;Uy#5RX5ZNK38uK4RExG<(qI^iYkVQ6a=wDZf4=D zY}(c2OVqvI?yeon1aUs&1>!w!d88Q2NU+WGMLCv=Ux2>Q6(xn}&C7zJHL`n)Q@cJNOAHVO?P~^Qu+W7|ZrgJH z9~KBv@E>e>FNrS1N+((sa-v=iv9StMaXrJj7pEVL44($m25enhjTM+^@VVJqMMh&& zMN_qb@EWgeq}^^BykdrQk|&{`su@V$G{X}FhqO!Ftmj=8`I{D+Z_-}Uhc@)ZzCJTd zdxw3;WxTp5Gl-7%vl}-X3{{Pdm>{cbs*G%VtJB^EnHn-wxSr<=DdbVoON3SoGKK3Y z#r=|th(^CQcN-Tsx!Sy{%oQC~XXXg@u(8WTC zQ;yFASvIj{mdfQmV!^~k0ojP_=dqIt0$RMA^M%AA5v3%*{Z23B;8;fxKSHdTOYT$YK?ZmUL>&-Cy7OwH zj8sZNw~M4N6pdzq*9qt#wmaVvv;~H>yqYv9nrS_Sxj}Hyh#@k$s|ut|50sV?`2;j^ zdyq;VL5?uS`ie`$bdl%f!>_3NnD9~0%ZD#2`k3%h&&!9`L(*BKTdfoFNXDSYN?Y6v zx>QjwjXEuEv;(3xU(aJAMQt_Im};9j=NIdN9l^T#It(*)#tJKV6?27k12%ln=4ZNr z;E1#lO&D_FR=Z;tbu@~q7J}ZHwXp(PC6~>A)N@*ndDTZMY{jM8#YLVU6aM2`!-|M! zZ20Y-4to#!dZ%pl|8!d>jqfZoRW>&`YC$;-Cun)#%F#tsri9Q9F0A{9261{=vv$y+ zhmEOjIHB)T=6rldW-0`DDmSLn{h|U7BIpLs(Al$cMG+U)b3Ug7?2EYKL+O3{ZKiilQvrI^^YI*R|LkM>SNF%35`i0Tt~NS5OhhhOO3$hD$hO zi9gNN;c|Pn=k`f6AozH%-L|8nyVc$Srq9;q=yddS*wAo##LZfok;Q=>Gmyu%&(>=9 zIc>VWm8&~^MVH1S)h^w~&@=q)ut%E7WOZqm4BX$k*NB zl=u~CX@LyI_=!9T_Y(4WXBIm+rb{3~A|b7H+abA?wvTzQh?%X+prFG=leC=X0%77e zqDvu?Lu0Xw<+R)9Di91cmZBAgikfQlWRZSYl6X33k%7evty{_jbA{2^SVY?m(z3u; zM!S5po3;WF4JkU6V&y)=2`$udk<;pFP7V@-Opl8@>8HgdVoj;KAVqT0=`V^4Ghb|q z91E%emoKEWspP=Ai)aN*Fm$f{)URjKLqf$!^=VPTH_kw5?TUr=!`7=q~ z>KmJkQeAB4vM?G7Q5C4RcDn;RpjPJ&>VfM7?z`6uB}+o#GCaP&N>dC8(a_+q)%<@H z6d6J96t$sjeBS*G>0T`9FqGfu_RU*TXh3%>-|2nLF zX0i`a48v3mmk1x@t6NrjiTI0<{$=B?BwxYcvU_)sLWCK;BARXm57`49U&v$lq!#hs zjwa%uFitO@&Lwds_A#1;4J5)s_Z70TXo*08qIx=bZAMqcsANbPd|-nv@@XKc)|9)+ zV78L{^`Za~4+-Ce3Gdh{EThZzoBizre$F!0b7!vI(4aCrr+@Sv~+3x+P}TvJ?A zUt&yX-=gldh|C*2iBb5N)hwXU(ooq*i&hMhGybGL5*viJuMFnu2FxgJq-Z2I((1Y< zTP;MtP+h7c(g|EVL{e{Zm54brc`n?rK*}r%sb_kl-xHq;Rw$CnObqHMlzy``P0aK+ zf_gJbM4uorjR%|vHc(Tf0a$gK-Jv@{I@<*_L6EX9O%66tm`k;s=wtKn1gL$1OERLyh%Qgo{LB+iHU5+h+-2t=e=s^cln?LVa2?PA{OB4-RM{ zc7AXnA~m>Ny3$tWCsoz-G{i=-*Y5BY@d={<`cW7G#DQLviC(hGq{PZ9H*c`j*FogK zmG&-)8l^|OuMXTeQ>bwq34S zbBs2pH0#c6^u%*TddGBevV*;stNt%#c{5emOk zaY*>o)u79RgCgBfxZG|fZlMW0Itg%mz5=d=MI!=ld!H==UMrCZ3NDV|l2n+U9}`t< zPp3zZl*ufbmV-|l0VoRvtB(mPQqbt#!|7|Q22C2>jUq{SDK109%Vz+C9yS9Yc`D#T zQFPm&NZ_JuVY|Mxd7YlG`k~W7{rVHL7h7S`=*5QenX}jC?*2?oY`YQr)Lh9fwuNxg zASxU5Q!tzL6$qr_f`dhkP0=zHKqyFhlBITg=~UypJmDy3e1A-=6H&J5z^qFx01NF) zw&m&3(Fnn(B!}CBaY$sT_!L%N(eRmy{V_37wO+0~GlLP~`26^p5|6EKu_PGc&^s?r zolj~iTQ&~wJ`dOXc2Got_Q&l?W2X?id7L^Tvbgw(#K8sPl~#U2 z5c9mWCl`^#Q!t?pi-ZbuNnI=J`Hu)05Vh<%vDn&cyVKZ@B7DW-q%!D@)&y|fs4e)H%s^yD@JFKJ0ipv_dKQ* zg`@KQ6KZKOxL_?Z7EXX|XT^5juf<=Lm8mT7rp4J}AaO%La*pUVN991Qoq)4x7`X6Vrjj*26^% zlxsdRQU)>qQ!b!wsAgD$lnGKW&X}OIa5FZGi&^&$m(WO?Thp9Py%5Pt&R82+c_cVD zy15ptbkv~{dv$22m@77I#!M08v!!x#qqq=>actb&*ico6MPD=mthPwOCdOq->n6sL z4y?u^HP++k4A0W`ss;$r8>{M?u(+?Onc>>BSxk?kqE(7(cq?fW(B_sp3)Lgsc%wjO z;d<=E;p{J*Il3s`!-88v7R0~SPRXT-P9e}#897ZNv`RkHUH5LG2WwceOw)v=fm6Q+12C4CJfhi;iEVW1=Dau$+^@zX!JqbgYeji^Tm8D zl7_C>0ZEc{#*RamMir@m#u^y_FBj)0kc$-2aVXm6!44y>z37$!l4U^lI2AJ5rKGZ8 zu&Jmd;Q-%2mPW(|lG)ZkdV&F?hc?U5!)N%HT+YA2+ucE(X1S@!SS{|3MYdA0$p!^+ zw3pbpxaV>(0?_uNWApB=C>pw=VBU&;fD^2I<)s(TTJWq#eK^~Ky(M55>1;Hv(hd`G z7t`@X-sDptPLFVlwaK={T7?S&pcZ;@tfb^LBj!tlsCBlv?M=>I*sxkr+SfNFwWHxi zh;(YItSMPm#MMYLRNlErDjpqR3>Xo6yKuUWv%XXQ;?yf%Q~+h3Zo$3>>;We&hIlO7 z#cLSaJ9>Sth~NfCy|6okV`0)P0~?o^CGk1#w(r%f7MAtxE29FM5 z3r3QvSvPFPXu3m)9LrWSa-riM5J%&WYLQ%Os_Hg0naM5Uf{{f;iMsG^zonu^Y_Jrn zaVwO6Ai@+~E>0C%^*m*sMwzg~2KleeM@O{z2`}&ryKH;gaLfu!jBx;tAMZK zu#o3UjSV$oVJJ1$fVQV**IWbjq8gz=sITLeYtZ&_xR7>Mr#9QL*CtU9ec;j_R6C@V z!WqUMuX_jN?WiH*zeMWf`pQU88F)5h6$z~jO*MH?5u#n4T{gSd;SvQhf*q=wkUfjy zQshRgW?JH*4Ui5TIvQP%^k#{dsB9L{Vn^g6NQyg2R2{dENGu%*oUnZN zf?0$Nti3y;_k=Y#xgifE*O&A$Maod!l8i>=v?ZZGazQthka8a#V2msQuoS@=BOEry z%E17QAsm_nw?y%Yf=tfOP@9JyF3yzgzjzxY9m=VZcz`}V9tw!RNF3tVrGJ0$A>4l~{`=*IuNd(qyYKd% zz;Cs84#<>u47IqGipspUmk%6Z>;V2Ev9!dItv`N5Or}5LPUfdcm+*Ekz>mOKS~<)X z#_orKzjAsDNBo-}6Y1a5-*uPqkI<6d*%ALDF4Mo-qW;t4k6`cm1b=$JNBR?MQu>I5 zr+0lm&i}S4|MCbTnUV1H-jDRxPj?nYJ|g~+?^ttMMq)kw*Z#j0_+JYAzeNF=T#=Bd zo~2a9#WUEGl4s9Jo1dPMdc~DjY39yL$y~5-5xJ8;;gLVNlRx1_{OP{9jy&A|xhp!J zurF2%Y}_nxdi3L$#+QFB&0?Pi-XCC|1&jeE03Nvc0Pn%R2j)J&jR5+ixC!s~fIkAB z2mA%_0^nu9D}Yx4e+Rq{_$Oc#a0>7NAQH!Yi09w<-ivrYYd$FL4*?$m#sLAqc|aH- z&lmHhf~j1M`}$zc0?Y=?1*8J#Z$EIK+%-j?(>1t}4{oeu%B>b|o0|ke?}uh?^zYM* zxyvXTX?{Iy+-Ag=?AF_rfsvxPV=`sJ&^3;7MP+u|rkV4rMn%U>`s3Nvd^*)c6a5Sp z8GD+^@#>0#|I(#|VRj9|Q=NCm#N&yv?~bv1W9+^ddryqLH^#mv#=bYk-WOxv7h`wF z*muU*cg5H{V(gtU_O2NF<{0~y82i>3`?eVSwK4YVV(jBFc3dhL{hN&17&{+hzW_Tb zi9;yHohIyvJGV%F#M(vvjz+{yC`m=aVsOXjVLavVKY=E&!eUpeIgexfP* zAsCZms8A-NKIw3?N|nPjvP8KF$DkD_(6|KLb*Tfa0+a)c05hNk!0duX2}l4403Dzl zU<7yo5DIAe05<~q0k;7t69-_P06YVD4)8p{zM{3*QL<{KZI8aZq^P95q`kBRf2E}> zO500|VQa&`;_@tnXXRP4m|xN5Vs{Zo^8Fo7;^8uA{NgqYeQ8l?NpW$kRgAY-U#z2l zMfT$2Vx5#sBxmK2j96@y;?0#1;+X1@*Hsih{-QDwEbn@DkREWCM{lExRF>gJ91-WT zzgzVB71{&F;zP_MrcqrN?T*tq|4T>lf8*My0OY3{_|1RTrrrBQTeWQGrvKi5WMS&E zHFp{R`QyJU;&wmoSd#yf_;y)HllzkkAN};Lo1Xh-#{lN<>(!`!Z_asP|IT*? zZd>{9(qAs0mwD&Y_nsS21+u?+@2Ka`k1y)_v+;@5U&-=a`Qw*Um+t(-$OAWM9^I^X zu1HmT=fgkv`Ci-BLo4rkd;G4ic@CfcPT-ECnt3nm)_m`5Fn&kE+iO4fYR0<{RNNPS zdgY(??=O7l$>Tqo``n+BZ)q=lF#FL59ts5x^xdEN?3Qg4=U?mn)$hNTH)3zv_qm37 zKhx!Y`>uzc`PIYeSr7mAjaTyLyC-wfe?C9hcmSuEqbc!zg9gtv1iudFBHx> zxas*8r{bIc`TX0P&JEvC_{-3PZ$`Pb+=lA52-uBQYk&Y@iZc;Nvfp!m%shF3 ze(KxL{_*bmz|Fnqo^#K=_uO;OJ@?M@v#Y4t*V@)zkz!hd_vv-}r@jp;x8W!}Gh!C&;9;l-EAW&%gDAUIT2qnzdM#VB23fe!+SDqh{}kff#bOh;ye=|OE7%V4`rU_!i- z5$Ga*V-dz7q#;Z|n23;pkcmKTy8+=w1RAp(gsBL0O+)w`0#!h5yagd2p#Y%}VK%}X zgt-XDYaTM@BP>9uMCke6Z(iE`yC=79ZP>ka$>&p_Gv$4<=Xa0pn!5F&&;+f~mHd;J z`@8JNw!d|-V8f)Pch8@&c;)xE&R%s}^hAt(sUq^w)UNODntJ;u!-v9M)BzBBYah;^zMv}g zxyHSYr`8=A`?Vka@Fx@Acx>0y=YJf_c=L9&;~OV#+vNX4V9kMN(x?A=%;1-R8$02^ z|GMj~r;~ngxphMOLw`FQTJ-4Fe_l}axdqeTpK#}iT~j|Py!(}j9lN*QczV+ix;Ek> z*{VxJ;x?rSNE2Lype_xG#R@=7uv-Vy82!-z`%H-p!tXJ_;RKqGahn1Ep#fij_8oSa zxt>mB+3axx{i_D}*9Q0=1Hb=mfUg+nX1>a4gB^S;8p|NXMo=|@cXR+f13erG{7$z;2Z<|pn*S@sQ5+WpQf8%1Wz*H zUogN7wmcB_2Hg%9+3*r(Usk`;?s5m+O}SHp4vudQx!oJ$R3Ue`)zRX%w+3`s z%^pT=jOV!AVTaR8t#?wp=dn;Y=nQOO?si|8Q@VUX777G?tzi%I_yg`%qG)xt1eiY% z_O-g0)6?SE;0`)AGiS3u^IH4)yqh=pl)Zx)}`HTO2-!s8uq!*6OYoNK>05=mLYL7JsW`U}sBLEUT`u&nYgC zr%LC8 zNiiI)M=8FUvBxQfbGDmejMP&US71G-SYzxNif1skmtr^#`zS7EY(K>Xj2)yH19^zz za*PATaN1v^_*RSu#o3G>izWx5BHy(cf(4P){sM7m&>Akx29$k93F8!!3{je^*U6e79>^ar~1 zNnQGFUHXVF{hBU)NSEHPOYhaC_vq5Qb?HZS>4$ac?Yi_Kx?Y!F zp-WqJ=|#G9xh`FZ^y+>#4k68a=ssK0e$)PcA4osEav-~c9Dr?mHhC-EbWIMT1vj%W7c+kgq_w%YIp-VcrZY!3E=wQPZKO{>V2d2H zf+{Jmeaef&v0o3H^6~=dFQ*(>5={zFX^S`W#g}_is^0oYm1PCd?#Gv2{HXK5WBb^1 z0}U@W+}}WTg4#00+u`o;vVxSOHPNJo!x0l3j@^6C-*2*9>gn)K@#ffG^wvbDO3bQr zm%Sa14j<@`*F?)@u9efj-(#NM?t`4pC11$4Otw*a&3TJW(AG-YV$hl`M|y}R+cq4_ zIk)h>$+ntkgT&tixaJ~rE^J(VkvVFj?J_^(T$hjNc1U=vEVoC(=5y3qqBtyb2F_9r z^=#pNdHt+rVPlt%;x5M=-ZRq(Oby4(r+>_m@flt{|Y5PU~XG+V+?0j3@oO8D`!qQ_Md-g#C?>Rt)&I7>3j zu`w?7_s=Rxw@ZBcS%1I9awC`YOOQ;vkM-{uP*gi5l?PNwmLxfLfwL?x+op8m{+21; zC#p@|!?A5=@1Fm%t@CB}YUhD%(4ltdPq);cak-}HHPOA2-`CHwS5vM_o62bqO4`6# zTcnqBG3Dlf<6g%F zYsyjNRzt7Nm%S%gru80ga?fS2sqAvYWp7Hshwnh*b=kHowC{@pNgXu*t~V#zy~D9z z4O?u`cJB)xciPu?3u!Nj+_ZQAxSP1VCmkP-ZAWT~ms)B?D#x}Y!X{#bO*PTiWk2`# zt?nN#TiVkFJuI9O{W$f1HbX0xZkTXH6dpBU-R1KYW*JG@zto-MLZ zj?D`fhHp>pPQaJEt1rG+O15c%+SJM{T5Y@!`l# zTxY)dSMaHhJaxz6$jzLO=da+iB68SqI8wyiFrx^#S#FQk~4MDi9Bhx9WvlPBovnF_mSjXW;PUOY{+uT)n9%Uu$A z{SIaE`cDfhZH*k1CB~vn7E5*y%Oktj&83j-Rr1I|O10G*d7JlSI97N@%ta-^OIQts zHQ#-DdOX%H0nG(8Iu6YTH1;UrY>~OaoCa&8UXI>xPN@<%>uA<-nt-G^9H-fm zo8a?zoMwllc@{KQ%hE_obxtRx%w^zf&hT0zd-w>FPGmt+R*N;VH=c9DDbjz|zn7P> zM)t=sDH8KTi8&OVG?)|688lEb~vs^WWh4 z4Kn|Oc>XIqzh36|#q*!%`L#0tVm$w8p1(-uUy0{G!ShRGe$sShk-o+AXUP22c>Xq? zpDpvV;`y6+eyYr$8qdFv=U4UL`ZdwxgpBUxm>Xq@goM`c{BbfrAt5Wzp8(w<$<4?` zOU;k;T5yVzR5m$4xh!}6#_#qBd_scxBlsmGHFX5P!t3yBk^B-pWxU)%**+!Vq1Z*f z@0cy~mBfZ(y*xip<}1k$#ZK~k)qf@Vp;$N1SN&HbJ`{V6=hNJ=V(lo;L;o$i(0_~w z%aN^AavzF4%c;|(w5qPtJCYU6hYIv5$3{@5)f%bg)al;rhVSfnWXtzDpV&y4$u?_b zjYgJsD7O8)-WF&{W}Phnc;VqrABeOI4 zf~?1!D77M9Du`4*T2OCc(}~MAE{A;Hm&1|G4*&}tyX?_Zje6WJ$>tT%H1yYB9lzRe(2s$QqY(aw8FS)!_(aiujD^_(?@Fdbo2z8GigQXY;i<$aa%{^ZX?$-t6x#~U z#Lv<{!EB3OjB^ty!L43$%Q&Yf=u86R6Q>p_aDq0iM_U9edRcE7#t1dmLYGlqVZJty zJYBVI3fguBbIfdB9+@EboI|l<-e;kqCip3JTylR|OAnp>e{X38S{nXTEj@mAR1aph zlu{ID0{IrwupQ`u@;B1Z`g(3N!jkSjes-W{AZ8M@Xa+A=%k_t57AyGb#YxYqd=K~u zKV~fI+bQ|H0zO$5czR~?Sh7$mv8VjqK>c*#aSp{A&nAET?BkpTtPzpjNWyDLjVdh^D8D*}JJvP-Fn}B-xZ`p~QImQhKb>S_vKJXB2n#(3x3M z0a3%I7o_pnR4}&N8VyUz*T69e9xBVbT~fo|MfXeW&-==FuDQS>%N79JEwN9d>cV{=TPWdONh}n|-t!U4G`WmCLej)T6T*q3nH0*&+yfZH~Hl2g_H z_no)lBxWdfZ=Cxl;I7utXTaTT`94}eG|MH;q@zUhjBLSUeBbv_54Ewd&x|v!9P4H5 z;wHSKPPL}AYX#@KFMFr7k106ASga`M+PsMt}8kEm^G@_nw~Q^#81bF z&jiV59FJK+vgBvs@%VycMqu?HPf0}M!c@aC8><0X^kF{lE^rdjG08U<|Xe!-xJlt(fQBO z_=_1$=XgKH`0Mv>+e@s`5AsOENDCG^tbBzrSvs812`6Sq8OOPS!|Y$!Ks(6}{+IUk z>MRnr<@l0FD)-T?(HSK|L*F<(9{QkYD!t1i+3~d_{S13mwc~dK+cjkadrt4*)`#|* zKl?cO%j~M%X4V{>BJkZFt@g^hQv1)8Bx|&y6!n{|(M7Ty51%H#BgHZWx;ydcQ0((K zd7$+X6q52@Ng3q(@w>1Rs9k9~Y<>!CT^7s1xUh{wv3Aalc8cT~TBBQK*(0YXqFfgD zPQNfjDbT}9B3qVyM(h+>!N0*f5G|Pw|2l=QCOP~hWGr~8_Uw~9Z#|vXGZgzH&J9Mk z_ce*n;rr*2>q%Cwl4a%TSnCTo;deKkj^om~y0b#$I*jRqwDAD=pi^^$%|vPL^) zUgs&IFNBR7j$Iz2exx5~xvMXBFQ$`_gJf0FdVRak^``aQ50B5pXDd-uo+A9ClH>1t zDepAr+l787yqQFguJno?(LDZJoEfz@EZ|l{oG<+X=Su2aj?bfa6Hrn??z`6LAz7CO z8R9hZgwjL(_$Fapp;Je3-kH-d8d@OI=rR0JDrrBl5P$FOhBc-gOQbJ=)d@S6Ri}n? z7r+})@QPDNhiK(uxnCO?))JT`oTl)zO^zM8ySjWG>yG_BorcP~9__7wyn1?*Y}cnJ zEAg+`)8<*%PmQ-^`uFNndW}nb zyR>rKA_p-i=(pKy+hFW@)GJ^y_WEDwF3EXDR8?}GiQjE_kD$SHraKsW3_DzFbZ5L@ zsp!{JvMnxMzb;`Vn$1Ex-adg}ABPj|73aKC+&{*l z$Ic5|^?{Vg3Y>Q+P0;_Y$qH`J*;!hpKj0%`jrPluKRCB6Lbg8%dJ#GI)<>iZN~84j z*$qM`zkY5wmNH1ED>xlM59!>172I+>!KFLC3kODL*#~2X&W$WbV``Or*JHOwyy!H; zeDny~L3%0jh|VkNY?3Z<&P=7MBI=x3K5fJ{mMXEvIjeG zrK#Y>_u|X33X9*g24i2xZ~X#Kzgz8>{h4Aq{(PdnI0v$1*3b#jC|+(bcHi0ISjMG- zKUkx?mBv$RF^|_n+bMoR#>aUqEDm9K3Ra%e${2H)!^aV4nd3XlxWrUxVQGeQu|u6m zD*^h0+G*sTMlbrDBqyvV!n$`U=DW9TU)M>@j${#L`? zx^j>uPKyU)^SD0L(vE`8bse@5G<2doi1Q25nHl^fv(~a6d$N6UT%YJG*3s+r^Zq_r zx75$8^jJ#Tqv*J9?b7M-P;B(@_4W9XKD{1)_2Rte68hi$33-*1;By|7?X>j`$5vmu z+Hxw3_zHgERC+G>kUrli_1TOzk`2T_fGQn%M=lXW z7OyV|oibC|w`FU-eg^mEpiC`4DZjvdVAlV~PFv)4Im0TaWni~c^{11%yeC zoq~GA*xk)#K<9TaeEi<+lTIL?elds+$a>bISHjMS-zF2ItU-gRoC$YES))?}VqJPZ zPERLAbp9y#RY?4;Bk+nh`MlH@vSF(I5fq^mrLg~q8=`%AWX&LPnIivze%B&u(zL^}9cxdI>q*cM=A^_}PbczOLDo?P!FobpO=dlB zDtA$q%RjAJPrna{c8~@vk7SvSVC5K$HR~vZmgT?(CDso73W573pOKn=_3E)AUOq8< zmPaOW?j(UlIz0JC>YlT~Sg{V1e4&v4zCJbX7i;{Sq!3!q3a0V#sE)Ql`X)2&!wyP4 zo5Ami7~PH2BPM1={^``7CGsAu!I*||UJ|L2I6CiWw>->uB-C?)Ou4_r`H@JGch`

XgHW)jC-_->)9?(A#WL_K@%tSqw%sAx);10$q&4Bhv%A*EK6L3GqK2caMvOiw# zPkJqjbD!v>y%GYfI{g-s`yOFg?s1+!8MIcMBzbWrbg7Y~8azcBZWYowJ{Y@*T_&9= zv!kQl8;qR;G!>rCX`V~;&maYQQ?6|c?o?|~@;DXkQC!&3UZlO27d{zX^5pXt+*d+( z2mE`dTx+9!C_}6BZ{j^5%cdm_=R&Vcz;S)Q(o5~4-_KY<(z_xxT#$y@Dtb*l(O`R* z$a{PSW5;^;lFnObh5(2DXIil<2#6kQ$g9QKnW|$bw(D}D=V>$#AZ4>8db<&{>7Yel z?>wc-A?AHtBJUO&jBUl9SoCQcwN92u<#N`N=+`syYs{v6NZ*RlO3+-Azde(bo~SOu zepcLT1U{1EO&B}kG?hzB>=06p4#v#!@jMJ37HIYn-W!seX%~Am(>n)uMs}m6CSLFF z(Z*gmb6LUd7ys>9RRfJr8csz-55%5Qi;t}E(Gs)XRA9VIiOwEr@22iFB3)4TW(~%w z(K>#L6cKkSU5R~gp0vLm?NRqokyiG`VNs)g*ZsSJJ@S{WE3qhcg1^N{WIyhWEjl$& zlWZHeYKLvy%J0~|V!aZ3^!%5to2L9ceM~o-VJcrYkhE~QZLzJw_W08M)zPCb_YQo` zoNHnO)A5`z?nR|%An5rAdN!sdJa68dl46(Jv$&O>q2zGINVrUgZ*;V|?4_l1=aiJ# z>3JFsFPKw0PY(l07ZGs$oVg?6G7cv2Wd?kC0#DCQ;lZN-suIs{NdOOD@l+`2wFeww zJR-)}ver$GW}iy~`8qu6RO4^;_?nQ9C$!oEc09=x25HdIqRn*S|JVe*JLq#XYXN%f ztH#lKOIX8GRUFh%6c3R#g;>~E?6l({EJu@en^w|3v!tS(9xrA!D^}MmULo=*C*L3R z&EmwqtB4c0s~L@GbJ6EL&fBP!`6ZRDcq*?jw7Jl`xsX4HJ!>pOL$sQ;^>sD%b)w?Z zdAu=ByH8to_v%&p7Ro%EO_wS17O(mnU0%M!6TWV{<2XaR(O)4ih{+(YM82=p7bfwN zCTKx=E)Wk4+P!Uo;^N}5JdMW>TQ~rD&J0y*)r;3zD>eS?nilr+!3cZZ7z-LEjC!!m z8PF28#59m!sx1yL=%h^=FlRW&IcG>em?X zwKdDuEyk!Wsb8~pb^U6Tg-+Ocjr3SzC8@Q&#qV+xZ%x%{_wc$jVkYVex;}0fke;GrMKd8Cft(a4q)9VXhW;y+>o7|Ws43Am{wfh_{w-H16ZqT3+ zMiiS_Qr?cD(&i{zBjPgH3fP{x^YQE(#T7DMz~hS2Ie3F_KU;`wtW zexA&)5PasB;TbuOm+=CWU%PtcCKTf_iiz0X+(K<499S@AOt?+a==oGF5Of!LeC+kUpKBFO(mcLq=q1#jG|LU!N*Pd|kTd8DKpiz- z2vaSraRUw33{yb6t7a86s-@A7S>bQSyb2d;P#u!4R$5$A6m&Pc@n|et7jiUVPD1%Y zTSE3`M_a4Y3wac^Xfz$PqJU_G$KQ+xYf0?jui*kges%rqrEBVD+g4Idc!(9!fVuHF zoNiG#ggW@c%Xns!%FtC*TB*@g6cqW!f&!_hFN4jhUuL^5Jt6h<<&|2Ub=m6c(i2kB zqjUL6Rw2KW3n8?HPb~;tsGJ-F^_VqE>iXg?ZYtJBYADaThBV7alp{!Ivwe7xz)6I3 zE8Z`H5JuR8@HRsF5)&&#kmEy+#9uNx+C4=sjaFlqdy~)UZp9dW5qXVq^GlGEQ+S&F zo6*p4(BJ$;U7sMoKQlgDwj=~TmOA;>a9tx)c74(DGL6t1tX8xXkXCA&y)gR;O$uTG z(b`&}Y>8$RLcO(CJS>hiMWEs%JaRmQ?=)MuOtYn@G+TN|v!!P=TY5yZr6(l&0*8S2 zTL=y{y4;1Lai6L+)JM9Cgl>S_Y^+`@>q`r@*>PY_0;sJ602_zLa2YS>l;TJxeaJTy90c3Yc4<81x#e0XNwm0!cK4>&5c<~dd!1a0eIQq%RymupaSojf&YxExNc=r7_-b8jo= z*9Qn$HZk975kG~{gHX8C#JmVQ5RM_F*Ww*R2wM?W)~r*enVUrdyzpztVbbB+n&I~* zFnSzc`(U~G!oZEU#}74wCg9ZzqzbGq9MD!m2bFQ>2Ha>ZwYCr~1bpbF*`qR49`lhb z@-k(Sbyo2jxcH1`I-xSmIx;1wfout^JKpI~II>ROXV8%Y%BS=-iLhqf)gkSb=t`eDHwt2?|71=Vl*P_*+_T(YRn}eHQ+xj{cV03|KwRSh5j|_6F2P zD|zJx_ZD~@v|zTmrSlr}7dN)~nq9@=EdlP&xr5Z{;?2(1VkcZaS6fStC97>3IfV2Y3a!Pl1%42hmE6lgURtQl>4e!Ne?$1D$P-S) zh&o92ai?8+qmmWFTRz-y&rmNRmbu6^Bgc$edU&m9n#|#OlAw@G7H#gxCl3VSXa|K0 zPfcNfLU=JsaZ7lElrQ|0Vo@>Sxej`Lo{-DurU$z~FkRb;@kgz+#t#xed+SF|}m&-klK@|*5z3D6y%l|Qo$2#h;2Y|>jp?SaifJ6`R9MHV)bCL;DVoADR(lJcM#8rg6b&z;#GA0CW% za0{APNFyJFQv&+{4qPcn7ww+S?iL?j{{k%{II-%w8k;m^Yo4ILMFWl2*yiz|Rwmwx zA{2&i0kxJ;lQdgG=GX954#661bXXCVrR{FhO`5V+e)rqR=0<5!Z*2_ zw{X*_6cC0&)gRxTkKiFJX`CF~*3elC>5psx=A~F5xWkWqVZviWM;$bFd~Sn|P^47k z%@K}v=(Lq&a6aO8oUb|td&&(wM+p1MofT~0bSsNk1O%Fi*AHn>ZBk?L(jz$~uZ{C> zp!yT`#nHUk0mWB3Pi>^v`bf2eW+~%W$SwYw)hkvkTg3&}*cQfQ!1j*sutnDy*fVDf zoi)Jd(i#eW*dPb&Gx2t!7VO`#Zz7lye87O`@BWdwP)@O7$Loj0{O0u|N%e~&5T#wb z{fFBfOlYwl*l7^Jucgve*;whU3{ttFcnUirxa789fWsRR7RAx=lYt3LTf z?|El<$0ktxUD{cQCnDe#rfla}6Hj{)X8_Je$V5m%7#be-4~)Tk>JSr;e#F}Vf7*-Q zk*}_D^z*+;P<^6U^N8`R!1(bWJxc73R=m--OdZtfiT{hI^QA0ml`JZREK2_y%A!Qd z;%+I6GN~8;9c97(5qGtbVMsfdk7 z+|x9dr6FcxZetS=dm+mgGfk`=@gU+Ih!*yD)5f%qB3M-d-H{1d!<{dL3_5FbOl z;0F9=hxq$9npi*L2eNVR9paxLhMkLFWU&a)@DA6dH8qv^RkaZ(=xwuC_*xx7zc#nH z9Cty?YvY-vUn!keTvA?KK1<|lb4p6*mCP$yz!u{ulsVjvMjtbgX&p7cXfYc-HhFQ1 zX^eSnQbtmyDa$m;bfYEPG})A6o@&CafY-d}8zyvF_^JVWABTl)-5H0uwP&cAqW_UkM;{tPcVn!(&=E1T0QPY5fu~tv+}sb{wYF z4eyM`w_fP7@KsK%a{^A|`Q;b`0pkVSxahktbXoXHhIebnVOqJw`be>buUbgRHO9hM zFRYVsm{vQiXK`4ridYZnvhXjBFm^Hy)2ayF!#jED!uzavto~T|>Z~Bb=g1Kec}eWT z@V!W?@u9D-*a55lGxVSEs(-Xn6WlH3qwq=|^mP=%tM<{V-3VA+RNu=0PU^}Z*1=|3 z-+&HJ^lH4wTOgSH4soTiH)V<<#lJ+3r=l;>(dVn8k{*vE#pRD*$9eym^ns{ws527V+Bv_!!0y5kfYXpVANVZtf?9)CUvb9|0ym zjV{$5^1sBD!F~pmg2_vw@gV-<%4SDIQ4Xr{uZYV>jNb>k_V$221?6i|0&mD?9|1lI zm}ZJ!Vqz;KeI{TBCJCCr+jk4# zwpk|js4PDh@R(ao>^Bmw0sJoD$0hwLqAxVDD-!Pnys^l{c1ySe@FAW2Nk7YJ67oy* zC!mAB0eW?jzLI?V@Gf(43HzkQ^;eY7*TKg5PW37KOgoG3g1>@kcR_e%kLl}9{}Xrx zlYP)%)Sl<4eR6)%7j+H;R`%P3UCloOR`ZeYCyBm+29@N01Gi^t{h{3z)o+d4uT+k& z)xi;zr+2y&hYaYCSuB~vj*n@U0iI=m7wTXQWsYM>RrXrL{63LPoWw;sau?{;`jU?M z>(-Sg{3ZkZbp!l81N>71{2E~Ld&s^}e|`s;>LW7xp3+4F{XK9AlA4A5s6DBG6YaZ^ zWdfe8<9D-gA;3+@XFlLN@*sJr5Y=}D@>J_d2EOoB3%ve&M(Y9V>+=}+Z39ex+0C5) zc=ib3gYov?$esdB_7udhPh&BDwn#VKW>1}8sMZ9#=p(5NS4n6tS)L_i2+_}fbTKDUC=YVzP1?f zzlVJ3TZVLzyrvoC-3fYq`5k~0^DCP@YT)-YVA{{rN`AipO#2p>oL{d4rteSu9G22mFC*m@H~f8v3XF*$nuz z-vz8L;&<9me#ii`*=?a9|Da-%(^=#U`a_}F_@bixwqjFj8|~k`p4oF}7Z)e~UyB0Y zav}nXoWXEuv7gOwu^Hk2tO|TofrB|6&CT}BxIfYEY5mWtsufkCOQA4s1}k>rt5eHs z*4kGrtE;!$S>j7&_Hc_GcM7(;>C;^n1?YK>?WebYvAUoYVHG-5L#NkhqsYemeSbpzK zh&9neX#$Bmo#^p1yWQuv<1r8?9yD;VCVu}E-H<1fHhy<5YpM$etnN)brrY?K?$$k? zwxMi&cnd`}Ev`EH-q>2)GQ<sHm&FI&CJZZDo+UQ*6*8y=pBYqH}bWi9kz9iF#h#A@WN zN023+*Pt?U=TvZhvK&v-ZEp~;$B#d_iIZ(?a|gHJQ*4xro1^G zZeK(J7SE(ccsAo6LvizypQMD_6w!i;3g&M16w!zl`|B_^wzZ2_F0n6JWrd0feN*WX zqmECYS^s9$;+4y4Xgm}8!0!WQ_N6OUS1(>+Uv0DD=`DNx;_4Mkh#mjxnlseKm5t$^ zO#H8^N_;&n{$)CSCTQ^SHhs>Y{ZgO3F%*K%VdT*R{{1_BQMwgP56jQU>9hE^?erPy zBYxt`dwLA+Ripds?R2l8z05v$!v=H`b<2838$Ef%@BJIWi9QV|zO|>%j(-PnL?-{(pFStv4ySr@Reb1A zPeV%J2qiR4p2s3(1RP>)12_?^1?Ji~_uRqed-cw&b1%@y*iF{1|&MwDK* z8VzyzS}|_0wWt6$OzH_#KQVlCJ1M?AnZV)`h9ns8h~B9Nkj{utI>I1A1rx=})wdY+ zS-NjW>a%qgfoupm!|&sae;-p%i?*omLXOCmA8yp=i4Rihb9mvALyWrQ42c^I`ISn2 zLDgTOEtrrhg9JdM&-mvfRjxDybI1~qsWIrr2(ogr7T5T$sQh-Pz7_PvOFb;6s2%Je zGJL31+UpVQ@mLl3(>G18`Hj*Mv}I_D_!g(W79sHwL(8*98e{%(&=JK950}TkGO8zv zf2UKQ$%;c;S}?H?hl3*asuX`pF~Ev(%doq6arLsIFz(_N5PU`PSVs|7$YO%L4tyE3 z*tG?B>$iv)?g7WhrzuAOcHr=2CDDsSpgGKnxk46)-R($|Zv>Q|Tj}D(YgZOyrn%Z# zvD+&gBS9{FB0;Xw_c_5GoEoJr9Rv*4L|NvT=aW2 z?Skkefqt*32SC4Nt4r*V7|TNjZP|#9&dKRJ=^E1NqJ1M>^gOVlqu)1nf^G)Kh(C&s z_8n3DHckBKcaQy`JA|ON`9w!y6$1S_!Ry8EM-JT|`S4J`c}-8z&U~ezFbwicLtXdMTd*ZZYS-rBj-IR~Z0Z0BNe1>QVi;A8Fc} z5FP#A;>7`FKGKRG(b3lCYY0SFjX=M{>;xU16%rjj=gIjI-NOjfR;q{gNBKBl7Qeh+hc-xQK3{NbNBwgLc|tmE>!|T3VJjjHTyOJNs6EYX`ZJKpzej-i*ZTUK_;<3nq5NWahlkM zu}JJsEip@$lPX+_p`i)HajCDsZy5S8^rR`sB$-ufqNz z&~E7c<6l4?>ju+y!^y7kM-5v@c8L(9#weuan~GLB((SmgEDn&Tk*iRAAD~8{*?#+ z_^k&I|8vFi6UV>5eD`SmCmVNu`Xbb`N{dg5fM4vBtH57dCV#3-=6X~i{(2>#rd(Sl zHD3OXC0Br+9_v1*y)6m6!~1zvN9r_u~I_UiPv+Ek#+Q8!)D9i za609+=%S;mv$ajXDash6XZ`;eJ@mbrbG2R%%n)lhw3;fyfihvcD^Q_4{GA=d77w>9iOa@9G?uto|veJeElq<{H;$E8@0EJ z#lKH2*2D(*XThB7QIP$5>=%wIq6wRk}U#zBFn!yTCp@#1Y*I}ia61zm->uI90j z_RcE@Iz#hLm*Ydv0vQAprNYDn93s_*AR&>6sL@xne26PxZVOvJ_uLG*8)e&eioF6)g+ z4IPERf!`E@+K64e6q(*^Y_a2oW1hZhdaM1+yT#ioUx^o<^4e;qIm^uxx7r;A?Z7X+ zp26wMeeC&?hq`#~{UNcw^7VM(uU^ZC=h$zJ+b>ueaq67xC*UKl@byx^u-EdY+fPi0 z+HiaLma+CDV-0U#Zd=g4c;{Ez7k7WP{h{r}OFuq$c>BTCKMgHBE$XzUy_bVq?`Usn z-`swz<7Df_SH`9;KXUCtO)LR%ZyC>wWxieQlEZr##Iz3D2@6k9Be=%esZHY2x2)|yKR z$JhsrBwFOa5!>7lu|{kMGY}$ol|BQ8ox~VUIx-94_A%3u;k21gS`n^lW}KNm?rJ^E zQt`bHiVySsF<0h1Fz10e56pRB&I5BE`2X<0H*gj{3}WFgX$fc_a$z18>TzCXp31y) zHEQN+HJ}h=nI;SI-iO8XN#vBwRUfU;++6GeWFB5V3u11?++!t(h54GmxtY0J9K_sj z1!xs0jB&|_P&1EWj(v?+e^@N0&%=HZHRpLA^&5~sYGHn?iivUl7bzTTj9ctzYr8d4 zzqcR9xqM@noieiN$j#BFXsn?*?>26HXk&9U))Z}8C)*=8#Wps_nqyl;%T2IhSVq4s zw0f}fZfR%{^A{~>snix$EDBZyuhFWtmD;L6Si4TEsaT`kaFwO;{(vRm?v~8yr7YKV zw4`@EEx0#Q&)q}bUXtbQ0{4t1ATw*Bd>Rl){!r+1mVmn(a&M%(&~4|QN!dNFy0If= znN`!jQf6ccai%1@$5A)Nq<)#Jk0Iuyj0+7E-np;@ybN}8NoJ(T*km1WBL?&H_BY^0 z4&tjMGt%T83G0B0NW`L)W!4`n$&5(c!<6K(E32P?`(!AI_G-Kxk!?ZoZt)(lyl;`E zLg--B`URda>ec!%b65Vr^G`|d`9p~167S82PfWjOnH9$yLtW`T&+I?$lPkRO>U?_Q z_m#$5EGYAtmt~oF+2dF#`+a5j4L*Fm>gwS)L00}p#_g_ugKzve^bMY@=GW!Z(_g!M zax3t6mEoIw{@4q>dY{qWe#qQERG_fyKNTN*v)m7bk~PTRh0J#%i<%GLeX>-EA3>#L zzM;5(Dn1Zd;w9PDg{%GF?3>?f&{O7`y7fD?NW`xMgF!srLhr?)XkAzLvQ95ueWgKeuc1KCm_eY`A|MKOTS9o4Ou-8RbrVqUWWexWL0SYg);efkkx!bn9rZe z^zW3(mGYJCnvCFgl~1Pq8zHNBUs172G(qP3lJT?x?}s+XyxZCanf_S``~LO)0W$Bo zS*YIwykGx0$bSC}LgsxL@0*EFLRKXL=7Y_HzNzBLpfR7zx|hd; zi9|ypo6hALaeM6DBM+wX{Chbx(0FrWG&=MDN(f#+1H&qjbv8!RqRtd`&c`)?%>fLN zFp^3AKFipz52QY>p;8zMOUgOPI)SS>upyrJU>`F_1Ne zE#1ry4}=`oYy--tac{td-qF?5+R~->w72is(X02iw07;FIrox0k;}Ww5PD~C zw?5;b-tIQKr`PCDTHZ~2JU(-8uIv4|TakkpbrS%~rWn%7nXAg!j?UbI+S#Z?Mvgs(ua=yL=3Hiz3 zj)VGcFIw7?MlR=u3f!W$gZ@(CG|OA=*9rf8L^OA3*fIK1J6Tx|DGr}7tZYU^Q)$PF zwzPIOIL4qS;dzes=WTo^vP}`CG-Tw4MAST#f<0L~S*bZ_Wpj2qHA~Q;%UVg|C6h@y zBI>R>>R2P-8NX1a-QA0}?Cy@@s?;12QENyBuY}9Em2k!1n}Bs#Hiqp4Moq(-w1N;2 zQ9M1vcp`*r({P-u-Jf^hz>iRvKk?1WS3b}1{2s{MN)`E5mfwze@+MAxuM;AoK&a&@ zUWkq06^>{AqcBi+1>APDT|}-#d&~t+0v87_Pyf;$ZSDl|#7-P@gbTnO1;6(9j`TH7>OUk-UJ+VJ=*UAajs}`W8QCX6zS{Fd=1Lpe*mjqYJdO$ diff --git a/packages/blobs/mt7623n/wireless/wmt_loopback b/packages/blobs/mt7623n/wireless/wmt_loopback deleted file mode 100755 index 0e2c33eec592d67cd056370794768f268a2928ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13372 zcmeHOe{fXCecyL?fDi&sAcsRD_Tz^esL&yhOavl{P7=ot19CvlFKj;l!~`OC~0QjwfX@b|a5HjU79wLQ8@X*s^Q`HJ+%S z&%U>(y)#al&g4H9_I5w}{juNO{l0x~f9Q+rw}cJD5Gr`YQbF{MDTZi9djAUi_{5ZE zVT$RXT`%fL&y36yVq~5nV+B|keQunJl(Nm>WHcebIK`!Vk#+-jqh7}Oz>Jhfv5ZLE zoFUGmE=J0eN*>=0j2;;uM8RQ1)=RnvzkbmDpfipEGm@@s%z!_Gx*0oB&ZuagJd=+B zzAsSTkGLIlz5e%5#z=YEwj!D6S&@u2BonDZe?uhO7w-+`(!nN>BoB3vZ^O1*StQsW zw3&fAY7kjQ`q4YzOMOe+`08ERb1%gHw(InB9V>sJ_{lpBQHXX?-8uNM@C2rd&M!4k z7j2z^X!gXW`41evyYbjPGezKlrHm1|@>@uyy9MsnE z+Q)?$tr$3d);H2{#y9flnOP$bj8u&M@Jyf%3V-y#>FOWfe>!mG=`$+t*YXuwUTFEt z?@scMY5B8SeniW^q~(XT{3$JeLdzf1@{eozZzJC|CT1Yc@;rTK*!Pt2)PG*~pV)fY z_ndd5@8*e1C*GL2bo!0ws|{h#G{j#bt!aGpOpW>I8E@kQBOdeNUt_lVuj?mP7(bnu zIA_)xVk5?J+Rg3b2gQkTkEpAiT0iCGwsGM-f$05SU_)ku82TFe6C7Tb3p9_IU;7om zG5Y-HH~FUwm-G9NwvQk7fy=kJzwY}Jmwqx~EMA=PAFntXx>%K=v^PHY`^V2#w7u|a zB`fML4jzw}1I@@!e@}27FcP%w0%@zr|o`)U2sw>Itl!yQ_Wt5H0c6 z#izY9xZU$+jb|=sE#5$@SX3)>HLYD^6RVgHc%8C<*F)+6OKMuF$-frAM%9|S_?-Ck zcxZgYe`4Ga6PGT(PM)gPy7<(3|IeL#E$B-=3Azy)7pBAa->;*NrZcBev(LY->+QkM zgU6*!eS_Awc>T~K>Z^V>Dc$IDJR_xl1Zk%(U;WzWL*rXq>Wi>}(#E3AgA7(=PvQng!pKc{K(zMkZ@NgxW`3i5}D*K0Vpy&$${(+uZ)X zHoxb}FVSjDy7|dA&xdB!&gGywy=>Ia9QM>#4~u#+JP&r!EAZ>7Svx0QJ21;FG2kZ^ z@1u$#rA5@A7@skykhfmE<&%h>HZEIR(Ha`}dBnm%c;eDjS-YpT_CEGQMXTeX3#6~s zO6~>ll2@KEnqGdw;lQtF0W6x^>1(PC*JfC{0Cqa1hU?c#Bc&f{|JkdwCxCp{+xxSg zE8e$Q_di^Kl&@wTWh>zC^n%Uf6~?o!M;*N2_$jQ4lUf7$hudcjJ9*vfmo_?HAHQ(F z+rqkdZJ2x&t@A(Zq~41@FKfN+0{yg7^ODcF(wi^z6{XqlbF}B`K9{EjHanx`sjnOM z);A6t7_Co0j-$n1r{vn6egkF7?F1K!`(*SF&xL2q^E_L7mPa=pUw zl=;wqo2$1{_Ovr6PkDtJoH=oeENA}(!s^|k-YiZ_jA6VNMp5?Z1s^>ge(?Cf(R=Wo z5{nP)VyqfzACJj5(*F34%ZnQM42+K+h#O4@b{&Y%sDI;SF;oG$f#VMz<@>FF*BZ$E zU>Ev6cLl!#(bfp`L?BUL`D$oU_+JEKuisXiyBV38n#1&qW<}4OQba+>MQV;8FA^mMxE9li2I~%{-SMushOCX zGeyl+w>Uns1ez6f*Jyv_Kw@p;f8xjRhI{3THyj8%4_uldEy*oH|WYpvN*EetQ_>PEC&m4SjiLZsl z(0AVw15b{g{Gu3Y8^zb@(BF-o%sn|esNq52kcLCRhK3E`lW9#p3V96=0*5pl0yZ>k z0H3rp`5lng@E~wV!y#Zp!v^rlE=|4z@){ll4rw?9Y-rd3KKThvz6tUg9s~|)I0S5H z*Z@AcLX%$%c?}N&hcp}lHZ*JipS(enp9^^n4+4iY90E2pYyh8}t;u^Kui-)9kcLCR zhK3FA({GB|8;9E3GaC+{Q@NHQVfu!;&YjP+jbR6213YM)-b3ES?|Q}@ezEk_PE;{|q8^aUH}p5O+fUIKMArFTF9g%#5ZBsl3efMfzomC6m~BWA1h{8cC(nc{5kY zWUzoWZ;Y8(i(&zqNTdQO)9g);W^5jXGPO(Wgu``pt%g&nV6zb~h zNt@AlB6GW{<0>?hi)K6afwE?L&q68h%J%k_DweiijixD9HkHV_ilw~MmaAEZ+9wrB z-YvJZ-^^xbBkUTNxZKRz`9d~jChgSjeBAsP`mfUIr%!L~wz}8v=(Z?mb!_c4Gm(AC zbR@=hWFlGHw6ocCmK`AV+x>Rbe7{hx5RKY)Y-uu`&Pesk&0J!?&1@0_>+~PTG1R$f zJ?i?sY%I!rplOo%9t^` zH&RIE&ApLi!8TVmu9EvCx{hW|2mIb*8+u?ROc1MAuWGbpVWww~NlP)Fc({}Y#O!2b zANWj!h6bl4b}ol@B_c_;T+$lX%D$mqGjHeerg>Ka9@LxYw_|XX=pLBrG(hT-GAqkv zq(}*~nMg&mb|i!#l!hX=kyP;c|yzH3i(q%r&cbue9y@=RjXBsEv7EWIFSl&DSz7Oj z3lm?&&eyeYtp~34z_lK@)&tji;93uq^}y{@4Y3}Pfxjy9Obo|W;#r>|a9kx`#QBOm zr^cCb9Wc*5YY{7e7r6MH-%O;RG7NcEz1(ZabJztQL-1qwC?bx*ic~I&&O4G3HtuO zQR!f6KqZd-gvV9gjKjg(5c7!NM!byJi37fV#K#fOBQD2Xf;i$~#0?!CYt5y%_TZDc zuwqLh70IT}n}W^3#)j1eS-A2GD^~{_n}f~EoN{wjseqd`hYIuy#xlY^akgyfPC-Xw6vGTen_#8_HuN+-x%pHsaP6YY_gI9Wzz?wSEn<2geBJdEuk=L6 z=UMKR9*O6qNT&zGSBu#7boe-fSA0mOTZ)*T?wlPn_2M3Z9=!62n=J9-iE}J<%6#I@ ziQACnJq{;$1n&)~_6xM1bk#mSMa0jz{iEorKLq-NbY&l(#2#Q3Sl@AgVNL#ohCOb5 z=QTR{Ifpo5h9Kr#;)Ge^IXA~d>3^|||0RuosSbF(CVobD|UGiv1ucY`|Z>0n9m< zLFrfi#hV$Afut~JK8^?VJ0T#RbwnjpiZ`=daRG_9nji~ zjWV$Wa}wux1LOZLa0B+zT7bzv6;;QezfscXiE3pEFzctjmu4xWW{Nt{f1%-38ovO4 zi-wi_eMNg`iq5Oh4{CJw$0-f7{$UN5`v>{e^USx)Ezqwp-!P;r|KS_x4$u{*Kk0$? z-U+%IPmb3CVD-Ek;yUpqU^RZEe+`)LI0ggHKmDKY87EZ9`p;^Z^z#~i45GZ_Kn-&+ z9>*P3Qk?I_f7h@H{1Z&c>iIR{uje#6`QHOR=-T6lzgB|(HelW_s|No9VEtax4&Wmi z{~F*)`FWxZSOx0;7wA{d_Z%@xY%i0)ql|w)a39*oZ;3gcnc}O!^k-$y;WGZm%J2~I zS0K-se-Y%L16J+#qdh+><3Cr1r#Y`I*#r~6ylbNZ+w(`j>iMts%o9z(oG-~%jpwBu znU~@32hncYe={)eqO1d*F9NeY3~bLYHGUIiS2RrdTY=U5J_lcTRnA34 zP*^|0ib5_cF9q(7MjN8pbS}37w*uY!fxA-$ey_xPSKPEB7@YinH4a`Z1P_yFHor2M z7E5AcN&XL2L4p-TL^P62T6ftI+;U6(p{h!uDl{pVFZA{XqqxqtxnsMvWfS(!EfKS` z_U=RuyIxkl&%$N7l+DX`v9z^2neK@styn&t%~_E`KemVaGD$mc$AW9tG=B8zOjd6q zm9Qe&Y-FE>J=yF&(VLC**;cI3*S8NM8nVEdFJaa9f?=l)AsW7QTSxb%u5FeTT-|b0 zi*pswD&!)&ZCv=nFN#~5g%wNe%_W-9*0Vjdb-lHITPJ$Q=_-{kF&NhZJ3qTEv~^PlxHO8qT_~&#Te{jqTdb~d zc*lAiRD{~MtfxA80Wq2@$bNF}EVi{xUMRFSb#JvMhopOJ2M44((v!5^tB)nzR!=Th zyp~vcwz2+G-KcKz4yC-wSR!o4BKe4Wg|dVowc4qeZ2zPNo;Z~9$+du$K-c!AW1_Tv z9LPAAF?A8=UZ!4RS&ot<#|H+}CZ|R68fYnN+3n3zV#yUv9-ozxW4W{y$7VS?(%RI8 zDq@KgoX6(vPRCF5(cyTymrP65sBW2TdZWC4TFO-%79nq$TATM;+uf(EBN@SIMNZyL zEfvCG7rky$J*@r%U5C8tsuzf0ZeL$M(t|Xgb<()X$(`_df<*C1E{^AEUkdu1G@o@Sd+lrvd-Wy20xfGN$?s$`$-D^4 zJ`LvWe&jhzfRvUl7z}OS8npWpv3?P>;moMxh;=BYlY|YE46%qXnHV zf|#Rt#wDcANIsuU^c3*a^F{H03*39)+X=5x_YS>te_lyDZ!RGgqd>01kvezX@foI= zkgC@h&w~^n*R{M)zvL=>ohZBL?l*9~`xN-%C{wRH>SNr7$Wk} za4+Lii2M{GAJ@mr0k}t^0(lwkKver2TsNNv-y)Q$dMVGy!#VDYFwgb055}}1&w6DU zQilDATvfA-dn=vbqdiI=+rT}RdlAXkj>z?QHwfILAs<(} zez&~}J}-@RgW~%ZF!W{aLF)W%hog_{A_m3xJ>*$0^>H0>7E5?VLs2pR1LV2ez%k}} zK>p1H@+v5qe?tLxA;`ydMa2!1I>@W|UO=Apl8@_?st@3M33N7(d|a3CZ$ZY~G9*$T z`{|d6N}n*%8WZ2mC{uy;GX4rt@$tKQiz(ziY81<$>^l!cy{wn(hl6J6c&M>?6Ljk1 zdXj;Btup8QkjD5fB6MY(QmkuCA><#CxCP{4z;MbsCBV;MP>4!J1Xfw595WSs3x(JP dqdts+&mpoMd=BXIY=a81W#CZ{2MU$G{{>#T?HK?7 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) - { From 8c0e4ac083363aab77207d575af343b84747de5a Mon Sep 17 00:00:00 2001 From: ColorfulRhino <131405023+ColorfulRhino@users.noreply.github.com> Date: Sun, 7 Jul 2024 12:13:30 +0200 Subject: [PATCH 2/4] mt7623: current: Rewrite kernel config --- config/kernel/linux-mt7623-current.config | 3081 ++++++++++++++------- 1 file changed, 2117 insertions(+), 964 deletions(-) diff --git a/config/kernel/linux-mt7623-current.config b/config/kernel/linux-mt7623-current.config index 98b5b7a0a703..db22373e73d5 100644 --- a/config/kernel/linux-mt7623-current.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,8 +1662,10 @@ 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_RTL=y @@ -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,97 @@ 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_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 +2106,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 +2119,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 +2134,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 +2153,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 +2174,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 +2193,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 +2206,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 +2224,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 +2232,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 +2252,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 +2265,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 +2297,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 +2324,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 +2371,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 +2412,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 +2487,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 +2498,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 +2529,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 +2540,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 +2581,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 +2594,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 +2614,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 +2653,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 +2665,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 +2716,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 +2724,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 +2734,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 +2909,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 +2967,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 +3025,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 +3072,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 +3100,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 +3112,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 +3134,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 +3142,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 +3212,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 +3249,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 +3256,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 +3279,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 +3319,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 +3331,9 @@ CONFIG_KEYBOARD_IQS62X=m CONFIG_KEYBOARD_CROS_EC=m # CONFIG_KEYBOARD_CAP11XX is not set # CONFIG_KEYBOARD_BCM is not set +# CONFIG_KEYBOARD_MT6779 is not set # CONFIG_KEYBOARD_MTK_PMIC is not set +# 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 +3348,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 +3368,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 +3389,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 +3408,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 +3455,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 +3468,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 +3500,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 +3521,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 +3531,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 +3575,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 +3584,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 +3621,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 +3632,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 +3647,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 +3662,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 +3696,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 is not set # CONFIG_HSI is not set CONFIG_PPS=y # CONFIG_PPS_DEBUG is not set @@ -3528,10 +3720,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,18 +3737,20 @@ 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_MT7623=y @@ -3562,14 +3760,19 @@ CONFIG_PINCTRL_MT8127=y CONFIG_PINCTRL_MT6397=y # 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,25 @@ 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 is not set +# CONFIG_MTK_LVTS_THERMAL is not set +# end of Mediatek thermal drivers + # CONFIG_GENERIC_ADC_THERMAL is not set CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y @@ -3916,6 +4164,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 +4175,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 +4184,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 +4229,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 +4239,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 +4251,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 +4266,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 +4317,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 +4331,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 +4342,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 +4362,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 +4383,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 +4447,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 +4565,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 +4590,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 +4612,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 +4652,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 +4932,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 +4954,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 +5275,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 +5382,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 +5452,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 +5497,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 +5536,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 +5561,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 +5591,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 +5669,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 +5682,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 +5704,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 +5718,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 +5739,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 +5756,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 +5764,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 +5810,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 +5845,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 +5939,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 +6009,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 +6036,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 +6075,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 +6090,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 +6103,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 +6119,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 +6136,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 +6195,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 +6214,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 +6258,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 +6266,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 +6282,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 +6297,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 +6329,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 +6338,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 +6386,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 +6404,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 +6442,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 +6468,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 +6503,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 +6530,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 +6541,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 +6583,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 +6605,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 +6622,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 +6634,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 +6652,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 +6669,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,6 +6687,9 @@ 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_UART_APDMA=m @@ -5817,16 +6715,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 +6738,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 +6759,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 +6785,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 +6793,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 +6806,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 +6814,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 +6864,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 +6878,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 +6888,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 +6900,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 +6923,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 +6931,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 is not set CONFIG_MTK_CMDQ_MBOX=y -CONFIG_IOMMU_IOVA=y +CONFIG_IOMMU_IOVA=m CONFIG_IOMMU_API=y CONFIG_IOMMU_SUPPORT=y @@ -6059,9 +6948,11 @@ 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 @@ -6077,6 +6968,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 +6979,7 @@ CONFIG_SOUNDWIRE=m # # SoundWire Devices # +# CONFIG_SOUNDWIRE_QCOM is not set # # SOC (System On Chip) specific Drivers @@ -6096,11 +6990,6 @@ CONFIG_SOUNDWIRE=m # # end of Amlogic SoC drivers -# -# Aspeed SoC drivers -# -# end of Aspeed SoC drivers - # # Broadcom SoC drivers # @@ -6114,20 +7003,37 @@ 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 # end of MediaTek SoC drivers +# CONFIG_WPCM450_SOC is not set + # # Qualcomm SoC drivers # @@ -6138,7 +7044,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 +7061,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 +7082,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 +7092,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 +7112,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 +7135,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 +7148,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 +7170,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 +7184,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 +7198,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 +7208,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 +7241,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 +7280,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 +7294,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 +7305,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 +7324,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 +7341,11 @@ CONFIG_TI_DAC7612=m # # end of IIO dummy driver +# +# Filters +# +# end of Filters + # # Frequency Synthesizers DDS/PLL # @@ -6389,6 +7361,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 +7375,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 +7407,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 +7419,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 +7448,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 +7464,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 +7484,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 +7512,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 +7545,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 +7556,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 +7578,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 +7596,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 +7630,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 +7662,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 is not set 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 is not set +# 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 +7714,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 is not set +# CONFIG_NVMEM_RMEM is not set CONFIG_NVMEM_SPMI_SDAM=m +# CONFIG_NVMEM_U_BOOT_ENV is not set # # HW tracing support @@ -6734,10 +7766,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 +7780,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 +7795,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 +7821,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 +7839,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 +7848,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 +7879,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 +7894,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 +7924,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 +7945,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 +7968,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 +7981,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 +8060,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 +8072,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 +8091,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 +8129,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 +8147,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 +8155,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 +8164,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 +8267,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 +8279,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 +8344,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 +8363,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 +8371,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 +8411,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 +8422,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 +8435,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 +8444,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 +8455,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 +8482,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 +8493,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 +8505,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 +8521,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 +8561,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 +8602,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 +8622,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 +8655,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 +8670,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 +8698,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 +8709,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 +8721,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 +8758,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 +8777,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 +8796,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 +8820,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 From 0c2e6ecb75052c690a74686f2dd072b3ad06f2a2 Mon Sep 17 00:00:00 2001 From: ColorfulRhino <131405023+ColorfulRhino@users.noreply.github.com> Date: Sun, 7 Jul 2024 12:23:32 +0200 Subject: [PATCH 3/4] mt7623: Bump U-Boot to 2024.07 - Move uboot patch dir to v2024.07 since the `legacy` folder is only for vendor or very old uboots. --- config/sources/families/mt7623.conf | 4 +- .../enable-boot-from-ext4.patch | 121 +++++------------- 2 files changed, 32 insertions(+), 93 deletions(-) rename patch/u-boot/{legacy => v2024.07}/board_bananapir2/enable-boot-from-ext4.patch (51%) diff --git a/config/sources/families/mt7623.conf b/config/sources/families/mt7623.conf index 53892644ffae..8e8dd7103155 100644 --- a/config/sources/families/mt7623.conf +++ b/config/sources/families/mt7623.conf @@ -9,8 +9,8 @@ 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" 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 From b01c28c3f6189a485f4d9641798139b157101860 Mon Sep 17 00:00:00 2001 From: ColorfulRhino <131405023+ColorfulRhino@users.noreply.github.com> Date: Sun, 7 Jul 2024 13:57:37 +0200 Subject: [PATCH 4/4] mt7623: Enable various Mediatek-related kernel config options This enabled more Mediatek drivers for potential better support for the mt7623 SoC. --- config/kernel/linux-mt7623-current.config | 36 ++++++++++++----------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/config/kernel/linux-mt7623-current.config b/config/kernel/linux-mt7623-current.config index db22373e73d5..3a63a47fbca4 100644 --- a/config/kernel/linux-mt7623-current.config +++ b/config/kernel/linux-mt7623-current.config @@ -1667,7 +1667,7 @@ 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 @@ -1995,6 +1995,7 @@ 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 @@ -3332,7 +3333,7 @@ CONFIG_KEYBOARD_CROS_EC=m # CONFIG_KEYBOARD_CAP11XX is not set # CONFIG_KEYBOARD_BCM is not set # CONFIG_KEYBOARD_MT6779 is not set -# CONFIG_KEYBOARD_MTK_PMIC 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 @@ -3699,7 +3700,7 @@ CONFIG_SPI_SPIDEV=m CONFIG_SPI_DYNAMIC=y CONFIG_SPMI=y # CONFIG_SPMI_HISI3670 is not set -# CONFIG_SPMI_MTK_PMIF is not set +CONFIG_SPMI_MTK_PMIF=m # CONFIG_HSI is not set CONFIG_PPS=y # CONFIG_PPS_DEBUG is not set @@ -3749,15 +3750,14 @@ CONFIG_PINCTRL_STMFX=m # 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 # @@ -4153,8 +4153,9 @@ CONFIG_THERMAL_MMIO=m # Mediatek thermal drivers # CONFIG_MTK_THERMAL=y -# CONFIG_MTK_SOC_THERMAL is not set -# CONFIG_MTK_LVTS_THERMAL is not set +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 @@ -6691,7 +6692,7 @@ CONFIG_PLX_DMA=m # 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 @@ -6931,7 +6932,7 @@ 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 is not set +CONFIG_MTK_ADSP_MBOX=m CONFIG_MTK_CMDQ_MBOX=y CONFIG_IOMMU_IOVA=m CONFIG_IOMMU_API=y @@ -6955,7 +6956,7 @@ CONFIG_OF_IOMMU=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 @@ -7030,6 +7031,7 @@ 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 @@ -7692,13 +7694,13 @@ CONFIG_PHY_CADENCE_SIERRA=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 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 is not set +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 @@ -7737,7 +7739,7 @@ CONFIG_NVMEM_SYSFS=y # CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set # end of Layout Types -# CONFIG_NVMEM_MTK_EFUSE is not set +CONFIG_NVMEM_MTK_EFUSE=y # CONFIG_NVMEM_RMEM is not set CONFIG_NVMEM_SPMI_SDAM=m # CONFIG_NVMEM_U_BOOT_ENV is not set